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