1 /* 2 * Copyright (c) 1992 Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ralph Campbell. 7 * 8 * %sccs.include.redist.c% 9 * 10 * @(#)tz.c 7.5 (Berkeley) 07/25/92 11 * 12 * from: $Header: /sprite/src/kernel/dev/RCS/devSCSITape.c, 13 * v 8.14 89/07/31 17:26:13 mendel Exp $ SPRITE (Berkeley) 14 */ 15 16 /* 17 * SCSI CCS (Command Command Set) tape driver. 18 */ 19 #include "tz.h" 20 #if NTZ > 0 21 22 #include "param.h" 23 #include "systm.h" 24 #include "buf.h" 25 #include "errno.h" 26 #include "file.h" 27 #include "ioctl.h" 28 #include "mtio.h" 29 #include "syslog.h" 30 #include "tprintf.h" 31 32 #include "device.h" 33 #include "scsi.h" 34 35 int tzprobe(); 36 void tzstart(), tzdone(); 37 38 struct driver tzdriver = { 39 "tz", tzprobe, tzstart, tzdone, 40 }; 41 42 struct tz_softc { 43 struct scsi_device *sc_sd; /* physical unit info */ 44 int sc_flags; /* see below */ 45 int sc_tapeid; /* tape drive id */ 46 int sc_blklen; /* 0 = variable len records */ 47 long sc_numblks; /* number of blocks on tape */ 48 tpr_t sc_ctty; /* terminal for error messages */ 49 struct buf sc_tab; /* queue of pending operations */ 50 struct buf sc_buf; /* buf for doing I/O */ 51 struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */ 52 struct ScsiCmd sc_cmd; /* command for controller */ 53 ScsiGroup0Cmd sc_rwcmd; /* SCSI cmd for read/write */ 54 struct scsi_fmt_cdb sc_cdb; /* SCSI cmd if not read/write */ 55 struct scsi_fmt_sense sc_sense; /* sense data from last cmd */ 56 struct ScsiTapeModeSelectHdr sc_mode; /* SCSI_MODE_SENSE data */ 57 char sc_modelen; /* SCSI_MODE_SENSE data length */ 58 } tz_softc[NTZ]; 59 60 /* sc_flags values */ 61 #define TZF_ALIVE 0x01 /* drive found and ready */ 62 #define TZF_SENSEINPROGRESS 0x02 /* REQUEST_SENSE command in progress */ 63 #define TZF_ALTCMD 0x04 /* alternate command in progress */ 64 #define TZF_WRITTEN 0x08 /* tape has been written to */ 65 #define TZF_OPEN 0x10 /* device is open */ 66 #define TZF_WAIT 0x20 /* waiting for sc_tab to drain */ 67 #define TZF_SEENEOF 0x40 /* seen file mark on read */ 68 69 /* bits in minor device */ 70 #define tzunit(x) (minor(x) >> 4) /* tz%d unit number */ 71 #define TZ_NOREWIND 0x01 /* don't rewind on close */ 72 #define TZ_HIDENSITY 0x02 73 #define TZ_EXSFMK 0x04 74 #define TZ_FIXEDBLK 0x08 75 76 #ifdef DEBUG 77 int tzdebug = 1; 78 #endif 79 80 /* 81 * Test to see if device is present. 82 * Return true if found and initialized ok. 83 */ 84 tzprobe(sd) 85 struct scsi_device *sd; 86 { 87 register struct tz_softc *sc = &tz_softc[sd->sd_unit]; 88 register int i; 89 ScsiInquiryData inqbuf; 90 ScsiClass7Sense *sp; 91 92 /* init some parameters that don't change */ 93 sc->sc_sd = sd; 94 sc->sc_cmd.sd = sd; 95 sc->sc_cmd.unit = sd->sd_unit; 96 sc->sc_cmd.flags = 0; 97 sc->sc_rwcmd.unitNumber = sd->sd_slave; 98 99 /* try to find out what type of device this is */ 100 sc->sc_flags = TZF_ALTCMD; /* force use of sc_cdb */ 101 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 102 scsiGroup0Cmd(SCSI_INQUIRY, sd->sd_slave, 0, sizeof(inqbuf), 103 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 104 sc->sc_buf.b_flags = B_BUSY | B_READ; 105 sc->sc_buf.b_bcount = sizeof(inqbuf); 106 sc->sc_buf.b_un.b_addr = (caddr_t)&inqbuf; 107 sc->sc_buf.av_forw = (struct buf *)0; 108 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 109 tzstart(sd->sd_unit); 110 if (biowait(&sc->sc_buf) || 111 (i = sizeof(inqbuf) - sc->sc_buf.b_resid) < 5) 112 goto bad; 113 if (inqbuf.type != SCSI_TAPE_TYPE || !inqbuf.rmb) 114 goto bad; 115 116 /* check for device ready to clear UNIT_ATTN */ 117 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 118 scsiGroup0Cmd(SCSI_TEST_UNIT_READY, sd->sd_slave, 0, 0, 119 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 120 sc->sc_buf.b_flags = B_BUSY | B_READ; 121 sc->sc_buf.b_bcount = 0; 122 sc->sc_buf.b_un.b_addr = (caddr_t)0; 123 sc->sc_buf.av_forw = (struct buf *)0; 124 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 125 tzstart(sd->sd_unit); 126 (void) biowait(&sc->sc_buf); 127 128 sc->sc_flags = TZF_ALIVE; 129 sc->sc_modelen = 12; 130 sc->sc_buf.b_flags = 0; 131 printf("tz%d at %s%d drive %d slave %d", sd->sd_unit, 132 sd->sd_cdriver->d_name, sd->sd_ctlr, sd->sd_drive, 133 sd->sd_slave); 134 if (i == 5 && inqbuf.version == 1 && inqbuf.qualifier == 0x50) { 135 printf(" TK50\n"); 136 sc->sc_tapeid = MT_ISTK50; 137 } else if (i == 5 && inqbuf.version == 1 && inqbuf.qualifier == 0) { 138 /* assume Emultex MT02 controller */ 139 printf(" MT02\n"); 140 sc->sc_tapeid = MT_ISMT02; 141 } else if (inqbuf.version > 2 || i < 36) { 142 printf(" GENERIC SCSI tape device: qual 0x%x, ver %d\n", 143 inqbuf.qualifier, inqbuf.version); 144 sc->sc_tapeid = 0; 145 } else { 146 char vid[9], pid[17], revl[5]; 147 148 bcopy((caddr_t)inqbuf.vendorID, (caddr_t)vid, 8); 149 bcopy((caddr_t)inqbuf.productID, (caddr_t)pid, 16); 150 bcopy((caddr_t)inqbuf.revLevel, (caddr_t)revl, 4); 151 for (i = 8; --i > 0; ) 152 if (vid[i] != ' ') 153 break; 154 vid[i+1] = 0; 155 for (i = 16; --i > 0; ) 156 if (pid[i] != ' ') 157 break; 158 pid[i+1] = 0; 159 for (i = 4; --i > 0; ) 160 if (revl[i] != ' ') 161 break; 162 revl[i+1] = 0; 163 printf(" %s %s rev %s\n", vid, pid, revl); 164 165 if (bcmp("EXB-8200", pid, 8) == 0) { 166 sc->sc_tapeid = MT_ISEXABYTE; 167 sc->sc_modelen = 17; 168 } else if (bcmp("VIPER 150", pid, 9) == 0) { 169 sc->sc_tapeid = MT_ISVIPER1; 170 } else if (bcmp("Python 25501", pid, 12) == 0) { 171 sc->sc_tapeid = MT_ISPYTHON; 172 } else if (bcmp("HP35450A", pid, 8) == 0) { 173 #if 0 174 /* XXX "extra" stat makes the HP drive happy at boot time */ 175 stat = scsi_test_unit_rdy(ctlr, slave, unit); 176 #endif 177 sc->sc_tapeid = MT_ISHPDAT; 178 } else if (bcmp("123107 SCSI", pid, 11) == 0) { 179 sc->sc_tapeid = MT_ISMFOUR; 180 } else { 181 printf("tz%d: assuming GENERIC SCSI tape device\n", 182 sd->sd_unit, 183 inqbuf.type, inqbuf.qualifier, inqbuf.version); 184 sc->sc_tapeid = 0; 185 } 186 } 187 return (1); 188 189 bad: 190 /* doesn't exist or not a CCS device */ 191 sc->sc_flags = 0; 192 sc->sc_buf.b_flags = 0; 193 return (0); 194 } 195 196 /* 197 * Perform a special tape command on a SCSI Tape drive. 198 */ 199 tzcommand(dev, command, code, count, data) 200 dev_t dev; 201 int command; 202 int code; 203 int count; 204 caddr_t data; 205 { 206 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 207 register ScsiGroup0Cmd *c; 208 int s, error; 209 210 s = splbio(); 211 /* wait for pending operations to finish */ 212 while (sc->sc_tab.b_actf) { 213 sc->sc_flags |= TZF_WAIT; 214 sleep(&sc->sc_flags, PZERO); 215 } 216 sc->sc_flags |= TZF_ALTCMD; /* force use of sc_cdb */ 217 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 218 c = (ScsiGroup0Cmd *)sc->sc_cdb.cdb; 219 c->command = command; 220 c->unitNumber = sc->sc_sd->sd_slave; 221 c->highAddr = code; 222 c->midAddr = count >> 16; 223 c->lowAddr = count >> 8; 224 c->blockCount = count; 225 c->control = 0; 226 if (command == SCSI_MODE_SELECT) 227 sc->sc_buf.b_flags = B_BUSY; 228 else { 229 sc->sc_buf.b_flags = B_BUSY | B_READ; 230 #if 0 231 /* this seems to work but doesn't give us a speed advantage */ 232 if (command == SCSI_TEST_UNIT_READY) 233 sc->sc_cmd.flags |= SCSICMD_USE_SYNC; 234 #endif 235 } 236 sc->sc_buf.b_bcount = data ? count : 0; 237 sc->sc_buf.b_un.b_addr = data; 238 sc->sc_buf.av_forw = (struct buf *)0; 239 sc->sc_tab.b_actf = sc->sc_tab.b_actl = &sc->sc_buf; 240 tzstart(sc->sc_sd->sd_unit); 241 error = biowait(&sc->sc_buf); 242 sc->sc_flags &= ~TZF_ALTCMD; /* force use of sc_cdb */ 243 sc->sc_buf.b_flags = 0; 244 sc->sc_cmd.flags = 0; 245 if (sc->sc_buf.b_resid) 246 printf("tzcommand: resid %d\n", sc->sc_buf.b_resid); /* XXX */ 247 if (error == 0) 248 switch (command) { 249 case SCSI_SPACE: 250 case SCSI_WRITE_EOF: 251 case SCSI_REWIND: 252 sc->sc_flags &= ~TZF_SEENEOF; 253 } 254 splx(s); 255 return (error); 256 } 257 258 void 259 tzstart(unit) 260 int unit; 261 { 262 register struct tz_softc *sc = &tz_softc[unit]; 263 register struct buf *bp = sc->sc_tab.b_actf; 264 register int n; 265 266 sc->sc_cmd.buf = bp->b_un.b_addr; 267 sc->sc_cmd.buflen = bp->b_bcount; 268 269 if (sc->sc_flags & (TZF_SENSEINPROGRESS | TZF_ALTCMD)) { 270 if (bp->b_flags & B_READ) 271 sc->sc_cmd.flags &= ~SCSICMD_DATA_TO_DEVICE; 272 else 273 sc->sc_cmd.flags |= SCSICMD_DATA_TO_DEVICE; 274 sc->sc_cmd.cmd = sc->sc_cdb.cdb; 275 sc->sc_cmd.cmdlen = sc->sc_cdb.len; 276 } else { 277 if (bp->b_flags & B_READ) { 278 sc->sc_cmd.flags = 0; 279 sc->sc_rwcmd.command = SCSI_READ; 280 sc->sc_flags &= ~TZF_WRITTEN; 281 } else { 282 sc->sc_cmd.flags = SCSICMD_DATA_TO_DEVICE; 283 sc->sc_rwcmd.command = SCSI_WRITE; 284 sc->sc_flags |= TZF_WRITTEN; 285 } 286 sc->sc_cmd.cmd = (u_char *)&sc->sc_rwcmd; 287 sc->sc_cmd.cmdlen = sizeof(sc->sc_rwcmd); 288 if (sc->sc_blklen) { 289 /* fixed sized records */ 290 n = bp->b_bcount / sc->sc_blklen; 291 if (bp->b_bcount % sc->sc_blklen) { 292 tprintf(sc->sc_ctty, 293 "tz%d: I/O not block aligned %d/%ld\n", 294 unit, sc->sc_blklen, bp->b_bcount); 295 tzdone(unit, EIO, bp->b_bcount, 0); 296 } 297 sc->sc_rwcmd.highAddr = 1; 298 } else { 299 /* variable sized records */ 300 n = bp->b_bcount; 301 sc->sc_rwcmd.highAddr = 0; 302 } 303 sc->sc_rwcmd.midAddr = n >> 16; 304 sc->sc_rwcmd.lowAddr = n >> 8; 305 sc->sc_rwcmd.blockCount = n; 306 } 307 308 /* tell controller to start this command */ 309 (*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd); 310 } 311 312 /* 313 * This is called by the controller driver when the command is done. 314 */ 315 void 316 tzdone(unit, error, resid, status) 317 int unit; 318 int error; /* error number from errno.h */ 319 int resid; /* amount not transfered */ 320 int status; /* SCSI status byte */ 321 { 322 register struct tz_softc *sc = &tz_softc[unit]; 323 register struct buf *bp = sc->sc_tab.b_actf; 324 extern int cold; 325 326 if (bp == NULL) { 327 printf("tz%d: bp == NULL\n", unit); 328 return; 329 } 330 if (sc->sc_flags & TZF_SENSEINPROGRESS) { 331 sc->sc_flags &= ~TZF_SENSEINPROGRESS; 332 sc->sc_tab.b_actf = bp = bp->b_actf; /* remove sc_errbuf */ 333 #ifdef DIAGNOSTIC 334 if (bp == 0) 335 panic("tzdone"); 336 #endif 337 338 if (error || (status & SCSI_STATUS_CHECKCOND)) { 339 printf("tz%d: error reading sense data: error %d scsi status 0x%x\n", 340 unit, error, status); 341 /* 342 * We got an error during the REQUEST_SENSE, 343 * fill in no sense for data. 344 */ 345 sc->sc_sense.sense[0] = 0x70; 346 sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE; 347 } else if (!cold) { 348 ScsiClass7Sense *sp; 349 long resid; 350 351 sp = (ScsiClass7Sense *)sc->sc_sense.sense; 352 if (sp->error7 != 0x70) 353 goto prerr; 354 if (sp->valid) { 355 resid = (sp->info1 << 24) | (sp->info2 << 16) | 356 (sp->info3 << 8) | sp->info4; 357 if (sc->sc_blklen) 358 resid *= sc->sc_blklen; 359 } else 360 resid = 0; 361 switch (sp->key) { 362 case SCSI_CLASS7_NO_SENSE: 363 /* 364 * Hit a filemark, end of media, or 365 * end of record. 366 * Fixed length blocks, an error. 367 */ 368 if (sp->endOfMedia) { 369 bp->b_error = ENOSPC; 370 bp->b_resid = resid; 371 break; 372 } 373 if (sc->sc_blklen && sp->badBlockLen) { 374 tprintf(sc->sc_ctty, 375 "tz%d: Incorrect Block Length, expected %d got %d\n", 376 unit, sc->sc_blklen, resid); 377 break; 378 } 379 if (sp->fileMark) 380 sc->sc_flags |= TZF_SEENEOF; 381 bp->b_flags &= ~B_ERROR; 382 bp->b_error = 0; 383 bp->b_resid = resid; 384 break; 385 386 case SCSI_CLASS7_UNIT_ATTN: 387 if (!(sc->sc_flags & TZF_OPEN)) 388 break; 389 390 default: 391 prerr: 392 tprintf(sc->sc_ctty, "tz%d: ", unit); 393 scsiPrintSense((ScsiClass7Sense *) 394 sc->sc_sense.sense, 395 sizeof(sc->sc_sense.sense) - resid); 396 } 397 } 398 } else if (error || (status & SCSI_STATUS_CHECKCOND)) { 399 #ifdef DEBUG 400 if (!cold && tzdebug) 401 printf("tz%d: error %d scsi status 0x%x\n", 402 unit, error, status); 403 #endif 404 /* save error info */ 405 sc->sc_sense.status = status; 406 bp->b_flags |= B_ERROR; 407 bp->b_error = error; 408 bp->b_resid = resid; 409 410 if (status & SCSI_STATUS_CHECKCOND) { 411 /* 412 * Start a REQUEST_SENSE command. 413 * Since we are called at interrupt time, we can't 414 * wait for the command to finish; that's why we use 415 * the sc_flags field. 416 */ 417 sc->sc_flags |= TZF_SENSEINPROGRESS; 418 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 419 scsiGroup0Cmd(SCSI_REQUEST_SENSE, sc->sc_sd->sd_slave, 420 0, sizeof(sc->sc_sense.sense), 421 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 422 sc->sc_errbuf.b_flags = B_BUSY | B_READ; 423 sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense); 424 sc->sc_errbuf.b_un.b_addr = (caddr_t)sc->sc_sense.sense; 425 sc->sc_errbuf.av_forw = bp; 426 sc->sc_tab.b_actf = &sc->sc_errbuf; 427 tzstart(unit); 428 return; 429 } 430 } else { 431 sc->sc_sense.status = status; 432 bp->b_resid = resid; 433 } 434 435 sc->sc_tab.b_actf = bp->b_actf; 436 biodone(bp); 437 if (sc->sc_tab.b_actf) 438 tzstart(unit); 439 else { 440 sc->sc_tab.b_active = 0; 441 if (sc->sc_flags & TZF_WAIT) { 442 sc->sc_flags &= ~TZF_WAIT; 443 wakeup(&sc->sc_flags); 444 } 445 } 446 } 447 448 /* ARGSUSED */ 449 tzopen(dev, flags, type, p) 450 dev_t dev; 451 int flags, type; 452 struct proc *p; 453 { 454 register int unit = tzunit(dev); 455 register struct tz_softc *sc = &tz_softc[unit]; 456 int error; 457 458 if (unit >= NTZ) 459 return (ENXIO); 460 if (!(sc->sc_flags & TZF_ALIVE)) { 461 /* check again, tape may have been turned off at boot time */ 462 if (!tzprobe(sc->sc_sd)) 463 return (ENXIO); 464 } 465 if (sc->sc_flags & TZF_OPEN) 466 return (EBUSY); 467 468 /* clear UNIT_ATTENTION */ 469 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0); 470 if (error) { 471 ScsiClass7Sense *sp = (ScsiClass7Sense *)sc->sc_sense.sense; 472 473 /* return error if last error was not UNIT_ATTENTION */ 474 if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND) || 475 sp->error7 != 0x70 || sp->key != SCSI_CLASS7_UNIT_ATTN) 476 return (error); 477 478 /* 479 * Try it again just to be sure and 480 * try to negotiate synchonous transfers. 481 */ 482 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0); 483 } 484 485 /* get the current mode settings */ 486 error = tzcommand(dev, SCSI_MODE_SENSE, 0, 487 sc->sc_modelen, (caddr_t)&sc->sc_mode); 488 if (error) 489 return (error); 490 491 /* check for write protected tape */ 492 if ((flags & FWRITE) && sc->sc_mode.writeprot) { 493 uprintf("tz%d: write protected\n", unit); 494 return (EACCES); 495 } 496 497 /* set record length */ 498 switch (sc->sc_tapeid) { 499 case MT_ISAR: 500 case MT_ISHPDAT: 501 case MT_ISVIPER1: 502 sc->sc_blklen = 512; 503 break; 504 505 case MT_ISEXABYTE: 506 #if 0 507 if (minor(dev) & TZ_FIXEDBLK) 508 sc->sc_blklen = 1024; 509 else 510 sc->sc_blklen = st_exblklen; 511 #endif 512 break; 513 514 case MT_ISPYTHON: 515 case MT_ISMFOUR: 516 case MT_ISTK50: 517 sc->sc_blklen = 0; 518 break; 519 520 default: 521 sc->sc_blklen = (sc->sc_mode.block_size2 << 16) | 522 (sc->sc_mode.block_size1 << 8) | sc->sc_mode.block_size0; 523 } 524 525 /* save total number of blocks on tape */ 526 sc->sc_numblks = (sc->sc_mode.blocks_2 << 16) | 527 (sc->sc_mode.blocks_1 << 8) | sc->sc_mode.blocks_0; 528 529 /* setup for mode select */ 530 sc->sc_mode.len = 0; 531 sc->sc_mode.media = 0; 532 sc->sc_mode.bufferedMode = 1; 533 sc->sc_mode.blocks_0 = 0; 534 sc->sc_mode.blocks_1 = 0; 535 sc->sc_mode.blocks_2 = 0; 536 sc->sc_mode.block_size0 = sc->sc_blklen >> 16; 537 sc->sc_mode.block_size1 = sc->sc_blklen >> 8; 538 sc->sc_mode.block_size2 = sc->sc_blklen; 539 540 /* check for tape density changes */ 541 switch (sc->sc_tapeid) { 542 case MT_ISAR: 543 if (minor(dev) & TZ_HIDENSITY) 544 sc->sc_mode.density = 0x5; 545 else { 546 if (flags & FWRITE) { 547 uprintf("Can only write QIC-24\n"); 548 return (EIO); 549 } 550 sc->sc_mode.density = 0x4; 551 } 552 break; 553 554 case MT_ISMT02: 555 /* 556 * The tape density is set automatically when the tape 557 * is loaded. We only need to change it if we are writing. 558 */ 559 if (flags & FWRITE) { 560 if (minor(dev) & TZ_HIDENSITY) 561 sc->sc_mode.density = 0; 562 else 563 sc->sc_mode.density = 0x4; 564 } 565 break; 566 567 case MT_ISEXABYTE: 568 #if 0 569 if (minor(dev) & TZ_HIDENSITY) 570 uprintf("EXB-8200 density support only\n"); 571 sc->sc_mode.vupb = (u_char)st_exvup; 572 sc->sc_mode.rsvd5 = 0; 573 sc->sc_mode.p5 = 0; 574 sc->sc_mode.motionthres = (u_char)st_exmotthr; 575 sc->sc_mode.reconthres = (u_char)st_exreconthr; 576 sc->sc_mode.gapthres = (u_char)st_exgapthr; 577 #endif 578 break; 579 580 case MT_ISHPDAT: 581 case MT_ISVIPER1: 582 case MT_ISPYTHON: 583 case MT_ISTK50: 584 if (minor(dev) & TZ_HIDENSITY) 585 uprintf("tz%d: Only one density supported\n", unit); 586 break; 587 588 case MT_ISMFOUR: 589 break; /* XXX could do density select? */ 590 } 591 592 /* set the current mode settings */ 593 error = tzcommand(dev, SCSI_MODE_SELECT, 0, 594 sc->sc_modelen, (caddr_t)&sc->sc_mode); 595 if (error) 596 return (error); 597 598 sc->sc_ctty = tprintf_open(p); 599 sc->sc_flags = TZF_ALIVE | TZF_OPEN; 600 return (0); 601 } 602 603 tzclose(dev, flag) 604 dev_t dev; 605 int flag; 606 { 607 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 608 int error = 0; 609 610 if (!(sc->sc_flags & TZF_OPEN)) 611 return (0); 612 if (flag == FWRITE || 613 ((flag & FWRITE) && (sc->sc_flags & TZF_WRITTEN))) { 614 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0); 615 #if 0 616 /* 617 * Cartridge tapes don't do double EOFs on EOT. 618 */ 619 switch (sc->sc_tapeid) { 620 case MT_ISAR: 621 case MT_ISMT02: 622 break; 623 624 default: 625 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0); 626 if (minor(dev) & TZ_NOREWIND) 627 (void) tzcommand(dev, SCSI_SPACE, 0, -1, 0); 628 } 629 #endif 630 } 631 if ((minor(dev) & TZ_NOREWIND) == 0) 632 (void) tzcommand(dev, SCSI_REWIND, 0, 0, 0); 633 sc->sc_flags &= ~(TZF_OPEN | TZF_WRITTEN); 634 tprintf_close(sc->sc_ctty); 635 return (error); 636 } 637 638 tzioctl(dev, cmd, data, flag) 639 dev_t dev; 640 int cmd; 641 caddr_t data; 642 int flag; 643 { 644 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 645 register struct buf *bp = &sc->sc_buf; 646 struct mtop *mtop; 647 struct mtget *mtget; 648 int code, count; 649 static tzops[] = { 650 SCSI_WRITE_EOF, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, 651 SCSI_REWIND, SCSI_REWIND, SCSI_TEST_UNIT_READY 652 }; 653 654 switch (cmd) { 655 656 case MTIOCTOP: /* tape operation */ 657 mtop = (struct mtop *)data; 658 if ((unsigned)mtop->mt_op < MTREW && mtop->mt_count <= 0) 659 return (EINVAL); 660 switch (mtop->mt_op) { 661 662 case MTWEOF: 663 code = 0; 664 count = mtop->mt_count; 665 break; 666 667 case MTFSF: 668 code = 1; 669 count = mtop->mt_count; 670 break; 671 672 case MTBSF: 673 code = 1; 674 count = -mtop->mt_count; 675 break; 676 677 case MTFSR: 678 code = 0; 679 count = mtop->mt_count; 680 break; 681 682 case MTBSR: 683 code = 0; 684 count = -mtop->mt_count; 685 break; 686 687 case MTREW: 688 case MTOFFL: 689 case MTNOP: 690 code = 0; 691 count = 0; 692 break; 693 694 default: 695 return (EINVAL); 696 } 697 return (tzcommand(dev, tzops[mtop->mt_op], code, count, 0)); 698 699 case MTIOCGET: 700 mtget = (struct mtget *)data; 701 mtget->mt_dsreg = 0; 702 mtget->mt_erreg = sc->sc_sense.status; 703 mtget->mt_resid = 0; 704 mtget->mt_type = 0; 705 break; 706 707 default: 708 return (EINVAL); 709 } 710 return (0); 711 } 712 713 void 714 tzstrategy(bp) 715 register struct buf *bp; 716 { 717 register int unit = tzunit(bp->b_dev); 718 register struct tz_softc *sc = &tz_softc[unit]; 719 register struct buf *dp; 720 register int s; 721 722 if (sc->sc_flags & TZF_SEENEOF) { 723 bp->b_resid = bp->b_bcount; 724 biodone(bp); 725 return; 726 } 727 bp->av_forw = NULL; 728 dp = &sc->sc_tab; 729 s = splbio(); 730 if (dp->b_actf == NULL) 731 dp->b_actf = bp; 732 else 733 dp->b_actl->av_forw = bp; 734 dp->b_actl = bp; 735 if (dp->b_active == 0) { 736 dp->b_active = 1; 737 tzstart(unit); 738 } 739 splx(s); 740 } 741 #endif 742