Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7f1dc313 authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

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 ce60c488
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -313,8 +313,13 @@ static ssize_t wdm_write
	r = usb_autopm_get_interface(desc->intf);
	if (r < 0)
		goto outnp;

	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++;
		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;
}