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