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.2 (Berkeley) 01/14/87 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 "dkstat.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 15884, 393, /* D=cyl 393 thru 633 */ 67 0, 0, 68 11792, 634, /* F=cyl 634 thru 814 */ 69 27786, 393, /* G=cyl 393 thru 814, should be 27698 */ 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 = rkunit(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) { 211 bp->b_resid = bp->b_bcount; 212 goto done; 213 } 214 bp->b_error = EINVAL; 215 goto bad; 216 } 217 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 218 s = spl5(); 219 dp = &rkutab[ui->ui_unit]; 220 disksort(dp, bp); 221 if (dp->b_active == 0) { 222 (void) rkustart(ui); 223 bp = &ui->ui_mi->um_tab; 224 if (bp->b_actf && bp->b_active == 0) 225 (void) rkstart(ui->ui_mi); 226 } 227 splx(s); 228 return; 229 230 bad: 231 bp->b_flags |= B_ERROR; 232 done: 233 iodone(bp); 234 return; 235 } 236 237 rkustart(ui) 238 register struct uba_device *ui; 239 { 240 register struct buf *bp, *dp; 241 register struct uba_ctlr *um; 242 register struct rkdevice *rkaddr; 243 244 if (ui == 0) 245 return; 246 dk_busy &= ~(1<<ui->ui_dk); 247 dp = &rkutab[ui->ui_unit]; 248 um = ui->ui_mi; 249 rkaddr = (struct rkdevice *)um->um_addr; 250 if (um->um_tab.b_active) { 251 rk_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 252 return; 253 } 254 if ((bp = dp->b_actf) == NULL) 255 return; 256 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_CERR; 257 rkaddr->rkcs2 = ui->ui_slave; 258 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 259 rkwait(rkaddr); 260 if ((rkaddr->rkds & RKDS_VV) == 0 || ui->ui_flags == 0) { 261 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 262 struct rkst *st = &rkst[ui->ui_type]; 263 struct buf *bbp = &brkbuf[ui->ui_unit]; 264 265 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_PACK|RK_GO; 266 ui->ui_flags = 1; 267 bbp->b_flags = B_READ|B_BUSY; 268 bbp->b_dev = bp->b_dev; 269 bbp->b_bcount = 512; 270 bbp->b_un.b_addr = (caddr_t)&rkbad[ui->ui_unit]; 271 bbp->b_blkno = st->ncyl*st->nspc - st->nsect; 272 bbp->b_cylin = st->ncyl - 1; 273 dp->b_actf = bbp; 274 bbp->av_forw = bp; 275 bp = bbp; 276 rkwait(rkaddr); 277 } 278 if (dp->b_active) 279 goto done; 280 dp->b_active = 1; 281 if ((rkaddr->rkds & RKDS_DREADY) != RKDS_DREADY) 282 goto done; 283 if (rk_softc[um->um_ctlr].sc_ndrive == 1) 284 goto done; 285 if (bp->b_cylin == rkcyl[ui->ui_unit]) 286 goto done; 287 rkaddr->rkcyl = bp->b_cylin; 288 rkcyl[ui->ui_unit] = bp->b_cylin; 289 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_SEEK|RK_GO; 290 if (ui->ui_dk >= 0) { 291 dk_busy |= 1<<ui->ui_dk; 292 dk_seek[ui->ui_dk]++; 293 } 294 goto out; 295 done: 296 if (dp->b_active != 2) { 297 dp->b_forw = NULL; 298 if (um->um_tab.b_actf == NULL) 299 um->um_tab.b_actf = dp; 300 else 301 um->um_tab.b_actl->b_forw = dp; 302 um->um_tab.b_actl = dp; 303 dp->b_active = 2; 304 } 305 out: 306 return; 307 } 308 309 rkstart(um) 310 register struct uba_ctlr *um; 311 { 312 register struct buf *bp, *dp; 313 register struct uba_device *ui; 314 register struct rkdevice *rkaddr; 315 struct rkst *st; 316 daddr_t bn; 317 int sn, tn, cmd; 318 319 loop: 320 if ((dp = um->um_tab.b_actf) == NULL) 321 return; 322 if ((bp = dp->b_actf) == NULL) { 323 um->um_tab.b_actf = dp->b_forw; 324 goto loop; 325 } 326 um->um_tab.b_active++; 327 ui = rkdinfo[rkunit(bp->b_dev)]; 328 bn = bp->b_blkno; 329 st = &rkst[ui->ui_type]; 330 sn = bn%st->nspc; 331 tn = sn/st->nsect; 332 sn %= st->nsect; 333 rkaddr = (struct rkdevice *)ui->ui_addr; 334 retry: 335 rkaddr->rkcs1 = RK_CCLR; 336 rkaddr->rkcs2 = ui->ui_slave; 337 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 338 rkwait(rkaddr); 339 if ((rkaddr->rkds&RKDS_SVAL) == 0) { 340 rknosval++; 341 goto nosval; 342 } 343 if (rkaddr->rkds&RKDS_PIP) { 344 rkpip++; 345 goto retry; 346 } 347 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 348 printf("rk%d: not ready", rkunit(bp->b_dev)); 349 if ((rkaddr->rkds&RKDS_DREADY) != RKDS_DREADY) { 350 printf("\n"); 351 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 352 rkwait(rkaddr); 353 rkaddr->rkcs1 = RK_CCLR; 354 rkwait(rkaddr); 355 um->um_tab.b_active = 0; 356 um->um_tab.b_errcnt = 0; 357 dp->b_actf = bp->av_forw; 358 dp->b_active = 0; 359 bp->b_flags |= B_ERROR; 360 iodone(bp); 361 goto loop; 362 } 363 printf(" (came back!)\n"); 364 } 365 nosval: 366 rkaddr->rkcyl = bp->b_cylin; 367 rkcyl[ui->ui_unit] = bp->b_cylin; 368 rkaddr->rkda = (tn << 8) + sn; 369 rkaddr->rkwc = -bp->b_bcount / sizeof (short); 370 if (bp->b_flags & B_READ) 371 cmd = rktypes[ui->ui_type]|RK_IE|RK_READ|RK_GO; 372 else 373 cmd = rktypes[ui->ui_type]|RK_IE|RK_WRITE|RK_GO; 374 um->um_cmd = cmd; 375 (void) ubago(ui); 376 } 377 378 rkdgo(um) 379 register struct uba_ctlr *um; 380 { 381 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 382 383 um->um_tab.b_active = 2; /* should now be 2 */ 384 rkaddr->rkba = um->um_ubinfo; 385 rkaddr->rkcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 386 } 387 388 rkintr(rk11) 389 int rk11; 390 { 391 register struct uba_ctlr *um = rkminfo[rk11]; 392 register struct uba_device *ui; 393 register struct rkdevice *rkaddr = (struct rkdevice *)um->um_addr; 394 register struct buf *bp, *dp; 395 int unit; 396 struct rk_softc *sc = &rk_softc[um->um_ctlr]; 397 int as = (rkaddr->rkatt >> 8) | sc->sc_softas; 398 399 sc->sc_wticks = 0; 400 sc->sc_softas = 0; 401 if (um->um_tab.b_active == 2 || sc->sc_recal) { 402 um->um_tab.b_active = 1; 403 dp = um->um_tab.b_actf; 404 bp = dp->b_actf; 405 ui = rkdinfo[rkunit(bp->b_dev)]; 406 dk_busy &= ~(1 << ui->ui_dk); 407 if (bp->b_flags&B_BAD) 408 if (rkecc(ui, CONT)) 409 return; 410 if (rkaddr->rkcs1 & RK_CERR) { 411 int recal; 412 u_short ds = rkaddr->rkds; 413 u_short cs2 = rkaddr->rkcs2; 414 u_short er = rkaddr->rker; 415 #ifdef RKDEBUG 416 if (rkdebug) { 417 printf("cs2=%b ds=%b er=%b\n", 418 cs2, RKCS2_BITS, ds, 419 RKDS_BITS, er, RKER_BITS); 420 } 421 #endif 422 if (er & RKER_WLE) { 423 printf("rk%d: write locked\n", 424 rkunit(bp->b_dev)); 425 bp->b_flags |= B_ERROR; 426 } else if (++um->um_tab.b_errcnt > 28 || 427 ds&RKDS_HARD || er&RKER_HARD || cs2&RKCS2_HARD) { 428 hard: 429 harderr(bp, "rk"); 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 rkread(dev, uio) 535 dev_t dev; 536 struct uio *uio; 537 { 538 register int unit = rkunit(dev); 539 540 if (unit >= NRK) 541 return (ENXIO); 542 return (physio(rkstrategy, &rrkbuf[unit], dev, B_READ, minphys, uio)); 543 } 544 545 rkwrite(dev, uio) 546 dev_t dev; 547 struct uio *uio; 548 { 549 register int unit = rkunit(dev); 550 551 if (unit >= NRK) 552 return (ENXIO); 553 return (physio(rkstrategy, &rrkbuf[unit], dev, B_WRITE, minphys, uio)); 554 } 555 556 rkecc(ui, flag) 557 register struct uba_device *ui; 558 { 559 register struct rkdevice *rk = (struct rkdevice *)ui->ui_addr; 560 register struct buf *bp = rkutab[ui->ui_unit].b_actf; 561 register struct uba_ctlr *um = ui->ui_mi; 562 register struct rkst *st; 563 struct uba_regs *ubp = ui->ui_hd->uh_uba; 564 caddr_t addr; 565 int reg, npf, o, cmd, ubaddr; 566 int bn, cn, tn, sn; 567 568 if (flag == CONT) 569 npf = bp->b_error; 570 else 571 npf = btodb(bp->b_bcount + (rk->rkwc * sizeof(short)) + 511); 572 reg = btop(um->um_ubinfo&0x3ffff) + npf; 573 o = (int)bp->b_un.b_addr & PGOFSET; 574 bn = bp->b_blkno; 575 st = &rkst[ui->ui_type]; 576 cn = bp->b_cylin; 577 sn = bn%st->nspc + npf; 578 tn = sn/st->nsect; 579 sn %= st->nsect; 580 cn += tn/st->ntrak; 581 tn %= st->ntrak; 582 ubapurge(um); 583 switch (flag) { 584 case ECC: 585 { 586 register int i; 587 int bit, byte, mask; 588 589 npf--; 590 reg--; 591 log(LOG_WARNING, "rk%d%c: soft ecc sn%d\n", rkunit(bp->b_dev), 592 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); 593 mask = rk->rkec2; 594 i = rk->rkec1 - 1; /* -1 makes 0 origin */ 595 bit = i&07; 596 i = (i&~07)>>3; 597 byte = i + o; 598 while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) { 599 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 600 (byte & PGOFSET); 601 putmemc(addr, getmemc(addr)^(mask<<bit)); 602 byte++; 603 i++; 604 bit -= 8; 605 } 606 if (rk->rkwc == 0) { 607 um->um_tab.b_active = 0; 608 return (0); 609 } 610 npf++; 611 reg++; 612 break; 613 } 614 615 case BSE: 616 #ifdef RKBDEBUG 617 if (rkbdebug) 618 printf("rkecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 619 #endif 620 if ((bn = isbad(&rkbad[ui->ui_unit], cn, tn, sn)) < 0) 621 return(0); 622 bp->b_flags |= B_BAD; 623 bp->b_error = npf + 1; 624 bn = st->ncyl*st->nspc - st->nsect - 1 - bn; 625 cn = bn/st->nspc; 626 sn = bn%st->nspc; 627 tn = sn/st->nsect; 628 sn %= st->nsect; 629 #ifdef RKBDEBUG 630 if (rkbdebug) 631 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 632 #endif 633 rk->rkwc = -(512 / sizeof (short)); 634 break; 635 636 case CONT: 637 #ifdef RKBDEBUG 638 if (rkbdebug) 639 printf("rkecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); 640 #endif 641 bp->b_flags &= ~B_BAD; 642 if ((int)dbtob(npf) >= bp->b_bcount) 643 return (0); 644 rk->rkwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof (short)); 645 break; 646 } 647 rk->rkcs1 = RK_CCLR; 648 rk->rkcs2 = ui->ui_slave; 649 rk->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 650 rkwait(rk); 651 rk->rkcyl = cn; 652 rk->rkda = (tn << 8) | sn; 653 ubaddr = (int)ptob(reg) + o; 654 rk->rkba = ubaddr; 655 cmd = (bp->b_flags&B_READ ? RK_READ : RK_WRITE)|RK_IE|RK_GO; 656 cmd |= (ubaddr >> 8) & 0x300; 657 cmd |= rktypes[ui->ui_type]; 658 rk->rkcs1 = cmd; 659 um->um_tab.b_active = 2; /* continuing */ 660 um->um_tab.b_errcnt = 0; /* error has been corrected */ 661 return (1); 662 } 663 664 rkreset(uban) 665 int uban; 666 { 667 register struct uba_ctlr *um; 668 register struct uba_device *ui; 669 register rk11, unit; 670 671 for (rk11 = 0; rk11 < NHK; rk11++) { 672 if ((um = rkminfo[rk11]) == 0 || um->um_ubanum != uban || 673 um->um_alive == 0) 674 continue; 675 printf(" hk%d", rk11); 676 um->um_tab.b_active = 0; 677 um->um_tab.b_actf = um->um_tab.b_actl = 0; 678 rk_softc[um->um_ctlr].sc_recal = 0; 679 rk_softc[um->um_ctlr].sc_wticks = 0; 680 if (um->um_ubinfo) { 681 printf("<%d>", (um->um_ubinfo>>28)&0xf); 682 um->um_ubinfo = 0; 683 } 684 for (unit = 0; unit < NRK; unit++) { 685 if ((ui = rkdinfo[unit]) == 0) 686 continue; 687 if (ui->ui_alive == 0 || ui->ui_mi != um) 688 continue; 689 rkutab[unit].b_active = 0; 690 (void) rkustart(ui); 691 } 692 (void) rkstart(um); 693 } 694 } 695 696 rkwatch() 697 { 698 register struct uba_ctlr *um; 699 register rk11, unit; 700 register struct rk_softc *sc; 701 702 timeout(rkwatch, (caddr_t)0, hz); 703 for (rk11 = 0; rk11 < NHK; rk11++) { 704 um = rkminfo[rk11]; 705 if (um == 0 || um->um_alive == 0) 706 continue; 707 sc = &rk_softc[rk11]; 708 if (um->um_tab.b_active == 0) { 709 for (unit = 0; unit < NRK; unit++) 710 if (rkutab[unit].b_active && 711 rkdinfo[unit]->ui_mi == um) 712 goto active; 713 sc->sc_wticks = 0; 714 continue; 715 } 716 active: 717 sc->sc_wticks++; 718 if (sc->sc_wticks >= 20) { 719 sc->sc_wticks = 0; 720 printf("hk%d: lost interrupt\n", rk11); 721 ubareset(um->um_ubanum); 722 } 723 } 724 } 725 726 #define DBSIZE 20 727 728 rkdump(dev) 729 dev_t dev; 730 { 731 struct rkdevice *rkaddr; 732 char *start; 733 int num, blk, unit; 734 struct size *sizes; 735 register struct uba_regs *uba; 736 register struct uba_device *ui; 737 register short *rp; 738 struct rkst *st; 739 740 unit = rkunit(dev); 741 if (unit >= NRK) 742 return (ENXIO); 743 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 744 ui = phys(struct uba_device *, rkdinfo[unit]); 745 if (ui->ui_alive == 0) 746 return (ENXIO); 747 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 748 ubainit(uba); 749 rkaddr = (struct rkdevice *)ui->ui_physaddr; 750 num = maxfree; 751 start = 0; 752 rkaddr->rkcs1 = RK_CCLR; 753 rkaddr->rkcs2 = unit; 754 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_DCLR|RK_GO; 755 rkwait(rkaddr); 756 if ((rkaddr->rkds & RKDS_VV) == 0) { 757 rkaddr->rkcs1 = rktypes[ui->ui_type]|RK_IE|RK_PACK|RK_GO; 758 rkwait(rkaddr); 759 } 760 st = &rkst[ui->ui_type]; 761 sizes = phys(struct size *, st->sizes); 762 if (dumplo < 0) 763 return (EINVAL); 764 if (dumplo + num >= sizes[minor(dev)&07].nblocks) 765 num = sizes[minor(dev)&07].nblocks - dumplo; 766 while (num > 0) { 767 register struct pte *io; 768 register int i; 769 int cn, sn, tn; 770 daddr_t bn; 771 772 blk = num > DBSIZE ? DBSIZE : num; 773 io = uba->uba_map; 774 for (i = 0; i < blk; i++) 775 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 776 *(int *)io = 0; 777 bn = dumplo + btop(start); 778 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 779 sn = bn%st->nspc; 780 tn = sn/st->nsect; 781 sn = sn%st->nsect; 782 rkaddr->rkcyl = cn; 783 rp = (short *) &rkaddr->rkda; 784 *rp = (tn << 8) + sn; 785 *--rp = 0; 786 *--rp = -blk*NBPG / sizeof (short); 787 *--rp = rktypes[ui->ui_type]|RK_GO|RK_WRITE; 788 rkwait(rkaddr); 789 if (rkaddr->rkcs1 & RK_CERR) 790 return (EIO); 791 start += blk*NBPG; 792 num -= blk; 793 } 794 return (0); 795 } 796 797 rksize(dev) 798 dev_t dev; 799 { 800 int unit = rkunit(dev); 801 struct uba_device *ui; 802 struct rkst *st; 803 804 if (unit >= NRK || (ui = rkdinfo[unit]) == 0 || ui->ui_alive == 0) 805 return (-1); 806 st = &rkst[ui->ui_type]; 807 return (st->sizes[minor(dev) & 07].nblocks); 808 } 809 #endif 810