diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-27 17:19:17 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-27 17:19:17 -0400 |
| commit | 50f732ee63b91eb08a29974b36bd63e1150bb642 (patch) | |
| tree | fdfc63411a34ffbe26a3b0a997aaeff742a0301b /drivers/usb/misc | |
| parent | aa5bc2b58e3344da57f26b62e99e13e91c9e0a94 (diff) | |
| parent | a7205b30106a2d4ee268132644cdb292da2d9b41 (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (78 commits)
USB: update MAINAINERS and CREDITS for Freescale USB driver
USB: update gadget files for fsl_usb2_udc driver
USB: add Freescale high-speed USB SOC device controller driver
USB: quirk for broken suspend of IT8152F/G
USB: iowarrior.c: timeouts too small in usb_control_msg calls
USB: dell device id for option.c
USB: Remove Huawei unusual_devs entry
USB: CP2101 New Device IDs
USB: add picdem device to ldusb
usbfs micro optimitation
USB: remove ancient/broken CRIS hcd
usb ethernet gadget, workaround network stack API glitch
USB: add "busnum" attribute for USB devices
USB: cxacru: ADSL state management
usbatm: Detect usb device shutdown and ignore failed urbs
USB: Remove duplicate define of OHCI_QUIRK_ZFMICRO
USB: BandRich BandLuxe HSDPA Data Card Driver
USB gadget rndis: fix struct rndis_packet_msg_type unaligned bug
USB Elan FTDI: check for driver registration status
USB: sierra: add more checks on shutdown
...
Diffstat (limited to 'drivers/usb/misc')
| -rw-r--r-- | drivers/usb/misc/adutux.c | 48 | ||||
| -rw-r--r-- | drivers/usb/misc/cypress_cy7c63.c | 4 | ||||
| -rw-r--r-- | drivers/usb/misc/ftdi-elan.c | 19 | ||||
| -rw-r--r-- | drivers/usb/misc/iowarrior.c | 20 | ||||
| -rw-r--r-- | drivers/usb/misc/ldusb.c | 3 | ||||
| -rw-r--r-- | drivers/usb/misc/usblcd.c | 7 |
6 files changed, 60 insertions, 41 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 | ||
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index b63b5f34b2aa..d721380b242d 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c | |||
| @@ -246,11 +246,13 @@ static void cypress_disconnect(struct usb_interface *interface) | |||
| 246 | struct cypress *dev; | 246 | struct cypress *dev; |
| 247 | 247 | ||
| 248 | dev = usb_get_intfdata(interface); | 248 | dev = usb_get_intfdata(interface); |
| 249 | usb_set_intfdata(interface, NULL); | ||
| 250 | 249 | ||
| 251 | /* remove device attribute files */ | 250 | /* remove device attribute files */ |
| 252 | device_remove_file(&interface->dev, &dev_attr_port0); | 251 | device_remove_file(&interface->dev, &dev_attr_port0); |
| 253 | device_remove_file(&interface->dev, &dev_attr_port1); | 252 | device_remove_file(&interface->dev, &dev_attr_port1); |
| 253 | /* the intfdata can be set to NULL only after the | ||
| 254 | * device files have been removed */ | ||
| 255 | usb_set_intfdata(interface, NULL); | ||
| 254 | 256 | ||
| 255 | usb_put_dev(dev->udev); | 257 | usb_put_dev(dev->udev); |
| 256 | 258 | ||
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index bc3327e3dd78..e2172e5cf152 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
| @@ -2304,7 +2304,6 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi) | |||
| 2304 | #define OHCI_QUIRK_SUPERIO 0x02 | 2304 | #define OHCI_QUIRK_SUPERIO 0x02 |
| 2305 | #define OHCI_QUIRK_INITRESET 0x04 | 2305 | #define OHCI_QUIRK_INITRESET 0x04 |
| 2306 | #define OHCI_BIG_ENDIAN 0x08 | 2306 | #define OHCI_BIG_ENDIAN 0x08 |
| 2307 | #define OHCI_QUIRK_ZFMICRO 0x10 | ||
| 2308 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR | 2307 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR |
| 2309 | #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ | 2308 | #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ |
| 2310 | OHCI_INTR_WDH) | 2309 | OHCI_INTR_WDH) |
| @@ -2910,24 +2909,28 @@ static int __init ftdi_elan_init(void) | |||
| 2910 | INIT_LIST_HEAD(&ftdi_static_list); | 2909 | INIT_LIST_HEAD(&ftdi_static_list); |
| 2911 | status_queue = create_singlethread_workqueue("ftdi-status-control"); | 2910 | status_queue = create_singlethread_workqueue("ftdi-status-control"); |
| 2912 | if (!status_queue) | 2911 | if (!status_queue) |
| 2913 | goto err1; | 2912 | goto err_status_queue; |
| 2914 | command_queue = create_singlethread_workqueue("ftdi-command-engine"); | 2913 | command_queue = create_singlethread_workqueue("ftdi-command-engine"); |
| 2915 | if (!command_queue) | 2914 | if (!command_queue) |
| 2916 | goto err2; | 2915 | goto err_command_queue; |
| 2917 | respond_queue = create_singlethread_workqueue("ftdi-respond-engine"); | 2916 | respond_queue = create_singlethread_workqueue("ftdi-respond-engine"); |
| 2918 | if (!respond_queue) | 2917 | if (!respond_queue) |
| 2919 | goto err3; | 2918 | goto err_respond_queue; |
| 2920 | result = usb_register(&ftdi_elan_driver); | 2919 | result = usb_register(&ftdi_elan_driver); |
| 2921 | if (result) | 2920 | if (result) { |
| 2921 | destroy_workqueue(status_queue); | ||
| 2922 | destroy_workqueue(command_queue); | ||
| 2923 | destroy_workqueue(respond_queue); | ||
| 2922 | printk(KERN_ERR "usb_register failed. Error number %d\n", | 2924 | printk(KERN_ERR "usb_register failed. Error number %d\n", |
| 2923 | result); | 2925 | result); |
| 2926 | } | ||
| 2924 | return result; | 2927 | return result; |
| 2925 | 2928 | ||
| 2926 | err3: | 2929 | err_respond_queue: |
| 2927 | destroy_workqueue(command_queue); | 2930 | destroy_workqueue(command_queue); |
| 2928 | err2: | 2931 | err_command_queue: |
| 2929 | destroy_workqueue(status_queue); | 2932 | destroy_workqueue(status_queue); |
| 2930 | err1: | 2933 | err_status_queue: |
| 2931 | printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name); | 2934 | printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name); |
| 2932 | return -ENOMEM; | 2935 | return -ENOMEM; |
| 2933 | } | 2936 | } |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index d69665c8de02..fc51207b71b8 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
| @@ -118,7 +118,7 @@ static int usb_get_report(struct usb_device *dev, | |||
| 118 | USB_DIR_IN | USB_TYPE_CLASS | | 118 | USB_DIR_IN | USB_TYPE_CLASS | |
| 119 | USB_RECIP_INTERFACE, (type << 8) + id, | 119 | USB_RECIP_INTERFACE, (type << 8) + id, |
| 120 | inter->desc.bInterfaceNumber, buf, size, | 120 | inter->desc.bInterfaceNumber, buf, size, |
| 121 | GET_TIMEOUT); | 121 | GET_TIMEOUT*HZ); |
| 122 | } | 122 | } |
| 123 | //#endif | 123 | //#endif |
| 124 | 124 | ||
| @@ -133,7 +133,7 @@ static int usb_set_report(struct usb_interface *intf, unsigned char type, | |||
| 133 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 133 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 134 | (type << 8) + id, | 134 | (type << 8) + id, |
| 135 | intf->cur_altsetting->desc.bInterfaceNumber, buf, | 135 | intf->cur_altsetting->desc.bInterfaceNumber, buf, |
| 136 | size, 1); | 136 | size, HZ); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | /*---------------------*/ | 139 | /*---------------------*/ |
| @@ -417,14 +417,14 @@ static ssize_t iowarrior_write(struct file *file, | |||
| 417 | if (!int_out_urb) { | 417 | if (!int_out_urb) { |
| 418 | retval = -ENOMEM; | 418 | retval = -ENOMEM; |
| 419 | dbg("%s Unable to allocate urb ", __func__); | 419 | dbg("%s Unable to allocate urb ", __func__); |
| 420 | goto error; | 420 | goto error_no_urb; |
| 421 | } | 421 | } |
| 422 | buf = usb_buffer_alloc(dev->udev, dev->report_size, | 422 | buf = usb_buffer_alloc(dev->udev, dev->report_size, |
| 423 | GFP_KERNEL, &int_out_urb->transfer_dma); | 423 | GFP_KERNEL, &int_out_urb->transfer_dma); |
| 424 | if (!buf) { | 424 | if (!buf) { |
| 425 | retval = -ENOMEM; | 425 | retval = -ENOMEM; |
| 426 | dbg("%s Unable to allocate buffer ", __func__); | 426 | dbg("%s Unable to allocate buffer ", __func__); |
| 427 | goto error; | 427 | goto error_no_buffer; |
| 428 | } | 428 | } |
| 429 | usb_fill_int_urb(int_out_urb, dev->udev, | 429 | usb_fill_int_urb(int_out_urb, dev->udev, |
| 430 | usb_sndintpipe(dev->udev, | 430 | usb_sndintpipe(dev->udev, |
| @@ -459,7 +459,9 @@ static ssize_t iowarrior_write(struct file *file, | |||
| 459 | error: | 459 | error: |
| 460 | usb_buffer_free(dev->udev, dev->report_size, buf, | 460 | usb_buffer_free(dev->udev, dev->report_size, buf, |
| 461 | int_out_urb->transfer_dma); | 461 | int_out_urb->transfer_dma); |
| 462 | error_no_buffer: | ||
| 462 | usb_free_urb(int_out_urb); | 463 | usb_free_urb(int_out_urb); |
| 464 | error_no_urb: | ||
| 463 | atomic_dec(&dev->write_busy); | 465 | atomic_dec(&dev->write_busy); |
| 464 | wake_up_interruptible(&dev->write_wait); | 466 | wake_up_interruptible(&dev->write_wait); |
| 465 | exit: | 467 | exit: |
| @@ -748,7 +750,6 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
| 748 | struct usb_endpoint_descriptor *endpoint; | 750 | struct usb_endpoint_descriptor *endpoint; |
| 749 | int i; | 751 | int i; |
| 750 | int retval = -ENOMEM; | 752 | int retval = -ENOMEM; |
| 751 | int idele = 0; | ||
| 752 | 753 | ||
| 753 | /* allocate memory for our device state and intialize it */ | 754 | /* allocate memory for our device state and intialize it */ |
| 754 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); | 755 | dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); |
| @@ -824,11 +825,10 @@ static int iowarrior_probe(struct usb_interface *interface, | |||
| 824 | 825 | ||
| 825 | /* Set the idle timeout to 0, if this is interface 0 */ | 826 | /* Set the idle timeout to 0, if this is interface 0 */ |
| 826 | if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) { | 827 | if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) { |
| 827 | idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 828 | usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
| 828 | 0x0A, | 829 | 0x0A, |
| 829 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, | 830 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, |
| 830 | 0, NULL, 0, USB_CTRL_SET_TIMEOUT); | 831 | 0, NULL, 0, USB_CTRL_SET_TIMEOUT); |
| 831 | dbg("idele = %d", idele); | ||
| 832 | } | 832 | } |
| 833 | /* allow device read and ioctl */ | 833 | /* allow device read and ioctl */ |
| 834 | dev->present = 1; | 834 | dev->present = 1; |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 788a11e6772f..11555bde655b 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
| @@ -62,6 +62,8 @@ | |||
| 62 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | 62 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 |
| 63 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 63 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
| 64 | 64 | ||
| 65 | #define USB_VENDOR_ID_MICROCHIP 0x04d8 | ||
| 66 | #define USB_DEVICE_ID_PICDEM 0x000c | ||
| 65 | 67 | ||
| 66 | #ifdef CONFIG_USB_DYNAMIC_MINORS | 68 | #ifdef CONFIG_USB_DYNAMIC_MINORS |
| 67 | #define USB_LD_MINOR_BASE 0 | 69 | #define USB_LD_MINOR_BASE 0 |
| @@ -89,6 +91,7 @@ static struct usb_device_id ld_usb_table [] = { | |||
| 89 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 91 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
| 90 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 92 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
| 91 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | 93 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, |
| 94 | { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) }, | ||
| 92 | { } /* Terminating entry */ | 95 | { } /* Terminating entry */ |
| 93 | }; | 96 | }; |
| 94 | MODULE_DEVICE_TABLE(usb, ld_usb_table); | 97 | MODULE_DEVICE_TABLE(usb, ld_usb_table); |
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index ada2ebc464ae..887ef953f3d8 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
| @@ -47,6 +47,7 @@ struct usb_lcd { | |||
| 47 | #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) | 47 | #define to_lcd_dev(d) container_of(d, struct usb_lcd, kref) |
| 48 | 48 | ||
| 49 | static struct usb_driver lcd_driver; | 49 | static struct usb_driver lcd_driver; |
| 50 | static DEFINE_MUTEX(usb_lcd_open_mutex); | ||
| 50 | 51 | ||
| 51 | 52 | ||
| 52 | static void lcd_delete(struct kref *kref) | 53 | static void lcd_delete(struct kref *kref) |
| @@ -68,6 +69,7 @@ static int lcd_open(struct inode *inode, struct file *file) | |||
| 68 | 69 | ||
| 69 | subminor = iminor(inode); | 70 | subminor = iminor(inode); |
| 70 | 71 | ||
| 72 | mutex_lock(&usb_lcd_open_mutex); | ||
| 71 | interface = usb_find_interface(&lcd_driver, subminor); | 73 | interface = usb_find_interface(&lcd_driver, subminor); |
| 72 | if (!interface) { | 74 | if (!interface) { |
| 73 | err ("USBLCD: %s - error, can't find device for minor %d", | 75 | err ("USBLCD: %s - error, can't find device for minor %d", |
| @@ -89,6 +91,7 @@ static int lcd_open(struct inode *inode, struct file *file) | |||
| 89 | file->private_data = dev; | 91 | file->private_data = dev; |
| 90 | 92 | ||
| 91 | exit: | 93 | exit: |
| 94 | mutex_unlock(&usb_lcd_open_mutex); | ||
| 92 | return retval; | 95 | return retval; |
| 93 | } | 96 | } |
| 94 | 97 | ||
| @@ -347,7 +350,7 @@ static void lcd_disconnect(struct usb_interface *interface) | |||
| 347 | int minor = interface->minor; | 350 | int minor = interface->minor; |
| 348 | 351 | ||
| 349 | /* prevent skel_open() from racing skel_disconnect() */ | 352 | /* prevent skel_open() from racing skel_disconnect() */ |
| 350 | lock_kernel(); | 353 | mutex_lock(&usb_lcd_open_mutex); |
| 351 | 354 | ||
| 352 | dev = usb_get_intfdata(interface); | 355 | dev = usb_get_intfdata(interface); |
| 353 | usb_set_intfdata(interface, NULL); | 356 | usb_set_intfdata(interface, NULL); |
| @@ -355,7 +358,7 @@ static void lcd_disconnect(struct usb_interface *interface) | |||
| 355 | /* give back our minor */ | 358 | /* give back our minor */ |
| 356 | usb_deregister_dev(interface, &lcd_class); | 359 | usb_deregister_dev(interface, &lcd_class); |
| 357 | 360 | ||
| 358 | unlock_kernel(); | 361 | mutex_unlock(&usb_lcd_open_mutex); |
| 359 | 362 | ||
| 360 | /* decrement our usage count */ | 363 | /* decrement our usage count */ |
| 361 | kref_put(&dev->kref, lcd_delete); | 364 | kref_put(&dev->kref, lcd_delete); |
