Annotation of sys/arch/hp300/stand/common/ct.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ct.c,v 1.5 2006/08/17 06:31:10 miod Exp $ */
2: /* $NetBSD: ct.c,v 1.9 1996/10/14 07:29:57 thorpej Exp $ */
3:
4: /*
5: * Copyright (c) 1982, 1990, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. Neither the name of the University nor the names of its contributors
17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: *
32: * @(#)ct.c 8.1 (Berkeley) 7/15/93
33: */
34:
35: /*
36: * CS80 tape driver
37: */
38: #include <sys/param.h>
39:
40: #include <hp300/dev/ctreg.h>
41:
42: #include <lib/libsa/stand.h>
43:
44: #include "samachdep.h"
45: #include "hpibvar.h"
46:
47: struct ct_iocmd ct_ioc;
48: struct ct_rscmd ct_rsc;
49: struct ct_stat ct_stat;
50: struct ct_ssmcmd ct_ssmc;
51:
52: struct ct_softc {
53: int sc_ctlr;
54: int sc_unit;
55: char sc_retry;
56: char sc_alive;
57: short sc_punit;
58: int sc_blkno;
59: } ct_softc[NHPIB][NCT];
60:
61: #define CTRETRY 5
62: #define MTFSF 10
63: #define MTREW 11
64:
65: int ctclose(struct open_file *);
66: int cterror(int, int);
67: int ctident(int, int);
68: int ctinit(int, int);
69: int ctopen(struct open_file *, int, int, int);
70: int ctpunit(int, int, int *);
71: int ctstrategy(void *, int, daddr_t, size_t, void *, size_t *);
72:
73: char ctio_buf[MAXBSIZE];
74:
75: struct ctinfo {
76: short hwid;
77: short punit;
78: } ctinfo[] = {
79: { CT7946ID, 1 },
80: { CT7912PID, 1 },
81: { CT7914PID, 1 },
82: { CT9144ID, 0 },
83: { CT9145ID, 0 }
84: };
85: int nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]);
86:
87: int
88: ctinit(int ctlr, int unit)
89: {
90: struct ct_softc *rs = &ct_softc[ctlr][unit];
91: u_char stat;
92:
93: if (hpibrecv(ctlr, unit, C_QSTAT, &stat, 1) != 1 || stat)
94: return (0);
95: if (ctident(ctlr, unit) < 0)
96: return (0);
97: bzero(&ct_ssmc, sizeof(ct_ssmc));
98: ct_ssmc.unit = C_SUNIT(rs->sc_punit);
99: ct_ssmc.cmd = C_SSM;
100: ct_ssmc.fefm = FEF_MASK;
101: ct_ssmc.refm = REF_MASK;
102: ct_ssmc.aefm = AEF_MASK;
103: ct_ssmc.iefm = IEF_MASK;
104: hpibsend(ctlr, unit, C_CMD, &ct_ssmc, sizeof(ct_ssmc));
105: hpibswait(ctlr, unit);
106: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
107: rs->sc_alive = 1;
108: return (1);
109: }
110:
111: int
112: ctident(int ctlr, int unit)
113: {
114: struct cs80_describe desc;
115: u_char stat, cmd[3];
116: char name[7];
117: int id, i;
118:
119: id = hpibid(ctlr, unit);
120: if ((id & 0x200) == 0)
121: return(-1);
122: for (i = 0; i < nctinfo; i++)
123: if (id == ctinfo[i].hwid)
124: break;
125: if (i == nctinfo)
126: return(-1);
127: ct_softc[ctlr][unit].sc_punit = ctinfo[i].punit;
128: id = i;
129:
130: /*
131: * Collect device description.
132: * Right now we only need this to differentiate 7945 from 7946.
133: * Note that we always issue the describe command to unit 0.
134: */
135: cmd[0] = C_SUNIT(0);
136: cmd[1] = C_SVOL(0);
137: cmd[2] = C_DESC;
138: hpibsend(ctlr, unit, C_CMD, cmd, sizeof(cmd));
139: hpibrecv(ctlr, unit, C_EXEC, &desc, sizeof(desc));
140: hpibrecv(ctlr, unit, C_QSTAT, &stat, sizeof(stat));
141: bzero(name, sizeof(name));
142: if (!stat) {
143: int n = desc.d_name;
144: for (i = 5; i >= 0; i--) {
145: name[i] = (n & 0xf) + '0';
146: n >>= 4;
147: }
148: }
149: switch (ctinfo[id].hwid) {
150: case CT7946ID:
151: if (bcmp(name, "079450", 6) == 0)
152: id = -1; /* not really a 7946 */
153: break;
154: default:
155: break;
156: }
157: return(id);
158: }
159:
160: int
161: ctpunit(int ctlr, int slave, int *punit)
162: {
163: struct ct_softc *rs;
164:
165: if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
166: return(EADAPT);
167: if (slave >= NCT)
168: return(ECTLR);
169: rs = &ct_softc[ctlr][slave];
170:
171: if (rs->sc_alive == 0)
172: return(ENXIO);
173:
174: *punit = rs->sc_punit;
175: return (0);
176: }
177:
178: int
179: ctopen(struct open_file *f, int ctlr, int unit, int part)
180: {
181: struct ct_softc *rs;
182: int skip;
183: size_t resid;
184:
185: if (ctlr >= NHPIB || hpibalive(ctlr) == 0)
186: return(EADAPT);
187: if (unit >= NCT)
188: return(ECTLR);
189: rs = &ct_softc[ctlr][unit];
190: rs->sc_blkno = 0;
191: rs->sc_unit = unit;
192: rs->sc_ctlr = ctlr;
193: if (rs->sc_alive == 0)
194: if (ctinit(ctlr, unit) == 0)
195: return(ENXIO);
196: f->f_devdata = (void *)rs;
197: ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
198: skip = part;
199: while (skip--)
200: ctstrategy(f->f_devdata, MTFSF, 0, 0, ctio_buf, &resid);
201: return(0);
202: }
203:
204: int
205: ctclose(struct open_file *f)
206: {
207: size_t resid;
208:
209: ctstrategy(f->f_devdata, MTREW, 0, 0, ctio_buf, &resid);
210: return (0);
211: }
212:
213: int
214: ctstrategy(void *devdata, int func, daddr_t dblk, size_t size, void *v_buf,
215: size_t *rsize)
216: {
217: struct ct_softc *rs = devdata;
218: char *buf = v_buf;
219: int ctlr = rs->sc_ctlr;
220: int unit = rs->sc_unit;
221: char stat;
222:
223: if (size == 0 && (func == F_READ || func == F_WRITE))
224: return(0);
225:
226: rs->sc_retry = 0;
227: bzero(&ct_ioc, sizeof(ct_ioc));
228: ct_ioc.unit = C_SUNIT(rs->sc_punit);
229: ct_ioc.saddr = C_SADDR;
230: ct_ioc.nop2 = C_NOP;
231: ct_ioc.slen = C_SLEN;
232: ct_ioc.nop3 = C_NOP;
233: top:
234: if (func == F_READ) {
235: ct_ioc.cmd = C_READ;
236: ct_ioc.addr = rs->sc_blkno;
237: ct_ioc.len = size;
238: }
239: else if (func == F_WRITE) {
240: ct_ioc.cmd = C_WRITE;
241: ct_ioc.addr = rs->sc_blkno;
242: ct_ioc.len = size;
243: }
244: else if (func == MTFSF) {
245: ct_ioc.cmd = C_READ;
246: ct_ioc.addr = rs->sc_blkno;
247: ct_ioc.len = size = MAXBSIZE;
248: }
249: else {
250: ct_ioc.cmd = C_READ;
251: ct_ioc.addr = 0;
252: ct_ioc.len = 0;
253: rs->sc_blkno = 0;
254: size = 0;
255: }
256: retry:
257: hpibsend(ctlr, unit, C_CMD, &ct_ioc, sizeof(ct_ioc));
258: if (func != MTREW) {
259: hpibswait(ctlr, unit);
260: hpibgo(ctlr, unit, C_EXEC, buf, size,
261: func != F_WRITE ? F_READ : F_WRITE);
262: hpibswait(ctlr, unit);
263: } else {
264: while (hpibswait(ctlr, unit) < 0)
265: ;
266: }
267: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
268: if (stat) {
269: stat = cterror(ctlr, unit);
270: if (stat == 0)
271: return (-1);
272: if (stat == 2)
273: return (0);
274: if (++rs->sc_retry > CTRETRY)
275: return (-1);
276: goto retry;
277: }
278: rs->sc_blkno += CTBTOK(size);
279: if (func == MTFSF)
280: goto top;
281: *rsize = size;
282:
283: return(0);
284: }
285:
286: int
287: cterror(int ctlr, int unit)
288: {
289: struct ct_softc *rs = &ct_softc[ctlr][unit];
290: char stat;
291:
292: bzero(&ct_rsc, sizeof(ct_rsc));
293: bzero(&ct_stat, sizeof(ct_stat));
294: ct_rsc.unit = C_SUNIT(rs->sc_punit);
295: ct_rsc.cmd = C_STATUS;
296: hpibsend(ctlr, unit, C_CMD, &ct_rsc, sizeof(ct_rsc));
297: hpibrecv(ctlr, unit, C_EXEC, &ct_stat, sizeof(ct_stat));
298: hpibrecv(ctlr, unit, C_QSTAT, &stat, 1);
299: if (stat) {
300: printf("ct%d: request status fail %d\n", unit, stat);
301: return(0);
302: }
303: if (ct_stat.c_aef & AEF_EOF) {
304: /* 9145 drives don't increment block number at EOF */
305: if ((ct_stat.c_blk - rs->sc_blkno) == 0)
306: rs->sc_blkno++;
307: else
308: rs->sc_blkno = ct_stat.c_blk;
309: return (2);
310: }
311: printf("ct%d err: vu 0x%x, pend 0x%x, bn%ld", unit,
312: ct_stat.c_vu, ct_stat.c_pend, ct_stat.c_blk);
313: printf(", R 0x%x F 0x%x A 0x%x I 0x%x\n", ct_stat.c_ref,
314: ct_stat.c_fef, ct_stat.c_aef, ct_stat.c_ief);
315: return (1);
316: }
CVSweb