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