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