merge in NFS code from Rick Macklem
[unix-history] / usr / src / sys / vax / stand / uda.c
CommitLineData
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 */
39u_short udastd[MAXCTLR] = { 0772150 };
788aa549 40
b313b409 41struct udadevice *udaddr[MAXNUBA][MAXCTLR];
788aa549 42
4eb2864b
KB
43struct 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 */
50struct uda1 *ud_ubaddr[MAXNUBA][MAXCTLR];
51struct disklabel ralabel[MAXNUBA][MAXCTLR][NRA];
68000458 52static u_long ramedia[MAXNUBA][MAXCTLR][NRA];
80c81fbf 53char lbuf[SECTSIZ];
788aa549 54
76780d43 55raopen(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 133int
80c81fbf 134udcmd(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 169rastrategy(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 192u_long rc25_off[] = { 0, 15884, 0, -1, -1, -1, 25916, -1 };
4eb2864b
KB
193u_long rx50_off[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
194u_long rd52_off[] = { 0, 15884, 0, 0, 0, 0, 25650, 0 };
195u_long rd53_off[] = { 0, 15884, 0, 0, 0, 33440, 49324, 15884 };
80c81fbf 196u_long ra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
68000458 197#define ra70_off ra60_off
80c81fbf
MK
198u_long ra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
199#ifndef UCBRA
200#ifdef RA_COMPAT
201u_long ra81_off[] = { 0, 16422, 0, 49324, 131404, 412490, 375564, 83538 };
202#else
203u_long ra81_off[] = { 0, 16422, 0, 375564, 391986, 699720, 375564, 83538 };
204#endif
205#else
206u_long ra81_off[] = { 0, 15884, 0, 242606, 258490, 565690, 242606, 49324 };
207#endif
68000458
MK
208u_long ra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
209
210struct 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
227ramaptype(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