aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc')
-rw-r--r--drivers/usb/misc/adutux.c48
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c4
-rw-r--r--drivers/usb/misc/ftdi-elan.c19
-rw-r--r--drivers/usb/misc/iowarrior.c20
-rw-r--r--drivers/usb/misc/ldusb.c3
-rw-r--r--drivers/usb/misc/usblcd.c7
6 files changed, 60 insertions, 41 deletions
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 75bfab95ab3..77145f9db04 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)
/* save device in the file's private structure */
file->private_data = dev;
- /* initialize in direction */
- dev->read_buffer_length = 0;
-
- /* fixup first read by having urb waiting for it */
- usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
- usb_rcvintpipe(dev->udev,
- dev->interrupt_in_endpoint->bEndpointAddress),
- dev->interrupt_in_buffer,
- le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
- adu_interrupt_in_callback, dev,
- dev->interrupt_in_endpoint->bInterval);
- /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
- dev->read_urb_finished = 0;
- usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
- /* we ignore failure */
- /* end of fixup for first read */
+ if (dev->open_count == 1) {
+ /* initialize in direction */
+ dev->read_buffer_length = 0;
+ /* fixup first read by having urb waiting for it */
+ usb_fill_int_urb(dev->interrupt_in_urb,dev->udev,
+ usb_rcvintpipe(dev->udev,
+ dev->interrupt_in_endpoint->bEndpointAddress),
+ dev->interrupt_in_buffer,
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize),
+ adu_interrupt_in_callback, dev,
+ dev->interrupt_in_endpoint->bInterval);
+ /* dev->interrupt_in_urb->transfer_flags |= URB_ASYNC_UNLINK; */
+ dev->read_urb_finished = 0;
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ if (retval)
+ --dev->open_count;
+ }
up(&dev->sem);
exit_no_device:
@@ -469,7 +470,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
adu_interrupt_in_callback,
dev,
dev->interrupt_in_endpoint->bInterval);
- retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
+ retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
if (!retval) {
spin_unlock_irqrestore(&dev->buflock, flags);
dbg(2," %s : submitted OK", __FUNCTION__);
@@ -539,7 +540,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
size_t bytes_written = 0;
size_t bytes_to_write;
size_t buffer_size;
- int retval = 0;
+ int retval;
int timeout = 0;
dbg(2," %s : enter, count = %Zd", __FUNCTION__, count);
@@ -547,7 +548,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
dev = file->private_data;
/* lock this object */
- down_interruptible(&dev->sem);
+ retval = down_interruptible(&dev->sem);
+ if (retval)
+ goto exit_nolock;
/* verify that the device wasn't unplugged */
if (dev->udev == NULL || dev->minor == 0) {
@@ -575,7 +578,11 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
}
up(&dev->sem);
timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout);
- down_interruptible(&dev->sem);
+ retval = down_interruptible(&dev->sem);
+ if (retval) {
+ retval = bytes_written ? bytes_written : retval;
+ goto exit_nolock;
+ }
if (timeout > 0) {
break;
}
@@ -637,6 +644,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
exit:
/* unlock the device */
up(&dev->sem);
+exit_nolock:
dbg(2," %s : leave, return value %d", __FUNCTION__, retval);
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
index b63b5f34b2a..d721380b242 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)
struct cypress *dev;
dev = usb_get_intfdata(interface);
- usb_set_intfdata(interface, NULL);
/* remove device attribute files */
device_remove_file(&interface->dev, &dev_attr_port0);
device_remove_file(&interface->dev, &dev_attr_port1);
+ /* the intfdata can be set to NULL only after the
+ * device files have been removed */
+ usb_set_intfdata(interface, NULL);
usb_put_dev(dev->udev);
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index bc3327e3dd7..e2172e5cf15 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)
#define OHCI_QUIRK_SUPERIO 0x02
#define OHCI_QUIRK_INITRESET 0x04
#define OHCI_BIG_ENDIAN 0x08
-#define OHCI_QUIRK_ZFMICRO 0x10
#define OHCI_CONTROL_INIT OHCI_CTRL_CBSR
#define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \
OHCI_INTR_WDH)
@@ -2910,24 +2909,28 @@ static int __init ftdi_elan_init(void)
INIT_LIST_HEAD(&ftdi_static_list);
status_queue = create_singlethread_workqueue("ftdi-status-control");
if (!status_queue)
- goto err1;
+ goto err_status_queue;
command_queue = create_singlethread_workqueue("ftdi-command-engine");
if (!command_queue)
- goto err2;
+ goto err_command_queue;
respond_queue = create_singlethread_workqueue("ftdi-respond-engine");
if (!respond_queue)
- goto err3;
+ goto err_respond_queue;
result = usb_register(&ftdi_elan_driver);
- if (result)
+ if (result) {
+ destroy_workqueue(status_queue);
+ destroy_workqueue(command_queue);
+ destroy_workqueue(respond_queue);
printk(KERN_ERR "usb_register failed. Error number %d\n",
result);
+ }
return result;
- err3:
+ err_respond_queue:
destroy_workqueue(command_queue);
- err2:
+ err_command_queue:
destroy_workqueue(status_queue);
- err1:
+ err_status_queue:
printk(KERN_ERR "%s couldn't create workqueue\n", ftdi_elan_driver.name);
return -ENOMEM;
}
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index d69665c8de0..fc51207b71b 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,
USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE, (type << 8) + id,
inter->desc.bInterfaceNumber, buf, size,
- GET_TIMEOUT);
+ GET_TIMEOUT*HZ);
}
//#endif
@@ -133,7 +133,7 @@ static int usb_set_report(struct usb_interface *intf, unsigned char type,
USB_TYPE_CLASS | USB_RECIP_INTERFACE,
(type << 8) + id,
intf->cur_altsetting->desc.bInterfaceNumber, buf,
- size, 1);
+ size, HZ);
}
/*---------------------*/
@@ -417,14 +417,14 @@ static ssize_t iowarrior_write(struct file *file,
if (!int_out_urb) {
retval = -ENOMEM;
dbg("%s Unable to allocate urb ", __func__);
- goto error;
+ goto error_no_urb;
}
buf = usb_buffer_alloc(dev->udev, dev->report_size,
GFP_KERNEL, &int_out_urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
dbg("%s Unable to allocate buffer ", __func__);
- goto error;
+ goto error_no_buffer;
}
usb_fill_int_urb(int_out_urb, dev->udev,
usb_sndintpipe(dev->udev,
@@ -459,7 +459,9 @@ static ssize_t iowarrior_write(struct file *file,
error:
usb_buffer_free(dev->udev, dev->report_size, buf,
int_out_urb->transfer_dma);
+error_no_buffer:
usb_free_urb(int_out_urb);
+error_no_urb:
atomic_dec(&dev->write_busy);
wake_up_interruptible(&dev->write_wait);
exit:
@@ -748,7 +750,6 @@ static int iowarrior_probe(struct usb_interface *interface,
struct usb_endpoint_descriptor *endpoint;
int i;
int retval = -ENOMEM;
- int idele = 0;
/* allocate memory for our device state and intialize it */
dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL);
@@ -824,11 +825,10 @@ static int iowarrior_probe(struct usb_interface *interface,
/* Set the idle timeout to 0, if this is interface 0 */
if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) {
- idele = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
- 0x0A,
- USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
- 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
- dbg("idele = %d", idele);
+ usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+ 0x0A,
+ USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0,
+ 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
}
/* allow device read and ioctl */
dev->present = 1;
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 788a11e6772..11555bde655 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -62,6 +62,8 @@
#define USB_DEVICE_ID_VERNIER_SKIP 0x0003
#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004
+#define USB_VENDOR_ID_MICROCHIP 0x04d8
+#define USB_DEVICE_ID_PICDEM 0x000c
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_LD_MINOR_BASE 0
@@ -89,6 +91,7 @@ static struct usb_device_id ld_usb_table [] = {
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) },
{ USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) },
+ { USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICDEM) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ld_usb_table);
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index ada2ebc464a..887ef953f3d 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -47,6 +47,7 @@ struct usb_lcd {
#define to_lcd_dev(d) container_of(d, struct usb_lcd, kref)
static struct usb_driver lcd_driver;
+static DEFINE_MUTEX(usb_lcd_open_mutex);
static void lcd_delete(struct kref *kref)
@@ -68,6 +69,7 @@ static int lcd_open(struct inode *inode, struct file *file)
subminor = iminor(inode);
+ mutex_lock(&usb_lcd_open_mutex);
interface = usb_find_interface(&lcd_driver, subminor);
if (!interface) {
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)
file->private_data = dev;
exit:
+ mutex_unlock(&usb_lcd_open_mutex);
return retval;
}
@@ -347,7 +350,7 @@ static void lcd_disconnect(struct usb_interface *interface)
int minor = interface->minor;
/* prevent skel_open() from racing skel_disconnect() */
- lock_kernel();
+ mutex_lock(&usb_lcd_open_mutex);
dev = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
@@ -355,7 +358,7 @@ static void lcd_disconnect(struct usb_interface *interface)
/* give back our minor */
usb_deregister_dev(interface, &lcd_class);
- unlock_kernel();
+ mutex_unlock(&usb_lcd_open_mutex);
/* decrement our usage count */
kref_put(&dev->kref, lcd_delete);