diff options
Diffstat (limited to 'sys/dev/pci')
-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 |