1 /* cy.c 1.9 87/01/11 */ 2 3 #include "yc.h" 4 #if NCY > 0 5 /* 6 * Cipher Tapemaster driver. 7 */ 8 #define CYDEBUG 9 #ifdef CYDEBUG 10 int cydebug = 0; 11 #define dlog(params) if (cydebug) log params 12 #else 13 #define dlog(params) /* */ 14 #endif 15 16 #include "param.h" 17 #include "systm.h" 18 #include "vm.h" 19 #include "buf.h" 20 #include "file.h" 21 #include "dir.h" 22 #include "user.h" 23 #include "proc.h" 24 #include "signal.h" 25 #include "uio.h" 26 #include "ioctl.h" 27 #include "mtio.h" 28 #include "errno.h" 29 #include "cmap.h" 30 #include "kernel.h" 31 #include "syslog.h" 32 #include "tty.h" 33 34 #include "../tahoe/cpu.h" 35 #include "../tahoe/mtpr.h" 36 #include "../tahoe/pte.h" 37 38 #include "../tahoevba/vbavar.h" 39 #define CYERROR 40 #include "../tahoevba/cyreg.h" 41 42 /* 43 * There is a ccybuf per tape controller. 44 * It is used as the token to pass to the internal routines 45 * to execute tape ioctls, and also acts as a lock on the slaves 46 * on the controller, since there is only one per controller. 47 * In particular, when the tape is rewinding on close we release 48 * the user process but any further attempts to use the tape drive 49 * before the rewind completes will hang waiting for ccybuf. 50 */ 51 struct buf ccybuf[NCY]; 52 53 /* 54 * Raw tape operations use rcybuf. The driver notices when 55 * rcybuf is being used and allows the user program to contine 56 * after errors and read records not of the standard length. 57 */ 58 struct buf rcybuf[NCY]; 59 60 int cyprobe(), cyslave(), cyattach(); 61 struct buf ycutab[NYC]; 62 short yctocy[NYC]; 63 struct vba_ctlr *cyminfo[NCY]; 64 struct vba_device *ycdinfo[NYC]; 65 long cystd[] = { 0 }; 66 struct vba_driver cydriver = 67 { cyprobe, cyslave, cyattach, 0, cystd, "yc", ycdinfo, "cy", cyminfo }; 68 69 /* bits in minor device */ 70 #define YCUNIT(dev) (minor(dev)&03) 71 #define CYUNIT(dev) (yctocy[YCUNIT(dev)]) 72 #define T_NOREWIND 0x04 73 #define T_1600BPI 0x00 /* pseudo */ 74 #define T_3200BPI 0x08 /* unused */ 75 76 #define INF 1000000L /* close to infinity */ 77 #define CYMAXIO (32*NBPG) /* max i/o size */ 78 79 /* 80 * Software state and shared command areas per controller. 81 * 82 * The i/o buffer must be defined statically to insure 83 * it's address will fit in 20-bits (YECH!!!!!!!!!!!!!!) 84 */ 85 struct cy_softc { 86 struct pte *cy_map; /* pte's for mapped buffer i/o */ 87 caddr_t cy_utl; /* mapped virtual address */ 88 int cy_bs; /* controller's buffer size */ 89 struct cyscp *cy_scp; /* system configuration block address */ 90 struct cyccb cy_ccb; /* channel control block */ 91 struct cyscb cy_scb; /* system configuration block */ 92 struct cytpb cy_tpb; /* tape parameter block */ 93 struct cytpb cy_nop; /* nop parameter block for cyintr */ 94 char cy_buf[CYMAXIO];/* intermediate buffer */ 95 } cy_softc[NCY]; 96 97 /* 98 * Software state per tape transport. 99 */ 100 struct yc_softc { 101 char yc_openf; /* lock against multiple opens */ 102 char yc_lastiow; /* last operation was a write */ 103 short yc_tact; /* timeout is active */ 104 long yc_timo; /* time until timeout expires */ 105 u_short yc_control; /* copy of last tpcb.tpcontrol */ 106 u_short yc_status; /* copy of last tpcb.tpstatus */ 107 u_short yc_resid; /* copy of last bc */ 108 u_short yc_dens; /* prototype control word with density info */ 109 struct tty *yc_ttyp; /* user's tty for errors */ 110 daddr_t yc_blkno; /* block number, for block device tape */ 111 daddr_t yc_nxrec; /* position of end of tape, if known */ 112 int yc_blksize; /* current tape blocksize estimate */ 113 int yc_blks; /* number of I/O operations since open */ 114 int yc_softerrs; /* number of soft I/O errors since open */ 115 } yc_softc[NYC]; 116 117 /* 118 * States for vm->um_tab.b_active, the per controller state flag. 119 * This is used to sequence control in the driver. 120 */ 121 #define SSEEK 1 /* seeking */ 122 #define SIO 2 /* doing seq i/o */ 123 #define SCOM 3 /* sending control command */ 124 #define SREW 4 /* sending a rewind */ 125 #define SERASE 5 /* erase inter-record gap */ 126 #define SERASED 6 /* erased inter-record gap */ 127 128 /* there's no way to figure these out dynamically? -- yech */ 129 struct cyscp *cyscp[] = 130 { (struct cyscp *)0xc0000c06, (struct cyscp *)0xc0000c16 }; 131 #define NCYSCP (sizeof (cyscp) / sizeof (cyscp[0])) 132 133 cyprobe(reg, vm) 134 caddr_t reg; 135 struct vba_ctlr *vm; 136 { 137 register br, cvec; /* must be r12, r11 */ 138 register struct cy_softc *cy; 139 int ctlr = vm->um_ctlr; 140 141 #ifdef lint 142 br = 0; cvec = br; br = cvec; 143 cyintr(0); 144 #endif 145 if (badcyaddr(reg+1)) 146 return (0); 147 if (ctlr > NCYSCP || cyscp[ctlr] == 0) /* XXX */ 148 return (0); 149 cy = &cy_softc[ctlr]; 150 cy->cy_scp = cyscp[ctlr]; /* XXX */ 151 /* 152 * Tapemaster controller must have interrupt handler 153 * disable interrupt, so we'll just kludge things 154 * (stupid multibus non-vectored interrupt crud). 155 */ 156 if (cyinit(ctlr, reg)) { 157 uncache(&cy->cy_tpb.tpcount); 158 cy->cy_bs = htoms(cy->cy_tpb.tpcount); 159 /* 160 * Setup nop parameter block for clearing interrupts. 161 */ 162 cy->cy_nop.tpcmd = CY_NOP; 163 cy->cy_nop.tpcontrol = 0; 164 /* 165 * Allocate page tables. 166 */ 167 vbmapalloc(btoc(CYMAXIO)+1, &cy->cy_map, &cy->cy_utl); 168 169 br = 0x13, cvec = 0x80; /* XXX */ 170 return (sizeof (struct cyccb)); 171 } else 172 return (0); 173 } 174 175 /* 176 * Check to see if a drive is attached to a controller. 177 * Since we can only tell that a drive is there if a tape is loaded and 178 * the drive is placed online, we always indicate the slave is present. 179 */ 180 cyslave(vi, addr) 181 struct vba_device *vi; 182 caddr_t addr; 183 { 184 185 #ifdef lint 186 vi = vi; addr = addr; 187 #endif 188 return (1); 189 } 190 191 cyattach(vi) 192 struct vba_device *vi; 193 { 194 register struct cy_softc *cy; 195 int ctlr = vi->ui_mi->um_ctlr; 196 197 yctocy[vi->ui_unit] = ctlr; 198 cy = &cy_softc[ctlr]; 199 if (vi->ui_slave == 0 && cy->cy_bs) 200 printf("; %dkb buffer", cy->cy_bs/1024); 201 } 202 203 /* 204 * Initialize the controller after a controller reset or 205 * during autoconfigure. All of the system control blocks 206 * are initialized and the controller is asked to configure 207 * itself for later use. 208 */ 209 cyinit(ctlr, addr) 210 int ctlr; 211 register caddr_t addr; 212 { 213 register struct cy_softc *cy = &cy_softc[ctlr]; 214 register int *pte; 215 216 /* 217 * Initialize the system configuration pointer. 218 */ 219 /* make kernel writable */ 220 pte = (int *)vtopte((struct proc *)0, btop(cy->cy_scp)); 221 *pte &= ~PG_PROT; *pte |= PG_KW; 222 mtpr(TBIS, cy->cy_scp); 223 /* load the correct values in the scp */ 224 cy->cy_scp->csp_buswidth = CSP_16BITS; 225 cyldmba(cy->cy_scp->csp_scb, (caddr_t)&cy->cy_scb); 226 /* put it back to read-only */ 227 *pte &= ~PG_PROT; *pte |= PG_KR; 228 mtpr(TBIS, cy->cy_scp); 229 230 /* 231 * Init system configuration block. 232 */ 233 cy->cy_scb.csb_fixed = CSB_FIXED; 234 /* set pointer to the channel control block */ 235 cyldmba(cy->cy_scb.csb_ccb, (caddr_t)&cy->cy_ccb); 236 237 /* 238 * Initialize the chanel control block. 239 */ 240 cy->cy_ccb.cbcw = CBCW_CLRINT; 241 cy->cy_ccb.cbgate = GATE_OPEN; 242 /* set pointer to the tape parameter block */ 243 cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb); 244 245 /* 246 * Issue a nop cmd and get the internal buffer size for buffered i/o. 247 */ 248 cy->cy_tpb.tpcmd = CY_NOP; 249 cy->cy_tpb.tpcontrol = CYCW_16BITS; 250 cy->cy_ccb.cbgate = GATE_CLOSED; 251 CY_GO(addr); 252 if (cywait(&cy->cy_ccb) || (cy->cy_tpb.tpstatus&CYS_ERR)) { 253 uncache(&cy->cy_tpb.tpstatus); 254 printf("cy%d: timeout or err during init, status=%b\n", ctlr, 255 cy->cy_tpb.tpstatus, CYS_BITS); 256 return (0); 257 } 258 cy->cy_tpb.tpcmd = CY_CONFIG; 259 cy->cy_tpb.tpcontrol = CYCW_16BITS; 260 cy->cy_ccb.cbgate = GATE_CLOSED; 261 CY_GO(addr); 262 if (cywait(&cy->cy_ccb) || (cy->cy_tpb.tpstatus&CYS_ERR)) { 263 uncache(&cy->cy_tpb.tpstatus); 264 printf("cy%d: configuration failure, status=%b\n", ctlr, 265 cy->cy_tpb.tpstatus, CYS_BITS); 266 return (0); 267 } 268 return (1); 269 } 270 271 int cytimer(); 272 /* 273 * Open the device. Tapes are unique open 274 * devices, so we refuse if it is already open. 275 * We also check that a tape is available, and 276 * don't block waiting here; if you want to wait 277 * for a tape you should timeout in user code. 278 */ 279 cyopen(dev, flag) 280 dev_t dev; 281 register int flag; 282 { 283 register int ycunit; 284 register struct vba_device *vi; 285 register struct yc_softc *yc; 286 int s; 287 288 ycunit = YCUNIT(dev); 289 if (ycunit >= NYC || (vi = ycdinfo[ycunit]) == 0 || vi->ui_alive == 0) 290 return (ENXIO); 291 if ((yc = &yc_softc[ycunit])->yc_openf) 292 return (EBUSY); 293 yc->yc_openf = 1; 294 #define PACKUNIT(vi) \ 295 (((vi->ui_slave&1)<<11)|((vi->ui_slave&2)<<9)|((vi->ui_slave&4)>>2)) 296 /* no way to select density */ 297 yc->yc_dens = PACKUNIT(vi)|CYCW_IE|CYCW_16BITS; 298 if (yc->yc_tact == 0) { 299 yc->yc_timo = INF; 300 yc->yc_tact = 1; 301 timeout(cytimer, (caddr_t)dev, 5*hz); 302 } 303 cycommand(dev, CY_SENSE, 1); 304 if ((yc->yc_status&CYS_OL) == 0) { /* not on-line */ 305 uprintf("yc%d: not online\n", ycunit); 306 return (ENXIO); 307 } 308 if ((flag&FWRITE) && (yc->yc_status&CYS_WP)) { 309 uprintf("yc%d: no write ring\n", ycunit); 310 return (ENXIO); 311 } 312 yc->yc_blkno = (daddr_t)0; 313 yc->yc_nxrec = INF; 314 yc->yc_lastiow = 0; 315 yc->yc_blksize = 1024; /* guess > 0 */ 316 yc->yc_blks = 0; 317 yc->yc_softerrs = 0; 318 yc->yc_ttyp = u.u_ttyp; 319 return (0); 320 } 321 322 /* 323 * Close tape device. 324 * 325 * If tape was open for writing or last operation was a write, 326 * then write two EOF's and backspace over the last one. 327 * Unless this is a non-rewinding special file, rewind the tape. 328 * Make the tape available to others. 329 */ 330 cyclose(dev, flag) 331 dev_t dev; 332 int flag; 333 { 334 struct yc_softc *yc = &yc_softc[YCUNIT(dev)]; 335 336 if (flag == FWRITE || (flag&FWRITE) && yc->yc_lastiow) { 337 cycommand(dev, CY_WEOF, 2); 338 cycommand(dev, CY_SREV, 1); 339 } 340 if ((minor(dev)&T_NOREWIND) == 0) 341 /* 342 * 0 count means don't hang waiting for rewind complete 343 * rather ccybuf stays busy until the operation completes 344 * preventing further opens from completing by preventing 345 * a CY_SENSE from completing. 346 */ 347 cycommand(dev, CY_REW, 0); 348 if (yc->yc_blks > 10 && yc->yc_softerrs > yc->yc_blks / 10) 349 log(LOG_INFO, "yc%d: %d soft errors in %d blocks\n", 350 YCUNIT(dev), yc->yc_softerrs, yc->yc_blks); 351 dlog((LOG_INFO, "%d soft errors in %d blocks\n", 352 yc->yc_softerrs, yc->yc_blks)); 353 yc->yc_openf = 0; 354 } 355 356 /* 357 * Execute a command on the tape drive a specified number of times. 358 */ 359 cycommand(dev, com, count) 360 dev_t dev; 361 int com, count; 362 { 363 register struct buf *bp; 364 int s; 365 366 bp = &ccybuf[CYUNIT(dev)]; 367 s = spl3(); 368 dlog((LOG_INFO, "cycommand(%o, %x, %d), b_flags %x\n", 369 dev, com, count, bp->b_flags)); 370 while (bp->b_flags&B_BUSY) { 371 /* 372 * This special check is because B_BUSY never 373 * gets cleared in the non-waiting rewind case. 374 */ 375 if (bp->b_repcnt == 0 && (bp->b_flags&B_DONE)) 376 break; 377 bp->b_flags |= B_WANTED; 378 sleep((caddr_t)bp, PRIBIO); 379 } 380 bp->b_flags = B_BUSY|B_READ; 381 splx(s); 382 bp->b_dev = dev; 383 bp->b_repcnt = count; 384 bp->b_command = com; 385 bp->b_blkno = 0; 386 cystrategy(bp); 387 /* 388 * In case of rewind from close; don't wait. 389 * This is the only case where count can be 0. 390 */ 391 if (count == 0) 392 return; 393 biowait(bp); 394 if (bp->b_flags&B_WANTED) 395 wakeup((caddr_t)bp); 396 bp->b_flags &= B_ERROR; 397 } 398 399 cystrategy(bp) 400 register struct buf *bp; 401 { 402 int ycunit = YCUNIT(bp->b_dev); 403 register struct vba_ctlr *vm; 404 register struct buf *dp; 405 int s; 406 407 /* 408 * Put transfer at end of unit queue. 409 */ 410 dlog((LOG_INFO, "cystrategy(%o, %x)\n", bp->b_dev, bp->b_command)); 411 dp = &ycutab[ycunit]; 412 bp->av_forw = NULL; 413 bp->b_errcnt = 0; 414 vm = ycdinfo[ycunit]->ui_mi; 415 /* BEGIN GROT */ 416 if (bp == &rcybuf[CYUNIT(bp->b_dev)]) { 417 if (bp->b_bcount > CYMAXIO) { 418 uprintf("cy%d: i/o size too large\n", vm->um_ctlr); 419 bp->b_error = EIO; 420 bp->b_resid = bp->b_bcount; 421 bp->b_flags |= B_ERROR; 422 biodone(bp); 423 return; 424 } 425 vbasetup(bp, CYMAXIO); 426 } 427 /* END GROT */ 428 s = spl3(); 429 if (dp->b_actf == NULL) { 430 dp->b_actf = bp; 431 /* 432 * Transport not already active... 433 * put at end of controller queue. 434 */ 435 dp->b_forw = NULL; 436 if (vm->um_tab.b_actf == NULL) 437 vm->um_tab.b_actf = dp; 438 else 439 vm->um_tab.b_actl->b_forw = dp; 440 } else 441 dp->b_actl->av_forw = bp; 442 dp->b_actl = bp; 443 /* 444 * If the controller is not busy, get it going. 445 */ 446 if (vm->um_tab.b_active == 0) 447 cystart(vm); 448 splx(s); 449 } 450 451 /* 452 * Start activity on a cy controller. 453 */ 454 cystart(vm) 455 register struct vba_ctlr *vm; 456 { 457 register struct buf *bp, *dp; 458 register struct yc_softc *yc; 459 register struct cy_softc *cy; 460 int ycunit; 461 daddr_t blkno; 462 463 dlog((LOG_INFO, "cystart()\n")); 464 /* 465 * Look for an idle transport on the controller. 466 */ 467 loop: 468 if ((dp = vm->um_tab.b_actf) == NULL) 469 return; 470 if ((bp = dp->b_actf) == NULL) { 471 vm->um_tab.b_actf = dp->b_forw; 472 goto loop; 473 } 474 ycunit = YCUNIT(bp->b_dev); 475 yc = &yc_softc[ycunit]; 476 cy = &cy_softc[CYUNIT(bp->b_dev)]; 477 /* 478 * Default is that last command was NOT a write command; 479 * if we do a write command we will notice this in cyintr(). 480 */ 481 yc->yc_lastiow = 0; 482 if (yc->yc_openf < 0 || 483 (bp->b_command != CY_SENSE && (cy->cy_tpb.tpstatus&CYS_OL) == 0)) { 484 /* 485 * Have had a hard error on a non-raw tape 486 * or the tape unit is now unavailable (e.g. 487 * taken off line). 488 */ 489 dlog((LOG_INFO, "openf %d command %x status %b\n", 490 yc->yc_openf, bp->b_command, cy->cy_tpb.tpstatus, CYS_BITS)); 491 bp->b_flags |= B_ERROR; 492 goto next; 493 } 494 if (bp == &ccybuf[CYUNIT(bp->b_dev)]) { 495 /* 496 * Execute control operation with the specified count. 497 * 498 * Set next state; give 5 minutes to complete 499 * rewind or file mark search, or 10 seconds per 500 * iteration (minimum 60 seconds and max 5 minutes) 501 * to complete other ops. 502 */ 503 if (bp->b_command == CY_REW) { 504 vm->um_tab.b_active = SREW; 505 yc->yc_timo = 5*60; 506 } else { 507 vm->um_tab.b_active = SCOM; 508 yc->yc_timo = imin(imax(10*(int)bp->b_repcnt,60),5*60); 509 } 510 cy->cy_tpb.tprec = htoms(bp->b_repcnt); 511 goto dobpcmd; 512 } 513 /* 514 * The following checks handle boundary cases for operation 515 * on no-raw tapes. On raw tapes the initialization of 516 * yc->yc_nxrec by cyphys causes them to be skipped normally 517 * (except in the case of retries). 518 */ 519 if (bdbtofsb(bp->b_blkno) > yc->yc_nxrec) { 520 /* 521 * Can't read past known end-of-file. 522 */ 523 bp->b_flags |= B_ERROR; 524 bp->b_error = ENXIO; 525 goto next; 526 } 527 if (bdbtofsb(bp->b_blkno) == yc->yc_nxrec && bp->b_flags&B_READ) { 528 /* 529 * Reading at end of file returns 0 bytes. 530 */ 531 bp->b_resid = bp->b_bcount; 532 clrbuf(bp); 533 goto next; 534 } 535 if ((bp->b_flags&B_READ) == 0) 536 /* 537 * Writing sets EOF. 538 */ 539 yc->yc_nxrec = bdbtofsb(bp->b_blkno) + 1; 540 if ((blkno = yc->yc_blkno) == bdbtofsb(bp->b_blkno)) { 541 caddr_t addr; 542 int cmd; 543 544 /* 545 * Choose the appropriate i/o command based on the 546 * transfer size, the estimated block size, 547 * and the controller's internal buffer size. 548 * If we're retrying a read on a raw device because 549 * the original try was a buffer request which failed 550 * due to a record length error, then we force the use 551 * of the raw controller read (YECH!!!!). 552 */ 553 if (bp->b_flags&B_READ) { 554 if ((bp->b_bcount > cy->cy_bs && 555 yc->yc_blksize > cy->cy_bs) || bp->b_errcnt) 556 cmd = CY_RCOM; 557 else 558 cmd = CY_BRCOM; 559 } else { 560 /* 561 * On write error retries erase the 562 * inter-record gap before rewriting. 563 */ 564 if (vm->um_tab.b_errcnt && 565 vm->um_tab.b_active != SERASED) { 566 vm->um_tab.b_active = SERASE; 567 bp->b_command = CY_ERASE; 568 yc->yc_timo = 60; 569 goto dobpcmd; 570 } 571 cmd = (bp->b_bcount > cy->cy_bs) ? CY_WCOM : CY_BWCOM; 572 } 573 vm->um_tab.b_active = SIO; 574 addr = (caddr_t)vbastart(bp, cy->cy_buf, 575 (long *)cy->cy_map, cy->cy_utl); 576 cy->cy_tpb.tpcmd = cmd; 577 cy->cy_tpb.tpcontrol = yc->yc_dens; 578 if (cmd == CY_RCOM || cmd == CY_WCOM) 579 cy->cy_tpb.tpcontrol |= CYCW_LOCK; 580 cy->cy_tpb.tpstatus = 0; 581 cy->cy_tpb.tpcount = 0; 582 cyldmba(cy->cy_tpb.tpdata, (caddr_t)addr); 583 cy->cy_tpb.tprec = 0; 584 if (cmd == CY_BRCOM && bp->b_bcount > cy->cy_bs) 585 cy->cy_tpb.tpsize = htoms(cy->cy_bs); 586 else 587 cy->cy_tpb.tpsize = htoms(bp->b_bcount); 588 cyldmba(cy->cy_tpb.tplink, (caddr_t)0); 589 do 590 uncache(&cy->cy_ccb.cbgate); 591 while (cy->cy_ccb.cbgate == GATE_CLOSED); 592 cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb); 593 cy->cy_ccb.cbcw = CBCW_IE; 594 cy->cy_ccb.cbgate = GATE_CLOSED; 595 dlog((LOG_INFO, "CY_GO(%x) cmd %x control %x size %d\n", 596 vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol, 597 htoms(cy->cy_tpb.tpsize))); 598 CY_GO(vm->um_addr); 599 return; 600 } 601 /* 602 * Tape positioned incorrectly; set to seek forwards 603 * or backwards to the correct spot. This happens 604 * for raw tapes only on error retries. 605 */ 606 vm->um_tab.b_active = SSEEK; 607 if (blkno < bdbtofsb(bp->b_blkno)) { 608 bp->b_command = CY_SFORW; 609 cy->cy_tpb.tprec = htoms(bdbtofsb(bp->b_blkno) - blkno); 610 } else { 611 bp->b_command = CY_SREV; 612 cy->cy_tpb.tprec = htoms(blkno - bdbtofsb(bp->b_blkno)); 613 } 614 yc->yc_timo = imin(imax(10 * htoms(cy->cy_tpb.tprec), 60), 5*60); 615 dobpcmd: 616 /* 617 * Do the command in bp. Reverse direction commands 618 * are indicated by having CYCW_REV or'd into their 619 * value. For these we must set the appropriate bit 620 * in the control field. 621 */ 622 if (bp->b_command&CYCW_REV) { 623 cy->cy_tpb.tpcmd = bp->b_command &~ CYCW_REV; 624 cy->cy_tpb.tpcontrol = yc->yc_dens | CYCW_REV; 625 } else { 626 cy->cy_tpb.tpcmd = bp->b_command; 627 cy->cy_tpb.tpcontrol = yc->yc_dens; 628 } 629 cy->cy_tpb.tpstatus = 0; 630 cy->cy_tpb.tpcount = 0; 631 cyldmba(cy->cy_tpb.tplink, (caddr_t)0); 632 do 633 uncache(&cy->cy_ccb.cbgate); 634 while (cy->cy_ccb.cbgate == GATE_CLOSED); 635 cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb); 636 cy->cy_ccb.cbcw = CBCW_IE; 637 cy->cy_ccb.cbgate = GATE_CLOSED; 638 dlog((LOG_INFO, "CY_GO(%x) cmd %x control %x rec %d\n", 639 vm->um_addr, cy->cy_tpb.tpcmd, cy->cy_tpb.tpcontrol, 640 htoms(cy->cy_tpb.tprec))); 641 CY_GO(vm->um_addr); 642 return; 643 next: 644 /* 645 * Done with this operation due to error or the 646 * fact that it doesn't do anything. Release VERSAbus 647 * resource (if any), dequeue the transfer and continue 648 * processing this slave. 649 */ 650 if (bp == &rcybuf[CYUNIT(bp->b_dev)]) 651 vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl); 652 vm->um_tab.b_errcnt = 0; 653 dp->b_actf = bp->av_forw; 654 biodone(bp); 655 goto loop; 656 } 657 658 /* 659 * Cy interrupt routine. 660 */ 661 cyintr(cipher) 662 int cipher; 663 { 664 struct buf *dp; 665 register struct buf *bp; 666 register struct vba_ctlr *vm = cyminfo[cipher]; 667 register struct cy_softc *cy; 668 register struct yc_softc *yc; 669 int cyunit, err; 670 register state; 671 672 dlog((LOG_INFO, "cyintr(%d)\n", cipher)); 673 /* 674 * First, turn off the interrupt from the controller 675 * (device uses Multibus non-vectored interrupts...yech). 676 */ 677 cy = &cy_softc[vm->um_ctlr]; 678 cy->cy_ccb.cbcw = CBCW_CLRINT; 679 cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_nop); 680 cy->cy_ccb.cbgate = GATE_CLOSED; 681 CY_GO(vm->um_addr); 682 if ((dp = vm->um_tab.b_actf) == NULL) { 683 dlog((LOG_ERR, "cy%d: stray interrupt", vm->um_ctlr)); 684 return; 685 } 686 bp = dp->b_actf; 687 cyunit = CYUNIT(bp->b_dev); 688 cy = &cy_softc[cyunit]; 689 cyuncachetpb(cy); 690 yc = &yc_softc[YCUNIT(bp->b_dev)]; 691 /* 692 * If last command was a rewind and tape is 693 * still moving, wait for the operation to complete. 694 */ 695 if (vm->um_tab.b_active == SREW) { 696 vm->um_tab.b_active = SCOM; 697 if ((cy->cy_tpb.tpstatus&CYS_RDY) == 0) { 698 yc->yc_timo = 5*60; /* 5 minutes */ 699 return; 700 } 701 } 702 /* 703 * An operation completed...record status. 704 */ 705 yc->yc_timo = INF; 706 yc->yc_control = cy->cy_tpb.tpcontrol; 707 yc->yc_status = cy->cy_tpb.tpstatus; 708 yc->yc_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount); 709 dlog((LOG_INFO, "cmd %x control %b status %b resid %d\n", 710 cy->cy_tpb.tpcmd, yc->yc_control, CYCW_BITS, 711 yc->yc_status, CYS_BITS, yc->yc_resid)); 712 if ((bp->b_flags&B_READ) == 0) 713 yc->yc_lastiow = 1; 714 state = vm->um_tab.b_active; 715 vm->um_tab.b_active = 0; 716 /* 717 * Check for errors. 718 */ 719 if (cy->cy_tpb.tpstatus&CYS_ERR) { 720 err = cy->cy_tpb.tpstatus&CYS_ERR; 721 dlog((LOG_INFO, "error %d\n", err)); 722 /* 723 * If we hit the end of tape file, update our position. 724 */ 725 if (err == CYER_FM) { 726 yc->yc_status |= CYS_FM; 727 state = SCOM; /* force completion */ 728 cyseteof(bp); /* set blkno and nxrec */ 729 goto opdone; 730 } 731 /* 732 * Fix up errors which occur due to backspacing over 733 * the beginning of the tape. 734 */ 735 if (err == CYER_BOT && cy->cy_tpb.tpcontrol&CYCW_REV) { 736 yc->yc_status |= CYS_BOT; 737 goto ignoreerr; 738 } 739 /* 740 * If we were reading raw tape and the only error was that the 741 * record was too long, then we don't consider this an error. 742 */ 743 if (bp == &rcybuf[cyunit] && (bp->b_flags&B_READ) && 744 err == CYER_STROBE) { 745 /* 746 * Retry reads with the command changed to 747 * a raw read if necessary. Setting b_errcnt 748 * here causes cystart (above) to force a CY_RCOM. 749 */ 750 if (htoms(cy->cy_tpb.tprec) > cy->cy_bs && 751 bp->b_bcount > cy->cy_bs && 752 yc->yc_blksize <= cy->cy_bs && 753 bp->b_errcnt++ == 0) { 754 yc->yc_blkno++; 755 goto opcont; 756 } else 757 goto ignoreerr; 758 } 759 /* 760 * If error is not hard, and this was an i/o operation 761 * retry up to 8 times. 762 */ 763 if (((1<<err)&CYER_SOFT) && state == SIO) { 764 if (++vm->um_tab.b_errcnt < 7) { 765 yc->yc_blkno++; 766 goto opcont; 767 } 768 } else 769 /* 770 * Hard or non-i/o errors on non-raw tape 771 * cause it to close. 772 */ 773 if (yc->yc_openf > 0 && bp != &rcybuf[cyunit]) 774 yc->yc_openf = -1; 775 /* 776 * Couldn't recover from error. 777 */ 778 tprintf(yc->yc_ttyp, 779 "yc%d: hard error bn%d status=%b, %s\n", YCUNIT(bp->b_dev), 780 bp->b_blkno, yc->yc_status, CYS_BITS, 781 (err < NCYERROR) ? cyerror[err] : ""); 782 bp->b_flags |= B_ERROR; 783 goto opdone; 784 } 785 /* 786 * Advance tape control FSM. 787 */ 788 ignoreerr: 789 /* 790 * If we hit a tape mark update our position. 791 */ 792 if (yc->yc_status&CYS_FM && bp->b_flags&B_READ) { 793 cyseteof(bp); 794 goto opdone; 795 } 796 switch (state) { 797 798 case SIO: 799 /* 800 * Read/write increments tape block number. 801 */ 802 yc->yc_blkno++; 803 yc->yc_blks++; 804 if (vm->um_tab.b_errcnt || yc->yc_status & CYS_CR) 805 yc->yc_softerrs++; 806 yc->yc_blksize = htoms(cy->cy_tpb.tpcount); 807 dlog((LOG_ERR, "blocksize %d", yc->yc_blksize)); 808 goto opdone; 809 810 case SCOM: 811 /* 812 * For forward/backward space record update current position. 813 */ 814 if (bp == &ccybuf[CYUNIT(bp->b_dev)]) 815 switch ((int)bp->b_command) { 816 817 case CY_SFORW: 818 yc->yc_blkno -= bp->b_repcnt; 819 break; 820 821 case CY_SREV: 822 yc->yc_blkno += bp->b_repcnt; 823 break; 824 } 825 goto opdone; 826 827 case SSEEK: 828 yc->yc_blkno = bdbtofsb(bp->b_blkno); 829 goto opcont; 830 831 case SERASE: 832 /* 833 * Completed erase of the inter-record gap due to a 834 * write error; now retry the write operation. 835 */ 836 vm->um_tab.b_active = SERASED; 837 goto opcont; 838 } 839 840 opdone: 841 /* 842 * Reset error count and remove from device queue. 843 */ 844 vm->um_tab.b_errcnt = 0; 845 dp->b_actf = bp->av_forw; 846 /* 847 * Save resid and release resources. 848 */ 849 bp->b_resid = bp->b_bcount - htoms(cy->cy_tpb.tpcount); 850 if (bp == &rcybuf[CYUNIT(bp->b_dev)]) 851 vbadone(bp, cy->cy_buf, (long *)cy->cy_map, cy->cy_utl); 852 biodone(bp); 853 /* 854 * Circulate slave to end of controller 855 * queue to give other slaves a chance. 856 */ 857 vm->um_tab.b_actf = dp->b_forw; 858 if (dp->b_actf) { 859 dp->b_forw = NULL; 860 if (vm->um_tab.b_actf == NULL) 861 vm->um_tab.b_actf = dp; 862 else 863 vm->um_tab.b_actl->b_forw = dp; 864 } 865 if (vm->um_tab.b_actf == 0) 866 return; 867 opcont: 868 cystart(vm); 869 } 870 871 cytimer(dev) 872 int dev; 873 { 874 register struct yc_softc *yc = &yc_softc[YCUNIT(dev)]; 875 int s; 876 877 if (yc->yc_openf == 0 && yc->yc_timo == INF) { 878 yc->yc_tact = 0; 879 return; 880 } 881 if (yc->yc_timo != INF && (yc->yc_timo -= 5) < 0) { 882 printf("yc%d: lost interrupt\n", YCUNIT(dev)); 883 yc->yc_timo = INF; 884 s = spl3(); 885 cyintr(CYUNIT(dev)); 886 splx(s); 887 } 888 timeout(cytimer, (caddr_t)dev, 5*hz); 889 } 890 891 cyseteof(bp) 892 register struct buf *bp; 893 { 894 register int cyunit = CYUNIT(bp->b_dev); 895 register struct cy_softc *cy = &cy_softc[cyunit]; 896 register struct yc_softc *yc = &yc_softc[YCUNIT(bp->b_dev)]; 897 898 if (bp == &ccybuf[cyunit]) { 899 if (yc->yc_blkno > bdbtofsb(bp->b_blkno)) { 900 /* reversing */ 901 yc->yc_nxrec = bdbtofsb(bp->b_blkno) - 902 htoms(cy->cy_tpb.tpcount); 903 yc->yc_blkno = yc->yc_nxrec; 904 } else { 905 yc->yc_blkno = bdbtofsb(bp->b_blkno) + 906 htoms(cy->cy_tpb.tpcount); 907 yc->yc_nxrec = yc->yc_blkno - 1; 908 } 909 return; 910 } 911 /* eof on read */ 912 yc->yc_nxrec = bdbtofsb(bp->b_blkno); 913 } 914 915 cyread(dev, uio) 916 dev_t dev; 917 struct uio *uio; 918 { 919 int errno; 920 921 errno = cyphys(dev, uio); 922 if (errno) 923 return (errno); 924 return (physio(cystrategy, &rcybuf[CYUNIT(dev)], dev, B_READ, minphys, uio)); 925 } 926 927 cywrite(dev, uio) 928 dev_t dev; 929 struct uio *uio; 930 { 931 int errno; 932 933 errno = cyphys(dev, uio); 934 if (errno) 935 return (errno); 936 return (physio(cystrategy, &rcybuf[CYUNIT(dev)], dev, B_WRITE, minphys, uio)); 937 } 938 939 /* 940 * Check that a raw device exits. 941 * If it does, set up the yc_blkno and yc_nxrec 942 * so that the tape will appear positioned correctly. 943 */ 944 cyphys(dev, uio) 945 dev_t dev; 946 struct uio *uio; 947 { 948 register int ycunit = YCUNIT(dev); 949 register daddr_t a; 950 register struct yc_softc *yc; 951 register struct vba_device *vi; 952 953 if (ycunit >= NYC || (vi = ycdinfo[ycunit]) == 0 || vi->ui_alive == 0) 954 return (ENXIO); 955 yc = &yc_softc[ycunit]; 956 a = bdbtofsb(uio->uio_offset >> DEV_BSHIFT); 957 yc->yc_blkno = a; 958 yc->yc_nxrec = a + 1; 959 return (0); 960 } 961 962 /*ARGSUSED*/ 963 cyioctl(dev, cmd, data, flag) 964 caddr_t data; 965 dev_t dev; 966 { 967 int ycunit = YCUNIT(dev); 968 register struct yc_softc *yc = &yc_softc[ycunit]; 969 register struct buf *bp = &ccybuf[CYUNIT(dev)]; 970 register callcount; 971 int fcount, op; 972 struct mtop *mtop; 973 struct mtget *mtget; 974 /* we depend of the values and order of the MT codes here */ 975 static cyops[] = 976 {CY_WEOF,CY_FSF,CY_BSF,CY_SFORW,CY_SREV,CY_REW,CY_OFFL,CY_SENSE}; 977 978 switch (cmd) { 979 980 case MTIOCTOP: /* tape operation */ 981 mtop = (struct mtop *)data; 982 switch (op = mtop->mt_op) { 983 984 case MTWEOF: 985 callcount = mtop->mt_count; 986 fcount = 1; 987 break; 988 989 case MTFSR: case MTBSR: 990 callcount = 1; 991 fcount = mtop->mt_count; 992 break; 993 994 case MTFSF: case MTBSF: 995 callcount = mtop->mt_count; 996 fcount = 1; 997 break; 998 999 case MTREW: case MTOFFL: case MTNOP: 1000 callcount = 1; 1001 fcount = 1; 1002 break; 1003 1004 default: 1005 return (ENXIO); 1006 } 1007 if (callcount <= 0 || fcount <= 0) 1008 return (EINVAL); 1009 while (--callcount >= 0) { 1010 #ifdef notdef 1011 /* 1012 * Gagh, this controller is the pits... 1013 */ 1014 if (op == MTFSF || op == MTBSF) { 1015 do 1016 cycommand(dev, cyops[op], 1); 1017 while ((bp->b_flags&B_ERROR) == 0 && 1018 (yc->yc_status&(CYS_EOT|CYS_BOT|CYS_FM)) == 0); 1019 } else 1020 #endif 1021 cycommand(dev, cyops[op], fcount); 1022 dlog((LOG_INFO, 1023 "cyioctl: status %x, b_flags %x, resid %d\n", 1024 yc->yc_status, bp->b_flags, bp->b_resid)); 1025 if ((bp->b_flags&B_ERROR) || 1026 (yc->yc_status&(CYS_BOT|CYS_EOT))) 1027 break; 1028 } 1029 bp->b_resid = callcount + 1; 1030 return (geterror(bp)); 1031 1032 case MTIOCGET: 1033 cycommand(dev, CY_SENSE, 1); 1034 mtget = (struct mtget *)data; 1035 mtget->mt_dsreg = yc->yc_status; 1036 mtget->mt_erreg = yc->yc_control; 1037 mtget->mt_resid = yc->yc_resid; 1038 mtget->mt_type = MT_ISCY; 1039 break; 1040 1041 default: 1042 return (ENXIO); 1043 } 1044 return (0); 1045 } 1046 1047 /* 1048 * Poll until the controller is ready. 1049 */ 1050 cywait(cp) 1051 register struct cyccb *cp; 1052 { 1053 register int i = 5000; 1054 1055 uncache(&cp->cbgate); 1056 while (i-- > 0 && cp->cbgate == GATE_CLOSED) { 1057 DELAY(1000); 1058 uncache(&cp->cbgate); 1059 } 1060 return (i <= 0); 1061 } 1062 1063 /* 1064 * Load a 20 bit pointer into a Tapemaster pointer. 1065 */ 1066 cyldmba(reg, value) 1067 register caddr_t reg; 1068 caddr_t value; 1069 { 1070 register int v = (int)value; 1071 1072 *reg++ = v; 1073 *reg++ = v >> 8; 1074 *reg++ = 0; 1075 *reg = (v&0xf0000) >> 12; 1076 } 1077 1078 /* 1079 * Unconditionally reset all controllers to their initial state. 1080 */ 1081 cyreset(vba) 1082 int vba; 1083 { 1084 register caddr_t addr; 1085 register int ctlr; 1086 1087 for (ctlr = 0; ctlr < NCY; ctlr++) 1088 if (cyminfo[ctlr] && cyminfo[ctlr]->um_vbanum == vba) { 1089 addr = cyminfo[ctlr]->um_addr; 1090 CY_RESET(addr); 1091 if (!cyinit(ctlr, addr)) { 1092 printf("cy%d: reset failed\n", ctlr); 1093 cyminfo[ctlr] = NULL; 1094 } 1095 } 1096 } 1097 1098 cyuncachetpb(cy) 1099 struct cy_softc *cy; 1100 { 1101 register long *lp = (long *)&cy->cy_tpb; 1102 register int i; 1103 1104 for (i = 0; i < howmany(sizeof (struct cytpb), sizeof (long)); i++) 1105 uncache(lp++); 1106 } 1107 1108 /* 1109 * Dump routine. 1110 */ 1111 cydump(dev) 1112 dev_t dev; 1113 { 1114 register struct cy_softc *cy; 1115 register int bs, num, start; 1116 register caddr_t addr; 1117 int unit = CYUNIT(dev), error; 1118 1119 if (unit >= NCY || cyminfo[unit] == 0 || 1120 (cy = &cy_softc[unit])->cy_bs == 0 || YCUNIT(dev) >= NYC) 1121 return (ENXIO); 1122 if (cywait(&cy->cy_ccb)) 1123 return (EFAULT); 1124 #define phys(a) ((caddr_t)((int)(a)&~0xc0000000)) 1125 addr = phys(cyminfo[unit]->um_addr); 1126 num = maxfree, start = NBPG*2; 1127 while (num > 0) { 1128 bs = num > btoc(CYMAXIO) ? btoc(CYMAXIO) : num; 1129 error = cydwrite(cy, start, bs, addr); 1130 if (error) 1131 return (error); 1132 start += bs, num -= bs; 1133 } 1134 cyweof(cy, addr); 1135 cyweof(cy, addr); 1136 uncache(&cy->cy_tpb); 1137 if (cy->cy_tpb.tpstatus&CYS_ERR) 1138 return (EIO); 1139 cyrewind(cy, addr); 1140 return (0); 1141 } 1142 1143 cydwrite(cy, pf, npf, addr) 1144 register struct cy_softc *cy; 1145 int pf, npf; 1146 caddr_t addr; 1147 { 1148 1149 cy->cy_tpb.tpcmd = CY_WCOM; 1150 cy->cy_tpb.tpcontrol = CYCW_LOCK|CYCW_25IPS|CYCW_16BITS; 1151 cy->cy_tpb.tpstatus = 0; 1152 cy->cy_tpb.tpsize = htoms(npf*NBPG); 1153 cyldmba(cy->cy_tpb.tplink, (caddr_t)0); 1154 cyldmba(cy->cy_tpb.tpdata, (caddr_t)(pf*NBPG)); 1155 cyldmba(cy->cy_ccb.cbtpb, (caddr_t)&cy->cy_tpb); 1156 cy->cy_ccb.cbgate = GATE_CLOSED; 1157 CY_GO(addr); 1158 if (cywait(&cy->cy_ccb)) 1159 return (EFAULT); 1160 uncache(&cy->cy_tpb); 1161 if (cy->cy_tpb.tpstatus&CYS_ERR) 1162 return (EIO); 1163 return (0); 1164 } 1165 1166 cyweof(cy, addr) 1167 register struct cy_softc *cy; 1168 caddr_t addr; 1169 { 1170 1171 cy->cy_tpb.tpcmd = CY_WEOF; 1172 cy->cy_tpb.tpcount = htoms(1); 1173 cy->cy_ccb.cbgate = GATE_CLOSED; 1174 CY_GO(addr); 1175 (void) cywait(&cy->cy_ccb); 1176 } 1177 1178 cyrewind(cy, addr) 1179 register struct cy_softc *cy; 1180 caddr_t addr; 1181 { 1182 1183 cy->cy_tpb.tpcmd = CY_REW; 1184 cy->cy_tpb.tpcount = htoms(1); 1185 cy->cy_ccb.cbgate = GATE_CLOSED; 1186 CY_GO(addr); 1187 (void) cywait(&cy->cy_ccb); 1188 } 1189 #endif 1190