summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-12-31 19:13:37 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-12-31 19:13:37 +0000
commit0aad862da9f9f21719e7d94885e6f428e2314a7d (patch)
tree92e6c5ea15703d4dd3e25de0225cf7c1fddf3bcb /sys/dev
parent1983cad2f4127affd8762dabd8f51e13f89e33aa (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.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