|
|
1.1 root 1:
2: /* @(#)tmscp.c 7.5 (Berkeley) 4/4/90 */
3:
4: /****************************************************************
5: * *
6: * Licensed from Digital Equipment Corporation *
7: * Copyright (c) *
8: * Digital Equipment Corporation *
9: * Maynard, Massachusetts *
10: * 1985, 1986 *
11: * All rights reserved. *
12: * *
13: * The Information in this software is subject to change *
14: * without notice and should not be construed as a commitment *
15: * by Digital Equipment Corporation. Digital makes no *
16: * representations about the suitability of this software for *
17: * any purpose. It is supplied "As Is" without expressed or *
18: * implied warranty. *
19: * *
20: * If the Regents of the University of California or its *
21: * licensees modify the software in a manner creating *
22: * diriviative copyright rights, appropriate copyright *
23: * legends may be placed on the drivative work in addition *
24: * to that set forth above. *
25: ***************************************************************/
26: /*
27: * tmscp.c - TMSCP (TK50/TU81) standalone driver
28: */
29:
30: # ifndef lint
31: static char *sccsid = "@(#)tmscp.c 1.5 (ULTRIX) 4/18/86";
32: # endif not lint
33:
34: /* ------------------------------------------------------------------------
35: * Modification History: /sys/stand/tmscp.c
36: *
37: * 3-15-85 afd
38: * Don't ask for an interrupt when commands are issued and
39: * check ownership bit in the response descriptor to detect when a
40: * command is complete. Necessary due to the TU81's failure to set
41: * the response interrupt field in the communications area.
42: *
43: * ------------------------------------------------------------------------
44: */
45:
46: #include "param.h"
47:
48: #include "../vax/pte.h"
49:
50: #include "savax.h"
51: #include "saio.h"
52:
53: /*
54: * Parameters for the communications area
55: * (Only 1 cmd & 1 rsp packet)
56: */
57: #define NRSPL2 0
58: #define NCMDL2 0
59: #define NRSP (1<<NRSPL2)
60: #define NCMD (1<<NCMDL2)
61:
62: #include "../vaxuba/tmscpreg.h"
63: #include "../vaxuba/ubareg.h"
64: #include "../vax/tmscp.h"
65:
66: #define MAXCTLR 1 /* all addresses must be specified */
67: u_short tmscpstd[MAXCTLR] = { 0174500 };
68:
69: struct iob ctmscpbuf;
70:
71: struct tmscpdevice *tmscpaddr = 0;
72:
73: struct tmscp {
74: struct tmscpca tmscp_ca;
75: struct mscp tmscp_rsp;
76: struct mscp tmscp_cmd;
77: } tmscp;
78:
79: struct tmscp *tmscp_ubaddr; /* Unibus address of tmscp structure */
80:
81: struct mscp *tmscpcmd();
82:
83: int tmscp_offline = 1; /* Flag to prevent multiple STCON */
84: int tms_offline[4] = {1,1,1,1}; /* Flag to prevent multiple ONLIN */
85:
86: /*
87: * Open a tmscp device. Initialize the controller and set the unit online.
88: */
89: tmscpopen(io)
90: register struct iob *io;
91: {
92: register struct mscp *mp;
93: int i;
94:
95: if ((u_int)io->i_ctlr >= MAXCTLR)
96: return (ECTLR);
97: /*
98: * Have the tmscp controller characteristics already been set up
99: * (STCON)?
100: */
101: if (tmscp_offline) {
102: if (tmscpaddr == 0)
103: tmscpaddr = (struct tmscpdevice *)ubamem(io->i_adapt, tmscpstd[0]);
104: if (tmscp_ubaddr == 0) {
105: ctmscpbuf = *io;
106: ctmscpbuf.i_ma = (caddr_t)&tmscp;
107: ctmscpbuf.i_cc = sizeof(tmscp);
108: tmscp_ubaddr = (struct tmscp *)ubasetup(&ctmscpbuf, 2);
109: }
110: /*
111: * Initialize the tmscp device and wait for the 4 steps
112: * to complete.
113: */
114: tmscpaddr->tmscpip = 0;
115: while ((tmscpaddr->tmscpsa & TMSCP_STEP1) == 0);
116: tmscpaddr->tmscpsa =TMSCP_ERR|(NCMDL2<<11)|(NRSPL2<<8);
117:
118: while ((tmscpaddr->tmscpsa & TMSCP_STEP2) == 0);
119: # define STEP1MASK 0174377
120: # define STEP1GOOD (TMSCP_STEP2|TMSCP_IE|(NCMDL2<<3)|NRSPL2)
121: if ((tmscpaddr->tmscpsa&STEP1MASK) != STEP1GOOD)
122: printf("tmscpopen: step 1 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
123: tmscpaddr->tmscpsa = (short)&tmscp_ubaddr->tmscp_ca.ca_ringbase;
124:
125: while ((tmscpaddr->tmscpsa & TMSCP_STEP3) == 0);
126: # define STEP2MASK 0174377
127: # define STEP2GOOD (TMSCP_STEP3)
128: if ((tmscpaddr->tmscpsa&STEP2MASK) != STEP2GOOD)
129: printf("tmscpopen: step 2 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
130: tmscpaddr->tmscpsa = (short)(((int)&tmscp_ubaddr->tmscp_ca.ca_ringbase) >> 16);
131:
132: while ((tmscpaddr->tmscpsa & TMSCP_STEP4) == 0);
133: # define STEP3MASK 0174000
134: # define STEP3GOOD TMSCP_STEP4
135: if ((tmscpaddr->tmscpsa&STEP3MASK) != STEP3GOOD)
136: printf("tmscpopen: step 3 not successful sa=%o\n",tmscpaddr->tmscpsa&0xffff);
137: tmscpaddr->tmscpsa = TMSCP_GO;
138:
139: /*
140: * Init cmd & rsp area
141: */
142: tmscp.tmscp_ca.ca_cmddsc[0] = (long)&tmscp_ubaddr->tmscp_cmd.mscp_cmdref;
143: tmscp.tmscp_cmd.mscp_dscptr = tmscp.tmscp_ca.ca_cmddsc;
144: tmscp.tmscp_cmd.mscp_header.tmscp_vcid = 1; /* for tape */
145:
146: tmscp.tmscp_ca.ca_rspdsc[0] = (long)&tmscp_ubaddr->tmscp_rsp.mscp_cmdref;
147: tmscp.tmscp_rsp.mscp_dscptr = tmscp.tmscp_ca.ca_rspdsc;
148: tmscp.tmscp_cmd.mscp_cntflgs = 0;
149: if (tmscpcmd(M_OP_STCON, 0) == 0) {
150: printf("tms: open error, STCON\n");
151: return (EIO);
152: }
153: tmscp_offline = 0;
154: }
155: tmscp.tmscp_cmd.mscp_unit = io->i_unit&03;
156: /*
157: * Has this unit been issued an ONLIN?
158: */
159: if (tms_offline[tmscp.tmscp_cmd.mscp_unit]) {
160: if ((mp = tmscpcmd(M_OP_ONLIN, 0)) == 0) {
161: _stop("tms: open error, ONLIN\n");
162: return (EIO);
163: }
164: tms_offline[tmscp.tmscp_cmd.mscp_unit] = 0;
165: }
166: /*
167: * This makes no sense, but I could be wrong... KB
168: *
169: * if ((u_int)io->i_part > 3)
170: * return (EPART);
171: */
172: if (io->i_part) {
173: /*
174: * Skip forward the appropriate number of files on the tape.
175: */
176: tmscp.tmscp_cmd.mscp_tmkcnt = io->i_part;
177: (void)tmscpcmd(M_OP_REPOS, 0);
178: tmscp.tmscp_cmd.mscp_tmkcnt = 0;
179: }
180: return (0);
181: }
182:
183: /*
184: * Close the device (rewind it to BOT)
185: */
186: tmscpclose(io)
187: register struct iob *io;
188: {
189: (void)tmscpcmd(M_OP_REPOS, M_MD_REWND);
190: }
191:
192: /*
193: * Set up tmscp command packet. Cause the controller to poll to pick up
194: * the command.
195: */
196: struct mscp *
197: tmscpcmd(op,mod)
198: int op, mod; /* opcode and modifier (usu 0) */
199: {
200: struct mscp *mp; /* ptr to cmd packet */
201: int i; /* read into to init polling */
202:
203: tmscp.tmscp_cmd.mscp_opcode = op;
204: tmscp.tmscp_cmd.mscp_modifier = mod;
205: tmscp.tmscp_cmd.mscp_header.tmscp_msglen = mscp_msglen;
206: tmscp.tmscp_ca.ca_cmddsc[0] |= TMSCP_OWN; /* | TMSCP_INT */
207: tmscp.tmscp_rsp.mscp_header.tmscp_msglen = mscp_msglen;
208: tmscp.tmscp_ca.ca_rspdsc[0] |= TMSCP_OWN; /* | TMSCP_INT */
209:
210: i = tmscpaddr->tmscpip;
211: for (;;) {
212: if (tmscpaddr->tmscpsa & TMSCP_ERR) {
213: printf("tmscpcmd: Fatal error sa=%o\n", tmscpaddr->tmscpsa & 0xffff);
214: return(0);
215: }
216:
217: if (tmscp.tmscp_ca.ca_cmdint)
218: tmscp.tmscp_ca.ca_cmdint = 0;
219: /*
220: * This is to handle the case of devices not setting the
221: * interrupt field in the communications area. Some
222: * devices (early TU81's) only clear the ownership field
223: * in the Response Descriptor.
224: *
225: *
226: * if (tmscp.tmscp_ca.ca_rspint)
227: * break;
228: */
229: if (!(tmscp.tmscp_ca.ca_rspdsc[0] & (TMSCP_OWN)))
230: break;
231: }
232: tmscp.tmscp_ca.ca_rspint = 0;
233: mp = &tmscp.tmscp_rsp;
234: if (mp->mscp_opcode != (op|M_OP_END) ||
235: (mp->mscp_status&M_ST_MASK) != M_ST_SUCC) {
236: /*
237: * Detect hitting tape mark. This signifies the end of the
238: * tape mini-root file. We don't want to return an error
239: * condition to the strategy routine.
240: */
241: if ((mp->mscp_status & M_ST_MASK) != M_ST_TAPEM)
242: return(0);
243: }
244: return(mp);
245: }
246:
247: /*
248: * Set up to do reads and writes; call tmscpcmd to issue the cmd.
249: */
250: tmscpstrategy(io, func)
251: register struct iob *io;
252: int func;
253: {
254: register struct mscp *mp;
255: int ubinfo;
256:
257: ubinfo = ubasetup(io, 1);
258: mp = &tmscp.tmscp_cmd;
259: mp->mscp_lbn = io->i_bn;
260: mp->mscp_unit = io->i_unit&03;
261: mp->mscp_bytecnt = io->i_cc;
262: mp->mscp_buffer = (ubinfo & 0x3fffff) | (((ubinfo>>28)&0xf)<<24);
263: if ((mp = tmscpcmd(func == READ ? M_OP_READ : M_OP_WRITE, 0)) == 0) {
264: ubafree(io, ubinfo);
265: printf("tms: I/O error\n");
266: return(-1);
267: }
268: ubafree(io, ubinfo);
269: /*
270: * Detect hitting tape mark so we do it gracefully and return a
271: * character count of 0 to signify end of copy. Rewind the tape
272: * before returning.
273: */
274: if ((mp->mscp_status & M_ST_MASK) == M_ST_TAPEM)
275: return(0);
276: return(io->i_cc);
277: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.