Commit 9e873d88 authored by Oliver Neukum's avatar Oliver Neukum Committed by Stephen Rothwell

USB: CDC WDM driver doesn't support non-blocking reads

support for O_NONBLOCK in read and write path
by simply not waiting for data in read or availability
of the write urb in write but returning -EAGAIN
Signed-off-by: default avatarOliver Neukum <oliver@neukum.org>
Tested-by: default avatarMarcel Holtmann <marcel@holtmann.org>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 409ddaea
...@@ -313,8 +313,13 @@ static ssize_t wdm_write ...@@ -313,8 +313,13 @@ static ssize_t wdm_write
r = usb_autopm_get_interface(desc->intf); r = usb_autopm_get_interface(desc->intf);
if (r < 0) if (r < 0)
goto outnp; goto outnp;
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
&desc->flags)); if (!file->f_flags && O_NONBLOCK)
r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
&desc->flags));
else
if (test_bit(WDM_IN_USE, &desc->flags))
r = -EAGAIN;
if (r < 0) if (r < 0)
goto out; goto out;
...@@ -377,7 +382,7 @@ outnl: ...@@ -377,7 +382,7 @@ outnl:
static ssize_t wdm_read static ssize_t wdm_read
(struct file *file, char __user *buffer, size_t count, loff_t *ppos) (struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{ {
int rv, cntr; int rv, cntr = 0;
int i = 0; int i = 0;
struct wdm_device *desc = file->private_data; struct wdm_device *desc = file->private_data;
...@@ -389,10 +394,23 @@ static ssize_t wdm_read ...@@ -389,10 +394,23 @@ static ssize_t wdm_read
if (desc->length == 0) { if (desc->length == 0) {
desc->read = 0; desc->read = 0;
retry: retry:
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
rv = -ENODEV;
goto err;
}
i++; i++;
rv = wait_event_interruptible(desc->wait, if (file->f_flags & O_NONBLOCK) {
test_bit(WDM_READ, &desc->flags)); if (!test_bit(WDM_READ, &desc->flags)) {
rv = cntr ? cntr : -EAGAIN;
goto err;
}
rv = 0;
} else {
rv = wait_event_interruptible(desc->wait,
test_bit(WDM_READ, &desc->flags));
}
/* may have happened while we slept */
if (test_bit(WDM_DISCONNECTING, &desc->flags)) { if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
rv = -ENODEV; rv = -ENODEV;
goto err; goto err;
...@@ -448,7 +466,7 @@ retry: ...@@ -448,7 +466,7 @@ retry:
err: err:
mutex_unlock(&desc->rlock); mutex_unlock(&desc->rlock);
if (rv < 0) if (rv < 0 && rv != -EAGAIN)
dev_err(&desc->intf->dev, "wdm_read: exit error\n"); dev_err(&desc->intf->dev, "wdm_read: exit error\n");
return rv; return rv;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment