1 /* $NetBSD: mscp_subr.c,v 1.40 2009/05/12 13:16:17 cegger Exp $ */
3 * Copyright (c) 1988 Regents of the University of California.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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.
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
33 * @(#)mscp.c 7.5 (Berkeley) 12/16/90
37 * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
39 * This code is derived from software contributed to Berkeley by
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
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.
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.
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
70 * @(#)mscp.c 7.5 (Berkeley) 12/16/90
74 * MSCP generic driver routines
77 #include <sys/cdefs.h>
78 __KERNEL_RCSID(0, "$NetBSD: mscp_subr.c,v 1.40 2009/05/12 13:16:17 cegger Exp $");
80 #include <sys/param.h>
81 #include <sys/device.h>
84 #include <sys/systm.h>
89 #include <machine/sid.h>
91 #include <dev/mscp/mscp.h>
92 #include <dev/mscp/mscpreg.h>
93 #include <dev/mscp/mscpvar.h>
98 #define b_forw b_hash.le_next
100 int mscp_match(device_t
, cfdata_t
, void *);
101 void mscp_attach(device_t
, device_t
, void *);
102 void mscp_start(struct mscp_softc
*);
103 int mscp_init(struct mscp_softc
*);
104 void mscp_initds(struct mscp_softc
*);
105 int mscp_waitstep(struct mscp_softc
*, int, int);
107 CFATTACH_DECL(mscpbus
, sizeof(struct mscp_softc
),
108 mscp_match
, mscp_attach
, NULL
, NULL
);
110 #define READ_SA (bus_space_read_2(mi->mi_iot, mi->mi_sah, 0))
111 #define READ_IP (bus_space_read_2(mi->mi_iot, mi->mi_iph, 0))
112 #define WRITE_IP(x) bus_space_write_2(mi->mi_iot, mi->mi_iph, 0, (x))
113 #define WRITE_SW(x) bus_space_write_2(mi->mi_iot, mi->mi_swh, 0, (x))
115 struct mscp slavereply
;
120 mscp_free_workitems(struct mscp_softc
*mi
)
122 struct mscp_work
*mw
;
124 while (!SLIST_EMPTY(&mi
->mi_freelist
)) {
125 mw
= SLIST_FIRST(&mi
->mi_freelist
);
126 SLIST_REMOVE_HEAD(&mi
->mi_freelist
, mw_list
);
127 kmem_free(mw
, sizeof(*mw
));
132 * This function is for delay during init. Some MSCP clone card (Dilog)
133 * can't handle fast read from its registers, and therefore need
134 * a delay between them.
137 #define DELAYTEN 1000
139 mscp_waitstep(struct mscp_softc
*mi
, int mask
, int result
)
143 if ((READ_SA
& mask
) != result
) {
144 volatile int count
= 0;
145 while ((READ_SA
& mask
) != result
) {
148 if (count
> DELAYTEN
)
151 if (count
> DELAYTEN
)
158 mscp_match(device_t parent
, cfdata_t match
, void *aux
)
160 struct mscp_attach_args
*ma
= aux
;
163 if (ma
->ma_type
& MSCPBUS_DISK
)
167 if (ma
->ma_type
& MSCPBUS_TAPE
)
174 mscp_attach(device_t parent
, device_t self
, void *aux
)
176 struct mscp_attach_args
*ma
= aux
;
177 struct mscp_softc
*mi
= device_private(self
);
179 volatile struct mscp
*mp
;
181 int timeout
, error
, next
= 0;
183 mi
->mi_mc
= ma
->ma_mc
;
185 mi
->mi_type
= ma
->ma_type
;
186 mi
->mi_uda
= ma
->ma_uda
;
187 mi
->mi_dmat
= ma
->ma_dmat
;
188 mi
->mi_dmam
= ma
->ma_dmam
;
189 mi
->mi_iot
= ma
->ma_iot
;
190 mi
->mi_iph
= ma
->ma_iph
;
191 mi
->mi_sah
= ma
->ma_sah
;
192 mi
->mi_swh
= ma
->ma_swh
;
193 mi
->mi_ivec
= ma
->ma_ivec
;
194 mi
->mi_adapnr
= ma
->ma_adapnr
;
195 mi
->mi_ctlrnr
= ma
->ma_ctlrnr
;
198 mutex_init(&mi
->mi_mtx
, MUTEX_DEFAULT
, IPL_VM
);
199 SLIST_INIT(&mi
->mi_freelist
);
201 error
= workqueue_create(&mi
->mi_wq
, "mscp_wq", mscp_worker
, NULL
,
202 PRI_NONE
, IPL_VM
, 0);
204 aprint_error_dev(&mi
->mi_dev
, "could not create workqueue");
208 /* Stick some items on the free list to be used in autoconf */
209 for (i
= 0; i
< NITEMS
; i
++) {
210 struct mscp_work
*mw
;
212 if ((mw
= kmem_zalloc(sizeof(*mw
), KM_SLEEP
)) == NULL
) {
213 mscp_free_workitems(mi
);
214 aprint_error_dev(&mi
->mi_dev
,
215 "failed to allocate memory for work items");
219 SLIST_INSERT_HEAD(&mi
->mi_freelist
, mw
, mw_list
);
223 * Go out to init the bus, so that we can give commands
226 mi
->mi_cmd
.mri_size
= NCMD
;
227 mi
->mi_cmd
.mri_desc
= mi
->mi_uda
->mp_ca
.ca_cmddsc
;
228 mi
->mi_cmd
.mri_ring
= mi
->mi_uda
->mp_cmd
;
229 mi
->mi_rsp
.mri_size
= NRSP
;
230 mi
->mi_rsp
.mri_desc
= mi
->mi_uda
->mp_ca
.ca_rspdsc
;
231 mi
->mi_rsp
.mri_ring
= mi
->mi_uda
->mp_rsp
;
232 bufq_alloc(&mi
->mi_resq
, "fcfs", 0);
235 aprint_error_dev(&mi
->mi_dev
, "can't init, controller hung\n");
238 for (i
= 0; i
< NCMD
; i
++) {
239 mi
->mi_mxiuse
|= (1 << i
);
240 if (bus_dmamap_create(mi
->mi_dmat
, (64*1024), 16, (64*1024),
241 0, BUS_DMA_NOWAIT
, &mi
->mi_xi
[i
].mxi_dmam
)) {
242 printf("Couldn't alloc dmamap %d\n", i
);
249 if (ma
->ma_type
& MSCPBUS_DISK
) {
250 extern struct mscp_device ra_device
;
252 mi
->mi_me
= &ra_device
;
256 if (ma
->ma_type
& MSCPBUS_TAPE
) {
257 extern struct mscp_device mt_device
;
259 mi
->mi_me
= &mt_device
;
263 * Go out and search for sub-units on this MSCP bus,
264 * and call config_found for each found.
267 mp
= mscp_getcp(mi
, MSCP_DONTWAIT
);
269 panic("mscpattach: no packets");
270 mp
->mscp_opcode
= M_OP_GETUNITST
;
271 mp
->mscp_unit
= next
;
272 mp
->mscp_modifier
= M_GUM_NEXTUNIT
;
273 *mp
->mscp_addr
|= MSCP_OWN
| MSCP_INT
;
274 slavereply
.mscp_opcode
= 0;
276 i
= bus_space_read_2(mi
->mi_iot
, mi
->mi_iph
, 0);
279 while (timeout
-- > 0) {
284 printf("%s: no response to Get Unit Status request\n",
285 device_xname(&mi
->mi_dev
));
289 * Got a slave response. If the unit is there, use it.
291 switch (mp
->mscp_status
& M_ST_MASK
) {
293 case M_ST_SUCCESS
: /* worked */
294 case M_ST_AVAILABLE
: /* found another drive */
299 * Figure out why it is off line. It may be because
300 * it is nonexistent, or because it is spun down, or
301 * for some other reason.
303 switch (mp
->mscp_status
& ~M_ST_MASK
) {
305 case M_OFFLINE_UNKNOWN
:
307 * No such drive, and there are none with
308 * higher unit numbers either, if we are
309 * using M_GUM_NEXTUNIT.
314 case M_OFFLINE_UNMOUNTED
:
316 * The drive is not spun up. Use it anyway.
318 * N.B.: this seems to be a common occurrance
319 * after a power failure. The first attempt
320 * to bring it on line seems to spin it up
321 * (and thus takes several minutes). Perhaps
322 * we should note here that the on-line may
323 * take longer than usual.
329 * In service, or something else equally unusable.
331 printf("%s: unit %d off line: ", device_xname(&mi
->mi_dev
),
333 mp2
= __UNVOLATILE(mp
);
334 mscp_printevent(mp2
);
341 aprint_error_dev(&mi
->mi_dev
, "unable to get unit status: ");
342 mscp_printevent(__UNVOLATILE(mp
));
347 * If we get a lower number, we have circulated around all
348 * devices and are finished, otherwise try to find next unit.
349 * We shouldn't ever get this, it's a workaround.
351 if (mp
->mscp_unit
< next
)
354 next
= mp
->mscp_unit
+ 1;
360 * The ctlr gets initialised, normally after boot but may also be
361 * done if the ctlr gets in an unknown state. Returns 1 if init
362 * fails, 0 otherwise.
365 mscp_init(struct mscp_softc
*mi
)
373 * While we are thinking about it, reset the next command
374 * and response indicies.
376 mi
->mi_cmd
.mri_next
= 0;
377 mi
->mi_rsp
.mri_next
= 0;
379 mi
->mi_flags
|= MSC_IGNOREINTR
;
381 if ((mi
->mi_type
& MSCPBUS_KDB
) == 0)
382 WRITE_IP(0); /* Kick off */;
384 status
= mscp_waitstep(mi
, MP_STEP1
, MP_STEP1
);/* Wait to it wakes up */
386 return 1; /* Init failed */
387 if (READ_SA
& MP_ERR
) {
388 (*mi
->mi_mc
->mc_saerror
)(device_parent(&mi
->mi_dev
), 0);
393 WRITE_SW(MP_ERR
| (NCMDL2
<< 11) | (NRSPL2
<< 8) |
394 MP_IE
| (mi
->mi_ivec
>> 2));
395 status
= mscp_waitstep(mi
, STEP1MASK
, STEP1GOOD
);
397 (*mi
->mi_mc
->mc_saerror
)(device_parent(&mi
->mi_dev
), 0);
402 WRITE_SW(((mi
->mi_dmam
->dm_segs
[0].ds_addr
& 0xffff) +
403 offsetof(struct mscp_pack
, mp_ca
.ca_rspdsc
[0])) |
404 (vax_cputype
== VAX_780
|| vax_cputype
== VAX_8600
? MP_PI
: 0));
405 status
= mscp_waitstep(mi
, STEP2MASK
, STEP2GOOD(mi
->mi_ivec
>> 2));
407 (*mi
->mi_mc
->mc_saerror
)(device_parent(&mi
->mi_dev
), 0);
412 WRITE_SW((mi
->mi_dmam
->dm_segs
[0].ds_addr
>> 16));
413 status
= mscp_waitstep(mi
, STEP3MASK
, STEP3GOOD
);
415 (*mi
->mi_mc
->mc_saerror
)(device_parent(&mi
->mi_dev
), 0);
419 printf(": version %d model %d\n", i
& 15, i
>> 4);
421 #define BURST 4 /* XXX */
422 if (mi
->mi_type
& MSCPBUS_UDA
) {
423 WRITE_SW(MP_GO
| (BURST
- 1) << 2);
424 printf("%s: DMA burst size set to %d\n",
425 device_xname(&mi
->mi_dev
), BURST
);
430 mi
->mi_flags
&= ~MSC_IGNOREINTR
;
433 * Set up all necessary info in the bus softc struct, get a
434 * mscp packet and set characteristics for this controller.
436 mi
->mi_credits
= MSCP_MINCREDITS
+ 1;
437 mp
= mscp_getcp(mi
, MSCP_DONTWAIT
);
440 mp
->mscp_opcode
= M_OP_SETCTLRC
;
441 mp
->mscp_unit
= mp
->mscp_modifier
= mp
->mscp_flags
=
442 mp
->mscp_sccc
.sccc_version
= mp
->mscp_sccc
.sccc_hosttimo
=
443 mp
->mscp_sccc
.sccc_time
= mp
->mscp_sccc
.sccc_time1
=
444 mp
->mscp_sccc
.sccc_errlgfl
= 0;
445 mp
->mscp_sccc
.sccc_ctlrflags
= M_CF_ATTN
| M_CF_MISC
| M_CF_THIS
;
446 *mp
->mscp_addr
|= MSCP_OWN
| MSCP_INT
;
450 while (count
< DELAYTEN
) {
451 if (((volatile int)mi
->mi_flags
& MSC_READY
) != 0)
453 if ((j
= READ_SA
) & MP_ERR
)
458 if (count
== DELAYTEN
) {
460 aprint_error_dev(&mi
->mi_dev
, "couldn't set ctlr characteristics, sa=%x\n", j
);
467 * Initialise the various data structures that control the mscp protocol.
470 mscp_initds(struct mscp_softc
*mi
)
472 struct mscp_pack
*ud
= mi
->mi_uda
;
476 for (i
= 0, mp
= ud
->mp_rsp
; i
< NRSP
; i
++, mp
++) {
477 ud
->mp_ca
.ca_rspdsc
[i
] = MSCP_OWN
| MSCP_INT
|
478 (mi
->mi_dmam
->dm_segs
[0].ds_addr
+
479 offsetof(struct mscp_pack
, mp_rsp
[i
].mscp_cmdref
));
480 mp
->mscp_addr
= &ud
->mp_ca
.ca_rspdsc
[i
];
481 mp
->mscp_msglen
= MSCP_MSGLEN
;
483 for (i
= 0, mp
= ud
->mp_cmd
; i
< NCMD
; i
++, mp
++) {
484 ud
->mp_ca
.ca_cmddsc
[i
] = MSCP_INT
|
485 (mi
->mi_dmam
->dm_segs
[0].ds_addr
+
486 offsetof(struct mscp_pack
, mp_cmd
[i
].mscp_cmdref
));
487 mp
->mscp_addr
= &ud
->mp_ca
.ca_cmddsc
[i
];
488 mp
->mscp_msglen
= MSCP_MSGLEN
;
489 if (mi
->mi_type
& MSCPBUS_TAPE
)
494 static void mscp_kickaway(struct mscp_softc
*);
497 mscp_intr(struct mscp_softc
*mi
)
499 struct mscp_pack
*ud
= mi
->mi_uda
;
501 if (mi
->mi_flags
& MSC_IGNOREINTR
)
504 * Check for response and command ring transitions.
506 if (ud
->mp_ca
.ca_rspint
) {
507 ud
->mp_ca
.ca_rspint
= 0;
510 if (ud
->mp_ca
.ca_cmdint
) {
511 ud
->mp_ca
.ca_cmdint
= 0;
516 * If there are any not-yet-handled request, try them now.
518 if (bufq_peek(mi
->mi_resq
))
523 mscp_print(void *aux
, const char *name
)
525 struct drive_attach_args
*da
= aux
;
526 struct mscp
*mp
= da
->da_mp
;
527 int type
= mp
->mscp_guse
.guse_mediaid
;
530 aprint_normal("%c%c", MSCP_MID_CHAR(2, type
),
531 MSCP_MID_CHAR(1, type
));
532 if (MSCP_MID_ECH(0, type
))
533 aprint_normal("%c", MSCP_MID_CHAR(0, type
));
534 aprint_normal("%d at %s drive %d", MSCP_MID_NUM(type
), name
,
541 * common strategy routine for all types of MSCP devices.
544 mscp_strategy(struct buf
*bp
, device_t usc
)
546 struct mscp_softc
*mi
= (void *)usc
;
549 bufq_put(mi
->mi_resq
, bp
);
556 mscp_kickaway(struct mscp_softc
*mi
)
562 while ((bp
= bufq_peek(mi
->mi_resq
)) != NULL
) {
564 * Ok; we are ready to try to start a xfer. Get a MSCP packet
565 * and try to start...
567 if ((mp
= mscp_getcp(mi
, MSCP_DONTWAIT
)) == NULL
) {
568 if (mi
->mi_credits
> MSCP_MINCREDITS
)
569 printf("%s: command ring too small\n",
570 device_xname(device_parent(&mi
->mi_dev
)));
572 * By some (strange) reason we didn't get a MSCP packet.
573 * Just return and wait for free packets.
578 if ((next
= (ffs(mi
->mi_mxiuse
) - 1)) < 0)
579 panic("no mxi buffers");
580 mi
->mi_mxiuse
&= ~(1 << next
);
581 if (mi
->mi_xi
[next
].mxi_inuse
)
584 * Set up the MSCP packet and ask the ctlr to start.
587 (bp
->b_flags
& B_READ
) ? M_OP_READ
: M_OP_WRITE
;
588 mp
->mscp_cmdref
= next
;
589 mi
->mi_xi
[next
].mxi_bp
= bp
;
590 mi
->mi_xi
[next
].mxi_mp
= mp
;
591 mi
->mi_xi
[next
].mxi_inuse
= 1;
593 (*mi
->mi_me
->me_fillin
)(bp
, mp
);
594 (*mi
->mi_mc
->mc_go
)(device_parent(&mi
->mi_dev
),
596 (void)bufq_get(mi
->mi_resq
);
601 mscp_dgo(struct mscp_softc
*mi
, struct mscp_xi
*mxi
)
607 * Fill in the MSCP packet and move the buffer to the I/O wait queue.
610 mp
->mscp_seq
.seq_buffer
= mxi
->mxi_dmam
->dm_segs
[0].ds_addr
;
612 *mp
->mscp_addr
|= MSCP_OWN
| MSCP_INT
;
618 * Dump the entire contents of an MSCP packet in hex. Mainly useful
622 mscp_hexdump(struct mscp
*mp
)
624 long *p
= (long *) mp
;
625 int i
= mp
->mscp_msglen
;
627 if (i
> 256) /* sanity */
629 i
/= sizeof (*p
); /* ASSUMES MULTIPLE OF sizeof(long) */
631 printf("0x%x ", (int)*p
++);
637 * MSCP error reporting
641 * Messages for the various subcodes.
643 static char unknown_msg
[] = "unknown subcode";
646 * Subcodes for Success (0)
648 static const char *succ_msgs
[] = {
650 "spin down ignored", /* 1 = Spin-Down Ignored */
651 "still connected", /* 2 = Still Connected */
653 "dup. unit #", /* 4 = Duplicate Unit Number */
657 "already online", /* 8 = Already Online */
665 "still online", /* 16 = Still Online */
669 * Subcodes for Invalid Command (1)
671 static const char *icmd_msgs
[] = {
672 "invalid msg length", /* 0 = Invalid Message Length */
676 * Subcodes for Command Aborted (2)
681 * Subcodes for Unit Offline (3)
683 static const char *offl_msgs
[] = {
684 "unknown drive", /* 0 = Unknown, or online to other ctlr */
685 "not mounted", /* 1 = Unmounted, or RUN/STOP at STOP */
686 "inoperative", /* 2 = Unit Inoperative */
688 "duplicate", /* 4 = Duplicate Unit Number */
692 "in diagnosis", /* 8 = Disabled by FS or diagnostic */
696 * Subcodes for Unit Available (4)
701 * Subcodes for Media Format Error (5)
703 static const char *media_fmt_msgs
[] = {
704 "fct unread - edc", /* 0 = FCT unreadable */
705 "invalid sector header",/* 1 = Invalid Sector Header */
706 "not 512 sectors", /* 2 = Not 512 Byte Sectors */
707 "not formatted", /* 3 = Not Formatted */
708 "fct ecc", /* 4 = FCT ECC */
712 * Subcodes for Write Protected (6)
713 * N.B.: Code 6 subcodes are 7 bits higher than other subcodes
714 * (i.e., bits 12-15).
716 static const char *wrprot_msgs
[] = {
718 "software", /* 1 = Software Write Protect */
719 "hardware", /* 2 = Hardware Write Protect */
723 * Subcodes for Compare Error (7)
728 * Subcodes for Data Error (8)
730 static const char *data_msgs
[] = {
731 "forced error", /* 0 = Forced Error (software) */
733 "header compare", /* 2 = Header Compare Error */
734 "sync timeout", /* 3 = Sync Timeout Error */
738 "uncorrectable ecc", /* 7 = Uncorrectable ECC */
739 "1 symbol ecc", /* 8 = 1 bit ECC */
740 "2 symbol ecc", /* 9 = 2 bit ECC */
741 "3 symbol ecc", /* 10 = 3 bit ECC */
742 "4 symbol ecc", /* 11 = 4 bit ECC */
743 "5 symbol ecc", /* 12 = 5 bit ECC */
744 "6 symbol ecc", /* 13 = 6 bit ECC */
745 "7 symbol ecc", /* 14 = 7 bit ECC */
746 "8 symbol ecc", /* 15 = 8 bit ECC */
750 * Subcodes for Host Buffer Access Error (9)
752 static const char *host_buffer_msgs
[] = {
754 "odd xfer addr", /* 1 = Odd Transfer Address */
755 "odd xfer count", /* 2 = Odd Transfer Count */
756 "non-exist. memory", /* 3 = Non-Existent Memory */
757 "memory parity", /* 4 = Memory Parity Error */
761 * Subcodes for Controller Error (10)
763 static const char *cntlr_msgs
[] = {
765 "serdes overrun", /* 1 = Serialiser/Deserialiser Overrun */
766 "edc", /* 2 = Error Detection Code? */
767 "inconsistent internal data struct",/* 3 = Internal Error */
771 * Subcodes for Drive Error (11)
773 static const char *drive_msgs
[] = {
775 "sdi command timeout", /* 1 = SDI Command Timeout */
776 "ctlr detected protocol",/* 2 = Controller Detected Protocol Error */
777 "positioner", /* 3 = Positioner Error */
778 "lost rd/wr ready", /* 4 = Lost R/W Ready Error */
779 "drive clock dropout", /* 5 = Lost Drive Clock */
780 "lost recvr ready", /* 6 = Lost Receiver Ready */
781 "drive detected error", /* 7 = Drive Error */
782 "ctlr detected pulse or parity",/* 8 = Pulse or Parity Error */
786 * The following table correlates message codes with the
792 const char **cdc_submsgs
;
794 #define SC(m) sizeof (m) / sizeof (m[0]), m
795 {"success", SC(succ_msgs
)},
796 {"invalid command", SC(icmd_msgs
)},
797 {"command aborted", 0, 0},
798 {"unit offline", SC(offl_msgs
)},
799 {"unit available", 0, 0},
800 {"media format error", SC(media_fmt_msgs
)},
801 {"write protected", SC(wrprot_msgs
)},
802 {"compare error", 0, 0},
803 {"data error", SC(data_msgs
)},
804 {"host buffer access error", SC(host_buffer_msgs
)},
805 {"controller error", SC(cntlr_msgs
)},
806 {"drive error", SC(drive_msgs
)},
811 * Print the decoded error event from an MSCP error datagram.
814 mscp_printevent(struct mscp
*mp
)
816 int event
= mp
->mscp_event
;
817 struct code_decode
*cdc
;
819 const char *cm
, *scm
;
822 * The code is the lower six bits of the event number (aka
823 * status). If that is 6 (write protect), the subcode is in
824 * bits 12-15; otherwise, it is in bits 5-11.
825 * I WONDER WHAT THE OTHER BITS ARE FOR. IT SURE WOULD BE
826 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
828 c
= event
& M_ST_MASK
;
829 sc
= (c
!= 6 ? event
>> 5 : event
>> 12) & 0x7ff;
830 if (c
>= sizeof code_decode
/ sizeof code_decode
[0])
831 cm
= "- unknown code", scm
= "??";
833 cdc
= &code_decode
[c
];
835 if (sc
>= cdc
->cdc_nsubcodes
)
838 scm
= cdc
->cdc_submsgs
[sc
];
840 printf(" %s (%s) (code %d, subcode %d)\n", cm
, scm
, c
, sc
);
843 static const char *codemsg
[16] = {
844 "lbn", "code 1", "code 2", "code 3",
845 "code 4", "code 5", "rbn", "code 7",
846 "code 8", "code 9", "code 10", "code 11",
847 "code 12", "code 13", "code 14", "code 15"
850 * Print the code and logical block number for an error packet.
851 * THIS IS PROBABLY PECULIAR TO DISK DRIVES. IT SURE WOULD BE
852 * NICE IF DEC SOLD DOCUMENTATION FOR THEIR OWN CONTROLLERS.
855 mscp_decodeerror(const char *name
, struct mscp
*mp
, struct mscp_softc
*mi
)
859 * We will get three sdi errors of type 11 after autoconfig
860 * is finished; depending of searching for non-existing units.
861 * How can we avoid this???
863 if (((mp
->mscp_event
& M_ST_MASK
) == 11) && (mi
->mi_ierr
++ < 3))
866 * For bad blocks, mp->mscp_erd.erd_hdr identifies a code and
867 * the logical block number. Code 0 is a regular block; code 6
868 * is a replacement block. The remaining codes are currently
869 * undefined. The code is in the upper four bits of the header
870 * (bits 0-27 are the lbn).
872 issoft
= mp
->mscp_flags
& (M_LF_SUCC
| M_LF_CONT
);
873 #define BADCODE(h) (codemsg[(unsigned)(h) >> 28])
874 #define BADLBN(h) ((h) & 0xfffffff)
876 printf("%s: drive %d %s error datagram%s:", name
, mp
->mscp_unit
,
877 issoft
? "soft" : "hard",
878 mp
->mscp_flags
& M_LF_CONT
? " (continuing)" : "");
879 switch (mp
->mscp_format
& 0377) {
881 case M_FM_CTLRERR
: /* controller error */
884 case M_FM_BUSADDR
: /* host memory access error */
885 printf(" memory addr 0x%x:", (int)mp
->mscp_erd
.erd_busaddr
);
889 printf(" unit %d: level %d retry %d, %s %d:",
891 mp
->mscp_erd
.erd_level
, mp
->mscp_erd
.erd_retry
,
892 BADCODE(mp
->mscp_erd
.erd_hdr
),
893 (int)BADLBN(mp
->mscp_erd
.erd_hdr
));
897 printf(" unit %d: %s %d:", mp
->mscp_unit
,
898 BADCODE(mp
->mscp_erd
.erd_hdr
),
899 (int)BADLBN(mp
->mscp_erd
.erd_hdr
));
903 printf(" unit %d: small disk error, cyl %d:",
904 mp
->mscp_unit
, mp
->mscp_erd
.erd_sdecyl
);
908 printf(" unit %d: tape transfer error, grp 0x%x event 0%o:",
909 mp
->mscp_unit
, mp
->mscp_erd
.erd_sdecyl
, mp
->mscp_event
);
913 printf(" unit %d: STI error, event 0%o:", mp
->mscp_unit
,
918 printf(" unit %d: unknown error, format 0x%x:",
919 mp
->mscp_unit
, mp
->mscp_format
);