summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci.c24
-rw-r--r--sys/dev/pci/pcivar.h3
-rw-r--r--sys/dev/pci/ppb.c11
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