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