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