|
|
1.1 root 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) 7/9/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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.