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