xref: /csrg-svn/sys/vax/stand/idc.c (revision 6969)
1*6969Ssam /*	idc.c	4.1	82/05/27	*/
2*6969Ssam 
3*6969Ssam /*
4*6969Ssam  * IDC (RB730)
5*6969Ssam  *
6*6969Ssam  * This driver is full of kludges!
7*6969Ssam  * It depends heavily on the 1K file system.
8*6969Ssam  */
9*6969Ssam 
10*6969Ssam #include "../h/param.h"
11*6969Ssam #include "../h/idcreg.h"
12*6969Ssam #include "../h/inode.h"
13*6969Ssam #include "../h/pte.h"
14*6969Ssam #include "../h/ubareg.h"
15*6969Ssam #include "saio.h"
16*6969Ssam #include "savax.h"
17*6969Ssam 
18*6969Ssam u_short	idcstd[] = { 0175606 };
19*6969Ssam short	rb02_off[] = { 0, 400, 0, -1, -1, -1, -1, -1 };
20*6969Ssam short	rb80_off[] = { 0, 37, 0, -1, -1, -1, 115, 305 };
21*6969Ssam 
22*6969Ssam int idc_type[4];
23*6969Ssam 
24*6969Ssam idcopen(io)
25*6969Ssam 	register struct iob *io;
26*6969Ssam {
27*6969Ssam 	register struct idcdevice *idcaddr;
28*6969Ssam 	register int i;
29*6969Ssam 
30*6969Ssam 	idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
31*6969Ssam 	if (io->i_boff < 0 || io->i_boff > 7)
32*6969Ssam 		_stop("idc bad unit");
33*6969Ssam 	idcaddr->idcmpr = IDCGS_GETSTAT;
34*6969Ssam 	idcaddr->idccsr = IDC_GETSTAT|(io->i_unit<<8);
35*6969Ssam 	idcwait(idcaddr);
36*6969Ssam 	i = idcaddr->idcmpr;
37*6969Ssam 	idcaddr->idccsr = IDC_CRDY|(1<<(io->i_unit+16));
38*6969Ssam 	idcwait(idcaddr);
39*6969Ssam 	idcaddr->idccsr = (io->i_unit<<8)|IDC_RHDR;
40*6969Ssam 	idcwait(idcaddr);
41*6969Ssam 	if (idcaddr->idccsr & IDC_ERR) {
42*6969Ssam 		printf("idc error: idccsr %x\n", idcaddr->idccsr);
43*6969Ssam 		_stop("idc fatal error");
44*6969Ssam 	}
45*6969Ssam 	i = idcaddr->idcmpr;
46*6969Ssam 	i = idcaddr->idcmpr;
47*6969Ssam 	if (idcaddr->idccsr & IDC_R80) {
48*6969Ssam 		idc_type[io->i_unit] = 1;
49*6969Ssam 		io->i_boff = rb80_off[io->i_boff];
50*6969Ssam 	} else {
51*6969Ssam 		idc_type[io->i_unit] = 0;
52*6969Ssam 		io->i_boff = rb02_off[io->i_boff];
53*6969Ssam 	}
54*6969Ssam 	if (io->i_boff < 0)
55*6969Ssam 		_stop("idc bad unit");
56*6969Ssam }
57*6969Ssam 
58*6969Ssam idcstrategy(io, func)
59*6969Ssam 	register struct iob *io;
60*6969Ssam {
61*6969Ssam 	register struct idcdevice *idcaddr;
62*6969Ssam 	int com;
63*6969Ssam 	daddr_t bn;
64*6969Ssam 	short dn, cn, sn, tn;
65*6969Ssam 	int ubinfo, errcnt = 0;
66*6969Ssam 
67*6969Ssam 	idcaddr = (struct idcdevice *)((caddr_t)ubauba(io->i_unit) + 0x200);
68*6969Ssam retry:
69*6969Ssam 	ubinfo = ubasetup(io, 1);
70*6969Ssam 	bn = io->i_bn;
71*6969Ssam 	dn = io->i_unit;
72*6969Ssam 	if (io->i_cc != 1024) printf("idc: count %d != 1024\n", io->i_cc);
73*6969Ssam 	if (idc_type[dn]) {
74*6969Ssam 		cn = bn/(NRB80SECT*NRB80TRK);
75*6969Ssam 		sn = bn%NRB80SECT;
76*6969Ssam 		tn = (bn / NRB80SECT) % NRB80TRK;
77*6969Ssam 		if (sn == NRB80SECT)
78*6969Ssam 			io->i_cc = 512;
79*6969Ssam 	} else {
80*6969Ssam 		bn *= 2;
81*6969Ssam 		cn = bn/(NRB02SECT*NRB02TRK);
82*6969Ssam 		sn = bn%NRB02SECT;
83*6969Ssam 		tn = (bn / NRB02SECT) % NRB02TRK;
84*6969Ssam 	}
85*6969Ssam 	cn += io->i_boff;
86*6969Ssam 	idcaddr->idccsr = IDC_CRDY|IDC_SEEK|(dn<<8)|(1<<(dn+16));
87*6969Ssam 	idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
88*6969Ssam 	idcaddr->idccsr = IDC_SEEK|(dn<<8);
89*6969Ssam 	idcwait(idcaddr);
90*6969Ssam 	idcaddr->idccsr &= ~IDC_ATTN;
91*6969Ssam 	com = dn<<8;
92*6969Ssam 	if (func == READ)
93*6969Ssam 		com |= IDC_READ;
94*6969Ssam 	else
95*6969Ssam 		com |= IDC_WRITE;
96*6969Ssam 	idcaddr->idccsr = IDC_CRDY|com;
97*6969Ssam 	idcaddr->idcbar = ubinfo&0x3ffff;
98*6969Ssam 	idcaddr->idcbcr = -io->i_cc;
99*6969Ssam 	idcaddr->idcdar = (cn<<16)|(tn<<8)|sn;
100*6969Ssam 	idcaddr->idccsr = com;
101*6969Ssam 	idcwait(idcaddr);
102*6969Ssam 	ubafree(io, ubinfo);
103*6969Ssam 	if (idcaddr->idccsr & IDC_ERR) {
104*6969Ssam 		printf("idc error: (cyl,trk,sec)=(%d,%d,%d) csr=%b\n",
105*6969Ssam 		    cn, tn, sn, idcaddr->idccsr, IDCCSR_BITS);
106*6969Ssam 		if (errcnt == 10) {
107*6969Ssam 			printf("idc: unrecovered error\n");
108*6969Ssam 			return (-1);
109*6969Ssam 		}
110*6969Ssam 		errcnt++;
111*6969Ssam 		goto retry;
112*6969Ssam 	}
113*6969Ssam 	if (errcnt)
114*6969Ssam 		printf("idc: recovered by retry\n");
115*6969Ssam 	if (idc_type[dn] && sn == NRB80SECT) {
116*6969Ssam 		io->i_bn++;
117*6969Ssam 		goto retry;
118*6969Ssam 	}
119*6969Ssam 	return (1024);
120*6969Ssam }
121*6969Ssam 
122*6969Ssam idcwait(idcaddr)
123*6969Ssam 	register struct idcdevice *idcaddr;
124*6969Ssam {
125*6969Ssam 	register int i;
126*6969Ssam 
127*6969Ssam 	while ((idcaddr->idccsr & (IDC_CRDY|IDC_DRDY)) != (IDC_CRDY|IDC_DRDY))
128*6969Ssam 		for (i = 10; i; i--)
129*6969Ssam 			;
130*6969Ssam }
131