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