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