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