xref: /csrg-svn/sys/vax/stand/uda.c (revision 29315)
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) 06/05/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 }
201