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