1 /* rk.c 4.16 02/27/81 */ 2 3 #include "rk.h" 4 #if NHK > 0 5 int rkflags,rkerrs; /* GROT */ 6 /* 7 * RK11/RK07 disk driver 8 * 9 * This driver mimics up.c; see it for an explanation of common code. 10 * 11 * THIS DRIVER DOESN'T DEAL WITH DRIVES SPINNING DOWN AND UP 12 */ 13 #define DELAY(i) { register int j; j = i; while (--j > 0); } 14 #include "../h/param.h" 15 #include "../h/systm.h" 16 #include "../h/buf.h" 17 #include "../h/conf.h" 18 #include "../h/dir.h" 19 #include "../h/user.h" 20 #include "../h/pte.h" 21 #include "../h/map.h" 22 #include "../h/vm.h" 23 #include "../h/uba.h" 24 #include "../h/dk.h" 25 #include "../h/cpu.h" 26 #include "../h/cmap.h" 27 28 #include "../h/rkreg.h" 29 30 struct rk_softc { 31 int sc_softas; 32 int sc_ndrive; 33 int sc_wticks; 34 int sc_recal; 35 } rk_softc[NHK]; 36 37 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 38 struct size 39 { 40 daddr_t nblocks; 41 int cyloff; 42 } rk7_sizes[] ={ 43 15884, 0, /* A=cyl 0 thru 240 */ 44 10032, 241, /* B=cyl 241 thru 392 */ 45 53790, 0, /* C=cyl 0 thru 814 */ 46 0, 0, 47 0, 0, 48 0, 0, 49 27786, 393, /* G=cyl 393 thru 813 */ 50 0, 0, 51 }; 52 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 53 54 int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 55 struct uba_minfo *rkminfo[NHK]; 56 struct uba_dinfo *rkdinfo[NRK]; 57 struct uba_dinfo *rkip[NHK][4]; 58 59 u_short rkstd[] = { 0777440, 0 }; 60 struct uba_driver hkdriver = 61 { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 62 struct buf rkutab[NRK]; 63 short rkcyl[NRK]; 64 65 struct rkst { 66 short nsect; 67 short ntrak; 68 short nspc; 69 short ncyl; 70 struct size *sizes; 71 } rkst[] = { 72 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, 73 }; 74 75 u_char rk_offset[16] = 76 { P400,M400,P400,M400,P800,M800,P800,M800,P1200,M1200,P1200,M1200,0,0,0,0 }; 77 78 struct buf rrkbuf[NRK]; 79 80 #define b_cylin b_resid 81 82 #ifdef INTRLVE 83 daddr_t dkblock(); 84 #endif 85 86 int rkwstart, rkwatch(); 87 88 rkprobe(reg) 89 caddr_t reg; 90 { 91 register int br, cvec; 92 93 #ifdef lint 94 br = 0; cvec = br; br = cvec; 95 #endif 96 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 97 DELAY(10); 98 ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 99 return (1); 100 } 101 102 rkslave(ui, reg) 103 struct uba_dinfo *ui; 104 caddr_t reg; 105 { 106 register struct rkdevice *rkaddr = (struct rkdevice *)reg; 107 108 rkaddr->rkcs1 = RK_CDT; 109 rkaddr->rkcs2 = ui->ui_slave; 110 rkwait(rkaddr); 111 /* SHOULD TRY THIS BY PULLING A PLUG */ 112 /* A DELAY OR SOMETHING MAY BE NEEDED */ 113 if (rkaddr->rkcs2&RK_NED) { 114 rkaddr->rkcs1 = RK_CDT|RK_CCLR; 115 return (0); 116 } 117 return (1); 118 } 119 120 rkattach(ui) 121 register struct uba_dinfo *ui; 122 { 123 124 if (rkwstart == 0) { 125 timeout(rkwatch, (caddr_t)0, hz); 126 rkwstart++; 127 } 128 if (ui->ui_dk >= 0) 129 dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 130 rkip[ui->ui_ctlr][ui->ui_slave] = ui; 131 rk_softc[ui->ui_ctlr].sc_ndrive++; 132 rkcyl[ui->ui_unit] = -1; 133 } 134 135 rkstrategy(bp) 136 register struct buf *bp; 137 { 138 register struct uba_dinfo *ui; 139 register struct rkst *st; 140 register int unit; 141 register struct buf *dp; 142 int xunit = minor(bp->b_dev) & 07; 143 long bn, sz; 144 145 sz = (bp->b_bcount+511) >> 9; 146 unit = dkunit(bp); 147 if (unit >= NRK) 148 goto bad; 149 ui = rkdinfo[unit]; 150 if (ui == 0 || ui->ui_alive == 0) 151 goto bad; 152 st = &rkst[ui->ui_type]; 153 if (bp->b_blkno < 0 || 154 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 155 goto bad; 156 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 157 (void) spl5(); 158 dp = &rkutab[ui->ui_unit]; 159 disksort(dp, bp); 160 if (dp->b_active == 0) { 161 (void) rkustart(ui); 162 bp = &ui->ui_mi->um_tab; 163 if (bp->b_actf && bp->b_active == 0) 164 (void) rkstart(ui->ui_mi); 165 } 166 (void) spl0(); 167 return; 168 169 bad: 170 bp->b_flags |= B_ERROR; 171 iodone(bp); 172 return; 173 } 174 175 rkustart(ui) 176 register struct uba_dinfo *ui; 177 { 178 register struct buf *bp, *dp; 179 register struct uba_minfo *um; 180 register struct rkdevice *rkaddr; 181 register struct rkst *st; 182 daddr_t bn; 183 int sn, csn; 184 int didie = 0; 185 186 if (ui == 0) 187 return (0); 188 dk_busy &= ~(1<<ui->ui_dk); 189 dp = &rkutab[ui->ui_unit]; 190 if ((bp = dp->b_actf) == NULL) 191 goto out; 192 um = ui->ui_mi; 193 if (um->um_tab.b_active) { 194 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 195 return (0); 196 } 197 rkaddr = (struct rkdevice *)um->um_addr; 198 rkaddr->rkcs1 = RK_CDT|RK_CERR; 199 rkaddr->rkcs2 = ui->ui_slave; 200 rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 201 rkwait(rkaddr); 202 if (dp->b_active) 203 goto done; 204 dp->b_active = 1; 205 if ((rkaddr->rkds & RK_VV) == 0) { 206 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 207 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; 208 rkwait(rkaddr); 209 didie = 1; 210 } 211 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 212 goto done; 213 if (bp->b_cylin == rkcyl[ui->ui_unit]) 214 goto done; 215 rkaddr->rkcyl = bp->b_cylin; 216 rkcyl[ui->ui_unit] = bp->b_cylin; 217 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_SEEK|RK_GO; 218 didie = 1; 219 if (ui->ui_dk >= 0) { 220 dk_busy |= 1<<ui->ui_dk; 221 dk_seek[ui->ui_dk]++; 222 } 223 goto out; 224 done: 225 if (dp->b_active != 2) { 226 dp->b_forw = NULL; 227 if (um->um_tab.b_actf == NULL) 228 um->um_tab.b_actf = dp; 229 else 230 um->um_tab.b_actl->b_forw = dp; 231 um->um_tab.b_actl = dp; 232 dp->b_active = 2; 233 } 234 out: 235 return (didie); 236 } 237 238 rkstart(um) 239 register struct uba_minfo *um; 240 { 241 register struct buf *bp, *dp; 242 register struct uba_dinfo *ui; 243 register struct rkdevice *rkaddr; 244 struct rkst *st; 245 daddr_t bn; 246 int sn, tn, cmd; 247 248 loop: 249 if ((dp = um->um_tab.b_actf) == NULL) 250 return (0); 251 if ((bp = dp->b_actf) == NULL) { 252 um->um_tab.b_actf = dp->b_forw; 253 goto loop; 254 } 255 um->um_tab.b_active++; 256 ui = rkdinfo[dkunit(bp)]; 257 bn = dkblock(bp); 258 st = &rkst[ui->ui_type]; 259 sn = bn%st->nspc; 260 tn = sn/st->nsect; 261 sn %= st->nsect; 262 rkaddr = (struct rkdevice *)ui->ui_addr; 263 rkaddr->rkcs1 = RK_CDT|RK_CERR; 264 rkaddr->rkcs2 = ui->ui_slave; 265 rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 266 rkwait(rkaddr); 267 if (um->um_tab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { 268 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 269 rkaddr->rkcs1 = RK_CDT|RK_OFFSET|RK_GO; 270 rkwait(rkaddr); 271 } 272 rkaddr->rkcyl = bp->b_cylin; 273 rkcyl[ui->ui_unit] = bp->b_cylin; 274 rkaddr->rkda = (tn << 8) + sn; 275 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 276 if (bp->b_flags & B_READ) 277 cmd = RK_CDT|RK_IE|RK_READ|RK_GO; 278 else 279 cmd = RK_CDT|RK_IE|RK_WRITE|RK_GO; 280 um->um_cmd = cmd; 281 ubago(ui); 282 return (1); 283 } 284 285 rkdgo(um) 286 register struct uba_minfo *um; 287 { 288 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 289 290 rkaddr->rkba = um->um_ubinfo; 291 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 292 } 293 294 rkintr(rk11) 295 int rk11; 296 { 297 register struct uba_minfo *um = rkminfo[rk11]; 298 register struct uba_dinfo *ui; 299 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 300 register struct buf *bp, *dp; 301 int unit; 302 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 303 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 304 int needie = 1; 305 306 sc->sc_wticks = 0; 307 sc->sc_softas = 0; 308 if (um->um_tab.b_active) { 309 dp = um->um_tab.b_actf; 310 bp = dp->b_actf; 311 ui = rkdinfo[dkunit(bp)]; 312 dk_busy &= ~(1 << ui->ui_dk); 313 if (rkaddr->rkcs1 & RK_CERR) { 314 int recal; 315 #ifdef notdef 316 int del = 0; 317 #endif 318 u_short ds = rkaddr->rkds; 319 u_short cs2 = rkaddr->rkcs2; 320 u_short er = rkaddr->rker; 321 if (sc->sc_recal) 322 printf("recal CERR\n"); 323 rkerrs++; 324 #ifdef notdef 325 /* THIS ATTEMPTED TO FIND OUT IF THE DRIVE IS SPUN */ 326 /* DOWN BUT IT DOESN'T SEEM TO WORK... THE DRIVE SEEMS TO */ 327 /* TELL PAINFULLY LITTLE WHEN IT IS SPUN DOWN (I.E. NOTHING CHANGES) */ 328 /* THE DRIVE JUST KEEPS SAYING IT WANTS ATTENTION AND BLOWING ALL COMMANDS */ 329 if (ds & RK_CDA) { 330 rkaddr->rkcs1 = RK_CDT|RK_CERR; 331 rkaddr->rkcs2 = ui->ui_slave; 332 rkaddr->rkcs1 = RK_CDT|RK_SELECT|RK_GO; 333 rkwait(rkaddr); 334 while ((rkaddr->rkds & RK_SVAL) == 0) 335 if (++del > 512) 336 break; 337 } 338 if (del > 512) { 339 printf("rk%d is down\n", dkunit(bp)); 340 bp->b_flags |= B_ERROR; 341 } else 342 #endif 343 if (ds & RK_WLE) { 344 printf("rk%d is write locked\n", dkunit(bp)); 345 bp->b_flags |= B_ERROR; 346 } else if (++um->um_tab.b_errcnt > 28 || 347 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 348 bp->b_flags |= B_ERROR; 349 harderr(bp); 350 printf("rk%d cs2 %b ds %b er %b\n", 351 dkunit(bp), cs2, RKCS2_BITS, ds, 352 RKDS_BITS, er, RKER_BITS); 353 } else 354 um->um_tab.b_active = 0; 355 if (cs2&RK_MDS) { 356 rkaddr->rkcs2 = RK_SCLR; 357 goto retry; 358 } 359 recal = 0; 360 if (ds&RK_DROT || er&(RK_OPI|RK_SKI|RK_UNS) || 361 (um->um_tab.b_errcnt&07) == 4) 362 recal = 1; 363 if ((er & (RK_DCK|RK_ECH)) == RK_DCK) 364 if (rkecc(ui)) 365 return; 366 rkaddr->rkcs1 = RK_CDT|RK_CCLR; 367 rkaddr->rkcs2 = ui->ui_slave; 368 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 369 rkwait(rkaddr); 370 if (recal && um->um_tab.b_active == 0) { 371 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_RECAL|RK_GO; 372 rkcyl[ui->ui_unit] = -1; 373 rkwait(rkaddr); 374 um->um_tab.b_active = 1; 375 sc->sc_recal = 1; 376 return; 377 } 378 } 379 retry: 380 if (sc->sc_recal) { 381 sc->sc_recal = 0; 382 um->um_tab.b_active = 0; 383 } 384 ubadone(um); 385 if (um->um_tab.b_active) { 386 um->um_tab.b_active = 0; 387 um->um_tab.b_errcnt = 0; 388 um->um_tab.b_actf = dp->b_forw; 389 dp->b_active = 0; 390 dp->b_errcnt = 0; 391 dp->b_actf = bp->av_forw; 392 bp->b_resid = -rkaddr->rkwc * sizeof(short); 393 iodone(bp); 394 if (dp->b_actf) 395 if (rkustart(ui)) 396 needie = 0; 397 } 398 as &= ~(1<<ui->ui_slave); 399 } 400 for (unit = 0; as; as >>= 1, unit++) 401 if (as & 1) 402 if (rkustart(rkip[rk11][unit])) 403 needie = 0; 404 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 405 if (rkstart(um)) 406 needie = 0; 407 if (needie) 408 rkaddr->rkcs1 = RK_CDT|RK_IE; 409 } 410 411 rkwait(addr) 412 register struct rkdevice *addr; 413 { 414 415 while ((addr->rkcs1 & RK_CRDY) == 0) 416 ; 417 } 418 419 rkread(dev) 420 dev_t dev; 421 { 422 register int unit = minor(dev) >> 3; 423 424 if (unit >= NRK) 425 u.u_error = ENXIO; 426 else 427 physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys); 428 } 429 430 rkwrite(dev) 431 dev_t dev; 432 { 433 register int unit = minor(dev) >> 3; 434 435 if (unit >= NRK) 436 u.u_error = ENXIO; 437 else 438 physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys); 439 } 440 441 rkecc(ui) 442 register struct uba_dinfo *ui; 443 { 444 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 445 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 446 register struct uba_minfo *um = ui->ui_mi; 447 register struct rkst *st; 448 struct uba_regs *ubp = ui->ui_hd->uh_uba; 449 register int i; 450 caddr_t addr; 451 int reg, bit, byte, npf, mask, o, cmd, ubaddr; 452 int bn, cn, tn, sn; 453 454 npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount) - 1; 455 reg = btop(um->um_ubinfo&0x3ffff) + npf; 456 o = (int)bp->b_un.b_addr & PGOFSET; 457 printf("%D ", bp->b_blkno+npf); 458 prdev("ECC", bp->b_dev); 459 mask = rk->rkec2; 460 if (mask == 0) { 461 rk->rkatt = 0; 462 return (0); 463 } 464 ubapurge(um); 465 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 466 bit = i&07; 467 i = (i&~07)>>3; 468 byte = i + o; 469 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 470 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 471 (byte & PGOFSET); 472 putmemc(addr, getmemc(addr)^(mask<<bit)); 473 byte++; 474 i++; 475 bit -= 8; 476 } 477 um->um_tab.b_active++; /* Either complete or continuing... */ 478 if (rk->rkwc == 0) 479 return (0); 480 #ifdef notdef 481 rk->rkcs1 |= RK_GO; 482 #else 483 rk->rkcs1 = RK_CDT|RK_CCLR; 484 rk->rkcs2 = ui->ui_slave; 485 rk->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 486 rkwait(rk); 487 bn = dkblock(bp); 488 st = &rkst[ui->ui_type]; 489 cn = bp->b_cylin; 490 sn = bn%st->nspc + npf + 1; 491 tn = sn/st->nsect; 492 sn %= st->nsect; 493 cn += tn/st->ntrak; 494 tn %= st->ntrak; 495 rk->rkcyl = cn; 496 rk->rkda = (tn << 8) | sn; 497 ubaddr = (int)ptob(reg+1) + o; 498 rk->rkba = ubaddr; 499 cmd = (ubaddr >> 8) & 0x300; 500 cmd |= RK_CDT|RK_IE|RK_GO|RK_READ; 501 rk->rkcs1 = cmd; 502 #endif 503 return (1); 504 } 505 506 rkreset(uban) 507 { 508 register struct uba_minfo *um; 509 register struct uba_dinfo *ui; 510 register rk11, unit; 511 int any = 0; 512 513 for (rk11 = 0; rk11 < NHK; rk11++) { 514 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 515 um->um_alive == 0) 516 continue; 517 if (any == 0) { 518 printf(" rk"); 519 any++; 520 } 521 um->um_tab.b_active = 0; 522 um->um_tab.b_actf = um->um_tab.b_actl = 0; 523 rk_softc[um->um_ctlr].sc_recal = 0; 524 if (um->um_ubinfo) { 525 printf("<%d>", (um->um_ubinfo>>28)&0xf); 526 ubadone(um); 527 } 528 for (unit = 0; unit < NHK; unit++) { 529 if ((ui = rkdinfo[unit]) == 0) 530 continue; 531 if (ui->ui_alive == 0) 532 continue; 533 rkutab[unit].b_active = 0; 534 (void) rkustart(ui); 535 } 536 (void) rkstart(um); 537 } 538 } 539 540 rkwatch() 541 { 542 register struct uba_minfo *um; 543 register rk11, unit; 544 register struct rk_softc *sc; 545 546 timeout(rkwatch, (caddr_t)0, hz); 547 for (rk11 = 0; rk11 < NHK; rk11++) { 548 um = rkminfo[rk11]; 549 if (um == 0 || um->um_alive == 0) 550 continue; 551 sc = &rk_softc[rk11]; 552 if (um->um_tab.b_active == 0) { 553 for (unit = 0; unit < NRK; unit++) 554 if (rkutab[unit].b_active && 555 rkdinfo[unit]->ui_mi == um) 556 goto active; 557 sc->sc_wticks = 0; 558 continue; 559 } 560 active: 561 sc->sc_wticks++; 562 if (sc->sc_wticks >= 20) { 563 sc->sc_wticks = 0; 564 printf("LOST rkintr "); 565 ubareset(um->um_ubanum); 566 } 567 } 568 } 569 570 #define DBSIZE 20 571 572 rkdump(dev) 573 dev_t dev; 574 { 575 struct rkdevice *rkaddr; 576 char *start; 577 int num, blk, unit; 578 struct size *sizes; 579 register struct uba_regs *uba; 580 register struct uba_dinfo *ui; 581 register short *rp; 582 struct rkst *st; 583 584 unit = minor(dev) >> 3; 585 if (unit >= NRK) { 586 printf("bad unit\n"); 587 return (-1); 588 } 589 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 590 ui = phys(struct uba_dinfo *, rkdinfo[unit]); 591 if (ui->ui_alive == 0) { 592 printf("dna\n"); 593 return(-1); 594 } 595 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 596 #if VAX780 597 if (cpu == VAX_780) 598 ubainit(uba); 599 #endif 600 rkaddr = (struct rkdevice *)ui->ui_physaddr; 601 num = maxfree; 602 start = 0; 603 rkaddr->rkcs1 = RK_CDT|RK_CERR; 604 rkaddr->rkcs2 = unit; 605 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 606 rkwait(rkaddr); 607 if ((rkaddr->rkds & RK_VV) == 0) { 608 rkaddr->rkcs1 = RK_CDT|RK_IE|RK_PACK|RK_GO; 609 rkwait(rkaddr); 610 } 611 st = &rkst[ui->ui_type]; 612 sizes = phys(struct size *, st->sizes); 613 if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) { 614 printf("oor\n"); 615 return (-1); 616 } 617 while (num > 0) { 618 register struct pte *io; 619 register int i; 620 int cn, sn, tn; 621 daddr_t bn; 622 623 blk = num > DBSIZE ? DBSIZE : num; 624 io = uba->uba_map; 625 for (i = 0; i < blk; i++) 626 *(int *)io++ = (btop(start)+i) | (1<<21) | UBA_MRV; 627 *(int *)io = 0; 628 bn = dumplo + btop(start); 629 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 630 sn = bn%st->nspc; 631 tn = sn/st->nsect; 632 sn = sn%st->nsect; 633 rkaddr->rkcyl = cn; 634 rp = (short *) &rkaddr->rkda; 635 *rp = (tn << 8) + sn; 636 *--rp = 0; 637 *--rp = -blk*NBPG / sizeof (short); 638 *--rp = RK_CDT|RK_GO|RK_WRITE; 639 rkwait(rkaddr); 640 if (rkaddr->rkcs1 & RK_CERR) { 641 printf("rk dump dsk err: (%d,%d,%d) cs1=%x, ds=%x, er1=%x\n", 642 cn, tn, sn, 643 rkaddr->rkcs1&0xffff, rkaddr->rkds&0xffff, 644 rkaddr->rker&0xffff); 645 return (-1); 646 } 647 start += blk*NBPG; 648 num -= blk; 649 } 650 return (0); 651 } 652 #endif 653