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