diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-04-02 09:16:36 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-04-27 16:28:39 -0400 |
commit | ebc3ac149bf3a20c235625f1c07e0f997b3e08ba (patch) | |
tree | 6ae0e3b9f43bc55f4ef8caa9c3f36b706a3ec71c /drivers/usb/misc | |
parent | 1941044aa9632aa8debbb94a3c8a5ed0ebddade8 (diff) |
USB: cleanup ofd adutux
this driver does
- ignore errors during open
- submit a running urb
- use down_interruptible not handling signals
- GFP_KERNEL with a spinlock held
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/misc')
-rw-r--r-- | drivers/usb/misc/adutux.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 75bfab95ab3c..77145f9db043 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -285,23 +285,24 @@ static int adu_open(struct inode *inode, struct file *file) | |||
285 | /* save device in the file's private structure */ | 285 | /* save device in the file's private structure */ |
286 | file->private_data = dev; | 286 | file->private_data = dev; |
287 | 287 | ||
288 | /* initialize in direction */ | 288 | if (dev->open_count == 1) { |
289 | dev->read_buffer_length = 0; | 289 | /* initialize in direction */ |
290 | 290 | dev->read_buffer_length = 0; | |
291 | /* fixup first read by having urb waiting for it */ | ||
292 | usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, | ||
293 | usb_rcvintpipe(dev->udev, | ||
294 | dev->interrupt_in_endpoint->bEndpointAddress), | ||
295 | dev->interrupt_in_buffer, | ||
296 | le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), | ||
297 | adu_interrupt_in_callback, dev, | ||
298 | dev->interrupt_in_endpoint->bInterval); | ||
299 | /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ | ||
300 | dev->read_urb_finished = 0; | ||
301 | usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); | ||
302 | /* we ignore failure */ | ||
303 | /* end of fixup for first read */ | ||
304 | 291 | ||
292 | /* fixup first read by having urb waiting for it */ | ||
293 | usb_fill_int_urb(dev->interrupt_in_urb,dev->udev, | ||
294 | usb_rcvintpipe(dev->udev, | ||
295 | dev->interrupt_in_endpoint->bEndpointAddress), | ||
296 | dev->interrupt_in_buffer, | ||
297 | le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize), | ||
298 | adu_interrupt_in_callback, dev, | ||
299 | dev->interrupt_in_endpoint->bInterval); | ||
300 | /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */ | ||
301 | dev->read_urb_finished = 0; | ||
302 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); | ||
303 | if (retval) | ||
304 | --dev->open_count; | ||
305 | } | ||
305 | up(&dev->sem); | 306 | up(&dev->sem); |
306 | 307 | ||
307 | exit_no_device: | 308 | exit_no_device: |
@@ -469,7 +470,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
469 | adu_interrupt_in_callback, | 470 | adu_interrupt_in_callback, |
470 | dev, | 471 | dev, |
471 | dev->interrupt_in_endpoint->bInterval); | 472 | dev->interrupt_in_endpoint->bInterval); |
472 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); | 473 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); |
473 | if (!retval) { | 474 | if (!retval) { |
474 | spin_unlock_irqrestore(&dev->buflock, flags); | 475 | spin_unlock_irqrestore(&dev->buflock, flags); |
475 | dbg(2," %s : submitted OK", __FUNCTION__); | 476 | dbg(2," %s : submitted OK", __FUNCTION__); |
@@ -539,7 +540,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
539 | size_t bytes_written = 0; | 540 | size_t bytes_written = 0; |
540 | size_t bytes_to_write; | 541 | size_t bytes_to_write; |
541 | size_t buffer_size; | 542 | size_t buffer_size; |
542 | int retval = 0; | 543 | int retval; |
543 | int timeout = 0; | 544 | int timeout = 0; |
544 | 545 | ||
545 | dbg(2," %s : enter, count = %Zd", __FUNCTION__, count); | 546 | dbg(2," %s : enter, count = %Zd", __FUNCTION__, count); |
@@ -547,7 +548,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
547 | dev = file->private_data; | 548 | dev = file->private_data; |
548 | 549 | ||
549 | /* lock this object */ | 550 | /* lock this object */ |
550 | down_interruptible(&dev->sem); | 551 | retval = down_interruptible(&dev->sem); |
552 | if (retval) | ||
553 | goto exit_nolock; | ||
551 | 554 | ||
552 | /* verify that the device wasn't unplugged */ | 555 | /* verify that the device wasn't unplugged */ |
553 | if (dev->udev == NULL || dev->minor == 0) { | 556 | if (dev->udev == NULL || dev->minor == 0) { |
@@ -575,7 +578,11 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
575 | } | 578 | } |
576 | up(&dev->sem); | 579 | up(&dev->sem); |
577 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); | 580 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); |
578 | down_interruptible(&dev->sem); | 581 | retval = down_interruptible(&dev->sem); |
582 | if (retval) { | ||
583 | retval = bytes_written ? bytes_written : retval; | ||
584 | goto exit_nolock; | ||
585 | } | ||
579 | if (timeout > 0) { | 586 | if (timeout > 0) { |
580 | break; | 587 | break; |
581 | } | 588 | } |
@@ -637,6 +644,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
637 | exit: | 644 | exit: |
638 | /* unlock the device */ | 645 | /* unlock the device */ |
639 | up(&dev->sem); | 646 | up(&dev->sem); |
647 | exit_nolock: | ||
640 | 648 | ||
641 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 649 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
642 | 650 | ||