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