aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pccbb/pccbb.c
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2007-02-15 07:13:38 +0000
committerWarner Losh <imp@FreeBSD.org>2007-02-15 07:13:38 +0000
commit9d101a95565e10d1ca6d9cd38167b5a2c4581d7e (patch)
tree22ce65edf23786281f64fae61a2e8a80eb9a9597 /sys/dev/pccbb/pccbb.c
parentd798671ba874c1640a7e07f6d0e6f122927bed9c (diff)
downloadsrc-9d101a95565e10d1ca6d9cd38167b5a2c4581d7e.tar.gz
src-9d101a95565e10d1ca6d9cd38167b5a2c4581d7e.zip
Fix three bugs:
o When detaching all children, try really hard to get all the children list before giving up. This is based on an observation by hans petter selasky in his usb p4 branch. o When rescanning devices after a driver is added, abort if we can't get the child list with a message. o when rescanning devices, if the reprobe/attach is successful, save the device for cardbus/pccard.
Notes
Notes: svn path=/head/; revision=166741
Diffstat (limited to 'sys/dev/pccbb/pccbb.c')
-rw-r--r--sys/dev/pccbb/pccbb.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c
index 4971e89f00b5..a7cb56bb2214 100644
--- a/sys/dev/pccbb/pccbb.c
+++ b/sys/dev/pccbb/pccbb.c
@@ -281,10 +281,8 @@ int
cbb_detach(device_t brdev)
{
struct cbb_softc *sc = device_get_softc(brdev);
- int numdevs;
device_t *devlist;
- int tmp;
- int error;
+ int tmp, tries, error, numdevs;
/*
* Before we delete the children (which we have to do because
@@ -302,7 +300,19 @@ cbb_detach(device_t brdev)
* for the kldload/unload case to work. If we failed to do that, then
* we'd get duplicate devices when cbb.ko was reloaded.
*/
- device_get_children(brdev, &devlist, &numdevs);
+ tries = 10;
+ do {
+ error = device_get_children(brdev, &devlist, &numdevs);
+ if (error == 0)
+ break;
+ /*
+ * Try hard to cope with low memory.
+ */
+ if (error == ENOMEM) {
+ tsleep(sc, PZERO, "cbbnomem", 1);
+ continue;
+ }
+ } while (tries-- > 0);
for (tmp = 0; tmp < numdevs; tmp++)
device_delete_child(brdev, devlist[tmp]);
free(devlist, M_TEMP);
@@ -413,12 +423,21 @@ cbb_driver_added(device_t brdev, driver_t *driver)
int wake = 0;
DEVICE_IDENTIFY(driver, brdev);
- device_get_children(brdev, &devlist, &numdevs);
+ tmp = device_get_children(brdev, &devlist, &numdevs);
+ if (tmp != 0) {
+ device_printf(brdev, "Cannot get children list, no reprobe\n");
+ return;
+ }
for (tmp = 0; tmp < numdevs; tmp++) {
dev = devlist[tmp];
if (device_get_state(dev) == DS_NOTPRESENT &&
- device_probe_and_attach(dev) == 0)
+ device_probe_and_attach(dev) == 0) {
wake++;
+ if (strcmp(device_get_name(dev), "cardbus") == 0)
+ sc->cbdev = dev;
+ else if (strcmp(device_get_name(dev), "pccard") == 0)
+ sc->exca[0].pccarddev = dev;
+ }
}
free(devlist, M_TEMP);