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 * @(#)up.c 7.7 (Berkeley) 04/25/89 7 */ 8 9 #include "up.h" 10 #if NSC > 0 11 /* 12 * UNIBUS disk driver with: 13 * overlapped seeks, 14 * ECC recovery, and 15 * bad sector forwarding. 16 * 17 * TODO: 18 * Check that offset recovery code works 19 */ 20 #include "machine/pte.h" 21 22 #include "param.h" 23 #include "systm.h" 24 #include "dkstat.h" 25 #include "dkbad.h" 26 #include "ioctl.h" 27 #include "disklabel.h" 28 #include "buf.h" 29 #include "conf.h" 30 #include "dir.h" 31 #include "user.h" 32 #include "map.h" 33 #include "vm.h" 34 #include "cmap.h" 35 #include "uio.h" 36 #include "kernel.h" 37 #include "syslog.h" 38 39 #include "../vax/cpu.h" 40 #include "../vax/nexus.h" 41 #include "ubavar.h" 42 #include "ubareg.h" 43 #include "upreg.h" 44 45 struct up_softc { 46 int sc_softas; 47 int sc_ndrive; 48 int sc_wticks; 49 int sc_recal; 50 } up_softc[NSC]; 51 52 #define upunit(dev) (minor(dev) >> 3) 53 54 /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ 55 struct size { 56 daddr_t nblocks; 57 int cyloff; 58 } up9300_sizes[8] = { 59 15884, 0, /* A=cyl 0 thru 26 */ 60 33440, 27, /* B=cyl 27 thru 81 */ 61 495520, 0, /* C=cyl 0 thru 814 */ 62 15884, 562, /* D=cyl 562 thru 588 */ 63 55936, 589, /* E=cyl 589 thru 680 */ 64 81376, 681, /* F=cyl 681 thru 814 */ 65 153728, 562, /* G=cyl 562 thru 814 */ 66 291346, 82, /* H=cyl 82 thru 561 */ 67 }, up9766_sizes[8] = { 68 15884, 0, /* A=cyl 0 thru 26 */ 69 33440, 27, /* B=cyl 27 thru 81 */ 70 500384, 0, /* C=cyl 0 thru 822 */ 71 15884, 562, /* D=cyl 562 thru 588 */ 72 55936, 589, /* E=cyl 589 thru 680 */ 73 86240, 681, /* F=cyl 681 thru 822 */ 74 158592, 562, /* G=cyl 562 thru 822 */ 75 291346, 82, /* H=cyl 82 thru 561 */ 76 }, up160_sizes[8] = { 77 15884, 0, /* A=cyl 0 thru 49 */ 78 33440, 50, /* B=cyl 50 thru 154 */ 79 263360, 0, /* C=cyl 0 thru 822 */ 80 15884, 155, /* D=cyl 155 thru 204 */ 81 55936, 205, /* E=cyl 205 thru 379 */ 82 141664, 380, /* F=cyl 380 thru 822 */ 83 213664, 155, /* G=cyl 155 thru 822 */ 84 0, 0, 85 }, upam_sizes[8] = { 86 15884, 0, /* A=cyl 0 thru 31 */ 87 33440, 32, /* B=cyl 32 thru 97 */ 88 524288, 0, /* C=cyl 0 thru 1023 */ 89 15884, 668, /* D=cyl 668 thru 699 */ 90 55936, 700, /* E=cyl 700 thru 809 */ 91 109472, 810, /* F=cyl 810 thru 1023 */ 92 182176, 668, /* G=cyl 668 thru 1023 */ 93 291346, 98, /* H=cyl 98 thru 667 */ 94 }, up980_sizes[8] = { 95 15884, 0, /* A=cyl 0 thru 99 */ 96 33440, 100, /* B=cyl 100 thru 308 */ 97 131680, 0, /* C=cyl 0 thru 822 */ 98 15884, 309, /* D=cyl 309 thru 408 */ 99 55936, 409, /* E=cyl 409 thru 758 */ 100 10080, 759, /* F=cyl 759 thru 822 */ 101 82080, 309, /* G=cyl 309 thru 822 */ 102 0, 0, 103 }, upeagle_sizes[8] = { 104 15884, 0, /* A=cyl 0 thru 16 */ 105 66880, 17, /* B=cyl 17 thru 86 */ 106 808320, 0, /* C=cyl 0 thru 841 */ 107 15884, 391, /* D=cyl 391 thru 407 */ 108 307200, 408, /* E=cyl 408 thru 727 */ 109 109296, 728, /* F=cyl 728 thru 841 */ 110 432816, 391, /* G=cyl 391 thru 841 */ 111 291346, 87, /* H=cyl 87 thru 390 */ 112 }; 113 /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ 114 115 int upprobe(), upslave(), upattach(), updgo(), upintr(); 116 struct uba_ctlr *upminfo[NSC]; 117 struct uba_device *updinfo[NUP]; 118 #define UPIPUNITS 8 119 struct uba_device *upip[NSC][UPIPUNITS]; /* fuji w/fixed head gives n,n+4 */ 120 121 u_short upstd[] = { 0776700, 0774400, 0776300, 0 }; 122 struct uba_driver scdriver = 123 { upprobe, upslave, upattach, updgo, upstd, "up", updinfo, "sc", upminfo }; 124 struct buf uputab[NUP]; 125 char upinit[NUP]; 126 127 struct upst { 128 short nsect; /* # sectors/track */ 129 short ntrak; /* # tracks/cylinder */ 130 short nspc; /* # sectors/cylinder */ 131 short ncyl; /* # cylinders */ 132 struct size *sizes; /* partition tables */ 133 short sdist; /* seek distance metric */ 134 short rdist; /* rotational distance metric */ 135 } upst[] = { 136 { 32, 19, 32*19, 815, up9300_sizes, 3, 4 }, /* 9300 */ 137 { 32, 19, 32*19, 823, up9766_sizes, 3, 4 }, /* 9766 */ 138 { 32, 10, 32*10, 823, up160_sizes, 3, 4 }, /* fuji 160m */ 139 { 32, 16, 32*16, 1024, upam_sizes, 7, 8 }, /* Capricorn */ 140 { 32, 5, 32*5, 823, up980_sizes, 3, 4 }, /* DM980 */ 141 { 48, 20, 48*20, 842, upeagle_sizes, 15, 8 }, /* EAGLE */ 142 { 0, 0, 0, 0, 0, 0, 0 } 143 }; 144 145 u_char up_offset[16] = { 146 UPOF_P400, UPOF_M400, UPOF_P400, UPOF_M400, 147 UPOF_P800, UPOF_M800, UPOF_P800, UPOF_M800, 148 UPOF_P1200, UPOF_M1200, UPOF_P1200, UPOF_M1200, 149 0, 0, 0, 0 150 }; 151 152 struct buf bupbuf[NUP]; 153 struct dkbad upbad[NUP]; 154 155 #define b_cylin b_resid 156 157 int upwstart, upwatch(); /* Have started guardian */ 158 int upseek; 159 int upwaitdry; 160 161 /*ARGSUSED*/ 162 upprobe(reg) 163 caddr_t reg; 164 { 165 register int br, cvec; 166 167 #ifdef lint 168 br = 0; cvec = br; br = cvec; upintr(0); 169 #endif 170 ((struct updevice *)reg)->upcs1 = UP_IE|UP_RDY; 171 DELAY(10); 172 ((struct updevice *)reg)->upcs1 = 0; 173 return (sizeof (struct updevice)); 174 } 175 176 upslave(ui, reg) 177 struct uba_device *ui; 178 caddr_t reg; 179 { 180 register struct updevice *upaddr = (struct updevice *)reg; 181 182 upaddr->upcs1 = 0; /* conservative */ 183 upaddr->upcs2 = ui->ui_slave; 184 upaddr->upcs1 = UP_NOP|UP_GO; 185 if (upaddr->upcs2&UPCS2_NED) { 186 upaddr->upcs1 = UP_DCLR|UP_GO; 187 return (0); 188 } 189 return (1); 190 } 191 192 upattach(ui) 193 register struct uba_device *ui; 194 { 195 196 if (upwstart == 0) { 197 timeout(upwatch, (caddr_t)0, hz); 198 upwstart++; 199 } 200 if (ui->ui_dk >= 0) 201 dk_mspw[ui->ui_dk] = .0000020345; 202 upip[ui->ui_ctlr][ui->ui_slave] = ui; 203 up_softc[ui->ui_ctlr].sc_ndrive++; 204 ui->ui_type = upmaptype(ui); 205 } 206 207 upmaptype(ui) 208 register struct uba_device *ui; 209 { 210 register struct updevice *upaddr = (struct updevice *)ui->ui_addr; 211 int type = ui->ui_type; 212 register struct upst *st; 213 214 upaddr->upcs1 = 0; 215 upaddr->upcs2 = ui->ui_slave; 216 upaddr->uphr = UPHR_MAXTRAK; 217 for (st = upst; st->nsect != 0; st++) 218 if (upaddr->uphr == st->ntrak - 1) { 219 type = st - upst; 220 break; 221 } 222 if (st->nsect == 0) 223 printf(": uphr=%x", upaddr->uphr); 224 if (type == 0) { 225 upaddr->uphr = UPHR_MAXCYL; 226 if (upaddr->uphr == 822) 227 type++; 228 } 229 upaddr->upcs2 = UPCS2_CLR; 230 return (type); 231 } 232 233 upopen(dev) 234 dev_t dev; 235 { 236 register int unit = upunit(dev); 237 register struct uba_device *ui; 238 239 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0) 240 return (ENXIO); 241 return (0); 242 } 243 244 upstrategy(bp) 245 register struct buf *bp; 246 { 247 register struct uba_device *ui; 248 register struct upst *st; 249 register int unit; 250 register struct buf *dp; 251 int xunit = minor(bp->b_dev) & 07; 252 long bn, sz; 253 int s; 254 255 sz = (bp->b_bcount+511) >> 9; 256 unit = upunit(bp->b_dev); 257 if (unit >= NUP) { 258 bp->b_error = ENXIO; 259 goto bad; 260 } 261 ui = updinfo[unit]; 262 if (ui == 0 || ui->ui_alive == 0) { 263 bp->b_error = ENXIO; 264 goto bad; 265 } 266 st = &upst[ui->ui_type]; 267 if (bp->b_blkno < 0 || 268 (bn = bp->b_blkno)+sz > st->sizes[xunit].nblocks) { 269 if (bp->b_blkno == st->sizes[xunit].nblocks) { 270 bp->b_resid = bp->b_bcount; 271 goto done; 272 } 273 bp->b_error = EINVAL; 274 goto bad; 275 } 276 bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; 277 s = spl5(); 278 dp = &uputab[ui->ui_unit]; 279 disksort(dp, bp); 280 if (dp->b_active == 0) { 281 (void) upustart(ui); 282 bp = &ui->ui_mi->um_tab; 283 if (bp->b_actf && bp->b_active == 0) 284 (void) upstart(ui->ui_mi); 285 } 286 splx(s); 287 return; 288 289 bad: 290 bp->b_flags |= B_ERROR; 291 done: 292 iodone(bp); 293 return; 294 } 295 296 /* 297 * Unit start routine. 298 * Seek the drive to be where the data is 299 * and then generate another interrupt 300 * to actually start the transfer. 301 * If there is only one drive on the controller, 302 * or we are very close to the data, don't 303 * bother with the search. If called after 304 * searching once, don't bother to look where 305 * we are, just queue for transfer (to avoid 306 * positioning forever without transferrring.) 307 */ 308 upustart(ui) 309 register struct uba_device *ui; 310 { 311 register struct buf *bp, *dp; 312 register struct uba_ctlr *um; 313 register struct updevice *upaddr; 314 register struct upst *st; 315 daddr_t bn; 316 int sn, csn; 317 /* 318 * The SC21 cancels commands if you just say 319 * cs1 = UP_IE 320 * so we are cautious about handling of cs1. 321 * Also don't bother to clear as bits other than in upintr(). 322 */ 323 int didie = 0; 324 325 if (ui == 0) 326 return (0); 327 um = ui->ui_mi; 328 dk_busy &= ~(1<<ui->ui_dk); 329 dp = &uputab[ui->ui_unit]; 330 if ((bp = dp->b_actf) == NULL) 331 goto out; 332 /* 333 * If the controller is active, just remember 334 * that this device would like to be positioned... 335 * if we tried to position now we would confuse the SC21. 336 */ 337 if (um->um_tab.b_active) { 338 up_softc[um->um_ctlr].sc_softas |= 1<<ui->ui_slave; 339 return (0); 340 } 341 /* 342 * If we have already positioned this drive, 343 * then just put it on the ready queue. 344 */ 345 if (dp->b_active) 346 goto done; 347 dp->b_active = 1; 348 upaddr = (struct updevice *)um->um_addr; 349 upaddr->upcs2 = ui->ui_slave; 350 /* 351 * If drive has just come up, 352 * setup the pack. 353 */ 354 if ((upaddr->upds & UPDS_VV) == 0 || upinit[ui->ui_unit] == 0) { 355 struct buf *bbp = &bupbuf[ui->ui_unit]; 356 357 /* SHOULD WARN SYSTEM THAT THIS HAPPENED */ 358 upinit[ui->ui_unit] = 1; 359 upaddr->upcs1 = UP_IE|UP_DCLR|UP_GO; 360 upaddr->upcs1 = UP_IE|UP_PRESET|UP_GO; 361 upaddr->upof = UPOF_FMT22; 362 didie = 1; 363 st = &upst[ui->ui_type]; 364 bbp->b_flags = B_READ|B_BUSY; 365 bbp->b_dev = bp->b_dev; 366 bbp->b_bcount = 512; 367 bbp->b_un.b_addr = (caddr_t)&upbad[ui->ui_unit]; 368 bbp->b_blkno = st->ncyl * st->nspc - st->nsect; 369 bbp->b_cylin = st->ncyl - 1; 370 dp->b_actf = bbp; 371 bbp->av_forw = bp; 372 bp = bbp; 373 } 374 /* 375 * If drive is offline, forget about positioning. 376 */ 377 if ((upaddr->upds & (UPDS_DPR|UPDS_MOL)) != (UPDS_DPR|UPDS_MOL)) 378 goto done; 379 /* 380 * If there is only one drive, 381 * dont bother searching. 382 */ 383 if (up_softc[um->um_ctlr].sc_ndrive == 1) 384 goto done; 385 /* 386 * Figure out where this transfer is going to 387 * and see if we are close enough to justify not searching. 388 */ 389 st = &upst[ui->ui_type]; 390 bn = bp->b_blkno; 391 sn = bn%st->nspc; 392 sn = (sn + st->nsect - st->sdist) % st->nsect; 393 if (bp->b_cylin - upaddr->updc) 394 goto search; /* Not on-cylinder */ 395 else if (upseek) 396 goto done; /* Ok just to be on-cylinder */ 397 csn = (upaddr->upla>>6) - sn - 1; 398 if (csn < 0) 399 csn += st->nsect; 400 if (csn > st->nsect - st->rdist) 401 goto done; 402 search: 403 upaddr->updc = bp->b_cylin; 404 /* 405 * Not on cylinder at correct position, 406 * seek/search. 407 */ 408 if (upseek) 409 upaddr->upcs1 = UP_IE|UP_SEEK|UP_GO; 410 else { 411 upaddr->upda = sn; 412 upaddr->upcs1 = UP_IE|UP_SEARCH|UP_GO; 413 } 414 didie = 1; 415 /* 416 * Mark unit busy for iostat. 417 */ 418 if (ui->ui_dk >= 0) { 419 dk_busy |= 1<<ui->ui_dk; 420 dk_seek[ui->ui_dk]++; 421 } 422 goto out; 423 done: 424 /* 425 * Device is ready to go. 426 * Put it on the ready queue for the controller 427 * (unless its already there.) 428 */ 429 if (dp->b_active != 2) { 430 dp->b_forw = NULL; 431 if (um->um_tab.b_actf == NULL) 432 um->um_tab.b_actf = dp; 433 else 434 um->um_tab.b_actl->b_forw = dp; 435 um->um_tab.b_actl = dp; 436 dp->b_active = 2; 437 } 438 out: 439 return (didie); 440 } 441 442 /* 443 * Start up a transfer on a drive. 444 */ 445 upstart(um) 446 register struct uba_ctlr *um; 447 { 448 register struct buf *bp, *dp; 449 register struct uba_device *ui; 450 register struct updevice *upaddr; 451 struct upst *st; 452 daddr_t bn; 453 int dn, sn, tn, cmd, waitdry; 454 455 loop: 456 /* 457 * Pull a request off the controller queue 458 */ 459 if ((dp = um->um_tab.b_actf) == NULL) 460 return (0); 461 if ((bp = dp->b_actf) == NULL) { 462 um->um_tab.b_actf = dp->b_forw; 463 goto loop; 464 } 465 /* 466 * Mark controller busy, and 467 * determine destination of this request. 468 */ 469 um->um_tab.b_active++; 470 ui = updinfo[upunit(bp->b_dev)]; 471 bn = bp->b_blkno; 472 dn = ui->ui_slave; 473 st = &upst[ui->ui_type]; 474 sn = bn%st->nspc; 475 tn = sn/st->nsect; 476 sn %= st->nsect; 477 upaddr = (struct updevice *)ui->ui_addr; 478 /* 479 * Select drive if not selected already. 480 */ 481 if ((upaddr->upcs2&07) != dn) 482 upaddr->upcs2 = dn; 483 /* 484 * Check that it is ready and online 485 */ 486 waitdry = 0; 487 while ((upaddr->upds&UPDS_DRY) == 0) { 488 printf("up%d: ds wait ds=%o\n",upunit(bp->b_dev),upaddr->upds); 489 if (++waitdry > 512) 490 break; 491 upwaitdry++; 492 } 493 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 494 printf("up%d: not ready", upunit(bp->b_dev)); 495 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 496 printf("\n"); 497 um->um_tab.b_active = 0; 498 um->um_tab.b_errcnt = 0; 499 dp->b_actf = bp->av_forw; 500 dp->b_active = 0; 501 bp->b_flags |= B_ERROR; 502 iodone(bp); 503 goto loop; 504 } 505 /* 506 * Oh, well, sometimes this 507 * happens, for reasons unknown. 508 */ 509 printf(" (flakey)\n"); 510 } 511 /* 512 * Setup for the transfer, and get in the 513 * UNIBUS adaptor queue. 514 */ 515 upaddr->updc = bp->b_cylin; 516 upaddr->upda = (tn << 8) + sn; 517 upaddr->upwc = -bp->b_bcount / sizeof (short); 518 if (bp->b_flags & B_READ) 519 cmd = UP_IE|UP_RCOM|UP_GO; 520 else 521 cmd = UP_IE|UP_WCOM|UP_GO; 522 um->um_cmd = cmd; 523 (void) ubago(ui); 524 return (1); 525 } 526 527 /* 528 * Now all ready to go, stuff the registers. 529 */ 530 updgo(um) 531 struct uba_ctlr *um; 532 { 533 register struct updevice *upaddr = (struct updevice *)um->um_addr; 534 535 um->um_tab.b_active = 2; /* should now be 2 */ 536 upaddr->upba = um->um_ubinfo; 537 upaddr->upcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x300); 538 } 539 540 /* 541 * Handle a disk interrupt. 542 */ 543 upintr(sc21) 544 register sc21; 545 { 546 register struct buf *bp, *dp; 547 register struct uba_ctlr *um = upminfo[sc21]; 548 register struct uba_device *ui; 549 register struct updevice *upaddr = (struct updevice *)um->um_addr; 550 register unit; 551 struct up_softc *sc = &up_softc[um->um_ctlr]; 552 int as = (upaddr->upas & 0377) | sc->sc_softas; 553 int needie = 1, waitdry; 554 555 sc->sc_wticks = 0; 556 sc->sc_softas = 0; 557 /* 558 * If controller wasn't transferring, then this is an 559 * interrupt for attention status on seeking drives. 560 * Just service them. 561 */ 562 if (um->um_tab.b_active != 2 && !sc->sc_recal) { 563 if (upaddr->upcs1 & UP_TRE) 564 upaddr->upcs1 = UP_TRE; 565 goto doattn; 566 } 567 um->um_tab.b_active = 1; 568 /* 569 * Get device and block structures, and a pointer 570 * to the uba_device for the drive. Select the drive. 571 */ 572 dp = um->um_tab.b_actf; 573 bp = dp->b_actf; 574 ui = updinfo[upunit(bp->b_dev)]; 575 dk_busy &= ~(1 << ui->ui_dk); 576 if ((upaddr->upcs2&07) != ui->ui_slave) 577 upaddr->upcs2 = ui->ui_slave; 578 if (bp->b_flags&B_BAD) { 579 if (upecc(ui, CONT)) 580 return; 581 } 582 /* 583 * Check for and process errors on 584 * either the drive or the controller. 585 */ 586 if ((upaddr->upds&UPDS_ERR) || (upaddr->upcs1&UP_TRE)) { 587 waitdry = 0; 588 while ((upaddr->upds & UPDS_DRY) == 0) { 589 if (++waitdry > 512) 590 break; 591 upwaitdry++; 592 } 593 if (upaddr->uper1&UPER1_WLE) { 594 /* 595 * Give up on write locked devices 596 * immediately. 597 */ 598 printf("up%d: write locked\n", upunit(bp->b_dev)); 599 bp->b_flags |= B_ERROR; 600 } else if (++um->um_tab.b_errcnt > 27) { 601 /* 602 * After 28 retries (16 without offset, and 603 * 12 with offset positioning) give up. 604 * If the error was header CRC, the header is 605 * screwed up, and the sector may in fact exist 606 * in the bad sector table, better check... 607 */ 608 if (upaddr->uper1&UPER1_HCRC) { 609 if (upecc(ui, BSE)) 610 return; 611 } 612 hard: 613 diskerr(bp, "up", "hard error", LOG_PRINTF, -1, 614 (struct disklabel *)0); 615 printf(" cn=%d tn=%d sn=%d cs2=%b er1=%b er2=%b\n", 616 upaddr->updc, ((upaddr->upda)>>8)&077, 617 (upaddr->upda)&037, 618 upaddr->upcs2, UPCS2_BITS, 619 upaddr->uper1, UPER1_BITS, 620 upaddr->uper2, UPER2_BITS); 621 bp->b_flags |= B_ERROR; 622 } else if (upaddr->uper2 & UPER2_BSE) { 623 if (upecc(ui, BSE)) 624 return; 625 else 626 goto hard; 627 } else { 628 /* 629 * Retriable error. 630 * If a soft ecc, correct it (continuing 631 * by returning if necessary. 632 * Otherwise fall through and retry the transfer 633 */ 634 if ((upaddr->uper1&(UPER1_DCK|UPER1_ECH))==UPER1_DCK) { 635 if (upecc(ui, ECC)) 636 return; 637 } else 638 um->um_tab.b_active = 0; /* force retry */ 639 } 640 /* 641 * Clear drive error and, every eight attempts, 642 * (starting with the fourth) 643 * recalibrate to clear the slate. 644 */ 645 upaddr->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 646 needie = 0; 647 if ((um->um_tab.b_errcnt&07) == 4 && um->um_tab.b_active == 0) { 648 upaddr->upcs1 = UP_RECAL|UP_IE|UP_GO; 649 sc->sc_recal = 0; 650 goto nextrecal; 651 } 652 } 653 /* 654 * Advance recalibration finite state machine 655 * if recalibrate in progress, through 656 * RECAL 657 * SEEK 658 * OFFSET (optional) 659 * RETRY 660 */ 661 switch (sc->sc_recal) { 662 663 case 1: 664 upaddr->updc = bp->b_cylin; 665 upaddr->upcs1 = UP_SEEK|UP_IE|UP_GO; 666 goto nextrecal; 667 case 2: 668 if (um->um_tab.b_errcnt < 16 || (bp->b_flags&B_READ) == 0) 669 goto donerecal; 670 upaddr->upof = up_offset[um->um_tab.b_errcnt & 017] | UPOF_FMT22; 671 upaddr->upcs1 = UP_IE|UP_OFFSET|UP_GO; 672 goto nextrecal; 673 nextrecal: 674 sc->sc_recal++; 675 um->um_tab.b_active = 1; 676 return; 677 donerecal: 678 case 3: 679 sc->sc_recal = 0; 680 um->um_tab.b_active = 0; 681 break; 682 } 683 /* 684 * If still ``active'', then don't need any more retries. 685 */ 686 if (um->um_tab.b_active) { 687 /* 688 * If we were offset positioning, 689 * return to centerline. 690 */ 691 if (um->um_tab.b_errcnt >= 16) { 692 upaddr->upof = UPOF_FMT22; 693 upaddr->upcs1 = UP_RTC|UP_GO|UP_IE; 694 while (upaddr->upds & UPDS_PIP) 695 DELAY(25); 696 needie = 0; 697 } 698 um->um_tab.b_active = 0; 699 um->um_tab.b_errcnt = 0; 700 um->um_tab.b_actf = dp->b_forw; 701 dp->b_active = 0; 702 dp->b_errcnt = 0; 703 dp->b_actf = bp->av_forw; 704 bp->b_resid = (-upaddr->upwc * sizeof(short)); 705 iodone(bp); 706 /* 707 * If this unit has more work to do, 708 * then start it up right away. 709 */ 710 if (dp->b_actf) 711 if (upustart(ui)) 712 needie = 0; 713 } 714 as &= ~(1<<ui->ui_slave); 715 /* 716 * Release unibus resources and flush data paths. 717 */ 718 ubadone(um); 719 doattn: 720 /* 721 * Process other units which need attention. 722 * For each unit which needs attention, call 723 * the unit start routine to place the slave 724 * on the controller device queue. 725 */ 726 while (unit = ffs((long)as)) { 727 unit--; /* was 1 origin */ 728 as &= ~(1<<unit); 729 upaddr->upas = 1<<unit; 730 if (unit < UPIPUNITS && upustart(upip[sc21][unit])) 731 needie = 0; 732 } 733 /* 734 * If the controller is not transferring, but 735 * there are devices ready to transfer, start 736 * the controller. 737 */ 738 if (um->um_tab.b_actf && um->um_tab.b_active == 0) 739 if (upstart(um)) 740 needie = 0; 741 if (needie) 742 upaddr->upcs1 = UP_IE; 743 } 744 745 /* 746 * Correct an ECC error, and restart the i/o to complete 747 * the transfer if necessary. This is quite complicated because 748 * the transfer may be going to an odd memory address base and/or 749 * across a page boundary. 750 */ 751 upecc(ui, flag) 752 register struct uba_device *ui; 753 int flag; 754 { 755 register struct updevice *up = (struct updevice *)ui->ui_addr; 756 register struct buf *bp = uputab[ui->ui_unit].b_actf; 757 register struct uba_ctlr *um = ui->ui_mi; 758 register struct upst *st; 759 struct uba_regs *ubp = ui->ui_hd->uh_uba; 760 register int i; 761 caddr_t addr; 762 int reg, bit, byte, npf, mask, o, cmd, ubaddr; 763 int bn, cn, tn, sn; 764 765 /* 766 * Npf is the number of sectors transferred before the sector 767 * containing the ECC error, and reg is the UBA register 768 * mapping (the first part of) the transfer. 769 * O is offset within a memory page of the first byte transferred. 770 */ 771 if (flag == CONT) 772 npf = bp->b_error; 773 else 774 npf = btodb(bp->b_bcount + (up->upwc * sizeof(short)) + 511); 775 reg = btop(UBAI_ADDR(um->um_ubinfo)) + npf; 776 o = (int)bp->b_un.b_addr & PGOFSET; 777 mask = up->upec2; 778 #ifdef UPECCDEBUG 779 printf("npf %d reg %x o %d mask %o pos %d\n", npf, reg, o, mask, 780 up->upec1); 781 #endif 782 bn = bp->b_blkno; 783 st = &upst[ui->ui_type]; 784 cn = bp->b_cylin; 785 sn = bn%st->nspc + npf; 786 tn = sn/st->nsect; 787 sn %= st->nsect; 788 cn += tn/st->ntrak; 789 tn %= st->ntrak; 790 ubapurge(um); 791 um->um_tab.b_active=2; 792 /* 793 * action taken depends on the flag 794 */ 795 switch(flag){ 796 case ECC: 797 npf--; 798 reg--; 799 mask = up->upec2; 800 diskerr(bp, "up", "soft ecc", LOG_WARNING, npf, 801 (struct disklabel *)0); 802 addlog("\n"); 803 /* 804 * Flush the buffered data path, and compute the 805 * byte and bit position of the error. The variable i 806 * is the byte offset in the transfer, the variable byte 807 * is the offset from a page boundary in main memory. 808 */ 809 i = up->upec1 - 1; /* -1 makes 0 origin */ 810 bit = i&07; 811 i = (i&~07)>>3; 812 byte = i + o; 813 /* 814 * Correct while possible bits remain of mask. Since mask 815 * contains 11 bits, we continue while the bit offset is > -11. 816 * Also watch out for end of this block and the end of the whole 817 * transfer. 818 */ 819 while (i < 512 && (int)dbtob(npf)+i < bp->b_bcount && bit > -11) { 820 struct pte pte; 821 822 pte = ubp->uba_map[reg + btop(byte)]; 823 addr = ptob(pte.pg_pfnum) + (byte & PGOFSET); 824 #ifdef UPECCDEBUG 825 printf("addr %x map reg %x\n", 826 addr, *(int *)(&ubp->uba_map[reg+btop(byte)])); 827 printf("old: %x, ", getmemc(addr)); 828 #endif 829 putmemc(addr, getmemc(addr)^(mask<<bit)); 830 #ifdef UPECCDEBUG 831 printf("new: %x\n", getmemc(addr)); 832 #endif 833 byte++; 834 i++; 835 bit -= 8; 836 } 837 if (up->upwc == 0) 838 return (0); 839 npf++; 840 reg++; 841 break; 842 case BSE: 843 /* 844 * if not in bad sector table, return 0 845 */ 846 if ((bn = isbad(&upbad[ui->ui_unit], cn, tn, sn)) < 0) 847 return(0); 848 /* 849 * flag this one as bad 850 */ 851 bp->b_flags |= B_BAD; 852 bp->b_error = npf + 1; 853 #ifdef UPECCDEBUG 854 printf("BSE: restart at %d\n",npf+1); 855 #endif 856 bn = st->ncyl * st->nspc -st->nsect - 1 - bn; 857 cn = bn / st->nspc; 858 sn = bn % st->nspc; 859 tn = sn / st->nsect; 860 sn %= st->nsect; 861 up->upwc = -(512 / sizeof (short)); 862 #ifdef UPECCDEBUG 863 printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); 864 #endif 865 break; 866 case CONT: 867 #ifdef UPECCDEBUG 868 printf("upecc, CONT: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); 869 #endif 870 bp->b_flags &= ~B_BAD; 871 if ((int)dbtob(npf) >= bp->b_bcount) 872 return (0); 873 up->upwc = -((bp->b_bcount - (int)dbtob(npf)) / sizeof(short)); 874 break; 875 } 876 if (up->upwc == 0) { 877 um->um_tab.b_active = 0; 878 return (0); 879 } 880 /* 881 * Have to continue the transfer... clear the drive, 882 * and compute the position where the transfer is to continue. 883 * We have completed npf+1 sectors of the transfer already; 884 * restart at offset o of next sector (i.e. in UBA register reg+1). 885 */ 886 #ifdef notdef 887 up->uper1 = 0; 888 up->upcs1 |= UP_GO; 889 #else 890 up->upcs1 = UP_TRE|UP_IE|UP_DCLR|UP_GO; 891 up->updc = cn; 892 up->upda = (tn << 8) | sn; 893 ubaddr = (int)ptob(reg) + o; 894 up->upba = ubaddr; 895 cmd = (ubaddr >> 8) & 0x300; 896 cmd |= ((bp->b_flags&B_READ)?UP_RCOM:UP_WCOM)|UP_IE|UP_GO; 897 um->um_tab.b_errcnt = 0; 898 up->upcs1 = cmd; 899 #endif 900 return (1); 901 } 902 903 /* 904 * Reset driver after UBA init. 905 * Cancel software state of all pending transfers 906 * and restart all units and the controller. 907 */ 908 upreset(uban) 909 int uban; 910 { 911 register struct uba_ctlr *um; 912 register struct uba_device *ui; 913 register sc21, unit; 914 915 for (sc21 = 0; sc21 < NSC; sc21++) { 916 if ((um = upminfo[sc21]) == 0 || um->um_ubanum != uban || 917 um->um_alive == 0) 918 continue; 919 printf(" sc%d", sc21); 920 um->um_tab.b_active = 0; 921 um->um_tab.b_actf = um->um_tab.b_actl = 0; 922 up_softc[sc21].sc_recal = 0; 923 up_softc[sc21].sc_wticks = 0; 924 if (um->um_ubinfo) { 925 printf("<%d>", (um->um_ubinfo>>28)&0xf); 926 um->um_ubinfo = 0; 927 } 928 ((struct updevice *)(um->um_addr))->upcs2 = UPCS2_CLR; 929 for (unit = 0; unit < NUP; unit++) { 930 if ((ui = updinfo[unit]) == 0) 931 continue; 932 if (ui->ui_alive == 0 || ui->ui_mi != um) 933 continue; 934 uputab[unit].b_active = 0; 935 (void) upustart(ui); 936 } 937 (void) upstart(um); 938 } 939 } 940 941 /* 942 * Wake up every second and if an interrupt is pending 943 * but nothing has happened increment a counter. 944 * If nothing happens for 20 seconds, reset the UNIBUS 945 * and begin anew. 946 */ 947 upwatch() 948 { 949 register struct uba_ctlr *um; 950 register sc21, unit; 951 register struct up_softc *sc; 952 953 timeout(upwatch, (caddr_t)0, hz); 954 for (sc21 = 0; sc21 < NSC; sc21++) { 955 um = upminfo[sc21]; 956 if (um == 0 || um->um_alive == 0) 957 continue; 958 sc = &up_softc[sc21]; 959 if (um->um_tab.b_active == 0) { 960 for (unit = 0; unit < NUP; unit++) 961 if (uputab[unit].b_active && 962 updinfo[unit]->ui_mi == um) 963 goto active; 964 sc->sc_wticks = 0; 965 continue; 966 } 967 active: 968 sc->sc_wticks++; 969 if (sc->sc_wticks >= 20) { 970 sc->sc_wticks = 0; 971 printf("sc%d: lost interrupt\n", sc21); 972 ubareset(um->um_ubanum); 973 } 974 } 975 } 976 977 #define DBSIZE 20 978 979 updump(dev) 980 dev_t dev; 981 { 982 struct updevice *upaddr; 983 char *start; 984 int num, blk, unit; 985 struct size *sizes; 986 register struct uba_regs *uba; 987 register struct uba_device *ui; 988 register short *rp; 989 struct upst *st; 990 register int retry; 991 992 unit = upunit(dev); 993 if (unit >= NUP) 994 return (ENXIO); 995 #define phys(cast, addr) ((cast)((int)addr & 0x7fffffff)) 996 ui = phys(struct uba_device *, updinfo[unit]); 997 if (ui->ui_alive == 0) 998 return (ENXIO); 999 uba = phys(struct uba_hd *, ui->ui_hd)->uh_physuba; 1000 ubainit(uba); 1001 upaddr = (struct updevice *)ui->ui_physaddr; 1002 DELAY(5000000); 1003 num = maxfree; 1004 upaddr->upcs2 = unit; 1005 DELAY(100); 1006 upaddr->upcs1 = UP_DCLR|UP_GO; 1007 upaddr->upcs1 = UP_PRESET|UP_GO; 1008 upaddr->upof = UPOF_FMT22; 1009 retry = 0; 1010 do { 1011 DELAY(25); 1012 if (++retry > 527) 1013 break; 1014 } while ((upaddr->upds & UP_RDY) == 0); 1015 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) 1016 return (EFAULT); 1017 start = 0; 1018 st = &upst[ui->ui_type]; 1019 sizes = phys(struct size *, st->sizes); 1020 if (dumplo < 0) 1021 return (EINVAL); 1022 if (dumplo + num >= sizes[minor(dev)&07].nblocks) 1023 num = sizes[minor(dev)&07].nblocks - dumplo; 1024 while (num > 0) { 1025 register struct pte *io; 1026 register int i; 1027 int cn, sn, tn; 1028 daddr_t bn; 1029 1030 blk = num > DBSIZE ? DBSIZE : num; 1031 io = uba->uba_map; 1032 for (i = 0; i < blk; i++) 1033 *(int *)io++ = (btop(start)+i) | (1<<21) | UBAMR_MRV; 1034 *(int *)io = 0; 1035 bn = dumplo + btop(start); 1036 cn = bn/st->nspc + sizes[minor(dev)&07].cyloff; 1037 sn = bn%st->nspc; 1038 tn = sn/st->nsect; 1039 sn = sn%st->nsect; 1040 upaddr->updc = cn; 1041 rp = (short *) &upaddr->upda; 1042 *rp = (tn << 8) + sn; 1043 *--rp = 0; 1044 *--rp = -blk*NBPG / sizeof (short); 1045 *--rp = UP_GO|UP_WCOM; 1046 retry = 0; 1047 do { 1048 DELAY(25); 1049 if (++retry > 527) 1050 break; 1051 } while ((upaddr->upcs1 & UP_RDY) == 0); 1052 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1053 printf("up%d: not ready", unit); 1054 if ((upaddr->upds & UPDS_DREADY) != UPDS_DREADY) { 1055 printf("\n"); 1056 return (EIO); 1057 } 1058 printf(" (flakey)\n"); 1059 } 1060 if (upaddr->upds&UPDS_ERR) 1061 return (EIO); 1062 start += blk*NBPG; 1063 num -= blk; 1064 } 1065 return (0); 1066 } 1067 1068 upsize(dev) 1069 dev_t dev; 1070 { 1071 int unit = upunit(dev); 1072 struct uba_device *ui; 1073 struct upst *st; 1074 1075 if (unit >= NUP || (ui = updinfo[unit]) == 0 || ui->ui_alive == 0) 1076 return (-1); 1077 st = &upst[ui->ui_type]; 1078 return (st->sizes[minor(dev) & 07].nblocks); 1079 } 1080 #endif 1081