1 /* 2 * Copyright (c) 1982, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ct.c 8.3 (Berkeley) 01/09/95 8 */ 9 10 #include "ct.h" 11 #if NCT > 0 12 /* 13 * CS80 cartridge tape driver (9144, 88140, 9145) 14 * 15 * Reminder: 16 * C_CC bit (character count option) when used in the CS/80 command 17 * 'set options' will cause the tape not to stream. 18 * 19 * TODO: 20 * make filesystem compatible 21 * make block mode work according to mtio(4) spec. (if possible) 22 * merge with cs80 disk driver 23 * finish support of 9145 24 */ 25 26 #include <sys/param.h> 27 #include <sys/buf.h> 28 #include <sys/ioctl.h> 29 #include <sys/mtio.h> 30 #include <sys/tprintf.h> 31 #include <sys/proc.h> 32 33 #include <hp/dev/device.h> 34 35 #include <hp300/dev/ctreg.h> 36 37 /* number of eof marks to remember */ 38 #define EOFS 128 39 40 int ctinit(), ctstart(), ctgo(), ctintr(); 41 void ctstrategy(); 42 struct driver ctdriver = { 43 ctinit, "ct", ctstart, ctgo, ctintr, 44 }; 45 46 struct ct_softc { 47 struct hp_device *sc_hd; 48 struct ct_iocmd sc_ioc; 49 struct ct_rscmd sc_rsc; 50 struct ct_stat sc_stat; 51 struct ct_ssmcmd sc_ssmc; 52 struct ct_srcmd sc_src; 53 struct ct_soptcmd sc_soptc; 54 struct ct_ulcmd sc_ul; 55 struct ct_wfmcmd sc_wfm; 56 struct ct_clearcmd sc_clear; 57 struct buf *sc_bp; 58 int sc_blkno; 59 int sc_cmd; 60 int sc_resid; 61 char *sc_addr; 62 int sc_flags; 63 short sc_type; 64 short sc_punit; 65 tpr_t sc_tpr; 66 struct devqueue sc_dq; 67 int sc_eofp; 68 int sc_eofs[EOFS]; 69 } ct_softc[NCT]; 70 71 /* flags */ 72 #define CTF_OPEN 0x01 73 #define CTF_ALIVE 0x02 74 #define CTF_WRT 0x04 75 #define CTF_CMD 0x08 76 #define CTF_IO 0x10 77 #define CTF_BEOF 0x20 78 #define CTF_AEOF 0x40 79 #define CTF_EOT 0x80 80 #define CTF_STATWAIT 0x100 81 #define CTF_CANSTREAM 0x200 82 #define CTF_WRTTN 0x400 83 84 struct ctinfo { 85 short hwid; 86 short punit; 87 char *desc; 88 } ctinfo[] = { 89 CT7946ID, 1, "7946A", 90 CT7912PID, 1, "7912P", 91 CT7914PID, 1, "7914P", 92 CT9144ID, 0, "9144", 93 CT9145ID, 0, "9145", 94 }; 95 int nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]); 96 97 struct buf cttab[NCT]; 98 struct buf ctbuf[NCT]; 99 100 #define CT_NOREW 4 101 #define CT_STREAM 8 102 #define UNIT(x) (minor(x) & 3) 103 #define ctpunit(x) ((x) & 7) 104 105 #ifdef DEBUG 106 int ctdebug = 0; 107 #define CDB_FILES 0x01 108 #define CT_BSF 0x02 109 #endif 110 111 ctinit(hd) 112 register struct hp_device *hd; 113 { 114 register struct ct_softc *sc = &ct_softc[hd->hp_unit]; 115 register struct buf *bp; 116 117 for (bp = cttab; bp < &cttab[NCT]; bp++) 118 bp->b_actb = &bp->b_actf; 119 sc->sc_hd = hd; 120 sc->sc_punit = ctpunit(hd->hp_flags); 121 if (ctident(sc, hd) < 0) 122 return(0); 123 ctreset(sc, hd); 124 sc->sc_dq.dq_ctlr = hd->hp_ctlr; 125 sc->sc_dq.dq_unit = hd->hp_unit; 126 sc->sc_dq.dq_slave = hd->hp_slave; 127 sc->sc_dq.dq_driver = &ctdriver; 128 sc->sc_flags |= CTF_ALIVE; 129 return(1); 130 } 131 132 ctident(sc, hd) 133 register struct ct_softc *sc; 134 register struct hp_device *hd; 135 { 136 struct ct_describe desc; 137 u_char stat, cmd[3]; 138 char name[7]; 139 int id, i; 140 141 /* 142 * Read device id and verify that: 143 * 1. It is a CS80 device 144 * 2. It is one of our recognized tape devices 145 * 3. It has the proper physical unit number 146 */ 147 id = hpibid(hd->hp_ctlr, hd->hp_slave); 148 if ((id & 0x200) == 0) 149 return(-1); 150 for (i = 0; i < nctinfo; i++) 151 if (id == ctinfo[i].hwid) 152 break; 153 if (i == nctinfo || sc->sc_punit != ctinfo[i].punit) 154 return(-1); 155 id = i; 156 157 /* 158 * Collect device description. 159 * Right now we only need this to differentiate 7945 from 7946. 160 * Note that we always issue the describe command to unit 0. 161 */ 162 cmd[0] = C_SUNIT(0); 163 cmd[1] = C_SVOL(0); 164 cmd[2] = C_DESC; 165 hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, cmd, sizeof(cmd)); 166 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_EXEC, &desc, 37); 167 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); 168 bzero(name, sizeof(name)); 169 if (!stat) { 170 register int n = desc.d_name; 171 for (i = 5; i >= 0; i--) { 172 name[i] = (n & 0xf) + '0'; 173 n >>= 4; 174 } 175 } 176 switch (ctinfo[id].hwid) { 177 case CT7946ID: 178 if (bcmp(name, "079450", 6) == 0) 179 return(-1); /* not really a 7946 */ 180 /* fall into... */ 181 case CT9144ID: 182 case CT9145ID: 183 sc->sc_type = CT9144; 184 sc->sc_flags |= CTF_CANSTREAM; 185 break; 186 187 case CT7912PID: 188 case CT7914PID: 189 sc->sc_type = CT88140; 190 break; 191 } 192 printf("ct%d: %s %stape\n", hd->hp_unit, ctinfo[id].desc, 193 (sc->sc_flags & CTF_CANSTREAM) ? "streaming " : " "); 194 return(id); 195 } 196 197 ctreset(sc, hd) 198 register struct ct_softc *sc; 199 register struct hp_device *hd; 200 { 201 u_char stat; 202 203 sc->sc_clear.unit = C_SUNIT(sc->sc_punit); 204 sc->sc_clear.cmd = C_CLEAR; 205 hpibsend(hd->hp_ctlr, hd->hp_slave, C_TCMD, &sc->sc_clear, 206 sizeof(sc->sc_clear)); 207 hpibswait(hd->hp_ctlr, hd->hp_slave); 208 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); 209 sc->sc_src.unit = C_SUNIT(CTCTLR); 210 sc->sc_src.nop = C_NOP; 211 sc->sc_src.cmd = C_SREL; 212 sc->sc_src.param = C_REL; 213 hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_src, 214 sizeof(sc->sc_src)); 215 hpibswait(hd->hp_ctlr, hd->hp_slave); 216 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); 217 sc->sc_ssmc.unit = C_SUNIT(sc->sc_punit); 218 sc->sc_ssmc.cmd = C_SSM; 219 sc->sc_ssmc.refm = REF_MASK; 220 sc->sc_ssmc.fefm = FEF_MASK; 221 sc->sc_ssmc.aefm = AEF_MASK; 222 sc->sc_ssmc.iefm = IEF_MASK; 223 hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_ssmc, 224 sizeof(sc->sc_ssmc)); 225 hpibswait(hd->hp_ctlr, hd->hp_slave); 226 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); 227 sc->sc_soptc.unit = C_SUNIT(sc->sc_punit); 228 sc->sc_soptc.nop = C_NOP; 229 sc->sc_soptc.cmd = C_SOPT; 230 sc->sc_soptc.opt = C_SPAR; 231 hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_soptc, 232 sizeof(sc->sc_soptc)); 233 hpibswait(hd->hp_ctlr, hd->hp_slave); 234 hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); 235 } 236 237 /*ARGSUSED*/ 238 ctopen(dev, flag, type, p) 239 dev_t dev; 240 int flag, type; 241 struct proc *p; 242 { 243 register struct ct_softc *sc = &ct_softc[UNIT(dev)]; 244 u_char stat; 245 int cc; 246 247 if (UNIT(dev) >= NCT || (sc->sc_flags & CTF_ALIVE) == 0) 248 return(ENXIO); 249 if (sc->sc_flags & CTF_OPEN) 250 return(EBUSY); 251 sc->sc_soptc.unit = C_SUNIT(sc->sc_punit); 252 sc->sc_soptc.nop = C_NOP; 253 sc->sc_soptc.cmd = C_SOPT; 254 if ((dev & CT_STREAM) && (sc->sc_flags & CTF_CANSTREAM)) 255 sc->sc_soptc.opt = C_SPAR | C_IMRPT; 256 else 257 sc->sc_soptc.opt = C_SPAR; 258 /* 259 * Check the return of hpibsend() and hpibswait(). 260 * Drive could be loading/unloading a tape. If not checked, 261 * driver hangs. 262 */ 263 cc = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 264 C_CMD, &sc->sc_soptc, sizeof(sc->sc_soptc)); 265 if (cc != sizeof(sc->sc_soptc)) 266 return(EBUSY); 267 hpibswait(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave); 268 cc = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, 269 &stat, sizeof(stat)); 270 if (cc != sizeof(stat)) 271 return(EBUSY); 272 sc->sc_tpr = tprintf_open(p); 273 sc->sc_flags |= CTF_OPEN; 274 return(0); 275 } 276 277 /*ARGSUSED*/ 278 ctclose(dev, flag) 279 dev_t dev; 280 int flag; 281 { 282 register struct ct_softc *sc = &ct_softc[UNIT(dev)]; 283 284 if ((sc->sc_flags & (CTF_WRT|CTF_WRTTN)) == (CTF_WRT|CTF_WRTTN) && 285 (sc->sc_flags & CTF_EOT) == 0 ) { /* XXX return error if EOT ?? */ 286 ctcommand(dev, MTWEOF, 2); 287 ctcommand(dev, MTBSR, 1); 288 if (sc->sc_eofp == EOFS - 1) 289 sc->sc_eofs[EOFS - 1]--; 290 else 291 sc->sc_eofp--; 292 #ifdef DEBUG 293 if(ctdebug & CT_BSF) 294 printf("ct%d: ctclose backup eofs prt %d blk %d\n", 295 UNIT(dev), sc->sc_eofp, sc->sc_eofs[sc->sc_eofp]); 296 #endif 297 } 298 if ((minor(dev) & CT_NOREW) == 0) 299 ctcommand(dev, MTREW, 1); 300 sc->sc_flags &= ~(CTF_OPEN | CTF_WRT | CTF_WRTTN); 301 tprintf_close(sc->sc_tpr); 302 #ifdef DEBUG 303 if (ctdebug & CDB_FILES) 304 printf("ctclose: flags %x\n", sc->sc_flags); 305 #endif 306 return(0); /* XXX */ 307 } 308 309 ctcommand(dev, cmd, cnt) 310 dev_t dev; 311 int cmd; 312 register int cnt; 313 { 314 register struct ct_softc *sc = &ct_softc[UNIT(dev)]; 315 register struct buf *bp = &ctbuf[UNIT(dev)]; 316 register struct buf *nbp = 0; 317 318 if (cmd == MTBSF && sc->sc_eofp == EOFS - 1) { 319 cnt = sc->sc_eofs[EOFS - 1] - cnt; 320 ctcommand(dev, MTREW, 1); 321 ctcommand(dev, MTFSF, cnt); 322 cnt = 2; 323 cmd = MTBSR; 324 } 325 326 if (cmd == MTBSF && sc->sc_eofp - cnt < 0) { 327 cnt = 1; 328 cmd = MTREW; 329 } 330 331 sc->sc_flags |= CTF_CMD; 332 sc->sc_bp = bp; 333 sc->sc_cmd = cmd; 334 bp->b_dev = dev; 335 if (cmd == MTFSF) { 336 nbp = (struct buf *)geteblk(MAXBSIZE); 337 bp->b_un.b_addr = nbp->b_un.b_addr; 338 bp->b_bcount = MAXBSIZE; 339 } 340 again: 341 bp->b_flags = B_BUSY; 342 if (cmd == MTBSF) { 343 sc->sc_blkno = sc->sc_eofs[sc->sc_eofp]; 344 sc->sc_eofp--; 345 #ifdef DEBUG 346 if (ctdebug & CT_BSF) 347 printf("ct%d: backup eof pos %d blk %d\n", 348 UNIT(dev), sc->sc_eofp, 349 sc->sc_eofs[sc->sc_eofp]); 350 #endif 351 } 352 ctstrategy(bp); 353 iowait(bp); 354 if (--cnt > 0) 355 goto again; 356 bp->b_flags = 0; 357 sc->sc_flags &= ~CTF_CMD; 358 if (nbp) 359 brelse(nbp); 360 } 361 362 void 363 ctstrategy(bp) 364 register struct buf *bp; 365 { 366 register struct buf *dp; 367 register int s, unit; 368 369 unit = UNIT(bp->b_dev); 370 dp = &cttab[unit]; 371 bp->b_actf = NULL; 372 s = splbio(); 373 bp->b_actb = dp->b_actb; 374 *dp->b_actb = bp; 375 dp->b_actb = &bp->b_actf; 376 if (dp->b_active == 0) { 377 dp->b_active = 1; 378 ctustart(unit); 379 } 380 splx(s); 381 } 382 383 ctustart(unit) 384 register int unit; 385 { 386 register struct ct_softc *sc = &ct_softc[unit]; 387 register struct buf *bp; 388 389 bp = cttab[unit].b_actf; 390 sc->sc_addr = bp->b_un.b_addr; 391 sc->sc_resid = bp->b_bcount; 392 if (hpibreq(&sc->sc_dq)) 393 ctstart(unit); 394 } 395 396 ctstart(unit) 397 register int unit; 398 { 399 register struct ct_softc *sc = &ct_softc[unit]; 400 register struct buf *bp, *dp; 401 register int i; 402 403 bp = cttab[unit].b_actf; 404 again: 405 if ((sc->sc_flags & CTF_CMD) && sc->sc_bp == bp) { 406 switch(sc->sc_cmd) { 407 408 case MTFSF: 409 bp->b_flags |= B_READ; 410 goto mustio; 411 412 case MTBSF: 413 goto gotaddr; 414 415 case MTOFFL: 416 sc->sc_blkno = 0; 417 sc->sc_ul.unit = C_SUNIT(sc->sc_punit); 418 sc->sc_ul.cmd = C_UNLOAD; 419 hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 420 C_CMD, &sc->sc_ul, sizeof(sc->sc_ul)); 421 break; 422 423 case MTWEOF: 424 sc->sc_blkno++; 425 sc->sc_flags |= CTF_WRT; 426 sc->sc_wfm.unit = C_SUNIT(sc->sc_punit); 427 sc->sc_wfm.cmd = C_WFM; 428 hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 429 C_CMD, &sc->sc_wfm, sizeof(sc->sc_wfm)); 430 ctaddeof(unit); 431 break; 432 433 case MTBSR: 434 sc->sc_blkno--; 435 goto gotaddr; 436 437 case MTFSR: 438 sc->sc_blkno++; 439 goto gotaddr; 440 441 case MTREW: 442 sc->sc_blkno = 0; 443 #ifdef DEBUG 444 if(ctdebug & CT_BSF) 445 printf("ct%d: clearing eofs\n", unit); 446 #endif 447 for (i=0; i<EOFS; i++) 448 sc->sc_eofs[i] = 0; 449 sc->sc_eofp = 0; 450 451 gotaddr: 452 sc->sc_ioc.saddr = C_SADDR; 453 sc->sc_ioc.addr0 = 0; 454 sc->sc_ioc.addr = sc->sc_blkno; 455 sc->sc_ioc.unit = C_SUNIT(sc->sc_punit); 456 sc->sc_ioc.nop2 = C_NOP; 457 sc->sc_ioc.slen = C_SLEN; 458 sc->sc_ioc.len = 0; 459 sc->sc_ioc.nop3 = C_NOP; 460 sc->sc_ioc.cmd = C_READ; 461 hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, 462 C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc)); 463 break; 464 } 465 } 466 else { 467 mustio: 468 if ((bp->b_flags & B_READ) && 469 sc->sc_flags & (CTF_BEOF|CTF_EOT)) { 470 #ifdef DEBUG 471 if (ctdebug & CDB_FILES) 472 printf("ctstart: before flags %x\n", sc->sc_flags); 473 #endif 474 if (sc->sc_flags & CTF_BEOF) { 475 sc->sc_flags &= ~CTF_BEOF; 476 sc->sc_flags |= CTF_AEOF; 477 #ifdef DEBUG 478 if (ctdebug & CDB_FILES) 479 printf("ctstart: after flags %x\n", sc->sc_flags); 480 #endif 481 } 482 bp->b_resid = bp->b_bcount; 483 iodone(bp); 484 hpibfree(&sc->sc_dq); 485 if (dp = bp->b_actf) 486 dp->b_actb = bp->b_actb; 487 else 488 cttab[unit].b_actb = bp->b_actb; 489 *bp->b_actb = dp; 490 if ((bp = dp) == NULL) { 491 cttab[unit].b_active = 0; 492 return; 493 } 494 sc->sc_addr = bp->b_un.b_addr; 495 sc->sc_resid = bp->b_bcount; 496 if (hpibreq(&sc->sc_dq)) 497 goto again; 498 return; 499 } 500 sc->sc_flags |= CTF_IO; 501 sc->sc_ioc.unit = C_SUNIT(sc->sc_punit); 502 sc->sc_ioc.saddr = C_SADDR; 503 sc->sc_ioc.addr0 = 0; 504 sc->sc_ioc.addr = sc->sc_blkno; 505 sc->sc_ioc.nop2 = C_NOP; 506 sc->sc_ioc.slen = C_SLEN; 507 sc->sc_ioc.len = sc->sc_resid; 508 sc->sc_ioc.nop3 = C_NOP; 509 if (bp->b_flags & B_READ) 510 sc->sc_ioc.cmd = C_READ; 511 else { 512 sc->sc_ioc.cmd = C_WRITE; 513 sc->sc_flags |= (CTF_WRT | CTF_WRTTN); 514 } 515 hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, 516 &sc->sc_ioc, sizeof(sc->sc_ioc)); 517 } 518 hpibawait(sc->sc_hd->hp_ctlr); 519 } 520 521 ctgo(unit) 522 register int unit; 523 { 524 register struct ct_softc *sc = &ct_softc[unit]; 525 register struct buf *bp; 526 527 bp = cttab[unit].b_actf; 528 hpibgo(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, 529 sc->sc_addr, sc->sc_resid, bp->b_flags & B_READ); 530 } 531 532 /* 533 * Hideous grue to handle EOF/EOT (mostly for reads) 534 */ 535 cteof(sc, bp) 536 register struct ct_softc *sc; 537 register struct buf *bp; 538 { 539 long blks; 540 541 /* 542 * EOT on a write is an error. 543 */ 544 if ((bp->b_flags & B_READ) == 0) { 545 bp->b_resid = bp->b_bcount; 546 bp->b_flags |= B_ERROR; 547 bp->b_error = ENOSPC; 548 sc->sc_flags |= CTF_EOT; 549 return; 550 } 551 /* 552 * Use returned block position to determine how many blocks 553 * we really read and update b_resid. 554 */ 555 blks = sc->sc_stat.c_blk - sc->sc_blkno - 1; 556 #ifdef DEBUG 557 if (ctdebug & CDB_FILES) 558 printf("cteof: bc %d oblk %d nblk %d read %d, resid %d\n", 559 bp->b_bcount, sc->sc_blkno, sc->sc_stat.c_blk, 560 blks, bp->b_bcount - CTKTOB(blks)); 561 #endif 562 if (blks == -1) { /* 9145 on EOF does not change sc_stat.c_blk */ 563 blks = 0; 564 sc->sc_blkno++; 565 } 566 else { 567 sc->sc_blkno = sc->sc_stat.c_blk; 568 } 569 bp->b_resid = bp->b_bcount - CTKTOB(blks); 570 /* 571 * If we are at physical EOV or were after an EOF, 572 * we are now at logical EOT. 573 */ 574 if ((sc->sc_stat.c_aef & AEF_EOV) || 575 (sc->sc_flags & CTF_AEOF)) { 576 sc->sc_flags |= CTF_EOT; 577 sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF); 578 } 579 /* 580 * If we were before an EOF or we have just completed a FSF, 581 * we are now after EOF. 582 */ 583 else if ((sc->sc_flags & CTF_BEOF) || 584 (sc->sc_flags & CTF_CMD) && sc->sc_cmd == MTFSF) { 585 sc->sc_flags |= CTF_AEOF; 586 sc->sc_flags &= ~CTF_BEOF; 587 } 588 /* 589 * Otherwise if we read something we are now before EOF 590 * (and no longer after EOF). 591 */ 592 else if (blks) { 593 sc->sc_flags |= CTF_BEOF; 594 sc->sc_flags &= ~CTF_AEOF; 595 } 596 /* 597 * Finally, if we didn't read anything we just passed an EOF 598 */ 599 else 600 sc->sc_flags |= CTF_AEOF; 601 #ifdef DEBUG 602 if (ctdebug & CDB_FILES) 603 printf("cteof: leaving flags %x\n", sc->sc_flags); 604 #endif 605 } 606 607 ctintr(unit) 608 register int unit; 609 { 610 register struct ct_softc *sc = &ct_softc[unit]; 611 register struct buf *bp, *dp; 612 u_char stat; 613 614 bp = cttab[unit].b_actf; 615 if (bp == NULL) { 616 printf("ct%d: bp == NULL\n", unit); 617 return; 618 } 619 if (sc->sc_flags & CTF_IO) { 620 sc->sc_flags &= ~CTF_IO; 621 if (hpibustart(sc->sc_hd->hp_ctlr)) 622 ctgo(unit); 623 return; 624 } 625 if ((sc->sc_flags & CTF_STATWAIT) == 0) { 626 if (hpibpptest(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave) == 0) { 627 sc->sc_flags |= CTF_STATWAIT; 628 hpibawait(sc->sc_hd->hp_ctlr); 629 return; 630 } 631 } else 632 sc->sc_flags &= ~CTF_STATWAIT; 633 hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, &stat, 1); 634 #ifdef DEBUG 635 if (ctdebug & CDB_FILES) 636 printf("ctintr: before flags %x\n", sc->sc_flags); 637 #endif 638 if (stat) { 639 sc->sc_rsc.unit = C_SUNIT(sc->sc_punit); 640 sc->sc_rsc.cmd = C_STATUS; 641 hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, 642 &sc->sc_rsc, sizeof(sc->sc_rsc)); 643 hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, 644 &sc->sc_stat, sizeof(sc->sc_stat)); 645 hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, 646 &stat, 1); 647 #ifdef DEBUG 648 if (ctdebug & CDB_FILES) 649 printf("ctintr: return stat 0x%x, A%x F%x blk %d\n", 650 stat, sc->sc_stat.c_aef, 651 sc->sc_stat.c_fef, sc->sc_stat.c_blk); 652 #endif 653 if (stat == 0) { 654 if (sc->sc_stat.c_aef & (AEF_EOF | AEF_EOV)) { 655 cteof(sc, bp); 656 ctaddeof(unit); 657 goto done; 658 } 659 if (sc->sc_stat.c_fef & FEF_PF) { 660 ctreset(sc, sc->sc_hd); 661 ctstart(unit); 662 return; 663 } 664 if (sc->sc_stat.c_fef & FEF_REXMT) { 665 ctstart(unit); 666 return; 667 } 668 if (sc->sc_stat.c_aef & 0x5800) { 669 if (sc->sc_stat.c_aef & 0x4000) 670 tprintf(sc->sc_tpr, 671 "ct%d: uninitialized media\n", 672 unit); 673 if (sc->sc_stat.c_aef & 0x1000) 674 tprintf(sc->sc_tpr, 675 "ct%d: not ready\n", unit); 676 if (sc->sc_stat.c_aef & 0x0800) 677 tprintf(sc->sc_tpr, 678 "ct%d: write protect\n", unit); 679 } else { 680 printf("ct%d err: v%d u%d ru%d bn%d, ", 681 unit, 682 (sc->sc_stat.c_vu>>4)&0xF, 683 sc->sc_stat.c_vu&0xF, 684 sc->sc_stat.c_pend, 685 sc->sc_stat.c_blk); 686 printf("R0x%x F0x%x A0x%x I0x%x\n", 687 sc->sc_stat.c_ref, 688 sc->sc_stat.c_fef, 689 sc->sc_stat.c_aef, 690 sc->sc_stat.c_ief); 691 } 692 } else 693 printf("ct%d: request status failed\n", unit); 694 bp->b_flags |= B_ERROR; 695 bp->b_error = EIO; 696 goto done; 697 } else 698 bp->b_resid = 0; 699 if (sc->sc_flags & CTF_CMD) { 700 switch (sc->sc_cmd) { 701 case MTFSF: 702 sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF); 703 sc->sc_blkno += CTBTOK(sc->sc_resid); 704 ctstart(unit); 705 return; 706 case MTBSF: 707 sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF|CTF_EOT); 708 break; 709 case MTBSR: 710 sc->sc_flags &= ~CTF_BEOF; 711 if (sc->sc_flags & CTF_EOT) { 712 sc->sc_flags |= CTF_AEOF; 713 sc->sc_flags &= ~CTF_EOT; 714 } else if (sc->sc_flags & CTF_AEOF) { 715 sc->sc_flags |= CTF_BEOF; 716 sc->sc_flags &= ~CTF_AEOF; 717 } 718 break; 719 case MTWEOF: 720 sc->sc_flags &= ~CTF_BEOF; 721 if (sc->sc_flags & (CTF_AEOF|CTF_EOT)) { 722 sc->sc_flags |= CTF_EOT; 723 sc->sc_flags &= ~CTF_AEOF; 724 } else 725 sc->sc_flags |= CTF_AEOF; 726 break; 727 case MTREW: 728 case MTOFFL: 729 sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF|CTF_EOT); 730 break; 731 } 732 } else { 733 sc->sc_flags &= ~CTF_AEOF; 734 sc->sc_blkno += CTBTOK(sc->sc_resid); 735 } 736 done: 737 #ifdef DEBUG 738 if (ctdebug & CDB_FILES) 739 printf("ctintr: after flags %x\n", sc->sc_flags); 740 #endif 741 if (dp = bp->b_actf) 742 dp->b_actb = bp->b_actb; 743 else 744 cttab[unit].b_actb = bp->b_actb; 745 *bp->b_actb = dp; 746 iodone(bp); 747 hpibfree(&sc->sc_dq); 748 if (cttab[unit].b_actf == NULL) { 749 cttab[unit].b_active = 0; 750 return; 751 } 752 ctustart(unit); 753 } 754 755 ctread(dev, uio) 756 dev_t dev; 757 struct uio *uio; 758 { 759 register int unit = UNIT(dev); 760 761 return(physio(ctstrategy, &ctbuf[unit], dev, B_READ, minphys, uio)); 762 } 763 764 ctwrite(dev, uio) 765 dev_t dev; 766 struct uio *uio; 767 { 768 register int unit = UNIT(dev); 769 770 return(physio(ctstrategy, &ctbuf[unit], dev, B_WRITE, minphys, uio)); 771 } 772 773 /*ARGSUSED*/ 774 ctioctl(dev, cmd, data, flag) 775 dev_t dev; 776 u_long cmd; 777 caddr_t data; 778 int flag; 779 { 780 register struct mtop *op; 781 register int cnt; 782 783 switch (cmd) { 784 785 case MTIOCTOP: 786 op = (struct mtop *)data; 787 switch(op->mt_op) { 788 789 case MTWEOF: 790 case MTFSF: 791 case MTBSR: 792 case MTBSF: 793 case MTFSR: 794 cnt = op->mt_count; 795 break; 796 797 case MTREW: 798 case MTOFFL: 799 cnt = 1; 800 break; 801 802 default: 803 return(EINVAL); 804 } 805 ctcommand(dev, op->mt_op, cnt); 806 break; 807 808 case MTIOCGET: 809 break; 810 811 default: 812 return(EINVAL); 813 } 814 return(0); 815 } 816 817 /*ARGSUSED*/ 818 ctdump(dev) 819 dev_t dev; 820 { 821 return(ENXIO); 822 } 823 824 ctaddeof(unit) 825 int unit; 826 { 827 register struct ct_softc *sc = &ct_softc[unit]; 828 829 if (sc->sc_eofp == EOFS - 1) 830 sc->sc_eofs[EOFS - 1]++; 831 else { 832 sc->sc_eofp++; 833 if (sc->sc_eofp == EOFS - 1) 834 sc->sc_eofs[EOFS - 1] = EOFS; 835 else 836 /* save blkno */ 837 sc->sc_eofs[sc->sc_eofp] = sc->sc_blkno - 1; 838 } 839 #ifdef DEBUG 840 if (ctdebug & CT_BSF) 841 printf("ct%d: add eof pos %d blk %d\n", 842 unit, sc->sc_eofp, 843 sc->sc_eofs[sc->sc_eofp]); 844 #endif 845 } 846 #endif 847