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