aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/cdc-wdm.c
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2009-09-09 04:12:48 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:16 -0400
commit7f1dc313d01f5f0f84c06051343a3b8623932d3c (patch)
tree762ae2c12f103f039a8215161172b0b52101c1c9 /drivers/usb/class/cdc-wdm.c
parentce60c48871d2b3a15ab3fa2450e783bebb4ae407 (diff)
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>
Diffstat (limited to 'drivers/usb/class/cdc-wdm.c')
-rw-r--r--drivers/usb/class/cdc-wdm.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 8c64c018b676..3e564bfe17d1 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -313,8 +313,13 @@ static ssize_t wdm_write
313 r = usb_autopm_get_interface(desc->intf); 313 r = usb_autopm_get_interface(desc->intf);
314 if (r < 0) 314 if (r < 0)
315 goto outnp; 315 goto outnp;
316 r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, 316
317 &desc->flags)); 317 if (!file->f_flags && O_NONBLOCK)
318 r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE,
319 &desc->flags));
320 else
321 if (test_bit(WDM_IN_USE, &desc->flags))
322 r = -EAGAIN;
318 if (r < 0) 323 if (r < 0)
319 goto out; 324 goto out;
320 325
@@ -377,7 +382,7 @@ outnl:
377static ssize_t wdm_read 382static ssize_t wdm_read
378(struct file *file, char __user *buffer, size_t count, loff_t *ppos) 383(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
379{ 384{
380 int rv, cntr; 385 int rv, cntr = 0;
381 int i = 0; 386 int i = 0;
382 struct wdm_device *desc = file->private_data; 387 struct wdm_device *desc = file->private_data;
383 388
@@ -389,10 +394,23 @@ static ssize_t wdm_read
389 if (desc->length == 0) { 394 if (desc->length == 0) {
390 desc->read = 0; 395 desc->read = 0;
391retry: 396retry:
397 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
398 rv = -ENODEV;
399 goto err;
400 }
392 i++; 401 i++;
393 rv = wait_event_interruptible(desc->wait, 402 if (file->f_flags & O_NONBLOCK) {
394 test_bit(WDM_READ, &desc->flags)); 403 if (!test_bit(WDM_READ, &desc->flags)) {
404 rv = cntr ? cntr : -EAGAIN;
405 goto err;
406 }
407 rv = 0;
408 } else {
409 rv = wait_event_interruptible(desc->wait,
410 test_bit(WDM_READ, &desc->flags));
411 }
395 412
413 /* may have happened while we slept */
396 if (test_bit(WDM_DISCONNECTING, &desc->flags)) { 414 if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
397 rv = -ENODEV; 415 rv = -ENODEV;
398 goto err; 416 goto err;
@@ -448,7 +466,7 @@ retry:
448 466
449err: 467err:
450 mutex_unlock(&desc->rlock); 468 mutex_unlock(&desc->rlock);
451 if (rv < 0) 469 if (rv < 0 && rv != -EAGAIN)
452 dev_err(&desc->intf->dev, "wdm_read: exit error\n"); 470 dev_err(&desc->intf->dev, "wdm_read: exit error\n");
453 return rv; 471 return rv;
454} 472}