154010Sfujita /* 254010Sfujita * Copyright (c) 1992 OMRON Corporation. 354010Sfujita * Copyright (c) 1992 The Regents of the University of California. 454010Sfujita * All rights reserved. 554010Sfujita * 654010Sfujita * This code is derived from software contributed to Berkeley by 754010Sfujita * OMRON Corporation. 854010Sfujita * 954010Sfujita * %sccs.include.redist.c% 1054010Sfujita * 11*55177Saki * @(#)st.c 7.2 (Berkeley) 07/13/92 1254010Sfujita */ 1354010Sfujita 1454010Sfujita /* 1554010Sfujita * st.c -- TEAC MT-2ST/N60 SCSI TAPE UNIT Device Driver 1654010Sfujita * remaked by A.Fujita, MAR-22-1992 1754010Sfujita */ 1854010Sfujita 1954010Sfujita /* 2054010Sfujita * SCSI CCS (Command Command Set) disk driver. 2154010Sfujita */ 2254010Sfujita #include "st.h" 2354010Sfujita #if NST > 0 2454010Sfujita 2554010Sfujita #include "param.h" 2654010Sfujita #include "buf.h" 2754010Sfujita #include "file.h" 2854010Sfujita #include "proc.h" 2954010Sfujita #include "mtio.h" 3054010Sfujita #include "tprintf.h" 3154010Sfujita 3254010Sfujita #include "device.h" 3354010Sfujita #include "scsireg.h" 3454010Sfujita #include "scsivar.h" 3554010Sfujita 3654010Sfujita extern int scsi_test_unit_rdy(); 3754010Sfujita extern int scsi_request_sense(); 3854010Sfujita extern int scsi_immed_command(); 3954010Sfujita extern char *scsi_status(); 4054010Sfujita 4154010Sfujita extern int scgo(); 4254010Sfujita extern void scfree(); 4354010Sfujita 4454010Sfujita char *sense_key(); 4554010Sfujita 4654010Sfujita int stinit(), ststrategy(), ststart(), stintr(); 4754010Sfujita 4854010Sfujita struct driver stdriver = { 4954010Sfujita stinit, "st", ststart, (int (*)()) 0, stintr, (int (*)()) 0 5054010Sfujita }; 5154010Sfujita 5254010Sfujita struct st_softc { 5354010Sfujita struct hp_device *sc_hd; 5454010Sfujita struct scsi_queue sc_dq; 5554010Sfujita int sc_flags; 5654010Sfujita short sc_type; /* drive type */ 5754010Sfujita short sc_punit; /* physical unit (scsi lun) */ 5854010Sfujita tpr_t sc_ctty; 5954010Sfujita } st_softc[NST]; 6054010Sfujita 6154010Sfujita /* softc flags */ 6254010Sfujita #define STF_ALIVE 0x0001 6354010Sfujita #define STF_OPEN 0x0002 6454010Sfujita #define STF_WMODE 0x0004 6554010Sfujita #define STF_WRTTN 0x0008 6654010Sfujita #define STF_CMD 0x0010 6754010Sfujita #define STF_LEOT 0x0020 6854010Sfujita #define STF_MOVED 0x0040 6954010Sfujita 7054010Sfujita u_char xsense_buff[60]; 7154010Sfujita 7254010Sfujita struct scsi_fmt_cdb st_read_cmd = { 6, CMD_READ }; 7354010Sfujita struct scsi_fmt_cdb st_write_cmd = { 6, CMD_WRITE }; 7454010Sfujita 7554010Sfujita struct buf sttab[NST]; 7654010Sfujita struct buf stbuf[NST]; 7754010Sfujita 7854010Sfujita #define stunit(x) (minor(x) & 3) 7954010Sfujita #define stpunit(x) ((x) & 7) 8054010Sfujita 8154010Sfujita #define STDEV_NOREWIND 0x04 8254010Sfujita 8354010Sfujita #define STRETRY 2 /* IO retry count */ 8454010Sfujita 8554010Sfujita struct st_iostat { 8654010Sfujita int imax; 8754010Sfujita int imin; 8854010Sfujita int omax; 8954010Sfujita int omin; 9054010Sfujita }; 9154010Sfujita 9254010Sfujita struct st_iostat st_iostat[NST]; 9354010Sfujita 9454010Sfujita 9554010Sfujita /* 9654010Sfujita * Initialize 9754010Sfujita */ 9854010Sfujita 9954010Sfujita int 10054010Sfujita stinit(hd) 10154010Sfujita register struct hp_device *hd; 10254010Sfujita { 10354010Sfujita register struct st_softc *sc = &st_softc[hd->hp_unit]; 10454010Sfujita 10554010Sfujita sc->sc_hd = hd; 10654010Sfujita sc->sc_punit = stpunit(hd->hp_flags); 10754010Sfujita sc->sc_type = stident(sc, hd); 10854010Sfujita if (sc->sc_type < 0) 10954010Sfujita return(0); 11054010Sfujita sc->sc_dq.dq_ctlr = hd->hp_ctlr; 11154010Sfujita sc->sc_dq.dq_unit = hd->hp_unit; 11254010Sfujita sc->sc_dq.dq_slave = hd->hp_slave; 11354010Sfujita sc->sc_dq.dq_driver = &stdriver; 11454010Sfujita sc->sc_flags = STF_ALIVE; 11554010Sfujita return(1); 11654010Sfujita } 11754010Sfujita 11854010Sfujita static struct scsi_inquiry inqbuf; 11954010Sfujita static struct scsi_fmt_cdb inq = { 12054010Sfujita 6, 12154010Sfujita CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 12254010Sfujita }; 12354010Sfujita 12454010Sfujita int 12554010Sfujita stident(sc, hd) 12654010Sfujita struct st_softc *sc; 12754010Sfujita struct hp_device *hd; 12854010Sfujita { 12954010Sfujita char idstr[32]; 13054010Sfujita int unit; 13154010Sfujita register int ctlr, slave; 13254010Sfujita register int i, stat; 13354010Sfujita register int tries = 10; 13454010Sfujita 13554010Sfujita ctlr = hd->hp_ctlr; 13654010Sfujita slave = hd->hp_slave; 13754010Sfujita unit = sc->sc_punit; 13854010Sfujita 13954010Sfujita /* 14054010Sfujita * See if unit exists and is a disk then read block size & nblocks. 14154010Sfujita */ 14254010Sfujita while ((stat = scsi_immed_command(ctlr, slave, unit, 14354010Sfujita &inq, (u_char *)&inqbuf, sizeof(inqbuf))) != 0) { 14454010Sfujita if (stat < 0 || --tries < 0) 14554010Sfujita return (-1); 14654010Sfujita DELAY(1000); 14754010Sfujita } 14854010Sfujita 14954010Sfujita switch (inqbuf.type) { 15054010Sfujita case 1: /* tape */ 15154010Sfujita break; 15254010Sfujita default: /* not a disk */ 15354010Sfujita printf("stident: inqbuf.type = %d\n", inqbuf.type); 15454010Sfujita return (-1); 15554010Sfujita } 15654010Sfujita 15754010Sfujita bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 15854010Sfujita for (i = 27; i > 23; --i) 15954010Sfujita if (idstr[i] != ' ') 16054010Sfujita break; 16154010Sfujita idstr[i+1] = 0; 16254010Sfujita for (i = 23; i > 7; --i) 16354010Sfujita if (idstr[i] != ' ') 16454010Sfujita break; 16554010Sfujita idstr[i+1] = 0; 16654010Sfujita for (i = 7; i >= 0; --i) 16754010Sfujita if (idstr[i] != ' ') 16854010Sfujita break; 16954010Sfujita idstr[i+1] = 0; 17054010Sfujita printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8], 17154010Sfujita &idstr[24]); 17254010Sfujita 17354010Sfujita return(inqbuf.type); 17454010Sfujita } 17554010Sfujita 17654010Sfujita 17754010Sfujita /* 17854010Sfujita * Open 17954010Sfujita */ 18054010Sfujita 18154010Sfujita int 18254010Sfujita stopen(dev, flag, type, p) 18354010Sfujita dev_t dev; 18454010Sfujita int flag, type; 18554010Sfujita struct proc *p; 18654010Sfujita { 18754010Sfujita register int unit = stunit(dev); 18854010Sfujita register struct st_softc *sc = &st_softc[unit]; 18954010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 19054010Sfujita int ctlr = sc->sc_dq.dq_ctlr; 19154010Sfujita int slave = sc->sc_dq.dq_slave; 19254010Sfujita int stat, retry = 9; 19354010Sfujita 19454010Sfujita if (unit >= NST || (sc->sc_flags & STF_ALIVE) == 0) 19554010Sfujita return(-1); 19654010Sfujita if (sc->sc_flags & STF_OPEN) 19754010Sfujita return(-1); 19854010Sfujita 19954010Sfujita /* drive ready ? */ 20054010Sfujita while ((stat = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) { 20154010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 20254010Sfujita 20354010Sfujita if (stat != STS_CHECKCOND) { 20454010Sfujita printf("st%d: stopen: %s\n", scsi_status(stat)); 20554010Sfujita return(EIO); 20654010Sfujita } 20754010Sfujita 20854010Sfujita if (retry-- < 0) { 20954010Sfujita printf("st%d: stopen: %s\n", sense_key(sp->key)); 21054010Sfujita return(EIO); 21154010Sfujita } 21254010Sfujita 21354010Sfujita DELAY(1000000); 21454010Sfujita } 21554010Sfujita 21654010Sfujita sc->sc_ctty = tprintf_open(p); 21754010Sfujita 21854010Sfujita sc->sc_flags |= STF_OPEN; 21954010Sfujita if (flag & FWRITE) 22054010Sfujita sc->sc_flags |= STF_WMODE; 22154010Sfujita sc->sc_flags &= ~STF_MOVED; 22254010Sfujita 22354010Sfujita return(0); 22454010Sfujita } 22554010Sfujita 22654010Sfujita /*ARGSUSED*/ 22754010Sfujita stclose(dev) 22854010Sfujita dev_t dev; 22954010Sfujita { 23054010Sfujita register int unit = stunit(dev); 23154010Sfujita register struct st_softc *sc = &st_softc[unit]; 23254010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 23354010Sfujita int ctlr = sc->sc_hd->hp_ctlr; 23454010Sfujita int slave = sc->sc_hd->hp_slave; 23554010Sfujita int stat, retry = 9; 23654010Sfujita 23754010Sfujita if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) { 23854010Sfujita st_write_EOF(dev); 23954010Sfujita } 24054010Sfujita 24154010Sfujita if ((minor(dev) & STDEV_NOREWIND) == 0) { 24254010Sfujita st_rewind(dev); 24354010Sfujita } 24454010Sfujita 24554010Sfujita sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN); 24654010Sfujita 24754010Sfujita tprintf_close(sc->sc_ctty); 24854010Sfujita 24954010Sfujita return(0); 25054010Sfujita } 25154010Sfujita 25254010Sfujita /* 25354010Sfujita * Strategy 25454010Sfujita */ 25554010Sfujita 25654010Sfujita int 25754010Sfujita ststrategy(bp) 25854010Sfujita register struct buf *bp; 25954010Sfujita { 26054010Sfujita register int unit = stunit(bp->b_dev); 26154010Sfujita register struct buf *dp = &sttab[unit]; 26254010Sfujita int s; 26354010Sfujita 26454010Sfujita bp->av_forw = NULL; 26554010Sfujita 26654010Sfujita s = splbio(); 26754010Sfujita 26854010Sfujita if (dp->b_actf == NULL) 26954010Sfujita dp->b_actf = bp; 27054010Sfujita else 27154010Sfujita dp->b_actl->av_forw = bp; 27254010Sfujita 27354010Sfujita dp->b_actl = bp; 27454010Sfujita 27554010Sfujita if (dp->b_active == 0) { 27654010Sfujita dp->b_active = 1; 27754010Sfujita stustart(unit); 27854010Sfujita } 27954010Sfujita 28054010Sfujita splx(s); 28154010Sfujita } 28254010Sfujita 28354010Sfujita int 28454010Sfujita stustart(unit) 28554010Sfujita register int unit; 28654010Sfujita { 28754010Sfujita register struct st_softc *sc = &st_softc[unit]; 28854010Sfujita register struct hp_device *hp = sc->sc_hd; 28954010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 29054010Sfujita register struct buf *bp = sttab[unit].b_actf; 29154010Sfujita register struct scsi_fmt_cdb *cmd; 29254010Sfujita long nblks; 29354010Sfujita 29454010Sfujita cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd; 29554010Sfujita cmd->cdb[1] = 1; /* unknown setup */ 29654010Sfujita 29754010Sfujita if (bp->b_flags & B_READ) 29854010Sfujita sc->sc_flags &= ~STF_WRTTN; 29954010Sfujita else 30054010Sfujita sc->sc_flags |= STF_WRTTN; 30154010Sfujita 30254010Sfujita nblks = bp->b_bcount >> DEV_BSHIFT; 30354010Sfujita 30454010Sfujita if (bp->b_bcount % DEV_BSIZE) { 30554010Sfujita tprintf(sc->sc_ctty, 30654010Sfujita "st%d: I/O not block aligned %d/%ld\n", 30754010Sfujita unit, DEV_BSIZE, bp->b_bcount); 30854010Sfujita 30954010Sfujita bp->b_flags |= B_ERROR; 31054010Sfujita bp->b_error = EIO; 31154010Sfujita 31254010Sfujita sttab[unit].b_errcnt = 0; 31354010Sfujita sttab[unit].b_actf = bp->b_actf; 31454010Sfujita 31554010Sfujita bp->b_resid = 0; 31654010Sfujita 31754010Sfujita biodone(bp); 31854010Sfujita 31954010Sfujita if (sttab[unit].b_actf) { 32054010Sfujita stustart(unit); 32154010Sfujita } else { 32254010Sfujita sttab[unit].b_active = 0; 32354010Sfujita } 32454010Sfujita } 32554010Sfujita 32654010Sfujita *(u_char *)(&cmd->cdb[2]) = (u_char) (nblks >> 16); 32754010Sfujita *(u_char *)(&cmd->cdb[3]) = (u_char) (nblks >> 8); 32854010Sfujita *(u_char *)(&cmd->cdb[4]) = (u_char) nblks; 32954010Sfujita 33054010Sfujita cmd->cdb[5] = 0; /* unknown setup */ 33154010Sfujita 33254010Sfujita sc->sc_flags |= STF_MOVED; 33354010Sfujita 33454010Sfujita dq->dq_cdb = cmd; 33554010Sfujita dq->dq_bp = bp; 33654010Sfujita dq->dq_flags = 0; /* No Disconnect */ 33754010Sfujita 33854010Sfujita if (screq(dq)) 33954010Sfujita ststart(unit); 34054010Sfujita } 34154010Sfujita 34254010Sfujita int 34354010Sfujita ststart(unit) 34454010Sfujita register int unit; 34554010Sfujita { 34654010Sfujita register struct st_softc *sc = &st_softc[unit]; 34754010Sfujita register struct hp_device *hp = sc->sc_hd; 34854010Sfujita 34954010Sfujita scstart(hp->hp_ctlr); 35054010Sfujita } 35154010Sfujita 35254010Sfujita /* 35354010Sfujita * Interrupt 35454010Sfujita */ 35554010Sfujita 35654010Sfujita char * 35754010Sfujita sense_key(key) 35854010Sfujita int key; 35954010Sfujita { 36054010Sfujita if (key == 0) 36154010Sfujita return("No Sense"); 36254010Sfujita else if (key == 2) 36354010Sfujita return("Not Ready"); 36454010Sfujita else if (key == 3) 36554010Sfujita return("Medium Error"); 36654010Sfujita else if (key == 4) 36754010Sfujita return("Hardware Error"); 36854010Sfujita else if (key == 5) 36954010Sfujita return("Illegal Request"); 37054010Sfujita else if (key == 6) 37154010Sfujita return("Unit Attention"); 37254010Sfujita else if (key == 7) 37354010Sfujita return("Data Protect"); 37454010Sfujita else if (key == 8) 37554010Sfujita return("No Data"); 37654010Sfujita else if (key == 11) 37754010Sfujita return("Aborted Command"); 37854010Sfujita else if (key == 13) 37954010Sfujita return("Volume Overflow"); 38054010Sfujita else 38154010Sfujita return("Unknown Error"); 38254010Sfujita } 38354010Sfujita 38454010Sfujita int 38554010Sfujita stintr(unit, stat) 38654010Sfujita register int unit; 38754010Sfujita int stat; 38854010Sfujita { 38954010Sfujita register struct st_softc *sc = &st_softc[unit]; 39054010Sfujita register struct scsi_xsense *xp = (struct scsi_xsense *) xsense_buff; 39154010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 39254010Sfujita register struct buf *bp = dq->dq_bp; 39354010Sfujita int ctlr = dq->dq_ctlr; 39454010Sfujita int slave = dq->dq_slave; 39554010Sfujita 39654010Sfujita if (bp->b_flags & B_READ) { 397*55177Saki st_iostat[unit].imin = min(dq->dq_imin, st_iostat[unit].imin); 39854010Sfujita if (dq->dq_imax > st_iostat[unit].imax) { 39954010Sfujita st_iostat[unit].imax = dq->dq_imax; 40054010Sfujita #ifdef ST_IOSTAT 40154010Sfujita printf("stintr: st%d INPUT MAX = %d, MIN = %d\n", 40254010Sfujita unit, st_iostat[unit].imax, st_iostat[unit].imin); 40354010Sfujita #endif 40454010Sfujita } 40554010Sfujita } else { 406*55177Saki st_iostat[unit].omin = min(dq->dq_omin, st_iostat[unit].omin); 40754010Sfujita if (dq->dq_omax > st_iostat[unit].omax) { 40854010Sfujita st_iostat[unit].omax = dq->dq_omax; 40954010Sfujita #ifdef ST_IOSTAT 41054010Sfujita printf("stintr: st%d OUTPUT MAX = %d, MIN = %d\n", 41154010Sfujita unit, st_iostat[unit].omax, st_iostat[unit].omin); 41254010Sfujita #endif 41354010Sfujita } 41454010Sfujita } 41554010Sfujita if (stat < 0) { 41654010Sfujita bp->b_flags |= B_ERROR; 41754010Sfujita bp->b_error = EIO; 41854010Sfujita goto done; 41954010Sfujita } 42054010Sfujita 42154010Sfujita switch (stat) { 42254010Sfujita /* scsi command completed ok */ 42354010Sfujita case 0: 42454010Sfujita bp->b_resid = 0; 42554010Sfujita break; 42654010Sfujita 42754010Sfujita /* more status */ 42854010Sfujita case STS_CHECKCOND: 42954010Sfujita scsi_request_sense(ctlr, slave, 0, xp, 8); 43054010Sfujita #ifdef DEBUG 43154010Sfujita printf("stintr: xsense_buff[0] = 0x%s\n", hexstr(xsense_buff[0], 2)); 43254010Sfujita printf("stintr: xsense_buff[2] = 0x%s\n", hexstr(xsense_buff[2], 2)); 43354010Sfujita printf("stintr: Sense Key = [%s]\n", sense_key(xp->key)); 43454010Sfujita #endif 43554010Sfujita if (xp->valid) { 43654010Sfujita bp->b_resid = (u_long)((xp->info1 << 24) | 43754010Sfujita (xp->info2 << 16) | 43854010Sfujita (xp->info3 << 8) | 43954010Sfujita (xp->info4)); 44054010Sfujita bp->b_resid <<= DEV_BSHIFT; 44154010Sfujita } 44254010Sfujita 44354010Sfujita if (xp->filemark) { /* End of File */ 44454010Sfujita tprintf(sc->sc_ctty, "st%d: End of File\n", unit); 44554010Sfujita bp->b_flags |= B_ERROR; 44654010Sfujita bp->b_error = EIO; 44754010Sfujita break; 44854010Sfujita } 44954010Sfujita 45054010Sfujita if (xp->key) { 45154010Sfujita tprintf(sc->sc_ctty, "st%d: %s\n", unit, sense_key(xp->key)); 45254010Sfujita bp->b_flags |= B_ERROR; 45354010Sfujita bp->b_error = EIO; 45454010Sfujita break; 45554010Sfujita } 45654010Sfujita 45754010Sfujita if (xp->eom) { /* End of TAPE */ 45854010Sfujita tprintf(sc->sc_ctty, "st%d: End of Tape\n", unit); 45954010Sfujita bp->b_flags |= B_ERROR; 46054010Sfujita bp->b_error = ENOSPC; 46154010Sfujita break; 46254010Sfujita } 46354010Sfujita 46454010Sfujita tprintf(sc->sc_ctty, "st%d: unknown scsi error\n", unit); 46554010Sfujita bp->b_flags |= B_ERROR; 46654010Sfujita bp->b_error = EIO; 46754010Sfujita break; 46854010Sfujita 46954010Sfujita default: 47054010Sfujita printf("st%d: stintr unknown stat 0x%x\n", unit, stat); 47154010Sfujita break; 47254010Sfujita } 47354010Sfujita 47454010Sfujita done: 47554010Sfujita sttab[unit].b_errcnt = 0; 47654010Sfujita sttab[unit].b_actf = bp->b_actf; 47754010Sfujita 47854010Sfujita bp->b_resid = 0; 47954010Sfujita 48054010Sfujita biodone(bp); 48154010Sfujita 48254010Sfujita scfree(&sc->sc_dq); 48354010Sfujita 48454010Sfujita if (sttab[unit].b_actf) { 48554010Sfujita stustart(unit); 48654010Sfujita } else { 48754010Sfujita sttab[unit].b_active = 0; 48854010Sfujita } 48954010Sfujita } 49054010Sfujita 49154010Sfujita 49254010Sfujita /* 49354010Sfujita * RAW Device Routines 49454010Sfujita */ 49554010Sfujita 49654010Sfujita 49754010Sfujita stread(dev, uio) 49854010Sfujita dev_t dev; 49954010Sfujita struct uio *uio; 50054010Sfujita { 50154010Sfujita int unit = stunit(dev); 50254010Sfujita 50354010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_READ, minphys, uio)); 50454010Sfujita } 50554010Sfujita 50654010Sfujita stwrite(dev, uio) 50754010Sfujita dev_t dev; 50854010Sfujita struct uio *uio; 50954010Sfujita { 51054010Sfujita int unit = stunit(dev); 51154010Sfujita 51254010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio)); 51354010Sfujita } 51454010Sfujita 51554010Sfujita int 51654010Sfujita stioctl(dev, cmd, data, flag, p) 51754010Sfujita dev_t dev; 51854010Sfujita int cmd; 51954010Sfujita caddr_t data; 52054010Sfujita int flag; 52154010Sfujita struct proc *p; 52254010Sfujita { 52354010Sfujita return(ENXIO); 52454010Sfujita } 52554010Sfujita 52654010Sfujita struct scsi_fmt_cdb st_cmd; 52754010Sfujita 52854010Sfujita st_rewind(dev) 52954010Sfujita dev_t dev; 53054010Sfujita { 53154010Sfujita register int unit = stunit(dev); 53254010Sfujita register struct st_softc *sc = &st_softc[unit]; 53354010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 53454010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 53554010Sfujita int ctlr, slave, stat; 53654010Sfujita int retry = 9; 53754010Sfujita 53854010Sfujita ctlr = sc->sc_hd->hp_ctlr; 53954010Sfujita slave = sc->sc_hd->hp_slave; 54054010Sfujita 54154010Sfujita cdb->len = 6; 54254010Sfujita 54354010Sfujita cdb->cdb[0] = CMD_REWIND; 54454010Sfujita 54554010Sfujita cdb->cdb[1] = 1; /* command finished soon */ 54654010Sfujita 54754010Sfujita cdb->cdb[2] = 0; 54854010Sfujita cdb->cdb[3] = 0; 54954010Sfujita cdb->cdb[4] = 0; 55054010Sfujita 55154010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 55254010Sfujita 55354010Sfujita rewind: 55454010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 55554010Sfujita 55654010Sfujita if (stat == 0) { 55754010Sfujita return(1); 55854010Sfujita } else { 55954010Sfujita printf("st: rewind error\n"); 56054010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 56154010Sfujita printf("st: status = 0x%x, sens key = 0x%x\n", stat, sp->key); 56254010Sfujita 56354010Sfujita if (retry > 0) { 56454010Sfujita DELAY(1000000); 56554010Sfujita retry--; 56654010Sfujita goto rewind; 56754010Sfujita } 56854010Sfujita 56954010Sfujita return(0); 57054010Sfujita } 57154010Sfujita } 57254010Sfujita 57354010Sfujita st_write_EOF(dev) 57454010Sfujita dev_t dev; 57554010Sfujita { 57654010Sfujita register int unit = stunit(dev); 57754010Sfujita register struct st_softc *sc = &st_softc[unit]; 57854010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 57954010Sfujita int ctlr, slave, stat; 58054010Sfujita int marks = 1; 58154010Sfujita 58254010Sfujita ctlr = sc->sc_hd->hp_ctlr; 58354010Sfujita slave = sc->sc_hd->hp_slave; 58454010Sfujita 58554010Sfujita cdb->len = 6; 58654010Sfujita 58754010Sfujita cdb->cdb[0] = CMD_WRITE_FILEMARK; 58854010Sfujita 58954010Sfujita cdb->cdb[1] = 0; 59054010Sfujita 59154010Sfujita cdb->cdb[2] = 0; 59254010Sfujita cdb->cdb[3] = 0; 59354010Sfujita cdb->cdb[4] = marks; 59454010Sfujita 59554010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 59654010Sfujita 59754010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 59854010Sfujita 59954010Sfujita if (stat == 0) 60054010Sfujita return(1); 60154010Sfujita 60254010Sfujita printf("st: write EOF error\n"); 60354010Sfujita 60454010Sfujita return(0); 60554010Sfujita } 60654010Sfujita 60754010Sfujita /* 60854010Sfujita * Dump 60954010Sfujita */ 61054010Sfujita 61154010Sfujita int 61254010Sfujita stdump(dev) 61354010Sfujita dev_t dev; 61454010Sfujita { 61554010Sfujita } 61654010Sfujita #endif 617