1 /* rl.c 4.3 83/05/18 */ 2 3 #include "rl.h" 4 #if NRL > 0 5 /* 6 * UNIBUS RL02 disk driver 7 * (not yet converted to 4.1c) 8 */ 9 10 #include "../h/param.h" 11 #include "../h/systm.h" 12 #include "../h/cpu.h" 13 #include "../h/nexus.h" 14 #include "../h/dk.h" 15 #include "../h/buf.h" 16 #include "../h/conf.h" 17 #include "../h/dir.h" 18 #include "../h/user.h" 19 #include "../h/map.h" 20 #include "../h/pte.h" 21 #include "../h/mtpr.h" 22 #include "../h/vm.h" 23 #include "../h/ubavar.h" 24 #include "../h/ubareg.h" 25 #include "../h/cmap.h" 26 27 #include "../h/rlreg.h" 28 29 /* Pending Controller items and statistics */ 30 struct rl_softc { 31 int rl_softas; /* Attention sumary, (seeks pending) */ 32 int rl_ndrive; /* Number of drives on controller */ 33 int rl_wticks; /* Monitor time for function */ 34 } rl_softc[NHL]; 35 36 /* 37 * this struct is used to keep the state of the controller for the last 38 * transfer done. Since only one transfer can be done at a time per 39 * controller, only allocate one for each controller. 40 */ 41 struct rl_stat { 42 short rl_cyl[4]; /* Current cylinder for each drive */ 43 short rl_dn; /* drive number currently transferring */ 44 short rl_cylnhd; /* current cylinder and head of transfer */ 45 u_short rl_bleft; /* bytes left to transfer */ 46 u_short rl_bpart; /* bytes transferred */ 47 } rl_stat[NHL]; 48 49 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 50 struct size { 51 daddr_t nblocks; 52 int cyloff; 53 } rl02_sizes[8] = { 54 14440, 0, /* A=cyl 0 thru 360 */ 55 6040, 361, /* B=cyl 361 thru 511 */ 56 20480, 0, /* C=cyl 0 thru 511 */ 57 0, 0, /* D= Not Defined */ 58 0, 0, /* E= Not Defined */ 59 0, 0, /* F= Not Defined */ 60 0, 0, /* G= Not Defined */ 61 0, 0, /* H= Not Defined */ 62 }; 63 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 64 65 int rlprobe(), rlslave(), rlattach(), rldgo(), rlintr(); 66 struct uba_ctlr *rlminfo[NHL]; 67 struct uba_device *rldinfo[NRL]; 68 struct uba_device *rlip[NHL][4]; 69 70 /* RL02 driver structure */ 71 u_short rlstd[] = { 0174400 }; 72 struct uba_driver hldriver = 73 { rlprobe, rlslave, rlattach, rldgo, rlstd, "rl", rldinfo, "hl", rlminfo }; 74 75 /* User table per controller */ 76 struct buf rlutab[NRL]; 77 78 /* RL02 drive structure */ 79 struct RL02 { 80 short nbpt; /* Number of 512 byte blocks/track */ 81 short ntrak; 82 short nbpc; /* Number of 512 byte blocks/cylinder */ 83 short ncyl; 84 short btrak; /* Number of bytes/track */ 85 struct size *sizes; 86 } rl02 = { 87 20, 2, 40, 512, 20*512, rl02_sizes /* rl02/DEC*/ 88 }; 89 90 struct buf rrlbuf[NRL]; 91 92 #define b_cylin b_resid /* Last seek as CYL<<1 | HD */ 93 94 #ifdef INTRLVE 95 daddr_t dkblock(); 96 #endif 97 98 int rlwstart, rlwatch(); /* Have started guardian */ 99 100 /* Check that controller exists */ 101 /*ARGSUSED*/ 102 rlprobe(reg) 103 caddr_t reg; 104 { 105 register int br, cvec; 106 107 #ifdef lint 108 br = 0; cvec = br; br = cvec; 109 #endif 110 ((struct rldevice *)reg)->rlcs = RL_IE | RL_NOOP; /* Enable intrpt */ 111 DELAY(10); /* Ensure interrupt takes place (10 microsec ) */ 112 ((struct rldevice *)reg)->rlcs &= ~RL_IE; /* Disable intrpt */ 113 return (sizeof (struct rldevice)); 114 } 115 116 /* Check that drive exists and is functional*/ 117 rlslave(ui, reg) 118 struct uba_device *ui; 119 caddr_t reg; 120 { 121 register struct rldevice *rladdr = (struct rldevice *)reg; 122 short ctr = 0; 123 124 /* 125 * DEC reports that: 126 * For some unknown reason the RL02 (seems to be only drive 1) 127 * does not return a valid drive status the first time that a 128 * GET STATUS request is issued for the drive, in fact it can 129 * take up to three or more GET STATUS requests to obtain the 130 * correct status. 131 * In order to overcome this, the driver has been modified to 132 * issue a GET STATUS request and validate the drive status 133 * returned. If a valid status is not returned after eight 134 * attempts, then an error message is printed. 135 */ 136 do { 137 rladdr->rlda.getstat = RL_RESET; 138 rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/ 139 rlwait(rladdr); 140 } while( (rladdr->rlmp.getstat&RLMP_STATUS) != RLMP_STATOK && ++ctr<8 ); 141 142 143 if ((rladdr->rlcs & RL_DE) || (ctr >= 8)) 144 return (0); /* Error return */ 145 if ((rladdr->rlmp.getstat & RLMP_DT) == 0 ) { /* NO RL01'S */ 146 printf("rl01 drives not supported (drive %d)\n", ui->ui_slave ); 147 return(0); 148 } 149 return (1); 150 } 151 152 /* Initialize controller */ 153 rlattach(ui) 154 register struct uba_device *ui; 155 { 156 register struct rldevice *rladdr; 157 158 if (rlwstart == 0) { 159 timeout(rlwatch, (caddr_t)0, hz); /* Watch for lost intr */ 160 rlwstart++; 161 } 162 /* Initialize iostat values */ 163 if (ui->ui_dk >= 0) 164 dk_mspw[ui->ui_dk] = .000003906; /* 16bit transfer time? */ 165 rlip[ui->ui_ctlr][ui->ui_slave] = ui; 166 rl_softc[ui->ui_ctlr].rl_ndrive++; /* increment device/ctrl */ 167 rladdr = (struct rldevice *)ui->ui_addr; 168 169 /* reset controller */ 170 rladdr->rlda.getstat = RL_RESET; /* SHOULD BE REPEATED? */ 171 rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT; /* Reset DE bit */ 172 rlwait(rladdr); 173 174 /* Determine disk posistion */ 175 rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR; 176 rlwait(rladdr); 177 178 /* save disk drive posistion */ 179 rl_stat[ui->ui_ctlr].rl_cyl[ui->ui_slave] = 180 (rladdr->rlmp.readhdr & 0177700) >> 6; 181 rl_stat[ui->ui_ctlr].rl_dn = -1; 182 } 183 184 rlopen(dev) 185 dev_t dev; 186 { 187 register int unit = minor(dev) >> 3; 188 register struct uba_device *mi; 189 190 if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0) 191 return (ENXIO); 192 return (0); 193 } 194 195 rlstrategy(bp) 196 register struct buf *bp; 197 { 198 register struct uba_device *ui; 199 register int drive; 200 register struct buf *dp; 201 int partition = minor(bp->b_dev) & 07; 202 long bn, sz; 203 204 sz = (bp->b_bcount+511) >> 9; /* Blocks to transfer */ 205 206 drive = dkunit(bp); /* Drive number */ 207 if (drive >= NRL) 208 goto bad; 209 ui = rldinfo[drive]; /* Controller uba_device */ 210 if (ui == 0 || ui->ui_alive == 0) 211 goto bad; 212 if (bp->b_blkno < 0 || 213 (bn = dkblock(bp))+sz > rl02.sizes[partition].nblocks) 214 goto bad; 215 216 /* bn is in 512 byte block size */ 217 bp->b_cylin = bn/rl02.nbpc + rl02.sizes[partition].cyloff; 218 (void) spl5(); 219 dp = &rlutab[ui->ui_unit]; 220 disksort(dp, bp); 221 if (dp->b_active == 0) { 222 (void) rlustart(ui); 223 bp = &ui->ui_mi->um_tab; 224 if (bp->b_actf && bp->b_active == 0) 225 (void) rlstart(ui->ui_mi); 226 } 227 (void) spl0(); 228 return; 229 230 bad: 231 bp->b_flags |= B_ERROR; 232 iodone(bp); 233 return; 234 } 235 236 /* 237 * Unit start routine. 238 * Seek the drive to be where the data is 239 * and then generate another interrupt 240 * to actually start the transfer. 241 */ 242 rlustart(ui) 243 register struct uba_device *ui; 244 { 245 register struct buf *bp, *dp; 246 register struct uba_ctlr *um; 247 register struct rldevice *rladdr; 248 daddr_t bn; 249 short cyl, sn, hd, diff; 250 251 if (ui == 0) 252 return (0); 253 um = ui->ui_mi; 254 dk_busy &= ~(1<<ui->ui_dk); /* Kernel define, drives busy */ 255 dp = &rlutab[ui->ui_unit]; 256 if ((bp = dp->b_actf) == NULL) 257 goto out; 258 /* 259 * If the controller is active, just remember 260 * that this device has to be positioned... 261 */ 262 if (um->um_tab.b_active) { 263 rl_softc[um->um_ctlr].rl_softas |= 1<<ui->ui_slave; 264 return (0); 265 } 266 /* 267 * If we have already positioned this drive, 268 * then just put it on the ready queue. 269 */ 270 if (dp->b_active) 271 goto done; 272 dp->b_active = 1; /* Posistioning drive */ 273 rladdr = (struct rldevice *)um->um_addr; 274 275 /* 276 * Figure out where this transfer is going to 277 * and see if we are seeked correctly. 278 */ 279 bn = dkblock(bp); /* Block # desired */ 280 /* 281 * these next two look funky... but we need to map 282 * 512 byte logical disk blocks to 256 byte sectors. 283 * (rl02's are stupid). 284 */ 285 sn = (bn % rl02.nbpt) << 1; /* Sector # desired */ 286 hd = (bn / rl02.nbpt) & 1; /* Get head required */ 287 288 diff = (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] >> 1) - bp->b_cylin; 289 if ( diff == 0 && (rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] & 1) == hd) 290 goto done; /* on cylinder and head */ 291 292 search: 293 /* 294 * Not at correct position. 295 */ 296 297 rl_stat[um->um_ctlr].rl_cyl[ui->ui_slave] = (bp->b_cylin << 1) | hd; 298 299 if (diff < 0) 300 rladdr->rlda.seek = -diff << 7 | RLDA_HGH | hd << 4; 301 else 302 rladdr->rlda.seek = diff << 7 | RLDA_LOW | hd << 4; 303 rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK; 304 305 /* 306 * Mark unit busy for iostat. 307 */ 308 if (ui->ui_dk >= 0) { 309 dk_busy |= 1<<ui->ui_dk; 310 dk_seek[ui->ui_dk]++; 311 } 312 rlwait(rladdr); 313 314 /* 315 * fall through since we are now at the correct cylinder 316 */ 317 done: 318 /* 319 * Device is ready to go. 320 * Put it on the ready queue for the controller 321 * (unless its already there.) 322 */ 323 if (dp->b_active != 2) { 324 dp->b_forw = NULL; 325 if (um->um_tab.b_actf == NULL) 326 um->um_tab.b_actf = dp; 327 else 328 um->um_tab.b_actl->b_forw = dp; 329 um->um_tab.b_actl = dp; 330 dp->b_active = 2; /* Request on ready queue */ 331 } 332 out: 333 return (0); 334 } 335 336 /* 337 * Start up a transfer on a drive. 338 */ 339 rlstart(um) 340 register struct uba_ctlr *um; 341 { 342 register struct buf *bp, *dp; 343 register struct uba_device *ui; 344 register struct rldevice *rladdr; 345 register struct rl_stat *st = &rl_stat[um->um_ctlr]; 346 daddr_t bn; 347 short sn, cyl, cmd; 348 349 loop: 350 /* 351 * Pull a request off the controller queue 352 */ 353 if ((dp = um->um_tab.b_actf) == NULL) { 354 st->rl_dn = -1; 355 st->rl_cylnhd = 0; 356 st->rl_bleft = 0; 357 st->rl_bpart = 0; 358 return (0); 359 } 360 if ((bp = dp->b_actf) == NULL) { 361 um->um_tab.b_actf = dp->b_forw; 362 goto loop; 363 } 364 /* 365 * Mark controller busy, and 366 * determine destinationst. 367 */ 368 um->um_tab.b_active++; 369 ui = rldinfo[dkunit(bp)]; /* Controller */ 370 bn = dkblock(bp); /* 512 byte Block number */ 371 cyl = bp->b_cylin << 1; /* Cylinder */ 372 cyl |= (bn / rl02.nbpt) & 1; /* Get head required */ 373 sn = (bn % rl02.nbpt) << 1; /* Sector number */ 374 rladdr = (struct rldevice *)ui->ui_addr; 375 376 /* 377 * Check that controller is ready 378 */ 379 rlwait(rladdr); 380 381 /* 382 * Setup for the transfer, and get in the 383 * UNIBUS adaptor queue. 384 */ 385 rladdr->rlda.rw = cyl<<6 | sn; 386 387 /* save away current transfers drive status */ 388 st->rl_dn = ui->ui_slave; 389 st->rl_cylnhd = cyl; 390 st->rl_bleft = bp->b_bcount; 391 st->rl_bpart = rl02.btrak - (sn * NRLBPSC); 392 393 /* RL02 must seek between cylinders and between tracks */ 394 /* Determine maximum data transfer at this time */ 395 if( st->rl_bleft < st->rl_bpart) 396 st->rl_bpart = st->rl_bleft; 397 398 rladdr->rlmp.rw = -(st->rl_bpart >> 1); 399 if (bp->b_flags & B_READ) 400 cmd = RL_IE | RL_READ | (ui->ui_slave << 8); 401 else 402 cmd = RL_IE | RL_WRITE | (ui->ui_slave << 8); 403 um->um_cmd = cmd; 404 (void) ubago(ui); 405 return (1); 406 } 407 408 /* 409 * Now all ready to go, stuff the registers. 410 */ 411 rldgo(um) 412 register struct uba_ctlr *um; 413 { 414 register struct rldevice *rladdr = (struct rldevice *)um->um_addr; 415 416 417 /* Place in unibus address for transfer (lower 18 bits of um_ubinfo) */ 418 /* Then execute instruction */ 419 rladdr->rlba = um->um_ubinfo; 420 rladdr->rlcs = um->um_cmd|((um->um_ubinfo>>12)&RL_BAE); 421 } 422 423 /* 424 * Handle a disk interrupt. 425 */ 426 rlintr(rl21) 427 register rl21; 428 { 429 register struct buf *bp, *dp; 430 register struct uba_ctlr *um = rlminfo[rl21]; 431 register struct uba_device *ui; 432 register struct rldevice *rladdr = (struct rldevice *)um->um_addr; 433 register unit; 434 struct rl_softc *rl = &rl_softc[um->um_ctlr]; 435 struct rl_stat *st = &rl_stat[um->um_ctlr]; 436 int as = rl->rl_softas; 437 int needie = 1, waitdry, status; 438 439 rl->rl_wticks = 0; 440 rl->rl_softas = 0; 441 442 /* 443 * Get device and block structures, and a pointer 444 * to the uba_device for the drive. 445 */ 446 dp = um->um_tab.b_actf; 447 bp = dp->b_actf; 448 ui = rldinfo[dkunit(bp)]; 449 dk_busy &= ~(1 << ui->ui_dk); /* Clear busy bit */ 450 451 /* 452 * Check for and process errors on 453 * either the drive or the controller. 454 */ 455 if (rladdr->rlcs & RL_ERR) { 456 u_short err; 457 rlwait( rladdr ); 458 459 err = rladdr->rlcs; 460 461 /* get staus and reset controller */ 462 rladdr->rlda.getstat = RL_GSTAT; 463 rladdr->rlcs = (ui->ui_slave << 8) | RL_GETSTAT; 464 rlwait(rladdr); 465 status = rladdr->rlmp.getstat; 466 467 /* reset drive */ 468 rladdr->rlda.getstat = RL_RESET; 469 rladdr->rlcs = (ui->ui_slave <<8) | RL_GETSTAT; /* Get status*/ 470 rlwait(rladdr); 471 472 if ( (status & RLMP_WL) == RLMP_WL ) { 473 /* 474 * Give up on write protected devices 475 * immediately. 476 */ 477 printf("rl%d: write protected\n", dkunit(bp)); 478 bp->b_flags |= B_ERROR; 479 } else if (++um->um_tab.b_errcnt > 10) { 480 /* 481 * After 10 retries give up. 482 */ 483 harderr(bp, "rl"); 484 printf("cs=%b mp=%b\n", 485 err, RLCS_BITS, status, RLER_BITS); 486 487 bp->b_flags |= B_ERROR; 488 } else 489 um->um_tab.b_active = 0; /* force retry */ 490 491 /* Determine disk posistion */ 492 rladdr->rlcs = (ui->ui_slave << 8) | RL_RHDR; 493 rlwait(rladdr); 494 495 /* save disk drive posistion */ 496 st->rl_cyl[ui->ui_slave] = (rladdr->rlmp.readhdr & 0177700) >> 6; 497 } 498 499 /* 500 * If still ``active'', then don't need any more retries. 501 */ 502 if (um->um_tab.b_active) { 503 /* RL02 check if more data from previous request */ 504 if ( (bp->b_flags & B_ERROR) == 0 && 505 (st->rl_bleft -= st->rl_bpart) > 0 ) { 506 /* 507 * the following code was modeled from the rk07 508 * driver when an ECC error occured. It has to 509 * fix the bits then restart the transfer which is 510 * what we have to do (restart transfer). 511 */ 512 int reg, npf, o, cmd, ubaddr, diff, head; 513 514 515 /* seek to next head/track */ 516 517 /* increment head and/or cylinder */ 518 st->rl_cylnhd++; 519 diff = (st->rl_cyl[ui->ui_slave] >> 1) - 520 (st->rl_cylnhd >> 1); 521 st->rl_cyl[ui->ui_slave] = st->rl_cylnhd; 522 head = st->rl_cylnhd & 1; 523 rlwait( rladdr ); 524 525 if ( diff < 0 ) 526 rladdr->rlda.seek = -diff << 7 | RLDA_HGH | head << 4; 527 else 528 rladdr->rlda.seek = diff << 7 | RLDA_LOW | head << 4; 529 rladdr->rlcs = (ui->ui_slave << 8) | RL_SEEK; 530 531 npf = btop( bp->b_bcount - st->rl_bleft ); 532 reg = btop(um->um_ubinfo&0x3ffff) + npf; 533 o = (int)bp->b_un.b_addr & PGOFSET; 534 ubapurge(um); 535 um->um_tab.b_active++; 536 537 rlwait( rladdr ); 538 rladdr->rlda.rw = st->rl_cylnhd << 6; 539 if ( st->rl_bleft < (st->rl_bpart = rl02.btrak) ) 540 st->rl_bpart = st->rl_bleft; 541 rladdr->rlmp.rw = -(st->rl_bpart >> 1); 542 cmd = (bp->b_flags&B_READ ? RL_READ : RL_WRITE) | 543 RL_IE | (ui->ui_slave << 8); 544 ubaddr = (int)ptob(reg) + o; 545 cmd |= ((ubaddr >> 12) & RL_BAE); 546 547 rladdr->rlba = ubaddr; 548 rladdr->rlcs = cmd; 549 return; 550 } 551 552 um->um_tab.b_active = 0; 553 um->um_tab.b_errcnt = 0; 554 dp->b_active = 0; 555 dp->b_errcnt = 0; 556 557 /* "b_resid" words remaining after error */ 558 bp->b_resid = st->rl_bleft; 559 um->um_tab.b_actf = dp->b_forw; 560 dp->b_actf = bp->av_forw; 561 562 retry: 563 st->rl_dn = -1; 564 st->rl_bpart = st->rl_bleft = 0; 565 iodone(bp); 566 /* 567 * If this unit has more work to do, 568 * then start it up right away. 569 */ 570 if (dp->b_actf) 571 if (rlustart(ui)) 572 needie = 0; 573 as &= ~(1<<ui->ui_slave); 574 } else 575 as |= (1<<ui->ui_slave); 576 /* 577 * Release unibus resources and flush data paths. 578 */ 579 ubadone(um); 580 581 /* reset state info */ 582 st->rl_dn = -1; 583 st->rl_cylnhd = st->rl_bpart = st->rl_bleft = 0; 584 585 doattn: 586 /* 587 * Process other units which need attention. 588 * For each unit which needs attention, call 589 * the unit start routine to place the slave 590 * on the controller device queue. 591 */ 592 while (unit = ffs(as)) { 593 unit--; /* was 1 origin */ 594 as &= ~(1<<unit); 595 (void) rlustart(rlip[rl21][unit]); 596 } 597 /* 598 * If the controller is not transferring, but 599 * there are devices ready to transfer, start 600 * the controller. 601 */ 602 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 603 (void) rlstart(um); 604 } 605 606 rlwait(rladdr) 607 register struct rldevice *rladdr; 608 { 609 610 while ((rladdr->rlcs & RL_CRDY) == 0) 611 continue; /* Wait */ 612 } 613 614 rlread(dev, uio) 615 dev_t dev; 616 struct uio *uio; 617 { 618 register int unit = minor(dev) >> 3; 619 620 if (unit >= NRL) 621 return (ENXIO); 622 return (physio(rlstrategy, &rrlbuf[unit], dev, B_READ, minphys, uio)); 623 } 624 625 rlwrite(dev, uio) 626 dev_t dev; 627 struct uio *uio; 628 { 629 register int unit = minor(dev) >> 3; 630 631 if (unit >= NRL) 632 return (ENXIO); 633 return (physio(rlstrategy, &rrlbuf[unit], dev, B_WRITE, minphys, uio)); 634 } 635 636 /* 637 * Reset driver after UBA init. 638 * Cancel software state of all pending transfers 639 * and restart all units and the controller. 640 */ 641 rlreset(uban) 642 int uban; 643 { 644 register struct uba_ctlr *um; 645 register struct uba_device *ui; 646 register struct rldevice *rladdr; 647 register struct rl_stat *st; 648 register int rl21, unit; 649 650 for (rl21 = 0; rl21 < NHL; rl21++) { 651 if ((um = rlminfo[rl21]) == 0 || um->um_ubanum != uban || 652 um->um_alive == 0) 653 continue; 654 printf(" Reset hl%d", rl21); 655 rladdr = (struct rldevice *)um->um_addr; 656 st = &rl_stat[rl21]; 657 um->um_tab.b_active = 0; 658 um->um_tab.b_actf = um->um_tab.b_actl = 0; 659 if (um->um_ubinfo) { 660 printf("<%d>", (um->um_ubinfo>>28)&0xf); 661 um->um_ubinfo = 0; 662 } 663 664 /* reset controller */ 665 st->rl_dn = -1; 666 st->rl_cylnhd = 0; 667 st->rl_bleft = 0; 668 st->rl_bpart = 0; 669 rlwait(rladdr); 670 671 for (unit = 0; unit < NRL; unit++) { 672 rladdr->rlcs = (unit << 8) | RL_GETSTAT; 673 rlwait(rladdr); 674 675 /* Determine disk posistion */ 676 rladdr->rlcs = (unit << 8) | RL_RHDR; 677 rlwait(rladdr); 678 679 /* save disk drive posistion */ 680 st->rl_cyl[unit] = 681 (rladdr->rlmp.readhdr & 0177700) >> 6; 682 683 if ((ui = rldinfo[unit]) == 0) 684 continue; 685 if (ui->ui_alive == 0 || ui->ui_mi != um) 686 continue; 687 rlutab[unit].b_active = 0; 688 (void) rlustart(ui); 689 } 690 (void) rlstart(um); 691 } 692 } 693 694 /* 695 * Wake up every second and if an interrupt is pending 696 * but nothing has happened increment a counter. 697 * If nothing happens for 20 seconds, reset the UNIBUS 698 * and begin anew. 699 */ 700 rlwatch() 701 { 702 register struct uba_ctlr *um; 703 register rl21, unit; 704 register struct rl_softc *rl; 705 706 timeout(rlwatch, (caddr_t)0, hz); 707 for (rl21 = 0; rl21 < NHL; rl21++) { 708 um = rlminfo[rl21]; 709 if (um == 0 || um->um_alive == 0) 710 continue; 711 rl = &rl_softc[rl21]; 712 if (um->um_tab.b_active == 0) { 713 for (unit = 0; unit < NRL; unit++) 714 if (rlutab[unit].b_active && 715 rldinfo[unit]->ui_mi == um) 716 goto active; 717 rl->rl_wticks = 0; 718 continue; 719 } 720 active: 721 rl->rl_wticks++; 722 if (rl->rl_wticks >= 20) { 723 rl->rl_wticks = 0; 724 printf("hl%d: lost interrupt\n", rl21); 725 ubareset(um->um_ubanum); 726 } 727 } 728 } 729 730 rldump(dev) 731 dev_t dev; 732 { 733 /* don't think there is room on swap for it anyway. */ 734 } 735 736 rlsize(dev) 737 dev_t dev; 738 { 739 int unit = minor(dev) >> 3; 740 struct uba_device *ui; 741 struct rlst *st; 742 743 if (unit >= NRL || (ui = rldinfo[unit]) == 0 || ui->ui_alive == 0) 744 return (-1); 745 st = &rl02; 746 return (st->sizes[minor(dev) & 07].nblocks); 747 } 748 #endif 749