aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2017-10-08 17:33:49 +0000
committerIan Lepore <ian@FreeBSD.org>2017-10-08 17:33:49 +0000
commit7f92689427ba6448c6ff252b219b676449e7b872 (patch)
tree8613102f81deffe44632b9efe44a67adf3ba8ef1 /sys/kern/subr_bus.c
parent131e8e028930619c3840e7682e4ff60be657b684 (diff)
downloadsrc-7f92689427ba6448c6ff252b219b676449e7b872.tar.gz
src-7f92689427ba6448c6ff252b219b676449e7b872.zip
Add eventhandler notifications for newbus device attach/detach.
The detach case is slightly complicated by the fact that some in-kernel consumers may want to know before a device detaches (so they can release related resources, stop using the device, etc), but the detach can fail. So there are pre- and post-detach notifications for those consumers who need to handle all cases. A couple salient comments from the review, they amount to some helpful documentation about these events, but there's currently no good place for such documentation... Note that in the current newbus locking model, DETACH_BEGIN and DETACH_COMPLETE/FAILED sequence of event handler invocation might interweave with other attach/detach events arbitrarily. The handlers should be prepared for such situations. Also should note that detach may be called after the parent bus knows the hardware has left the building. In-kernel consumers have to be prepared to cope with this race. Differential Revision: https://reviews.freebsd.org/D12557
Notes
Notes: svn path=/head/; revision=324415
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 73658b530387..8c5b975d2aaf 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -2936,6 +2936,7 @@ device_attach(device_t dev)
else
dev->state = DS_ATTACHED;
dev->flags &= ~DF_DONENOMATCH;
+ EVENTHANDLER_INVOKE(device_attach, dev);
devadded(dev);
return (0);
}
@@ -2969,8 +2970,13 @@ device_detach(device_t dev)
if (dev->state != DS_ATTACHED)
return (0);
- if ((error = DEVICE_DETACH(dev)) != 0)
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_BEGIN);
+ if ((error = DEVICE_DETACH(dev)) != 0) {
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_FAILED);
return (error);
+ } else {
+ EVENTHANDLER_INVOKE(device_detach, dev, EVHDEV_DETACH_COMPLETE);
+ }
devremoved(dev);
if (!device_is_quiet(dev))
device_printf(dev, "detached\n");