xref: /csrg-svn/sys/vax/mba/hp.c (revision 2362)
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