mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-03 17:40:04 +00:00
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: Oliver Neukum <oliver@neukum.org> Tested-by: Marcel Holtmann <marcel@holtmann.org> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
ce60c48871
commit
7f1dc313d0
1 changed files with 24 additions and 6 deletions
|
@ -313,8 +313,13 @@ static ssize_t wdm_write
|
|||
r = usb_autopm_get_interface(desc->intf);
|
||||
if (r < 0)
|
||||
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)
|
||||
goto out;
|
||||
|
||||
|
@ -377,7 +382,7 @@ static ssize_t wdm_write
|
|||
static ssize_t wdm_read
|
||||
(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
int rv, cntr;
|
||||
int rv, cntr = 0;
|
||||
int i = 0;
|
||||
struct wdm_device *desc = file->private_data;
|
||||
|
||||
|
@ -389,10 +394,23 @@ static ssize_t wdm_read
|
|||
if (desc->length == 0) {
|
||||
desc->read = 0;
|
||||
retry:
|
||||
if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
|
||||
rv = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
i++;
|
||||
rv = wait_event_interruptible(desc->wait,
|
||||
test_bit(WDM_READ, &desc->flags));
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
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)) {
|
||||
rv = -ENODEV;
|
||||
goto err;
|
||||
|
@ -448,7 +466,7 @@ static ssize_t wdm_read
|
|||
|
||||
err:
|
||||
mutex_unlock(&desc->rlock);
|
||||
if (rv < 0)
|
||||
if (rv < 0 && rv != -EAGAIN)
|
||||
dev_err(&desc->intf->dev, "wdm_read: exit error\n");
|
||||
return rv;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue