|
|
1.1 root 1: /* hp.c 4.47 82/02/18 */
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+ML11
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: #include "../h/dkio.h"
38:
39: #include "../h/hpreg.h"
40:
41: /* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
42: struct size {
43: daddr_t nblocks;
44: int cyloff;
45: } hp6_sizes[8] = {
46: 15884, 0, /* A=cyl 0 thru 37 */
47: 33440, 38, /* B=cyl 38 thru 117 */
48: 340670, 0, /* C=cyl 0 thru 814 */
49: 0, 0,
50: 0, 0,
51: 0, 0,
52: #ifndef NOBADSECT
53: 291280, 118, /* G=cyl 118 thru 814 */
54: #else
55: 291346, 118,
56: #endif
57: 0, 0,
58: }, rm3_sizes[8] = {
59: 15884, 0, /* A=cyl 0 thru 99 */
60: 33440, 100, /* B=cyl 100 thru 309 */
61: 131680, 0, /* C=cyl 0 thru 822 */
62: 0, 0,
63: 0, 0,
64: 0, 0,
65: #ifndef NOBADSECT
66: 81984, 310, /* G=cyl 310 thru 822 */
67: #else
68: 82080, 310,
69: #endif
70: 0, 0,
71: }, rm5_sizes[8] = {
72: 15884, 0, /* A=cyl 0 thru 26 */
73: 33440, 27, /* B=cyl 27 thru 81 */
74: 500384, 0, /* C=cyl 0 thru 822 */
75: 15884, 562, /* D=cyl 562 thru 588 */
76: 55936, 589, /* E=cyl 589 thru 680 */
77: #ifndef NOBADSECT
78: 86240, 681, /* F=cyl 681 thru 822 */
79: 158592, 562, /* G=cyl 562 thru 822 */
80: #else
81: 86636, 681,
82: 158688, 562,
83: #endif
84: 291346, 82, /* H=cyl 82 thru 561 */
85: }, rm80_sizes[8] = {
86: 15884, 0, /* A=cyl 0 thru 36 */
87: 33440, 37, /* B=cyl 37 thru 114 */
88: 242606, 0, /* C=cyl 0 thru 558 */
89: 0, 0,
90: 0, 0,
91: 192223, 115, /* F=cyl 115 thru 558 */
92: 82080, 115, /* G=cyl 115 thru 304 */
93: 110143, 305, /* H=cyl 305 thru 558 */
94: }, mfj_sizes[8] = {
95: 10240, 0, /* A=cyl 0 thru 31 */
96: 20480, 32, /* B=cyl 32 thru 95 */
97: 232640, 96, /* C=cyl 96 thru 822 */
98: 0, 0,
99: 0, 0,
100: 0, 0,
101: 0, 0,
102: 0, 0,
103: }, eagle_sizes[8] ={
104: 27520, 0, /* A=cyl 0 thru 31 */
105: 27520, 32, /* B=cyl 32 thru 63 */
106: 667360, 64, /* C=cyl 64 thru 839 */
107: 232640, 64, /* D=cyl 64 thru 340 (partial) */
108: 232640, 341, /* E=cyl 341 thru 617 (partial) */
109: 0, 0,
110: 0, 0,
111: 0, 0,
112: /* 48 sector Emulex Eagle */
113: }, eag48_sizes[8] = { /* cyl 841 used for bad sectors + info */
114:
115: 45*960, 0, /* A = cyl 0 thru 44 for /tmp */
116: 64*960, 45, /* B = cyl 45 thru 108 for swap */
117: 842*960, 0, /* C = all cyl 0 thru 841 for testing */
118: 244*960,109, /* D = cyl 109 thru 352 nearly 1/3 */
119: 244*960,353, /* E = cyl 353 thru 596 nearly 1/3 */
120: 244*960,597, /* F = cyl 597 thru 840 nearly 1/3 */
121: 0, 0, /* G = cyl 0 thru 402 nearly 1/2 */
122: 0, 0, /* H = cyl 438 thru 840 nearly 1/2 */
123: }, hp7_sizes[8] = {
124: 15884, 0, /* A=cyl 0 thru 9 */
125: 64000, 10, /* B=cyl 10 thru 49 */
126: 1008000,0, /* C=cyl 0 thru 629 */
127: 504000, 0, /* D=cyl 0 thru 314 */
128: 504000, 315, /* E=cyl 315 thru 629 */
129: 928000, 50, /* F=cyl 50 thru 629 */
130: 0, 0,
131: 0, 0,
132: };
133: /* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
134:
135: #ifndef JONES
136: #define _hpSDIST 2
137: #define _hpRDIST 3
138: #else JONES
139: /*
140: these constants were originally 2 and 3 respectively. they
141: have been changed to improve the performance of the eagle
142: drives with the emulex controller. to date, 8,9 is better than
143: 2,3. 12,13 did not do any better than 8,9. changing these
144: constants changes the lead for all drives using the hp driver
145: including the rm80. that's a mistake, but empirically,
146: changing these to 8,9 did not measurably change rm80
147: performance.
148: */
149: #define _hpSDIST 8
150: #define _hpRDIST 9
151: #endif JONES
152:
153: int hpSDIST = _hpSDIST;
154: int hpRDIST = _hpRDIST;
155:
156: short hptypes[] =
157: { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07,
158: MBDT_FUJI, MBDT_FUJI, MBDT_FUJI, MBDT_ML11A, MBDT_ML11B, 0 };
159: struct mba_device *hpinfo[NHP];
160: int hpattach(),hpustart(),hpstart(),hpdtint();
161: struct mba_driver hpdriver =
162: { hpattach, 0, hpustart, hpstart, hpdtint, 0,
163: hptypes, "hp", 0, hpinfo };
164:
165: struct hpst {
166: short nsect;
167: short ntrak;
168: short nspc;
169: short ncyl;
170: struct size *sizes;
171: } hpst[] = {
172: 32, 5, 32*5, 823, rm3_sizes, /* RM03 */
173: 32, 19, 32*19, 823, rm5_sizes, /* RM05 */
174: 22, 19, 22*19, 815, hp6_sizes, /* RP06 */
175: 31, 14, 31*14, 559, rm80_sizes, /* RM80 */
176: 22, 19, 22*19, 411, hp6_sizes, /* RP05 */
177: 50, 32, 50*32, 630, hp7_sizes, /* RP07 */
178: /* the following three entries must be contiguous */
179: 32, 10, 32*10, 823, mfj_sizes, /* little fujitsu */
180: 43, 20, 43*20, 842, eagle_sizes, /* eagle */
181: 48, 20, 48*20, 842, eag48_sizes, /* eagle 48 sectors */
182: 1, 1, 1, 1, 0, /* ML11A */
183: 1, 1, 1, 1, 0, /* ML11B */
184: };
185:
186: u_char hp_offset[16] = {
187: HPOF_P400, HPOF_M400, HPOF_P400, HPOF_M400,
188: HPOF_P800, HPOF_M800, HPOF_P800, HPOF_M800,
189: HPOF_P1200, HPOF_M1200, HPOF_P1200, HPOF_M1200,
190: 0, 0, 0, 0,
191: };
192:
193: struct buf rhpbuf[NHP];
194: #ifndef NOBADSECT
195: struct buf bhpbuf[NHP];
196: struct dkbad hpbad[NHP];
197: #endif
198: char hpinit[NHP];
199: char hprecal[NHP];
200: char hphdr[NHP];
201: daddr_t mlsize[NHP];
202:
203: #define b_cylin b_resid
204:
205: /* #define ML11 0 to remove ML11 support */
206: #define ML11 0
207: /*#define ML11 (hptypes[mi->mi_type] == MBDT_ML11A)*/
208: #define RP06 (hptypes[mi->mi_type] <= MBDT_RP06)
209: #define RM80 (hptypes[mi->mi_type] == MBDT_RM80)
210:
211: #ifdef INTRLVE
212: daddr_t dkblock();
213: #endif
214:
215: int hpseek;
216:
217: /*ARGSUSED*/
218: hpattach(mi, slave)
219: struct mba_device *mi;
220: {
221: register struct hpst *st = &hpst[mi->mi_type];
222:
223: if (hptypes[mi->mi_type] == MBDT_ML11B)
224: mi->mi_type--; /* A CHEAT - ML11B D.T. SHOULD == ML11A */
225: if (ML11) {
226: register struct hpdevice *hpaddr =
227: (struct hpdevice *)mi->mi_drv;
228: register int trt, sz;
229:
230: sz = hpaddr->hpmr & HPMR_SZ;
231: if ((hpaddr->hpmr & HPMR_ARRTYP) == 0)
232: sz >>= 2;
233: mlsize[mi->mi_unit] = sz;
234: if (mi->mi_dk >= 0) {
235: trt = (hpaddr->hpmr & HPMR_TRT) >> 8;
236: dk_mspw[mi->mi_dk] = 1.0 / (1<<(20-trt));
237: }
238: } else if (mi->mi_dk >= 0) {
239: register struct hpdevice *hp;
240: register int type;
241:
242: hp = (struct hpdevice *) mi->mi_drv;
243: type = hp->hpdt & MBDT_TYPE;
244: if (type == MBDT_FUJI) {
245: short maxtrk, maxsect;
246: /*
247: * we have some kind of disk on an Emulex SC750.
248: * We assume it's a little Fuji, and must now check
249: * if it's an Eagle.
250: */
251: hp->hphr = HPHR_MAXTRK;
252: maxtrk = hp->hphr;
253: if (maxtrk >= hpst[mi->mi_type].ntrak) {
254: mi->mi_type++;
255: /* it's an Eagle. now check # of sectors */
256: hp->hphr = HPHR_MAXSECT;
257: maxsect = hp->hphr;
258: if (maxsect > hpst[mi->mi_type].nsect) {
259: printf("%d sectors\n", maxsect);
260: mi->mi_type++;
261: }
262: }
263: }
264: st = &hpst[mi->mi_type];
265: dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
266: }
267: }
268:
269: hpstrategy(bp)
270: register struct buf *bp;
271: {
272: register struct mba_device *mi;
273: register struct hpst *st;
274: register int unit;
275: long sz, bn;
276: int xunit = minor(bp->b_dev) & 07;
277: int s;
278:
279: sz = bp->b_bcount;
280: sz = (sz+511) >> 9;
281: unit = dkunit(bp);
282: if (unit >= NHP)
283: goto bad;
284: mi = hpinfo[unit];
285: if (mi == 0 || mi->mi_alive == 0)
286: goto bad;
287: st = &hpst[mi->mi_type];
288: if (ML11) {
289: if (bp->b_blkno < 0 || dkblock(bp)+sz > mlsize[mi->mi_unit])
290: goto bad;
291: bp->b_cylin = 0;
292: } else {
293: if (bp->b_blkno < 0 ||
294: (bn = dkblock(bp))+sz > st->sizes[xunit].nblocks)
295: goto bad;
296: bp->b_cylin = bn/st->nspc + st->sizes[xunit].cyloff;
297: }
298: s = spl5();
299: disksort(&mi->mi_tab, bp);
300: if (mi->mi_tab.b_active == 0)
301: mbustart(mi);
302: splx(s);
303: return;
304:
305: bad:
306: bp->b_flags |= B_ERROR;
307: iodone(bp);
308: return;
309: }
310:
311: hpustart(mi)
312: register struct mba_device *mi;
313: {
314: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
315: register struct buf *bp = mi->mi_tab.b_actf;
316: register struct hpst *st = &hpst[mi->mi_type];
317: daddr_t bn;
318: int sn, dist;
319:
320: hpaddr->hpcs1 = 0;
321: if ((hpaddr->hpcs1&HP_DVA) == 0)
322: return (MBU_BUSY);
323: if ((hpaddr->hpds & HPDS_VV) == 0 || hpinit[mi->mi_unit] == 0) {
324: #ifndef NOBADSECT
325: struct buf *bbp = &bhpbuf[mi->mi_unit];
326: #endif
327:
328: hpinit[mi->mi_unit] = 1;
329: hpaddr->hpcs1 = HP_DCLR|HP_GO;
330: if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive))
331: printf("DCLR attn\n");
332: hpaddr->hpcs1 = HP_PRESET|HP_GO;
333: if (!ML11)
334: hpaddr->hpof = HPOF_FMT22;
335: mbclrattn(mi);
336: #ifndef NOBADSECT
337: if (!ML11) {
338: bbp->b_flags = B_READ|B_BUSY;
339: bbp->b_dev = bp->b_dev;
340: bbp->b_bcount = 512;
341: bbp->b_un.b_addr = (caddr_t)&hpbad[mi->mi_unit];
342: bbp->b_blkno = st->ncyl*st->nspc - st->nsect;
343: bbp->b_cylin = st->ncyl - 1;
344: mi->mi_tab.b_actf = bbp;
345: bbp->av_forw = bp;
346: bp = bbp;
347: }
348: #endif
349: }
350: if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1)
351: return (MBU_DODATA);
352: if (ML11)
353: return (MBU_DODATA);
354: if ((hpaddr->hpds & HPDS_DREADY) != HPDS_DREADY)
355: return (MBU_DODATA);
356: bn = dkblock(bp);
357: sn = bn%st->nspc;
358: sn = (sn+st->nsect-hpSDIST)%st->nsect;
359: if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
360: if (hpseek)
361: return (MBU_DODATA);
362: dist = ((hpaddr->hpla & 0xffff)>>6) - st->nsect + 1;
363: if (dist < 0)
364: dist += st->nsect;
365: if (dist > st->nsect - hpRDIST)
366: return (MBU_DODATA);
367: } else
368: hpaddr->hpdc = bp->b_cylin;
369: if (hpseek)
370: hpaddr->hpcs1 = HP_SEEK|HP_GO;
371: else {
372: hpaddr->hpda = sn;
373: hpaddr->hpcs1 = HP_SEARCH|HP_GO;
374: }
375: return (MBU_STARTED);
376: }
377:
378: hpstart(mi)
379: register struct mba_device *mi;
380: {
381: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
382: register struct buf *bp = mi->mi_tab.b_actf;
383: register struct hpst *st = &hpst[mi->mi_type];
384: daddr_t bn;
385: int sn, tn;
386:
387: bn = dkblock(bp);
388: if (ML11)
389: hpaddr->hpda = bn;
390: else {
391: sn = bn%st->nspc;
392: tn = sn/st->nsect;
393: sn %= st->nsect;
394: hpaddr->hpdc = bp->b_cylin;
395: hpaddr->hpda = (tn << 8) + sn;
396: }
397: if (hphdr[mi->mi_unit]) {
398: if (bp->b_flags & B_READ)
399: return (HP_RHDR|HP_GO);
400: else
401: return (HP_WHDR|HP_GO);
402: }
403: return (0);
404: }
405:
406: hpdtint(mi, mbsr)
407: register struct mba_device *mi;
408: int mbsr;
409: {
410: register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
411: register struct buf *bp = mi->mi_tab.b_actf;
412: register int er1, er2;
413: int retry = 0;
414:
415: #ifndef NOBADSECT
416: if (bp->b_flags&B_BAD) {
417: if (hpecc(mi, CONT))
418: return(MBD_RESTARTED);
419: }
420: #endif
421: if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) {
422: #ifdef HPDEBUG
423: if (hpdebug) {
424: int dc = hpaddr->hpdc, da = hpaddr->hpda;
425: struct hpst *st = &hpst[mi->mi_type];
426:
427: printf("hperr: bp %x cyl %d blk %d as %o ",
428: bp, bp->b_cylin, bp->b_blkno,
429: hpaddr->hpas&0xff);
430: printf("dc %x da %x\n",dc&0xffff, da&0xffff);
431: printf("errcnt %d ", mi->mi_tab.b_errcnt);
432: printf("mbsr=%b ", mbsr, mbsr_bits);
433: printf("er1=%b er2=%b\n",
434: hpaddr->hper1, HPER1_BITS,
435: hpaddr->hper2, HPER2_BITS);
436: DELAY(1000000);
437: }
438: #endif
439: er1 = hpaddr->hper1;
440: er2 = hpaddr->hper2;
441: if (er1 & HPER1_HCRC) {
442: er1 &= ~(HPER1_HCE|HPER1_FER);
443: er2 &= ~HPER2_BSE;
444: }
445: if (er1&HPER1_WLE) {
446: printf("hp%d: write locked\n", dkunit(bp));
447: bp->b_flags |= B_ERROR;
448: } else if ((er1&0xffff) == HPER1_FER && RP06 &&
449: hphdr[mi->mi_unit] == 0) {
450: #ifndef NOBADSECT
451: if (hpecc(mi, BSE))
452: {
453: #ifdef HPBDEBUG
454: if (hpdebug)
455: printf("MBD_RESTARTED\n");
456: #endif
457: return(MBD_RESTARTED);
458: }
459: else
460: #endif
461: goto hard;
462: } else if (++mi->mi_tab.b_errcnt > 27 ||
463: mbsr & MBSR_HARD ||
464: er1 & HPER1_HARD ||
465: hphdr[mi->mi_unit] ||
466: (!ML11 && (er2 & HPER2_HARD))) {
467: hard:
468: harderr(bp, "hp");
469: if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC)))
470: printf("mbsr=%b ", mbsr, mbsr_bits);
471: printf("er1=%b er2=%b",
472: hpaddr->hper1, HPER1_BITS,
473: hpaddr->hper2, HPER2_BITS);
474: if (hpaddr->hpmr)
475: printf(" mr=%o", hpaddr->hpmr&0xffff);
476: if (hpaddr->hpmr2)
477: printf(" mr2=%o", hpaddr->hpmr2&0xffff);
478: printf("\n");
479: bp->b_flags |= B_ERROR;
480: hprecal[mi->mi_unit] = 0;
481: } else if ((er2 & HPER2_BSE) && !ML11) {
482: #ifndef NOBADSECT
483: if (hpecc(mi, BSE))
484: return(MBD_RESTARTED);
485: else
486: #endif
487: goto hard;
488: } else if (RM80 && er2&HPER2_SSE) {
489: (void) hpecc(mi, SSE);
490: return (MBD_RESTARTED);
491: } else if ((er1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) {
492: if (hpecc(mi, ECC))
493: return (MBD_RESTARTED);
494: /* else done */
495: } else
496: retry = 1;
497: hpaddr->hpcs1 = HP_DCLR|HP_GO;
498: if (ML11) {
499: if (mi->mi_tab.b_errcnt >= 16)
500: goto hard;
501: } else if ((mi->mi_tab.b_errcnt&07) == 4) {
502: hpaddr->hpcs1 = HP_RECAL|HP_GO;
503: hprecal[mi->mi_unit] = 1;
504: return(MBD_RESTARTED);
505: }
506: if (retry)
507: return (MBD_RETRY);
508: }
509: #ifdef HPDEBUG
510: else
511: if (hpdebug && hprecal[mi->mi_unit]) {
512: printf("recal %d ", hprecal[mi->mi_unit]);
513: printf("errcnt %d\n", mi->mi_tab.b_errcnt);
514: printf("mbsr=%b ", mbsr, mbsr_bits);
515: printf("er1=%b er2=%b\n",
516: hpaddr->hper1, HPER1_BITS,
517: hpaddr->hper2, HPER2_BITS);
518: }
519: #endif
520: switch (hprecal[mi->mi_unit]) {
521:
522: case 1:
523: hpaddr->hpdc = bp->b_cylin;
524: hpaddr->hpcs1 = HP_SEEK|HP_GO;
525: hprecal[mi->mi_unit]++;
526: return (MBD_RESTARTED);
527: case 2:
528: if (mi->mi_tab.b_errcnt < 16 ||
529: (bp->b_flags & B_READ) == 0)
530: goto donerecal;
531: hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;
532: hpaddr->hpcs1 = HP_OFFSET|HP_GO;
533: hprecal[mi->mi_unit]++;
534: return (MBD_RESTARTED);
535: donerecal:
536: case 3:
537: hprecal[mi->mi_unit] = 0;
538: return (MBD_RETRY);
539: }
540: hphdr[mi->mi_unit] = 0;
541: bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
542: if (mi->mi_tab.b_errcnt >= 16) {
543: /*
544: * This is fast and occurs rarely; we don't
545: * bother with interrupts.
546: */
547: hpaddr->hpcs1 = HP_RTC|HP_GO;
548: while (hpaddr->hpds & HPDS_PIP)
549: ;
550: mbclrattn(mi);
551: }
552: if (!ML11) {
553: hpaddr->hpof = HPOF_FMT22;
554: hpaddr->hpcs1 = HP_RELEASE|HP_GO;
555: }
556: return (MBD_DONE);
557: }
558:
559: hpread(dev)
560: dev_t dev;
561: {
562: register int unit = minor(dev) >> 3;
563:
564: if (unit >= NHP)
565: u.u_error = ENXIO;
566: else
567: physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys);
568: }
569:
570: hpwrite(dev)
571: dev_t dev;
572: {
573: register int unit = minor(dev) >> 3;
574:
575: if (unit >= NHP)
576: u.u_error = ENXIO;
577: else
578: physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys);
579: }
580:
581: /*ARGSUSED*/
582: hpioctl(dev, cmd, addr, flag)
583: dev_t dev;
584: int cmd;
585: caddr_t addr;
586: int flag;
587: {
588:
589: switch (cmd) {
590: case DKIOCHDR: /* do header read/write */
591: if (suser())
592: hphdr[minor(dev)>>3] = 1;
593: return;
594:
595: default:
596: u.u_error = ENXIO;
597: }
598: }
599:
600: hpecc(mi, flag)
601: register struct mba_device *mi;
602: int flag;
603: {
604: register struct mba_regs *mbp = mi->mi_mba;
605: register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;
606: register struct buf *bp = mi->mi_tab.b_actf;
607: register struct hpst *st = &hpst[mi->mi_type];
608: int npf, o;
609: int bn, cn, tn, sn;
610: int bcr;
611: static nerr;
612:
613: bcr = mbp->mba_bcr & 0xffff;
614: if (bcr)
615: bcr |= 0xffff0000; /* sxt */
616: #ifndef NOBADSECT
617: if (flag == CONT)
618: npf = bp->b_error;
619: else
620: #endif
621: npf = btop(bcr + bp->b_bcount);
622: o = (int)bp->b_un.b_addr & PGOFSET;
623: bn = dkblock(bp);
624: #ifdef HPBDEBUG
625: if (hpbdebug)
626: printf("hpecc: mbp->mba_bcr %x bcr %x bp->b_bcount %x bp->b_error %x bn %x npf %x\n",
627: mbp->mba_bcr, bcr, bp->b_bcount, bp->b_error, bn, npf);
628: if (hpbdebug)
629: printf("ber npf: %x\n", ((rp->hpdc & 0xffff) * (st->nspc))
630: + ((((rp->hpda) >> 8) & 0xff) * st->nsect)
631: + ((rp->hpda) & 0xff)
632: - (((st->sizes[minor(bp->b_dev)&07].cyloff) * st->nspc)
633: + 1 + bn));
634: #endif
635: cn = bp->b_cylin;
636: sn = bn%(st->nspc) + npf;
637: tn = sn/st->nsect;
638: sn %= st->nsect;
639: cn += tn/st->ntrak;
640: tn %= st->ntrak;
641: switch (flag) {
642: case ECC:
643: {
644: register int i;
645: caddr_t addr;
646: struct pte mpte;
647: int bit, byte, mask;
648:
649: npf--; /* because block in error is previous block */
650: printf("hp%d%c: soft ecc sn%d\n", dkunit(bp),
651: 'a'+(minor(bp->b_dev)&07), bp->b_blkno + npf);
652: nerr++;
653: if ((nerr%100)==0)
654: printf("%d soft errors\n", nerr);
655: mask = rp->hpec2&0xffff;
656: i = (rp->hpec1&0xffff) - 1; /* -1 makes 0 origin */
657: bit = i&07;
658: i = (i&~07)>>3;
659: byte = i + o;
660: while (i < 512 && (int)ptob(npf)+i < bp->b_bcount && bit > -11) {
661: mpte = mbp->mba_map[npf+btop(byte)];
662: addr = ptob(mpte.pg_pfnum) + (byte & PGOFSET);
663: putmemc(addr, getmemc(addr)^(mask<<bit));
664: byte++;
665: i++;
666: bit -= 8;
667: }
668: if (bcr == 0)
669: return (0);
670: npf++;
671: break;
672: }
673:
674: case SSE:
675: #ifdef HPBDEBUG
676: if (hpbdebug)
677: printf("hpeccSSE\n");
678: #endif
679: rp->hpof |= HPOF_SSEI;
680: mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
681: break;
682:
683: #ifndef NOBADSECT
684: case BSE:
685: #ifdef HPBDEBUG
686: if (hpbdebug)
687: printf("hpeccBSE: bn %d cn %d tn %d sn %d\n", bn, cn, tn, sn);
688: #endif
689: if ((bn = isbad(&hpbad[mi->mi_unit], cn, tn, sn)) < 0)
690: return(0);
691: bp->b_flags |= B_BAD;
692: bp->b_error = npf + 1;
693: bn = st->ncyl*st->nspc - st->nsect - 1 - bn;
694: cn = bn/st->nspc;
695: sn = bn%st->nspc;
696: tn = sn/st->nsect;
697: sn %= st->nsect;
698: mbp->mba_bcr = -512;
699: #ifdef HPBDEBUG
700: if (hpbdebug)
701: printf("revector to cn %d tn %d sn %d\n", cn, tn, sn);
702: #endif
703: break;
704:
705: case CONT:
706: #ifdef HPBDEBUG
707: if (hpbdebug)
708: printf("hpecc, CONT: bn %d cn %d tn %d sn %d\n", bn,cn,tn,sn);
709: #endif
710: npf = bp->b_error;
711: bp->b_flags &= ~B_BAD;
712: mbp->mba_bcr = -(bp->b_bcount - (int)ptob(npf));
713: if ((mbp->mba_bcr & 0xffff) == 0)
714: return(0);
715: break;
716: #endif
717: }
718: #ifdef HPBDEBUG
719: if (hpbdebug)
720: printf("hpecc, endcase: bn %d\n",bn);
721: #endif
722: rp->hpcs1 = HP_DCLR|HP_GO;
723: if (rp->hpof&HPOF_SSEI)
724: sn++;
725: rp->hpdc = cn;
726: rp->hpda = (tn<<8) + sn;
727: mbp->mba_sr = -1;
728: mbp->mba_var = (int)ptob(npf) + o;
729: rp->hpcs1 = bp->b_flags&B_READ ? HP_RCOM|HP_GO : HP_WCOM|HP_GO;
730: mi->mi_tab.b_errcnt = 0; /* error has been corrected */
731: return (1);
732: }
733:
734: #define DBSIZE 20
735:
736: hpdump(dev)
737: dev_t dev;
738: {
739: register struct mba_device *mi;
740: register struct mba_regs *mba;
741: struct hpdevice *hpaddr;
742: char *start;
743: int num, unit;
744: register struct hpst *st;
745:
746: num = maxfree;
747: start = 0;
748: unit = minor(dev) >> 3;
749: if (unit >= NHP)
750: return (ENXIO);
751: #define phys(a,b) ((b)((int)(a)&0x7fffffff))
752: mi = phys(hpinfo[unit],struct mba_device *);
753: if (mi == 0 || mi->mi_alive == 0)
754: return (ENXIO);
755: mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
756: mba->mba_cr = MBCR_INIT;
757: hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
758: if ((hpaddr->hpds & HPDS_VV) == 0) {
759: hpaddr->hpcs1 = HP_DCLR|HP_GO;
760: hpaddr->hpcs1 = HP_PRESET|HP_GO;
761: hpaddr->hpof = HPOF_FMT22;
762: }
763: st = &hpst[mi->mi_type];
764: if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks)
765: return (EINVAL);
766: while (num > 0) {
767: register struct pte *hpte = mba->mba_map;
768: register int i;
769: int blk, cn, sn, tn;
770: daddr_t bn;
771:
772: blk = num > DBSIZE ? DBSIZE : num;
773: bn = dumplo + btop(start);
774: cn = bn/st->nspc + st->sizes[minor(dev)&07].cyloff;
775: sn = bn%st->nspc;
776: tn = sn/st->nsect;
777: sn = sn%st->nsect;
778: hpaddr->hpdc = cn;
779: hpaddr->hpda = (tn << 8) + sn;
780: for (i = 0; i < blk; i++)
781: *(int *)hpte++ = (btop(start)+i) | PG_V;
782: mba->mba_sr = -1;
783: mba->mba_bcr = -(blk*NBPG);
784: mba->mba_var = 0;
785: hpaddr->hpcs1 = HP_WCOM | HP_GO;
786: while ((hpaddr->hpds & HPDS_DRY) == 0)
787: ;
788: if (hpaddr->hpds&HPDS_ERR)
789: return (EIO);
790: start += blk*NBPG;
791: num -= blk;
792: }
793: return (0);
794: }
795: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.