Improve eisa bus probe by deciding the number of logical eisa slots from
authormiod <miod@openbsd.org>
Fri, 25 Jul 2008 21:11:14 +0000 (21:11 +0000)
committermiod <miod@openbsd.org>
Fri, 25 Jul 2008 21:11:14 +0000 (21:11 +0000)
the motherboard eisa id, instead of using a ``one size fits all'' value which
is too large on more than half the eisa-capable alpha designs.

The id -> slot # logic is based on the alpha ECU configuration files, so we
should not perform worse than ECU itself (and see all slots ECU sees too).

sys/arch/alpha/eisa/eisa_machdep.c
sys/arch/alpha/eisa/eisa_machdep.h
sys/arch/alpha/pci/sio.c

index a4d6665..150af80 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: eisa_machdep.c,v 1.1 2008/07/19 18:13:06 miod Exp $ */
+/* $OpenBSD: eisa_machdep.c,v 1.2 2008/07/25 21:11:14 miod Exp $ */
 /* $NetBSD: eisa_machdep.c,v 1.1 2000/07/29 23:18:47 thorpej Exp $ */
 
 /*-
@@ -42,6 +42,8 @@
 #include <dev/eisa/eisareg.h>
 #include <dev/eisa/eisavar.h>
 
+int    eisa_compute_maxslots(const char *);
+
 #define        EISA_SLOT_HEADER_SIZE   31
 #define        EISA_SLOT_INFO_OFFSET   20
 
@@ -367,6 +369,15 @@ eisa_init(eisa_chipset_tag_t ec)
        printf("EISA config stride: %ld\n", eisa_config_stride);
 #endif
 
+       /*
+        * Read SLOT 0 (motherboard) id, and decide how many (logical)
+        * slots there are.
+        */
+       eisa_read_config_bytes(eisa_config_header_addr, eisaid, sizeof(eisaid));
+       eisaid[EISA_IDSTRINGLEN - 1] = '\0';    /* sanity */
+       ec->ec_maxslots = eisa_compute_maxslots((const char *)eisaid);
+       printf(": %s, %d slots", (const char *)eisaid, ec->ec_maxslots - 1);
+
        /*
         * Read the slot headers, and allocate config structures for
         * valid slots.
@@ -514,6 +525,11 @@ eisa_init(eisa_chipset_tag_t ec)
 #endif
                                continue;
                        }
+#ifdef EISA_DEBUG
+                       else
+                               printf("SLOT %d:%d settings\n",
+                                   ecud->ecud_slot, func);
+#endif
 
                        ecuf = malloc(sizeof(*ecuf), M_DEVBUF, M_WAITOK);
                        if (ecuf == NULL)
@@ -574,3 +590,39 @@ eisa_init(eisa_chipset_tag_t ec)
        free(cdata, M_TEMP);
        free(data, M_TEMP);
 }
+
+/*
+ * Return the number of logical slots a motherboard supports,
+ * from its signature.
+ */
+int
+eisa_compute_maxslots(const char *idstring)
+{
+       int nslots;
+
+       if (strcmp(idstring, "DEC2400") == 0)           /* Jensen */
+               nslots = 1 + 6;
+       else if (strcmp(idstring, "DEC2A01") == 0)      /* AS 2000/2100 */
+               nslots = 1 + 8;
+       else if (strcmp(idstring, "DEC5000") == 0)      /* AS 1000/600A */
+               nslots = 1 + 8;
+       else if (strcmp(idstring, "DEC5100") == 0)      /* AS 600 */
+               nslots = 1 + 4;
+       else if (strcmp(idstring, "DEC5301") == 0)      /* AS 800 */
+               nslots = 1 + 3;
+       else if (strcmp(idstring, "DEC6000") == 0)      /* AS 8200/8400 */
+               nslots = 1 + 8;
+       else if (strcmp(idstring, "DEC6400") == 0)      /* AS 4x00/1200 */
+               nslots = 1 + 3;
+       else {
+               /*
+                * Unrecognized design. Not likely to happen, since
+                * Digital ECU will not recognize it either.
+                * But just in case the EISA configuration data badly
+                * fooled us, return the largest possible value.
+                */
+               nslots = 1 + 8;
+       }
+
+       return nslots;
+}
index 7b90406..bdbc10b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: eisa_machdep.h,v 1.6 2008/07/19 18:13:06 miod Exp $   */
+/*     $OpenBSD: eisa_machdep.h,v 1.7 2008/07/25 21:11:14 miod Exp $   */
 /*     $NetBSD: eisa_machdep.h,v 1.1 1996/04/12 05:39:51 cgd Exp $     */
 
 /*
@@ -36,10 +36,10 @@ typedef int eisa_intr_handle_t;
 
 struct alpha_eisa_chipset {
        void    *ec_v;
+       int     ec_maxslots;
 
        void    (*ec_attach_hook)(struct device *, struct device *,
                    struct eisabus_attach_args *);
-       int     (*ec_maxslots)(void *);
        int     (*ec_intr_map)(void *, u_int,
                    eisa_intr_handle_t *);
        const char *(*ec_intr_string)(void *, eisa_intr_handle_t);
@@ -54,7 +54,7 @@ struct alpha_eisa_chipset {
 #define        eisa_attach_hook(p, s, a)                                       \
     (*(a)->eba_ec->ec_attach_hook)((p), (s), (a))
 #define        eisa_maxslots(c)                                                \
-    (*(c)->ec_maxslots)((c)->ec_v)
+    ((c)->ec_maxslots)
 #define        eisa_intr_map(c, i, hp)                                         \
     (*(c)->ec_intr_map)((c)->ec_v, (i), (hp))
 #define        eisa_intr_string(c, h)                                          \
index 34ff03f..c8d80c0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sio.c,v 1.33 2008/07/22 20:06:01 miod Exp $   */
+/*     $OpenBSD: sio.c,v 1.34 2008/07/25 21:11:15 miod Exp $   */
 /*     $NetBSD: sio.c,v 1.15 1996/12/05 01:39:36 cgd Exp $     */
 
 /*
@@ -91,7 +91,6 @@ void  sio_isa_attach_hook(struct device *, struct device *,
            struct isabus_attach_args *);
 void   sio_eisa_attach_hook(struct device *, struct device *,
            struct eisabus_attach_args *);
-int    sio_eisa_maxslots(void *);
 int    sio_eisa_intr_map(void *, u_int, eisa_intr_handle_t *);
 void   sio_bridge_callback(struct device *);
 
@@ -169,8 +168,8 @@ sio_bridge_callback(self)
 
        if (sc->sc_haseisa) {
                ec.ec_v = NULL;
+               ec.ec_maxslots = 0;     /* will be filled by attach_hook */
                ec.ec_attach_hook = sio_eisa_attach_hook;
-               ec.ec_maxslots = sio_eisa_maxslots;
                ec.ec_intr_map = sio_eisa_intr_map;
                ec.ec_intr_string = sio_intr_string;
                ec.ec_intr_establish = sio_intr_establish;
@@ -230,16 +229,6 @@ sio_eisa_attach_hook(parent, self, eba)
 #endif
 }
 
-int
-sio_eisa_maxslots(v)
-       void *v;
-{
-       /*
-        * None of the alpha backplanes has more than 8 physical slots.
-        */
-       return 9;
-}
-
 int
 sio_eisa_intr_map(v, irq, ihp)
        void *v;