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.1 (Berkeley) 06/10/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/scsireg.h> 35 #include <luna68k/dev/scsivar.h> 36 37 extern int scsi_test_unit_rdy(); 38 extern int scsi_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 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 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 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 = scsi_test_unit_rdy(ctlr, slave, 0)) != 0) { 207 scsi_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*/ 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 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 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 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 * 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 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 scsi_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 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 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 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 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 scsi_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 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 624 stdump(dev) 625 dev_t dev; 626 { 627 } 628 #endif 629