154010Sfujita /* 254010Sfujita * Copyright (c) 1992 OMRON Corporation. 3*63192Sbostic * Copyright (c) 1992, 1993 4*63192Sbostic * The Regents of the University of California. 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*63192Sbostic * @(#)st.c 8.1 (Berkeley) 06/10/93 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 2556519Sbostic #include <sys/param.h> 2656519Sbostic #include <sys/systm.h> 2756519Sbostic #include <sys/buf.h> 2856519Sbostic #include <sys/file.h> 2956519Sbostic #include <sys/proc.h> 3056519Sbostic #include <sys/mtio.h> 3156519Sbostic #include <sys/tprintf.h> 3254010Sfujita 3356519Sbostic #include <luna68k/dev/device.h> 3456519Sbostic #include <luna68k/dev/scsireg.h> 3556519Sbostic #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]; 10557358Sakito register struct buf *bp; 10654010Sfujita 10757358Sakito for (bp = sttab; bp < &sttab[NST]; bp++) 10857358Sakito bp->b_actb = &bp->b_actf; 10954010Sfujita sc->sc_hd = hd; 11054010Sfujita sc->sc_punit = stpunit(hd->hp_flags); 11154010Sfujita sc->sc_type = stident(sc, hd); 11254010Sfujita if (sc->sc_type < 0) 11354010Sfujita return(0); 11454010Sfujita sc->sc_dq.dq_ctlr = hd->hp_ctlr; 11554010Sfujita sc->sc_dq.dq_unit = hd->hp_unit; 11654010Sfujita sc->sc_dq.dq_slave = hd->hp_slave; 11754010Sfujita sc->sc_dq.dq_driver = &stdriver; 11854010Sfujita sc->sc_flags = STF_ALIVE; 11954010Sfujita return(1); 12054010Sfujita } 12154010Sfujita 12254010Sfujita static struct scsi_inquiry inqbuf; 12354010Sfujita static struct scsi_fmt_cdb inq = { 12454010Sfujita 6, 12554010Sfujita CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 12654010Sfujita }; 12754010Sfujita 12854010Sfujita int 12954010Sfujita stident(sc, hd) 13054010Sfujita struct st_softc *sc; 13154010Sfujita struct hp_device *hd; 13254010Sfujita { 13354010Sfujita char idstr[32]; 13454010Sfujita int unit; 13554010Sfujita register int ctlr, slave; 13654010Sfujita register int i, stat; 13754010Sfujita register int tries = 10; 13854010Sfujita 13954010Sfujita ctlr = hd->hp_ctlr; 14054010Sfujita slave = hd->hp_slave; 14154010Sfujita unit = sc->sc_punit; 14254010Sfujita 14354010Sfujita /* 14454010Sfujita * See if unit exists and is a disk then read block size & nblocks. 14554010Sfujita */ 14654010Sfujita while ((stat = scsi_immed_command(ctlr, slave, unit, 14754010Sfujita &inq, (u_char *)&inqbuf, sizeof(inqbuf))) != 0) { 14854010Sfujita if (stat < 0 || --tries < 0) 14954010Sfujita return (-1); 15054010Sfujita DELAY(1000); 15154010Sfujita } 15254010Sfujita 15354010Sfujita switch (inqbuf.type) { 15454010Sfujita case 1: /* tape */ 15554010Sfujita break; 15654010Sfujita default: /* not a disk */ 15754010Sfujita printf("stident: inqbuf.type = %d\n", inqbuf.type); 15854010Sfujita return (-1); 15954010Sfujita } 16054010Sfujita 16154010Sfujita bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28); 16254010Sfujita for (i = 27; i > 23; --i) 16354010Sfujita if (idstr[i] != ' ') 16454010Sfujita break; 16554010Sfujita idstr[i+1] = 0; 16654010Sfujita for (i = 23; i > 7; --i) 16754010Sfujita if (idstr[i] != ' ') 16854010Sfujita break; 16954010Sfujita idstr[i+1] = 0; 17054010Sfujita for (i = 7; i >= 0; --i) 17154010Sfujita if (idstr[i] != ' ') 17254010Sfujita break; 17354010Sfujita idstr[i+1] = 0; 17454010Sfujita printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8], 17554010Sfujita &idstr[24]); 17654010Sfujita 17754010Sfujita return(inqbuf.type); 17854010Sfujita } 17954010Sfujita 18054010Sfujita 18154010Sfujita /* 18254010Sfujita * Open 18354010Sfujita */ 18454010Sfujita 18554010Sfujita int 18654010Sfujita stopen(dev, flag, type, p) 18754010Sfujita dev_t dev; 18854010Sfujita int flag, type; 18954010Sfujita struct proc *p; 19054010Sfujita { 19154010Sfujita register int unit = stunit(dev); 19254010Sfujita register struct st_softc *sc = &st_softc[unit]; 19354010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 19454010Sfujita int ctlr = sc->sc_dq.dq_ctlr; 19554010Sfujita int slave = sc->sc_dq.dq_slave; 19654010Sfujita int stat, retry = 9; 19754010Sfujita 19854010Sfujita if (unit >= NST || (sc->sc_flags & STF_ALIVE) == 0) 19954010Sfujita return(-1); 20054010Sfujita if (sc->sc_flags & STF_OPEN) 20154010Sfujita return(-1); 20254010Sfujita 20357127Sakito sc->sc_ctty = tprintf_open(p); 20457127Sakito 20554010Sfujita /* drive ready ? */ 20654010Sfujita while ((stat = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) { 20754010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 20854010Sfujita 20954010Sfujita if (stat != STS_CHECKCOND) { 21057127Sakito tprintf(sc->sc_ctty, 21157127Sakito "st%d:[stopen] %s\n", unit, scsi_status(stat)); 21257127Sakito tprintf_close(sc->sc_ctty); 21354010Sfujita return(EIO); 21454010Sfujita } 21554010Sfujita 21654010Sfujita if (retry-- < 0) { 21757127Sakito tprintf(sc->sc_ctty, 21857127Sakito "st%d:[stopen] %s\n", unit, sense_key(sp->key)); 21957127Sakito tprintf_close(sc->sc_ctty); 22054010Sfujita return(EIO); 22154010Sfujita } 22254010Sfujita 22354010Sfujita DELAY(1000000); 22454010Sfujita } 22554010Sfujita 22654010Sfujita sc->sc_flags |= STF_OPEN; 22754010Sfujita if (flag & FWRITE) 22854010Sfujita sc->sc_flags |= STF_WMODE; 22954010Sfujita sc->sc_flags &= ~STF_MOVED; 23054010Sfujita 23154010Sfujita return(0); 23254010Sfujita } 23354010Sfujita 23454010Sfujita /*ARGSUSED*/ 23554010Sfujita stclose(dev) 23654010Sfujita dev_t dev; 23754010Sfujita { 23854010Sfujita register int unit = stunit(dev); 23954010Sfujita register struct st_softc *sc = &st_softc[unit]; 24054010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 24154010Sfujita int ctlr = sc->sc_hd->hp_ctlr; 24254010Sfujita int slave = sc->sc_hd->hp_slave; 24354010Sfujita int stat, retry = 9; 24454010Sfujita 24554010Sfujita if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) { 24654010Sfujita st_write_EOF(dev); 24754010Sfujita } 24854010Sfujita 24954010Sfujita if ((minor(dev) & STDEV_NOREWIND) == 0) { 25054010Sfujita st_rewind(dev); 25154010Sfujita } 25254010Sfujita 25354010Sfujita sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN); 25454010Sfujita 25554010Sfujita tprintf_close(sc->sc_ctty); 25654010Sfujita 25754010Sfujita return(0); 25854010Sfujita } 25954010Sfujita 26054010Sfujita /* 26154010Sfujita * Strategy 26254010Sfujita */ 26354010Sfujita 26454010Sfujita int 26554010Sfujita ststrategy(bp) 26654010Sfujita register struct buf *bp; 26754010Sfujita { 26854010Sfujita register int unit = stunit(bp->b_dev); 26954010Sfujita register struct buf *dp = &sttab[unit]; 27054010Sfujita int s; 27154010Sfujita 27257358Sakito bp->b_actf = NULL; 27354010Sfujita s = splbio(); 27457358Sakito bp->b_actb = dp->b_actb; 27557358Sakito *dp->b_actb = bp; 27657358Sakito dp->b_actb = &bp->b_actf; 27754010Sfujita if (dp->b_active == 0) { 27854010Sfujita dp->b_active = 1; 27954010Sfujita stustart(unit); 28054010Sfujita } 28154010Sfujita 28254010Sfujita splx(s); 28354010Sfujita } 28454010Sfujita 28554010Sfujita int 28654010Sfujita stustart(unit) 28754010Sfujita register int unit; 28854010Sfujita { 28954010Sfujita register struct st_softc *sc = &st_softc[unit]; 29054010Sfujita register struct hp_device *hp = sc->sc_hd; 29154010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 29257358Sakito register struct buf *dp, *bp = sttab[unit].b_actf; 29354010Sfujita register struct scsi_fmt_cdb *cmd; 29454010Sfujita long nblks; 29554010Sfujita 29654010Sfujita cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd; 29754010Sfujita cmd->cdb[1] = 1; /* unknown setup */ 29854010Sfujita 29954010Sfujita if (bp->b_flags & B_READ) 30054010Sfujita sc->sc_flags &= ~STF_WRTTN; 30154010Sfujita else 30254010Sfujita sc->sc_flags |= STF_WRTTN; 30354010Sfujita 30454010Sfujita nblks = bp->b_bcount >> DEV_BSHIFT; 30554010Sfujita 30654010Sfujita if (bp->b_bcount % DEV_BSIZE) { 30754010Sfujita tprintf(sc->sc_ctty, 30857127Sakito "st%d:[stustart] I/O not block aligned %d/%ld\n", 30954010Sfujita unit, DEV_BSIZE, bp->b_bcount); 31054010Sfujita 31154010Sfujita bp->b_flags |= B_ERROR; 31254010Sfujita bp->b_error = EIO; 31354010Sfujita 31454010Sfujita sttab[unit].b_errcnt = 0; 31557358Sakito if (dp = bp->b_actf) 31657358Sakito dp->b_actb = bp->b_actb; 31757358Sakito else 31857358Sakito sttab[unit].b_actb = bp->b_actb; 31957358Sakito *bp->b_actb = dp; 32054010Sfujita bp->b_resid = 0; 32154010Sfujita 32254010Sfujita biodone(bp); 32354010Sfujita 32454010Sfujita if (sttab[unit].b_actf) { 32554010Sfujita stustart(unit); 32654010Sfujita } else { 32754010Sfujita sttab[unit].b_active = 0; 32854010Sfujita } 32954010Sfujita } 33054010Sfujita 33154010Sfujita *(u_char *)(&cmd->cdb[2]) = (u_char) (nblks >> 16); 33254010Sfujita *(u_char *)(&cmd->cdb[3]) = (u_char) (nblks >> 8); 33354010Sfujita *(u_char *)(&cmd->cdb[4]) = (u_char) nblks; 33454010Sfujita 33554010Sfujita cmd->cdb[5] = 0; /* unknown setup */ 33654010Sfujita 33754010Sfujita sc->sc_flags |= STF_MOVED; 33854010Sfujita 33954010Sfujita dq->dq_cdb = cmd; 34054010Sfujita dq->dq_bp = bp; 34154010Sfujita dq->dq_flags = 0; /* No Disconnect */ 34254010Sfujita 34354010Sfujita if (screq(dq)) 34454010Sfujita ststart(unit); 34554010Sfujita } 34654010Sfujita 34754010Sfujita int 34854010Sfujita ststart(unit) 34954010Sfujita register int unit; 35054010Sfujita { 35154010Sfujita register struct st_softc *sc = &st_softc[unit]; 35254010Sfujita register struct hp_device *hp = sc->sc_hd; 35354010Sfujita 35454010Sfujita scstart(hp->hp_ctlr); 35554010Sfujita } 35654010Sfujita 35754010Sfujita /* 35854010Sfujita * Interrupt 35954010Sfujita */ 36054010Sfujita 36154010Sfujita char * 36254010Sfujita sense_key(key) 36354010Sfujita int key; 36454010Sfujita { 36554010Sfujita if (key == 0) 36654010Sfujita return("No Sense"); 36754010Sfujita else if (key == 2) 36854010Sfujita return("Not Ready"); 36954010Sfujita else if (key == 3) 37054010Sfujita return("Medium Error"); 37154010Sfujita else if (key == 4) 37254010Sfujita return("Hardware Error"); 37354010Sfujita else if (key == 5) 37454010Sfujita return("Illegal Request"); 37554010Sfujita else if (key == 6) 37654010Sfujita return("Unit Attention"); 37754010Sfujita else if (key == 7) 37854010Sfujita return("Data Protect"); 37954010Sfujita else if (key == 8) 38054010Sfujita return("No Data"); 38154010Sfujita else if (key == 11) 38254010Sfujita return("Aborted Command"); 38354010Sfujita else if (key == 13) 38454010Sfujita return("Volume Overflow"); 38554010Sfujita else 38654010Sfujita return("Unknown Error"); 38754010Sfujita } 38854010Sfujita 38954010Sfujita int 39054010Sfujita stintr(unit, stat) 39154010Sfujita register int unit; 39254010Sfujita int stat; 39354010Sfujita { 39454010Sfujita register struct st_softc *sc = &st_softc[unit]; 39554010Sfujita register struct scsi_xsense *xp = (struct scsi_xsense *) xsense_buff; 39654010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 39757358Sakito register struct buf *dp, *bp = dq->dq_bp; 39854010Sfujita int ctlr = dq->dq_ctlr; 39954010Sfujita int slave = dq->dq_slave; 40054010Sfujita 40154010Sfujita if (bp->b_flags & B_READ) { 40255177Saki st_iostat[unit].imin = min(dq->dq_imin, st_iostat[unit].imin); 40354010Sfujita if (dq->dq_imax > st_iostat[unit].imax) { 40454010Sfujita st_iostat[unit].imax = dq->dq_imax; 40554010Sfujita #ifdef ST_IOSTAT 40654010Sfujita printf("stintr: st%d INPUT MAX = %d, MIN = %d\n", 40754010Sfujita unit, st_iostat[unit].imax, st_iostat[unit].imin); 40854010Sfujita #endif 40954010Sfujita } 41054010Sfujita } else { 41155177Saki st_iostat[unit].omin = min(dq->dq_omin, st_iostat[unit].omin); 41254010Sfujita if (dq->dq_omax > st_iostat[unit].omax) { 41354010Sfujita st_iostat[unit].omax = dq->dq_omax; 41454010Sfujita #ifdef ST_IOSTAT 41554010Sfujita printf("stintr: st%d OUTPUT MAX = %d, MIN = %d\n", 41654010Sfujita unit, st_iostat[unit].omax, st_iostat[unit].omin); 41754010Sfujita #endif 41854010Sfujita } 41954010Sfujita } 42054010Sfujita if (stat < 0) { 42154010Sfujita bp->b_flags |= B_ERROR; 42254010Sfujita bp->b_error = EIO; 42354010Sfujita goto done; 42454010Sfujita } 42554010Sfujita 42654010Sfujita switch (stat) { 42754010Sfujita /* scsi command completed ok */ 42854010Sfujita case 0: 42954010Sfujita bp->b_resid = 0; 43054010Sfujita break; 43154010Sfujita 43254010Sfujita /* more status */ 43354010Sfujita case STS_CHECKCOND: 43454010Sfujita scsi_request_sense(ctlr, slave, 0, xp, 8); 43554010Sfujita #ifdef DEBUG 43654010Sfujita printf("stintr: xsense_buff[0] = 0x%s\n", hexstr(xsense_buff[0], 2)); 43754010Sfujita printf("stintr: xsense_buff[2] = 0x%s\n", hexstr(xsense_buff[2], 2)); 43854010Sfujita printf("stintr: Sense Key = [%s]\n", sense_key(xp->key)); 43954010Sfujita #endif 44054010Sfujita if (xp->valid) { 44154010Sfujita bp->b_resid = (u_long)((xp->info1 << 24) | 44254010Sfujita (xp->info2 << 16) | 44354010Sfujita (xp->info3 << 8) | 44454010Sfujita (xp->info4)); 44554010Sfujita bp->b_resid <<= DEV_BSHIFT; 44654010Sfujita } 44754010Sfujita 44854010Sfujita if (xp->filemark) { /* End of File */ 44957127Sakito /* 45057127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] End of File\n", unit); 45154010Sfujita bp->b_flags |= B_ERROR; 45254010Sfujita bp->b_error = EIO; 45357127Sakito */ 45454010Sfujita break; 45554010Sfujita } 45654010Sfujita 45754010Sfujita if (xp->key) { 45857127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] %s\n", unit, sense_key(xp->key)); 45954010Sfujita bp->b_flags |= B_ERROR; 46054010Sfujita bp->b_error = EIO; 46154010Sfujita break; 46254010Sfujita } 46354010Sfujita 46454010Sfujita if (xp->eom) { /* End of TAPE */ 46557127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] End of Tape\n", unit); 46654010Sfujita bp->b_flags |= B_ERROR; 46754010Sfujita bp->b_error = ENOSPC; 46854010Sfujita break; 46954010Sfujita } 47054010Sfujita 47157127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] unknown scsi error\n", unit); 47254010Sfujita bp->b_flags |= B_ERROR; 47354010Sfujita bp->b_error = EIO; 47454010Sfujita break; 47554010Sfujita 47654010Sfujita default: 47757127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] stintr unknown stat 0x%x\n", unit, stat); 47854010Sfujita break; 47954010Sfujita } 48054010Sfujita 48154010Sfujita done: 48254010Sfujita sttab[unit].b_errcnt = 0; 48357358Sakito if (dp = bp->b_actf) 48457358Sakito dp->b_actb = bp->b_actb; 48557358Sakito else 48657358Sakito sttab[unit].b_actb = bp->b_actb; 48757358Sakito *bp->b_actb = dp; 48854010Sfujita bp->b_resid = 0; 48954010Sfujita 49054010Sfujita biodone(bp); 49154010Sfujita 49254010Sfujita scfree(&sc->sc_dq); 49354010Sfujita 49454010Sfujita if (sttab[unit].b_actf) { 49554010Sfujita stustart(unit); 49654010Sfujita } else { 49754010Sfujita sttab[unit].b_active = 0; 49854010Sfujita } 49954010Sfujita } 50054010Sfujita 50154010Sfujita 50254010Sfujita /* 50354010Sfujita * RAW Device Routines 50454010Sfujita */ 50554010Sfujita 50654010Sfujita 50754010Sfujita stread(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_READ, minphys, uio)); 51454010Sfujita } 51554010Sfujita 51654010Sfujita stwrite(dev, uio) 51754010Sfujita dev_t dev; 51854010Sfujita struct uio *uio; 51954010Sfujita { 52054010Sfujita int unit = stunit(dev); 52154010Sfujita 52254010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio)); 52354010Sfujita } 52454010Sfujita 52554010Sfujita int 52654010Sfujita stioctl(dev, cmd, data, flag, p) 52754010Sfujita dev_t dev; 52854010Sfujita int cmd; 52954010Sfujita caddr_t data; 53054010Sfujita int flag; 53154010Sfujita struct proc *p; 53254010Sfujita { 53354010Sfujita return(ENXIO); 53454010Sfujita } 53554010Sfujita 53654010Sfujita struct scsi_fmt_cdb st_cmd; 53754010Sfujita 53854010Sfujita st_rewind(dev) 53954010Sfujita dev_t dev; 54054010Sfujita { 54154010Sfujita register int unit = stunit(dev); 54254010Sfujita register struct st_softc *sc = &st_softc[unit]; 54354010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 54454010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 54554010Sfujita int ctlr, slave, stat; 54654010Sfujita int retry = 9; 54754010Sfujita 54854010Sfujita ctlr = sc->sc_hd->hp_ctlr; 54954010Sfujita slave = sc->sc_hd->hp_slave; 55054010Sfujita 55154010Sfujita cdb->len = 6; 55254010Sfujita 55354010Sfujita cdb->cdb[0] = CMD_REWIND; 55454010Sfujita 55554010Sfujita cdb->cdb[1] = 1; /* command finished soon */ 55654010Sfujita 55754010Sfujita cdb->cdb[2] = 0; 55854010Sfujita cdb->cdb[3] = 0; 55954010Sfujita cdb->cdb[4] = 0; 56054010Sfujita 56154010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 56254010Sfujita 56354010Sfujita rewind: 56454010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 56554010Sfujita 56654010Sfujita if (stat == 0) { 56754010Sfujita return(1); 56854010Sfujita } else { 56957127Sakito tprintf(sc->sc_ctty, "st%d:[st_rewind] rewind error\n", unit); 57054010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 57157127Sakito tprintf(sc->sc_ctty, 57257127Sakito "st%d:[st_rewind] status = 0x%x, sens key = 0x%x\n", 57357127Sakito unit, stat, sp->key); 57454010Sfujita 57554010Sfujita if (retry > 0) { 57654010Sfujita DELAY(1000000); 57754010Sfujita retry--; 57854010Sfujita goto rewind; 57954010Sfujita } 58054010Sfujita 58154010Sfujita return(0); 58254010Sfujita } 58354010Sfujita } 58454010Sfujita 58554010Sfujita st_write_EOF(dev) 58654010Sfujita dev_t dev; 58754010Sfujita { 58854010Sfujita register int unit = stunit(dev); 58954010Sfujita register struct st_softc *sc = &st_softc[unit]; 59054010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 59154010Sfujita int ctlr, slave, stat; 59254010Sfujita int marks = 1; 59354010Sfujita 59454010Sfujita ctlr = sc->sc_hd->hp_ctlr; 59554010Sfujita slave = sc->sc_hd->hp_slave; 59654010Sfujita 59754010Sfujita cdb->len = 6; 59854010Sfujita 59954010Sfujita cdb->cdb[0] = CMD_WRITE_FILEMARK; 60054010Sfujita 60154010Sfujita cdb->cdb[1] = 0; 60254010Sfujita 60354010Sfujita cdb->cdb[2] = 0; 60454010Sfujita cdb->cdb[3] = 0; 60554010Sfujita cdb->cdb[4] = marks; 60654010Sfujita 60754010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 60854010Sfujita 60954010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 61054010Sfujita 61154010Sfujita if (stat == 0) 61254010Sfujita return(1); 61354010Sfujita 61457127Sakito tprintf(sc->sc_ctty, "st%d:[st_write_EOF] write EOF error\n", unit); 61554010Sfujita 61654010Sfujita return(0); 61754010Sfujita } 61854010Sfujita 61954010Sfujita /* 62054010Sfujita * Dump 62154010Sfujita */ 62254010Sfujita 62354010Sfujita int 62454010Sfujita stdump(dev) 62554010Sfujita dev_t dev; 62654010Sfujita { 62754010Sfujita } 62854010Sfujita #endif 629