|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)uda.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: /*
10: * UDA50/RAxx disk device driver
11: */
12: #include "../machine/pte.h"
13:
14: #include "../h/param.h"
15: #include "../h/inode.h"
16: #include "../h/fs.h"
17:
18: #include "saio.h"
19: #include "savax.h"
20:
21: #define NRA 4
22: /*
23: * Parameters for the communications area
24: */
25: #define NRSPL2 0
26: #define NCMDL2 0
27: #define NRSP (1<<NRSPL2)
28: #define NCMD (1<<NCMDL2)
29:
30: #include "../vaxuba/udareg.h"
31: #include "../vaxuba/ubareg.h"
32: #include "../vax/mscp.h"
33:
34: u_short udastd[] = { 0772150 };
35:
36: struct iob cudbuf;
37:
38: struct udadevice *udaddr = 0;
39:
40: struct uda {
41: struct udaca uda_ca;
42: struct mscp uda_rsp;
43: struct mscp uda_cmd;
44: } uda;
45:
46: struct uda *ud_ubaddr; /* Unibus address of uda structure */
47:
48: int ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
49: int ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
50: int ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
51: #ifndef UCBRA
52: #ifdef RA_COMPAT
53: int ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
54: #else
55: int ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
56: #endif
57: #else
58: int ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
59: #endif
60:
61: struct mscp *udcmd();
62: static int ratype[NRA];
63:
64: raopen(io)
65: register struct iob *io;
66: {
67: register struct mscp *mp;
68: static int udainit, udadriveinit[NRA];
69: int i;
70: daddr_t off;
71:
72: if (udaddr == 0)
73: udaddr = (struct udadevice *)ubamem(io->i_unit, udastd[0]);
74: if (ud_ubaddr == 0) {
75: /*
76: * Initialise cudbuf.i_unit so that controllers
77: * on UNIBUSes other than 0 can be used.
78: */
79: cudbuf.i_unit = io->i_unit;
80: cudbuf.i_ma = (caddr_t)&uda;
81: cudbuf.i_cc = sizeof(uda);
82: ud_ubaddr = (struct uda *)ubasetup(&cudbuf, 2);
83: }
84: if (udainit == 0) {
85: udaddr->udaip = 0;
86: while ((udaddr->udasa & UDA_STEP1) == 0)
87: ;
88: udaddr->udasa = UDA_ERR;
89: while ((udaddr->udasa & UDA_STEP2) == 0)
90: ;
91: udaddr->udasa = (short)&ud_ubaddr->uda_ca.ca_ringbase;
92: while ((udaddr->udasa & UDA_STEP3) == 0)
93: ;
94: udaddr->udasa =
95: (short)(((int)&ud_ubaddr->uda_ca.ca_ringbase) >> 16);
96: while ((udaddr->udasa & UDA_STEP4) == 0)
97: ;
98: udaddr->udasa = UDA_GO;
99: uda.uda_ca.ca_rspdsc[0] = (long)&ud_ubaddr->uda_rsp.mscp_cmdref;
100: uda.uda_ca.ca_cmddsc[0] = (long)&ud_ubaddr->uda_cmd.mscp_cmdref;
101: uda.uda_cmd.mscp_cntflgs = 0;
102: if (udcmd(M_OP_STCON) == 0) {
103: _stop("ra: open error, STCON");
104: return;
105: }
106: }
107: i = io->i_unit & 7;
108: if (udadriveinit[i] == 0) {
109: uda.uda_cmd.mscp_unit = i;
110: if (udcmd(M_OP_ONLIN) == 0) {
111: _stop("ra: open error, ONLIN");
112: return;
113: }
114: udainit = 1;
115: }
116: if (io->i_boff < 0 || io->i_boff > 7)
117: _stop("ra: bad unit");
118:
119: switch (ratype[i]) {
120: case 25:
121: off = ra25_off[io->i_boff];
122: break;
123: case 60:
124: off = ra60_off[io->i_boff];
125: break;
126: case 80:
127: off = ra80_off[io->i_boff];
128: break;
129: case 81:
130: off = ra81_off[io->i_boff];
131: break;
132: default:
133: printf("uda%d: don't support ra%d's\n", i, ratype[i]);
134: off = -1;
135: break;
136: }
137: if (off == -1)
138: _stop("ra: bad partition");
139: io->i_boff = off;
140: }
141:
142: struct mscp *
143: udcmd(op)
144: int op;
145: {
146: struct mscp *mp;
147: int i;
148:
149: uda.uda_cmd.mscp_opcode = op;
150: uda.uda_rsp.mscp_header.uda_msglen = sizeof (struct mscp);
151: uda.uda_cmd.mscp_header.uda_msglen = sizeof (struct mscp);
152: uda.uda_ca.ca_rspdsc[0] |= UDA_OWN|UDA_INT;
153: uda.uda_ca.ca_cmddsc[0] |= UDA_OWN|UDA_INT;
154: i = udaddr->udaip;
155: for (;;) {
156: if (uda.uda_ca.ca_cmdint)
157: uda.uda_ca.ca_cmdint = 0;
158: if (uda.uda_ca.ca_rspint)
159: break;
160: }
161: uda.uda_ca.ca_rspint = 0;
162: mp = &uda.uda_rsp;
163: if (mp->mscp_opcode != (op|M_OP_END) ||
164: (mp->mscp_status&M_ST_MASK) != M_ST_SUCC)
165: return(0);
166: if (mp->mscp_opcode == (M_OP_ONLIN|M_OP_END))
167: ratype[uda.uda_cmd.mscp_unit] = mp->mscp_mediaid & 0x7f;
168: return(mp);
169: }
170:
171: rastrategy(io, func)
172: register struct iob *io;
173: {
174: register struct mscp *mp;
175: int ubinfo;
176:
177: ubinfo = ubasetup(io, 1);
178: mp = &uda.uda_cmd;
179: mp->mscp_lbn = io->i_bn;
180: mp->mscp_unit = io->i_unit&7;
181: mp->mscp_bytecnt = io->i_cc;
182: mp->mscp_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
183: if ((mp = udcmd(func == READ ? M_OP_READ : M_OP_WRITE)) == 0) {
184: printf("ra: I/O error\n");
185: ubafree(io, ubinfo);
186: return(-1);
187: }
188: ubafree(io, ubinfo);
189: return(io->i_cc);
190: }
191:
192: /*ARGSUSED*/
193: raioctl(io, cmd, arg)
194: struct iob *io;
195: int cmd;
196: caddr_t arg;
197: {
198:
199: return (ECMD);
200: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.