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