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*57127Sakito * @(#)st.c 7.5 (Berkeley) 12/14/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 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]; 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 200*57127Sakito sc->sc_ctty = tprintf_open(p); 201*57127Sakito 20254010Sfujita /* drive ready ? */ 20354010Sfujita while ((stat = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) { 20454010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 20554010Sfujita 20654010Sfujita if (stat != STS_CHECKCOND) { 207*57127Sakito tprintf(sc->sc_ctty, 208*57127Sakito "st%d:[stopen] %s\n", unit, scsi_status(stat)); 209*57127Sakito tprintf_close(sc->sc_ctty); 21054010Sfujita return(EIO); 21154010Sfujita } 21254010Sfujita 21354010Sfujita if (retry-- < 0) { 214*57127Sakito tprintf(sc->sc_ctty, 215*57127Sakito "st%d:[stopen] %s\n", unit, sense_key(sp->key)); 216*57127Sakito tprintf_close(sc->sc_ctty); 21754010Sfujita return(EIO); 21854010Sfujita } 21954010Sfujita 22054010Sfujita DELAY(1000000); 22154010Sfujita } 22254010Sfujita 22354010Sfujita sc->sc_flags |= STF_OPEN; 22454010Sfujita if (flag & FWRITE) 22554010Sfujita sc->sc_flags |= STF_WMODE; 22654010Sfujita sc->sc_flags &= ~STF_MOVED; 22754010Sfujita 22854010Sfujita return(0); 22954010Sfujita } 23054010Sfujita 23154010Sfujita /*ARGSUSED*/ 23254010Sfujita stclose(dev) 23354010Sfujita dev_t dev; 23454010Sfujita { 23554010Sfujita register int unit = stunit(dev); 23654010Sfujita register struct st_softc *sc = &st_softc[unit]; 23754010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 23854010Sfujita int ctlr = sc->sc_hd->hp_ctlr; 23954010Sfujita int slave = sc->sc_hd->hp_slave; 24054010Sfujita int stat, retry = 9; 24154010Sfujita 24254010Sfujita if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) { 24354010Sfujita st_write_EOF(dev); 24454010Sfujita } 24554010Sfujita 24654010Sfujita if ((minor(dev) & STDEV_NOREWIND) == 0) { 24754010Sfujita st_rewind(dev); 24854010Sfujita } 24954010Sfujita 25054010Sfujita sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN); 25154010Sfujita 25254010Sfujita tprintf_close(sc->sc_ctty); 25354010Sfujita 25454010Sfujita return(0); 25554010Sfujita } 25654010Sfujita 25754010Sfujita /* 25854010Sfujita * Strategy 25954010Sfujita */ 26054010Sfujita 26154010Sfujita int 26254010Sfujita ststrategy(bp) 26354010Sfujita register struct buf *bp; 26454010Sfujita { 26554010Sfujita register int unit = stunit(bp->b_dev); 26654010Sfujita register struct buf *dp = &sttab[unit]; 26754010Sfujita int s; 26854010Sfujita 26954010Sfujita bp->av_forw = NULL; 27054010Sfujita 27154010Sfujita s = splbio(); 27254010Sfujita 27354010Sfujita if (dp->b_actf == NULL) 27454010Sfujita dp->b_actf = bp; 27554010Sfujita else 27654010Sfujita dp->b_actl->av_forw = bp; 27754010Sfujita 27854010Sfujita dp->b_actl = bp; 27954010Sfujita 28054010Sfujita if (dp->b_active == 0) { 28154010Sfujita dp->b_active = 1; 28254010Sfujita stustart(unit); 28354010Sfujita } 28454010Sfujita 28554010Sfujita splx(s); 28654010Sfujita } 28754010Sfujita 28854010Sfujita int 28954010Sfujita stustart(unit) 29054010Sfujita register int unit; 29154010Sfujita { 29254010Sfujita register struct st_softc *sc = &st_softc[unit]; 29354010Sfujita register struct hp_device *hp = sc->sc_hd; 29454010Sfujita register struct scsi_queue *dq = &sc->sc_dq; 29554010Sfujita register struct buf *bp = sttab[unit].b_actf; 29654010Sfujita register struct scsi_fmt_cdb *cmd; 29754010Sfujita long nblks; 29854010Sfujita 29954010Sfujita cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd; 30054010Sfujita cmd->cdb[1] = 1; /* unknown setup */ 30154010Sfujita 30254010Sfujita if (bp->b_flags & B_READ) 30354010Sfujita sc->sc_flags &= ~STF_WRTTN; 30454010Sfujita else 30554010Sfujita sc->sc_flags |= STF_WRTTN; 30654010Sfujita 30754010Sfujita nblks = bp->b_bcount >> DEV_BSHIFT; 30854010Sfujita 30954010Sfujita if (bp->b_bcount % DEV_BSIZE) { 31054010Sfujita tprintf(sc->sc_ctty, 311*57127Sakito "st%d:[stustart] I/O not block aligned %d/%ld\n", 31254010Sfujita unit, DEV_BSIZE, bp->b_bcount); 31354010Sfujita 31454010Sfujita bp->b_flags |= B_ERROR; 31554010Sfujita bp->b_error = EIO; 31654010Sfujita 31754010Sfujita sttab[unit].b_errcnt = 0; 31854010Sfujita sttab[unit].b_actf = bp->b_actf; 31954010Sfujita 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; 39754010Sfujita register struct buf *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 */ 449*57127Sakito /* 450*57127Sakito tprintf(sc->sc_ctty, "st%d:[stintr] End of File\n", unit); 45154010Sfujita bp->b_flags |= B_ERROR; 45254010Sfujita bp->b_error = EIO; 453*57127Sakito */ 45454010Sfujita break; 45554010Sfujita } 45654010Sfujita 45754010Sfujita if (xp->key) { 458*57127Sakito 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 */ 465*57127Sakito 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 471*57127Sakito 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: 477*57127Sakito 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; 48354010Sfujita sttab[unit].b_actf = bp->b_actf; 48454010Sfujita 48554010Sfujita bp->b_resid = 0; 48654010Sfujita 48754010Sfujita biodone(bp); 48854010Sfujita 48954010Sfujita scfree(&sc->sc_dq); 49054010Sfujita 49154010Sfujita if (sttab[unit].b_actf) { 49254010Sfujita stustart(unit); 49354010Sfujita } else { 49454010Sfujita sttab[unit].b_active = 0; 49554010Sfujita } 49654010Sfujita } 49754010Sfujita 49854010Sfujita 49954010Sfujita /* 50054010Sfujita * RAW Device Routines 50154010Sfujita */ 50254010Sfujita 50354010Sfujita 50454010Sfujita stread(dev, uio) 50554010Sfujita dev_t dev; 50654010Sfujita struct uio *uio; 50754010Sfujita { 50854010Sfujita int unit = stunit(dev); 50954010Sfujita 51054010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_READ, minphys, uio)); 51154010Sfujita } 51254010Sfujita 51354010Sfujita stwrite(dev, uio) 51454010Sfujita dev_t dev; 51554010Sfujita struct uio *uio; 51654010Sfujita { 51754010Sfujita int unit = stunit(dev); 51854010Sfujita 51954010Sfujita return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio)); 52054010Sfujita } 52154010Sfujita 52254010Sfujita int 52354010Sfujita stioctl(dev, cmd, data, flag, p) 52454010Sfujita dev_t dev; 52554010Sfujita int cmd; 52654010Sfujita caddr_t data; 52754010Sfujita int flag; 52854010Sfujita struct proc *p; 52954010Sfujita { 53054010Sfujita return(ENXIO); 53154010Sfujita } 53254010Sfujita 53354010Sfujita struct scsi_fmt_cdb st_cmd; 53454010Sfujita 53554010Sfujita st_rewind(dev) 53654010Sfujita dev_t dev; 53754010Sfujita { 53854010Sfujita register int unit = stunit(dev); 53954010Sfujita register struct st_softc *sc = &st_softc[unit]; 54054010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 54154010Sfujita register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff; 54254010Sfujita int ctlr, slave, stat; 54354010Sfujita int retry = 9; 54454010Sfujita 54554010Sfujita ctlr = sc->sc_hd->hp_ctlr; 54654010Sfujita slave = sc->sc_hd->hp_slave; 54754010Sfujita 54854010Sfujita cdb->len = 6; 54954010Sfujita 55054010Sfujita cdb->cdb[0] = CMD_REWIND; 55154010Sfujita 55254010Sfujita cdb->cdb[1] = 1; /* command finished soon */ 55354010Sfujita 55454010Sfujita cdb->cdb[2] = 0; 55554010Sfujita cdb->cdb[3] = 0; 55654010Sfujita cdb->cdb[4] = 0; 55754010Sfujita 55854010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 55954010Sfujita 56054010Sfujita rewind: 56154010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 56254010Sfujita 56354010Sfujita if (stat == 0) { 56454010Sfujita return(1); 56554010Sfujita } else { 566*57127Sakito tprintf(sc->sc_ctty, "st%d:[st_rewind] rewind error\n", unit); 56754010Sfujita scsi_request_sense(ctlr, slave, 0, sp, 8); 568*57127Sakito tprintf(sc->sc_ctty, 569*57127Sakito "st%d:[st_rewind] status = 0x%x, sens key = 0x%x\n", 570*57127Sakito unit, stat, sp->key); 57154010Sfujita 57254010Sfujita if (retry > 0) { 57354010Sfujita DELAY(1000000); 57454010Sfujita retry--; 57554010Sfujita goto rewind; 57654010Sfujita } 57754010Sfujita 57854010Sfujita return(0); 57954010Sfujita } 58054010Sfujita } 58154010Sfujita 58254010Sfujita st_write_EOF(dev) 58354010Sfujita dev_t dev; 58454010Sfujita { 58554010Sfujita register int unit = stunit(dev); 58654010Sfujita register struct st_softc *sc = &st_softc[unit]; 58754010Sfujita register struct scsi_fmt_cdb *cdb = &st_cmd; 58854010Sfujita int ctlr, slave, stat; 58954010Sfujita int marks = 1; 59054010Sfujita 59154010Sfujita ctlr = sc->sc_hd->hp_ctlr; 59254010Sfujita slave = sc->sc_hd->hp_slave; 59354010Sfujita 59454010Sfujita cdb->len = 6; 59554010Sfujita 59654010Sfujita cdb->cdb[0] = CMD_WRITE_FILEMARK; 59754010Sfujita 59854010Sfujita cdb->cdb[1] = 0; 59954010Sfujita 60054010Sfujita cdb->cdb[2] = 0; 60154010Sfujita cdb->cdb[3] = 0; 60254010Sfujita cdb->cdb[4] = marks; 60354010Sfujita 60454010Sfujita cdb->cdb[5] = 0; /* unknown setup */ 60554010Sfujita 60654010Sfujita stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0); 60754010Sfujita 60854010Sfujita if (stat == 0) 60954010Sfujita return(1); 61054010Sfujita 611*57127Sakito tprintf(sc->sc_ctty, "st%d:[st_write_EOF] write EOF error\n", unit); 61254010Sfujita 61354010Sfujita return(0); 61454010Sfujita } 61554010Sfujita 61654010Sfujita /* 61754010Sfujita * Dump 61854010Sfujita */ 61954010Sfujita 62054010Sfujita int 62154010Sfujita stdump(dev) 62254010Sfujita dev_t dev; 62354010Sfujita { 62454010Sfujita } 62554010Sfujita #endif 626