xref: /original-bsd/sys/vax/stand/uda.c (revision c18ec352)
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.7 (Berkeley) 02/23/88
7  */
8 
9 /*
10  * UDA50/RAxx disk device driver
11  */
12 #include "../machine/pte.h"
13 
14 #include "param.h"
15 #include "inode.h"
16 #include "fs.h"
17 #include "disklabel.h"
18 
19 #include "saio.h"
20 #include "savax.h"
21 
22 #define	NRA		8	/* max. unit number on controller */
23 #define	SECTSIZ 	512	/* sector size in bytes */
24 
25 /*
26  * Unused, but needed in udareg.h
27  */
28 #define NRSP	1
29 #define NCMD	1
30 
31 #include "../vaxuba/udareg.h"
32 #include "../vaxuba/ubareg.h"
33 #include "../vax/mscp.h"
34 
35 #define	MAXCTLR		1		/* all addresses must be specified */
36 u_short udastd[MAXCTLR] = { 0772150 };
37 
38 struct iob	cudbuf;
39 
40 struct udadevice *udaddr[MAXNUBA][MAXCTLR];
41 
42 struct	uda1 {
43 	struct	uda1ca uda1_ca;	/* communications area */
44 	struct	mscp uda1_rsp;	/* response packet */
45 	struct	mscp uda1_cmd;	/* command packet */
46 } uda1;
47 
48 				/* Unibus address of uda structure */
49 struct	uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
50 struct	disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
51 static	u_int ratype[MAXNUBA][MAXCTLR][NRA];
52 char	lbuf[SECTSIZ];
53 
54 raopen(io)
55 	register struct iob *io;
56 {
57 	register struct mscp *mp;
58 	register struct disklabel *lp, *dlp;
59 	register struct udadevice *addr;
60 	register struct uda1 *ubaddr;
61 	register unit;
62 	static int udainit[MAXNUBA][MAXCTLR];
63 	int uba;
64 
65 	if ((u_int)io->i_ctlr >= MAXCTLR)
66 		return (ECTLR);
67 	unit = io->i_unit;
68 	uba = io->i_adapt;
69 	addr = udaddr[uba][io->i_ctlr] =
70 	    (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]);
71 	if (badaddr((char *)addr, sizeof(short))) {
72 		printf("ra: nonexistent device\n");
73 		return (ENXIO);
74 	}
75 	if (ud_ubaddr[uba][io->i_ctlr] == 0) {
76 		/*
77 		 * Initialize cudbuf.i_unit so that controllers
78 		 * on UNIBUSes other than 0 can be used.
79 		 */
80 		cudbuf.i_unit = unit;
81 		cudbuf.i_ma = (caddr_t)&uda1;
82 		cudbuf.i_cc = sizeof(uda1);
83 		ud_ubaddr[uba][io->i_ctlr] = (struct uda1 *)ubasetup(&cudbuf, 2);
84 	}
85 	ubaddr = ud_ubaddr[uba][io->i_ctlr];
86 	if (udainit[uba][io->i_ctlr] == 0) {
87 		addr->udaip = 0;
88 		while ((addr->udasa & UDA_STEP1) == 0)
89 			;
90 		addr->udasa = UDA_ERR;
91 		while ((addr->udasa & UDA_STEP2) == 0)
92 			;
93 		addr->udasa = (short)&ubaddr->uda1_ca.ca_rspdsc;
94 		while ((addr->udasa & UDA_STEP3) == 0)
95 			;
96 		addr->udasa =
97 		    (short)(((int)&ubaddr->uda1_ca.ca_rspdsc) >> 16);
98 		while ((addr->udasa & UDA_STEP4) == 0)
99 			;
100 		addr->udasa = UDA_GO;
101 		uda1.uda1_ca.ca_rspdsc = (long)&ubaddr->uda1_rsp.mscp_cmdref;
102 		uda1.uda1_ca.ca_cmddsc = (long)&ubaddr->uda1_cmd.mscp_cmdref;
103 		/* uda1.uda1_cmd.mscp_cntflgs = 0; */
104 		if (udcmd(M_OP_SETCTLRC, io)) {
105 			printf("ra: open error, SETCTLRC\n");
106 			return (ENXIO);
107 		}
108 		udainit[uba][io->i_ctlr] = 1;
109 	}
110 	lp = &ralabel[uba][io->i_ctlr][unit];
111 	if (ratype[uba][io->i_ctlr][unit] == 0) {
112 		struct iob tio;
113 
114 		uda1.uda1_cmd.mscp_unit = unit;
115 		if (udcmd(M_OP_ONLINE, io)) {
116 			printf("ra: open error, ONLINE\n");
117 			return (ENXIO);
118 		}
119 		ratype[uba][io->i_ctlr][unit] =
120 		    uda1.uda1_rsp.mscp_onle.onle_drivetype;
121 		tio = *io;
122 		tio.i_bn = LABELSECTOR;
123 		tio.i_ma = lbuf;
124 		tio.i_cc = SECTSIZ;
125 		tio.i_flgs |= F_RDDATA;
126 		if (rastrategy(&tio, READ) != SECTSIZ) {
127 			printf("ra: can't read disk label\n");
128 			return (ENXIO);
129 		}
130 		*lp = *(struct disklabel *)(lbuf + LABELOFFSET);
131 		if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
132 			printf("ra%d: unlabeled\n", unit);
133 #ifdef COMPAT_42
134 			ramaptype(io, lp);
135 #else
136 			return (ENXIO);
137 #endif
138 		}
139 	}
140 	if ((u_int)io->i_part >= lp->d_npartitions ||
141 	    (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
142 		return (EPART);
143 	return (0);
144 }
145 
146 int
147 udcmd(op, io)
148 	int op;
149 	register struct iob *io;
150 {
151 	register struct uda1 *u = &uda1;
152 	register struct mscp *mp;
153 	int i;
154 
155 	u->uda1_cmd.mscp_opcode = op;
156 	u->uda1_cmd.mscp_msglen = MSCP_MSGLEN;
157 	u->uda1_rsp.mscp_msglen = MSCP_MSGLEN;
158 	u->uda1_ca.ca_rspdsc |= MSCP_OWN|MSCP_INT;
159 	u->uda1_ca.ca_cmddsc |= MSCP_OWN|MSCP_INT;
160 	i = udaddr[io->i_adapt][io->i_ctlr]->udaip;
161 	mp = &u->uda1_rsp;
162 	for (;;) {
163 		if (u->uda1_ca.ca_cmdint)
164 			u->uda1_ca.ca_cmdint = 0;
165 		if (u->uda1_ca.ca_rspint == 0)
166 			continue;
167 		u->uda1_ca.ca_rspint = 0;
168 		if (mp->mscp_opcode == (op | M_OP_END))
169 			break;
170 		printf("unexpected rsp type %x op %x ignored\n",
171 			MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
172 		u->uda1_ca.ca_rspdsc |= MSCP_OWN | MSCP_INT;
173 	}
174 	if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS)
175 		return (-1);
176 	return (0);
177 }
178 
179 rastrategy(io, func)
180 	register struct iob *io;
181 {
182 	register struct mscp *mp;
183 	int ubinfo;
184 
185 	ubinfo = ubasetup(io, 1);
186 	mp = &uda1.uda1_cmd;
187 	mp->mscp_unit = io->i_unit;
188 	mp->mscp_seq.seq_lbn = io->i_bn;
189 	mp->mscp_seq.seq_bytecount = io->i_cc;
190 	mp->mscp_seq.seq_buffer = (ubinfo & 0x3ffff) | (((ubinfo>>28)&0xf)<<24);
191 	if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) {
192 		printf("ra: I/O error\n");
193 		ubafree(io, ubinfo);
194 		return(-1);
195 	}
196 	ubafree(io, ubinfo);
197 	return(io->i_cc);
198 }
199 
200 #ifdef COMPAT_42
201 u_long ra25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
202 u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
203 u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
204 u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
205 u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
206 u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
207 #ifndef	UCBRA
208 #ifdef RA_COMPAT
209 u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
210 #else
211 u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
212 #endif
213 #else
214 u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
215 #endif
216 
217 u_long	*ra_off[] = {
218 	0,		/* 0 = unused */
219 	ra80_off,	/* 1 = ra80 */
220 	ra25_off,	/* 2 = rc25 removable */
221 	ra25_off,	/* 3 = rc25 fixed */
222 	ra60_off,	/* 4 = ra60 */
223 	ra81_off,	/* 5 = ra81 */
224 	0,		/* 6 = ? */
225 	rx50_off,	/* 7 = rx50 */
226 	rd52_off,	/* 8 = rd52 */
227 	rd53_off,	/* 9 = rd53 */
228 };
229 
230 #define NOFFS	(sizeof(ra_off)/sizeof(ra_off[0]))
231 
232 ramaptype(io, lp)
233 	register struct iob *io;
234 	register struct disklabel *lp;
235 {
236 	register struct partition *pp;
237 	register u_int i;
238 	register u_long *off;
239 
240 	if ((i = ratype[io->i_adapt][io->i_ctlr][io->i_unit]) >= NOFFS ||
241 	    (off = ra_off[i]) == 0) {
242 		printf("ra%d: ra type %d unsupported\n", io->i_unit, i);
243 		lp->d_npartitions = 0;
244 		return;
245 	}
246 	lp->d_npartitions = 8;
247 	for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
248 		pp->p_offset = *off++;
249 }
250 #endif
251