xref: /csrg-svn/sys/luna68k/dev/st.c (revision 65036)
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