summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2009-09-03 13:40:41 +0000
committerattilio <attilio@FreeBSD.org>2009-09-03 13:40:41 +0000
commitef39f869d5b5088b0603a8d812466b9d0a29c67b (patch)
tree87d2c6d7a60deab2854de52b04bacccdb9c304db /sys/kern/subr_bus.c
parent7141ae0d62822f313149dd64ee01eb8442329bd1 (diff)
downloadFreeBSD-src-ef39f869d5b5088b0603a8d812466b9d0a29c67b.zip
FreeBSD-src-ef39f869d5b5088b0603a8d812466b9d0a29c67b.tar.gz
Add intermediate states for attaching and detaching that will be
reused by the enhached newbus locking once it is checked in. This change can be easilly MFCed to STABLE_8 at the appropriate moment. Reviewed by: jhb, scottl Tested by: Giovanni Trematerra <giovanni dot trematerra at gmail dot com>
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index f202631..e4f9946 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -2625,10 +2625,16 @@ device_attach(device_t dev)
{
int error;
+ if (dev->state >= DS_ATTACHING)
+ return (0);
device_sysctl_init(dev);
if (!device_is_quiet(dev))
device_print_child(dev->parent, dev);
+ dev->state = DS_ATTACHING;
if ((error = DEVICE_ATTACH(dev)) != 0) {
+ KASSERT(dev->state == DS_ATTACHING,
+ ("%s: %p device state must not been changing", __func__,
+ dev));
printf("device_attach: %s%d attach returned %d\n",
dev->driver->name, dev->unit, error);
/* Unset the class; set in device_probe_child */
@@ -2639,6 +2645,8 @@ device_attach(device_t dev)
dev->state = DS_NOTPRESENT;
return (error);
}
+ KASSERT(dev->state == DS_ATTACHING,
+ ("%s: %p device state must not been changing", __func__, dev));
device_sysctl_update(dev);
dev->state = DS_ATTACHED;
devadded(dev);
@@ -2674,8 +2682,16 @@ device_detach(device_t dev)
if (dev->state != DS_ATTACHED)
return (0);
- if ((error = DEVICE_DETACH(dev)) != 0)
+ dev->state = DS_DETACHING;
+ if ((error = DEVICE_DETACH(dev)) != 0) {
+ KASSERT(dev->state == DS_DETACHING,
+ ("%s: %p device state must not been changing", __func__,
+ dev));
+ dev->state = DS_ATTACHED;
return (error);
+ }
+ KASSERT(dev->state == DS_DETACHING,
+ ("%s: %p device state must not been changing", __func__, dev));
devremoved(dev);
if (!device_is_quiet(dev))
device_printf(dev, "detached\n");
@@ -2730,7 +2746,7 @@ device_quiesce(device_t dev)
int
device_shutdown(device_t dev)
{
- if (dev->state < DS_ATTACHED)
+ if (dev->state < DS_ATTACHED || dev->state == DS_DETACHING)
return (0);
return (DEVICE_SHUTDOWN(dev));
}
OpenPOWER on IntegriCloud