On Sun, Nov 28, 2010 at 05:38:28PM +0100, Markus Bergkvist wrote:
> It sure helped with the panic. Now it get unresponsive for about 2
> min then I get the print-out below, all at once and then it
> unfreezes.
try this then, it tries to figure out if the device has gone
out from under us
a dmesg would be interesting to see how your interrupt lines
are mapped
Index: if_bge.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bge.c,v
retrieving revision 1.303
diff -u -p -r1.303 if_bge.c
--- if_bge.c 20 Sep 2010 07:40:38 -0000 1.303
+++ if_bge.c 28 Nov 2010 22:36:19 -0000
@@ -127,10 +127,12 @@
const struct bge_revision * bge_lookup_rev(u_int32_t);
int bge_probe(struct device *, void *, void *);
void bge_attach(struct device *, struct device *, void *);
+int bge_detach(struct device *, int);
int bge_activate(struct device *, int);
struct cfattach bge_ca = {
- sizeof(struct bge_softc), bge_probe, bge_attach, NULL, bge_activate
+ sizeof(struct bge_softc), bge_probe, bge_attach, bge_detach,
+ bge_activate
};
struct cfdriver bge_cd = {
@@ -590,6 +592,9 @@ bge_miibus_readreg(struct device *dev, i
u_int32_t val, autopoll;
int i;
+ if (sc->sc_dying)
+ return (0);
+
/*
* Broadcom's own driver always assumes the internal
* PHY is at GMII address 1. On some chips, the PHY responds
@@ -649,6 +654,9 @@ bge_miibus_writereg(struct device *dev,
u_int32_t autopoll;
int i;
+ if (sc->sc_dying)
+ return;
+
/* Reading with autopolling on may trigger PCI errors */
autopoll = CSR_READ_4(sc, BGE_MI_MODE);
if (autopoll & BGE_MIMODE_AUTOPOLL) {
@@ -1797,7 +1805,6 @@ bge_attach(struct device *parent, struct
pcireg_t pm_ctl, memtype, subid;
pci_intr_handle_t ih;
const char *intrstr = NULL;
- bus_size_t size;
bus_dma_segment_t seg;
int rseg, gotenaddr = 0;
u_int32_t hwcfg = 0;
@@ -1821,7 +1828,7 @@ bge_attach(struct device *parent, struct
DPRINTFN(5, ("pci_mapreg_map\n"));
memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BGE_PCI_BAR0);
if (pci_mapreg_map(pa, BGE_PCI_BAR0, memtype, 0, &sc->bge_btag,
- &sc->bge_bhandle, NULL, &size, 0)) {
+ &sc->bge_bhandle, NULL, &sc->bge_size, 0)) {
printf(": can't find mem space\n");
return;
}
@@ -2215,6 +2222,7 @@ bge_attach(struct device *parent, struct
printf("\n");
goto fail_5;
}
+ sc->bge_pc = pa->pa_pc;
/*
* A Broadcom chip was detected. Inform the world.
@@ -2280,7 +2288,31 @@ fail_2:
bus_dmamem_free(sc->bge_dmatag, &seg, rseg);
fail_1:
- bus_space_unmap(sc->bge_btag, sc->bge_bhandle, size);
+ bus_space_unmap(sc->bge_btag, sc->bge_bhandle, sc->bge_size);
+}
+
+int
+bge_detach(struct device *self, int flags)
+{
+ struct bge_softc *sc = (struct bge_softc *)self;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+
+ pci_intr_disestablish(sc->bge_pc, sc->bge_intrhand);
+
+ bge_stop(sc);
+
+ /* Detach all PHYs */
+ mii_detach(&sc->bge_mii, MII_PHY_ANY, MII_OFFSET_ANY);
+
+ /* Delete any remaining media. */
+ ifmedia_delete_instance(&sc->bge_mii.mii_media, IFM_INST_ANY);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ bus_space_unmap(sc->bge_btag, sc->bge_bhandle, sc->bge_size);
+
+ return (0);
}
int
@@ -2733,7 +2765,7 @@ bge_intr(void *xsc)
{
struct bge_softc *sc;
struct ifnet *ifp;
- u_int32_t statusword;
+ u_int32_t statusword, pcistate;
sc = xsc;
ifp = &sc->arpcom.ac_if;
@@ -2746,9 +2778,19 @@ bge_intr(void *xsc)
/* read status word from status block */
statusword = sc->bge_rdata->bge_status_block.bge_status;
+ pcistate = CSR_READ_4(sc, BGE_PCI_PCISTATE);
+
+ /*
+ * This bit is self clearing, if set the device has
+ * likely disappeared
+ */
+ if (pcistate & BGE_PCISTATE_FORCE_RESET) {
+ sc->sc_dying = 1;
+ return (0);
+ }
if ((statusword & BGE_STATFLAG_UPDATED) ||
- (!(CSR_READ_4(sc, BGE_PCI_PCISTATE) &
BGE_PCISTATE_INTR_NOT_ACTIVE))) {
+ (!(pcistate & BGE_PCISTATE_INTR_NOT_ACTIVE))) {
/* Ack interrupt and stop others from occurring. */
bge_writembx(sc, BGE_MBX_IRQ0_LO, 1);
Index: if_bgereg.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_bgereg.h,v
retrieving revision 1.103
diff -u -p -r1.103 if_bgereg.h
--- if_bgereg.h 20 Sep 2010 07:40:38 -0000 1.103
+++ if_bgereg.h 28 Nov 2010 22:36:20 -0000
@@ -2578,7 +2578,9 @@ struct bge_softc {
struct arpcom arpcom; /* interface info */
bus_space_handle_t bge_bhandle;
bus_space_tag_t bge_btag;
+ bus_size_t bge_size;
void *bge_intrhand;
+ int sc_dying;
struct pci_attach_args bge_pa;
struct mii_data bge_mii;
struct ifmedia bge_ifmedia; /* media info */
@@ -2611,6 +2613,7 @@ struct bge_softc {
#define BGE_5700_FAMILY 0x02000000
bus_dma_tag_t bge_dmatag;
+ pci_chipset_tag_t bge_pc;
u_int32_t bge_chipid;
struct bge_ring_data *bge_rdata; /* rings */
struct bge_chain_data bge_cdata; /* mbufs */