xref: /original-bsd/sys/hp300/stand/rd.c (revision 13deef58)
1 /*
2  * Copyright (c) 1988 University of Utah.
3  * Copyright (c) 1982, 1990 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * the Systems Programming Group of the University of Utah Computer
8  * Science Department.
9  *
10  * %sccs.include.redist.c%
11  *
12  * from: Utah $Hdr: rd.c 1.17 92/06/18$
13  *
14  *	@(#)rd.c	7.4 (Berkeley) 06/18/92
15  */
16 
17 /*
18  * CS80/SS80 disk driver
19  */
20 #include "sys/param.h"
21 #include "saio.h"
22 #include "samachdep.h"
23 
24 #include "../dev/rdreg.h"
25 
26 struct	rd_iocmd rd_ioc;
27 struct	rd_rscmd rd_rsc;
28 struct	rd_stat rd_stat;
29 struct	rd_ssmcmd rd_ssmc;
30 
31 struct	rd_softc {
32 	char	sc_retry;
33 	char	sc_alive;
34 	short	sc_type;
35 } rd_softc[NHPIB][NRD];
36 
37 #define	RDRETRY		5
38 
39 int rdcyloff[][8] = {
40 	{ 1, 143, 0, 143, 0,   0,   323, 503, },	/* 7945A */
41 	{ 1, 167, 0, 0,   0,   0,   0,   0,   },	/* 9134D */
42 	{ 0, 0,   0, 0,   0,   0,   0,   0,   },	/* 9122S */
43 	{ 0, 71,  0, 221, 292, 542, 221, 0,   },	/* 7912P */
44 	{ 1, 72,  0, 72,  362, 802, 252, 362, },	/* 7914P */
45 	{ 1, 28,  0, 140, 167, 444, 140, 721, },	/* 7933H */
46 	{ 1, 200, 0, 200, 0,   0,   450, 600, },	/* 9134L */
47 	{ 1, 105, 0, 105, 380, 736, 265, 380, },	/* 7957A */
48 	{ 1, 65,  0, 65,  257, 657, 193, 257, },	/* 7958A */
49 	{ 1, 128, 0, 128, 518, 918, 388, 518, },	/* 7957B */
50 	{ 1, 44,  0, 44,  174, 496, 131, 174, },	/* 7958B */
51 	{ 1, 44,  0, 44,  218, 1022,174, 218, },	/* 7959B */
52 	{ 1, 37,  0, 37,  183, 857, 147, 183, },	/* 2200A */
53 	{ 1, 19,  0, 94,  112, 450, 94,  788, },	/* 2203A */
54 	{ 1, 20,  0, 98,  117, 256, 98,  397, },	/* 7936H */
55 	{ 1, 11,  0, 53,  63,  217, 53,  371, },	/* 7937H */
56 };
57 
58 struct rdinfo {
59 	int	nbpc;
60 	int	hwid;
61 	int	*cyloff;
62 } rdinfo[] = {
63 	NRD7945ABPT*NRD7945ATRK, RD7946AID, rdcyloff[0],
64 	NRD9134DBPT*NRD9134DTRK, RD9134DID, rdcyloff[1],
65 	NRD9122SBPT*NRD9122STRK, RD9134LID, rdcyloff[2],
66 	NRD7912PBPT*NRD7912PTRK, RD7912PID, rdcyloff[3],
67 	NRD7914PBPT*NRD7914PTRK, RD7914PID, rdcyloff[4],
68 	NRD7958ABPT*NRD7958ATRK, RD7958AID, rdcyloff[8],
69 	NRD7957ABPT*NRD7957ATRK, RD7957AID, rdcyloff[7],
70 	NRD7933HBPT*NRD7933HTRK, RD7933HID, rdcyloff[5],
71 	NRD9134LBPT*NRD9134LTRK, RD9134LID, rdcyloff[6],
72 	NRD7936HBPT*NRD7936HTRK, RD7936HID, rdcyloff[14],
73 	NRD7937HBPT*NRD7937HTRK, RD7937HID, rdcyloff[15],
74 	NRD7914PBPT*NRD7914PTRK, RD7914CTID,rdcyloff[4],
75 	NRD7945ABPT*NRD7945ATRK, RD7946AID, rdcyloff[0],
76 	NRD9122SBPT*NRD9122STRK, RD9134LID, rdcyloff[2],
77 	NRD7957BBPT*NRD7957BTRK, RD7957BID, rdcyloff[9],
78 	NRD7958BBPT*NRD7958BTRK, RD7958BID, rdcyloff[10],
79 	NRD7959BBPT*NRD7959BTRK, RD7959BID, rdcyloff[11],
80 	NRD2200ABPT*NRD2200ATRK, RD2200AID, rdcyloff[12],
81 	NRD2203ABPT*NRD2203ATRK, RD2203AID, rdcyloff[13],
82 };
83 int	nrdinfo = sizeof(rdinfo) / sizeof(rdinfo[0]);
84 
85 rdinit(ctlr, unit)
86 	int ctlr, unit;
87 {
88 	register struct rd_softc *rs = &rd_softc[ctlr][unit];
89 	u_char stat;
90 
91 	rs->sc_type = rdident(ctlr, unit);
92 	if (rs->sc_type < 0)
93 		return (0);
94 	rs->sc_alive = 1;
95 	return (1);
96 }
97 
98 rdreset(ctlr, unit)
99 	register int ctlr, unit;
100 {
101 	u_char stat;
102 
103 	rd_ssmc.c_unit = C_SUNIT(0);
104 	rd_ssmc.c_cmd = C_SSM;
105 	rd_ssmc.c_refm = REF_MASK;
106 	rd_ssmc.c_fefm = FEF_MASK;
107 	rd_ssmc.c_aefm = AEF_MASK;
108 	rd_ssmc.c_iefm = IEF_MASK;
109 	hpibsend(ctlr, unit, C_CMD, &rd_ssmc, sizeof(rd_ssmc));
110 	hpibswait(ctlr, unit);
111 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
112 }
113 
114 rdident(ctlr, unit)
115 	register int ctlr, unit;
116 {
117 	struct rd_describe desc;
118 	u_char stat, cmd[3];
119 	char name[7];
120 	register int id, i;
121 
122 	id = hpibid(ctlr, unit);
123 	if ((id & 0x200) == 0)
124 		return(-1);
125 	for (i = 0; i < nrdinfo; i++)
126 		if (id == rdinfo[i].hwid)
127 			break;
128 	if (i == nrdinfo)
129 		return(-1);
130 	id = i;
131 	rdreset(ctlr, unit);
132 	cmd[0] = C_SUNIT(0);
133 	cmd[1] = C_SVOL(0);
134 	cmd[2] = C_DESC;
135 	hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
136 	hpibrecv(ctlr, unit, C_EXEC, &desc, 37);
137 	hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
138 	bzero(name, sizeof(name));
139 	if (!stat) {
140 		register int n = desc.d_name;
141 		for (i = 5; i >= 0; i--) {
142 			name[i] = (n & 0xf) + '0';
143 			n >>= 4;
144 		}
145 	}
146 	/*
147 	 * Take care of a couple of anomolies:
148 	 * 1. 7945A and 7946A both return same HW id
149 	 * 2. 9122S and 9134D both return same HW id
150 	 * 3. 9122D and 9134L both return same HW id
151 	 */
152 	switch (rdinfo[id].hwid) {
153 	case RD7946AID:
154 		if (bcmp(name, "079450", 6) == 0)
155 			id = RD7945A;
156 		else
157 			id = RD7946A;
158 		break;
159 
160 	case RD9134LID:
161 		if (bcmp(name, "091340", 6) == 0)
162 			id = RD9134L;
163 		else
164 			id = RD9122D;
165 		break;
166 
167 	case RD9134DID:
168 		if (bcmp(name, "091220", 6) == 0)
169 			id = RD9122S;
170 		else
171 			id = RD9134D;
172 		break;
173 	}
174 	return(id);
175 }
176 
177 rdopen(io)
178 	struct iob *io;
179 {
180 	register struct rd_softc *rs;
181 	struct rdinfo *ri;
182 	int unit, ctlr, part;
183 
184 	devconvert(io);
185 
186 	ctlr = io->i_adapt;
187 	if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
188 		return (EADAPT);
189 	unit = io->i_ctlr;
190 	if (unit >= NRD)
191 		return (ECTLR);
192 	rs = &rd_softc[ctlr][unit];
193 	if (rs->sc_alive == 0)
194 		if (rdinit(ctlr, unit) == 0)
195 			return (ENXIO);
196 	part = io->i_part;
197 	if (part >= 8)
198 		return (EPART);
199 	ri = &rdinfo[rs->sc_type];
200 	io->i_boff = ri->cyloff[part] * ri->nbpc;
201 }
202 
203 rdstrategy(io, func)
204 	register struct iob *io;
205 	int func;
206 {
207 	register int ctlr = io->i_adapt;
208 	register int unit = io->i_ctlr;
209 	register struct rd_softc *rs = &rd_softc[ctlr][unit];
210 	char stat;
211 
212 	rs->sc_retry = 0;
213 	rd_ioc.c_unit = C_SUNIT(0);
214 	rd_ioc.c_volume = C_SVOL(0);
215 	rd_ioc.c_saddr = C_SADDR;
216 	rd_ioc.c_hiaddr = 0;
217 	rd_ioc.c_addr = RDBTOS(io->i_bn);
218 	rd_ioc.c_nop2 = C_NOP;
219 	rd_ioc.c_slen = C_SLEN;
220 	rd_ioc.c_len = io->i_cc;
221 	rd_ioc.c_cmd = func == F_READ ? C_READ : C_WRITE;
222 retry:
223 	hpibsend(ctlr, unit, C_CMD, &rd_ioc.c_unit, sizeof(rd_ioc)-2);
224 	hpibswait(ctlr, unit);
225 	hpibgo(ctlr, unit, C_EXEC, io->i_ma, io->i_cc, func);
226 	hpibswait(ctlr, unit);
227 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
228 	if (stat) {
229 		if (rderror(ctlr, unit, io->i_part) == 0)
230 			return(-1);
231 		if (++rs->sc_retry > RDRETRY)
232 			return(-1);
233 		goto retry;
234 	}
235 	return(io->i_cc);
236 }
237 
238 rderror(ctlr, unit, part)
239 	register int ctlr, unit;
240 	int part;
241 {
242 	register struct rd_softc *rd = &rd_softc[ctlr][unit];
243 	char stat;
244 
245 	rd_rsc.c_unit = C_SUNIT(0);
246 	rd_rsc.c_sram = C_SRAM;
247 	rd_rsc.c_ram = C_RAM;
248 	rd_rsc.c_cmd = C_STATUS;
249 	hpibsend(ctlr, unit, C_CMD, &rd_rsc, sizeof(rd_rsc));
250 	hpibrecv(ctlr, unit, C_EXEC, &rd_stat, sizeof(rd_stat));
251 	hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
252 	if (stat) {
253 		printf("rd(%d,%d,0,%d): request status fail %d\n",
254 		       ctlr, unit, part, stat);
255 		return(0);
256 	}
257 	printf("rd(%d,%d,0,%d) err: vu 0x%x",
258 	       ctlr, unit, part, rd_stat.c_vu);
259 	if ((rd_stat.c_aef & AEF_UD) || (rd_stat.c_ief & (IEF_MD|IEF_RD)))
260 		printf(", block %d", rd_stat.c_blk);
261 	printf(", R0x%x F0x%x A0x%x I0x%x\n",
262 	       rd_stat.c_ref, rd_stat.c_fef, rd_stat.c_aef, rd_stat.c_ief);
263 	return(1);
264 }
265