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