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