diff options
author | David Fries <David@Fries.net> | 2014-01-15 22:29:18 -0600 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-07 15:40:17 -0800 |
commit | 9fcbbac5ded489c3a4e121343db999dd51cd6c75 (patch) | |
tree | 1207602c8d7cc2da54784114a5d32d9ed6924b58 /drivers/w1/w1_int.c | |
parent | 70b34d2ed807b722413894975a8c60617defb887 (diff) | |
download | op-kernel-dev-9fcbbac5ded489c3a4e121343db999dd51cd6c75.zip op-kernel-dev-9fcbbac5ded489c3a4e121343db999dd51cd6c75.tar.gz |
w1: process w1 netlink commands in w1_process thread
Netlink is a socket interface and is expected to be asynchronous.
Clients can now make w1 requests without blocking by making use of the
w1_master thread to process netlink commands which was previously only
used for doing an automatic bus search.
Signed-off-by: David Fries <David@Fries.net>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/w1/w1_int.c')
-rw-r--r-- | drivers/w1/w1_int.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 423f3c2..66b2caa 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -75,8 +75,10 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, atomic_set(&dev->refcnt, 2); INIT_LIST_HEAD(&dev->slist); + INIT_LIST_HEAD(&dev->async_list); mutex_init(&dev->mutex); mutex_init(&dev->bus_mutex); + mutex_init(&dev->list_mutex); memcpy(&dev->dev, device, sizeof(struct device)); dev_set_name(&dev->dev, "w1_bus_master%u", dev->id); @@ -188,17 +190,22 @@ void __w1_remove_master_device(struct w1_master *dev) struct w1_netlink_msg msg; struct w1_slave *sl, *sln; - set_bit(W1_ABORT_SEARCH, &dev->flags); - kthread_stop(dev->thread); - mutex_lock(&w1_mlock); list_del(&dev->w1_master_entry); mutex_unlock(&w1_mlock); + set_bit(W1_ABORT_SEARCH, &dev->flags); + kthread_stop(dev->thread); + mutex_lock(&dev->mutex); - list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) + mutex_lock(&dev->list_mutex); + list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { + mutex_unlock(&dev->list_mutex); w1_slave_detach(sl); + mutex_lock(&dev->list_mutex); + } w1_destroy_master_attributes(dev); + mutex_unlock(&dev->list_mutex); mutex_unlock(&dev->mutex); atomic_dec(&dev->refcnt); @@ -208,7 +215,9 @@ void __w1_remove_master_device(struct w1_master *dev) if (msleep_interruptible(1000)) flush_signals(current); + w1_process_callbacks(dev); } + w1_process_callbacks(dev); memset(&msg, 0, sizeof(msg)); msg.id.mst.id = dev->id; |