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