From 96b15e7f0792038302d773ba14c811720484d630 Mon Sep 17 00:00:00 2001 From: "Samuel J. Greear" Date: Mon, 5 Jul 2010 07:53:29 +0000 Subject: [PATCH] dev - Add kq support to hotplug --- sys/dev/misc/hotplug/hotplug.c | 64 +++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/sys/dev/misc/hotplug/hotplug.c b/sys/dev/misc/hotplug/hotplug.c index 4faafbb719..dd7769262b 100644 --- a/sys/dev/misc/hotplug/hotplug.c +++ b/sys/dev/misc/hotplug/hotplug.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -42,13 +43,18 @@ static d_open_t hotplugopen; static d_close_t hotplugclose; static d_read_t hotplugread; static d_poll_t hotplugpoll; +static d_kqfilter_t hotplugkqfilter; + +static void hotplugfiltdetach(struct knote *); +static int hotplugfilt(struct knote *, long); static struct dev_ops hotplug_ops = { - { "hotplug", CDEV_MAJOR, 0 }, + { "hotplug", CDEV_MAJOR, D_KQFILTER }, .d_open = hotplugopen, .d_close = hotplugclose, .d_read = hotplugread, .d_poll = hotplugpoll, + .d_kqfilter = hotplugkqfilter }; struct hotplug_event_info { @@ -119,6 +125,62 @@ hotplugpoll(struct dev_poll_args *ap) return (0); } +static struct filterops hotplugfiltops = + { 1, NULL, hotplugfiltdetach, hotplugfilt }; + +static int +hotplugkqfilter(struct dev_kqfilter_args *ap) +{ + struct knote *kn = ap->a_kn; + struct klist *klist; + + ap->a_result = 0; + + switch (kn->kn_filter) { + case EVFILT_READ: + kn->kn_fop = &hotplugfiltops; + break; + default: + ap->a_result = 1; + return (0); + } + + lockmgr(&hpsc.lock, LK_EXCLUSIVE); + crit_enter(); + klist = &hpsc.sel.si_note; + SLIST_INSERT_HEAD(klist, kn, kn_selnext); + crit_exit(); + lockmgr(&hpsc.lock, LK_RELEASE); + + return (0); +} + +static void +hotplugfiltdetach(struct knote *kn) +{ + struct klist *klist; + + lockmgr(&hpsc.lock, LK_EXCLUSIVE); + crit_enter(); + klist = &hpsc.sel.si_note; + SLIST_REMOVE(klist, kn, knote, kn_selnext); + crit_exit(); + lockmgr(&hpsc.lock, LK_RELEASE); +} + +static int +hotplugfilt(struct knote *kn, long hint) +{ + int ready = 0; + + lockmgr(&hpsc.lock, LK_EXCLUSIVE); + if (!TAILQ_EMPTY(&hpsc.queue)) + ready = 1; + lockmgr(&hpsc.lock, LK_RELEASE); + + return (ready); +} + int hotplug_get_event(struct hotplug_event *he) { -- 2.41.0