154010Sfujita /*
254010Sfujita * Copyright (c) 1992 OMRON Corporation.
363192Sbostic * Copyright (c) 1992, 1993
463192Sbostic * 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*65036Sakito * @(#)st.c 8.2 (Berkeley) 12/06/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>
34*65036Sakito #include <luna68k/dev/screg.h>
35*65036Sakito #include <luna68k/dev/scvar.h>
3654010Sfujita
37*65036Sakito extern int sc_test_unit_rdy();
38*65036Sakito extern int sc_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
stinit(hd)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
stident(sc,hd)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
stopen(dev,flag,type,p)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 ? */
206*65036Sakito while ((stat = sc_test_unit_rdy(ctlr, slave, 0)) != 0) {
207*65036Sakito sc_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*/
stclose(dev)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
ststrategy(bp)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
stustart(unit)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
ststart(unit)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 *
sense_key(key)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
stintr(unit,stat)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:
434*65036Sakito sc_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
stread(dev,uio)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
stwrite(dev,uio)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
stioctl(dev,cmd,data,flag,p)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
st_rewind(dev)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);
570*65036Sakito sc_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
st_write_EOF(dev)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
stdump(dev)62454010Sfujita stdump(dev)
62554010Sfujita dev_t dev;
62654010Sfujita {
62754010Sfujita }
62854010Sfujita #endif
629