1 /* 2 * Copyright (c) 1982 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 * @(#)rk.c 6.6 (Berkeley) 08/08/85 7 */ 8 9 #include "rk.h" 10 #if NHK > 0 11 int rkpip; /* DEBUG */ 12 int rknosval; /* DEBUG */ 13 #ifdef RKDEBUG 14 int rkdebug; 15 #endif 16 #ifdef RKBDEBUG 17 int rkbdebug; 18 #endif 19 /* 20 * RK611/RK0[67] disk driver 21 * 22 * This driver mimics up.c; see it for an explanation of common code. 23 * 24 * TODO: 25 * Learn why we lose an interrupt sometime when spinning drives down 26 */ 27 #include "../machine/pte.h" 28 29 #include "param.h" 30 #include "systm.h" 31 #include "buf.h" 32 #include "conf.h" 33 #include "dir.h" 34 #include "user.h" 35 #include "map.h" 36 #include "vm.h" 37 #include "dk.h" 38 #include "cmap.h" 39 #include "dkbad.h" 40 #include "uio.h" 41 #include "kernel.h" 42 #include "syslog.h" 43 44 #include "../vax/cpu.h" 45 #include "ubareg.h" 46 #include "ubavar.h" 47 #include "rkreg.h" 48 49 struct rk_softc { 50 int sc_softas; 51 int sc_ndrive; 52 int sc_wticks; 53 int sc_recal; 54 } rk_softc[NHK]; 55 56 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 57 struct size { 58 daddr_t nblocks; 59 int cyloff; 60 } rk7_sizes[8] ={ 61 15884, 0, /* A=cyl 0 thru 240 */ 62 10032, 241, /* B=cyl 241 thru 392 */ 63 53790, 0, /* C=cyl 0 thru 814 */ 64 0, 0, 65 0, 0, 66 0, 0, 67 27786, 393, /* G=cyl 393 thru 813 */ 68 0, 0, 69 }, rk6_sizes[8] ={ 70 15884, 0, /* A=cyl 0 thru 240 */ 71 11154, 241, /* B=cyl 241 thru 409 */ 72 27126, 0, /* C=cyl 0 thru 410 */ 73 0, 0, 74 0, 0, 75 0, 0, 76 0, 0, 77 0, 0, 78 }; 79 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 80 81 short rktypes[] = { RK_CDT, 0 }; 82 83 int rkprobe(), rkslave(), rkattach(), rkdgo(), rkintr(); 84 struct uba_ctlr *rkminfo[NHK]; 85 struct uba_device *rkdinfo[NRK]; 86 struct uba_device *rkip[NHK][4]; 87 88 u_short rkstd[] = { 0777440, 0 }; 89 struct uba_driver hkdriver = 90 { rkprobe, rkslave, rkattach, rkdgo, rkstd, "rk", rkdinfo, "hk", rkminfo, 1 }; 91 struct buf rkutab[NRK]; 92 short rkcyl[NRK]; 93 struct dkbad rkbad[NRK]; 94 struct buf brkbuf[NRK]; 95 96 struct rkst { 97 short nsect; 98 short ntrak; 99 short nspc; 100 short ncyl; 101 struct size *sizes; 102 } rkst[] = { 103 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK7CYL, rk7_sizes, 104 NRKSECT, NRKTRK, NRKSECT*NRKTRK, NRK6CYL, rk6_sizes, 105 }; 106 107 u_char rk_offset[16] = 108 { RKAS_P400,RKAS_M400,RKAS_P400,RKAS_M400,RKAS_P800,RKAS_M800,RKAS_P800, 109 RKAS_M800,RKAS_P1200,RKAS_M1200,RKAS_P1200,RKAS_M1200,0,0,0,0 110 }; 111 112 struct buf rrkbuf[NRK]; 113 114 #define b_cylin b_resid 115 116 #ifdef INTRLVE 117 daddr_t dkblock(); 118 #endif 119 120 int rkwstart, rkwatch(); 121 122 rkprobe(reg) 123 caddr_t reg; 124 { 125 register int br, cvec; 126 127 #ifdef lint 128 br = 0; cvec = br; br = cvec; 129 rkintr(0); 130 #endif 131 ((struct rkdevice *)reg)->rkcs1 = RK_CDT|RK_IE|RK_CRDY; 132 DELAY(10); 133 ((struct rkdevice *)reg)->rkcs1 = RK_CDT; 134 return (sizeof (struct rkdevice)); 135 } 136 137 rkslave(ui, reg) 138 struct uba_device *ui; 139 caddr_t reg; 140 { 141 register struct rkdevice *rkaddr = (struct rkdevice *)reg; 142 143 ui->ui_type = 0; 144 rkaddr->rkcs1 = RK_CCLR; 145 rkaddr->rkcs2 = ui->ui_slave; 146 rkaddr->rkcs1 = RK_CDT|RK_DCLR|RK_GO; 147 rkwait(rkaddr); 148 DELAY(50); 149 if (rkaddr->rkcs2&RKCS2_NED || (rkaddr->rkds&RKDS_SVAL) == 0) { 150 rkaddr->rkcs1 = RK_CCLR; 151 return (0); 152 } 153 if (rkaddr->rkcs1&RK_CERR && rkaddr->rker&RKER_DTYE) { 154 ui->ui_type = 1; 155 rkaddr->rkcs1 = RK_CCLR; 156 } 157 return (1); 158 } 159 160 rkattach(ui) 161 register struct uba_device *ui; 162 { 163 164 if (rkwstart == 0) { 165 timeout(rkwatch, (caddr_t)0, hz); 166 rkwstart++; 167 } 168 if (ui->ui_dk >= 0) 169 dk_mspw[ui->ui_dk] = 1.0 / (60 * NRKSECT * 256); 170 rkip[ui->ui_ctlr][ui->ui_slave] = ui; 171 rk_softc[ui->ui_ctlr].sc_ndrive++; 172 rkcyl[ui->ui_unit] = -1; 173 ui->ui_flags = 0; 174 } 175 176 rkopen(dev) 177 dev_t dev; 178 { 179 register int unit = minor(dev) >> 3; 180 register struct uba_device *ui; 181 182 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) 183 return (ENXIO); 184 return (0); 185 } 186 187 rkstrategy(bp) 188 register struct buf *bp; 189 { 190 register struct uba_device *ui; 191 register struct rkst *st; 192 register int unit; 193 register struct buf *dp; 194 int xunit = minor(bp->b_dev) & 07; 195 long bn, sz; 196 int s; 197 198 sz = (bp->b_bcount+511) >> 9; 199 unit = dkunit(bp); 200 if (unit >= NRK) 201 goto bad; 202 ui = rkdinfo[unit]; 203 if (ui == 0 || ui->ui_alive == 0) 204 goto bad; 205 st = &rkst[ui->ui_type]; 206 if (bp->b_blkno < 0 || 207 (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) 208 goto bad; 209 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 210 s = spl5(); 211 dp = &rkutab[ui->ui_unit]; 212 disksort(dp, bp); 213 if (dp->b_active == 0) { 214 (void) rkustart(ui); 215 bp = &ui->ui_mi->um_tab; 216 if (bp->b_actf && bp->b_active == 0) 217 (void) rkstart(ui->ui_mi); 218 } 219 splx(s); 220 return; 221 222 bad: 223 bp->b_flags |= B_ERROR; 224 iodone(bp); 225 return; 226 } 227 228 rkustart(ui) 229 register struct uba_device *ui; 230 { 231 register struct buf *bp, *dp; 232 register struct uba_ctlr *um; 233 register struct rkdevice *rkaddr; 234 235 if (ui == 0) 236 return; 237 dk_busy &= ~(1<<ui->ui_dk); 238 dp = &rkutab[ui->ui_unit]; 239 um = ui->ui_mi; 240 rkaddr = (struct rkdevice *)um->um_addr; 241 if (um->um_tab.b_active) { 242 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 243 return; 244 } 245 if ((bp = dp->b_actf) == NULL) 246 return; 247 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 248 rkaddr->rkcs2 = ui->ui_slave; 249 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 250 rkwait(rkaddr); 251 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 252 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 253 struct rkst *st = &rkst[ui->ui_type]; 254 struct buf *bbp = &brkbuf[ui->ui_unit]; 255 256 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 257 ui->ui_flags = 1; 258 bbp->b_flags = B_READ|B_BUSY; 259 bbp->b_dev = bp->b_dev; 260 bbp->b_bcount = 512; 261 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 262 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 263 bbp->b_cylin = st->ncyl - 1; 264 dp->b_actf = bbp; 265 bbp->av_forw = bp; 266 bp = bbp; 267 rkwait(rkaddr); 268 } 269 if (dp->b_active) 270 goto done; 271 dp->b_active = 1; 272 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 273 goto done; 274 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 275 goto done; 276 if (bp->b_cylin == rkcyl[ui->ui_unit]) 277 goto done; 278 rkaddr->rkcyl = bp->b_cylin; 279 rkcyl[ui->ui_unit] = bp->b_cylin; 280 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 281 if (ui->ui_dk >= 0) { 282 dk_busy |= 1<<ui->ui_dk; 283 dk_seek[ui->ui_dk]++; 284 } 285 goto out; 286 done: 287 if (dp->b_active != 2) { 288 dp->b_forw = NULL; 289 if (um->um_tab.b_actf == NULL) 290 um->um_tab.b_actf = dp; 291 else 292 um->um_tab.b_actl->b_forw = dp; 293 um->um_tab.b_actl = dp; 294 dp->b_active = 2; 295 } 296 out: 297 return; 298 } 299 300 rkstart(um) 301 register struct uba_ctlr *um; 302 { 303 register struct buf *bp, *dp; 304 register struct uba_device *ui; 305 register struct rkdevice *rkaddr; 306 struct rkst *st; 307 daddr_t bn; 308 int sn, tn, cmd; 309 310 loop: 311 if ((dp = um->um_tab.b_actf) == NULL) 312 return; 313 if ((bp = dp->b_actf) == NULL) { 314 um->um_tab.b_actf = dp->b_forw; 315 goto loop; 316 } 317 um->um_tab.b_active++; 318 ui = rkdinfo[dkunit(bp)]; 319 bn = dkblock(bp); 320 st = &rkst[ui->ui_type]; 321 sn = bn%st->nspc; 322 tn = sn/st->nsect; 323 sn %= st->nsect; 324 rkaddr = (struct rkdevice *)ui->ui_addr; 325 retry: 326 rkaddr->rkcs1 = RK_CCLR; 327 rkaddr->rkcs2 = ui->ui_slave; 328 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 329 rkwait(rkaddr); 330 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 331 rknosval++; 332 goto nosval; 333 } 334 if (rkaddr->rkds&RKDS_PIP) { 335 rkpip++; 336 goto retry; 337 } 338 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 339 printf("rk%d: not ready", dkunit(bp)); 340 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 341 printf("\n"); 342 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 343 rkwait(rkaddr); 344 rkaddr->rkcs1 = RK_CCLR; 345 rkwait(rkaddr); 346 um->um_tab.b_active = 0; 347 um->um_tab.b_errcnt = 0; 348 dp->b_actf = bp->av_forw; 349 dp->b_active = 0; 350 bp->b_flags |= B_ERROR; 351 iodone(bp); 352 goto loop; 353 } 354 printf(" (came back!)\n"); 355 } 356 nosval: 357 rkaddr->rkcyl = bp->b_cylin; 358 rkcyl[ui->ui_unit] = bp->b_cylin; 359 rkaddr->rkda = (tn << 8) + sn; 360 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 361 if (bp->b_flags & B_READ) 362 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 363 else 364 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 365 um->um_cmd = cmd; 366 (void) ubago(ui); 367 } 368 369 rkdgo(um) 370 register struct uba_ctlr *um; 371 { 372 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 373 374 um->um_tab.b_active = 2; /* should now be 2 */ 375 rkaddr->rkba = um->um_ubinfo; 376 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 377 } 378 379 rkintr(rk11) 380 int rk11; 381 { 382 register struct uba_ctlr *um = rkminfo[rk11]; 383 register struct uba_device *ui; 384 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 385 register struct buf *bp, *dp; 386 int unit; 387 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 388 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 389 390 sc->sc_wticks = 0; 391 sc->sc_softas = 0; 392 if (um->um_tab.b_active == 2 || sc->sc_recal) { 393 um->um_tab.b_active = 1; 394 dp = um->um_tab.b_actf; 395 bp = dp->b_actf; 396 ui = rkdinfo[dkunit(bp)]; 397 dk_busy &= ~(1 << ui->ui_dk); 398 if (bp->b_flags&B_BAD) 399 if (rkecc(ui, CONT)) 400 return; 401 if (rkaddr->rkcs1 & RK_CERR) { 402 int recal; 403 u_short ds = rkaddr->rkds; 404 u_short cs2 = rkaddr->rkcs2; 405 u_short er = rkaddr->rker; 406 #ifdef RKDEBUG 407 if (rkdebug) { 408 printf("cs2=%b ds=%b er=%b\n", 409 cs2, RKCS2_BITS, ds, 410 RKDS_BITS, er, RKER_BITS); 411 } 412 #endif 413 if (er & RKER_WLE) { 414 printf("rk%d: write locked\n", dkunit(bp)); 415 bp->b_flags |= B_ERROR; 416 } else if (++um->um_tab.b_errcnt > 28 || 417 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 418 hard: 419 harderr(bp, "rk"); 420 printf("cs2=%b ds=%b er=%b\n", 421 cs2, RKCS2_BITS, ds, 422 RKDS_BITS, er, RKER_BITS); 423 bp->b_flags |= B_ERROR; 424 sc->sc_recal = 0; 425 } else if (er & RKER_BSE) { 426 if (rkecc(ui, BSE)) 427 return; 428 else 429 goto hard; 430 } else { 431 if ((er & (RKER_DCK|RKER_ECH)) == RKER_DCK) { 432 if (rkecc(ui, ECC)) 433 return; 434 } else 435 um->um_tab.b_active = 0; 436 } 437 if (cs2&RKCS2_MDS) { 438 rkaddr->rkcs2 = RKCS2_SCLR; 439 goto retry; 440 } 441 recal = 0; 442 if (ds&RKDS_DROT || er&(RKER_OPI|RKER_SKI|RKER_UNS) || 443 (um->um_tab.b_errcnt&07) == 4) 444 recal = 1; 445 rkaddr->rkcs1 = RK_CCLR; 446 rkaddr->rkcs2 = ui->ui_slave; 447 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 448 rkwait(rkaddr); 449 if (recal && um->um_tab.b_active == 0) { 450 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_RECAL|RK_GO; 451 rkcyl[ui->ui_unit] = -1; 452 sc->sc_recal = 0; 453 goto nextrecal; 454 } 455 } 456 retry: 457 switch (sc->sc_recal) { 458 459 case 1: 460 rkaddr->rkcyl = bp->b_cylin; 461 rkcyl[ui->ui_unit] = bp->b_cylin; 462 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 463 goto nextrecal; 464 case 2: 465 if (um->um_tab.b_errcnt < 16 || 466 (bp->b_flags&B_READ) == 0) 467 goto donerecal; 468 rkaddr->rkatt = rk_offset[um->um_tab.b_errcnt & 017]; 469 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_OFFSET|RK_GO; 470 /* fall into ... */ 471 nextrecal: 472 sc->sc_recal++; 473 rkwait(rkaddr); 474 um->um_tab.b_active = 1; 475 return; 476 donerecal: 477 case 3: 478 sc->sc_recal = 0; 479 um->um_tab.b_active = 0; 480 break; 481 } 482 ubadone(um); 483 if (um->um_tab.b_active) { 484 um->um_tab.b_active = 0; 485 um->um_tab.b_errcnt = 0; 486 um->um_tab.b_actf = dp->b_forw; 487 dp->b_active = 0; 488 dp->b_errcnt = 0; 489 dp->b_actf = bp->av_forw; 490 bp->b_resid = -rkaddr->rkwc * sizeof(short); 491 iodone(bp); 492 if (dp->b_actf) 493 rkustart(ui); 494 } 495 as &= ~(1<<ui->ui_slave); 496 } 497 for (unit = 0; as; as >>= 1, unit++) 498 if (as & 1) { 499 ui = rkip[rk11][unit]; 500 if (ui) { 501 rkustart(rkip[rk11][unit]); 502 } else { 503 rkaddr->rkcs1 = RK_CCLR; 504 rkaddr->rkcs2 = unit; 505 rkaddr->rkcs1 = RK_DCLR|RK_GO; 506 rkwait(rkaddr); 507 rkaddr->rkcs1 = RK_CCLR; 508 } 509 } 510 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 511 rkstart(um); 512 if (((rkaddr->rkcs1) & RK_IE) == 0) 513 rkaddr->rkcs1 = RK_IE; 514 } 515 516 rkwait(addr) 517 register struct rkdevice *addr; 518 { 519 520 while ((addr->rkcs1 & RK_CRDY) == 0) 521 ; 522 } 523 524 rkread(dev, uio) 525 dev_t dev; 526 struct uio *uio; 527 { 528 register int unit = minor(dev) >> 3; 529 530 if (unit >= NRK) 531 return (ENXIO); 532 return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio)); 533 } 534 535 rkwrite(dev, uio) 536 dev_t dev; 537 struct uio *uio; 538 { 539 register int unit = minor(dev) >> 3; 540 541 if (unit >= NRK) 542 return (ENXIO); 543 return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio)); 544 } 545 546 rkecc(ui, flag) 547 register struct uba_device *ui; 548 { 549 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 550 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 551 register struct uba_ctlr *um = ui->ui_mi; 552 register struct rkst *st; 553 struct uba_regs *ubp = ui->ui_hd->uh_uba; 554 caddr_t addr; 555 int reg, npf, o, cmd, ubaddr; 556 int bn, cn, tn, sn; 557 558 if (flag == CONT) 559 npf = bp->b_error; 560 else 561 npf = btop((rk->rkwc * sizeof(short)) + bp->b_bcount); 562 reg = btop(um->um_ubinfo&0x3ffff) + npf; 563 o = (int)bp->b_un.b_addr & PGOFSET; 564 bn = dkblock(bp); 565 st = &rkst[ui->ui_type]; 566 cn = bp->b_cylin; 567 sn = bn%st->nspc + npf; 568 tn = sn/st->nsect; 569 sn %= st->nsect; 570 cn += tn/st->ntrak; 571 tn %= st->ntrak; 572 ubapurge(um); 573 switch (flag) { 574 case ECC: 575 { 576 register int i; 577 int bit, byte, mask; 578 579 npf--; 580 reg--; 581 log(KERN_RECOV, "rk%d%c: soft ecc sn%d\n", dkunit(bp), 582 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 583 mask = rk->rkec2; 584 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 585 bit = i&07; 586 i = (i&~07)>>3; 587 byte = i + o; 588 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 589 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 590 (byte & PGOFSET); 591 putmemc(addr, getmemc(addr)^(mask<<bit)); 592 byte++; 593 i++; 594 bit -= 8; 595 } 596 if (rk->rkwc == 0) { 597 um->um_tab.b_active = 0; 598 return (0); 599 } 600 npf++; 601 reg++; 602 break; 603 } 604 605 case BSE: 606 #ifdef RKBDEBUG 607 if (rkbdebug) 608 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 609 #endif 610 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) 611 return(0); 612 bp->b_flags |= B_BAD; 613 bp->b_error = npf + 1; 614 bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 615 cn = bn/st->nspc; 616 sn = bn%st->nspc; 617 tn = sn/st->nsect; 618 sn %= st->nsect; 619 #ifdef RKBDEBUG 620 if (rkbdebug) 621 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 622 #endif 623 rk->rkwc = -(512 / sizeof (short)); 624 break; 625 626 case CONT: 627 #ifdef RKBDEBUG 628 if (rkbdebug) 629 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); 630 #endif 631 bp->b_flags &= ~B_BAD; 632 rk->rkwc = -((bp->b_bcount - (int)ptob(npf)) / sizeof (short)); 633 if (rk->rkwc == 0) 634 return (0); 635 break; 636 } 637 rk->rkcs1 = RK_CCLR; 638 rk->rkcs2 = ui->ui_slave; 639 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 640 rkwait(rk); 641 rk->rkcyl = cn; 642 rk->rkda = (tn << 8) | sn; 643 ubaddr = (int)ptob(reg) + o; 644 rk->rkba = ubaddr; 645 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 646 cmd |= (ubaddr >> 8) & 0x300; 647 cmd |= rktypes[ui->ui_type]; 648 rk->rkcs1 = cmd; 649 um->um_tab.b_active = 2; /* continuing */ 650 um->um_tab.b_errcnt = 0; /* error has been corrected */ 651 return (1); 652 } 653 654 rkreset(uban) 655 int uban; 656 { 657 register struct uba_ctlr *um; 658 register struct uba_device *ui; 659 register rk11, unit; 660 661 for (rk11 = 0; rk11 < NHK; rk11++) { 662 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 663 um->um_alive == 0) 664 continue; 665 printf(" hk%d", rk11); 666 um->um_tab.b_active = 0; 667 um->um_tab.b_actf = um->um_tab.b_actl = 0; 668 rk_softc[um->um_ctlr].sc_recal = 0; 669 rk_softc[um->um_ctlr].sc_wticks = 0; 670 if (um->um_ubinfo) { 671 printf("<%d>", (um->um_ubinfo>>28)&0xf); 672 um->um_ubinfo = 0; 673 } 674 for (unit = 0; unit < NRK; unit++) { 675 if ((ui = rkdinfo[unit]) == 0) 676 continue; 677 if (ui->ui_alive == 0 || ui->ui_mi != um) 678 continue; 679 rkutab[unit].b_active = 0; 680 (void) rkustart(ui); 681 } 682 (void) rkstart(um); 683 } 684 } 685 686 rkwatch() 687 { 688 register struct uba_ctlr *um; 689 register rk11, unit; 690 register struct rk_softc *sc; 691 692 timeout(rkwatch, (caddr_t)0, hz); 693 for (rk11 = 0; rk11 < NHK; rk11++) { 694 um = rkminfo[rk11]; 695 if (um == 0 || um->um_alive == 0) 696 continue; 697 sc = &rk_softc[rk11]; 698 if (um->um_tab.b_active == 0) { 699 for (unit = 0; unit < NRK; unit++) 700 if (rkutab[unit].b_active && 701 rkdinfo[unit]->ui_mi == um) 702 goto active; 703 sc->sc_wticks = 0; 704 continue; 705 } 706 active: 707 sc->sc_wticks++; 708 if (sc->sc_wticks >= 20) { 709 sc->sc_wticks = 0; 710 printf("hk%d: lost interrupt\n", rk11); 711 ubareset(um->um_ubanum); 712 } 713 } 714 } 715 716 #define DBSIZE 20 717 718 rkdump(dev) 719 dev_t dev; 720 { 721 struct rkdevice *rkaddr; 722 char *start; 723 int num, blk, unit; 724 struct size *sizes; 725 register struct uba_regs *uba; 726 register struct uba_device *ui; 727 register short *rp; 728 struct rkst *st; 729 730 unit = minor(dev) >> 3; 731 if (unit >= NRK) 732 return (ENXIO); 733 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 734 ui = phys(struct uba_device *, rkdinfo[unit]); 735 if (ui->ui_alive == 0) 736 return (ENXIO); 737 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 738 ubainit(uba); 739 rkaddr = (struct rkdevice *)ui->ui_physaddr; 740 num = maxfree; 741 start = 0; 742 rkaddr->rkcs1 = RK_CCLR; 743 rkaddr->rkcs2 = unit; 744 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 745 rkwait(rkaddr); 746 if ((rkaddr->rkds & RKDS_VV) == 0) { 747 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 748 rkwait(rkaddr); 749 } 750 st = &rkst[ui->ui_type]; 751 sizes = phys(struct size *, st->sizes); 752 if (dumplo < 0) 753 return (EINVAL); 754 if (dumplo + num >= sizes[minor(dev)&07].nblocks) 755 num = sizes[minor(dev)&07].nblocks - dumplo; 756 while (num > 0) { 757 register struct pte *io; 758 register int i; 759 int cn, sn, tn; 760 daddr_t bn; 761 762 blk = num > DBSIZE ? DBSIZE : num; 763 io = uba->uba_map; 764 for (i = 0; i < blk; i++) 765 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 766 *(int *)io = 0; 767 bn = dumplo + btop(start); 768 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 769 sn = bn%st->nspc; 770 tn = sn/st->nsect; 771 sn = sn%st->nsect; 772 rkaddr->rkcyl = cn; 773 rp = (short *) &rkaddr->rkda; 774 *rp = (tn << 8) + sn; 775 *--rp = 0; 776 *--rp = -blk*NBPG / sizeof (short); 777 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 778 rkwait(rkaddr); 779 if (rkaddr->rkcs1 & RK_CERR) 780 return (EIO); 781 start += blk*NBPG; 782 num -= blk; 783 } 784 return (0); 785 } 786 787 rksize(dev) 788 dev_t dev; 789 { 790 int unit = minor(dev) >> 3; 791 struct uba_device *ui; 792 struct rkst *st; 793 794 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) 795 return (-1); 796 st = &rkst[ui->ui_type]; 797 return (st->sizes[minor(dev) & 07].nblocks); 798 } 799 #endif 800