/* THIS SHOULD BE READ OFF THE PACK, PER DRIVE */
15884, 0, /* A=cyl 0 thru 37 */
33440, 38, /* B=cyl 38 thru 117 */
340670, 0, /* C=cyl 0 thru 814 */
291346, 118, /* G=cyl 118 thru 814 */
15884, 0, /* A=cyl 0 thru 99 */
33440, 100, /* B=cyl 100 thru 309 */
131680, 0, /* C=cyl 0 thru 822 */
82080, 310, /* G=cyl 310 thru 822 */
15884, 0, /* A=cyl 0 thru 26 */
33440, 27, /* B=cyl 27 thru 81 */
500992, 0, /* C=cyl 0 thru 823 */
15884, 562, /* D=cyl 562 thru 588 */
55936, 589, /* E=cyl 589 thru 680 */
86944, 681, /* F=cyl 681 thru 823 */
159296, 562, /* G=cyl 562 thru 823 */
291346, 82, /* H=cyl 82 thru 561 */
15884, 0, /* A=cyl 0 thru 36 */
33440, 37, /* B=cyl 37 thru 114 */
242606, 0, /* C=cyl 0 thru 558 */
82080, 115, /* G=cyl 115 thru 304 */
110236, 305, /* H=cyl 305 thru 558 */
/* END OF STUFF WHICH SHOULD BE READ IN PER DISK */
{ MBDT_RM03
, MBDT_RM05
, MBDT_RP06
, MBDT_RM80
, 0 };
struct mba_info
*hpinfo
[NHP
];
int hpdkinit(),hpustart(),hpstart(),hpdtint();
struct mba_driver hpdriver
=
{ hpdkinit
, hpustart
, hpstart
, hpdtint
, 0, hptypes
, hpinfo
};
32, 5, 32*5, 823, rm_sizes
, /* RM03 */
32, 19, 32*19, 823, rm5_sizes
, /* RM05 */
22, 19, 22*19, 815, hp_sizes
, /* RP06 */
31, 14, 31*14, 559, rm80_sizes
/* RM80 */
P1200
, M1200
, P1200
, M1200
,
register struct mba_info
*mi
;
register struct hpst
*st
;
int xunit
= minor(bp
->b_dev
) & 07;
(bn
= dkblock(bp
))+sz
> st
->sizes
[xunit
].nblocks
)
bp
->b_cylin
= bn
/st
->nspc
+ st
->sizes
[xunit
].cyloff
;
disksort(&mi
->mi_tab
, bp
);
if (mi
->mi_tab
.b_active
== 0)
register struct mba_info
*mi
;
register struct device
*hpaddr
= (struct device
*)mi
->mi_drv
;
register struct buf
*bp
= mi
->mi_tab
.b_actf
;
register struct hpst
*st
;
if ((hpaddr
->hpcs1
&DVA
) == 0)
if ((hpaddr
->hpds
& VV
) == 0) {
hpaddr
->hpcs1
= PRESET
|GO
;
if ((hpaddr
->hpds
& (DPR
|MOL
)) != (DPR
|MOL
))
hpaddr
->hpdc
= bp
->b_cylin
;
flags
= mi
->mi_hd
->mh_flags
;
if (bp
->b_cylin
== (hpaddr
->hpdc
& 0xffff)) {
sn
= (sn
+st
->nsect
-hpSDIST
)%st
->nsect
;
dist
= ((hpaddr
->hpla
& 0xffff)>>6) - st
->nsect
+ 1;
if (dist
> st
->nsect
- hpRDIST
)
hpaddr
->hpcs1
= SEARCH
|GO
;
register struct mba_info
*mi
;
register struct device
*hpaddr
= (struct device
*)mi
->mi_drv
;
register struct buf
*bp
= mi
->mi_tab
.b_actf
;
register struct hpst
*st
= &hpst
[mi
->mi_type
];
if (mi
->mi_tab
.b_errcnt
>= 16 && (bp
->b_flags
&B_READ
) != 0) {
hpaddr
->hpof
= hp_offset
[mi
->mi_tab
.b_errcnt
& 017] | FMT22
;
hpaddr
->hpcs1
= OFFSET
|GO
;
while (hpaddr
->hpds
& PIP
)
hpaddr
->hpdc
= bp
->b_cylin
;
hpaddr
->hpda
= (tn
<< 8) + sn
;
register struct mba_info
*mi
;
register struct device
*hpaddr
= (struct device
*)mi
->mi_drv
;
register struct buf
*bp
= mi
->mi_tab
.b_actf
;
while ((hpaddr
->hpds
& DRY
) == 0) /* shouldn't happen */
printf("hp dry not set\n");
if (hpaddr
->hpds
& ERR
|| mbastat
& MBAEBITS
)
if (++mi
->mi_tab
.b_errcnt
< 28 && (hpaddr
->hper1
&WLE
) == 0) {
if ((hpaddr
->hper1
&0xffff) != DCK
) {
if ((mi
->mi_tab
.b_errcnt
&07) == 4) {
hpaddr
->hpcs1
= RECAL
|GO
;
while (hpaddr
->hpds
& PIP
)
deverror(bp
, mbastat
, hpaddr
->hper1
);
bp
->b_resid
= -(mi
->mi_mba
->mba_bcr
) & 0xffff;
if (mi
->mi_tab
.b_errcnt
) {
while (hpaddr
->hpds
& PIP
)
hpaddr
->hpcs1
= RELEASE
|GO
;
physio(hpstrategy
, &rhpbuf
, dev
, B_READ
, minphys
);
physio(hpstrategy
, &rhpbuf
, dev
, B_WRITE
, minphys
);
register struct mba_info
*mi
;
register struct mba_regs
*mbp
= mi
->mi_mba
;
register struct device
*rp
= (struct device
*)mi
->mi_drv
;
register struct buf
*bp
= mi
->mi_tab
.b_actf
;
register struct hpst
*st
;
int reg
, bit
, byte
, npf
, mask
, o
;
* Npf is the number of sectors transferred before the sector
* containing the ECC error, and reg is the MBA register
* mapping (the first part of)the transfer.
* O is offset within a memory page of the first byte transferred.
bcr
= mbp
->mba_bcr
& 0xffff;
bcr
|= 0xffff0000; /* sxt */
npf
= btop(bcr
+ bp
->b_bcount
) - 1;
o
= (int)bp
->b_un
.b_addr
& PGOFSET
;
printf("%D ", bp
->b_blkno
+ npf
);
* Compute the byte and bit position of the error.
* The variable i is the byte offset in the transfer,
* the variable byte is the offset from a page boundary
i
= (rp
->hpec1
&0xffff) - 1; /* -1 makes 0 origin */
* Correct while possible bits remain of mask. Since mask
* contains 11 bits, we continue while the bit offset is > -11.
* Also watch out for end of this block and the end of the whole
while (i
< 512 && (int)ptob(npf
)+i
< bp
->b_bcount
&& bit
> -11) {
mpte
= mbp
->mba_map
[reg
+btop(byte
)];
addr
= ptob(mpte
.pg_pfnum
) + (byte
& PGOFSET
);
putmemc(addr
, getmemc(addr
)^(mask
<<bit
));
mi
->mi_hd
->mh_active
++; /* Either complete or continuing */
* Have to continue the transfer... clear the drive,
* and compute the position where the transfer is to continue.
* We have completed npf+1 sectores of the transfer already;
* restart at offset o of next sector (i.e. in MBA register reg+1).
sn
= bn
%(st
->nspc
) + npf
+ 1;
mbp
->mba_var
= (int)ptob(reg
+1) + o
;
register struct mba_info
*mi
;
register struct mba_regs
*mba
;
register struct hpst
*st
;
#define phys(a,b) ((b)((int)(a)&0x7fffffff))
mi
= phys(hpinfo
[unit
],struct mba_info
*);
mba
= phys(mi
->mi_hd
, struct mba_hd
*)->mh_physmba
;
hpaddr
= (struct device
*)&mba
->mba_drv
[mi
->mi_drive
];
if ((hpaddr
->hpds
& VV
) == 0) {
hpaddr
->hpcs1
= PRESET
|GO
;
if (dumplo
< 0 || dumplo
+ num
>= st
->sizes
[minor(dev
)&07].nblocks
) {
register struct pte
*hpte
= mba
->mba_map
;
blk
= num
> DBSIZE
? DBSIZE
: num
;
bn
= dumplo
+ btop(start
);
cn
= bn
/st
->nspc
+ st
->sizes
[minor(dev
)&07].cyloff
;
hpaddr
->hpda
= (tn
<< 8) + sn
;
for (i
= 0; i
< blk
; i
++)
*(int *)hpte
++ = (btop(start
)+i
) | PG_V
;
mba
->mba_bcr
= -(blk
*NBPG
);
hpaddr
->hpcs1
= WCOM
| GO
;
while ((hpaddr
->hpds
& DRY
) == 0)
printf("dskerr: (%d,%d,%d) ds=%x er=%x\n",
cn
, tn
, sn
, hpaddr
->hpds
, hpaddr
->hper1
);
/* I don't really care what this does .. kre */