xref: /csrg-svn/sys/luna68k/dev/st.c (revision 54010)
1*54010Sfujita /*
2*54010Sfujita  * Copyright (c) 1992 OMRON Corporation.
3*54010Sfujita  * Copyright (c) 1992 The Regents of the University of California.
4*54010Sfujita  * All rights reserved.
5*54010Sfujita  *
6*54010Sfujita  * This code is derived from software contributed to Berkeley by
7*54010Sfujita  * OMRON Corporation.
8*54010Sfujita  *
9*54010Sfujita  * %sccs.include.redist.c%
10*54010Sfujita  *
11*54010Sfujita  *	@(#)st.c	7.1 (Berkeley) 06/15/92
12*54010Sfujita  */
13*54010Sfujita 
14*54010Sfujita /*
15*54010Sfujita  * st.c -- TEAC MT-2ST/N60 SCSI TAPE UNIT Device Driver
16*54010Sfujita  * remaked by A.Fujita, MAR-22-1992
17*54010Sfujita  */
18*54010Sfujita 
19*54010Sfujita /*
20*54010Sfujita  * SCSI CCS (Command Command Set) disk driver.
21*54010Sfujita  */
22*54010Sfujita #include "st.h"
23*54010Sfujita #if NST > 0
24*54010Sfujita 
25*54010Sfujita #include "param.h"
26*54010Sfujita #include "buf.h"
27*54010Sfujita #include "file.h"
28*54010Sfujita #include "proc.h"
29*54010Sfujita #include "mtio.h"
30*54010Sfujita #include "tprintf.h"
31*54010Sfujita 
32*54010Sfujita #include "device.h"
33*54010Sfujita #include "scsireg.h"
34*54010Sfujita #include "scsivar.h"
35*54010Sfujita 
36*54010Sfujita extern int scsi_test_unit_rdy();
37*54010Sfujita extern int scsi_request_sense();
38*54010Sfujita extern int scsi_immed_command();
39*54010Sfujita extern char *scsi_status();
40*54010Sfujita 
41*54010Sfujita extern int scgo();
42*54010Sfujita extern void scfree();
43*54010Sfujita 
44*54010Sfujita char *sense_key();
45*54010Sfujita 
46*54010Sfujita int	stinit(), ststrategy(), ststart(), stintr();
47*54010Sfujita 
48*54010Sfujita struct	driver stdriver = {
49*54010Sfujita 	stinit, "st", ststart, (int (*)()) 0, stintr, (int (*)()) 0
50*54010Sfujita };
51*54010Sfujita 
52*54010Sfujita struct	st_softc {
53*54010Sfujita 	struct	hp_device *sc_hd;
54*54010Sfujita 	struct	scsi_queue sc_dq;
55*54010Sfujita 	int	sc_flags;
56*54010Sfujita 	short	sc_type;	/* drive type */
57*54010Sfujita 	short	sc_punit;	/* physical unit (scsi lun) */
58*54010Sfujita 	tpr_t	sc_ctty;
59*54010Sfujita } st_softc[NST];
60*54010Sfujita 
61*54010Sfujita /* softc flags */
62*54010Sfujita #define STF_ALIVE	0x0001
63*54010Sfujita #define STF_OPEN	0x0002
64*54010Sfujita #define STF_WMODE	0x0004
65*54010Sfujita #define STF_WRTTN	0x0008
66*54010Sfujita #define STF_CMD		0x0010
67*54010Sfujita #define STF_LEOT	0x0020
68*54010Sfujita #define STF_MOVED	0x0040
69*54010Sfujita 
70*54010Sfujita u_char xsense_buff[60];
71*54010Sfujita 
72*54010Sfujita struct scsi_fmt_cdb st_read_cmd  = { 6, CMD_READ  };
73*54010Sfujita struct scsi_fmt_cdb st_write_cmd = { 6, CMD_WRITE };
74*54010Sfujita 
75*54010Sfujita struct buf sttab[NST];
76*54010Sfujita struct buf stbuf[NST];
77*54010Sfujita 
78*54010Sfujita #define	stunit(x)	(minor(x) & 3)
79*54010Sfujita #define	stpunit(x)	((x) & 7)
80*54010Sfujita 
81*54010Sfujita #define STDEV_NOREWIND	0x04
82*54010Sfujita 
83*54010Sfujita #define	STRETRY		2	/* IO retry count */
84*54010Sfujita 
85*54010Sfujita struct st_iostat {
86*54010Sfujita 	int imax;
87*54010Sfujita 	int imin;
88*54010Sfujita 	int omax;
89*54010Sfujita 	int omin;
90*54010Sfujita };
91*54010Sfujita 
92*54010Sfujita struct st_iostat st_iostat[NST];
93*54010Sfujita 
94*54010Sfujita 
95*54010Sfujita /*
96*54010Sfujita  * Initialize
97*54010Sfujita  */
98*54010Sfujita 
99*54010Sfujita int
100*54010Sfujita stinit(hd)
101*54010Sfujita 	register struct hp_device *hd;
102*54010Sfujita {
103*54010Sfujita 	register struct st_softc *sc = &st_softc[hd->hp_unit];
104*54010Sfujita 
105*54010Sfujita 	sc->sc_hd = hd;
106*54010Sfujita 	sc->sc_punit = stpunit(hd->hp_flags);
107*54010Sfujita 	sc->sc_type = stident(sc, hd);
108*54010Sfujita 	if (sc->sc_type < 0)
109*54010Sfujita 		return(0);
110*54010Sfujita 	sc->sc_dq.dq_ctlr = hd->hp_ctlr;
111*54010Sfujita 	sc->sc_dq.dq_unit = hd->hp_unit;
112*54010Sfujita 	sc->sc_dq.dq_slave = hd->hp_slave;
113*54010Sfujita 	sc->sc_dq.dq_driver = &stdriver;
114*54010Sfujita 	sc->sc_flags = STF_ALIVE;
115*54010Sfujita 	return(1);
116*54010Sfujita }
117*54010Sfujita 
118*54010Sfujita static struct scsi_inquiry inqbuf;
119*54010Sfujita static struct scsi_fmt_cdb inq = {
120*54010Sfujita 	6,
121*54010Sfujita 	CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
122*54010Sfujita };
123*54010Sfujita 
124*54010Sfujita int
125*54010Sfujita stident(sc, hd)
126*54010Sfujita 	struct st_softc *sc;
127*54010Sfujita 	struct hp_device *hd;
128*54010Sfujita {
129*54010Sfujita 	char idstr[32];
130*54010Sfujita 	int unit;
131*54010Sfujita 	register int ctlr, slave;
132*54010Sfujita 	register int i, stat;
133*54010Sfujita 	register int tries = 10;
134*54010Sfujita 
135*54010Sfujita 	ctlr = hd->hp_ctlr;
136*54010Sfujita 	slave = hd->hp_slave;
137*54010Sfujita 	unit = sc->sc_punit;
138*54010Sfujita 
139*54010Sfujita 	/*
140*54010Sfujita 	 * See if unit exists and is a disk then read block size & nblocks.
141*54010Sfujita 	 */
142*54010Sfujita 	while ((stat = scsi_immed_command(ctlr, slave, unit,
143*54010Sfujita 				  &inq, (u_char *)&inqbuf, sizeof(inqbuf))) != 0) {
144*54010Sfujita 		if (stat < 0 || --tries < 0)
145*54010Sfujita 			return (-1);
146*54010Sfujita 		DELAY(1000);
147*54010Sfujita 	}
148*54010Sfujita 
149*54010Sfujita 	switch (inqbuf.type) {
150*54010Sfujita 	case 1:		/* tape */
151*54010Sfujita 		break;
152*54010Sfujita 	default:	/* not a disk */
153*54010Sfujita 		printf("stident: inqbuf.type = %d\n", inqbuf.type);
154*54010Sfujita 		return (-1);
155*54010Sfujita 	}
156*54010Sfujita 
157*54010Sfujita 	bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)idstr, 28);
158*54010Sfujita 	for (i = 27; i > 23; --i)
159*54010Sfujita 		if (idstr[i] != ' ')
160*54010Sfujita 			break;
161*54010Sfujita 	idstr[i+1] = 0;
162*54010Sfujita 	for (i = 23; i > 7; --i)
163*54010Sfujita 		if (idstr[i] != ' ')
164*54010Sfujita 			break;
165*54010Sfujita 	idstr[i+1] = 0;
166*54010Sfujita 	for (i = 7; i >= 0; --i)
167*54010Sfujita 		if (idstr[i] != ' ')
168*54010Sfujita 			break;
169*54010Sfujita 	idstr[i+1] = 0;
170*54010Sfujita 	printf("st%d: %s %s rev %s\n", hd->hp_unit, idstr, &idstr[8],
171*54010Sfujita 	       &idstr[24]);
172*54010Sfujita 
173*54010Sfujita 	return(inqbuf.type);
174*54010Sfujita }
175*54010Sfujita 
176*54010Sfujita 
177*54010Sfujita /*
178*54010Sfujita  * Open
179*54010Sfujita  */
180*54010Sfujita 
181*54010Sfujita int
182*54010Sfujita stopen(dev, flag, type, p)
183*54010Sfujita 	dev_t dev;
184*54010Sfujita 	int flag, type;
185*54010Sfujita 	struct proc *p;
186*54010Sfujita {
187*54010Sfujita 	register int unit = stunit(dev);
188*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
189*54010Sfujita 	register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff;
190*54010Sfujita 	int ctlr  = sc->sc_dq.dq_ctlr;
191*54010Sfujita 	int slave = sc->sc_dq.dq_slave;
192*54010Sfujita 	int stat, retry = 9;
193*54010Sfujita 
194*54010Sfujita 	if (unit >= NST || (sc->sc_flags & STF_ALIVE) == 0)
195*54010Sfujita 		return(-1);
196*54010Sfujita 	if (sc->sc_flags & STF_OPEN)
197*54010Sfujita 		return(-1);
198*54010Sfujita 
199*54010Sfujita 	/* drive ready ? */
200*54010Sfujita 	while ((stat = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) {
201*54010Sfujita 		scsi_request_sense(ctlr, slave, 0, sp, 8);
202*54010Sfujita 
203*54010Sfujita 		if (stat != STS_CHECKCOND) {
204*54010Sfujita 			printf("st%d: stopen: %s\n", scsi_status(stat));
205*54010Sfujita 			return(EIO);
206*54010Sfujita 		}
207*54010Sfujita 
208*54010Sfujita 		if (retry-- < 0) {
209*54010Sfujita 			printf("st%d: stopen: %s\n", sense_key(sp->key));
210*54010Sfujita 			return(EIO);
211*54010Sfujita 		}
212*54010Sfujita 
213*54010Sfujita 		DELAY(1000000);
214*54010Sfujita 	}
215*54010Sfujita 
216*54010Sfujita 	sc->sc_ctty = tprintf_open(p);
217*54010Sfujita 
218*54010Sfujita 	sc->sc_flags |= STF_OPEN;
219*54010Sfujita 	if (flag & FWRITE)
220*54010Sfujita 		sc->sc_flags |= STF_WMODE;
221*54010Sfujita 	sc->sc_flags &= ~STF_MOVED;
222*54010Sfujita 
223*54010Sfujita 	return(0);
224*54010Sfujita }
225*54010Sfujita 
226*54010Sfujita /*ARGSUSED*/
227*54010Sfujita stclose(dev)
228*54010Sfujita 	dev_t dev;
229*54010Sfujita {
230*54010Sfujita 	register int unit = stunit(dev);
231*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
232*54010Sfujita 	register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff;
233*54010Sfujita 	int ctlr  = sc->sc_hd->hp_ctlr;
234*54010Sfujita 	int slave = sc->sc_hd->hp_slave;
235*54010Sfujita 	int stat, retry = 9;
236*54010Sfujita 
237*54010Sfujita 	if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) {
238*54010Sfujita 		st_write_EOF(dev);
239*54010Sfujita 	}
240*54010Sfujita 
241*54010Sfujita 	if ((minor(dev) & STDEV_NOREWIND) == 0) {
242*54010Sfujita 		st_rewind(dev);
243*54010Sfujita 	}
244*54010Sfujita 
245*54010Sfujita 	sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN);
246*54010Sfujita 
247*54010Sfujita 	tprintf_close(sc->sc_ctty);
248*54010Sfujita 
249*54010Sfujita 	return(0);
250*54010Sfujita }
251*54010Sfujita 
252*54010Sfujita /*
253*54010Sfujita  * Strategy
254*54010Sfujita  */
255*54010Sfujita 
256*54010Sfujita int
257*54010Sfujita ststrategy(bp)
258*54010Sfujita 	register struct buf *bp;
259*54010Sfujita {
260*54010Sfujita 	register int unit = stunit(bp->b_dev);
261*54010Sfujita 	register struct buf *dp = &sttab[unit];
262*54010Sfujita 	int s;
263*54010Sfujita 
264*54010Sfujita 	bp->av_forw = NULL;
265*54010Sfujita 
266*54010Sfujita 	s = splbio();
267*54010Sfujita 
268*54010Sfujita 	if (dp->b_actf == NULL)
269*54010Sfujita 		dp->b_actf = bp;
270*54010Sfujita 	else
271*54010Sfujita 		dp->b_actl->av_forw = bp;
272*54010Sfujita 
273*54010Sfujita 	dp->b_actl = bp;
274*54010Sfujita 
275*54010Sfujita 	if (dp->b_active == 0) {
276*54010Sfujita 		dp->b_active = 1;
277*54010Sfujita 		stustart(unit);
278*54010Sfujita 	}
279*54010Sfujita 
280*54010Sfujita 	splx(s);
281*54010Sfujita }
282*54010Sfujita 
283*54010Sfujita int
284*54010Sfujita stustart(unit)
285*54010Sfujita 	register int unit;
286*54010Sfujita {
287*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
288*54010Sfujita 	register struct hp_device *hp = sc->sc_hd;
289*54010Sfujita 	register struct scsi_queue *dq = &sc->sc_dq;
290*54010Sfujita 	register struct buf *bp = sttab[unit].b_actf;
291*54010Sfujita 	register struct scsi_fmt_cdb *cmd;
292*54010Sfujita 	long nblks;
293*54010Sfujita 
294*54010Sfujita 	cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd;
295*54010Sfujita 	cmd->cdb[1] = 1;		/* unknown setup */
296*54010Sfujita 
297*54010Sfujita 	if (bp->b_flags & B_READ)
298*54010Sfujita 		sc->sc_flags &= ~STF_WRTTN;
299*54010Sfujita 	else
300*54010Sfujita 		sc->sc_flags |= STF_WRTTN;
301*54010Sfujita 
302*54010Sfujita 	nblks = bp->b_bcount >> DEV_BSHIFT;
303*54010Sfujita 
304*54010Sfujita 	if (bp->b_bcount % DEV_BSIZE) {
305*54010Sfujita 		tprintf(sc->sc_ctty,
306*54010Sfujita 			"st%d: I/O not block aligned %d/%ld\n",
307*54010Sfujita 			unit, DEV_BSIZE, bp->b_bcount);
308*54010Sfujita 
309*54010Sfujita 		bp->b_flags |= B_ERROR;
310*54010Sfujita 		bp->b_error = EIO;
311*54010Sfujita 
312*54010Sfujita 		sttab[unit].b_errcnt = 0;
313*54010Sfujita 		sttab[unit].b_actf = bp->b_actf;
314*54010Sfujita 
315*54010Sfujita 		bp->b_resid = 0;
316*54010Sfujita 
317*54010Sfujita 		biodone(bp);
318*54010Sfujita 
319*54010Sfujita 		if (sttab[unit].b_actf) {
320*54010Sfujita 			stustart(unit);
321*54010Sfujita 		} else {
322*54010Sfujita 			sttab[unit].b_active = 0;
323*54010Sfujita 		}
324*54010Sfujita 	}
325*54010Sfujita 
326*54010Sfujita 	*(u_char *)(&cmd->cdb[2]) = (u_char) (nblks >> 16);
327*54010Sfujita 	*(u_char *)(&cmd->cdb[3]) = (u_char) (nblks >>  8);
328*54010Sfujita 	*(u_char *)(&cmd->cdb[4]) = (u_char)  nblks;
329*54010Sfujita 
330*54010Sfujita 	cmd->cdb[5] = 0;		/* unknown setup */
331*54010Sfujita 
332*54010Sfujita 	sc->sc_flags |= STF_MOVED;
333*54010Sfujita 
334*54010Sfujita 	dq->dq_cdb = cmd;
335*54010Sfujita 	dq->dq_bp  = bp;
336*54010Sfujita 	dq->dq_flags = 0;		/* No Disconnect */
337*54010Sfujita 
338*54010Sfujita 	if (screq(dq))
339*54010Sfujita 		ststart(unit);
340*54010Sfujita }
341*54010Sfujita 
342*54010Sfujita int
343*54010Sfujita ststart(unit)
344*54010Sfujita 	register int unit;
345*54010Sfujita {
346*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
347*54010Sfujita 	register struct hp_device *hp = sc->sc_hd;
348*54010Sfujita 
349*54010Sfujita 	scstart(hp->hp_ctlr);
350*54010Sfujita }
351*54010Sfujita 
352*54010Sfujita /*
353*54010Sfujita  * Interrupt
354*54010Sfujita  */
355*54010Sfujita 
356*54010Sfujita char *
357*54010Sfujita sense_key(key)
358*54010Sfujita 	int key;
359*54010Sfujita {
360*54010Sfujita 	if (key == 0)
361*54010Sfujita 		return("No Sense");
362*54010Sfujita 	else if (key == 2)
363*54010Sfujita 		return("Not Ready");
364*54010Sfujita 	else if (key == 3)
365*54010Sfujita 		return("Medium Error");
366*54010Sfujita 	else if (key == 4)
367*54010Sfujita 		return("Hardware Error");
368*54010Sfujita 	else if (key == 5)
369*54010Sfujita 		return("Illegal Request");
370*54010Sfujita 	else if (key == 6)
371*54010Sfujita 		return("Unit Attention");
372*54010Sfujita 	else if (key == 7)
373*54010Sfujita 		return("Data Protect");
374*54010Sfujita 	else if (key == 8)
375*54010Sfujita 		return("No Data");
376*54010Sfujita 	else if (key == 11)
377*54010Sfujita 		return("Aborted Command");
378*54010Sfujita 	else if (key == 13)
379*54010Sfujita 		return("Volume Overflow");
380*54010Sfujita 	else
381*54010Sfujita 		return("Unknown Error");
382*54010Sfujita }
383*54010Sfujita 
384*54010Sfujita int
385*54010Sfujita stintr(unit, stat)
386*54010Sfujita 	register int unit;
387*54010Sfujita 	int stat;
388*54010Sfujita {
389*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
390*54010Sfujita 	register struct scsi_xsense *xp = (struct scsi_xsense *) xsense_buff;
391*54010Sfujita 	register struct scsi_queue *dq = &sc->sc_dq;
392*54010Sfujita 	register struct buf *bp = dq->dq_bp;
393*54010Sfujita 	int ctlr  = dq->dq_ctlr;
394*54010Sfujita 	int slave = dq->dq_slave;
395*54010Sfujita 
396*54010Sfujita 	if (bp->b_flags & B_READ) {
397*54010Sfujita 		st_iostat[unit].imin = MIN(dq->dq_imin, st_iostat[unit].imin);
398*54010Sfujita 		if (dq->dq_imax > st_iostat[unit].imax) {
399*54010Sfujita 			st_iostat[unit].imax = dq->dq_imax;
400*54010Sfujita #ifdef ST_IOSTAT
401*54010Sfujita 			printf("stintr: st%d  INPUT	MAX = %d, MIN = %d\n",
402*54010Sfujita 			       unit, st_iostat[unit].imax, st_iostat[unit].imin);
403*54010Sfujita #endif
404*54010Sfujita 		}
405*54010Sfujita 	} else {
406*54010Sfujita 		st_iostat[unit].omin = MIN(dq->dq_omin, st_iostat[unit].omin);
407*54010Sfujita 		if (dq->dq_omax > st_iostat[unit].omax) {
408*54010Sfujita 			st_iostat[unit].omax = dq->dq_omax;
409*54010Sfujita #ifdef ST_IOSTAT
410*54010Sfujita 			printf("stintr: st%d  OUTPUT	MAX = %d, MIN = %d\n",
411*54010Sfujita 			       unit, st_iostat[unit].omax, st_iostat[unit].omin);
412*54010Sfujita #endif
413*54010Sfujita 		}
414*54010Sfujita 	}
415*54010Sfujita 	if (stat < 0) {
416*54010Sfujita 		bp->b_flags |= B_ERROR;
417*54010Sfujita 		bp->b_error = EIO;
418*54010Sfujita 		goto done;
419*54010Sfujita 	}
420*54010Sfujita 
421*54010Sfujita 	switch (stat) {
422*54010Sfujita 	/* scsi command completed ok */
423*54010Sfujita 	case 0:
424*54010Sfujita 		bp->b_resid = 0;
425*54010Sfujita 		break;
426*54010Sfujita 
427*54010Sfujita 	/* more status */
428*54010Sfujita 	case STS_CHECKCOND:
429*54010Sfujita 		scsi_request_sense(ctlr, slave, 0, xp, 8);
430*54010Sfujita #ifdef DEBUG
431*54010Sfujita 		printf("stintr: xsense_buff[0] = 0x%s\n", hexstr(xsense_buff[0], 2));
432*54010Sfujita 		printf("stintr: xsense_buff[2] = 0x%s\n", hexstr(xsense_buff[2], 2));
433*54010Sfujita 		printf("stintr: Sense Key = [%s]\n", sense_key(xp->key));
434*54010Sfujita #endif
435*54010Sfujita 		if (xp->valid) {
436*54010Sfujita 			bp->b_resid = (u_long)((xp->info1 << 24) |
437*54010Sfujita 					       (xp->info2 << 16) |
438*54010Sfujita 					       (xp->info3 << 8) |
439*54010Sfujita 					       (xp->info4));
440*54010Sfujita 			bp->b_resid <<= DEV_BSHIFT;
441*54010Sfujita 		}
442*54010Sfujita 
443*54010Sfujita 		if (xp->filemark) {		/* End of File */
444*54010Sfujita 			tprintf(sc->sc_ctty, "st%d: End of File\n", unit);
445*54010Sfujita 			bp->b_flags |= B_ERROR;
446*54010Sfujita 			bp->b_error = EIO;
447*54010Sfujita 			break;
448*54010Sfujita 		}
449*54010Sfujita 
450*54010Sfujita 		if (xp->key) {
451*54010Sfujita 			tprintf(sc->sc_ctty, "st%d: %s\n", unit, sense_key(xp->key));
452*54010Sfujita 			bp->b_flags |= B_ERROR;
453*54010Sfujita 			bp->b_error = EIO;
454*54010Sfujita 			break;
455*54010Sfujita 		}
456*54010Sfujita 
457*54010Sfujita 		if (xp->eom) {		/* End of TAPE */
458*54010Sfujita 			tprintf(sc->sc_ctty, "st%d: End of Tape\n", unit);
459*54010Sfujita 			bp->b_flags |= B_ERROR;
460*54010Sfujita 			bp->b_error = ENOSPC;
461*54010Sfujita 			break;
462*54010Sfujita 		}
463*54010Sfujita 
464*54010Sfujita 		tprintf(sc->sc_ctty, "st%d: unknown scsi error\n", unit);
465*54010Sfujita 		bp->b_flags |= B_ERROR;
466*54010Sfujita 		bp->b_error = EIO;
467*54010Sfujita 		break;
468*54010Sfujita 
469*54010Sfujita 	default:
470*54010Sfujita 		printf("st%d: stintr unknown stat 0x%x\n", unit, stat);
471*54010Sfujita 		break;
472*54010Sfujita 	}
473*54010Sfujita 
474*54010Sfujita done:
475*54010Sfujita 	sttab[unit].b_errcnt = 0;
476*54010Sfujita 	sttab[unit].b_actf = bp->b_actf;
477*54010Sfujita 
478*54010Sfujita 	bp->b_resid = 0;
479*54010Sfujita 
480*54010Sfujita 	biodone(bp);
481*54010Sfujita 
482*54010Sfujita 	scfree(&sc->sc_dq);
483*54010Sfujita 
484*54010Sfujita 	if (sttab[unit].b_actf) {
485*54010Sfujita 		stustart(unit);
486*54010Sfujita 	} else {
487*54010Sfujita 		sttab[unit].b_active = 0;
488*54010Sfujita 	}
489*54010Sfujita }
490*54010Sfujita 
491*54010Sfujita 
492*54010Sfujita /*
493*54010Sfujita  * RAW Device Routines
494*54010Sfujita  */
495*54010Sfujita 
496*54010Sfujita 
497*54010Sfujita stread(dev, uio)
498*54010Sfujita 	dev_t dev;
499*54010Sfujita 	struct uio *uio;
500*54010Sfujita {
501*54010Sfujita 	int unit = stunit(dev);
502*54010Sfujita 
503*54010Sfujita 	return(physio(ststrategy, &stbuf[unit], dev, B_READ, minphys, uio));
504*54010Sfujita }
505*54010Sfujita 
506*54010Sfujita stwrite(dev, uio)
507*54010Sfujita 	dev_t dev;
508*54010Sfujita 	struct uio *uio;
509*54010Sfujita {
510*54010Sfujita 	int unit = stunit(dev);
511*54010Sfujita 
512*54010Sfujita 	return(physio(ststrategy, &stbuf[unit], dev, B_WRITE, minphys, uio));
513*54010Sfujita }
514*54010Sfujita 
515*54010Sfujita int
516*54010Sfujita stioctl(dev, cmd, data, flag, p)
517*54010Sfujita 	dev_t dev;
518*54010Sfujita 	int cmd;
519*54010Sfujita 	caddr_t data;
520*54010Sfujita 	int flag;
521*54010Sfujita 	struct proc *p;
522*54010Sfujita {
523*54010Sfujita 	return(ENXIO);
524*54010Sfujita }
525*54010Sfujita 
526*54010Sfujita struct scsi_fmt_cdb st_cmd;
527*54010Sfujita 
528*54010Sfujita st_rewind(dev)
529*54010Sfujita 	dev_t dev;
530*54010Sfujita {
531*54010Sfujita 	register int unit = stunit(dev);
532*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
533*54010Sfujita 	register struct scsi_fmt_cdb *cdb = &st_cmd;
534*54010Sfujita 	register struct scsi_xsense *sp = (struct scsi_xsense *) xsense_buff;
535*54010Sfujita 	int ctlr, slave, stat;
536*54010Sfujita 	int retry = 9;
537*54010Sfujita 
538*54010Sfujita 	ctlr  = sc->sc_hd->hp_ctlr;
539*54010Sfujita 	slave = sc->sc_hd->hp_slave;
540*54010Sfujita 
541*54010Sfujita 	cdb->len = 6;
542*54010Sfujita 
543*54010Sfujita 	cdb->cdb[0] = CMD_REWIND;
544*54010Sfujita 
545*54010Sfujita 	cdb->cdb[1] = 1;	/* command finished soon */
546*54010Sfujita 
547*54010Sfujita 	cdb->cdb[2] = 0;
548*54010Sfujita 	cdb->cdb[3] = 0;
549*54010Sfujita 	cdb->cdb[4] = 0;
550*54010Sfujita 
551*54010Sfujita 	cdb->cdb[5] = 0;		/* unknown setup */
552*54010Sfujita 
553*54010Sfujita  rewind:
554*54010Sfujita 	stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0);
555*54010Sfujita 
556*54010Sfujita 	if (stat == 0) {
557*54010Sfujita 		return(1);
558*54010Sfujita 	} else {
559*54010Sfujita 		printf("st: rewind error\n");
560*54010Sfujita 		scsi_request_sense(ctlr, slave, 0, sp, 8);
561*54010Sfujita 		printf("st: status = 0x%x, sens key = 0x%x\n", stat, sp->key);
562*54010Sfujita 
563*54010Sfujita 		if (retry > 0) {
564*54010Sfujita 			DELAY(1000000);
565*54010Sfujita 			retry--;
566*54010Sfujita 			goto rewind;
567*54010Sfujita 		}
568*54010Sfujita 
569*54010Sfujita 		return(0);
570*54010Sfujita 	}
571*54010Sfujita }
572*54010Sfujita 
573*54010Sfujita st_write_EOF(dev)
574*54010Sfujita 	dev_t dev;
575*54010Sfujita {
576*54010Sfujita 	register int unit = stunit(dev);
577*54010Sfujita 	register struct st_softc *sc = &st_softc[unit];
578*54010Sfujita 	register struct scsi_fmt_cdb *cdb = &st_cmd;
579*54010Sfujita 	int ctlr, slave, stat;
580*54010Sfujita 	int marks = 1;
581*54010Sfujita 
582*54010Sfujita 	ctlr  = sc->sc_hd->hp_ctlr;
583*54010Sfujita 	slave = sc->sc_hd->hp_slave;
584*54010Sfujita 
585*54010Sfujita 	cdb->len = 6;
586*54010Sfujita 
587*54010Sfujita 	cdb->cdb[0] = CMD_WRITE_FILEMARK;
588*54010Sfujita 
589*54010Sfujita 	cdb->cdb[1] = 0;
590*54010Sfujita 
591*54010Sfujita 	cdb->cdb[2] = 0;
592*54010Sfujita 	cdb->cdb[3] = 0;
593*54010Sfujita 	cdb->cdb[4] = marks;
594*54010Sfujita 
595*54010Sfujita 	cdb->cdb[5] = 0;		/* unknown setup */
596*54010Sfujita 
597*54010Sfujita 	stat = scsi_immed_command(ctlr, slave, 0, cdb, (char *) 0, 0);
598*54010Sfujita 
599*54010Sfujita 	if (stat == 0)
600*54010Sfujita 		return(1);
601*54010Sfujita 
602*54010Sfujita 	printf("st: write EOF error\n");
603*54010Sfujita 
604*54010Sfujita 	return(0);
605*54010Sfujita }
606*54010Sfujita 
607*54010Sfujita /*
608*54010Sfujita  * Dump
609*54010Sfujita  */
610*54010Sfujita 
611*54010Sfujita int
612*54010Sfujita stdump(dev)
613*54010Sfujita 	dev_t dev;
614*54010Sfujita {
615*54010Sfujita }
616*54010Sfujita #endif
617