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