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