|
|
1.1 ! root 1: /* hp.c 4.41 81/07/09 */ ! 2: ! 3: #ifdef HPDEBUG ! 4: int hpdebug; ! 5: #endif ! 6: #ifdef HPBDEBUG ! 7: int hpbdebug; ! 8: #endif ! 9: ! 10: #include "hp.h" ! 11: #if NHP > 0 ! 12: /* ! 13: * HP disk driver for RP0x+RMxx ! 14: * ! 15: * TODO: ! 16: * check RM80 skip sector handling when ECC's occur later ! 17: * check offset recovery handling ! 18: * see if DCLR and/or RELEASE set attention status ! 19: * print bits of mr && mr2 symbolically ! 20: */ ! 21: ! 22: #include "../h/param.h" ! 23: #include "../h/systm.h" ! 24: #include "../h/dk.h" ! 25: #include "../h/buf.h" ! 26: #include "../h/conf.h" ! 27: #include "../h/dir.h" ! 28: #include "../h/user.h" ! 29: #include "../h/map.h" ! 30: #include "../h/pte.h" ! 31: #include "../h/mbareg.h" ! 32: #include "../h/mbavar.h" ! 33: #include "../h/mtpr.h" ! 34: #include "../h/vm.h" ! 35: #include "../h/cmap.h" ! 36: #include "../h/dkbad.h" ! 37: ! 38: #include "../h/hpreg.h" ! 39: ! 40: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */ ! 41: struct size { ! 42: daddr_t nblocks; ! 43: int cyloff; ! 44: } hp6_sizes[8] = { ! 45: 15884, 0, /* A=cyl 0 thru 37 */ ! 46: 33440, 38, /* B=cyl 38 thru 117 */ ! 47: 340670, 0, /* C=cyl 0 thru 814 */ ! 48: 0, 0, ! 49: 0, 0, ! 50: 0, 0, ! 51: #ifndef NOBADSECT ! 52: 291280, 118, /* G=cyl 118 thru 814 */ ! 53: #else ! 54: 291346, 118, ! 55: #endif ! 56: 0, 0, ! 57: }, rm3_sizes[8] = { ! 58: 15884, 0, /* A=cyl 0 thru 99 */ ! 59: 33440, 100, /* B=cyl 100 thru 309 */ ! 60: 131680, 0, /* C=cyl 0 thru 822 */ ! 61: 0, 0, ! 62: 0, 0, ! 63: 0, 0, ! 64: #ifndef NOBADSECT ! 65: 81984, 310, /* G=cyl 310 thru 822 */ ! 66: #else ! 67: 82080, 310, ! 68: #endif ! 69: 0, 0, ! 70: }, rm5_sizes[8] = { ! 71: 15884, 0, /* A=cyl 0 thru 26 */ ! 72: 33440, 27, /* B=cyl 27 thru 81 */ ! 73: 500384, 0, /* C=cyl 0 thru 822 */ ! 74: 15884, 562, /* D=cyl 562 thru 588 */ ! 75: 55936, 589, /* E=cyl 589 thru 680 */ ! 76: #ifndef NOBADSECT ! 77: 86240, 681, /* F=cyl 681 thru 822 */ ! 78: 158592, 562, /* G=cyl 562 thru 822 */ ! 79: #else ! 80: 86636, 681, ! 81: 158688, 562, ! 82: #endif ! 83: 291346, 82, /* H=cyl 82 thru 561 */ ! 84: }, rm80_sizes[8] = { ! 85: 15884, 0, /* A=cyl 0 thru 36 */ ! 86: 33440, 37, /* B=cyl 37 thru 114 */ ! 87: 242606, 0, /* C=cyl 0 thru 558 */ ! 88: 0, 0, ! 89: 0, 0, ! 90: 0, 0, ! 91: 82080, 115, /* G=cyl 115 thru 304 */ ! 92: 110143, 305, /* H=cyl 305 thru 558 */ ! 93: }, hp7_sizes[8] = { ! 94: 15844, 0, /* A=cyl 0 thru 9 */ ! 95: 64000, 10, /* B=cyl 10 thru 49 */ ! 96: 1008000,0, /* C=cyl 0 thru 629 */ ! 97: 15884, 330, /* D=cyl 330 thru 339 */ ! 98: 256000, 340, /* E=cyl 340 thru 499 */ ! 99: 207850, 500, /* F=cyl 500 thru 629 */ ! 100: 479850, 330, /* G=cyl 330 thru 629 */ ! 101: 448000, 50, /* H=cyl 50 thru 329 */ ! 102: }; ! 103: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */ ! 104: ! 105: #define _hpSDIST 2 ! 106: #define _hpRDIST 3 ! 107: ! 108: int hpSDIST = _hpSDIST; ! 109: int hpRDIST = _hpRDIST; ! 110: ! 111: short hptypes[] = ! 112: { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07, 0 }; ! 113: struct mba_device *hpinfo[NHP]; ! 114: int hpattach(),hpustart(),hpstart(),hpdtint(); ! 115: struct mba_driver hpdriver = ! 116: { hpattach, 0, hpustart, hpstart, hpdtint, 0, ! 117: hptypes, "hp", 0, hpinfo }; ! 118: ! 119: struct hpst { ! 120: short nsect; ! 121: short ntrak; ! 122: short nspc; ! 123: short ncyl; ! 124: struct size *sizes; ! 125: } hpst[] = { ! 126: 32, 5, 32*5, 823, rm3_sizes, /* RM03 */ ! 127: 32, 19, 32*19, 823, rm5_sizes, /* RM05 */ ! 128: 22, 19, 22*19, 815, hp6_sizes, /* RP06 */ ! 129: 31, 14, 31*14, 559, rm80_sizes, /* RM80 */ ! 130: 22, 19, 22*19, 411, hp6_sizes, /* RP05 */ ! 131: 50, 32, 50*32, 630, hp7_sizes, /* RP07 */ ! 132: }; ! 133: ! 134: u_char hp_offset[16] = { ! 135: HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400, ! 136: HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800, ! 137: HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200, ! 138: 0, 0, 0, 0, ! 139: }; ! 140: ! 141: struct buf rhpbuf[NHP]; ! 142: #ifndef NOBADSECT ! 143: struct buf bhpbuf[NHP]; ! 144: struct dkbad hpbad[NHP]; ! 145: #endif ! 146: char hpinit[NHP]; ! 147: char hprecal[NHP]; ! 148: ! 149: #define b_cylin b_resid ! 150: ! 151: #ifdef INTRLVE ! 152: daddr_t dkblock(); ! 153: #endif ! 154: ! 155: int hpseek; ! 156: ! 157: /*ARGSUSED*/ ! 158: hpattach(mi, slave) ! 159: struct mba_device *mi; ! 160: { ! 161: register struct hpst *st = &hpst[mi->mi_type]; ! 162: ! 163: if (mi->mi_dk >= 0) ! 164: dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256); ! 165: } ! 166: ! 167: hpstrategy(bp) ! 168: register struct buf *bp; ! 169: { ! 170: register struct mba_device *mi; ! 171: register struct hpst *st; ! 172: register int unit; ! 173: long sz, bn; ! 174: int xunit = minor(bp->b_dev) & 07; ! 175: ! 176: sz = bp->b_bcount; ! 177: sz = (sz+511) >> 9; ! 178: unit = dkunit(bp); ! 179: if (unit >= NHP) ! 180: goto bad; ! 181: mi = hpinfo[unit]; ! 182: if (mi == 0 || mi->mi_alive == 0) ! 183: goto bad; ! 184: st = &hpst[mi->mi_type]; ! 185: if (bp->b_blkno < 0 || ! 186: (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks) ! 187: goto bad; ! 188: bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff; ! 189: (void) spl5(); ! 190: disksort(&mi->mi_tab, bp); ! 191: if (mi->mi_tab.b_active == 0) ! 192: mbustart(mi); ! 193: (void) spl0(); ! 194: return; ! 195: ! 196: bad: ! 197: bp->b_flags |= B_ERROR; ! 198: iodone(bp); ! 199: return; ! 200: } ! 201: ! 202: hpustart(mi) ! 203: register struct mba_device *mi; ! 204: { ! 205: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv; ! 206: register struct buf *bp = mi->mi_tab.b_actf; ! 207: register struct hpst *st = &hpst[mi->mi_type]; ! 208: daddr_t bn; ! 209: int sn, dist; ! 210: ! 211: hpaddr->hpcs1 = 0; ! 212: if ((hpaddr->hpcs1&HP_DVA) == 0) ! 213: return (MBU_BUSY); ! 214: if ((hpaddr->hpds & HPDS_VV) == 0 || hpinit[mi->mi_unit] == 0) { ! 215: #ifndef NOBADSECT ! 216: struct buf *bbp = &bhpbuf[mi->mi_unit]; ! 217: #endif ! 218: ! 219: hpinit[mi->mi_unit] = 1; ! 220: hpaddr->hpcs1 = HP_DCLR|HP_GO; ! 221: if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive)) ! 222: printf("DCLR attn\n"); ! 223: hpaddr->hpcs1 = HP_PRESET|HP_GO; ! 224: hpaddr->hpof = HPOF_FMT22; ! 225: mbclrattn(mi); ! 226: #ifndef NOBADSECT ! 227: bbp->b_flags = B_READ|B_BUSY; ! 228: bbp->b_dev = bp->b_dev; ! 229: bbp->b_bcount = 512; ! 230: bbp->b_un.b_addr = (caddr_t)&hpbad[mi->mi_unit]; ! 231: bbp->b_blkno = st->ncyl*st->nspc - st->nsect; ! 232: bbp->b_cylin = st->ncyl - 1; ! 233: mi->mi_tab.b_actf = bbp; ! 234: bbp->av_forw = bp; ! 235: bp = bbp; ! 236: #endif ! 237: } ! 238: if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1) ! 239: return (MBU_DODATA); ! 240: if ((hpaddr->hpds & HPDS_DREADY) != HPDS_DREADY) ! 241: return (MBU_DODATA); ! 242: bn = dkblock(bp); ! 243: sn = bn%st->nspc; ! 244: sn = (sn+st->nsect-hpSDIST)%st->nsect; ! 245: if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) { ! 246: if (hpseek) ! 247: return (MBU_DODATA); ! 248: dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1; ! 249: if (dist < 0) ! 250: dist += st->nsect; ! 251: if (dist > st->nsect - hpRDIST) ! 252: return (MBU_DODATA); ! 253: } else ! 254: hpaddr->hpdc = bp->b_cylin; ! 255: if (hpseek) ! 256: hpaddr->hpcs1 = HP_SEEK|HP_GO; ! 257: else { ! 258: hpaddr->hpda = sn; ! 259: hpaddr->hpcs1 = HP_SEARCH|HP_GO; ! 260: } ! 261: return (MBU_STARTED); ! 262: } ! 263: ! 264: hpstart(mi) ! 265: register struct mba_device *mi; ! 266: { ! 267: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv; ! 268: register struct buf *bp = mi->mi_tab.b_actf; ! 269: register struct hpst *st = &hpst[mi->mi_type]; ! 270: daddr_t bn; ! 271: int sn, tn; ! 272: ! 273: bn = dkblock(bp); ! 274: sn = bn%st->nspc; ! 275: tn = sn/st->nsect; ! 276: sn %= st->nsect; ! 277: hpaddr->hpdc = bp->b_cylin; ! 278: hpaddr->hpda = (tn << 8) + sn; ! 279: return(0); ! 280: } ! 281: ! 282: hpdtint(mi, mbsr) ! 283: register struct mba_device *mi; ! 284: int mbsr; ! 285: { ! 286: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv; ! 287: register struct buf *bp = mi->mi_tab.b_actf; ! 288: int retry = 0; ! 289: ! 290: #ifndef NOBADSECT ! 291: if (bp->b_flags&B_BAD) { ! 292: if (hpecc(mi, CONT)) ! 293: return(MBD_RESTARTED); ! 294: } ! 295: #endif ! 296: if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) { ! 297: #ifdef HPDEBUG ! 298: if (hpdebug) { ! 299: int dc = hpaddr->hpdc, da = hpaddr->hpda; ! 300: ! 301: printf("hperr: bp %x cyl %d blk %d as %o ", ! 302: bp, bp->b_cylin, bp->b_blkno, ! 303: hpaddr->hpas&0xff); ! 304: printf("dc %x da %x\n",dc&0xffff, da&0xffff); ! 305: printf("errcnt %d ", mi->mi_tab.b_errcnt); ! 306: printf("mbsr=%b ", mbsr, mbsr_bits); ! 307: printf("er1=%b er2=%b\n", ! 308: hpaddr->hper1, HPER1_BITS, ! 309: hpaddr->hper2, HPER2_BITS); ! 310: DELAY(1000000); ! 311: } ! 312: #endif ! 313: if (hpaddr->hper1&HPER1_WLE) { ! 314: printf("hp%d: write locked\n", dkunit(bp)); ! 315: bp->b_flags |= B_ERROR; ! 316: } else if (++mi->mi_tab.b_errcnt > 27 || ! 317: mbsr & MBSR_HARD || ! 318: hpaddr->hper1 & HPER1_HARD || ! 319: hpaddr->hper2 & HPER2_HARD) { ! 320: hard: ! 321: harderr(bp, "hp"); ! 322: if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC))) ! 323: printf("mbsr=%b ", mbsr, mbsr_bits); ! 324: printf("er1=%b er2=%b", ! 325: hpaddr->hper1, HPER1_BITS, ! 326: hpaddr->hper2, HPER2_BITS); ! 327: if (hpaddr->hpmr) ! 328: printf(" mr=%o", hpaddr->hpmr&0xffff); ! 329: if (hpaddr->hpmr2) ! 330: printf(" mr2=%o", hpaddr->hpmr2&0xffff); ! 331: printf("\n"); ! 332: bp->b_flags |= B_ERROR; ! 333: hprecal[mi->mi_unit] = 0; ! 334: } else if (hpaddr->hper2 & HPER2_BSE) { ! 335: #ifndef NOBADSECT ! 336: if (hpecc(mi, BSE)) ! 337: return(MBD_RESTARTED); ! 338: else ! 339: #endif ! 340: goto hard; ! 341: } else if (hptypes[mi->mi_type] == MBDT_RM80 && ! 342: hpaddr->hper2&HPER2_SSE) { ! 343: (void) hpecc(mi, SSE); ! 344: return (MBD_RESTARTED); ! 345: } else if ((hpaddr->hper1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) { ! 346: if (hpecc(mi, ECC)) ! 347: return (MBD_RESTARTED); ! 348: /* else done */ ! 349: } else ! 350: retry = 1; ! 351: hpaddr->hpcs1 = HP_DCLR|HP_GO; ! 352: if ((mi->mi_tab.b_errcnt&07) == 4) { ! 353: hpaddr->hpcs1 = HP_RECAL|HP_GO; ! 354: hprecal[mi->mi_unit] = 1; ! 355: return(MBD_RESTARTED); ! 356: } ! 357: if (retry) ! 358: return (MBD_RETRY); ! 359: } ! 360: #ifdef HPDEBUG ! 361: else ! 362: if (hpdebug && hprecal[mi->mi_unit]) { ! 363: printf("recal %d ", hprecal[mi->mi_unit]); ! 364: printf("errcnt %d\n", mi->mi_tab.b_errcnt); ! 365: printf("mbsr=%b ", mbsr, mbsr_bits); ! 366: printf("er1=%b er2=%b\n", ! 367: hpaddr->hper1, HPER1_BITS, ! 368: hpaddr->hper2, HPER2_BITS); ! 369: } ! 370: #endif ! 371: switch (hprecal[mi->mi_unit]) { ! 372: ! 373: case 1: ! 374: hpaddr->hpdc = bp->b_cylin; ! 375: hpaddr->hpcs1 = HP_SEEK|HP_GO; ! 376: hprecal[mi->mi_unit]++; ! 377: return (MBD_RESTARTED); ! 378: case 2: ! 379: if (mi->mi_tab.b_errcnt < 16 || ! 380: (bp->b_flags & B_READ) == 0) ! 381: goto donerecal; ! 382: hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22; ! 383: hpaddr->hpcs1 = HP_OFFSET|HP_GO; ! 384: hprecal[mi->mi_unit]++; ! 385: return (MBD_RESTARTED); ! 386: donerecal: ! 387: case 3: ! 388: hprecal[mi->mi_unit] = 0; ! 389: return (MBD_RETRY); ! 390: } ! 391: bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff; ! 392: if (mi->mi_tab.b_errcnt >= 16) { ! 393: /* ! 394: * This is fast and occurs rarely; we don't ! 395: * bother with interrupts. ! 396: */ ! 397: hpaddr->hpcs1 = HP_RTC|HP_GO; ! 398: while (hpaddr->hpds & HPDS_PIP) ! 399: ; ! 400: mbclrattn(mi); ! 401: } ! 402: hpaddr->hpof = HPOF_FMT22; ! 403: hpaddr->hpcs1 = HP_RELEASE|HP_GO; ! 404: return (MBD_DONE); ! 405: } ! 406: ! 407: hpread(dev) ! 408: dev_t dev; ! 409: { ! 410: register int unit = minor(dev) >> 3; ! 411: ! 412: if (unit >= NHP) ! 413: u.u_error = ENXIO; ! 414: else ! 415: physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys); ! 416: } ! 417: ! 418: hpwrite(dev) ! 419: dev_t dev; ! 420: { ! 421: register int unit = minor(dev) >> 3; ! 422: ! 423: if (unit >= NHP) ! 424: u.u_error = ENXIO; ! 425: else ! 426: physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys); ! 427: } ! 428: ! 429: hpecc(mi, flag) ! 430: register struct mba_device *mi; ! 431: int flag; ! 432: { ! 433: register struct mba_regs *mbp = mi->mi_mba; ! 434: register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv; ! 435: register struct buf *bp = mi->mi_tab.b_actf; ! 436: register struct hpst *st = &hpst[mi->mi_type]; ! 437: int npf, o; ! 438: int bn, cn, tn, sn; ! 439: int bcr; ! 440: ! 441: bcr = mbp->mba_bcr & 0xffff; ! 442: if (bcr) ! 443: bcr |= 0xffff0000; /* sxt */ ! 444: #ifndef NOBADSECT ! 445: if (flag == CONT) ! 446: npf = bp->b_error; ! 447: else ! 448: #endif ! 449: npf = btop(bcr + bp->b_bcount); ! 450: o = (int)bp->b_un.b_addr & PGOFSET; ! 451: bn = dkblock(bp); ! 452: cn = bp->b_cylin; ! 453: sn = bn%(st->nspc) + npf; ! 454: tn = sn/st->nsect; ! 455: sn %= st->nsect; ! 456: cn += tn/st->ntrak; ! 457: tn %= st->ntrak; ! 458: switch (flag) { ! 459: case ECC: ! 460: { ! 461: register int i; ! 462: caddr_t addr; ! 463: struct pte mpte; ! 464: int bit, byte, mask; ! 465: ! 466: npf--; /* because block in error is previous block */ ! 467: printf("hp%d%c: soft ecc sn%d\n", dkunit(bp), ! 468: 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf); ! 469: mask = rp->hpec2&0xffff; ! 470: i = (rp->hpec1&0xffff) - 1; /* -1 makes 0 origin */ ! 471: bit = i&07; ! 472: i = (i&~07)>>3; ! 473: byte = i + o; ! 474: while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { ! 475: mpte = mbp->mba_map[npf+btop(byte)]; ! 476: addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET); ! 477: putmemc(addr, getmemc(addr)^(mask<<bit)); ! 478: byte++; ! 479: i++; ! 480: bit -= 8; ! 481: } ! 482: if (bcr == 0) ! 483: return (0); ! 484: npf++; ! 485: break; ! 486: } ! 487: ! 488: case SSE: ! 489: rp->hpof |= HPOF_SSEI; ! 490: mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf)); ! 491: break; ! 492: ! 493: #ifndef NOBADSECT ! 494: case BSE: ! 495: #ifdef HPBDEBUG ! 496: if (hpbdebug) ! 497: printf("hpecc, BSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn); ! 498: #endif ! 499: if ((bn = isbad(&hpbad[mi->mi_unit], cn, tn, sn)) < 0) ! 500: return(0); ! 501: bp->b_flags |= B_BAD; ! 502: bp->b_error = npf + 1; ! 503: bn = st->ncyl*st->nspc - st->nsect - 1 - bn; ! 504: cn = bn/st->nspc; ! 505: sn = bn%st->nspc; ! 506: tn = sn/st->nsect; ! 507: sn %= st->nsect; ! 508: mbp->mba_bcr = -512; ! 509: #ifdef HPBDEBUG ! 510: if (hpbdebug) ! 511: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); ! 512: #endif ! 513: break; ! 514: ! 515: case CONT: ! 516: #ifdef HPBDEBUG ! 517: if (hpbdebug) ! 518: printf("hpecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn); ! 519: #endif ! 520: npf = bp->b_error; ! 521: bp->b_flags &= ~B_BAD; ! 522: mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf)); ! 523: if ((mbp->mba_bcr & 0xffff) == 0) ! 524: return(0); ! 525: break; ! 526: #endif ! 527: } ! 528: rp->hpcs1 = HP_DCLR|HP_GO; ! 529: if (rp->hpof&HPOF_SSEI) ! 530: sn++; ! 531: rp->hpdc = cn; ! 532: rp->hpda = (tn<<8) + sn; ! 533: mbp->mba_sr = -1; ! 534: mbp->mba_var = (int)ptob(npf) + o; ! 535: rp->hpcs1 = bp->b_flags&B_READ ? HP_RCOM|HP_GO : HP_WCOM|HP_GO; ! 536: mi->mi_tab.b_errcnt = 0; /* error has been corrected */ ! 537: return (1); ! 538: } ! 539: ! 540: #define DBSIZE 20 ! 541: ! 542: hpdump(dev) ! 543: dev_t dev; ! 544: { ! 545: register struct mba_device *mi; ! 546: register struct mba_regs *mba; ! 547: struct hpdevice *hpaddr; ! 548: char *start; ! 549: int num, unit; ! 550: register struct hpst *st; ! 551: ! 552: num = maxfree; ! 553: start = 0; ! 554: unit = minor(dev) >> 3; ! 555: if (unit >= NHP) ! 556: return (ENXIO); ! 557: #define phys(a,b) ((b)((int)(a)&0x7fffffff)) ! 558: mi = phys(hpinfo[unit],struct mba_device *); ! 559: if (mi == 0 || mi->mi_alive == 0) ! 560: return (ENXIO); ! 561: mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba; ! 562: mba->mba_cr = MBCR_INIT; ! 563: hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive]; ! 564: if ((hpaddr->hpds & HPDS_VV) == 0) { ! 565: hpaddr->hpcs1 = HP_DCLR|HP_GO; ! 566: hpaddr->hpcs1 = HP_PRESET|HP_GO; ! 567: hpaddr->hpof = HPOF_FMT22; ! 568: } ! 569: st = &hpst[mi->mi_type]; ! 570: if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks) ! 571: return (EINVAL); ! 572: while (num > 0) { ! 573: register struct pte *hpte = mba->mba_map; ! 574: register int i; ! 575: int blk, cn, sn, tn; ! 576: daddr_t bn; ! 577: ! 578: blk = num > DBSIZE ? DBSIZE : num; ! 579: bn = dumplo + btop(start); ! 580: cn = bn/st->nspc + st->sizes[minor(dev)&07].cyloff; ! 581: sn = bn%st->nspc; ! 582: tn = sn/st->nsect; ! 583: sn = sn%st->nsect; ! 584: hpaddr->hpdc = cn; ! 585: hpaddr->hpda = (tn << 8) + sn; ! 586: for (i = 0; i < blk; i++) ! 587: *(int *)hpte++ = (btop(start)+i) | PG_V; ! 588: mba->mba_sr = -1; ! 589: mba->mba_bcr = -(blk*NBPG); ! 590: mba->mba_var = 0; ! 591: hpaddr->hpcs1 = HP_WCOM | HP_GO; ! 592: while ((hpaddr->hpds & HPDS_DRY) == 0) ! 593: ; ! 594: if (hpaddr->hpds&HPDS_ERR) ! 595: return (EIO); ! 596: start += blk*NBPG; ! 597: num -= blk; ! 598: } ! 599: return (0); ! 600: } ! 601: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.