Annotation of sys/arch/hp300/stand/common/hd.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: hd.c,v 1.6 2006/08/17 06:31:10 miod Exp $ */
2: /* $NetBSD: rd.c,v 1.11 1996/12/21 21:34:40 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1988 University of Utah.
6: * Copyright (c) 1982, 1990, 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * the Systems Programming Group of the University of Utah Computer
11: * Science Department.
12: *
13: * Redistribution and use in source and binary forms, with or without
14: * modification, are permitted provided that the following conditions
15: * are met:
16: * 1. Redistributions of source code must retain the above copyright
17: * notice, this list of conditions and the following disclaimer.
18: * 2. Redistributions in binary form must reproduce the above copyright
19: * notice, this list of conditions and the following disclaimer in the
20: * documentation and/or other materials provided with the distribution.
21: * 3. Neither the name of the University nor the names of its contributors
22: * may be used to endorse or promote products derived from this software
23: * without specific prior written permission.
24: *
25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35: * SUCH DAMAGE.
36: *
37: * from: Utah Hdr: rd.c 1.20 92/12/21
38: *
39: * @(#)rd.c 8.1 (Berkeley) 7/15/93
40: */
41:
42: /*
43: * CS80/SS80 disk driver
44: */
45: #include <sys/param.h>
46: #include <sys/disklabel.h>
47:
48: #include <lib/libsa/stand.h>
49:
50: #include "samachdep.h"
51:
52: #include <hp300/dev/hdreg.h>
53: #include "hpibvar.h"
54:
55: struct hd_iocmd hd_ioc;
56: struct hd_rscmd hd_rsc;
57: struct hd_stat hd_stat;
58: struct hd_ssmcmd hd_ssmc;
59:
60: struct disklabel hdlabel;
61:
62: struct hdminilabel {
63: u_short npart;
64: u_long offset[MAXPARTITIONS];
65: };
66:
67: struct hd_softc {
68: int sc_ctlr;
69: int sc_unit;
70: int sc_part;
71: char sc_retry;
72: char sc_alive;
73: short sc_type;
74: struct hdminilabel sc_pinfo;
75: } hd_softc[NHPIB][NHD];
76:
77: #define HDRETRY 5
78:
79: struct hdidentinfo {
80: short ri_hwid;
81: short ri_maxunum;
82: int ri_nblocks;
83: } hdidentinfo[] = {
84: { HD7946AID, 0, 108416 },
85: { HD9134DID, 1, 29088 },
86: { HD9134LID, 1, 1232 },
87: { HD7912PID, 0, 128128 },
88: { HD7914PID, 0, 258048 },
89: { HD7958AID, 0, 255276 },
90: { HD7957AID, 0, 159544 },
91: { HD7933HID, 0, 789958 },
92: { HD9134LID, 1, 77840 },
93: { HD7936HID, 0, 600978 },
94: { HD7937HID, 0, 1116102 },
95: { HD7914CTID, 0, 258048 },
96: { HD7946AID, 0, 108416 },
97: { HD9134LID, 1, 1232 },
98: { HD7957BID, 0, 159894 },
99: { HD7958BID, 0, 297108 },
100: { HD7959BID, 0, 594216 },
101: { HD2200AID, 0, 654948 },
102: { HD2203AID, 0, 1309896 }
103: };
104: int numhdidentinfo = sizeof(hdidentinfo) / sizeof(hdidentinfo[0]);
105:
106: int hdclose(struct open_file *);
107: int hderror(int, int, int);
108: int hdgetinfo(struct hd_softc *);
109: int hdident(int, int);
110: int hdinit(int, int);
111: int hdopen(struct open_file *, int, int, int);
112: void hdreset(int, int);
113: int hdstrategy(void *, int, daddr_t, size_t, void *, size_t *);
114:
115: int
116: hdinit(int ctlr, int unit)
117: {
118: struct hd_softc *rs = &hd_softc[ctlr][unit];
119:
120: rs->sc_type = hdident(ctlr, unit);
121: if (rs->sc_type < 0)
122: return (0);
123: rs->sc_alive = 1;
124: return (1);
125: }
126:
127: void
128: hdreset(int ctlr, int unit)
129: {
130: u_char stat;
131:
132: hd_ssmc.c_unit = C_SUNIT(0);
133: hd_ssmc.c_cmd = C_SSM;
134: hd_ssmc.c_refm = REF_MASK;
135: hd_ssmc.c_fefm = FEF_MASK;
136: hd_ssmc.c_aefm = AEF_MASK;
137: hd_ssmc.c_iefm = IEF_MASK;
138: hpibsend(ctlr, unit, C_CMD, &hd_ssmc, sizeof(hd_ssmc));
139: hpibswait(ctlr, unit);
140: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
141: }
142:
143: int
144: hdident(int ctlr, int unit)
145: {
146: struct cs80_describe desc;
147: u_char stat, cmd[3];
148: char name[7];
149: int id, i;
150:
151: id = hpibid(ctlr, unit);
152: if ((id & 0x200) == 0)
153: return(-1);
154: for (i = 0; i < numhdidentinfo; i++)
155: if (id == hdidentinfo[i].ri_hwid)
156: break;
157: if (i == numhdidentinfo)
158: return(-1);
159: id = i;
160: hdreset(ctlr, unit);
161: cmd[0] = C_SUNIT(0);
162: cmd[1] = C_SVOL(0);
163: cmd[2] = C_DESC;
164: hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
165: hpibrecv(ctlr, unit, C_EXEC, &desc, sizeof(desc));
166: hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
167: bzero(name, sizeof(name));
168: if (!stat) {
169: int n = desc.d_name;
170: for (i = 5; i >= 0; i--) {
171: name[i] = (n & 0xf) + '0';
172: n >>= 4;
173: }
174: }
175: /*
176: * Take care of a couple of anomalies:
177: * 1. 7945A and 7946A both return same HW id
178: * 2. 9122S and 9134D both return same HW id
179: * 3. 9122D and 9134L both return same HW id
180: */
181: switch (hdidentinfo[id].ri_hwid) {
182: case HD7946AID:
183: if (bcmp(name, "079450", 6) == 0)
184: id = HD7945A;
185: else
186: id = HD7946A;
187: break;
188:
189: case HD9134LID:
190: if (bcmp(name, "091340", 6) == 0)
191: id = HD9134L;
192: else
193: id = HD9122D;
194: break;
195:
196: case HD9134DID:
197: if (bcmp(name, "091220", 6) == 0)
198: id = HD9122S;
199: else
200: id = HD9134D;
201: break;
202: }
203: return(id);
204: }
205:
206: char io_buf[MAXBSIZE];
207:
208: int
209: hdgetinfo(struct hd_softc *rs)
210: {
211: struct hdminilabel *pi = &rs->sc_pinfo;
212: struct disklabel *lp = &hdlabel;
213: char *msg;
214: int err, savepart;
215: size_t i;
216:
217: bzero((caddr_t)lp, sizeof *lp);
218: lp->d_secsize = DEV_BSIZE;
219:
220: /* Disklabel is always from RAW_PART. */
221: savepart = rs->sc_part;
222: rs->sc_part = RAW_PART;
223: err = hdstrategy(rs, F_READ, LABELSECTOR,
224: lp->d_secsize ? lp->d_secsize : DEV_BSIZE, io_buf, &i);
225: rs->sc_part = savepart;
226:
227: if (err) {
228: printf("hdgetinfo: hdstrategy error %d\n", err);
229: return(0);
230: }
231:
232: msg = getdisklabel(io_buf, lp);
233: if (msg) {
234: printf("hd(%d,%d,%d): WARNING: %s, ",
235: rs->sc_ctlr, rs->sc_unit, rs->sc_part, msg);
236: printf("defining `c' partition as entire disk\n");
237: pi->npart = 3;
238: pi->offset[0] = pi->offset[1] = -1;
239: pi->offset[2] = 0;
240: } else {
241: pi->npart = lp->d_npartitions;
242: for (i = 0; i < pi->npart; i++)
243: pi->offset[i] = lp->d_partitions[i].p_size == 0 ?
244: -1 : lp->d_partitions[i].p_offset;
245: }
246: return(1);
247: }
248:
249: int
250: hdopen(struct open_file *f, int ctlr, int unit, int part)
251: {
252: struct hd_softc *rs;
253:
254: if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
255: return (EADAPT);
256: if (unit >= NHD)
257: return (ECTLR);
258: rs = &hd_softc[ctlr][unit];
259: rs->sc_part = part;
260: rs->sc_unit = unit;
261: rs->sc_ctlr = ctlr;
262: if (rs->sc_alive == 0) {
263: if (hdinit(ctlr, unit) == 0)
264: return (ENXIO);
265: if (hdgetinfo(rs) == 0)
266: return (ERDLAB);
267: }
268: if (part != RAW_PART && /* always allow RAW_PART to be opened */
269: (part >= rs->sc_pinfo.npart || rs->sc_pinfo.offset[part] == -1))
270: return (EPART);
271: f->f_devdata = (void *)rs;
272: return (0);
273: }
274:
275: int
276: hdclose(struct open_file *f)
277: {
278: struct hd_softc *rs = f->f_devdata;
279:
280: /*
281: * Mark the disk `not alive' so that the disklabel
282: * will be re-loaded at next open.
283: */
284: bzero(rs, sizeof(struct hd_softc));
285: f->f_devdata = NULL;
286: return (0);
287: }
288:
289: int
290: hdstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
291: size_t *rsize)
292: {
293: char *buf = v_buf;
294: struct hd_softc *rs = devdata;
295: int ctlr = rs->sc_ctlr;
296: int unit = rs->sc_unit;
297: daddr_t blk;
298: char stat;
299:
300: if (size == 0)
301: return(0);
302:
303: /*
304: * Don't do partition translation on the `raw partition'.
305: */
306: blk = (dblk + ((rs->sc_part == RAW_PART) ? 0 :
307: rs->sc_pinfo.offset[rs->sc_part]));
308:
309: rs->sc_retry = 0;
310: hd_ioc.c_unit = C_SUNIT(0);
311: hd_ioc.c_volume = C_SVOL(0);
312: hd_ioc.c_saddr = C_SADDR;
313: hd_ioc.c_hiaddr = 0;
314: hd_ioc.c_addr = HDBTOS(blk);
315: hd_ioc.c_nop2 = C_NOP;
316: hd_ioc.c_slen = C_SLEN;
317: hd_ioc.c_len = size;
318: hd_ioc.c_cmd = func == F_READ ? C_READ : C_WRITE;
319: retry:
320: hpibsend(ctlr, unit, C_CMD, &hd_ioc.c_unit, sizeof(hd_ioc)-2);
321: hpibswait(ctlr, unit);
322: hpibgo(ctlr, unit, C_EXEC, buf, size, func);
323: hpibswait(ctlr, unit);
324: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
325: if (stat) {
326: if (hderror(ctlr, unit, rs->sc_part) == 0)
327: return(EIO);
328: if (++rs->sc_retry > HDRETRY)
329: return(EIO);
330: goto retry;
331: }
332: *rsize = size;
333:
334: return(0);
335: }
336:
337: int
338: hderror(int ctlr, int unit, int part)
339: {
340: char stat;
341:
342: hd_rsc.c_unit = C_SUNIT(0);
343: hd_rsc.c_sram = C_SRAM;
344: hd_rsc.c_ram = C_RAM;
345: hd_rsc.c_cmd = C_STATUS;
346: hpibsend(ctlr, unit, C_CMD, &hd_rsc, sizeof(hd_rsc));
347: hpibrecv(ctlr, unit, C_EXEC, &hd_stat, sizeof(hd_stat));
348: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
349: if (stat) {
350: printf("hd(%d,%d,0,%d): request status fail %d\n",
351: ctlr, unit, part, stat);
352: return(0);
353: }
354: printf("hd(%d,%d,0,%d) err: vu 0x%x",
355: ctlr, unit, part, hd_stat.c_vu);
356: if ((hd_stat.c_aef & AEF_UD) || (hd_stat.c_ief & (IEF_MD|IEF_RD)))
357: printf(", block %ld", hd_stat.c_blk);
358: printf(", R0x%x F0x%x A0x%x I0x%x\n",
359: hd_stat.c_ref, hd_stat.c_fef, hd_stat.c_aef, hd_stat.c_ief);
360: return(1);
361: }
CVSweb