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