lint
[unix-history] / usr / src / sys / vax / mba / hp.c
CommitLineData
89b8a44c 1/* hp.c 4.42 81/11/18 */
b70e4030
BJ
2
3#ifdef HPDEBUG
6ac24ecd 4int hpdebug;
b70e4030
BJ
5#endif
6#ifdef HPBDEBUG
7int hpbdebug;
8#endif
04b9d53d 9
66b4fb09 10#include "hp.h"
a5cc519e 11#if NHP > 0
04b9d53d 12/*
b70e4030 13 * HP disk driver for RP0x+RMxx
1b81ee79
BJ
14 *
15 * TODO:
b70e4030 16 * check RM80 skip sector handling when ECC's occur later
d565635a 17 * check offset recovery handling
b70e4030
BJ
18 * see if DCLR and/or RELEASE set attention status
19 * print bits of mr && mr2 symbolically
04b9d53d
BJ
20 */
21
22#include "../h/param.h"
23#include "../h/systm.h"
41888f16 24#include "../h/dk.h"
04b9d53d
BJ
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"
80e7c811 30#include "../h/pte.h"
4a4e3072
BJ
31#include "../h/mbareg.h"
32#include "../h/mbavar.h"
04b9d53d 33#include "../h/mtpr.h"
80e7c811 34#include "../h/vm.h"
e3b4b145 35#include "../h/cmap.h"
b70e4030 36#include "../h/dkbad.h"
04b9d53d 37
b81fd3e8 38#include "../h/hpreg.h"
04b9d53d 39
b81fd3e8
BJ
40/* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
41struct size {
04b9d53d
BJ
42 daddr_t nblocks;
43 int cyloff;
b70e4030 44} hp6_sizes[8] = {
5c777efe
BJ
45 15884, 0, /* A=cyl 0 thru 37 */
46 33440, 38, /* B=cyl 38 thru 117 */
47 340670, 0, /* C=cyl 0 thru 814 */
04b9d53d 48 0, 0,
04b9d53d
BJ
49 0, 0,
50 0, 0,
616c2a83 51#ifndef NOBADSECT
e897671e 52 291280, 118, /* G=cyl 118 thru 814 */
b70e4030
BJ
53#else
54 291346, 118,
55#endif
04b9d53d 56 0, 0,
b70e4030 57}, rm3_sizes[8] = {
5c777efe
BJ
58 15884, 0, /* A=cyl 0 thru 99 */
59 33440, 100, /* B=cyl 100 thru 309 */
60 131680, 0, /* C=cyl 0 thru 822 */
6edc8b46 61 0, 0,
04b9d53d
BJ
62 0, 0,
63 0, 0,
616c2a83 64#ifndef NOBADSECT
e897671e 65 81984, 310, /* G=cyl 310 thru 822 */
b70e4030
BJ
66#else
67 82080, 310,
68#endif
04b9d53d 69 0, 0,
5c777efe
BJ
70}, rm5_sizes[8] = {
71 15884, 0, /* A=cyl 0 thru 26 */
72 33440, 27, /* B=cyl 27 thru 81 */
e83ccfd7 73 500384, 0, /* C=cyl 0 thru 822 */
5c777efe
BJ
74 15884, 562, /* D=cyl 562 thru 588 */
75 55936, 589, /* E=cyl 589 thru 680 */
616c2a83 76#ifndef NOBADSECT
e897671e
BJ
77 86240, 681, /* F=cyl 681 thru 822 */
78 158592, 562, /* G=cyl 562 thru 822 */
b70e4030
BJ
79#else
80 86636, 681,
81 158688, 562,
82#endif
5c777efe 83 291346, 82, /* H=cyl 82 thru 561 */
b81fd3e8
BJ
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 */
e897671e 92 110143, 305, /* H=cyl 305 thru 558 */
b70e4030
BJ
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 */
e897671e
BJ
99 207850, 500, /* F=cyl 500 thru 629 */
100 479850, 330, /* G=cyl 330 thru 629 */
b70e4030 101 448000, 50, /* H=cyl 50 thru 329 */
04b9d53d 102};
b81fd3e8 103/* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
04b9d53d 104
b81fd3e8
BJ
105#define _hpSDIST 2
106#define _hpRDIST 3
107
108int hpSDIST = _hpSDIST;
109int hpRDIST = _hpRDIST;
110
111short hptypes[] =
b70e4030 112 { MBDT_RM03, MBDT_RM05, MBDT_RP06, MBDT_RM80, MBDT_RP05, MBDT_RP07, 0 };
4a4e3072
BJ
113struct mba_device *hpinfo[NHP];
114int hpattach(),hpustart(),hpstart(),hpdtint();
b81fd3e8 115struct mba_driver hpdriver =
4a4e3072
BJ
116 { hpattach, 0, hpustart, hpstart, hpdtint, 0,
117 hptypes, "hp", 0, hpinfo };
b81fd3e8
BJ
118
119struct hpst {
120 short nsect;
121 short ntrak;
122 short nspc;
123 short ncyl;
124 struct size *sizes;
125} hpst[] = {
b70e4030 126 32, 5, 32*5, 823, rm3_sizes, /* RM03 */
b81fd3e8 127 32, 19, 32*19, 823, rm5_sizes, /* RM05 */
b70e4030
BJ
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 */
b81fd3e8
BJ
132};
133
804f6eab 134u_char hp_offset[16] = {
d565635a
BJ
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,
04b9d53d
BJ
139};
140
804f6eab 141struct buf rhpbuf[NHP];
616c2a83 142#ifndef NOBADSECT
b70e4030
BJ
143struct buf bhpbuf[NHP];
144struct dkbad hpbad[NHP];
145#endif
146char hpinit[NHP];
3dbaa9da 147char hprecal[NHP];
04b9d53d
BJ
148
149#define b_cylin b_resid
150
151#ifdef INTRLVE
152daddr_t dkblock();
153#endif
154
71236e46
BJ
155int hpseek;
156
4a4e3072
BJ
157/*ARGSUSED*/
158hpattach(mi, slave)
159 struct mba_device *mi;
71236e46
BJ
160{
161 register struct hpst *st = &hpst[mi->mi_type];
162
163 if (mi->mi_dk >= 0)
7780575a 164 dk_mspw[mi->mi_dk] = 1.0 / 60 / (st->nsect * 256);
71236e46
BJ
165}
166
04b9d53d 167hpstrategy(bp)
b81fd3e8 168 register struct buf *bp;
04b9d53d 169{
4a4e3072 170 register struct mba_device *mi;
b81fd3e8
BJ
171 register struct hpst *st;
172 register int unit;
04b9d53d 173 long sz, bn;
b81fd3e8 174 int xunit = minor(bp->b_dev) & 07;
04b9d53d 175
04b9d53d
BJ
176 sz = bp->b_bcount;
177 sz = (sz+511) >> 9;
178 unit = dkunit(bp);
b81fd3e8
BJ
179 if (unit >= NHP)
180 goto bad;
181 mi = hpinfo[unit];
3f3a34c3 182 if (mi == 0 || mi->mi_alive == 0)
b81fd3e8
BJ
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;
81263dba 189 (void) spl5();
b81fd3e8
BJ
190 disksort(&mi->mi_tab, bp);
191 if (mi->mi_tab.b_active == 0)
192 mbustart(mi);
81263dba 193 (void) spl0();
b81fd3e8
BJ
194 return;
195
196bad:
197 bp->b_flags |= B_ERROR;
198 iodone(bp);
199 return;
04b9d53d
BJ
200}
201
b81fd3e8 202hpustart(mi)
4a4e3072 203 register struct mba_device *mi;
04b9d53d 204{
804f6eab 205 register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
b81fd3e8 206 register struct buf *bp = mi->mi_tab.b_actf;
b70e4030 207 register struct hpst *st = &hpst[mi->mi_type];
04b9d53d 208 daddr_t bn;
a0eab615 209 int sn, dist;
04b9d53d 210
b70e4030 211 hpaddr->hpcs1 = 0;
804f6eab 212 if ((hpaddr->hpcs1&HP_DVA) == 0)
b81fd3e8 213 return (MBU_BUSY);
b70e4030 214 if ((hpaddr->hpds & HPDS_VV) == 0 || hpinit[mi->mi_unit] == 0) {
616c2a83 215#ifndef NOBADSECT
b70e4030
BJ
216 struct buf *bbp = &bhpbuf[mi->mi_unit];
217#endif
218
219 hpinit[mi->mi_unit] = 1;
804f6eab 220 hpaddr->hpcs1 = HP_DCLR|HP_GO;
27a897a2
BJ
221 if (mi->mi_mba->mba_drv[0].mbd_as & (1<<mi->mi_drive))
222 printf("DCLR attn\n");
804f6eab 223 hpaddr->hpcs1 = HP_PRESET|HP_GO;
d565635a 224 hpaddr->hpof = HPOF_FMT22;
27a897a2 225 mbclrattn(mi);
616c2a83 226#ifndef NOBADSECT
b70e4030
BJ
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
04b9d53d 237 }
71236e46 238 if (mi->mi_tab.b_active || mi->mi_hd->mh_ndrive == 1)
b81fd3e8 239 return (MBU_DODATA);
d565635a 240 if ((hpaddr->hpds & HPDS_DREADY) != HPDS_DREADY)
b81fd3e8 241 return (MBU_DODATA);
3f3a34c3
BJ
242 bn = dkblock(bp);
243 sn = bn%st->nspc;
244 sn = (sn+st->nsect-hpSDIST)%st->nsect;
b81fd3e8 245 if (bp->b_cylin == (hpaddr->hpdc & 0xffff)) {
71236e46 246 if (hpseek)
b81fd3e8 247 return (MBU_DODATA);
b81fd3e8
BJ
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);
0801d37f
BJ
253 } else
254 hpaddr->hpdc = bp->b_cylin;
71236e46 255 if (hpseek)
804f6eab 256 hpaddr->hpcs1 = HP_SEEK|HP_GO;
41888f16
BJ
257 else {
258 hpaddr->hpda = sn;
804f6eab 259 hpaddr->hpcs1 = HP_SEARCH|HP_GO;
41888f16 260 }
b81fd3e8 261 return (MBU_STARTED);
04b9d53d
BJ
262}
263
b81fd3e8 264hpstart(mi)
4a4e3072 265 register struct mba_device *mi;
04b9d53d 266{
804f6eab 267 register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
b81fd3e8
BJ
268 register struct buf *bp = mi->mi_tab.b_actf;
269 register struct hpst *st = &hpst[mi->mi_type];
04b9d53d 270 daddr_t bn;
b81fd3e8 271 int sn, tn;
04b9d53d 272
04b9d53d 273 bn = dkblock(bp);
b81fd3e8
BJ
274 sn = bn%st->nspc;
275 tn = sn/st->nsect;
3f3a34c3 276 sn %= st->nsect;
b81fd3e8 277 hpaddr->hpdc = bp->b_cylin;
04b9d53d 278 hpaddr->hpda = (tn << 8) + sn;
b70e4030 279 return(0);
04b9d53d
BJ
280}
281
a0eab615 282hpdtint(mi, mbsr)
4a4e3072 283 register struct mba_device *mi;
a0eab615 284 int mbsr;
04b9d53d 285{
804f6eab 286 register struct hpdevice *hpaddr = (struct hpdevice *)mi->mi_drv;
b81fd3e8 287 register struct buf *bp = mi->mi_tab.b_actf;
e34bc1ef 288 int retry = 0;
b81fd3e8 289
616c2a83 290#ifndef NOBADSECT
b70e4030
BJ
291 if (bp->b_flags&B_BAD) {
292 if (hpecc(mi, CONT))
293 return(MBD_RESTARTED);
294 }
295#endif
a0eab615 296 if (hpaddr->hpds&HPDS_ERR || mbsr&MBSR_EBITS) {
b70e4030 297#ifdef HPDEBUG
6ac24ecd 298 if (hpdebug) {
b70e4030
BJ
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);
6ac24ecd
BJ
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 }
b70e4030 312#endif
d565635a 313 if (hpaddr->hper1&HPER1_WLE) {
fd2cb420 314 printf("hp%d: write locked\n", dkunit(bp));
e34bc1ef
BJ
315 bp->b_flags |= B_ERROR;
316 } else if (++mi->mi_tab.b_errcnt > 27 ||
a0eab615 317 mbsr & MBSR_HARD ||
e34bc1ef
BJ
318 hpaddr->hper1 & HPER1_HARD ||
319 hpaddr->hper2 & HPER2_HARD) {
b70e4030 320hard:
fd2cb420 321 harderr(bp, "hp");
e83ccfd7
BJ
322 if (mbsr & (MBSR_EBITS &~ (MBSR_DTABT|MBSR_MBEXC)))
323 printf("mbsr=%b ", mbsr, mbsr_bits);
b70e4030 324 printf("er1=%b er2=%b",
e34bc1ef
BJ
325 hpaddr->hper1, HPER1_BITS,
326 hpaddr->hper2, HPER2_BITS);
b70e4030
BJ
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");
b81fd3e8 332 bp->b_flags |= B_ERROR;
ec737306 333 hprecal[mi->mi_unit] = 0;
b70e4030 334 } else if (hpaddr->hper2 & HPER2_BSE) {
616c2a83 335#ifndef NOBADSECT
b70e4030
BJ
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) {
b620b354 343 (void) hpecc(mi, SSE);
c9e9b65b 344 return (MBD_RESTARTED);
d565635a 345 } else if ((hpaddr->hper1&(HPER1_DCK|HPER1_ECH))==HPER1_DCK) {
b70e4030 346 if (hpecc(mi, ECC))
e34bc1ef
BJ
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;
b70e4030
BJ
354 hprecal[mi->mi_unit] = 1;
355 return(MBD_RESTARTED);
04b9d53d 356 }
e34bc1ef
BJ
357 if (retry)
358 return (MBD_RETRY);
359 }
b70e4030 360#ifdef HPDEBUG
6ac24ecd
BJ
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 }
b70e4030 370#endif
d565635a
BJ
371 switch (hprecal[mi->mi_unit]) {
372
373 case 1:
374 hpaddr->hpdc = bp->b_cylin;
375 hpaddr->hpcs1 = HP_SEEK|HP_GO;
b70e4030
BJ
376 hprecal[mi->mi_unit]++;
377 return (MBD_RESTARTED);
d565635a
BJ
378 case 2:
379 if (mi->mi_tab.b_errcnt < 16 ||
6ac24ecd 380 (bp->b_flags & B_READ) == 0)
d565635a
BJ
381 goto donerecal;
382 hpaddr->hpof = hp_offset[mi->mi_tab.b_errcnt & 017]|HPOF_FMT22;
383 hpaddr->hpcs1 = HP_OFFSET|HP_GO;
d565635a
BJ
384 hprecal[mi->mi_unit]++;
385 return (MBD_RESTARTED);
386 donerecal:
a6442a2f 387 case 3:
3dbaa9da
BJ
388 hprecal[mi->mi_unit] = 0;
389 return (MBD_RETRY);
390 }
b81fd3e8 391 bp->b_resid = -(mi->mi_mba->mba_bcr) & 0xffff;
aeecd470 392 if (mi->mi_tab.b_errcnt >= 16) {
d565635a
BJ
393 /*
394 * This is fast and occurs rarely; we don't
395 * bother with interrupts.
396 */
804f6eab 397 hpaddr->hpcs1 = HP_RTC|HP_GO;
d565635a 398 while (hpaddr->hpds & HPDS_PIP)
b81fd3e8
BJ
399 ;
400 mbclrattn(mi);
04b9d53d 401 }
8eb99b75 402 hpaddr->hpof = HPOF_FMT22;
b70e4030 403 hpaddr->hpcs1 = HP_RELEASE|HP_GO;
b81fd3e8 404 return (MBD_DONE);
04b9d53d
BJ
405}
406
407hpread(dev)
804f6eab 408 dev_t dev;
04b9d53d 409{
804f6eab 410 register int unit = minor(dev) >> 3;
04b9d53d 411
804f6eab
BJ
412 if (unit >= NHP)
413 u.u_error = ENXIO;
414 else
415 physio(hpstrategy, &rhpbuf[unit], dev, B_READ, minphys);
04b9d53d
BJ
416}
417
418hpwrite(dev)
804f6eab 419 dev_t dev;
04b9d53d 420{
804f6eab 421 register int unit = minor(dev) >> 3;
04b9d53d 422
804f6eab
BJ
423 if (unit >= NHP)
424 u.u_error = ENXIO;
425 else
426 physio(hpstrategy, &rhpbuf[unit], dev, B_WRITE, minphys);
04b9d53d
BJ
427}
428
b70e4030 429hpecc(mi, flag)
4a4e3072 430 register struct mba_device *mi;
b70e4030 431 int flag;
04b9d53d 432{
b81fd3e8 433 register struct mba_regs *mbp = mi->mi_mba;
804f6eab 434 register struct hpdevice *rp = (struct hpdevice *)mi->mi_drv;
b81fd3e8 435 register struct buf *bp = mi->mi_tab.b_actf;
b70e4030
BJ
436 register struct hpst *st = &hpst[mi->mi_type];
437 int npf, o;
b81fd3e8 438 int bn, cn, tn, sn;
fa1d69d6 439 int bcr;
80e7c811 440
fa1d69d6
BJ
441 bcr = mbp->mba_bcr & 0xffff;
442 if (bcr)
443 bcr |= 0xffff0000; /* sxt */
616c2a83 444#ifndef NOBADSECT
b70e4030
BJ
445 if (flag == CONT)
446 npf = bp->b_error;
447 else
448#endif
449 npf = btop(bcr + bp->b_bcount);
80e7c811 450 o = (int)bp->b_un.b_addr & PGOFSET;
80e7c811 451 bn = dkblock(bp);
80e7c811 452 cn = bp->b_cylin;
b70e4030 453 sn = bn%(st->nspc) + npf;
b81fd3e8
BJ
454 tn = sn/st->nsect;
455 sn %= st->nsect;
456 cn += tn/st->ntrak;
457 tn %= st->ntrak;
b70e4030
BJ
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);
089adc9d 484 npf++;
b70e4030
BJ
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
616c2a83 493#ifndef NOBADSECT
b70e4030
BJ
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;
8eb99b75 529 if (rp->hpof&HPOF_SSEI)
c9e9b65b 530 sn++;
80e7c811
BJ
531 rp->hpdc = cn;
532 rp->hpda = (tn<<8) + sn;
533 mbp->mba_sr = -1;
b70e4030
BJ
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 */
80e7c811 537 return (1);
04b9d53d 538}
e3b4b145
BJ
539
540#define DBSIZE 20
541
542hpdump(dev)
543 dev_t dev;
544{
4a4e3072 545 register struct mba_device *mi;
b81fd3e8 546 register struct mba_regs *mba;
804f6eab 547 struct hpdevice *hpaddr;
e3b4b145 548 char *start;
b81fd3e8
BJ
549 int num, unit;
550 register struct hpst *st;
e3b4b145
BJ
551
552 num = maxfree;
553 start = 0;
554 unit = minor(dev) >> 3;
1b81ee79
BJ
555 if (unit >= NHP)
556 return (ENXIO);
b81fd3e8 557#define phys(a,b) ((b)((int)(a)&0x7fffffff))
4a4e3072 558 mi = phys(hpinfo[unit],struct mba_device *);
1b81ee79
BJ
559 if (mi == 0 || mi->mi_alive == 0)
560 return (ENXIO);
b81fd3e8 561 mba = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
a0eab615 562 mba->mba_cr = MBCR_INIT;
804f6eab 563 hpaddr = (struct hpdevice *)&mba->mba_drv[mi->mi_drive];
d565635a 564 if ((hpaddr->hpds & HPDS_VV) == 0) {
804f6eab
BJ
565 hpaddr->hpcs1 = HP_DCLR|HP_GO;
566 hpaddr->hpcs1 = HP_PRESET|HP_GO;
d565635a 567 hpaddr->hpof = HPOF_FMT22;
e3b4b145 568 }
b81fd3e8 569 st = &hpst[mi->mi_type];
1b81ee79
BJ
570 if (dumplo < 0 || dumplo + num >= st->sizes[minor(dev)&07].nblocks)
571 return (EINVAL);
e3b4b145 572 while (num > 0) {
b81fd3e8 573 register struct pte *hpte = mba->mba_map;
e3b4b145 574 register int i;
b81fd3e8 575 int blk, cn, sn, tn;
e3b4b145
BJ
576 daddr_t bn;
577
578 blk = num > DBSIZE ? DBSIZE : num;
579 bn = dumplo + btop(start);
b81fd3e8
BJ
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;
e3b4b145
BJ
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;
b81fd3e8
BJ
588 mba->mba_sr = -1;
589 mba->mba_bcr = -(blk*NBPG);
590 mba->mba_var = 0;
804f6eab 591 hpaddr->hpcs1 = HP_WCOM | HP_GO;
d565635a 592 while ((hpaddr->hpds & HPDS_DRY) == 0)
e3b4b145 593 ;
d565635a 594 if (hpaddr->hpds&HPDS_ERR)
1b81ee79 595 return (EIO);
e3b4b145
BJ
596 start += blk*NBPG;
597 num -= blk;
598 }
599 return (0);
600}
a5cc519e 601#endif