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