diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-06-08 14:13:57 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-06-08 14:50:01 +0200 |
commit | 4db7589f3d88c09d740560f1dcf2d4d843d918f2 (patch) | |
tree | 8369420bfd5bef1074fd9e617e84bc81e25341b3 /drivers/bluetooth | |
parent | ac28494c51ad20c7ff9cb991eaeee359a500d88e (diff) | |
download | op-kernel-dev-4db7589f3d88c09d740560f1dcf2d4d843d918f2.zip op-kernel-dev-4db7589f3d88c09d740560f1dcf2d4d843d918f2.tar.gz |
Bluetooth: Use wait_event_interruptible for virtual driver
The virtual driver still uses a home grown way of waiting for events and
so just replace it with wait_event_interruptible. And while at it remove
the useless access_ok() checks.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 43 |
1 files changed, 15 insertions, 28 deletions
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 379d302..0f5e049 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -179,41 +179,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, static ssize_t vhci_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { - DECLARE_WAITQUEUE(wait, current); struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(&data->read_wait, &wait); while (count) { - set_current_state(TASK_INTERRUPTIBLE); - skb = skb_dequeue(&data->readq); - if (!skb) { - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -ERESTARTSYS; - break; - } - - schedule(); - continue; + if (skb) { + ret = vhci_put_user(data, skb, buf, count); + if (ret < 0) + skb_queue_head(&data->readq, skb); + else + kfree_skb(skb); + break; } - if (access_ok(VERIFY_WRITE, buf, count)) - ret = vhci_put_user(data, skb, buf, count); - else - ret = -EFAULT; + if (file->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; + } - kfree_skb(skb); - break; + ret = wait_event_interruptible(data->read_wait, + !skb_queue_empty(&data->readq)); + if (ret < 0) + break; } - set_current_state(TASK_RUNNING); - remove_wait_queue(&data->read_wait, &wait); return ret; } @@ -223,9 +213,6 @@ static ssize_t vhci_write(struct file *file, { struct vhci_data *data = file->private_data; - if (!access_ok(VERIFY_READ, buf, count)) - return -EFAULT; - return vhci_get_user(data, buf, count); } |