Commit | Line | Data |
---|---|---|
da7c5cc6 | 1 | /* |
68000458 | 2 | * Copyright (c) 1982, 1986, 1988 Regents of the University of California. |
da7c5cc6 KM |
3 | * All rights reserved. The Berkeley software License Agreement |
4 | * specifies the terms and conditions for redistribution. | |
5 | * | |
68000458 | 6 | * @(#)uda.c 7.9 (Berkeley) %G% |
da7c5cc6 | 7 | */ |
788aa549 SL |
8 | |
9 | /* | |
10 | * UDA50/RAxx disk device driver | |
11 | */ | |
12 | ||
4eb2864b KB |
13 | #include "param.h" |
14 | #include "inode.h" | |
68000458 | 15 | #include "buf.h" |
4eb2864b KB |
16 | #include "fs.h" |
17 | #include "disklabel.h" | |
a031a31b | 18 | |
68000458 MK |
19 | #include "../vax/pte.h" |
20 | ||
788aa549 SL |
21 | #include "saio.h" |
22 | #include "savax.h" | |
23 | ||
24 | /* | |
4eb2864b | 25 | * Unused, but needed in udareg.h |
788aa549 | 26 | */ |
4eb2864b KB |
27 | #define NRSP 1 |
28 | #define NCMD 1 | |
788aa549 | 29 | |
39c71180 | 30 | #include "../vaxuba/udareg.h" |
a031a31b | 31 | #include "../vaxuba/ubareg.h" |
68000458 | 32 | #include "../vaxuba/ubavar.h" |
39c71180 | 33 | #include "../vax/mscp.h" |
788aa549 | 34 | |
68000458 MK |
35 | #define NRA 8 /* max. unit number on controller */ |
36 | #define SECTSIZ 512 /* sector size in bytes */ | |
37 | ||
b313b409 KB |
38 | #define MAXCTLR 1 /* all addresses must be specified */ |
39 | u_short udastd[MAXCTLR] = { 0772150 }; | |
788aa549 | 40 | |
b313b409 | 41 | struct udadevice *udaddr[MAXNUBA][MAXCTLR]; |
788aa549 | 42 | |
4eb2864b KB |
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; | |
788aa549 | 48 | |
b313b409 KB |
49 | /* Unibus address of uda structure */ |
50 | struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR]; | |
51 | struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA]; | |
68000458 | 52 | static u_long ramedia[MAXNUBA][MAXCTLR][NRA]; |
80c81fbf | 53 | char lbuf[SECTSIZ]; |
788aa549 | 54 | |
76780d43 | 55 | raopen(io) |
788aa549 SL |
56 | register struct iob *io; |
57 | { | |
68000458 | 58 | register struct disklabel *lp; |
80c81fbf | 59 | register struct udadevice *addr; |
68000458 | 60 | register struct uda1 *ubaaddr; |
24360a49 | 61 | register int uba, unit; |
b313b409 | 62 | static int udainit[MAXNUBA][MAXCTLR]; |
24360a49 | 63 | struct iob tio; |
788aa549 | 64 | |
68000458 MK |
65 | if ((u_int)(uba = io->i_adapt) >= nuba) |
66 | return (EADAPT); | |
b313b409 KB |
67 | if ((u_int)io->i_ctlr >= MAXCTLR) |
68 | return (ECTLR); | |
68000458 MK |
69 | if ((u_int)(unit = io->i_unit) >= NRA) |
70 | return (EUNIT); | |
b313b409 KB |
71 | addr = udaddr[uba][io->i_ctlr] = |
72 | (struct udadevice *)ubamem(uba, udastd[io->i_ctlr]); | |
24360a49 | 73 | if (badaddr((char *)addr, sizeof(short))) |
80c81fbf | 74 | return (ENXIO); |
68000458 | 75 | if ((ubaaddr = ud_ubaddr[uba][io->i_ctlr]) == 0) { |
24360a49 KB |
76 | tio = *io; |
77 | tio.i_ma = (caddr_t)&uda1; | |
78 | tio.i_cc = sizeof(uda1); | |
68000458 MK |
79 | ud_ubaddr[uba][io->i_ctlr] = ubaaddr = |
80 | (struct uda1 *)ubasetup(&tio, 2); | |
788aa549 | 81 | } |
b313b409 | 82 | if (udainit[uba][io->i_ctlr] == 0) { |
80c81fbf | 83 | addr->udaip = 0; |
24360a49 | 84 | while ((addr->udasa & UDA_STEP1) == 0); |
80c81fbf | 85 | addr->udasa = UDA_ERR; |
24360a49 | 86 | while ((addr->udasa & UDA_STEP2) == 0); |
68000458 | 87 | addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc; |
24360a49 | 88 | while ((addr->udasa & UDA_STEP3) == 0); |
68000458 | 89 | addr->udasa = (int)&ubaaddr->uda1_ca.ca_rspdsc >> 16; |
24360a49 | 90 | while ((addr->udasa & UDA_STEP4) == 0); |
80c81fbf | 91 | addr->udasa = UDA_GO; |
68000458 MK |
92 | uda1.uda1_ca.ca_rspdsc = (long)&ubaaddr->uda1_rsp.mscp_cmdref; |
93 | uda1.uda1_ca.ca_cmddsc = (long)&ubaaddr->uda1_cmd.mscp_cmdref; | |
4eb2864b | 94 | /* uda1.uda1_cmd.mscp_cntflgs = 0; */ |
39c71180 | 95 | if (udcmd(M_OP_SETCTLRC, io)) { |
4eb2864b | 96 | printf("ra: open error, SETCTLRC\n"); |
b313b409 | 97 | return (ENXIO); |
e0fcb4e0 | 98 | } |
b313b409 | 99 | udainit[uba][io->i_ctlr] = 1; |
e1bf496a | 100 | } |
b313b409 | 101 | lp = &ralabel[uba][io->i_ctlr][unit]; |
68000458 | 102 | if (ramedia[uba][io->i_ctlr][unit] == 0) { |
b313b409 | 103 | uda1.uda1_cmd.mscp_unit = unit; |
39c71180 | 104 | if (udcmd(M_OP_ONLINE, io)) { |
4eb2864b | 105 | printf("ra: open error, ONLINE\n"); |
b313b409 | 106 | return (ENXIO); |
80c81fbf | 107 | } |
68000458 MK |
108 | ramedia[uba][io->i_ctlr][unit] = |
109 | uda1.uda1_rsp.mscp_onle.onle_mediaid; | |
80c81fbf MK |
110 | tio = *io; |
111 | tio.i_bn = LABELSECTOR; | |
112 | tio.i_ma = lbuf; | |
113 | tio.i_cc = SECTSIZ; | |
114 | tio.i_flgs |= F_RDDATA; | |
24360a49 KB |
115 | if (rastrategy(&tio, READ) != SECTSIZ) |
116 | return (ERDLAB); | |
39c71180 | 117 | *lp = *(struct disklabel *)(lbuf + LABELOFFSET); |
68000458 | 118 | if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) { |
80c81fbf | 119 | #ifdef COMPAT_42 |
24360a49 | 120 | printf("ra%d: unlabeled\n", unit); |
80c81fbf MK |
121 | ramaptype(io, lp); |
122 | #else | |
24360a49 | 123 | return (EUNLAB); |
80c81fbf | 124 | #endif |
68000458 | 125 | } |
788aa549 | 126 | } |
b313b409 KB |
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); | |
80c81fbf | 130 | return (0); |
788aa549 SL |
131 | } |
132 | ||
39c71180 | 133 | int |
80c81fbf | 134 | udcmd(op, io) |
788aa549 | 135 | int op; |
80c81fbf | 136 | register struct iob *io; |
788aa549 | 137 | { |
39c71180 | 138 | register struct uda1 *u = &uda1; |
4eb2864b | 139 | register struct mscp *mp; |
24360a49 | 140 | register int i; |
788aa549 | 141 | |
39c71180 MK |
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; | |
24360a49 | 147 | i = udaddr[io->i_adapt][io->i_ctlr]->udaip; /* start uda polling */ |
68000458 MK |
148 | #ifdef lint |
149 | i = i; | |
150 | #endif | |
39c71180 | 151 | mp = &u->uda1_rsp; |
788aa549 | 152 | for (;;) { |
39c71180 MK |
153 | if (u->uda1_ca.ca_cmdint) |
154 | u->uda1_ca.ca_cmdint = 0; | |
155 | if (u->uda1_ca.ca_rspint == 0) | |
4eb2864b | 156 | continue; |
39c71180 | 157 | u->uda1_ca.ca_rspint = 0; |
4eb2864b | 158 | if (mp->mscp_opcode == (op | M_OP_END)) |
788aa549 | 159 | break; |
39c71180 MK |
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; | |
788aa549 | 163 | } |
4eb2864b | 164 | if ((mp->mscp_status&M_ST_MASK) != M_ST_SUCCESS) |
39c71180 MK |
165 | return (-1); |
166 | return (0); | |
788aa549 SL |
167 | } |
168 | ||
76780d43 | 169 | rastrategy(io, func) |
788aa549 | 170 | register struct iob *io; |
68000458 | 171 | int func; |
788aa549 SL |
172 | { |
173 | register struct mscp *mp; | |
68000458 | 174 | register int ubinfo; |
788aa549 SL |
175 | |
176 | ubinfo = ubasetup(io, 1); | |
4eb2864b | 177 | mp = &uda1.uda1_cmd; |
b313b409 | 178 | mp->mscp_unit = io->i_unit; |
4eb2864b KB |
179 | mp->mscp_seq.seq_lbn = io->i_bn; |
180 | mp->mscp_seq.seq_bytecount = io->i_cc; | |
68000458 | 181 | mp->mscp_seq.seq_buffer = UBAI_ADDR(ubinfo) | (UBAI_BDP(ubinfo) << 24); |
39c71180 | 182 | if (udcmd(func == READ ? M_OP_READ : M_OP_WRITE, io)) { |
788aa549 SL |
183 | printf("ra: I/O error\n"); |
184 | ubafree(io, ubinfo); | |
68000458 | 185 | return (-1); |
788aa549 SL |
186 | } |
187 | ubafree(io, ubinfo); | |
68000458 | 188 | return (io->i_cc); |
788aa549 | 189 | } |
75f313ad | 190 | |
80c81fbf | 191 | #ifdef COMPAT_42 |
68000458 | 192 | u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 }; |
4eb2864b KB |
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 }; | |
80c81fbf | 196 | u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 }; |
68000458 | 197 | #define ra70_off ra60_off |
80c81fbf MK |
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 | |
68000458 MK |
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 | |
4eb2864b KB |
225 | }; |
226 | ||
80c81fbf MK |
227 | ramaptype(io, lp) |
228 | register struct iob *io; | |
229 | register struct disklabel *lp; | |
230 | { | |
231 | register struct partition *pp; | |
68000458 MK |
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 | } | |
80c81fbf | 243 | } |
68000458 MK |
244 | printf("ra%d: media type 0x%x unsupported\n", io->i_unit, i); |
245 | lp->d_npartitions = 0; | |
80c81fbf MK |
246 | } |
247 | #endif |