1*2362Swnj /* hp.c 4.5 02/07/81 */ 221Sbill 31939Swnj #include "hp.h" 41565Sbill #if NHP > 0 521Sbill /* 6886Sbill * RP06/RM03/RM05 disk driver 721Sbill */ 821Sbill 921Sbill #include "../h/param.h" 1021Sbill #include "../h/systm.h" 11305Sbill #include "../h/dk.h" 1221Sbill #include "../h/buf.h" 1321Sbill #include "../h/conf.h" 1421Sbill #include "../h/dir.h" 1521Sbill #include "../h/user.h" 1621Sbill #include "../h/map.h" 17420Sbill #include "../h/pte.h" 1821Sbill #include "../h/mba.h" 1921Sbill #include "../h/mtpr.h" 20420Sbill #include "../h/vm.h" 21*2362Swnj #include "../h/cmap.h" 2221Sbill 2321Sbill struct device 2421Sbill { 2521Sbill int hpcs1; /* control and Status register 1 */ 2621Sbill int hpds; /* Drive Status */ 2721Sbill int hper1; /* Error register 1 */ 2821Sbill int hpmr; /* Maintenance */ 2921Sbill int hpas; /* Attention Summary */ 3021Sbill int hpda; /* Desired address register */ 3121Sbill int hpdt; /* Drive type */ 3221Sbill int hpla; /* Look ahead */ 3321Sbill int hpsn; /* serial number */ 3421Sbill int hpof; /* Offset register */ 3521Sbill int hpdc; /* Desired Cylinder address register */ 3621Sbill int hpcc; /* Current Cylinder */ 3721Sbill int hper2; /* Error register 2 */ 3821Sbill int hper3; /* Error register 3 */ 3921Sbill int hpec1; /* Burst error bit position */ 4021Sbill int hpec2; /* Burst error bit pattern */ 4121Sbill }; 4221Sbill 4321Sbill #define RP 022 4421Sbill #define RM 024 45886Sbill #define RM5 027 4621Sbill #define NSECT 22 4721Sbill #define NTRAC 19 4821Sbill #define NRMSECT 32 4921Sbill #define NRMTRAC 5 5021Sbill 511591Sbill #define _hpSDIST 2 521591Sbill #define _hpRDIST 3 53305Sbill 54305Sbill int hpSDIST = _hpSDIST; 55305Sbill int hpRDIST = _hpRDIST; 56305Sbill int hpseek; 57305Sbill 5821Sbill struct size 5921Sbill { 6021Sbill daddr_t nblocks; 6121Sbill int cyloff; 6221Sbill } hp_sizes[8] = 6321Sbill { 64886Sbill 15884, 0, /* A=cyl 0 thru 37 */ 65886Sbill 33440, 38, /* B=cyl 38 thru 117 */ 66886Sbill 340670, 0, /* C=cyl 0 thru 814 */ 6721Sbill 0, 0, 6821Sbill 0, 0, 6921Sbill 0, 0, 70886Sbill 291346, 118, /* G=cyl 118 thru 814 */ 7121Sbill 0, 0, 7221Sbill }, rm_sizes[8] = { 73886Sbill 15884, 0, /* A=cyl 0 thru 99 */ 74886Sbill 33440, 100, /* B=cyl 100 thru 309 */ 75886Sbill 131680, 0, /* C=cyl 0 thru 822 */ 76*2362Swnj 2720, 291, 7721Sbill 0, 0, 7821Sbill 0, 0, 79886Sbill 82080, 310, /* G=cyl 310 thru 822 */ 8021Sbill 0, 0, 81886Sbill }, rm5_sizes[8] = { 82886Sbill 15884, 0, /* A=cyl 0 thru 26 */ 83886Sbill 33440, 27, /* B=cyl 27 thru 81 */ 84886Sbill 500992, 0, /* C=cyl 0 thru 823 */ 85886Sbill 15884, 562, /* D=cyl 562 thru 588 */ 86886Sbill 55936, 589, /* E=cyl 589 thru 680 */ 87886Sbill 86944, 681, /* F=cyl 681 thru 823 */ 88886Sbill 159296, 562, /* G=cyl 562 thru 823 */ 89886Sbill 291346, 82, /* H=cyl 82 thru 561 */ 9021Sbill }; 9121Sbill 9221Sbill #define P400 020 9321Sbill #define M400 0220 9421Sbill #define P800 040 9521Sbill #define M800 0240 9621Sbill #define P1200 060 9721Sbill #define M1200 0260 9821Sbill int hp_offset[16] = 9921Sbill { 10021Sbill P400, M400, P400, M400, 10121Sbill P800, M800, P800, M800, 10221Sbill P1200, M1200, P1200, M1200, 10321Sbill 0, 0, 0, 0, 10421Sbill }; 10521Sbill 10621Sbill struct buf hptab; 10721Sbill struct buf rhpbuf; 10821Sbill struct buf hputab[NHP]; 10921Sbill char hp_type[NHP]; /* drive type */ 11021Sbill 11121Sbill #define GO 01 11221Sbill #define PRESET 020 11321Sbill #define RTC 016 11421Sbill #define OFFSET 014 115305Sbill #define SEEK 04 11621Sbill #define SEARCH 030 11721Sbill #define RECAL 06 11821Sbill #define DCLR 010 11921Sbill #define WCOM 060 12021Sbill #define RCOM 070 12121Sbill 12221Sbill #define IE 0100 12321Sbill #define PIP 020000 12421Sbill #define DRY 0200 12521Sbill #define ERR 040000 12621Sbill #define TRE 040000 12721Sbill #define DCK 0100000 12821Sbill #define WLE 04000 12921Sbill #define ECH 0100 13021Sbill #define VV 0100 13121Sbill #define DPR 0400 13221Sbill #define MOL 010000 13321Sbill #define FMT22 010000 13421Sbill 13521Sbill #define b_cylin b_resid 13621Sbill 13721Sbill #ifdef INTRLVE 13821Sbill daddr_t dkblock(); 13921Sbill #endif 14021Sbill 14121Sbill hpstrategy(bp) 14221Sbill register struct buf *bp; 14321Sbill { 14421Sbill register struct buf *dp; 14521Sbill register unit, xunit, nspc; 14621Sbill long sz, bn; 14721Sbill struct size *sizes; 14821Sbill 149420Sbill if ((mbaact&(1<<HPMBANUM)) == 0) 150420Sbill mbainit(HPMBANUM); 15121Sbill xunit = minor(bp->b_dev) & 077; 15221Sbill sz = bp->b_bcount; 15321Sbill sz = (sz+511) >> 9; 15421Sbill unit = dkunit(bp); 15521Sbill if (hp_type[unit] == 0) { 15621Sbill struct device *hpaddr; 1571413Sbill double mspw; 15821Sbill 15921Sbill /* determine device type */ 160420Sbill hpaddr = mbadev(HPMBA, unit); 1611413Sbill 1621413Sbill /* record transfer rate (these are guesstimates secs/word) */ 1631413Sbill switch (hp_type[unit] = hpaddr->hpdt) { 1641413Sbill case RM: mspw = .0000019728; break; 1651413Sbill case RM5: mspw = .0000020345; break; 1661413Sbill case RP: mspw = .0000029592; break; 1671413Sbill } 1681946Swnj if (HPDK_N + unit <= HPDK_NMAX) 1691946Swnj dk_mspw[HPDK_N+unit] = mspw; 17021Sbill } 171886Sbill switch (hp_type[unit]) { 172886Sbill 173886Sbill case RM: 17421Sbill sizes = rm_sizes; 17521Sbill nspc = NRMSECT*NRMTRAC; 176886Sbill break; 177886Sbill case RM5: 178886Sbill sizes = rm5_sizes; 179886Sbill nspc = NRMSECT*NTRAC; 180886Sbill break; 181886Sbill case RP: 18221Sbill sizes = hp_sizes; 18321Sbill nspc = NSECT*NTRAC; 184886Sbill break; 185886Sbill default: 186886Sbill printf("hp: unknown device type 0%o\n", hp_type[unit]); 187886Sbill u.u_error = ENXIO; 188886Sbill unit = NHP+1; /* force error */ 18921Sbill } 19021Sbill if (unit >= NHP || 19121Sbill bp->b_blkno < 0 || 19221Sbill (bn = dkblock(bp))+sz > sizes[xunit&07].nblocks) { 19321Sbill bp->b_flags |= B_ERROR; 19421Sbill iodone(bp); 19521Sbill return; 19621Sbill } 19721Sbill bp->b_cylin = bn/nspc + sizes[xunit&07].cyloff; 19821Sbill dp = &hputab[unit]; 199127Sbill (void) spl5(); 20021Sbill disksort(dp, bp); 20121Sbill if (dp->b_active == 0) { 20221Sbill hpustart(unit); 20321Sbill if(hptab.b_active == 0) 20421Sbill hpstart(); 20521Sbill } 206127Sbill (void) spl0(); 20721Sbill } 20821Sbill 20921Sbill hpustart(unit) 21021Sbill register unit; 21121Sbill { 21221Sbill register struct buf *bp, *dp; 21321Sbill register struct device *hpaddr; 21421Sbill daddr_t bn; 2152298Skre int sn, cn, csn, ns; 21621Sbill 2171734Sbill ((struct mba_regs *)HPMBA)->mba_cr |= MBAIE; 218420Sbill hpaddr = mbadev(HPMBA, 0); 219420Sbill hpaddr->hpas = 1<<unit; 22021Sbill 22121Sbill if(unit >= NHP) 22221Sbill return; 2231946Swnj if (unit+HPDK_N <= HPDK_NMAX) 2241946Swnj dk_busy &= ~(1<<(unit+HPDK_N)); 22521Sbill dp = &hputab[unit]; 22621Sbill if((bp=dp->b_actf) == NULL) 22721Sbill return; 228420Sbill hpaddr = mbadev(HPMBA, unit); 22921Sbill if((hpaddr->hpds & VV) == 0) { 2302298Skre hpaddr->hpcs1 = DCLR|GO; 23121Sbill hpaddr->hpcs1 = PRESET|GO; 23221Sbill hpaddr->hpof = FMT22; 23321Sbill } 23421Sbill if(dp->b_active) 23521Sbill goto done; 23621Sbill dp->b_active++; 23721Sbill if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL)) 23821Sbill goto done; 23921Sbill 2402298Skre #if NHP > 1 24121Sbill bn = dkblock(bp); 24221Sbill cn = bp->b_cylin; 243886Sbill switch (hp_type[unit]) { 244886Sbill 245886Sbill case RM: 24621Sbill sn = bn%(NRMSECT*NRMTRAC); 247305Sbill sn = (sn+NRMSECT-hpSDIST)%NRMSECT; 2482298Skre ns = NRMSECT; 249886Sbill break; 250886Sbill case RM5: 251886Sbill sn = bn%(NRMSECT*NTRAC); 252886Sbill sn = (sn+NRMSECT-hpSDIST)%NRMSECT; 2532298Skre ns = NRMSECT; 254886Sbill break; 255886Sbill case RP: 25621Sbill sn = bn%(NSECT*NTRAC); 257305Sbill sn = (sn+NSECT-hpSDIST)%NSECT; 2582298Skre ns = NSECT; 259886Sbill break; 260886Sbill default: 261886Sbill panic("hpustart"); 26221Sbill } 26321Sbill 26421Sbill if(cn - (hpaddr->hpdc & 0xffff)) 26521Sbill goto search; 266305Sbill else if (hpseek) 267305Sbill goto done; 268305Sbill csn = ((hpaddr->hpla & 0xffff)>>6) - sn + 1; 26921Sbill if(csn < 0) 2702298Skre csn += ns; 2712298Skre if(csn > ns-hpRDIST) 27221Sbill goto done; 27321Sbill 27421Sbill search: 27521Sbill hpaddr->hpdc = cn; 276305Sbill if (hpseek) 277305Sbill hpaddr->hpcs1 = SEEK|GO; 278305Sbill else { 279305Sbill hpaddr->hpda = sn; 280305Sbill hpaddr->hpcs1 = SEARCH|GO; 281305Sbill } 2821946Swnj unit += HPDK_N; 2831946Swnj if (unit <= HPDK_NMAX) { 284344Sbill dk_busy |= 1<<unit; 2851413Sbill dk_seek[unit]++; 2861465Sbill } 28721Sbill return; 2882298Skre #endif 28921Sbill 29021Sbill done: 29121Sbill dp->b_forw = NULL; 29221Sbill if(hptab.b_actf == NULL) 293344Sbill hptab.b_actf = dp; 294344Sbill else 29521Sbill hptab.b_actl->b_forw = dp; 29621Sbill hptab.b_actl = dp; 29721Sbill } 29821Sbill 29921Sbill hpstart() 30021Sbill { 30121Sbill register struct buf *bp, *dp; 30221Sbill register unit; 30321Sbill register struct device *hpaddr; 30421Sbill daddr_t bn; 30521Sbill int dn, sn, tn, cn, nspc, ns; 30621Sbill 30721Sbill loop: 30821Sbill if ((dp = hptab.b_actf) == NULL) 30921Sbill return; 31021Sbill if ((bp = dp->b_actf) == NULL) { 31121Sbill hptab.b_actf = dp->b_forw; 31221Sbill goto loop; 31321Sbill } 31421Sbill hptab.b_active++; 31521Sbill unit = minor(bp->b_dev) & 077; 31621Sbill dn = dkunit(bp); 31721Sbill bn = dkblock(bp); 318886Sbill switch (hp_type[dn]) { 319886Sbill case RM: 32021Sbill nspc = NRMSECT*NRMTRAC; 32121Sbill ns = NRMSECT; 32221Sbill cn = rm_sizes[unit&07].cyloff; 323886Sbill break; 324886Sbill case RM5: 325886Sbill nspc = NRMSECT*NTRAC; 326886Sbill ns = NRMSECT; 327886Sbill cn = rm5_sizes[unit&07].cyloff; 328886Sbill break; 329886Sbill case RP: 33021Sbill nspc = NSECT*NTRAC; 33121Sbill ns = NSECT; 33221Sbill cn = hp_sizes[unit&07].cyloff; 333886Sbill break; 334886Sbill default: 335886Sbill panic("hpstart"); 33621Sbill } 33721Sbill cn += bn/nspc; 33821Sbill sn = bn%nspc; 33921Sbill tn = sn/ns; 34021Sbill sn = sn%ns; 34121Sbill 342420Sbill hpaddr = mbadev(HPMBA, dn); 34321Sbill if ((hpaddr->hpds & (DPR|MOL)) != (DPR|MOL)) { 34421Sbill hptab.b_active = 0; 34521Sbill hptab.b_errcnt = 0; 34621Sbill dp->b_actf = bp->av_forw; 34721Sbill bp->b_flags |= B_ERROR; 34821Sbill iodone(bp); 34921Sbill goto loop; 35021Sbill } 3512298Skre if(hptab.b_errcnt >= 16 && (bp->b_flags&B_READ) != 0) { 35221Sbill hpaddr->hpof = hp_offset[hptab.b_errcnt & 017] | FMT22; 353420Sbill HPMBA->mba_cr &= ~MBAIE; 35421Sbill hpaddr->hpcs1 = OFFSET|GO; 35521Sbill while(hpaddr->hpds & PIP) 35621Sbill ; 357420Sbill HPMBA->mba_cr |= MBAIE; 35821Sbill } 35921Sbill hpaddr->hpdc = cn; 36021Sbill hpaddr->hpda = (tn << 8) + sn; 36121Sbill mbastart(bp, (int *)hpaddr); 36221Sbill 3631946Swnj unit = dn+HPDK_N; 3641946Swnj if (unit <= HPDK_NMAX) { 365344Sbill dk_busy |= 1<<unit; 3661413Sbill dk_xfer[unit]++; 367344Sbill dk_wds[unit] += bp->b_bcount>>6; 368344Sbill } 36921Sbill } 37021Sbill 37121Sbill hpintr(mbastat, as) 37221Sbill { 37321Sbill register struct buf *bp, *dp; 37421Sbill register unit; 37521Sbill register struct device *hpaddr; 37621Sbill 37721Sbill if(hptab.b_active) { 37821Sbill dp = hptab.b_actf; 37921Sbill bp = dp->b_actf; 38021Sbill unit = dkunit(bp); 3811946Swnj if (HPDK_N+unit <= HPDK_NMAX) 3821946Swnj dk_busy &= ~(1<<(HPDK_N+unit)); 383420Sbill hpaddr = mbadev(HPMBA, unit); 384420Sbill if (hpaddr->hpds & ERR || mbastat & MBAEBITS) { 38521Sbill while((hpaddr->hpds & DRY) == 0) 38621Sbill ; 38721Sbill if(++hptab.b_errcnt > 28 || hpaddr->hper1&WLE) 388420Sbill bp->b_flags |= B_ERROR; 389420Sbill else 39021Sbill hptab.b_active = 0; 39121Sbill if(hptab.b_errcnt > 27) 39221Sbill deverror(bp, mbastat, hpaddr->hper1); 39321Sbill if ((hpaddr->hper1&0xffff) == DCK) { 39421Sbill if (hpecc(hpaddr, bp)) 39521Sbill return; 39621Sbill } 39721Sbill hpaddr->hpcs1 = DCLR|GO; 39821Sbill if((hptab.b_errcnt&07) == 4) { 399420Sbill HPMBA->mba_cr &= ~MBAIE; 40021Sbill hpaddr->hpcs1 = RECAL|GO; 40121Sbill while(hpaddr->hpds & PIP) 40221Sbill ; 403420Sbill HPMBA->mba_cr |= MBAIE; 40421Sbill } 40521Sbill } 40621Sbill if(hptab.b_active) { 40721Sbill if(hptab.b_errcnt) { 408420Sbill HPMBA->mba_cr &= ~MBAIE; 40921Sbill hpaddr->hpcs1 = RTC|GO; 41021Sbill while(hpaddr->hpds & PIP) 41121Sbill ; 412420Sbill HPMBA->mba_cr |= MBAIE; 41321Sbill } 41421Sbill hptab.b_active = 0; 41521Sbill hptab.b_errcnt = 0; 41621Sbill hptab.b_actf = dp->b_forw; 41721Sbill dp->b_active = 0; 41821Sbill dp->b_errcnt = 0; 41921Sbill dp->b_actf = bp->av_forw; 420420Sbill bp->b_resid = -HPMBA->mba_bcr & 0xffff; 42121Sbill iodone(bp); 42221Sbill if(dp->b_actf) 42321Sbill hpustart(unit); 42421Sbill } 42521Sbill as &= ~(1<<unit); 42621Sbill } else { 42721Sbill if(as == 0) 428420Sbill HPMBA->mba_cr |= MBAIE; 42921Sbill } 43021Sbill for(unit=0; unit<NHP; unit++) 43121Sbill if(as & (1<<unit)) 43221Sbill hpustart(unit); 43321Sbill hpstart(); 43421Sbill } 43521Sbill 43621Sbill hpread(dev) 43721Sbill { 43821Sbill 43921Sbill physio(hpstrategy, &rhpbuf, dev, B_READ, minphys); 44021Sbill } 44121Sbill 44221Sbill hpwrite(dev) 44321Sbill { 44421Sbill 44521Sbill physio(hpstrategy, &rhpbuf, dev, B_WRITE, minphys); 44621Sbill } 44721Sbill 44821Sbill hpecc(rp, bp) 44921Sbill register struct device *rp; 45021Sbill register struct buf *bp; 45121Sbill { 452420Sbill struct mba_regs *mbp = HPMBA; 453420Sbill register int i; 454420Sbill caddr_t addr; 455420Sbill int reg, bit, byte, npf, mask, o; 456420Sbill int dn, bn, cn, tn, sn, ns, nt; 457106Sbill extern char buffers[NBUF][BSIZE]; 458420Sbill struct pte mpte; 459914Sbill int bcr; 46021Sbill 461420Sbill /* 462420Sbill * Npf is the number of sectors transferred before the sector 463420Sbill * containing the ECC error, and reg is the MBA register 464420Sbill * mapping (the first part of)the transfer. 465420Sbill * O is offset within a memory page of the first byte transferred. 466420Sbill */ 467914Sbill bcr = mbp->mba_bcr & 0xffff; 468914Sbill if (bcr) 469914Sbill bcr |= 0xffff0000; /* sxt */ 470719Sbill npf = btop(bcr + bp->b_bcount) - 1; 4711413Sbill reg = npf; 472420Sbill o = (int)bp->b_un.b_addr & PGOFSET; 473420Sbill printf("%D ", bp->b_blkno + npf); 47421Sbill prdev("ECC", bp->b_dev); 47521Sbill mask = rp->hpec2&0xffff; 47621Sbill if (mask == 0) { 47721Sbill rp->hpof = FMT22; 478420Sbill return (0); 47921Sbill } 480420Sbill 481420Sbill /* 482420Sbill * Compute the byte and bit position of the error. 483420Sbill * The variable i is the byte offset in the transfer, 484420Sbill * the variable byte is the offset from a page boundary 485420Sbill * in main memory. 486420Sbill */ 487420Sbill i = (rp->hpec1&0xffff) - 1; /* -1 makes 0 origin */ 488719Sbill bit = i&07; 489420Sbill i = (i&~07)>>3; 490420Sbill byte = i + o; 491420Sbill /* 492420Sbill * Correct while possible bits remain of mask. Since mask 493420Sbill * contains 11 bits, we continue while the bit offset is > -11. 494420Sbill * Also watch out for end of this block and the end of the whole 495420Sbill * transfer. 496420Sbill */ 497420Sbill while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) { 498420Sbill mpte = mbp->mba_map[reg+btop(byte)]; 499420Sbill addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET); 500420Sbill putmemc(addr, getmemc(addr)^(mask<<bit)); 501420Sbill byte++; 502420Sbill i++; 503420Sbill bit -= 8; 50421Sbill } 505420Sbill hptab.b_active++; /* Either complete or continuing */ 506719Sbill if (bcr == 0) 507420Sbill return (0); 508420Sbill /* 509420Sbill * Have to continue the transfer... clear the drive, 510420Sbill * and compute the position where the transfer is to continue. 511420Sbill * We have completed npf+1 sectores of the transfer already; 512420Sbill * restart at offset o of next sector (i.e. in MBA register reg+1). 513420Sbill */ 514420Sbill rp->hpcs1 = DCLR|GO; 515420Sbill dn = dkunit(bp); 516420Sbill bn = dkblock(bp); 517886Sbill switch (hp_type[dn]) { 518886Sbill 519886Sbill case RM: 520886Sbill ns = NRMSECT; nt = NRMTRAC; break; 521886Sbill case RM5: 522886Sbill ns = NRMSECT; nt = NTRAC; break; 523886Sbill case RP: 524886Sbill ns = NSECT; nt = NTRAC; break; 525886Sbill default: 526886Sbill panic("hpecc"); 52721Sbill } 528420Sbill cn = bp->b_cylin; 529420Sbill sn = bn%(ns*nt) + npf + 1; 530420Sbill tn = sn/ns; 531420Sbill sn %= ns; 532420Sbill cn += tn/nt; 533420Sbill tn %= nt; 534420Sbill rp->hpdc = cn; 535420Sbill rp->hpda = (tn<<8) + sn; 536420Sbill mbp->mba_sr = -1; 537420Sbill mbp->mba_var = (int)ptob(reg+1) + o; 538420Sbill rp->hpcs1 = RCOM|GO; 539420Sbill return (1); 54021Sbill } 541*2362Swnj 542*2362Swnj #define DBSIZE 20 543*2362Swnj 544*2362Swnj hpdump(dev) 545*2362Swnj dev_t dev; 546*2362Swnj { 547*2362Swnj struct device *hpaddr; 548*2362Swnj char *start; 549*2362Swnj int num, blk, unit, nsect, ntrak, nspc; 550*2362Swnj struct size *sizes; 551*2362Swnj 552*2362Swnj num = maxfree; 553*2362Swnj start = 0; 554*2362Swnj unit = minor(dev) >> 3; 555*2362Swnj if (unit >= NHP) { 556*2362Swnj printf("bad unit\n"); 557*2362Swnj return (-1); 558*2362Swnj } 559*2362Swnj HPPHYSMBA->mba_cr = MBAINIT; 560*2362Swnj hpaddr = mbadev(HPPHYSMBA, unit); 561*2362Swnj if (hp_type[unit] == 0) 562*2362Swnj hp_type[unit] = hpaddr->hpdt; 563*2362Swnj if((hpaddr->hpds & VV) == 0) { 564*2362Swnj hpaddr->hpcs1 = PRESET|GO; 565*2362Swnj hpaddr->hpof = FMT22; 566*2362Swnj } 567*2362Swnj switch (hp_type[unit]) { 568*2362Swnj case RM5: 569*2362Swnj nsect = NRMSECT; ntrak = NTRAC; sizes = rm5_sizes; break; 570*2362Swnj case RM: 571*2362Swnj nsect = NRMSECT; ntrak = NRMTRAC; sizes = rm_sizes; break; 572*2362Swnj case RP: 573*2362Swnj nsect = NSECT; ntrak = NTRAC; sizes = hp_sizes; break; 574*2362Swnj default: 575*2362Swnj printf("hp unknown type %x\n", hp_type[unit]); 576*2362Swnj return (-1); 577*2362Swnj } 578*2362Swnj if (dumplo < 0 || dumplo + num >= sizes[minor(dev)&07].nblocks) { 579*2362Swnj printf("dumplo+num, sizes %d %d\n", dumplo+num, sizes[minor(dev)&07].nblocks); 580*2362Swnj return (-1); 581*2362Swnj } 582*2362Swnj nspc = nsect * ntrak; 583*2362Swnj while (num > 0) { 584*2362Swnj register struct pte *hpte = HPPHYSMBA->mba_map; 585*2362Swnj register int i; 586*2362Swnj int cn, sn, tn; 587*2362Swnj daddr_t bn; 588*2362Swnj 589*2362Swnj blk = num > DBSIZE ? DBSIZE : num; 590*2362Swnj bn = dumplo + btop(start); 591*2362Swnj cn = bn/nspc + sizes[minor(dev)&07].cyloff; 592*2362Swnj sn = bn%nspc; 593*2362Swnj tn = sn/nsect; 594*2362Swnj sn = sn%nsect; 595*2362Swnj hpaddr->hpdc = cn; 596*2362Swnj hpaddr->hpda = (tn << 8) + sn; 597*2362Swnj for (i = 0; i < blk; i++) 598*2362Swnj *(int *)hpte++ = (btop(start)+i) | PG_V; 599*2362Swnj ((struct mba_regs *)HPPHYSMBA)->mba_sr = -1; 600*2362Swnj ((struct mba_regs *)HPPHYSMBA)->mba_bcr = -(blk*NBPG); 601*2362Swnj ((struct mba_regs *)HPPHYSMBA)->mba_var = 0; 602*2362Swnj hpaddr->hpcs1 = WCOM | GO; 603*2362Swnj while ((hpaddr->hpds & DRY) == 0) 604*2362Swnj ; 605*2362Swnj if (hpaddr->hpds&ERR) { 606*2362Swnj printf("hp dump dsk err: (%d,%d,%d) ds=%X er=%X\n", 607*2362Swnj cn, tn, sn, hpaddr->hpds, hpaddr->hper1); 608*2362Swnj return (-1); 609*2362Swnj } 610*2362Swnj start += blk*NBPG; 611*2362Swnj num -= blk; 612*2362Swnj } 613*2362Swnj return (0); 614*2362Swnj } 6151565Sbill #endif 616