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