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