Port-sparc64 archive

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

Re: 4.99.51 kernel crashes while detecting a PCI card



On Sat, Feb 02, 2008 at 10:55:02AM +0000, Matthias Scheler wrote:
> And here is what "gdb" found:
> 
> (gdb) list *(config_attach_loc+0x158)
> 0x1221798 is in config_attach_loc 
> (/src/NetBSD-current/src/sys/kern/subr_autoconf.c:1276).
> 1271
> 1272    #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
> 1273            if (splash_progress_state)
> 1274                    splash_progress_update(splash_progress_state);
> 1275    #endif
> 1276            (*dev->dv_cfattach->ca_attach)(parent, dev, aux);
> 1277    #if defined(SPLASHSCREEN) && defined(SPLASHSCREEN_PROGRESS)
> 1278            if (splash_progress_state)
> 1279                    splash_progress_update(splash_progress_state);
> 1280    #endif

I realized that the backtrace didn't give the right function. Here is
what disassembling at the report instruction pointer prints out:

0x12eac60 is in pci_conf_read 
(/src/NetBSD-current/src/sys/arch/sparc64/dev/pci_machdep.c:379).
374     /* assume we are mapped little-endian/side-effect */
375     pcireg_t
376     pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
377     {
378             struct psycho_pbm *pp = pc->cookie;
379             struct psycho_softc *sc = pp->pp_sc;
380             pcireg_t val = (pcireg_t)~0;
381     
382             DPRINTF(SPDB_CONF, ("pci_conf_read: tag %lx reg %x ", 
383                     (long)tag, reg));

I've chaned the code to ...

        struct psycho_pbm *pp;
        struct psycho_softc *sc;
        pcireg_t val = (pcireg_t)~0;

        KASSERT(pc != NULL);
        pp = pc->cookie;
        KASSERT(pp != NULL);
        sc = pp->pp_sc;

... and got this panic:

pci1 at psycho1
bge0 at pci1 dev 1 function 0: Broadcom BCM5701 Gigabit Ethernet
panic: kernel diagnostic assertion "pc != NULL" failed: file 
"/src/NetBSD-current/src/sys/arch/sparc64/dev/pci_machdep.c", line 387

cpu0: kdb breakpoint at 134a100
Stopped in pid 0.1 (system) at  netbsd:cpu_Debugger+0x4:        nop
db> bt
__kernassert(1473b88, 14c80f0, 183, 149bc80, 0, 0) at netbsd:__kernassert+0x2c
pci_conf_read(0, f0088f1400800800, 4, 0, 3559320, 3559340) at 
netbsd:pci_conf_read+0x84
bge_attach(3ab9000, 3aacd00, 1c05358, 1810800, 1813000, 2) at 
netbsd:bge_attach+0x74
config_attach_loc(3aacd00, 1808c28, 1c053bc, 1c05358, 1, 12ed0e0) at 
netbsd:config_attach_loc+0x164
pci_probe_device(0, f0088f1400800800, 0, 0, 0, 0) at 
netbsd:pci_probe_device+0x254
sparc64_pci_enumerate_bus(3ab9000, 13cd990, 0, 42, 40, 181cc00) at 
netbsd:sparc64_pci_enumerate_bus+0x35c
pcirescan(0, 1472fa8, 13cd990, 3ab9037, 0, 3ab9037) at netbsd:pcirescan+0x44
pciattach(0, 3ab9000, 1c057d8, 1810800, 1813000, 2) at netbsd:pciattach+0x14c
config_attach_loc(3ab9000, 1808b08, 0, 1c057d8, 1, 13100c0) at 
netbsd:config_attach_loc+0x164
psycho_attach(3aadf00, 3aaa200, 1c059f0, 1810800, 1813000, 2) at 
netbsd:psycho_attach+0x4f8
config_attach_loc(3aaa200, 1808ad8, 0, 1c059f0, 1, 133bca0) at 
netbsd:config_attach_loc+0x164
mainbus_attach(0, 3aadf00, 0, 1810800, 1479400, 133bc00) at 
netbsd:mainbus_attach+0x474
config_attach_loc(3aadf00, 1808898, 0, 0, 1, 7) at netbsd:config_attach_loc+0x16

The call in bge_attach() looks like this:

static void
bge_attach(device_t parent, device_t self, void *aux)
{
        struct bge_softc        *sc = device_private(self);
[...]
        pci_chipset_tag_t       pc = sc->sc_pc;
[...]
        sc->sc_pc = pa->pa_pc;
[...]
        command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
[...]
}

The following patch avoids the panic:

Index: sys/dev/pci/if_bge.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.142
diff -u -r1.142 if_bge.c
--- sys/dev/pci/if_bge.c        19 Jan 2008 22:10:18 -0000      1.142
+++ sys/dev/pci/if_bge.c        2 Feb 2008 11:57:36 -0000
@@ -2412,7 +2412,7 @@
        struct pci_attach_args  *pa = aux;
        const struct bge_product *bp;
        const struct bge_revision *br;
-       pci_chipset_tag_t       pc = sc->sc_pc;
+       pci_chipset_tag_t       pc;
        pci_intr_handle_t       ih;
        const char              *intrstr = NULL;
        bus_dma_segment_t       seg;
@@ -2442,6 +2442,7 @@
         * Map control/status registers.
         */
        DPRINTFN(5, ("Map control/status regs\n"));
+       pc = sc->sc_pc;
        command = pci_conf_read(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG);
        command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
        pci_conf_write(pc, sc->sc_pcitag, PCI_COMMAND_STATUS_REG, command);

Does this look correct?

        Kind regards

-- 
Matthias Scheler                                  http://zhadum.org.uk/



Home | Main Index | Thread Index | Old Index