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.3 (Berkeley) 03/29/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 #ifdef DEBUG 340 if (tzdebug) 341 printf("tz%d: error reading sense data: error %d scsi status 0x%x\n", 342 unit, error, status); 343 #endif 344 /* 345 * We got an error during the REQUEST_SENSE, 346 * fill in no sense for data. 347 */ 348 sc->sc_sense.sense[0] = 0x70; 349 sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE; 350 } else if (!cold) { 351 ScsiClass7Sense *sp; 352 long resid; 353 354 sp = (ScsiClass7Sense *)sc->sc_sense.sense; 355 if (sp->error7 != 0x70) 356 goto prerr; 357 if (sp->valid) { 358 resid = (sp->info1 << 24) | (sp->info2 << 16) | 359 (sp->info3 << 8) | sp->info4; 360 if (sc->sc_blklen) 361 resid *= sc->sc_blklen; 362 } else 363 resid = 0; 364 switch (sp->key) { 365 case SCSI_CLASS7_NO_SENSE: 366 /* 367 * Hit a filemark, end of media, or 368 * end of record. 369 * Fixed length blocks, an error. 370 */ 371 if (sp->endOfMedia) { 372 bp->b_error = ENOSPC; 373 bp->b_resid = resid; 374 break; 375 } 376 if (sc->sc_blklen && sp->badBlockLen) { 377 tprintf(sc->sc_ctty, 378 "tz%d: Incorrect Block Length, expected %d got %d\n", 379 unit, sc->sc_blklen, resid); 380 break; 381 } 382 if (sp->fileMark) 383 sc->sc_flags |= TZF_SEENEOF; 384 bp->b_flags &= ~B_ERROR; 385 bp->b_error = 0; 386 bp->b_resid = resid; 387 break; 388 389 case SCSI_CLASS7_UNIT_ATTN: 390 if (!(sc->sc_flags & TZF_OPEN)) 391 break; 392 393 default: 394 prerr: 395 tprintf(sc->sc_ctty, "tz%d: ", unit); 396 scsiPrintSense((ScsiClass7Sense *) 397 sc->sc_sense.sense, 398 sizeof(sc->sc_sense.sense) - resid); 399 } 400 } 401 } else if (error || (status & SCSI_STATUS_CHECKCOND)) { 402 #ifdef DEBUG 403 if (!cold && tzdebug) 404 printf("tz%d: error %d scsi status 0x%x\n", 405 unit, error, status); 406 #endif 407 /* save error info */ 408 sc->sc_sense.status = status; 409 bp->b_flags |= B_ERROR; 410 bp->b_error = error; 411 bp->b_resid = resid; 412 413 if (status & SCSI_STATUS_CHECKCOND) { 414 /* 415 * Start a REQUEST_SENSE command. 416 * Since we are called at interrupt time, we can't 417 * wait for the command to finish; that's why we use 418 * the sc_flags field. 419 */ 420 sc->sc_flags |= TZF_SENSEINPROGRESS; 421 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd); 422 scsiGroup0Cmd(SCSI_REQUEST_SENSE, sc->sc_sd->sd_slave, 423 0, sizeof(sc->sc_sense.sense), 424 (ScsiGroup0Cmd *)sc->sc_cdb.cdb); 425 sc->sc_errbuf.b_flags = B_BUSY | B_READ; 426 sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense); 427 sc->sc_errbuf.b_un.b_addr = (caddr_t)sc->sc_sense.sense; 428 sc->sc_errbuf.av_forw = bp; 429 sc->sc_tab.b_actf = &sc->sc_errbuf; 430 tzstart(unit); 431 return; 432 } 433 } else { 434 sc->sc_sense.status = status; 435 bp->b_resid = resid; 436 } 437 438 sc->sc_tab.b_actf = bp->b_actf; 439 biodone(bp); 440 if (sc->sc_tab.b_actf) 441 tzstart(unit); 442 else { 443 sc->sc_tab.b_active = 0; 444 if (sc->sc_flags & TZF_WAIT) { 445 sc->sc_flags &= ~TZF_WAIT; 446 wakeup(&sc->sc_flags); 447 } 448 } 449 } 450 451 /* ARGSUSED */ 452 tzopen(dev, flags, type, p) 453 dev_t dev; 454 int flags, type; 455 struct proc *p; 456 { 457 register int unit = tzunit(dev); 458 register struct tz_softc *sc = &tz_softc[unit]; 459 int error; 460 461 if (unit >= NTZ) 462 return (ENXIO); 463 if (!(sc->sc_flags & TZF_ALIVE)) { 464 /* check again, tape may have been turned off at boot time */ 465 if (!tzprobe(sc->sc_sd)) 466 return (ENXIO); 467 } 468 if (sc->sc_flags & TZF_OPEN) 469 return (EBUSY); 470 471 /* clear UNIT_ATTENTION */ 472 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0); 473 if (error) { 474 ScsiClass7Sense *sp = (ScsiClass7Sense *)sc->sc_sense.sense; 475 476 /* return error if last error was not UNIT_ATTENTION */ 477 if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND) || 478 sp->error7 != 0x70 || sp->key != SCSI_CLASS7_UNIT_ATTN) 479 return (error); 480 481 /* 482 * Try it again just to be sure and 483 * try to negotiate synchonous transfers. 484 */ 485 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0); 486 } 487 488 /* get the current mode settings */ 489 error = tzcommand(dev, SCSI_MODE_SENSE, 0, 490 sc->sc_modelen, (caddr_t)&sc->sc_mode); 491 if (error) 492 return (error); 493 494 /* check for write protected tape */ 495 if ((flags & FWRITE) && sc->sc_mode.writeprot) { 496 uprintf("tz%d: write protected\n", unit); 497 return (EACCES); 498 } 499 500 /* set record length */ 501 switch (sc->sc_tapeid) { 502 case MT_ISAR: 503 case MT_ISHPDAT: 504 case MT_ISVIPER1: 505 case MT_ISPYTHON: 506 sc->sc_blklen = 512; 507 break; 508 509 case MT_ISEXABYTE: 510 #if 0 511 if (minor(dev) & TZ_FIXEDBLK) 512 sc->sc_blklen = 1024; 513 else 514 sc->sc_blklen = st_exblklen; 515 #endif 516 break; 517 518 case MT_ISMFOUR: 519 case MT_ISTK50: 520 sc->sc_blklen = 0; 521 break; 522 523 default: 524 sc->sc_blklen = (sc->sc_mode.block_size2 << 16) | 525 (sc->sc_mode.block_size1 << 8) | sc->sc_mode.block_size0; 526 } 527 528 /* save total number of blocks on tape */ 529 sc->sc_numblks = (sc->sc_mode.blocks_2 << 16) | 530 (sc->sc_mode.blocks_1 << 8) | sc->sc_mode.blocks_0; 531 532 /* setup for mode select */ 533 sc->sc_mode.len = 0; 534 sc->sc_mode.media = 0; 535 sc->sc_mode.bufferedMode = 1; 536 sc->sc_mode.blocks_0 = 0; 537 sc->sc_mode.blocks_1 = 0; 538 sc->sc_mode.blocks_2 = 0; 539 sc->sc_mode.block_size0 = sc->sc_blklen >> 16; 540 sc->sc_mode.block_size1 = sc->sc_blklen >> 8; 541 sc->sc_mode.block_size2 = sc->sc_blklen; 542 543 /* check for tape density changes */ 544 switch (sc->sc_tapeid) { 545 case MT_ISAR: 546 if (minor(dev) & TZ_HIDENSITY) 547 sc->sc_mode.density = 0x5; 548 else { 549 if (flags & FWRITE) { 550 uprintf("Can only write QIC-24\n"); 551 return (EIO); 552 } 553 sc->sc_mode.density = 0x4; 554 } 555 break; 556 557 case MT_ISMT02: 558 /* 559 * The tape density is set automatically when the tape 560 * is loaded. We only need to change it if we are writing. 561 */ 562 if (flags & FWRITE) { 563 if (minor(dev) & TZ_HIDENSITY) 564 sc->sc_mode.density = 0; 565 else 566 sc->sc_mode.density = 0x4; 567 } 568 break; 569 570 case MT_ISEXABYTE: 571 #if 0 572 if (minor(dev) & TZ_HIDENSITY) 573 uprintf("EXB-8200 density support only\n"); 574 sc->sc_mode.vupb = (u_char)st_exvup; 575 sc->sc_mode.rsvd5 = 0; 576 sc->sc_mode.p5 = 0; 577 sc->sc_mode.motionthres = (u_char)st_exmotthr; 578 sc->sc_mode.reconthres = (u_char)st_exreconthr; 579 sc->sc_mode.gapthres = (u_char)st_exgapthr; 580 #endif 581 break; 582 583 case MT_ISHPDAT: 584 case MT_ISVIPER1: 585 case MT_ISPYTHON: 586 case MT_ISTK50: 587 if (minor(dev) & TZ_HIDENSITY) 588 uprintf("tz%d: Only one density supported\n", unit); 589 break; 590 591 case MT_ISMFOUR: 592 break; /* XXX could do density select? */ 593 } 594 595 /* set the current mode settings */ 596 error = tzcommand(dev, SCSI_MODE_SELECT, 0, 597 sc->sc_modelen, (caddr_t)&sc->sc_mode); 598 if (error) 599 return (error); 600 601 sc->sc_ctty = tprintf_open(p); 602 sc->sc_flags = TZF_ALIVE | TZF_OPEN; 603 return (0); 604 } 605 606 tzclose(dev, flag) 607 dev_t dev; 608 int flag; 609 { 610 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 611 int error = 0; 612 613 if (!(sc->sc_flags & TZF_OPEN)) 614 return (0); 615 if (flag == FWRITE || 616 ((flag & FWRITE) && (sc->sc_flags & TZF_WRITTEN))) { 617 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0); 618 #if 0 619 /* 620 * Cartridge tapes don't do double EOFs on EOT. 621 */ 622 switch (sc->sc_tapeid) { 623 case MT_ISAR: 624 case MT_ISMT02: 625 break; 626 627 default: 628 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0); 629 if (minor(dev) & TZ_NOREWIND) 630 (void) tzcommand(dev, SCSI_SPACE, 0, -1, 0); 631 } 632 #endif 633 } 634 if ((minor(dev) & TZ_NOREWIND) == 0) 635 (void) tzcommand(dev, SCSI_REWIND, 0, 0, 0); 636 sc->sc_flags &= ~(TZF_OPEN | TZF_WRITTEN); 637 tprintf_close(sc->sc_ctty); 638 return (error); 639 } 640 641 tzioctl(dev, cmd, data, flag) 642 dev_t dev; 643 int cmd; 644 caddr_t data; 645 int flag; 646 { 647 register struct tz_softc *sc = &tz_softc[tzunit(dev)]; 648 register struct buf *bp = &sc->sc_buf; 649 struct mtop *mtop; 650 struct mtget *mtget; 651 int code, count; 652 static tzops[] = { 653 SCSI_WRITE_EOF, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, 654 SCSI_REWIND, SCSI_REWIND, SCSI_TEST_UNIT_READY 655 }; 656 657 switch (cmd) { 658 659 case MTIOCTOP: /* tape operation */ 660 mtop = (struct mtop *)data; 661 if ((unsigned)mtop->mt_op < MTREW && mtop->mt_count <= 0) 662 return (EINVAL); 663 switch (mtop->mt_op) { 664 665 case MTWEOF: 666 code = 0; 667 count = mtop->mt_count; 668 break; 669 670 case MTFSF: 671 code = 1; 672 count = mtop->mt_count; 673 break; 674 675 case MTBSF: 676 code = 1; 677 count = -mtop->mt_count; 678 break; 679 680 case MTFSR: 681 code = 0; 682 count = mtop->mt_count; 683 break; 684 685 case MTBSR: 686 code = 0; 687 count = -mtop->mt_count; 688 break; 689 690 case MTREW: 691 case MTOFFL: 692 case MTNOP: 693 code = 0; 694 count = 0; 695 break; 696 697 default: 698 return (EINVAL); 699 } 700 return (tzcommand(dev, tzops[mtop->mt_op], code, count, 0)); 701 702 case MTIOCGET: 703 mtget = (struct mtget *)data; 704 mtget->mt_dsreg = 0; 705 mtget->mt_erreg = sc->sc_sense.status; 706 mtget->mt_resid = 0; 707 mtget->mt_type = 0; 708 break; 709 710 default: 711 return (EINVAL); 712 } 713 return (0); 714 } 715 716 void 717 tzstrategy(bp) 718 register struct buf *bp; 719 { 720 register int unit = tzunit(bp->b_dev); 721 register struct tz_softc *sc = &tz_softc[unit]; 722 register struct buf *dp; 723 register int s; 724 725 if (sc->sc_flags & TZF_SEENEOF) { 726 bp->b_resid = bp->b_bcount; 727 biodone(bp); 728 return; 729 } 730 bp->av_forw = NULL; 731 dp = &sc->sc_tab; 732 s = splbio(); 733 if (dp->b_actf == NULL) 734 dp->b_actf = bp; 735 else 736 dp->b_actl->av_forw = bp; 737 dp->b_actl = bp; 738 if (dp->b_active == 0) { 739 dp->b_active = 1; 740 tzstart(unit); 741 } 742 splx(s); 743 } 744 #endif 745