1 /* up.c 3.20 07/29/80 */ 2 3 /* 4 * Emulex UNIBUS disk driver with overlapped seeks and ECC recovery. 5 * 6 * NB: This driver works reliably only on an SC-11B controller with 7 * rev. level at least J (in particular rev. level H will not work well). 8 * If you have an newer controller you should change olducode below to: 9 * int olducode = 0; 10 * which saves time by stalling less in the system. 11 * 12 * Controller switch settings: 13 * SW1-1 5/19 surfaces (off, 19 surfaces on Ampex 9300) 14 * SW1-2 chksum enable (off, checksum disabled) 15 * SW1-3 volume select (off, 815 cylinders) 16 * SW1-4 sector select (on, 32 sectors) 17 * SW1-5 unused (off) 18 * SW1-6 port select (on, single port) 19 * SW1-7 npr delay (off, disable) 20 * SW1-8 ecc test mode (off, disable) 21 * and top mounted switches: 22 * SW2-1 extend opcodes (off=open, disable) 23 * SW2-2 extend diag (off=open, disable) 24 * SW2-3 4 wd dma burst (on=closed, enable) 25 * SW2-4 unused (off=open) 26 */ 27 28 #include "../h/param.h" 29 #include "../h/systm.h" 30 #include "../h/dk.h" 31 #include "../h/buf.h" 32 #include "../h/conf.h" 33 #include "../h/dir.h" 34 #include "../h/user.h" 35 #include "../h/map.h" 36 #include "../h/pte.h" 37 #include "../h/mba.h" 38 #include "../h/mtpr.h" 39 #include "../h/uba.h" 40 #include "../h/vm.h" 41 42 /* 43 * Define number of drives, and range of sampling information to be used. 44 * 45 * Normally, DK_N .. DK_N+NUP-1 gather individual drive stats, 46 * and DK_N+NUP gathers controller transferring stats. 47 * 48 * If DK_N+NUP > DK_NMAX, then transfer stats are divided per drive. 49 * If DK_NMAX is yet smaller, some drives are not monitored. 50 */ 51 #define DK_N 2 52 #define DK_NMAX 3 53 54 #define ushort unsigned short 55 56 struct device 57 { 58 ushort upcs1; /* control and status register 1 */ 59 short upwc; /* word count register */ 60 ushort upba; /* UNIBUS address register */ 61 ushort upda; /* desired address register */ 62 ushort upcs2; /* control and status register 2 */ 63 ushort upds; /* drive Status */ 64 ushort uper1; /* error register 1 */ 65 ushort upas; /* attention summary */ 66 ushort upla; /* look ahead */ 67 ushort updb; /* data buffer */ 68 ushort upmr; /* maintenance */ 69 ushort updt; /* drive type */ 70 ushort upsn; /* serial number */ 71 ushort upof; /* offset register */ 72 ushort updc; /* desired cylinder address register */ 73 ushort upcc; /* current cylinder */ 74 ushort uper2; /* error register 2 */ 75 ushort uper3; /* error register 3 */ 76 ushort upec1; /* burst error bit position */ 77 ushort upec2; /* burst error bit pattern */ 78 }; 79 80 /* 81 * Software extension to the upas register, so we can 82 * postpone starting SEARCH commands until the controller 83 * is not transferring. 84 */ 85 int upsoftas; 86 87 /* 88 * If upseek then we don't issue SEARCH commands but rather just 89 * settle for a SEEK to the correct cylinder. 90 */ 91 int upseek; 92 93 #define UPADDR ((struct device *)(UBA0_DEV + 0176700)) 94 95 #define NUP 2 /* Number of drives this installation */ 96 97 #define NSECT 32 98 #define NTRAC 19 99 100 /* 101 * Constants controlling on-cylinder SEARCH usage. 102 * 103 * upSDIST/2 msec time needed to start transfer 104 * upRDIST/2 msec tolerable rotational latency when on-cylinder 105 * 106 * If we are no closer than upSDIST sectors and no further than upSDIST+upRDIST 107 * and in the driver then we take it as it is. Otherwise we do a SEARCH 108 * requesting an interrupt upSDIST sectors in advance. 109 */ 110 #define _upSDIST 6 /* 3.0 msec */ 111 #define _upRDIST 6 /* 3.0 msec */ 112 113 int upSDIST = _upSDIST; 114 int upRDIST = _upRDIST; 115 116 /* 117 * To fill a 300M drive: 118 * A is designed to be used as a root. 119 * B is suitable for a swap area. 120 * H is the primary storage area. 121 * On systems with RP06'es, we normally use only 291346 blocks of the H 122 * area, and use DEF or G to cover the rest of the drive. The C system 123 * covers the whole drive and can be used for pack-pack copying. 124 */ 125 struct size 126 { 127 daddr_t nblocks; 128 int cyloff; 129 } up_sizes[8] = { 130 15884, 0, /* A=cyl 0 thru 26 */ 131 33440, 27, /* B=cyl 27 thru 81 */ 132 495520, 0, /* C=cyl 0 thru 814 */ 133 15884, 562, /* D=cyl 562 thru 588 */ 134 55936, 589, /* E=cyl 589 thru 680 */ 135 81472, 681, /* F=cyl 681 thru 814 */ 136 153824, 562, /* G=cyl 562 thru 814 */ 137 445664, 82, /* H=cyl 82 thru 814 */ 138 /* Later, and more safely for H area... 139 291346, 82, /* H=cyl 82 thru 561 */ 140 }; 141 142 /* 143 * The following defines are used in offset positioning 144 * when trying to recover disk errors, with the constants being 145 * +/- microinches. Note that header compare inhibit (HCI) is not 146 * tried (this makes sense only during read, in any case.) 147 * 148 * NOT ALL OF THESE ARE IMPLEMENTED ON 9300!?! 149 */ 150 #define P400 020 151 #define M400 0220 152 #define P800 040 153 #define M800 0240 154 #define P1200 060 155 #define M1200 0260 156 #define HCI 020000 157 158 int up_offset[16] = 159 { 160 P400, M400, P400, M400, 161 P800, M800, P800, M800, 162 P1200, M1200, P1200, M1200, 163 0, 0, 0, 0, 164 }; 165 166 /* 167 * Each drive has a table uputab[i]. On this table are sorted the 168 * pending requests implementing an elevator algorithm (see dsort.c.) 169 * In the upustart() routine, each drive is independently advanced 170 * until it is on the desired cylinder for the next transfer and near 171 * the desired sector. The drive is then chained onto the uptab 172 * table, and the transfer is initiated by the upstart() routine. 173 * When the transfer is completed the driver reinvokes the upustart() 174 * routine to set up the next transfer. 175 */ 176 struct buf uptab; 177 struct buf uputab[NUP]; 178 179 struct buf rupbuf; /* Buffer for raw i/o */ 180 181 /* Drive commands, placed in upcs1 */ 182 #define GO 01 /* Go bit, set in all commands */ 183 #define PRESET 020 /* Preset drive at init or after errors */ 184 #define OFFSET 014 /* Offset heads to try to recover error */ 185 #define RTC 016 /* Return to center-line after OFFSET */ 186 #define SEARCH 030 /* Search for cylinder+sector */ 187 #define SEEK 04 /* Seek to cylinder */ 188 #define RECAL 06 /* Recalibrate, needed after seek error */ 189 #define DCLR 010 /* Drive clear, after error */ 190 #define WCOM 060 /* Write */ 191 #define RCOM 070 /* Read */ 192 193 /* Other bits of upcs1 */ 194 #define IE 0100 /* Controller wide interrupt enable */ 195 #define TRE 040000 /* Transfer error */ 196 #define RDY 0200 /* Transfer terminated */ 197 198 /* Drive status bits of upds */ 199 #define PIP 020000 /* Positioning in progress */ 200 #define ERR 040000 /* Error has occurred, DCLR necessary */ 201 #define VV 0100 /* Volume is valid, set by PRESET */ 202 #define DPR 0400 /* Drive has been preset */ 203 #define MOL 010000 /* Drive is online, heads loaded, etc */ 204 #define DRY 0200 /* Drive ready */ 205 206 /* Bits of upcs2 */ 207 #define CLR 040 /* Controller clear */ 208 /* Bits of uper1 */ 209 #define DCK 0100000 /* Ecc error occurred */ 210 #define ECH 0100 /* Ecc error was unrecoverable */ 211 #define WLE 04000 /* Attempt to write read-only drive */ 212 213 /* Bits of upof; the offset bits above are also in this register */ 214 #define FMT22 010000 /* 16 bits/word, must be always set */ 215 216 #define b_cylin b_resid 217 218 int up_ubinfo; /* Information about UBA usage saved here */ 219 /* 220 * The EMULEX controller balks if accessed quickly after 221 * certain operations. With rev J delays seem to be needed only 222 * when selecting a new unit, and in drive initialization type 223 * like PRESET and DCLR. The following variables control the delay 224 * DELAY(n) is approximately n usec. 225 */ 226 int olducode = 1; 227 int idelay = 500; /* Delay after PRESET or DCLR */ 228 int osdelay = 150; /* Old delay after selecting drive in upcs2 */ 229 int ordelay = 100; /* Old delay after SEARCH */ 230 int oasdel = 100; /* Old delay after clearing bit in upas */ 231 int nsdelay = 25; 232 233 #define DELAY(N) { register int d; d = N; while (--d > 0); } 234 235 int nwaitcs2; /* How many sdelay loops ? */ 236 int neasycs2; /* How many sdelay loops not needed ? */ 237 238 int up_wticks; /* Ticks waiting for interrupt */ 239 int upwstart; /* Have started guardian */ 240 int upwatch(); 241 242 #ifdef INTRLVE 243 daddr_t dkblock(); 244 #endif 245 246 /* 247 * Queue an i/o request for a drive, checking first that it is in range. 248 * 249 * A unit start is issued if the drive is inactive, causing 250 * a SEARCH for the correct cylinder/sector. If the drive is 251 * already nearly on the money and the controller is not transferring 252 * we kick it to start the transfer. 253 */ 254 upstrategy(bp) 255 register struct buf *bp; 256 { 257 register struct buf *dp; 258 register unit, xunit; 259 long sz, bn; 260 261 if (upwstart == 0) { 262 timeout((caddr_t)upwatch, 0, HZ); 263 upwstart++; 264 } 265 xunit = minor(bp->b_dev) & 077; 266 sz = bp->b_bcount; 267 sz = (sz+511) >> 9; /* transfer size in 512 byte sectors */ 268 unit = dkunit(bp); 269 if (unit >= NUP || 270 bp->b_blkno < 0 || 271 (bn = dkblock(bp))+sz > up_sizes[xunit&07].nblocks) { 272 bp->b_flags |= B_ERROR; 273 iodone(bp); 274 return; 275 } 276 bp->b_cylin = bn/(NSECT*NTRAC) + up_sizes[xunit&07].cyloff; 277 dp = &uputab[unit]; 278 (void) spl5(); 279 disksort(dp, bp); 280 if (dp->b_active == 0) { 281 (void) upustart(unit); 282 if (uptab.b_actf && uptab.b_active == 0) 283 (void) upstart(); 284 } 285 (void) spl0(); 286 } 287 288 /* 289 * Start activity on specified drive; called when drive is inactive 290 * and new transfer request arrives and also when upas indicates that 291 * a SEARCH command is complete. 292 */ 293 upustart(unit) 294 register unit; 295 { 296 register struct buf *bp, *dp; 297 register struct device *upaddr = UPADDR; 298 daddr_t bn; 299 int sn, cn, csn; 300 int didie = 0; 301 302 /* 303 * Other drivers tend to say something like 304 * upaddr->upcs1 = IE; 305 * upaddr->upas = 1<<unit; 306 * here, but the SC-11B will cancel a command which 307 * happens to be sitting in the cs1 if you clear the go 308 * bit by storing there (so the first is not safe), 309 * and it also does not like being bothered with operations 310 * such as clearing upas when a transfer is active (as 311 * it may well be.) 312 * 313 * Thus we keep careful track of when we re-enable IE 314 * after an interrupt and do it only if we didn't issue 315 * a command which re-enabled it as a matter of course. 316 * We clear bits in upas in the interrupt routine, when 317 * no transfers are active. 318 */ 319 if (unit >= NUP) 320 goto out; 321 if (unit+DK_N <= DK_NMAX) 322 dk_busy &= ~(1<<(unit+DK_N)); 323 dp = &uputab[unit]; 324 if ((bp = dp->b_actf) == NULL) 325 goto out; 326 /* 327 * The SC-11B doesn't start SEARCH commands when transfers are 328 * in progress. In fact, it tends to get confused when given 329 * SEARCH'es during transfers, generating interrupts with neither 330 * RDY nor a bit in the upas register. Thus we defer 331 * until an interrupt when a transfer is pending. 332 */ 333 if (uptab.b_active) { 334 upsoftas |= 1<<unit; 335 return (0); 336 } 337 if (dp->b_active) 338 goto done; 339 dp->b_active = 1; 340 if ((upaddr->upcs2 & 07) != unit) { 341 upaddr->upcs2 = unit; 342 DELAY(olducode ? osdelay : nsdelay); 343 nwaitcs2++; 344 } else 345 neasycs2++; 346 /* 347 * If we have changed packs or just initialized, 348 * then the volume will not be valid; if so, clear 349 * the drive, preset it and put in 16bit/word mode. 350 */ 351 if ((upaddr->upds & VV) == 0) { 352 upaddr->upcs1 = IE|DCLR|GO; 353 DELAY(idelay); 354 upaddr->upcs1 = IE|PRESET|GO; 355 DELAY(idelay); 356 upaddr->upof = FMT22; 357 didie = 1; 358 } 359 if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) 360 goto done; 361 /* 362 * Do enough of the disk address decoding to determine 363 * which cylinder and sector the request is on. 364 * If we are on the correct cylinder and the desired sector 365 * lies between upSDIST and upSDIST+upRDIST sectors ahead of us, then 366 * we don't bother to SEARCH but just begin the transfer asap. 367 * Otherwise ask for a interrupt upSDIST sectors ahead. 368 */ 369 bn = dkblock(bp); 370 cn = bp->b_cylin; 371 sn = bn%(NSECT*NTRAC); 372 sn = (sn+NSECT-upSDIST)%NSECT; 373 374 if (cn - upaddr->updc) 375 goto search; /* Not on-cylinder */ 376 else if (upseek) 377 goto done; /* Ok just to be on-cylinder */ 378 csn = (upaddr->upla>>6) - sn - 1; 379 if (csn < 0) 380 csn += NSECT; 381 if (csn > NSECT-upRDIST) 382 goto done; 383 384 search: 385 upaddr->updc = cn; 386 if (upseek) 387 upaddr->upcs1 = IE|SEEK|GO; 388 else { 389 upaddr->upda = sn; 390 upaddr->upcs1 = IE|SEARCH|GO; 391 } 392 didie = 1; 393 /* 394 * Mark this unit busy. 395 */ 396 unit += DK_N; 397 if (unit <= DK_NMAX && DK_N+NUP <= DK_NMAX) { 398 dk_busy |= 1<<unit; 399 dk_numb[unit]++; 400 } 401 if (olducode) 402 DELAY(ordelay); 403 goto out; 404 405 done: 406 /* 407 * This unit is ready to go so 408 * link it onto the chain of ready disks. 409 */ 410 dp->b_forw = NULL; 411 if (uptab.b_actf == NULL) 412 uptab.b_actf = dp; 413 else 414 uptab.b_actl->b_forw = dp; 415 uptab.b_actl = dp; 416 417 out: 418 return (didie); 419 } 420 421 /* 422 * Start a transfer; call from top level at spl5() or on interrupt. 423 */ 424 upstart() 425 { 426 register struct buf *bp, *dp; 427 register unit; 428 register struct device *upaddr; 429 daddr_t bn; 430 int dn, sn, tn, cn, cmd; 431 432 loop: 433 /* 434 * Pick a drive off the queue of ready drives, and 435 * perform the first transfer on its queue. 436 * 437 * Looping here is completely for the sake of drives which 438 * are not present and on-line, for which we completely clear the 439 * request queue. 440 */ 441 if ((dp = uptab.b_actf) == NULL) 442 return (0); 443 if ((bp = dp->b_actf) == NULL) { 444 uptab.b_actf = dp->b_forw; 445 goto loop; 446 } 447 /* 448 * Mark the controller busy, and multi-part disk address. 449 * Select the unit on which the i/o is to take place. 450 */ 451 uptab.b_active++; 452 unit = minor(bp->b_dev) & 077; 453 dn = dkunit(bp); 454 bn = dkblock(bp); 455 cn = up_sizes[unit&07].cyloff; 456 cn += bn/(NSECT*NTRAC); 457 sn = bn%(NSECT*NTRAC); 458 tn = sn/NSECT; 459 sn %= NSECT; 460 upaddr = UPADDR; 461 if ((upaddr->upcs2 & 07) != dn) { 462 upaddr->upcs2 = dn; 463 /* DELAY(sdelay); Provided by ubasetup() */ 464 nwaitcs2++; 465 } else 466 neasycs2++; 467 up_ubinfo = ubasetup(bp, 1); /* Providing delay */ 468 /* 469 * If drive is not present and on-line, then 470 * get rid of this with an error and loop to get 471 * rid of the rest of its queued requests. 472 * (Then on to any other ready drives.) 473 */ 474 if ((upaddr->upds & (DPR|MOL)) != (DPR|MOL)) { 475 printf("!DPR || !MOL, unit %d, ds %o\n", dn, upaddr->upds); 476 uptab.b_active = 0; 477 uptab.b_errcnt = 0; 478 dp->b_actf = bp->av_forw; 479 dp->b_active = 0; 480 bp->b_flags |= B_ERROR; 481 iodone(bp); 482 ubafree(up_ubinfo), up_ubinfo = 0; /* A funny place ... */ 483 goto loop; 484 } 485 /* 486 * If this is a retry, then with the 16'th retry we 487 * begin to try offsetting the heads to recover the data. 488 */ 489 if (uptab.b_errcnt >= 16) { 490 upaddr->upof = up_offset[uptab.b_errcnt & 017] | FMT22; 491 upaddr->upcs1 = IE|OFFSET|GO; 492 DELAY(idelay); 493 while (upaddr->upds & PIP) 494 DELAY(25); 495 } 496 /* 497 * Now set up the transfer, retrieving the high 498 * 2 bits of the UNIBUS address from the information 499 * returned by ubasetup() for the cs1 register bits 8 and 9. 500 */ 501 upaddr->updc = cn; 502 upaddr->upda = (tn << 8) + sn; 503 upaddr->upba = up_ubinfo; 504 upaddr->upwc = -bp->b_bcount / sizeof (short); 505 cmd = (up_ubinfo >> 8) & 0x300; 506 if (bp->b_flags & B_READ) 507 cmd |= IE|RCOM|GO; 508 else 509 cmd |= IE|WCOM|GO; 510 upaddr->upcs1 = cmd; 511 /* 512 * This is a controller busy situation. 513 * Record in dk slot NUP+DK_N (after last drive) 514 * unless there aren't that many slots reserved for 515 * us in which case we record this as a drive busy 516 * (if there is room for that). 517 */ 518 unit = dn+DK_N; 519 if (NUP+DK_N == DK_NMAX) 520 unit = NUP+DK_N; 521 if (unit <= DK_NMAX) { 522 dk_busy |= 1<<unit; 523 dk_numb[unit]++; 524 dk_wds[unit] += bp->b_bcount>>6; 525 } 526 return (1); 527 } 528 529 /* 530 * Handle a device interrupt. 531 * 532 * If the transferring drive needs attention, service it 533 * retrying on error or beginning next transfer. 534 * Service all other ready drives, calling ustart to transfer 535 * their blocks to the ready queue in uptab, and then restart 536 * the controller if there is anything to do. 537 */ 538 upintr() 539 { 540 register struct buf *bp, *dp; 541 register unit; 542 register struct device *upaddr = UPADDR; 543 int as = upaddr->upas & 0377; 544 int oupsoftas; 545 int needie = 1; 546 547 (void) spl6(); 548 up_wticks = 0; 549 if (uptab.b_active) { 550 /* 551 * The drive is transferring, thus the hardware 552 * (say the designers) will only interrupt when the transfer 553 * completes; check for it anyways. 554 */ 555 if ((upaddr->upcs1 & RDY) == 0) { 556 printf("!RDY: cs1 %o, ds %o, wc %d\n", upaddr->upcs1, 557 upaddr->upds, upaddr->upwc); 558 printf("as=%d act %d %d %d\n", as, uptab.b_active, 559 uputab[0].b_active, uputab[1].b_active); 560 } 561 /* 562 * Mark controller or drive not busy, and check for an 563 * error condition which may have resulted from the transfer. 564 */ 565 dp = uptab.b_actf; 566 bp = dp->b_actf; 567 unit = dkunit(bp); 568 if (DK_N+NUP == DK_NMAX) 569 dk_busy &= ~(1<<(DK_N+NUP)); 570 else if (DK_N+unit <= DK_NMAX) 571 dk_busy &= ~(1<<(DK_N+unit)); 572 if ((upaddr->upcs2 & 07) != unit) { 573 upaddr->upcs2 = unit; 574 DELAY(olducode ? osdelay : nsdelay); 575 nwaitcs2++; 576 } else 577 neasycs2++; 578 if (upaddr->upds & ERR) { 579 /* 580 * An error occurred, indeed. Select this unit 581 * to get at the drive status (a SEARCH may have 582 * intervened to change the selected unit), and 583 * wait for the command which caused the interrupt 584 * to complete (DRY). 585 */ 586 while ((upaddr->upds & DRY) == 0) 587 DELAY(25); 588 /* 589 * After 28 retries (16 w/o servo offsets, and then 590 * 12 with servo offsets), or if we encountered 591 * an error because the drive is write-protected, 592 * give up. Print an error message on the last 2 593 * retries before a hard failure. 594 */ 595 if (++uptab.b_errcnt > 28 || upaddr->uper1&WLE) 596 bp->b_flags |= B_ERROR; 597 else 598 uptab.b_active = 0; /* To force retry */ 599 if (uptab.b_errcnt > 27) 600 deverror(bp, upaddr->upcs2, upaddr->uper1); 601 /* 602 * If this was a correctible ECC error, let upecc 603 * do the dirty work to correct it. If upecc 604 * starts another READ for the rest of the data 605 * then it returns 1 (having set uptab.b_active). 606 * Otherwise we are done and fall through to 607 * finish up. 608 */ 609 if ((upaddr->uper1&(DCK|ECH))==DCK && upecc(upaddr, bp)) 610 return; 611 /* 612 * Clear the drive and, every 4 retries, recalibrate 613 * to hopefully help clear up seek positioning problems. 614 */ 615 upaddr->upcs1 = TRE|IE|DCLR|GO; 616 DELAY(idelay); 617 needie = 0; 618 if ((uptab.b_errcnt&07) == 4) { 619 upaddr->upcs1 = RECAL|GO|IE; 620 DELAY(idelay); 621 while(upaddr->upds & PIP) 622 DELAY(25); 623 } 624 } 625 /* 626 * If we are still noted as active, then no 627 * (further) retries are necessary. 628 * 629 * Make sure the correct unit is selected, 630 * return it to centerline if necessary, and mark 631 * this i/o complete, starting the next transfer 632 * on this drive with the upustart routine (if any). 633 */ 634 if (uptab.b_active) { 635 if (uptab.b_errcnt >= 16) { 636 upaddr->upcs1 = RTC|GO|IE; 637 DELAY(idelay); 638 while (upaddr->upds & PIP) 639 DELAY(25); 640 needie = 0; 641 } 642 uptab.b_active = 0; 643 uptab.b_errcnt = 0; 644 uptab.b_actf = dp->b_forw; 645 dp->b_active = 0; 646 dp->b_errcnt = 0; 647 dp->b_actf = bp->av_forw; 648 bp->b_resid = (-upaddr->upwc * sizeof(short)); 649 if (bp->b_resid) 650 printf("resid %d ds %o er? %o %o %o\n", 651 bp->b_resid, upaddr->upds, 652 upaddr->uper1, upaddr->uper2, upaddr->uper3); 653 iodone(bp); 654 if(dp->b_actf) 655 if (upustart(unit)) 656 needie = 0; 657 } 658 as &= ~(1<<unit); 659 upsoftas &= ~(1<<unit); 660 ubafree(up_ubinfo), up_ubinfo = 0; 661 } else { 662 if (upaddr->upcs1 & TRE) { 663 upaddr->upcs1 = TRE; 664 DELAY(idelay); 665 } 666 } 667 /* 668 * If we have a unit with an outstanding SEARCH, 669 * and the hardware indicates the unit requires attention, 670 * the bring the drive to the ready queue. 671 * Finally, if the controller is not transferring 672 * start it if any drives are now ready to transfer. 673 */ 674 as |= upsoftas; 675 oupsoftas = upsoftas; 676 upsoftas = 0; 677 for (unit = 0; unit < NUP; unit++) 678 if ((as|oupsoftas) & (1<<unit)) { 679 if (as & (1<<unit)) { 680 upaddr->upas = 1<<unit; 681 if (olducode) 682 DELAY(oasdel); 683 } 684 if (upustart(unit)) 685 needie = 0; 686 } 687 if (uptab.b_actf && uptab.b_active == 0) 688 if (upstart()) 689 needie = 0; 690 out: 691 if (needie) 692 upaddr->upcs1 = IE; 693 } 694 695 upread(dev) 696 { 697 698 physio(upstrategy, &rupbuf, dev, B_READ, minphys); 699 } 700 701 upwrite(dev) 702 { 703 704 physio(upstrategy, &rupbuf, dev, B_WRITE, minphys); 705 } 706 707 /* 708 * Correct an ECC error, and restart the i/o to complete 709 * the transfer if necessary. This is quite complicated because 710 * the transfer may be going to an odd memory address base and/or 711 * across a page boundary. 712 */ 713 upecc(up, bp) 714 register struct device *up; 715 register struct buf *bp; 716 { 717 struct uba_regs *ubp = (struct uba_regs *)UBA0; 718 register int i; 719 caddr_t addr; 720 int reg, bit, byte, npf, mask, o, cmd, ubaddr; 721 int bn, cn, tn, sn; 722 723 /* 724 * Npf is the number of sectors transferred before the sector 725 * containing the ECC error, and reg is the UBA register 726 * mapping (the first part of) the transfer. 727 * O is offset within a memory page of the first byte transferred. 728 */ 729 npf = btop((up->upwc * sizeof(short)) + bp->b_bcount) - 1; 730 reg = btop(up_ubinfo&0x3ffff) + npf; 731 o = (int)bp->b_un.b_addr & PGOFSET; 732 printf("%D ", bp->b_blkno+npf); 733 prdev("ECC", bp->b_dev); 734 mask = up->upec2; 735 if (mask == 0) { 736 up->upof = FMT22; /* == RTC ???? */ 737 DELAY(idelay); 738 return (0); 739 } 740 /* 741 * Flush the buffered data path, and compute the 742 * byte and bit position of the error. The variable i 743 * is the byte offset in the transfer, the variable byte 744 * is the offset from a page boundary in main memory. 745 */ 746 ubp->uba_dpr[(up_ubinfo>>28)&0x0f] |= BNE; 747 i = up->upec1 - 1; /* -1 makes 0 origin */ 748 bit = i&07; 749 i = (i&~07)>>3; 750 byte = i + o; 751 /* 752 * Correct while possible bits remain of mask. Since mask 753 * contains 11 bits, we continue while the bit offset is > -11. 754 * Also watch out for end of this block and the end of the whole 755 * transfer. 756 */ 757 while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 758 addr = ptob(ubp->uba_map[reg+btop(byte)].pg_pfnum)+ 759 (byte & PGOFSET); 760 putmemc(addr, getmemc(addr)^(mask<<bit)); 761 byte++; 762 i++; 763 bit -= 8; 764 } 765 uptab.b_active++; /* Either complete or continuing... */ 766 if (up->upwc == 0) 767 return (0); 768 /* 769 * Have to continue the transfer... clear the drive, 770 * and compute the position where the transfer is to continue. 771 * We have completed npf+1 sectors of the transfer already; 772 * restart at offset o of next sector (i.e. in UBA register reg+1). 773 */ 774 up->upcs1 = TRE|IE|DCLR|GO; 775 DELAY(idelay); 776 bn = dkblock(bp); 777 cn = bp->b_cylin; 778 sn = bn%(NSECT*NTRAC) + npf + 1; 779 tn = sn/NSECT; 780 sn %= NSECT; 781 cn += tn/NTRAC; 782 tn %= NTRAC; 783 up->updc = cn; 784 up->upda = (tn << 8) | sn; 785 ubaddr = (int)ptob(reg+1) + o; 786 up->upba = ubaddr; 787 cmd = (ubaddr >> 8) & 0x300; 788 cmd |= IE|GO|RCOM; 789 up->upcs1 = cmd; 790 return (1); 791 } 792 793 /* 794 * Reset driver after UBA init. 795 * Cancel software state of all pending transfers 796 * and restart all units and the controller. 797 */ 798 upreset() 799 { 800 int unit; 801 802 printf(" up"); 803 uptab.b_active = 0; 804 uptab.b_actf = uptab.b_actl = 0; 805 if (DK_N+NUP == DK_NMAX) 806 dk_busy &= ~(1<<(DK_N+NUP)); 807 if (up_ubinfo) { 808 printf("<%d>", (up_ubinfo>>28)&0xf); 809 ubafree(up_ubinfo), up_ubinfo = 0; 810 } 811 UPADDR->upcs2 = CLR; /* clear controller */ 812 DELAY(idelay); 813 for (unit = 0; unit < NUP; unit++) { 814 uputab[unit].b_active = 0; 815 (void) upustart(unit); 816 } 817 (void) upstart(); 818 } 819 820 /* 821 * Wake up every second and if an interrupt is pending 822 * but nothing has happened increment a counter. 823 * If nothing happens for 20 seconds, reset the controller 824 * and begin anew. 825 */ 826 upwatch() 827 { 828 int i; 829 830 timeout((caddr_t)upwatch, 0, HZ); 831 if (uptab.b_active == 0) { 832 for (i = 0; i < NUP; i++) 833 if (uputab[i].b_active) 834 goto active; 835 up_wticks = 0; /* idling */ 836 return; 837 } 838 active: 839 up_wticks++; 840 if (up_wticks >= 20) { 841 up_wticks = 0; 842 printf("LOST INTERRUPT RESET"); 843 upreset(); 844 printf("\n"); 845 } 846 } 847