mscp_subr.c revision 1.38 1 1.38 dsl /* $NetBSD: mscp_subr.c,v 1.38 2009/03/14 15:36:19 dsl Exp $ */
2 1.1 ragge /*
3 1.1 ragge * Copyright (c) 1988 Regents of the University of California.
4 1.1 ragge * All rights reserved.
5 1.1 ragge *
6 1.1 ragge * This code is derived from software contributed to Berkeley by
7 1.1 ragge * Chris Torek.
8 1.1 ragge *
9 1.1 ragge * Redistribution and use in source and binary forms, with or without
10 1.1 ragge * modification, are permitted provided that the following conditions
11 1.1 ragge * are met:
12 1.1 ragge * 1. Redistributions of source code must retain the above copyright
13 1.1 ragge * notice, this list of conditions and the following disclaimer.
14 1.1 ragge * 2. Redistributions in binary form must reproduce the above copyright
15 1.1 ragge * notice, this list of conditions and the following disclaimer in the
16 1.1 ragge * documentation and/or other materials provided with the distribution.
17 1.24 agc * 3. Neither the name of the University nor the names of its contributors
18 1.24 agc * may be used to endorse or promote products derived from this software
19 1.24 agc * without specific prior written permission.
20 1.24 agc *
21 1.24 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 1.24 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 1.24 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 1.24 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 1.24 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 1.24 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 1.24 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.24 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 1.24 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 1.24 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 1.24 agc * SUCH DAMAGE.
32 1.24 agc *
33 1.24 agc * @(#)mscp.c 7.5 (Berkeley) 12/16/90
34 1.24 agc */
35 1.24 agc
36 1.24 agc /*
37 1.24 agc * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
38 1.24 agc *
39 1.24 agc * This code is derived from software contributed to Berkeley by
40 1.24 agc * Chris Torek.
41 1.24 agc *
42 1.24 agc * Redistribution and use in source and binary forms, with or without
43 1.24 agc * modification, are permitted provided that the following conditions
44 1.24 agc * are met:
45 1.24 agc * 1. Redistributions of source code must retain the above copyright
46 1.24 agc * notice, this list of conditions and the following disclaimer.
47 1.24 agc * 2. Redistributions in binary form must reproduce the above copyright
48 1.24 agc * notice, this list of conditions and the following disclaimer in the
49 1.24 agc * documentation and/or other materials provided with the distribution.
50 1.1 ragge * 3. All advertising materials mentioning features or use of this software
51 1.1 ragge * must display the following acknowledgement:
52 1.1 ragge * This product includes software developed by the University of
53 1.1 ragge * California, Berkeley and its contributors.
54 1.1 ragge * 4. Neither the name of the University nor the names of its contributors
55 1.1 ragge * may be used to endorse or promote products derived from this software
56 1.1 ragge * without specific prior written permission.
57 1.1 ragge *
58 1.1 ragge * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 1.1 ragge * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 1.1 ragge * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 1.1 ragge * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 1.1 ragge * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 1.1 ragge * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 1.1 ragge * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 1.1 ragge * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 1.1 ragge * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 1.1 ragge * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 1.1 ragge * SUCH DAMAGE.
69 1.1 ragge *
70 1.1 ragge * @(#)mscp.c 7.5 (Berkeley) 12/16/90
71 1.1 ragge */
72 1.1 ragge
73 1.1 ragge /*
74 1.1 ragge * MSCP generic driver routines
75 1.1 ragge */
76 1.18 lukem
77 1.18 lukem #include <sys/cdefs.h>
78 1.38 dsl __KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.38 2009/03/14 15:36:19 dsl Exp $");
79 1.1 ragge
80 1.1 ragge #include <sys/param.h>
81 1.2 ragge #include <sys/device.h>
82 1.1 ragge #include <sys/buf.h>
83 1.25 yamt #include <sys/bufq.h>
84 1.6 ragge #include <sys/systm.h>
85 1.6 ragge #include <sys/proc.h>
86 1.37 mjf #include <sys/kmem.h>
87 1.1 ragge
88 1.34 ad #include <sys/bus.h>
89 1.1 ragge #include <machine/sid.h>
90 1.1 ragge
91 1.12 ragge #include <dev/mscp/mscp.h>
92 1.12 ragge #include <dev/mscp/mscpreg.h>
93 1.12 ragge #include <dev/mscp/mscpvar.h>
94 1.1 ragge
95 1.1 ragge #include "ra.h"
96 1.2 ragge #include "mt.h"
97 1.1 ragge
98 1.9 ragge #define b_forw b_hash.le_next
99 1.1 ragge
100 1.26 perry int mscp_match(struct device *, struct cfdata *, void *);
101 1.26 perry void mscp_attach(struct device *, struct device *, void *);
102 1.26 perry void mscp_start(struct mscp_softc *);
103 1.26 perry int mscp_init(struct mscp_softc *);
104 1.26 perry void mscp_initds(struct mscp_softc *);
105 1.26 perry int mscp_waitstep(struct mscp_softc *, int, int);
106 1.1 ragge
107 1.21 thorpej CFATTACH_DECL(mscpbus, sizeof(struct mscp_softc),
108 1.22 thorpej mscp_match, mscp_attach, NULL, NULL);
109 1.1 ragge
110 1.12 ragge #define READ_SA (bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
111 1.12 ragge #define READ_IP (bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
112 1.12 ragge #define WRITE_IP(x) bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
113 1.12 ragge #define WRITE_SW(x) bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
114 1.12 ragge
115 1.1 ragge struct mscp slavereply;
116 1.1 ragge
117 1.37 mjf #define NITEMS 4
118 1.37 mjf
119 1.37 mjf static inline void
120 1.37 mjf mscp_free_workitems(struct mscp_softc *mi)
121 1.37 mjf {
122 1.37 mjf struct mscp_work *mw;
123 1.37 mjf
124 1.37 mjf while (!SLIST_EMPTY(&mi->mi_freelist)) {
125 1.37 mjf mw = SLIST_FIRST(&mi->mi_freelist);
126 1.37 mjf SLIST_REMOVE_HEAD(&mi->mi_freelist, mw_list);
127 1.37 mjf kmem_free(mw, sizeof(*mw));
128 1.37 mjf }
129 1.37 mjf }
130 1.37 mjf
131 1.1 ragge /*
132 1.1 ragge * This function is for delay during init. Some MSCP clone card (Dilog)
133 1.1 ragge * can't handle fast read from its registers, and therefore need
134 1.1 ragge * a delay between them.
135 1.1 ragge */
136 1.1 ragge
137 1.1 ragge #define DELAYTEN 1000
138 1.1 ragge int
139 1.1 ragge mscp_waitstep(mi, mask, result)
140 1.1 ragge struct mscp_softc *mi;
141 1.1 ragge int mask, result;
142 1.1 ragge {
143 1.1 ragge int status = 1;
144 1.1 ragge
145 1.12 ragge if ((READ_SA & mask) != result) {
146 1.1 ragge volatile int count = 0;
147 1.12 ragge while ((READ_SA & mask) != result) {
148 1.1 ragge DELAY(10000);
149 1.1 ragge count += 1;
150 1.1 ragge if (count > DELAYTEN)
151 1.1 ragge break;
152 1.1 ragge }
153 1.1 ragge if (count > DELAYTEN)
154 1.1 ragge status = 0;
155 1.1 ragge }
156 1.1 ragge return status;
157 1.1 ragge }
158 1.1 ragge
159 1.1 ragge int
160 1.38 dsl mscp_match(struct device *parent, struct cfdata *match, void *aux)
161 1.1 ragge {
162 1.1 ragge struct mscp_attach_args *ma = aux;
163 1.1 ragge
164 1.9 ragge #if NRA || NRX
165 1.1 ragge if (ma->ma_type & MSCPBUS_DISK)
166 1.1 ragge return 1;
167 1.1 ragge #endif
168 1.1 ragge #if NMT
169 1.1 ragge if (ma->ma_type & MSCPBUS_TAPE)
170 1.1 ragge return 1;
171 1.1 ragge #endif
172 1.1 ragge return 0;
173 1.1 ragge };
174 1.1 ragge
175 1.1 ragge void
176 1.1 ragge mscp_attach(parent, self, aux)
177 1.1 ragge struct device *parent, *self;
178 1.1 ragge void *aux;
179 1.1 ragge {
180 1.1 ragge struct mscp_attach_args *ma = aux;
181 1.32 thorpej struct mscp_softc *mi = device_private(self);
182 1.28 ragge struct mscp *mp2;
183 1.9 ragge volatile struct mscp *mp;
184 1.1 ragge volatile int i;
185 1.37 mjf int timeout, error, next = 0;
186 1.1 ragge
187 1.1 ragge mi->mi_mc = ma->ma_mc;
188 1.1 ragge mi->mi_me = NULL;
189 1.1 ragge mi->mi_type = ma->ma_type;
190 1.1 ragge mi->mi_uda = ma->ma_uda;
191 1.12 ragge mi->mi_dmat = ma->ma_dmat;
192 1.12 ragge mi->mi_dmam = ma->ma_dmam;
193 1.12 ragge mi->mi_iot = ma->ma_iot;
194 1.12 ragge mi->mi_iph = ma->ma_iph;
195 1.12 ragge mi->mi_sah = ma->ma_sah;
196 1.12 ragge mi->mi_swh = ma->ma_swh;
197 1.1 ragge mi->mi_ivec = ma->ma_ivec;
198 1.3 ragge mi->mi_adapnr = ma->ma_adapnr;
199 1.3 ragge mi->mi_ctlrnr = ma->ma_ctlrnr;
200 1.1 ragge *ma->ma_softc = mi;
201 1.37 mjf
202 1.37 mjf mutex_init(&mi->mi_mtx, MUTEX_DEFAULT, IPL_VM);
203 1.37 mjf SLIST_INIT(&mi->mi_freelist);
204 1.37 mjf
205 1.37 mjf error = workqueue_create(&mi->mi_wq, "mscp_wq", mscp_worker, NULL,
206 1.37 mjf PRI_NONE, IPL_VM, 0);
207 1.37 mjf if (error != 0) {
208 1.37 mjf aprint_error_dev(&mi->mi_dev, "could not create workqueue");
209 1.37 mjf return;
210 1.37 mjf }
211 1.37 mjf
212 1.37 mjf /* Stick some items on the free list to be used in autoconf */
213 1.37 mjf for (i = 0; i < NITEMS; i++) {
214 1.37 mjf struct mscp_work *mw;
215 1.37 mjf
216 1.37 mjf if ((mw = kmem_zalloc(sizeof(*mw), KM_SLEEP)) == NULL) {
217 1.37 mjf mscp_free_workitems(mi);
218 1.37 mjf aprint_error_dev(&mi->mi_dev,
219 1.37 mjf "failed to allocate memory for work items");
220 1.37 mjf return;
221 1.37 mjf }
222 1.37 mjf
223 1.37 mjf SLIST_INSERT_HEAD(&mi->mi_freelist, mw, mw_list);
224 1.37 mjf }
225 1.37 mjf
226 1.1 ragge /*
227 1.1 ragge * Go out to init the bus, so that we can give commands
228 1.1 ragge * to its devices.
229 1.1 ragge */
230 1.9 ragge mi->mi_cmd.mri_size = NCMD;
231 1.9 ragge mi->mi_cmd.mri_desc = mi->mi_uda->mp_ca.ca_cmddsc;
232 1.9 ragge mi->mi_cmd.mri_ring = mi->mi_uda->mp_cmd;
233 1.9 ragge mi->mi_rsp.mri_size = NRSP;
234 1.9 ragge mi->mi_rsp.mri_desc = mi->mi_uda->mp_ca.ca_rspdsc;
235 1.9 ragge mi->mi_rsp.mri_ring = mi->mi_uda->mp_rsp;
236 1.29 yamt bufq_alloc(&mi->mi_resq, "fcfs", 0);
237 1.1 ragge
238 1.1 ragge if (mscp_init(mi)) {
239 1.35 cegger aprint_error_dev(&mi->mi_dev, "can't init, controller hung\n");
240 1.1 ragge return;
241 1.1 ragge }
242 1.12 ragge for (i = 0; i < NCMD; i++) {
243 1.12 ragge mi->mi_mxiuse |= (1 << i);
244 1.14 ragge if (bus_dmamap_create(mi->mi_dmat, (64*1024), 16, (64*1024),
245 1.12 ragge 0, BUS_DMA_NOWAIT, &mi->mi_xi[i].mxi_dmam)) {
246 1.12 ragge printf("Couldn't alloc dmamap %d\n", i);
247 1.12 ragge return;
248 1.12 ragge }
249 1.12 ragge }
250 1.27 perry
251 1.1 ragge
252 1.1 ragge #if NRA
253 1.1 ragge if (ma->ma_type & MSCPBUS_DISK) {
254 1.1 ragge extern struct mscp_device ra_device;
255 1.1 ragge
256 1.1 ragge mi->mi_me = &ra_device;
257 1.1 ragge }
258 1.1 ragge #endif
259 1.1 ragge #if NMT
260 1.1 ragge if (ma->ma_type & MSCPBUS_TAPE) {
261 1.1 ragge extern struct mscp_device mt_device;
262 1.1 ragge
263 1.1 ragge mi->mi_me = &mt_device;
264 1.1 ragge }
265 1.1 ragge #endif
266 1.1 ragge /*
267 1.1 ragge * Go out and search for sub-units on this MSCP bus,
268 1.1 ragge * and call config_found for each found.
269 1.1 ragge */
270 1.1 ragge findunit:
271 1.1 ragge mp = mscp_getcp(mi, MSCP_DONTWAIT);
272 1.1 ragge if (mp == NULL)
273 1.1 ragge panic("mscpattach: no packets");
274 1.1 ragge mp->mscp_opcode = M_OP_GETUNITST;
275 1.1 ragge mp->mscp_unit = next;
276 1.1 ragge mp->mscp_modifier = M_GUM_NEXTUNIT;
277 1.1 ragge *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
278 1.1 ragge slavereply.mscp_opcode = 0;
279 1.1 ragge
280 1.12 ragge i = bus_space_read_2(mi->mi_iot, mi->mi_iph, 0);
281 1.1 ragge mp = &slavereply;
282 1.1 ragge timeout = 1000;
283 1.1 ragge while (timeout-- > 0) {
284 1.1 ragge DELAY(10000);
285 1.1 ragge if (mp->mscp_opcode)
286 1.1 ragge goto gotit;
287 1.1 ragge }
288 1.5 christos printf("%s: no response to Get Unit Status request\n",
289 1.35 cegger device_xname(&mi->mi_dev));
290 1.1 ragge return;
291 1.1 ragge
292 1.1 ragge gotit: /*
293 1.1 ragge * Got a slave response. If the unit is there, use it.
294 1.1 ragge */
295 1.1 ragge switch (mp->mscp_status & M_ST_MASK) {
296 1.1 ragge
297 1.9 ragge case M_ST_SUCCESS: /* worked */
298 1.9 ragge case M_ST_AVAILABLE: /* found another drive */
299 1.9 ragge break; /* use it */
300 1.1 ragge
301 1.1 ragge case M_ST_OFFLINE:
302 1.1 ragge /*
303 1.1 ragge * Figure out why it is off line. It may be because
304 1.9 ragge * it is nonexistent, or because it is spun down, or
305 1.9 ragge * for some other reason.
306 1.9 ragge */
307 1.9 ragge switch (mp->mscp_status & ~M_ST_MASK) {
308 1.9 ragge
309 1.9 ragge case M_OFFLINE_UNKNOWN:
310 1.9 ragge /*
311 1.9 ragge * No such drive, and there are none with
312 1.9 ragge * higher unit numbers either, if we are
313 1.9 ragge * using M_GUM_NEXTUNIT.
314 1.9 ragge */
315 1.2 ragge mi->mi_ierr = 3;
316 1.9 ragge return;
317 1.9 ragge
318 1.9 ragge case M_OFFLINE_UNMOUNTED:
319 1.9 ragge /*
320 1.9 ragge * The drive is not spun up. Use it anyway.
321 1.9 ragge *
322 1.9 ragge * N.B.: this seems to be a common occurrance
323 1.9 ragge * after a power failure. The first attempt
324 1.9 ragge * to bring it on line seems to spin it up
325 1.9 ragge * (and thus takes several minutes). Perhaps
326 1.9 ragge * we should note here that the on-line may
327 1.9 ragge * take longer than usual.
328 1.9 ragge */
329 1.9 ragge break;
330 1.1 ragge
331 1.9 ragge default:
332 1.9 ragge /*
333 1.9 ragge * In service, or something else equally unusable.
334 1.9 ragge */
335 1.35 cegger printf("%s: unit %d off line: ", device_xname(&mi->mi_dev),
336 1.9 ragge mp->mscp_unit);
337 1.28 ragge mp2 = __UNVOLATILE(mp);
338 1.28 ragge mscp_printevent(mp2);
339 1.1 ragge next++;
340 1.9 ragge goto findunit;
341 1.9 ragge }
342 1.9 ragge break;
343 1.1 ragge
344 1.9 ragge default:
345 1.35 cegger aprint_error_dev(&mi->mi_dev, "unable to get unit status: ");
346 1.28 ragge mscp_printevent(__UNVOLATILE(mp));
347 1.9 ragge return;
348 1.9 ragge }
349 1.9 ragge
350 1.9 ragge /*
351 1.9 ragge * If we get a lower number, we have circulated around all
352 1.1 ragge * devices and are finished, otherwise try to find next unit.
353 1.2 ragge * We shouldn't ever get this, it's a workaround.
354 1.9 ragge */
355 1.9 ragge if (mp->mscp_unit < next)
356 1.9 ragge return;
357 1.1 ragge
358 1.1 ragge next = mp->mscp_unit + 1;
359 1.1 ragge goto findunit;
360 1.1 ragge }
361 1.1 ragge
362 1.1 ragge
363 1.1 ragge /*
364 1.27 perry * The ctlr gets initialised, normally after boot but may also be
365 1.1 ragge * done if the ctlr gets in an unknown state. Returns 1 if init
366 1.1 ragge * fails, 0 otherwise.
367 1.1 ragge */
368 1.1 ragge int
369 1.38 dsl mscp_init(struct mscp_softc *mi)
370 1.1 ragge {
371 1.1 ragge struct mscp *mp;
372 1.1 ragge volatile int i;
373 1.1 ragge int status, count;
374 1.6 ragge unsigned int j = 0;
375 1.1 ragge
376 1.9 ragge /*
377 1.9 ragge * While we are thinking about it, reset the next command
378 1.9 ragge * and response indicies.
379 1.9 ragge */
380 1.1 ragge mi->mi_cmd.mri_next = 0;
381 1.1 ragge mi->mi_rsp.mri_next = 0;
382 1.1 ragge
383 1.1 ragge mi->mi_flags |= MSC_IGNOREINTR;
384 1.6 ragge
385 1.6 ragge if ((mi->mi_type & MSCPBUS_KDB) == 0)
386 1.12 ragge WRITE_IP(0); /* Kick off */;
387 1.6 ragge
388 1.1 ragge status = mscp_waitstep(mi, MP_STEP1, MP_STEP1);/* Wait to it wakes up */
389 1.1 ragge if (status == 0)
390 1.1 ragge return 1; /* Init failed */
391 1.12 ragge if (READ_SA & MP_ERR) {
392 1.31 thorpej (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0);
393 1.1 ragge return 1;
394 1.1 ragge }
395 1.1 ragge
396 1.1 ragge /* step1 */
397 1.12 ragge WRITE_SW(MP_ERR | (NCMDL2 << 11) | (NRSPL2 << 8) |
398 1.12 ragge MP_IE | (mi->mi_ivec >> 2));
399 1.1 ragge status = mscp_waitstep(mi, STEP1MASK, STEP1GOOD);
400 1.1 ragge if (status == 0) {
401 1.31 thorpej (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0);
402 1.1 ragge return 1;
403 1.1 ragge }
404 1.1 ragge
405 1.1 ragge /* step2 */
406 1.27 perry WRITE_SW(((mi->mi_dmam->dm_segs[0].ds_addr & 0xffff) +
407 1.12 ragge offsetof(struct mscp_pack, mp_ca.ca_rspdsc[0])) |
408 1.12 ragge (vax_cputype == VAX_780 || vax_cputype == VAX_8600 ? MP_PI : 0));
409 1.1 ragge status = mscp_waitstep(mi, STEP2MASK, STEP2GOOD(mi->mi_ivec >> 2));
410 1.9 ragge if (status == 0) {
411 1.31 thorpej (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0);
412 1.9 ragge return 1;
413 1.9 ragge }
414 1.1 ragge
415 1.1 ragge /* step3 */
416 1.12 ragge WRITE_SW((mi->mi_dmam->dm_segs[0].ds_addr >> 16));
417 1.1 ragge status = mscp_waitstep(mi, STEP3MASK, STEP3GOOD);
418 1.27 perry if (status == 0) {
419 1.31 thorpej (*mi->mi_mc->mc_saerror)(device_parent(&mi->mi_dev), 0);
420 1.9 ragge return 1;
421 1.9 ragge }
422 1.12 ragge i = READ_SA & 0377;
423 1.5 christos printf(": version %d model %d\n", i & 15, i >> 4);
424 1.1 ragge
425 1.9 ragge #define BURST 4 /* XXX */
426 1.1 ragge if (mi->mi_type & MSCPBUS_UDA) {
427 1.12 ragge WRITE_SW(MP_GO | (BURST - 1) << 2);
428 1.27 perry printf("%s: DMA burst size set to %d\n",
429 1.35 cegger device_xname(&mi->mi_dev), BURST);
430 1.1 ragge }
431 1.12 ragge WRITE_SW(MP_GO);
432 1.1 ragge
433 1.1 ragge mscp_initds(mi);
434 1.1 ragge mi->mi_flags &= ~MSC_IGNOREINTR;
435 1.1 ragge
436 1.1 ragge /*
437 1.1 ragge * Set up all necessary info in the bus softc struct, get a
438 1.1 ragge * mscp packet and set characteristics for this controller.
439 1.1 ragge */
440 1.1 ragge mi->mi_credits = MSCP_MINCREDITS + 1;
441 1.1 ragge mp = mscp_getcp(mi, MSCP_DONTWAIT);
442 1.2 ragge
443 1.1 ragge mi->mi_credits = 0;
444 1.1 ragge mp->mscp_opcode = M_OP_SETCTLRC;
445 1.2 ragge mp->mscp_unit = mp->mscp_modifier = mp->mscp_flags =
446 1.27 perry mp->mscp_sccc.sccc_version = mp->mscp_sccc.sccc_hosttimo =
447 1.2 ragge mp->mscp_sccc.sccc_time = mp->mscp_sccc.sccc_time1 =
448 1.2 ragge mp->mscp_sccc.sccc_errlgfl = 0;
449 1.1 ragge mp->mscp_sccc.sccc_ctlrflags = M_CF_ATTN | M_CF_MISC | M_CF_THIS;
450 1.1 ragge *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
451 1.12 ragge i = READ_IP;
452 1.1 ragge
453 1.9 ragge count = 0;
454 1.9 ragge while (count < DELAYTEN) {
455 1.10 ragge if (((volatile int)mi->mi_flags & MSC_READY) != 0)
456 1.9 ragge break;
457 1.12 ragge if ((j = READ_SA) & MP_ERR)
458 1.2 ragge goto out;
459 1.9 ragge DELAY(10000);
460 1.9 ragge count += 1;
461 1.9 ragge }
462 1.1 ragge if (count == DELAYTEN) {
463 1.2 ragge out:
464 1.35 cegger aprint_error_dev(&mi->mi_dev, "couldn't set ctlr characteristics, sa=%x\n", j);
465 1.1 ragge return 1;
466 1.1 ragge }
467 1.1 ragge return 0;
468 1.1 ragge }
469 1.1 ragge
470 1.1 ragge /*
471 1.1 ragge * Initialise the various data structures that control the mscp protocol.
472 1.1 ragge */
473 1.1 ragge void
474 1.38 dsl mscp_initds(struct mscp_softc *mi)
475 1.1 ragge {
476 1.1 ragge struct mscp_pack *ud = mi->mi_uda;
477 1.1 ragge struct mscp *mp;
478 1.1 ragge int i;
479 1.1 ragge
480 1.1 ragge for (i = 0, mp = ud->mp_rsp; i < NRSP; i++, mp++) {
481 1.1 ragge ud->mp_ca.ca_rspdsc[i] = MSCP_OWN | MSCP_INT |
482 1.12 ragge (mi->mi_dmam->dm_segs[0].ds_addr +
483 1.12 ragge offsetof(struct mscp_pack, mp_rsp[i].mscp_cmdref));
484 1.1 ragge mp->mscp_addr = &ud->mp_ca.ca_rspdsc[i];
485 1.1 ragge mp->mscp_msglen = MSCP_MSGLEN;
486 1.1 ragge }
487 1.1 ragge for (i = 0, mp = ud->mp_cmd; i < NCMD; i++, mp++) {
488 1.1 ragge ud->mp_ca.ca_cmddsc[i] = MSCP_INT |
489 1.12 ragge (mi->mi_dmam->dm_segs[0].ds_addr +
490 1.12 ragge offsetof(struct mscp_pack, mp_cmd[i].mscp_cmdref));
491 1.1 ragge mp->mscp_addr = &ud->mp_ca.ca_cmddsc[i];
492 1.1 ragge mp->mscp_msglen = MSCP_MSGLEN;
493 1.2 ragge if (mi->mi_type & MSCPBUS_TAPE)
494 1.2 ragge mp->mscp_vcid = 1;
495 1.1 ragge }
496 1.1 ragge }
497 1.1 ragge
498 1.12 ragge static void mscp_kickaway(struct mscp_softc *);
499 1.12 ragge
500 1.1 ragge void
501 1.38 dsl mscp_intr(struct mscp_softc *mi)
502 1.1 ragge {
503 1.1 ragge struct mscp_pack *ud = mi->mi_uda;
504 1.1 ragge
505 1.1 ragge if (mi->mi_flags & MSC_IGNOREINTR)
506 1.1 ragge return;
507 1.9 ragge /*
508 1.9 ragge * Check for response and command ring transitions.
509 1.9 ragge */
510 1.9 ragge if (ud->mp_ca.ca_rspint) {
511 1.9 ragge ud->mp_ca.ca_rspint = 0;
512 1.9 ragge mscp_dorsp(mi);
513 1.9 ragge }
514 1.9 ragge if (ud->mp_ca.ca_cmdint) {
515 1.9 ragge ud->mp_ca.ca_cmdint = 0;
516 1.9 ragge MSCP_DOCMD(mi);
517 1.9 ragge }
518 1.6 ragge
519 1.6 ragge /*
520 1.12 ragge * If there are any not-yet-handled request, try them now.
521 1.6 ragge */
522 1.36 yamt if (bufq_peek(mi->mi_resq))
523 1.12 ragge mscp_kickaway(mi);
524 1.1 ragge }
525 1.1 ragge
526 1.1 ragge int
527 1.38 dsl mscp_print(void *aux, const char *name)
528 1.1 ragge {
529 1.9 ragge struct drive_attach_args *da = aux;
530 1.9 ragge struct mscp *mp = da->da_mp;
531 1.9 ragge int type = mp->mscp_guse.guse_mediaid;
532 1.9 ragge
533 1.9 ragge if (name) {
534 1.23 thorpej aprint_normal("%c%c", MSCP_MID_CHAR(2, type),
535 1.23 thorpej MSCP_MID_CHAR(1, type));
536 1.9 ragge if (MSCP_MID_ECH(0, type))
537 1.23 thorpej aprint_normal("%c", MSCP_MID_CHAR(0, type));
538 1.23 thorpej aprint_normal("%d at %s drive %d", MSCP_MID_NUM(type), name,
539 1.9 ragge mp->mscp_unit);
540 1.9 ragge }
541 1.1 ragge return UNCONF;
542 1.1 ragge }
543 1.1 ragge
544 1.1 ragge /*
545 1.1 ragge * common strategy routine for all types of MSCP devices.
546 1.1 ragge */
547 1.1 ragge void
548 1.38 dsl mscp_strategy(struct buf *bp, struct device *usc)
549 1.1 ragge {
550 1.1 ragge struct mscp_softc *mi = (void *)usc;
551 1.17 thorpej int s = spluba();
552 1.12 ragge
553 1.36 yamt bufq_put(mi->mi_resq, bp);
554 1.12 ragge mscp_kickaway(mi);
555 1.12 ragge splx(s);
556 1.12 ragge }
557 1.12 ragge
558 1.12 ragge
559 1.12 ragge void
560 1.38 dsl mscp_kickaway(struct mscp_softc *mi)
561 1.12 ragge {
562 1.12 ragge struct buf *bp;
563 1.1 ragge struct mscp *mp;
564 1.12 ragge int next;
565 1.1 ragge
566 1.36 yamt while ((bp = bufq_peek(mi->mi_resq)) != NULL) {
567 1.12 ragge /*
568 1.12 ragge * Ok; we are ready to try to start a xfer. Get a MSCP packet
569 1.12 ragge * and try to start...
570 1.12 ragge */
571 1.12 ragge if ((mp = mscp_getcp(mi, MSCP_DONTWAIT)) == NULL) {
572 1.12 ragge if (mi->mi_credits > MSCP_MINCREDITS)
573 1.12 ragge printf("%s: command ring too small\n",
574 1.35 cegger device_xname(device_parent(&mi->mi_dev)));
575 1.12 ragge /*
576 1.12 ragge * By some (strange) reason we didn't get a MSCP packet.
577 1.12 ragge * Just return and wait for free packets.
578 1.12 ragge */
579 1.12 ragge return;
580 1.12 ragge }
581 1.27 perry
582 1.12 ragge if ((next = (ffs(mi->mi_mxiuse) - 1)) < 0)
583 1.12 ragge panic("no mxi buffers");
584 1.12 ragge mi->mi_mxiuse &= ~(1 << next);
585 1.12 ragge if (mi->mi_xi[next].mxi_inuse)
586 1.12 ragge panic("mxi inuse");
587 1.6 ragge /*
588 1.12 ragge * Set up the MSCP packet and ask the ctlr to start.
589 1.6 ragge */
590 1.12 ragge mp->mscp_opcode =
591 1.12 ragge (bp->b_flags & B_READ) ? M_OP_READ : M_OP_WRITE;
592 1.12 ragge mp->mscp_cmdref = next;
593 1.12 ragge mi->mi_xi[next].mxi_bp = bp;
594 1.12 ragge mi->mi_xi[next].mxi_mp = mp;
595 1.12 ragge mi->mi_xi[next].mxi_inuse = 1;
596 1.12 ragge bp->b_resid = next;
597 1.12 ragge (*mi->mi_me->me_fillin)(bp, mp);
598 1.31 thorpej (*mi->mi_mc->mc_go)(device_parent(&mi->mi_dev),
599 1.31 thorpej &mi->mi_xi[next]);
600 1.36 yamt (void)bufq_get(mi->mi_resq);
601 1.1 ragge }
602 1.1 ragge }
603 1.1 ragge
604 1.1 ragge void
605 1.38 dsl mscp_dgo(struct mscp_softc *mi, struct mscp_xi *mxi)
606 1.1 ragge {
607 1.1 ragge volatile int i;
608 1.1 ragge struct mscp *mp;
609 1.1 ragge
610 1.9 ragge /*
611 1.9 ragge * Fill in the MSCP packet and move the buffer to the I/O wait queue.
612 1.9 ragge */
613 1.12 ragge mp = mxi->mxi_mp;
614 1.12 ragge mp->mscp_seq.seq_buffer = mxi->mxi_dmam->dm_segs[0].ds_addr;
615 1.1 ragge
616 1.6 ragge *mp->mscp_addr |= MSCP_OWN | MSCP_INT;
617 1.12 ragge i = READ_IP;
618 1.1 ragge }
619 1.1 ragge
620 1.6 ragge #ifdef DIAGNOSTIC
621 1.1 ragge /*
622 1.1 ragge * Dump the entire contents of an MSCP packet in hex. Mainly useful
623 1.1 ragge * for debugging....
624 1.1 ragge */
625 1.1 ragge void
626 1.38 dsl mscp_hexdump(struct mscp *mp)
627 1.1 ragge {
628 1.15 augustss long *p = (long *) mp;
629 1.15 augustss int i = mp->mscp_msglen;
630 1.1 ragge
631 1.1 ragge if (i > 256) /* sanity */
632 1.1 ragge i = 256;
633 1.1 ragge i /= sizeof (*p); /* ASSUMES MULTIPLE OF sizeof(long) */
634 1.1 ragge while (--i >= 0)
635 1.5 christos printf("0x%x ", (int)*p++);
636 1.5 christos printf("\n");
637 1.1 ragge }
638 1.6 ragge #endif
639 1.1 ragge
640 1.1 ragge /*
641 1.1 ragge * MSCP error reporting
642 1.1 ragge */
643 1.1 ragge
644 1.1 ragge /*
645 1.1 ragge * Messages for the various subcodes.
646 1.1 ragge */
647 1.1 ragge static char unknown_msg[] = "unknown subcode";
648 1.1 ragge
649 1.1 ragge /*
650 1.1 ragge * Subcodes for Success (0)
651 1.1 ragge */
652 1.28 ragge static const char *succ_msgs[] = {
653 1.1 ragge "normal", /* 0 */
654 1.1 ragge "spin down ignored", /* 1 = Spin-Down Ignored */
655 1.1 ragge "still connected", /* 2 = Still Connected */
656 1.1 ragge unknown_msg,
657 1.1 ragge "dup. unit #", /* 4 = Duplicate Unit Number */
658 1.1 ragge unknown_msg,
659 1.1 ragge unknown_msg,
660 1.1 ragge unknown_msg,
661 1.1 ragge "already online", /* 8 = Already Online */
662 1.1 ragge unknown_msg,
663 1.1 ragge unknown_msg,
664 1.1 ragge unknown_msg,
665 1.1 ragge unknown_msg,
666 1.1 ragge unknown_msg,
667 1.1 ragge unknown_msg,
668 1.1 ragge unknown_msg,
669 1.1 ragge "still online", /* 16 = Still Online */
670 1.1 ragge };
671 1.1 ragge
672 1.1 ragge /*
673 1.1 ragge * Subcodes for Invalid Command (1)
674 1.1 ragge */
675 1.28 ragge static const char *icmd_msgs[] = {
676 1.1 ragge "invalid msg length", /* 0 = Invalid Message Length */
677 1.1 ragge };
678 1.1 ragge
679 1.1 ragge /*
680 1.1 ragge * Subcodes for Command Aborted (2)
681 1.1 ragge */
682 1.1 ragge /* none known */
683 1.1 ragge
684 1.1 ragge /*
685 1.1 ragge * Subcodes for Unit Offline (3)
686 1.1 ragge */
687 1.28 ragge static const char *offl_msgs[] = {
688 1.1 ragge "unknown drive", /* 0 = Unknown, or online to other ctlr */
689 1.1 ragge "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */
690 1.1 ragge "inoperative", /* 2 = Unit Inoperative */
691 1.1 ragge unknown_msg,
692 1.1 ragge "duplicate", /* 4 = Duplicate Unit Number */
693 1.1 ragge unknown_msg,
694 1.1 ragge unknown_msg,
695 1.1 ragge unknown_msg,
696 1.1 ragge "in diagnosis", /* 8 = Disabled by FS or diagnostic */
697 1.1 ragge };
698 1.1 ragge
699 1.1 ragge /*
700 1.1 ragge * Subcodes for Unit Available (4)
701 1.1 ragge */
702 1.1 ragge /* none known */
703 1.1 ragge
704 1.1 ragge /*
705 1.1 ragge * Subcodes for Media Format Error (5)
706 1.1 ragge */
707 1.28 ragge static const char *media_fmt_msgs[] = {
708 1.1 ragge "fct unread - edc", /* 0 = FCT unreadable */
709 1.1 ragge "invalid sector header",/* 1 = Invalid Sector Header */
710 1.1 ragge "not 512 sectors", /* 2 = Not 512 Byte Sectors */
711 1.1 ragge "not formatted", /* 3 = Not Formatted */
712 1.1 ragge "fct ecc", /* 4 = FCT ECC */
713 1.1 ragge };
714 1.1 ragge
715 1.1 ragge /*
716 1.1 ragge * Subcodes for Write Protected (6)
717 1.1 ragge * N.B.: Code 6 subcodes are 7 bits higher than other subcodes
718 1.1 ragge * (i.e., bits 12-15).
719 1.1 ragge */
720 1.28 ragge static const char *wrprot_msgs[] = {
721 1.1 ragge unknown_msg,
722 1.1 ragge "software", /* 1 = Software Write Protect */
723 1.1 ragge "hardware", /* 2 = Hardware Write Protect */
724 1.1 ragge };
725 1.1 ragge
726 1.1 ragge /*
727 1.1 ragge * Subcodes for Compare Error (7)
728 1.1 ragge */
729 1.1 ragge /* none known */
730 1.1 ragge
731 1.1 ragge /*
732 1.1 ragge * Subcodes for Data Error (8)
733 1.1 ragge */
734 1.28 ragge static const char *data_msgs[] = {
735 1.1 ragge "forced error", /* 0 = Forced Error (software) */
736 1.1 ragge unknown_msg,
737 1.1 ragge "header compare", /* 2 = Header Compare Error */
738 1.1 ragge "sync timeout", /* 3 = Sync Timeout Error */
739 1.1 ragge unknown_msg,
740 1.1 ragge unknown_msg,
741 1.1 ragge unknown_msg,
742 1.1 ragge "uncorrectable ecc", /* 7 = Uncorrectable ECC */
743 1.1 ragge "1 symbol ecc", /* 8 = 1 bit ECC */
744 1.1 ragge "2 symbol ecc", /* 9 = 2 bit ECC */
745 1.1 ragge "3 symbol ecc", /* 10 = 3 bit ECC */
746 1.1 ragge "4 symbol ecc", /* 11 = 4 bit ECC */
747 1.1 ragge "5 symbol ecc", /* 12 = 5 bit ECC */
748 1.1 ragge "6 symbol ecc", /* 13 = 6 bit ECC */
749 1.1 ragge "7 symbol ecc", /* 14 = 7 bit ECC */
750 1.1 ragge "8 symbol ecc", /* 15 = 8 bit ECC */
751 1.1 ragge };
752 1.1 ragge
753 1.1 ragge /*
754 1.1 ragge * Subcodes for Host Buffer Access Error (9)
755 1.1 ragge */
756 1.28 ragge static const char *host_buffer_msgs[] = {
757 1.1 ragge unknown_msg,
758 1.1 ragge "odd xfer addr", /* 1 = Odd Transfer Address */
759 1.1 ragge "odd xfer count", /* 2 = Odd Transfer Count */
760 1.1 ragge "non-exist. memory", /* 3 = Non-Existent Memory */
761 1.1 ragge "memory parity", /* 4 = Memory Parity Error */
762 1.1 ragge };
763 1.1 ragge
764 1.1 ragge /*
765 1.1 ragge * Subcodes for Controller Error (10)
766 1.1 ragge */
767 1.28 ragge static const char *cntlr_msgs[] = {
768 1.1 ragge unknown_msg,
769 1.1 ragge "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */
770 1.1 ragge "edc", /* 2 = Error Detection Code? */
771 1.33 msaitoh "inconsistent internal data struct",/* 3 = Internal Error */
772 1.1 ragge };
773 1.1 ragge
774 1.1 ragge /*
775 1.1 ragge * Subcodes for Drive Error (11)
776 1.1 ragge */
777 1.28 ragge static const char *drive_msgs[] = {
778 1.1 ragge unknown_msg,
779 1.1 ragge "sdi command timeout", /* 1 = SDI Command Timeout */
780 1.1 ragge "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */
781 1.1 ragge "positioner", /* 3 = Positioner Error */
782 1.1 ragge "lost rd/wr ready", /* 4 = Lost R/W Ready Error */
783 1.1 ragge "drive clock dropout", /* 5 = Lost Drive Clock */
784 1.1 ragge "lost recvr ready", /* 6 = Lost Receiver Ready */
785 1.9 ragge "drive detected error", /* 7 = Drive Error */
786 1.1 ragge "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */
787 1.1 ragge };
788 1.1 ragge
789 1.1 ragge /*
790 1.1 ragge * The following table correlates message codes with the
791 1.1 ragge * decoding strings.
792 1.1 ragge */
793 1.1 ragge struct code_decode {
794 1.28 ragge const char *cdc_msg;
795 1.1 ragge int cdc_nsubcodes;
796 1.28 ragge const char **cdc_submsgs;
797 1.1 ragge } code_decode[] = {
798 1.9 ragge #define SC(m) sizeof (m) / sizeof (m[0]), m
799 1.1 ragge {"success", SC(succ_msgs)},
800 1.1 ragge {"invalid command", SC(icmd_msgs)},
801 1.1 ragge {"command aborted", 0, 0},
802 1.1 ragge {"unit offline", SC(offl_msgs)},
803 1.1 ragge {"unit available", 0, 0},
804 1.1 ragge {"media format error", SC(media_fmt_msgs)},
805 1.1 ragge {"write protected", SC(wrprot_msgs)},
806 1.1 ragge {"compare error", 0, 0},
807 1.1 ragge {"data error", SC(data_msgs)},
808 1.1 ragge {"host buffer access error", SC(host_buffer_msgs)},
809 1.1 ragge {"controller error", SC(cntlr_msgs)},
810 1.1 ragge {"drive error", SC(drive_msgs)},
811 1.1 ragge #undef SC
812 1.1 ragge };
813 1.1 ragge
814 1.1 ragge /*
815 1.1 ragge * Print the decoded error event from an MSCP error datagram.
816 1.1 ragge */
817 1.1 ragge void
818 1.38 dsl mscp_printevent(struct mscp *mp)
819 1.1 ragge {
820 1.15 augustss int event = mp->mscp_event;
821 1.15 augustss struct code_decode *cdc;
822 1.1 ragge int c, sc;
823 1.28 ragge const char *cm, *scm;
824 1.1 ragge
825 1.1 ragge /*
826 1.1 ragge * The code is the lower six bits of the event number (aka
827 1.1 ragge * status). If that is 6 (write protect), the subcode is in
828 1.1 ragge * bits 12-15; otherwise, it is in bits 5-11.
829 1.1 ragge * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE
830 1.1 ragge * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
831 1.1 ragge */
832 1.1 ragge c = event & M_ST_MASK;
833 1.1 ragge sc = (c != 6 ? event >> 5 : event >> 12) & 0x7ff;
834 1.1 ragge if (c >= sizeof code_decode / sizeof code_decode[0])
835 1.1 ragge cm = "- unknown code", scm = "??";
836 1.1 ragge else {
837 1.1 ragge cdc = &code_decode[c];
838 1.1 ragge cm = cdc->cdc_msg;
839 1.1 ragge if (sc >= cdc->cdc_nsubcodes)
840 1.1 ragge scm = unknown_msg;
841 1.1 ragge else
842 1.1 ragge scm = cdc->cdc_submsgs[sc];
843 1.1 ragge }
844 1.5 christos printf(" %s (%s) (code %d, subcode %d)\n", cm, scm, c, sc);
845 1.1 ragge }
846 1.1 ragge
847 1.28 ragge static const char *codemsg[16] = {
848 1.2 ragge "lbn", "code 1", "code 2", "code 3",
849 1.2 ragge "code 4", "code 5", "rbn", "code 7",
850 1.2 ragge "code 8", "code 9", "code 10", "code 11",
851 1.2 ragge "code 12", "code 13", "code 14", "code 15"
852 1.2 ragge };
853 1.1 ragge /*
854 1.1 ragge * Print the code and logical block number for an error packet.
855 1.1 ragge * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE
856 1.1 ragge * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
857 1.1 ragge */
858 1.2 ragge int
859 1.38 dsl mscp_decodeerror(const char *name, struct mscp *mp, struct mscp_softc *mi)
860 1.1 ragge {
861 1.2 ragge int issoft;
862 1.27 perry /*
863 1.2 ragge * We will get three sdi errors of type 11 after autoconfig
864 1.2 ragge * is finished; depending of searching for non-existing units.
865 1.2 ragge * How can we avoid this???
866 1.2 ragge */
867 1.2 ragge if (((mp->mscp_event & M_ST_MASK) == 11) && (mi->mi_ierr++ < 3))
868 1.2 ragge return 1;
869 1.1 ragge /*
870 1.1 ragge * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and
871 1.1 ragge * the logical block number. Code 0 is a regular block; code 6
872 1.1 ragge * is a replacement block. The remaining codes are currently
873 1.1 ragge * undefined. The code is in the upper four bits of the header
874 1.1 ragge * (bits 0-27 are the lbn).
875 1.1 ragge */
876 1.2 ragge issoft = mp->mscp_flags & (M_LF_SUCC | M_LF_CONT);
877 1.1 ragge #define BADCODE(h) (codemsg[(unsigned)(h) >> 28])
878 1.1 ragge #define BADLBN(h) ((h) & 0xfffffff)
879 1.1 ragge
880 1.5 christos printf("%s: drive %d %s error datagram%s:", name, mp->mscp_unit,
881 1.1 ragge issoft ? "soft" : "hard",
882 1.1 ragge mp->mscp_flags & M_LF_CONT ? " (continuing)" : "");
883 1.1 ragge switch (mp->mscp_format & 0377) {
884 1.1 ragge
885 1.1 ragge case M_FM_CTLRERR: /* controller error */
886 1.1 ragge break;
887 1.1 ragge
888 1.1 ragge case M_FM_BUSADDR: /* host memory access error */
889 1.5 christos printf(" memory addr 0x%x:", (int)mp->mscp_erd.erd_busaddr);
890 1.1 ragge break;
891 1.1 ragge
892 1.1 ragge case M_FM_DISKTRN:
893 1.5 christos printf(" unit %d: level %d retry %d, %s %d:",
894 1.1 ragge mp->mscp_unit,
895 1.1 ragge mp->mscp_erd.erd_level, mp->mscp_erd.erd_retry,
896 1.1 ragge BADCODE(mp->mscp_erd.erd_hdr),
897 1.1 ragge (int)BADLBN(mp->mscp_erd.erd_hdr));
898 1.1 ragge break;
899 1.1 ragge
900 1.1 ragge case M_FM_SDI:
901 1.5 christos printf(" unit %d: %s %d:", mp->mscp_unit,
902 1.1 ragge BADCODE(mp->mscp_erd.erd_hdr),
903 1.1 ragge (int)BADLBN(mp->mscp_erd.erd_hdr));
904 1.1 ragge break;
905 1.1 ragge
906 1.1 ragge case M_FM_SMLDSK:
907 1.5 christos printf(" unit %d: small disk error, cyl %d:",
908 1.1 ragge mp->mscp_unit, mp->mscp_erd.erd_sdecyl);
909 1.1 ragge break;
910 1.1 ragge
911 1.2 ragge case M_FM_TAPETRN:
912 1.5 christos printf(" unit %d: tape transfer error, grp 0x%x event 0%o:",
913 1.2 ragge mp->mscp_unit, mp->mscp_erd.erd_sdecyl, mp->mscp_event);
914 1.2 ragge break;
915 1.2 ragge
916 1.2 ragge case M_FM_STIERR:
917 1.5 christos printf(" unit %d: STI error, event 0%o:", mp->mscp_unit,
918 1.2 ragge mp->mscp_event);
919 1.2 ragge break;
920 1.2 ragge
921 1.1 ragge default:
922 1.5 christos printf(" unit %d: unknown error, format 0x%x:",
923 1.1 ragge mp->mscp_unit, mp->mscp_format);
924 1.1 ragge }
925 1.1 ragge mscp_printevent(mp);
926 1.2 ragge return 0;
927 1.1 ragge #undef BADCODE
928 1.1 ragge #undef BADLBN
929 1.1 ragge }
930