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