Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc64 convert pci_intr_map() into a chipset tag f...



details:   https://anonhg.NetBSD.org/src/rev/ac089864df81
branches:  trunk
changeset: 749438:ac089864df81
user:      mrg <mrg%NetBSD.org@localhost>
date:      Mon Nov 30 05:00:58 2009 +0000

description:
convert pci_intr_map() into a chipset tag function pointer, and implement
the schizo version slightly differently.

pull out the schizo's IGN from the upaid, not the apparently broken device
ID register.  from openbsd.

with this i appear to have valid working interrupts on the SB2500.

tested on U60 and SB2500.


XXX: we can probably kill (*spc_find_ino)() now that pci_intr_map() itself
XXX: is no longer a first class function.

diffstat:

 sys/arch/sparc64/dev/pci_machdep.c     |  47 +---------------------------
 sys/arch/sparc64/dev/psycho.c          |  50 +++++++++++++++++++++++++++++-
 sys/arch/sparc64/dev/schizo.c          |  56 ++++++++++++++++++++++++++++++---
 sys/arch/sparc64/include/pci_machdep.h |   6 ++-
 4 files changed, 104 insertions(+), 55 deletions(-)

diffs (291 lines):

diff -r fca6f4e4386b -r ac089864df81 sys/arch/sparc64/dev/pci_machdep.c
--- a/sys/arch/sparc64/dev/pci_machdep.c        Mon Nov 30 01:58:49 2009 +0000
+++ b/sys/arch/sparc64/dev/pci_machdep.c        Mon Nov 30 05:00:58 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci_machdep.c,v 1.64 2009/11/28 21:32:46 mrg Exp $     */
+/*     $NetBSD: pci_machdep.c,v 1.65 2009/11/30 05:00:58 mrg Exp $     */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.64 2009/11/28 21:32:46 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.65 2009/11/30 05:00:58 mrg Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -375,49 +375,6 @@
        return (0);
 }
 
-/*
- * interrupt mapping foo.
- * XXX: how does this deal with multiple interrupts for a device?
- */
-int
-pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
-{
-       pcitag_t tag = pa->pa_tag;
-       int interrupts, *intp;
-       int len, node = PCITAG_NODE(tag);
-       char devtype[30];
-
-       intp = &interrupts;
-       len = 1;
-       if (prom_getprop(node, "interrupts", sizeof(interrupts),
-                       &len, &intp) != 0 || len != 1) {
-               DPRINTF(SPDB_INTMAP,
-                       ("pci_intr_map: could not read interrupts\n"));
-               return (ENODEV);
-       }
-
-       if (OF_mapintr(node, &interrupts, sizeof(interrupts), 
-               sizeof(interrupts)) < 0) {
-               printf("OF_mapintr failed\n");
-               KASSERT(pa->pa_pc->spc_find_ino);
-               pa->pa_pc->spc_find_ino(pa, &interrupts);
-       }
-       DPRINTF(SPDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts));
-
-       /* Try to find an IPL for this type of device. */
-       prom_getpropstringA(node, "device_type", devtype, sizeof(devtype));
-       for (len = 0; intrmap[len].in_class != NULL; len++)
-               if (strcmp(intrmap[len].in_class, devtype) == 0) {
-                       interrupts |= INTLEVENCODE(intrmap[len].in_lev);
-                       DPRINTF(SPDB_INTMAP, ("reset to %x\n", interrupts));
-                       break;
-               }
-
-       /* XXXX -- we use the ino.  What if there is a valid IGN? */
-       *ihp = interrupts;
-       return (0);
-}
-
 const char *
 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
 {
diff -r fca6f4e4386b -r ac089864df81 sys/arch/sparc64/dev/psycho.c
--- a/sys/arch/sparc64/dev/psycho.c     Mon Nov 30 01:58:49 2009 +0000
+++ b/sys/arch/sparc64/dev/psycho.c     Mon Nov 30 05:00:58 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: psycho.c,v 1.96 2009/11/27 22:31:29 mrg Exp $  */
+/*     $NetBSD: psycho.c,v 1.97 2009/11/30 05:00:58 mrg Exp $  */
 
 /*
  * Copyright (c) 1999, 2000 Matthew R. Green
@@ -55,7 +55,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.96 2009/11/27 22:31:29 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: psycho.c,v 1.97 2009/11/30 05:00:58 mrg Exp $");
 
 #include "opt_ddb.h"
 
@@ -116,6 +116,8 @@
 static pcireg_t        psycho_pci_conf_read(pci_chipset_tag_t, pcitag_t, int);
 static void    psycho_pci_conf_write(pci_chipset_tag_t, pcitag_t, int,
                                      pcireg_t);
+static int     psycho_pci_intr_map(struct pci_attach_args *,
+                                    pci_intr_handle_t *);
 static void    *psycho_pci_intr_establish(pci_chipset_tag_t,
                                           pci_intr_handle_t,
                                           int, int (*)(void *), void *);
@@ -751,6 +753,7 @@
        npc->rootnode = node;
        npc->spc_conf_read = psycho_pci_conf_read;
        npc->spc_conf_write = psycho_pci_conf_write;
+       npc->spc_intr_map = psycho_pci_intr_map;
        npc->spc_intr_establish = psycho_pci_intr_establish;
        npc->spc_find_ino = psycho_pci_find_ino;
 
@@ -1389,6 +1392,49 @@
                PCITAG_OFFSET(tag) + reg, data);
 }
 
+/*
+ * interrupt mapping foo.
+ * XXX: how does this deal with multiple interrupts for a device?
+ */
+int
+psycho_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
+{
+       pcitag_t tag = pa->pa_tag;
+       int interrupts, *intp;
+       int len, node = PCITAG_NODE(tag);
+       char devtype[30];
+
+       intp = &interrupts;
+       len = 1;
+       if (prom_getprop(node, "interrupts", sizeof(interrupts),
+                       &len, &intp) != 0 || len != 1) {
+               DPRINTF(PDB_INTMAP,
+                       ("pci_intr_map: could not read interrupts\n"));
+               return (ENODEV);
+       }
+
+       if (OF_mapintr(node, &interrupts, sizeof(interrupts), 
+               sizeof(interrupts)) < 0) {
+               printf("OF_mapintr failed\n");
+               KASSERT(pa->pa_pc->spc_find_ino);
+               pa->pa_pc->spc_find_ino(pa, &interrupts);
+       }
+       DPRINTF(PDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts));
+
+       /* Try to find an IPL for this type of device. */
+       prom_getpropstringA(node, "device_type", devtype, sizeof(devtype));
+       for (len = 0; intrmap[len].in_class != NULL; len++)
+               if (strcmp(intrmap[len].in_class, devtype) == 0) {
+                       interrupts |= INTLEVENCODE(intrmap[len].in_lev);
+                       DPRINTF(PDB_INTMAP, ("reset to %x\n", interrupts));
+                       break;
+               }
+
+       /* XXXX -- we use the ino.  What if there is a valid IGN? */
+       *ihp = interrupts;
+       return (0);
+}
+
 static void *
 psycho_pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
        int (*func)(void *), void *arg)
