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