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