diff -r fca6f4e4386b -r ac089864df81 sys/arch/sparc64/dev/schizo.c
--- a/sys/arch/sparc64/dev/schizo.c     Mon Nov 30 01:58:49 2009 +0000
+++ b/sys/arch/sparc64/dev/schizo.c     Mon Nov 30 05:00:58 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: schizo.c,v 1.9 2009/11/27 22:31:29 mrg Exp $   */
+/*     $NetBSD: schizo.c,v 1.10 2009/11/30 05:00:58 mrg Exp $  */
 /*     $OpenBSD: schizo.c,v 1.55 2008/08/18 20:29:37 brad Exp $        */
 
 /*
@@ -94,13 +94,13 @@
 pcireg_t schizo_conf_read(pci_chipset_tag_t, pcitag_t, int);
 void schizo_conf_write(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
 
-int schizo_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 int schizo_bus_map(bus_space_tag_t t, bus_addr_t offset, bus_size_t size,
                   int flags, vaddr_t unused, bus_space_handle_t *hp);
 static paddr_t schizo_bus_mmap(bus_space_tag_t t, bus_addr_t paddr,
                                off_t off, int prot, int flags);
 static void *schizo_intr_establish(bus_space_tag_t, int, int, int (*)(void *),
        void *, void(*)(void));
+static int schizo_pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 static void *schizo_pci_intr_establish(pci_chipset_tag_t, pci_intr_handle_t,
                                        int, int (*)(void *), void *);
 static int schizo_pci_find_ino(struct pci_attach_args *, pci_intr_handle_t *);
@@ -136,7 +136,7 @@
 {
        struct schizo_softc *sc = (struct schizo_softc *)self;
        struct mainbus_attach_args *ma = aux;
-       uint64_t eccctrl, csr;
+       uint64_t eccctrl;
        char *str;
 
        printf(": addr %lx", ma->ma_reg[0].ur_paddr);
@@ -157,9 +157,7 @@
                return;
        }
 
-       csr = schizo_read(sc, SCZ_CONTROL_STATUS);
-       sc->sc_ign = ((csr & SCZ_CONTROL_STATUS_AID_MASK) >>
-                      SCZ_CONTROL_STATUS_AID_SHIFT);
+       sc->sc_ign = INTIGN(ma->ma_upaid << INTMAP_IGN_SHIFT);
 
        /* enable schizo ecc error interrupts */
        eccctrl = schizo_read(sc, SCZ_ECCCTRL);
