diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-12-31 19:13:37 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-12-31 19:13:37 +0000 |
commit | 0aad862da9f9f21719e7d94885e6f428e2314a7d (patch) | |
tree | 92e6c5ea15703d4dd3e25de0225cf7c1fddf3bcb /sys/dev | |
parent | 1983cad2f4127affd8762dabd8f51e13f89e33aa (diff) |
On some machines we get hotplug interrupts when they're resumed, so don't
rescan the pci bus if it already has devices attached to it. Make sure we
clear the list of attached devices when we receive a surprise removal
interrupt. Fixes kurt@'s T43.
ok miod@, krw@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/pci.c | 24 | ||||
-rw-r--r-- | sys/dev/pci/pcivar.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/ppb.c | 11 |
3 files changed, 32 insertions, 6 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 7fb1e23879a..8faf73bd83f 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci.c,v 1.54 2007/11/30 14:28:24 kettenis Exp $ */ +/* $OpenBSD: pci.c,v 1.55 2007/12/31 19:13:36 kettenis Exp $ */ /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ /* @@ -166,7 +166,7 @@ pciattach(struct device *parent, struct device *self, void *aux) int pcidetach(struct device *self, int flags) { - return config_detach_children(self, flags); + return pci_detach_devices((struct pci_softc *)self, flags); } /* save and restore the pci config space */ @@ -356,6 +356,26 @@ pci_probe_device(struct pci_softc *sc, pcitag_t tag, } int +pci_detach_devices(struct pci_softc *sc, int flags) +{ + struct pci_dev *pd, *next; + int ret; + + ret = config_detach_children(&sc->sc_dev, flags); + if (ret != 0) + return (ret); + + for (pd = LIST_FIRST(&sc->sc_devs); + pd != LIST_END(&sc->sc_devs); pd = next) { + next = LIST_NEXT(pd, pd_next); + free(pd, M_DEVBUF); + } + LIST_INIT(&sc->sc_devs); + + return (0); +} + +int pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid, int *offset, pcireg_t *value) { diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index 157e4fe0de8..ccec3443502 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pcivar.h,v 1.56 2007/11/26 13:20:28 jsg Exp $ */ +/* $OpenBSD: pcivar.h,v 1.57 2007/12/31 19:13:36 kettenis Exp $ */ /* $NetBSD: pcivar.h,v 1.23 1997/06/06 23:48:05 thorpej Exp $ */ /* @@ -240,6 +240,7 @@ int pci_find_device(struct pci_attach_args *pa, int (*match)(struct pci_attach_args *)); int pci_probe_device(struct pci_softc *, pcitag_t tag, int (*)(struct pci_attach_args *), struct pci_attach_args *); +int pci_detach_devices(struct pci_softc *, int); void pci_devinfo(pcireg_t, pcireg_t, int, char *, size_t); const struct pci_quirkdata * pci_lookup_quirkdata(pci_vendor_id_t, pci_product_id_t); diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c index c33479efcdb..68ec830855c 100644 --- a/sys/dev/pci/ppb.c +++ b/sys/dev/pci/ppb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ppb.c,v 1.25 2007/12/04 17:33:13 kettenis Exp $ */ +/* $OpenBSD: ppb.c,v 1.26 2007/12/31 19:13:36 kettenis Exp $ */ /* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */ /* @@ -230,6 +230,10 @@ void ppb_hotplug_insert(void *arg1, void *arg2) { struct ppb_softc *sc = arg1; + struct pci_softc *psc = (struct pci_softc *)sc->sc_psc; + + if (!LIST_EMPTY(&psc->sc_devs)) + return; /* XXX Powerup the card. */ @@ -418,9 +422,10 @@ void ppb_hotplug_remove(void *arg1, void *arg2) { struct ppb_softc *sc = arg1; + struct pci_softc *psc = (struct pci_softc *)sc->sc_psc; - if (sc->sc_psc) - config_detach_children(sc->sc_psc, DETACH_FORCE); + if (psc) + pci_detach_devices(psc, DETACH_FORCE); } int |