1 /*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)kdb.c 7.9 (Berkeley) 05/04/91
8 */
9
10 /*
11 * KDB50/RAxx disk device driver
12 */
13 #include "../include/pte.h"
14
15 #include "sys/param.h"
16 #include "sys/disklabel.h"
17
18 #include "stand/saio.h"
19 #include "savax.h"
20
21 /*
22 * N.B.: on KDB50, controller == adapter
23 * here we just use the controller number
24 */
25
26 #define NKRA 8 /* max drive number */
27 #define SECTSIZ 512 /* sector size in bytes */
28
29 /*
30 * Parameters for the communications area:
31 * command and response rings both one entry.
32 */
33 #define NRSP 1
34 #define NCMD 1
35
36 #include "../bi/bireg.h"
37 #include "../bi/kdbreg.h"
38 #include "../vax/mscp.h"
39
40 struct kdb {
41 struct kdbca kdb_ca;
42 struct mscp kdb_rsp;
43 struct mscp kdb_cmd;
44 } kdb;
45
46 int kdbinit[MAXNKDB];
47 struct disklabel kralabel[MAXNKDB][NKRA];
48 u_long kramedia[MAXNKDB][NKRA];
49 char lbuf[SECTSIZ];
50
kraopen(io)51 kraopen(io)
52 register struct iob *io;
53 {
54 register struct kdb_regs *kr;
55 register struct disklabel *lp;
56 register int ctlr, unit;
57 struct iob tio;
58
59 if ((u_int)(ctlr = io->i_ctlr) >= nkdb)
60 return (EADAPT);
61 if ((u_int)(unit = io->i_unit) >= NKRA)
62 return (EUNIT);
63 kr = (struct kdb_regs *)kdbaddr[ctlr];
64 if (kdbinit[ctlr] == 0) {
65 kr->kdb_bi.bi_csr |= BICSR_NRST;
66 DELAY(10000); /* ??? */
67 /* clear any bus errors */
68 kr->kdb_bi.bi_ber = ~(BIBER_MBZ|BIBER_NMR|BIBER_UPEN);
69 while ((kr->kdb_sa & KDB_STEP1) == 0)
70 /* void */;
71 kr->kdb_bi.bi_bcicsr |= BCI_STOPEN | BCI_IDENTEN;
72 kr->kdb_sw = KDB_ERR;
73 while ((kr->kdb_sa & KDB_STEP2) == 0)
74 /* void */;
75 kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0];
76 while ((kr->kdb_sa & KDB_STEP3) == 0)
77 /* void */;
78 kr->kdb_sw = (int)&kdb.kdb_ca.ca_rspdsc[0] >> 16;
79 while ((kr->kdb_sa & KDB_STEP4) == 0)
80 /* void */;
81 kr->kdb_sw = KDB_GO;
82 kdb.kdb_ca.ca_rspdsc[0] = (long)&kdb.kdb_rsp.mscp_cmdref;
83 kdb.kdb_ca.ca_cmddsc[0] = (long)&kdb.kdb_cmd.mscp_cmdref;
84 if (kdbcmd(M_OP_SETCTLRC, io)) {
85 printf("kra: open error, SETCTLRC\n");
86 return (ENXIO);
87 }
88 kdbinit[ctlr] = 1;
89 }
90 lp = &kralabel[ctlr][unit];
91 if (kramedia[ctlr][unit] == 0) {
92 kdb.kdb_cmd.mscp_unit = unit;
93 if (kdbcmd(M_OP_ONLINE, io)) {
94 printf("kra: open error, ONLINE\n");
95 return (ENXIO);
96 }
97 kramedia[ctlr][unit] = kdb.kdb_rsp.mscp_onle.onle_mediaid;
98 tio = *io;
99 tio.i_bn = LABELSECTOR;
100 tio.i_ma = lbuf;
101 tio.i_cc = SECTSIZ;
102 tio.i_flgs |= F_RDDATA;
103 if (krastrategy(&tio, F_READ) != SECTSIZ)
104 return (ERDLAB);
105 *lp = *(struct disklabel *)(lbuf + LABELOFFSET);
106 if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC) {
107 #ifdef COMPAT_42
108 printf("kra%d: unlabeled\n", unit);
109 kramaptype(io, lp);
110 #else
111 return (EUNLAB);
112 #endif
113 }
114 }
115 if ((u_int)io->i_part >= lp->d_npartitions ||
116 (io->i_boff = lp->d_partitions[io->i_part].p_offset) == -1)
117 return (EPART);
118 return (0);
119 }
120
kdbcmd(op,io)121 kdbcmd(op, io)
122 int op;
123 struct iob *io;
124 {
125 register struct kdb *k = &kdb;
126 register struct mscp *mp;
127 register int i;
128
129 k->kdb_cmd.mscp_opcode = op;
130 k->kdb_rsp.mscp_msglen = MSCP_MSGLEN;
131 k->kdb_cmd.mscp_msglen = MSCP_MSGLEN;
132 k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
133 k->kdb_ca.ca_cmddsc[0] |= MSCP_OWN | MSCP_INT;
134 i = ((struct kdb_regs *)kdbaddr[io->i_ctlr])->kdb_ip;
135 #ifdef lint
136 i = i;
137 #endif
138 mp = &k->kdb_rsp;
139 for (;;) {
140 if (k->kdb_ca.ca_cmdint)
141 k->kdb_ca.ca_cmdint = 0;
142 if (k->kdb_ca.ca_rspint == 0)
143 continue;
144 k->kdb_ca.ca_rspint = 0;
145 if (mp->mscp_opcode == (op | M_OP_END))
146 break;
147 printf("unexpected rsp type %x op %x ignored\n",
148 MSCP_MSGTYPE(mp->mscp_msgtc), mp->mscp_opcode);
149 k->kdb_ca.ca_rspdsc[0] |= MSCP_OWN | MSCP_INT;
150 }
151 if ((mp->mscp_status & M_ST_MASK) != M_ST_SUCCESS)
152 return (-1);
153 return (0);
154 }
155
krastrategy(io,func)156 krastrategy(io, func)
157 register struct iob *io;
158 int func;
159 {
160 register struct mscp *mp;
161
162 mp = &kdb.kdb_cmd;
163 mp->mscp_unit = io->i_unit;
164 mp->mscp_seq.seq_lbn = io->i_bn;
165 mp->mscp_seq.seq_bytecount = io->i_cc;
166 mp->mscp_seq.seq_buffer = (long)io->i_ma | KDB_PHYS;
167 if (kdbcmd(func == F_READ ? M_OP_READ : M_OP_WRITE, io)) {
168 printf("kra: I/O error\n");
169 return (-1);
170 }
171 return (io->i_cc);
172 }
173
174 #ifdef COMPAT_42
175 u_long kra60_off[] = { 0, 15884, 0, 49324, 131404, 49324, 242606, 49324 };
176 #define kra70_off kra60_off
177 u_long kra80_off[] = { 0, 15884, 0, -1, 49324, 49324, 49910, 131404 };
178 u_long kra81_off[] = { 0, 15884, 0, 131404, 49324, 498790, 563050, 131404 };
179 u_long kra82_off[] = { 0, 15884, 0, 375345, 391590, 699390, 375345, 83790 };
180
181 struct mediamap {
182 u_long id; /* media ID */
183 u_long *off; /* offsets */
184 } kra_map[] = {
185 { MSCP_MKDRIVE2('R', 'A', 60), kra60_off },
186 { MSCP_MKDRIVE2('R', 'A', 70), kra70_off },
187 { MSCP_MKDRIVE2('R', 'A', 80), kra80_off },
188 { MSCP_MKDRIVE2('R', 'A', 81), kra81_off },
189 { MSCP_MKDRIVE2('R', 'A', 82), kra82_off },
190 0
191 };
192
kramaptype(io,lp)193 kramaptype(io, lp)
194 register struct iob *io;
195 register struct disklabel *lp;
196 {
197 register struct partition *pp;
198 register u_long i;
199 register struct mediamap *map;
200
201 i = MSCP_MEDIA_DRIVE(kramedia[io->i_ctlr][io->i_unit]);
202 for (map = kra_map; map->id != 0; map++) {
203 if (map->id == i) {
204 lp->d_npartitions = 8;
205 for (pp = lp->d_partitions, i = 0; i < 8; pp++, i++)
206 pp->p_offset = map->off[i];
207 return;
208 }
209 }
210 printf("kra%d: media type 0x%x unsupported\n", io->i_unit, i);
211 lp->d_npartitions = 0;
212 }
213 #endif
214