@@ -587,6 +585,7 @@
        npc->rootnode = node;
        npc->spc_conf_read = schizo_conf_read;
        npc->spc_conf_write = schizo_conf_write;
+       npc->spc_intr_map = schizo_pci_intr_map;
        npc->spc_intr_establish = schizo_pci_intr_establish;
        npc->spc_find_ino = schizo_pci_find_ino;
        return (npc);
@@ -682,6 +681,51 @@
        return (-1);
 }
 
+/*
+ * interrupt mapping foo.
+ * XXX: how does this deal with multiple interrupts for a device?
+ */
+int
+schizo_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
+{
+       pcitag_t tag = pa->pa_tag;
+       struct schizo_pbm *pbm = pa->pa_pc->cookie;
+       struct schizo_softc *sc = pbm->sp_sc;
+       int interrupts, *intp;
+       int len, node = PCITAG_NODE(tag);
+       char devtype[30];
+
+       intp = &interrupts;
+       len = 1;
+       if (prom_getprop(node, "interrupts", sizeof(interrupts),
+                       &len, &intp) != 0 || len != 1) {
+               DPRINTF(SDB_INTMAP,
+                       ("pci_intr_map: could not read interrupts\n"));
+               return (ENODEV);
+       }
+
+       if (OF_mapintr(node, &interrupts, sizeof(interrupts), 
+               sizeof(interrupts)) < 0) {
+               printf("OF_mapintr failed\n");
+               KASSERT(pa->pa_pc->spc_find_ino);
+               pa->pa_pc->spc_find_ino(pa, &interrupts);
+       }
+       DPRINTF(SDB_INTMAP, ("OF_mapintr() gave %x\n", interrupts));
+
+       /* Try to find an IPL for this type of device. */
+       prom_getpropstringA(node, "device_type", devtype, sizeof(devtype));
+       for (len = 0; intrmap[len].in_class != NULL; len++)
+               if (strcmp(intrmap[len].in_class, devtype) == 0) {
+                       interrupts |= INTLEVENCODE(intrmap[len].in_lev);
+                       DPRINTF(SDB_INTMAP, ("reset to %x\n", interrupts));
+                       break;
+               }
+
+       *ihp = interrupts | sc->sc_ign;
+       DPRINTF(SDB_INTMAP, ("returning IGN adjusted to %x\n", *ihp));
+       return (0);
+}
+
 static void *
 schizo_intr_establish(bus_space_tag_t t, int ihandle, int level,
        int (*handler)(void *), void *arg, void (*fastvec)(void) /* ignored */)
diff -r fca6f4e4386b -r ac089864df81 sys/arch/sparc64/include/pci_machdep.h
--- a/sys/arch/sparc64/include/pci_machdep.h    Mon Nov 30 01:58:49 2009 +0000
+++ b/sys/arch/sparc64/include/pci_machdep.h    Mon Nov 30 05:00:58 2009 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci_machdep.h,v 1.22 2008/12/10 03:31:51 mrg Exp $ */
+/* $NetBSD: pci_machdep.h,v 1.23 2009/11/30 05:00:58 mrg Exp $ */
 
 /*
  * Copyright (c) 1999 Matthew R. Green
@@ -67,6 +67,7 @@
        pcireg_t        (*spc_conf_read)(pci_chipset_tag_t, pcitag_t, int);
        void            (*spc_conf_write)(pci_chipset_tag_t, pcitag_t, int, pcireg_t);
 
+       int             (*spc_intr_map)(struct pci_attach_args *, pci_intr_handle_t *);
        void            *(*spc_intr_establish)(pci_chipset_tag_t, pci_intr_handle_t, int, int (*)(void *), void *);
 
        /* private interfaces */
@@ -87,7 +88,6 @@
 pcitag_t       pci_make_tag(pci_chipset_tag_t, int, int, int);
 void           pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, int *,
                    int *);
-int            pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
 const char     *pci_intr_string(pci_chipset_tag_t, pci_intr_handle_t);
 const struct evcnt *pci_intr_evcnt(pci_chipset_tag_t, pci_intr_handle_t);
 void           pci_intr_disestablish(pci_chipset_tag_t, void *);
@@ -101,6 +101,8 @@
                ((pc)->spc_conf_read(pc, tag, reg))
 #define        pci_conf_write(pc, tag, reg, val) \
                ((pc)->spc_conf_write(pc, tag, reg, val))
+#define        pci_intr_map(pa, handle) \
+               ((pa)->pa_pc->spc_intr_map(pa, handle))
 #define        pci_intr_establish(pc, handle, level, func, arg) \
                ((pc)->spc_intr_establish(pc, handle, level, func, arg))
 



Home | Main Index | Thread Index | Old Index