summaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc')
-rw-r--r--drivers/usb/misc/Kconfig25
-rw-r--r--drivers/usb/misc/Makefile2
-rw-r--r--drivers/usb/misc/adutux.c8
-rw-r--r--drivers/usb/misc/appledisplay.c5
-rw-r--r--drivers/usb/misc/berry_charge.c183
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c2
-rw-r--r--drivers/usb/misc/cytherm.c2
-rw-r--r--drivers/usb/misc/emi26.c2
-rw-r--r--drivers/usb/misc/emi62.c2
-rw-r--r--drivers/usb/misc/ftdi-elan.c11
-rw-r--r--drivers/usb/misc/idmouse.c2
-rw-r--r--drivers/usb/misc/iowarrior.c6
-rw-r--r--drivers/usb/misc/isight_firmware.c4
-rw-r--r--drivers/usb/misc/ldusb.c4
-rw-r--r--drivers/usb/misc/legousbtower.c13
-rw-r--r--drivers/usb/misc/rio500.c11
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c20
-rw-r--r--drivers/usb/misc/trancevibrator.c2
-rw-r--r--drivers/usb/misc/usblcd.c7
-rw-r--r--drivers/usb/misc/usbled.c2
-rw-r--r--drivers/usb/misc/usbsevseg.c2
-rw-r--r--drivers/usb/misc/usbtest.c6
-rw-r--r--drivers/usb/misc/uss720.c2
-rw-r--r--drivers/usb/misc/vstusb.c783
24 files changed, 71 insertions, 1035 deletions
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index abe3aa67ed0..55660eaf947 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -87,17 +87,6 @@ config USB_LCD
To compile this driver as a module, choose M here: the
module will be called usblcd.
-config USB_BERRY_CHARGE
- tristate "USB BlackBerry recharge support"
- depends on USB
- help
- Say Y here if you want to connect a BlackBerry device to your
- computer's USB port and have it automatically switch to "recharge"
- mode.
-
- To compile this driver as a module, choose M here: the
- module will be called berry_charge.
-
config USB_LED
tristate "USB LED driver support"
depends on USB
@@ -242,17 +231,3 @@ config USB_ISIGHTFW
driver beforehand. Tools for doing so are available at
http://bersace03.free.fr
-config USB_VST
- tristate "USB VST driver"
- depends on USB
- help
- This driver is intended for Vernier Software Technologies
- bulk usb devices such as their Ocean-Optics spectrometers or
- Labquest.
- It is a bulk channel driver with configurable read and write
- timeouts.
-
- To compile this driver as a module, choose M here: the
- module will be called vstusb.
-
-
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 0826aab8303..717703e8142 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_USB_ADUTUX) += adutux.o
obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
-obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o
obj-$(CONFIG_USB_EMI26) += emi26.o
@@ -23,7 +22,6 @@ obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
obj-$(CONFIG_USB_USS720) += uss720.o
obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o
-obj-$(CONFIG_USB_VST) += vstusb.o
obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 20352654201..d240de097c6 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -38,7 +38,7 @@ static int debug = 1;
#define dbg(lvl, format, arg...) \
do { \
if (debug >= lvl) \
- printk(KERN_DEBUG __FILE__ " : " format " \n", ## arg); \
+ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \
} while (0)
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
#define ADU_PRODUCT_ID 0x0064
/* table of devices that work with this driver */
-static struct usb_device_id device_table [] = {
+static const struct usb_device_id device_table[] = {
{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID) }, /* ADU100 */
{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+20) }, /* ADU120 */
{ USB_DEVICE(ADU_VENDOR_ID, ADU_PRODUCT_ID+30) }, /* ADU130 */
@@ -132,8 +132,8 @@ static void adu_debug_data(int level, const char *function, int size,
if (debug < level)
return;
- printk(KERN_DEBUG __FILE__": %s - length = %d, data = ",
- function, size);
+ printk(KERN_DEBUG "%s: %s - length = %d, data = ",
+ __FILE__, function, size);
for (i = 0; i < size; ++i)
printk("%.2x ", data[i]);
printk("\n");
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 1eb9e4162cc..4d2952f1fb1 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -57,7 +57,7 @@
.bInterfaceProtocol = 0x00
/* table of devices that work with this driver */
-static struct usb_device_id appledisplay_table [] = {
+static const struct usb_device_id appledisplay_table[] = {
{ APPLEDISPLAY_DEVICE(0x9218) },
{ APPLEDISPLAY_DEVICE(0x9219) },
{ APPLEDISPLAY_DEVICE(0x921c) },
@@ -179,7 +179,7 @@ static int appledisplay_bl_get_brightness(struct backlight_device *bd)
return pdata->msgdata[1];
}
-static struct backlight_ops appledisplay_bl_data = {
+static const struct backlight_ops appledisplay_bl_data = {
.get_brightness = appledisplay_bl_get_brightness,
.update_status = appledisplay_bl_update_status,
};
@@ -283,6 +283,7 @@ static int appledisplay_probe(struct usb_interface *iface,
&appledisplay_bl_data);
if (IS_ERR(pdata->bd)) {
dev_err(&iface->dev, "Backlight registration failed\n");
+ retval = PTR_ERR(pdata->bd);
goto error;
}
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c
deleted file mode 100644
index c05a85bc592..00000000000
--- a/drivers/usb/misc/berry_charge.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * USB BlackBerry charging module
- *
- * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- * Information on how to switch configs was taken by the bcharge.cc file
- * created by the barry.sf.net project.
- *
- * bcharge.cc has the following copyright:
- * Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
- * and is released under the GPLv2.
- *
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/usb.h>
-
-#define RIM_VENDOR 0x0fca
-#define BLACKBERRY 0x0001
-#define BLACKBERRY_PEARL_DUAL 0x0004
-#define BLACKBERRY_PEARL 0x0006
-
-static int debug;
-static int pearl_dual_mode = 1;
-
-#ifdef dbg
-#undef dbg
-#endif
-#define dbg(dev, format, arg...) \
- if (debug) \
- dev_printk(KERN_DEBUG , dev , format , ## arg)
-
-static struct usb_device_id id_table [] = {
- { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
- { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL) },
- { USB_DEVICE(RIM_VENDOR, BLACKBERRY_PEARL_DUAL) },
- { }, /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, id_table);
-
-static int magic_charge(struct usb_device *udev)
-{
- char *dummy_buffer = kzalloc(2, GFP_KERNEL);
- int retval;
-
- if (!dummy_buffer)
- return -ENOMEM;
-
- /* send two magic commands and then set the configuration. The device
- * will then reset itself with the new power usage and should start
- * charging. */
-
- /* Note, with testing, it only seems that the first message is really
- * needed (at least for the 8700c), but to be safe, we emulate what
- * other operating systems seem to be sending to their device. We
- * really need to get some specs for this device to be sure about what
- * is going on here.
- */
- dbg(&udev->dev, "Sending first magic command\n");
- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
- if (retval != 2) {
- dev_err(&udev->dev, "First magic command failed: %d.\n",
- retval);
- goto exit;
- }
-
- dbg(&udev->dev, "Sending second magic command\n");
- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
- if (retval != 0) {
- dev_err(&udev->dev, "Second magic command failed: %d.\n",
- retval);
- goto exit;
- }
-
- dbg(&udev->dev, "Calling set_configuration\n");
- retval = usb_driver_set_configuration(udev, 1);
- if (retval)
- dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
-
-exit:
- kfree(dummy_buffer);
- return retval;
-}
-
-static int magic_dual_mode(struct usb_device *udev)
-{
- char *dummy_buffer = kzalloc(2, GFP_KERNEL);
- int retval;
-
- if (!dummy_buffer)
- return -ENOMEM;
-
- /* send magic command so that the Blackberry Pearl device exposes
- * two interfaces: both the USB mass-storage one and one which can
- * be used for database access. */
- dbg(&udev->dev, "Sending magic pearl command\n");
- retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- 0xa9, 0xc0, 1, 1, dummy_buffer, 2, 100);
- dbg(&udev->dev, "Magic pearl command returned %d\n", retval);
-
- dbg(&udev->dev, "Calling set_configuration\n");
- retval = usb_driver_set_configuration(udev, 1);
- if (retval)
- dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
-
- kfree(dummy_buffer);
- return retval;
-}
-
-static int berry_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
-
- if (udev->bus_mA < 500) {
- dbg(&udev->dev, "Not enough power to charge available\n");
- return -ENODEV;
- }
-
- dbg(&udev->dev, "Power is set to %dmA\n",
- udev->actconfig->desc.bMaxPower * 2);
-
- /* check the power usage so we don't try to enable something that is
- * already enabled */
- if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
- dbg(&udev->dev, "device is already charging, power is "
- "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
- return -ENODEV;
- }
-
- /* turn the power on */
- magic_charge(udev);
-
- if ((le16_to_cpu(udev->descriptor.idProduct) == BLACKBERRY_PEARL) &&
- (pearl_dual_mode))
- magic_dual_mode(udev);
-
- /* we don't really want to bind to the device, userspace programs can
- * handle the syncing just fine, so get outta here. */
- return -ENODEV;
-}
-
-static void berry_disconnect(struct usb_interface *intf)
-{
-}
-
-static struct usb_driver berry_driver = {
- .name = "berry_charge",
- .probe = berry_probe,
- .disconnect = berry_disconnect,
- .id_table = id_table,
-};
-
-static int __init berry_init(void)
-{
- return usb_register(&berry_driver);
-}
-
-static void __exit berry_exit(void)
-{
- usb_deregister(&berry_driver);
-}
-
-module_init(berry_init);
-module_exit(berry_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug enabled or not");
-module_param(pearl_dual_mode, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(pearl_dual_mode, "Change Blackberry Pearl to run in dual mode");
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
index 5720bfef6a3..1547d8cac5f 100644
--- a/drivers/usb/misc/cypress_cy7c63.c
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -56,7 +56,7 @@
/* table of devices that work with this driver */
-static struct usb_device_id cypress_table [] = {
+static const struct usb_device_id cypress_table[] = {
{ USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 4fb3c38b924..b9cbbbda824 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -27,7 +27,7 @@
#define USB_SKEL_VENDOR_ID 0x04b4
#define USB_SKEL_PRODUCT_ID 0x0002
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index 879a980ca8c..a6521c95f68 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -245,7 +245,7 @@ wraperr:
return err;
}
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(EMI26_VENDOR_ID, EMI26_PRODUCT_ID) },
{ USB_DEVICE(EMI26_VENDOR_ID, EMI26B_PRODUCT_ID) },
{ } /* Terminating entry */
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 59860b32853..fc15ad4c313 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -259,7 +259,7 @@ wraperr:
return err;
}
-static __devinitdata struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] __devinitconst = {
{ USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 9d0675ed0d4..1edb6d36189 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -86,7 +86,7 @@ static struct list_head ftdi_static_list;
#define USB_FTDI_ELAN_VENDOR_ID 0x0403
#define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea
/* table of devices that work with this driver*/
-static struct usb_device_id ftdi_elan_table[] = {
+static const struct usb_device_id ftdi_elan_table[] = {
{USB_DEVICE(USB_FTDI_ELAN_VENDOR_ID, USB_FTDI_ELAN_PRODUCT_ID)},
{ /* Terminating entry */ }
};
@@ -623,9 +623,12 @@ static void ftdi_elan_status_work(struct work_struct *work)
*/
static int ftdi_elan_open(struct inode *inode, struct file *file)
{
- int subminor = iminor(inode);
- struct usb_interface *interface = usb_find_interface(&ftdi_elan_driver,
- subminor);
+ int subminor;
+ struct usb_interface *interface;
+
+ subminor = iminor(inode);
+ interface = usb_find_interface(&ftdi_elan_driver, subminor);
+
if (!interface) {
printk(KERN_ERR "can't find device for minor %d\n", subminor);
return -ENODEV;
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 1337a9ce80b..a54c3cb804c 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -48,7 +48,7 @@
#define ID_CHERRY 0x0010
/* device ID table */
-static struct usb_device_id idmouse_table[] = {
+static const struct usb_device_id idmouse_table[] = {
{USB_DEVICE(ID_SIEMENS, ID_IDMOUSE)}, /* Siemens ID Mouse (Professional) */
{USB_DEVICE(ID_SIEMENS, ID_CHERRY )}, /* Cherry FingerTIP ID Board */
{} /* terminating null entry */
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index e75bb87ee92..d3c85236388 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -139,7 +139,7 @@ static int usb_set_report(struct usb_interface *intf, unsigned char type,
/* driver registration */
/*---------------------*/
/* table of devices that work with this driver */
-static struct usb_device_id iowarrior_ids[] = {
+static const struct usb_device_id iowarrior_ids[] = {
{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW40)},
{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW24)},
{USB_DEVICE(USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOWPV1)},
@@ -602,10 +602,12 @@ static int iowarrior_open(struct inode *inode, struct file *file)
dbg("%s", __func__);
+ lock_kernel();
subminor = iminor(inode);
interface = usb_find_interface(&iowarrior_driver, subminor);
if (!interface) {
+ unlock_kernel();
err("%s - error, can't find device for minor %d", __func__,
subminor);
return -ENODEV;
@@ -615,6 +617,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
dev = usb_get_intfdata(interface);
if (!dev) {
mutex_unlock(&iowarrior_open_disc_lock);
+ unlock_kernel();
return -ENODEV;
}
@@ -641,6 +644,7 @@ static int iowarrior_open(struct inode *inode, struct file *file)
out:
mutex_unlock(&dev->mutex);
+ unlock_kernel();
return retval;
}
diff --git a/drivers/usb/misc/isight_firmware.c b/drivers/usb/misc/isight_firmware.c
index b897f6554ec..06e990adc6c 100644
--- a/drivers/usb/misc/isight_firmware.c
+++ b/drivers/usb/misc/isight_firmware.c
@@ -26,7 +26,7 @@
#include <linux/errno.h>
#include <linux/module.h>
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x05ac, 0x8300)},
{},
};
@@ -112,6 +112,8 @@ out:
return ret;
}
+MODULE_FIRMWARE("isight.fw");
+
static void isight_firmware_disconnect(struct usb_interface *intf)
{
}
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c
index 90f130126c1..dd41d871004 100644
--- a/drivers/usb/misc/ldusb.c
+++ b/drivers/usb/misc/ldusb.c
@@ -69,7 +69,7 @@
#endif
/* table of devices that work with this driver */
-static struct usb_device_id ld_usb_table [] = {
+static const struct usb_device_id ld_usb_table[] = {
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
{ USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
@@ -798,7 +798,7 @@ static int __init ld_usb_init(void)
/* register this driver with the USB subsystem */
retval = usb_register(&ld_usb_driver);
if (retval)
- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+ err("usb_register failed for the %s driver. Error number %d\n", __FILE__, retval);
return retval;
}
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index faa6d623de7..8547bf9e317 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -95,8 +95,11 @@
/* Use our own dbg macro */
#undef dbg
-#define dbg(lvl, format, arg...) do { if (debug >= lvl) printk(KERN_DEBUG __FILE__ ": " format "\n", ## arg); } while (0)
-
+#define dbg(lvl, format, arg...) \
+do { \
+ if (debug >= lvl) \
+ printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \
+} while (0)
/* Version Information */
#define DRIVER_VERSION "v0.96"
@@ -192,7 +195,7 @@ struct tower_get_version_reply {
/* table of devices that work with this driver */
-static struct usb_device_id tower_table [] = {
+static const struct usb_device_id tower_table[] = {
{ USB_DEVICE(LEGO_USB_TOWER_VENDOR_ID, LEGO_USB_TOWER_PRODUCT_ID) },
{ } /* Terminating entry */
};
@@ -302,7 +305,7 @@ static inline void lego_usb_tower_debug_data (int level, const char *function, i
if (debug < level)
return;
- printk (KERN_DEBUG __FILE__": %s - length = %d, data = ", function, size);
+ printk (KERN_DEBUG "%s: %s - length = %d, data = ", __FILE__, function, size);
for (i = 0; i < size; ++i) {
printk ("%.2x ", data[i]);
}
@@ -1055,7 +1058,7 @@ static int __init lego_usb_tower_init(void)
/* register this driver with the USB subsystem */
result = usb_register(&tower_driver);
if (result < 0) {
- err("usb_register failed for the "__FILE__" driver. Error number %d", result);
+ err("usb_register failed for the %s driver. Error number %d", __FILE__, result);
retval = -1;
goto exit;
}
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 32d0199d0c3..a85771b1563 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -78,10 +78,13 @@ static int open_rio(struct inode *inode, struct file *file)
{
struct rio_usb_data *rio = &rio_instance;
+ /* against disconnect() */
+ lock_kernel();
mutex_lock(&(rio->lock));
if (rio->isopen || !rio->present) {
mutex_unlock(&(rio->lock));
+ unlock_kernel();
return -EBUSY;
}
rio->isopen = 1;
@@ -91,6 +94,7 @@ static int open_rio(struct inode *inode, struct file *file)
mutex_unlock(&(rio->lock));
dev_info(&rio->rio_dev->dev, "Rio opened.\n");
+ unlock_kernel();
return 0;
}
@@ -115,7 +119,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
int retries;
int retval=0;
- lock_kernel();
mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */
if (rio->present == 0 || rio->rio_dev == NULL) {
@@ -254,7 +257,6 @@ static long ioctl_rio(struct file *file, unsigned int cmd, unsigned long arg)
err_out:
mutex_unlock(&(rio->lock));
- unlock_kernel();
return retval;
}
@@ -489,6 +491,7 @@ static void disconnect_rio(struct usb_interface *intf)
struct rio_usb_data *rio = usb_get_intfdata (intf);
usb_set_intfdata (intf, NULL);
+ lock_kernel();
if (rio) {
usb_deregister_dev(intf, &usb_rio_class);
@@ -498,6 +501,7 @@ static void disconnect_rio(struct usb_interface *intf)
/* better let it finish - the release will do whats needed */
rio->rio_dev = NULL;
mutex_unlock(&(rio->lock));
+ unlock_kernel();
return;
}
kfree(rio->ibuf);
@@ -508,9 +512,10 @@ static void disconnect_rio(struct usb_interface *intf)
rio->present = 0;
mutex_unlock(&(rio->lock));
}
+ unlock_kernel();
}
-static struct usb_device_id rio_table [] = {
+static const struct usb_device_id rio_table[] = {
{ USB_DEVICE(0x0841, 1) }, /* Rio 500 */
{ } /* Terminating entry */
};
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 8b37a4b9839..aae95a009bd 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -250,7 +250,7 @@ sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index, unsigned int pipe,
sisusb->urbstatus[index] |= SU_URB_BUSY;
/* Submit URB */
- retval = usb_submit_urb(urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_KERNEL);
/* If OK, and if timeout > 0, wait for completion */
if ((retval == 0) && timeout) {
@@ -306,7 +306,7 @@ sisusb_bulkin_msg(struct sisusb_usb_data *sisusb, unsigned int pipe, void *data,
urb->actual_length = 0;
sisusb->completein = 0;
- retval = usb_submit_urb(urb, GFP_ATOMIC);
+ retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval == 0) {
wait_event_timeout(sisusb->wait_q, sisusb->completein, timeout);
if (!sisusb->completein) {
@@ -2416,21 +2416,28 @@ sisusb_open(struct inode *inode, struct file *file)
struct usb_interface *interface;
int subminor = iminor(inode);
- if (!(interface = usb_find_interface(&sisusb_driver, subminor)))
+ lock_kernel();
+ if (!(interface = usb_find_interface(&sisusb_driver, subminor))) {
+ unlock_kernel();
return -ENODEV;
+ }
- if (!(sisusb = usb_get_intfdata(interface)))
+ if (!(sisusb = usb_get_intfdata(interface))) {
+ unlock_kernel();
return -ENODEV;
+ }
mutex_lock(&sisusb->lock);
if (!sisusb->present || !sisusb->ready) {
mutex_unlock(&sisusb->lock);
+ unlock_kernel();
return -ENODEV;
}
if (sisusb->isopen) {
mutex_unlock(&sisusb->lock);
+ unlock_kernel();
return -EBUSY;
}
@@ -2439,11 +2446,13 @@ sisusb_open(struct inode *inode, struct file *file)
if (sisusb_init_gfxdevice(sisusb, 0)) {
mutex_unlock(&sisusb->lock);
dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n");
+ unlock_kernel();
return -EIO;
}
} else {
mutex_unlock(&sisusb->lock);
dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n");
+ unlock_kernel();
return -EIO;
}
}
@@ -2456,6 +2465,7 @@ sisusb_open(struct inode *inode, struct file *file)
file->private_data = sisusb;
mutex_unlock(&sisusb->lock);
+ unlock_kernel();
return 0;
}
@@ -3238,7 +3248,7 @@ static void sisusb_disconnect(struct usb_interface *intf)
kref_put(&sisusb->kref, sisusb_delete);
}
-static struct usb_device_id sisusb_table [] = {
+static const struct usb_device_id sisusb_table[] = {
{ USB_DEVICE(0x0711, 0x0550) },
{ USB_DEVICE(0x0711, 0x0900) },
{ USB_DEVICE(0x0711, 0x0901) },
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 2e14102955c..5da28eaee31 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -33,7 +33,7 @@
#define TRANCEVIBRATOR_VENDOR_ID 0x0b49 /* ASCII Corporation */
#define TRANCEVIBRATOR_PRODUCT_ID 0x064f /* Trance Vibrator */
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(TRANCEVIBRATOR_VENDOR_ID, TRANCEVIBRATOR_PRODUCT_ID) },
{ },
};
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 4fb120357c5..90aede90553 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -30,7 +30,7 @@
#define IOCTL_GET_DRV_VERSION 2
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
{ .idVendor = 0x10D2, .match_flags = USB_DEVICE_ID_MATCH_VENDOR, },
{ },
};
@@ -74,10 +74,12 @@ static int lcd_open(struct inode *inode, struct file *file)
struct usb_interface *interface;
int subminor, r;
+ lock_kernel();
subminor = iminor(inode);
interface = usb_find_interface(&lcd_driver, subminor);
if (!interface) {
+ unlock_kernel();
err ("USBLCD: %s - error, can't find device for minor %d",
__func__, subminor);
return -ENODEV;
@@ -87,6 +89,7 @@ static int lcd_open(struct inode *inode, struct file *file)
dev = usb_get_intfdata(interface);
if (!dev) {
mutex_unlock(&open_disc_mutex);
+ unlock_kernel();
return -ENODEV;
}
@@ -98,11 +101,13 @@ static int lcd_open(struct inode *inode, struct file *file)
r = usb_autopm_get_interface(interface);
if (r < 0) {
kref_put(&dev->kref, lcd_delete);
+ unlock_kernel();
return r;
}
/* save our object in the file's private structure */
file->private_data = dev;
+ unlock_kernel();
return 0;
}
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c
index 06cb71942dc..63da2c3c838 100644
--- a/drivers/usb/misc/usbled.c
+++ b/drivers/usb/misc/usbled.c
@@ -24,7 +24,7 @@
#define PRODUCT_ID 0x1223
/* table of devices that work with this driver */
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
{ },
};
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
index 3db255537e7..a9555cb901a 100644
--- a/drivers/usb/misc/usbsevseg.c
+++ b/drivers/usb/misc/usbsevseg.c
@@ -27,7 +27,7 @@
#define MAXLEN 6
/* table of devices that work with this driver */
-static struct usb_device_id id_table[] = {
+static const struct usb_device_id id_table[] = {
{ USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
{ },
};
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 3dab0c0b196..a21cce6f740 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -1580,10 +1580,6 @@ usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
return -ERESTARTSYS;
/* FIXME: What if a system sleep starts while a test is running? */
- if (!intf->is_active) {
- mutex_unlock(&dev->lock);
- return -EHOSTUNREACH;
- }
/* some devices, like ez-usb default devices, need a non-default
* altsetting to have any active endpoints. some tests change
@@ -2101,7 +2097,7 @@ static struct usbtest_info generic_info = {
#endif
-static struct usb_device_id id_table [] = {
+static const struct usb_device_id id_table[] = {
/*-------------------------------------------------------------*/
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index 9a6c27a0179..f56fed53f2d 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -770,7 +770,7 @@ static void uss720_disconnect(struct usb_interface *intf)
}
/* table of cables that work through this driver */
-static struct usb_device_id uss720_table [] = {
+static const struct usb_device_id uss720_table[] = {
{ USB_DEVICE(0x047e, 0x1001) },
{ USB_DEVICE(0x0557, 0x2001) },
{ USB_DEVICE(0x0729, 0x1284) },
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c
deleted file mode 100644
index f26ea8dc157..00000000000
--- a/drivers/usb/misc/vstusb.c
+++ /dev/null
@@ -1,783 +0,0 @@
-/*****************************************************************************
- * File: drivers/usb/misc/vstusb.c
- *
- * Purpose: Support for the bulk USB Vernier Spectrophotometers
- *
- * Author: Johnnie Peters
- * Axian Consulting
- * Beaverton, OR, USA 97005
- *
- * Modified by: EQware Engineering, Inc.
- * Oregon City, OR, USA 97045
- *
- * Copyright: 2007, 2008
- * Vernier Software & Technology
- * Beaverton, OR, USA 97005
- *
- * Web: www.vernier.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *****************************************************************************/
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/uaccess.h>
-#include <linux/usb.h>
-
-#include <linux/usb/vstusb.h>
-
-#define DRIVER_VERSION "VST USB Driver Version 1.5"
-#define DRIVER_DESC "Vernier Software Technology Bulk USB Driver"
-
-#ifdef CONFIG_USB_DYNAMIC_MINORS
- #define VSTUSB_MINOR_BASE 0
-#else
- #define VSTUSB_MINOR_BASE 199
-#endif
-
-#define USB_VENDOR_OCEANOPTICS 0x2457
-#define USB_VENDOR_VERNIER 0x08F7 /* Vernier Software & Technology */
-
-#define USB_PRODUCT_USB2000 0x1002
-#define USB_PRODUCT_ADC1000_FW 0x1003 /* firmware download (renumerates) */
-#define USB_PRODUCT_ADC1000 0x1004
-#define USB_PRODUCT_HR2000_FW 0x1009 /* firmware download (renumerates) */
-#define USB_PRODUCT_HR2000 0x100A
-#define USB_PRODUCT_HR4000_FW 0x1011 /* firmware download (renumerates) */
-#define USB_PRODUCT_HR4000 0x1012
-#define USB_PRODUCT_USB650 0x1014 /* "Red Tide" */
-#define USB_PRODUCT_QE65000 0x1018
-#define USB_PRODUCT_USB4000 0x1022
-#define USB_PRODUCT_USB325 0x1024 /* "Vernier Spectrometer" */
-
-#define USB_PRODUCT_LABPRO 0x0001
-#define USB_PRODUCT_LABQUEST 0x0005
-
-#define VST_MAXBUFFER (64*1024)
-
-static struct usb_device_id id_table[] = {
- { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)},
- { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)},
- { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB650)},
- { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB4000)},
- { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB325)},
- { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABQUEST)},
- { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABPRO)},
- {},
-};
-
-MODULE_DEVICE_TABLE(usb, id_table);
-
-struct vstusb_device {
- struct kref kref;
- struct mutex lock;
- struct usb_device *usb_dev;
- char present;
- char isopen;
- struct usb_anchor submitted;
- int rd_pipe;
- int rd_timeout_ms;
- int wr_pipe;
- int wr_timeout_ms;
-};
-#define to_vst_dev(d) container_of(d, struct vstusb_device, kref)
-
-static struct usb_driver vstusb_driver;
-
-static void vstusb_delete(struct kref *kref)
-{
- struct vstusb_device *vstdev = to_vst_dev(kref);
-
- usb_put_dev(vstdev->usb_dev);
- kfree(vstdev);
-}
-
-static int vstusb_open(struct inode *inode, struct file *file)
-{
- struct vstusb_device *vstdev;
- struct usb_interface *interface;
-
- interface = usb_find_interface(&vstusb_driver, iminor(inode));
-
- if (!interface) {
- printk(KERN_ERR KBUILD_MODNAME
- ": %s - error, can't find device for minor %d\n",
- __func__, iminor(inode));
- return -ENODEV;
- }
-
- vstdev = usb_get_intfdata(interface);
-
- if (!vstdev)
- return -ENODEV;
-
- /* lock this device */
- mutex_lock(&vstdev->lock);
-
- /* can only open one time */
- if ((!vstdev->present) || (vstdev->isopen)) {
- mutex_unlock(&vstdev->lock);
- return -EBUSY;
- }
-
- /* increment our usage count */
- kref_get(&vstdev->kref);
-
- vstdev->isopen = 1;
-
- /* save device in the file's private structure */
- file->private_data = vstdev;
-
- dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__);
-
- mutex_unlock(&vstdev->lock);
-
- return 0;
-}
-
-static int vstusb_release(struct inode *inode, struct file *file)
-{
- struct vstusb_device *vstdev;
-
- vstdev = file->private_data;
-
- if (vstdev == NULL)
- return -ENODEV;
-
- mutex_lock(&vstdev->lock);
-
- vstdev->isopen = 0;
-
- dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__);
-
- mutex_unlock(&vstdev->lock);
-
- kref_put(&vstdev->kref, vstusb_delete);
-
- return 0;
-}
-
-static void usb_api_blocking_completion(struct urb *urb)
-{
- struct completion *completeit = urb->context;
-
- complete(completeit);
-}
-
-static int vstusb_fill_and_send_urb(struct urb *urb,
- struct usb_device *usb_dev,
- unsigned int pipe, void *data,
- unsigned int len, struct completion *done)
-{
- struct usb_host_endpoint *ep;
- struct usb_host_endpoint **hostep;
- unsigned int pipend;
-
- int status;
-
- hostep = usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out;
- pipend = usb_pipeendpoint(pipe);
- ep = hostep[pipend];
-
- if (!ep || (len == 0))
- return -EINVAL;
-
- if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
- == USB_ENDPOINT_XFER_INT) {
- pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
- usb_fill_int_urb(urb, usb_dev, pipe, data, len,
- (usb_complete_t)usb_api_blocking_completion,
- NULL, ep->desc.bInterval);
- } else
- usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
- (usb_complete_t)usb_api_blocking_completion,
- NULL);
-
- init_completion(done);
- urb->context = done;
- urb->actual_length = 0;
- status = usb_submit_urb(urb, GFP_KERNEL);
-
- return status;
-}
-
-static int vstusb_complete_urb(struct urb *urb, struct completion *done,
- int timeout, int *actual_length)
-{
- unsigned long expire;
- int status;
-
- expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
- if (!wait_for_completion_interruptible_timeout(done, expire)) {
- usb_kill_urb(urb);
- status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;
-
- dev_dbg(&urb->dev->dev,
- "%s timed out on ep%d%s len=%d/%d, urb status = %d\n",
- current->comm,
- usb_pipeendpoint(urb->pipe),
- usb_pipein(urb->pipe) ? "in" : "out",
- urb->actual_length,
- urb->transfer_buffer_length,
- urb->status);
-
- } else {
- if (signal_pending(current)) {
- /* if really an error */
- if (urb->status && !((urb->status == -ENOENT) ||
- (urb->status == -ECONNRESET) ||
- (urb->status == -ESHUTDOWN))) {
- status = -EINTR;
- usb_kill_urb(urb);
- } else {
- status = 0;
- }
-
- dev_dbg(&urb->dev->dev,
- "%s: signal pending on ep%d%s len=%d/%d,"
- "urb status = %d\n",
- current->comm,
- usb_pipeendpoint(urb->pipe),
- usb_pipein(urb->pipe) ? "in" : "out",
- urb->actual_length,
- urb->transfer_buffer_length,
- urb->status);
-
- } else {
- status = urb->status;
- }
- }
-
- if (actual_length)
- *actual_length = urb->actual_length;
-
- return status;
-}
-
-static ssize_t vstusb_read(struct file *file, char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct vstusb_device *vstdev;
- int cnt = -1;
- void *buf;
- int retval = 0;
-
- struct urb *urb;
- struct usb_device *dev;
- unsigned int pipe;
- int timeout;
-
- DECLARE_COMPLETION_ONSTACK(done);
-
- vstdev = file->private_data;
-
- if (vstdev == NULL)
- return -ENODEV;
-
- /* verify that we actually want to read some data */
- if ((count == 0) || (count > VST_MAXBUFFER))
- return -EINVAL;
-
- /* lock this object */
- if (mutex_lock_interruptible(&vstdev->lock))
- return -ERESTARTSYS;
-
- /* anyone home */
- if (!vstdev->present) {
- mutex_unlock(&vstdev->lock);
- printk(KERN_ERR KBUILD_MODNAME
- ": %s: device not present\n", __func__);
- return -ENODEV;
- }
-
- /* pull out the necessary data */
- dev = vstdev->usb_dev;
- pipe = usb_rcvbulkpipe(dev, vstdev->rd_pipe);
- timeout = vstdev->rd_timeout_ms;
-
- buf = kmalloc(count, GFP_KERNEL);
- if (buf == NULL) {
- mutex_unlock(&vstdev->lock);
- return -ENOMEM;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- kfree(buf);
- mutex_unlock(&vstdev->lock);
- return -ENOMEM;
- }
-
- usb_anchor_urb(urb, &vstdev->submitted);
- retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
- mutex_unlock(&vstdev->lock);
- if (retval) {
- usb_unanchor_urb(urb);
- dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
- if (retval) {
- dev_err(&dev->dev, "%s: error %d completing urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- if (copy_to_user(buffer, buf, cnt)) {
- dev_err(&dev->dev, "%s: can't copy_to_user\n", __func__);
- retval = -EFAULT;
- } else {
- retval = cnt;
- dev_dbg(&dev->dev, "%s: read %d bytes from pipe %d\n",
- __func__, cnt, pipe);
- }
-
-exit:
- usb_free_urb(urb);
- kfree(buf);
- return retval;
-}
-
-static ssize_t vstusb_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- struct vstusb_device *vstdev;
- int cnt = -1;
- void *buf;
- int retval = 0;
-
- struct urb *urb;
- struct usb_device *dev;
- unsigned int pipe;
- int timeout;
-
- DECLARE_COMPLETION_ONSTACK(done);
-
- vstdev = file->private_data;
-
- if (vstdev == NULL)
- return -ENODEV;
-
- /* verify that we actually have some data to write */
- if ((count == 0) || (count > VST_MAXBUFFER))
- return retval;
-
- /* lock this object */
- if (mutex_lock_interruptible(&vstdev->lock))
- return -ERESTARTSYS;
-
- /* anyone home */
- if (!vstdev->present) {
- mutex_unlock(&vstdev->lock);
- printk(KERN_ERR KBUILD_MODNAME
- ": %s: device not present\n", __func__);
- return -ENODEV;
- }
-
- /* pull out the necessary data */
- dev = vstdev->usb_dev;
- pipe = usb_sndbulkpipe(dev, vstdev->wr_pipe);
- timeout = vstdev->wr_timeout_ms;
-
- buf = kmalloc(count, GFP_KERNEL);
- if (buf == NULL) {
- mutex_unlock(&vstdev->lock);
- return -ENOMEM;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- kfree(buf);
- mutex_unlock(&vstdev->lock);
- return -ENOMEM;
- }
-
- if (copy_from_user(buf, buffer, count)) {
- mutex_unlock(&vstdev->lock);
- dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__);
- retval = -EFAULT;
- goto exit;
- }
-
- usb_anchor_urb(urb, &vstdev->submitted);
- retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
- mutex_unlock(&vstdev->lock);
- if (retval) {
- usb_unanchor_urb(urb);
- dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
- if (retval) {
- dev_err(&dev->dev, "%s: error %d completing urb %d\n",
- __func__, retval, pipe);
- goto exit;
- } else {
- retval = cnt;
- dev_dbg(&dev->dev, "%s: sent %d bytes to pipe %d\n",
- __func__, cnt, pipe);
- }
-
-exit:
- usb_free_urb(urb);
- kfree(buf);
- return retval;
-}
-
-static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
- int retval = 0;
- int cnt = -1;
- void __user *data = (void __user *)arg;
- struct vstusb_args usb_data;
-
- struct vstusb_device *vstdev;
- void *buffer = NULL; /* must be initialized. buffer is
- * referenced on exit but not all
- * ioctls allocate it */
-
- struct urb *urb = NULL; /* must be initialized. urb is
- * referenced on exit but not all
- * ioctls allocate it */
- struct usb_device *dev;
- unsigned int pipe;
- int timeout;
-
- DECLARE_COMPLETION_ONSTACK(done);
-
- vstdev = file->private_data;
-
- if (_IOC_TYPE(cmd) != VST_IOC_MAGIC) {
- dev_warn(&vstdev->usb_dev->dev,
- "%s: ioctl command %x, bad ioctl magic %x, "
- "expected %x\n", __func__, cmd,
- _IOC_TYPE(cmd), VST_IOC_MAGIC);
- return -EINVAL;
- }
-
- if (vstdev == NULL)
- return -ENODEV;
-
- if (copy_from_user(&usb_data, data, sizeof(struct vstusb_args))) {
- dev_err(&vstdev->usb_dev->dev, "%s: can't copy_from_user\n",
- __func__);
- return -EFAULT;
- }
-
- /* lock this object */
- if (mutex_lock_interruptible(&vstdev->lock)) {
- retval = -ERESTARTSYS;
- goto exit;
- }
-
- /* anyone home */
- if (!vstdev->present) {
- mutex_unlock(&vstdev->lock);
- dev_err(&vstdev->usb_dev->dev, "%s: device not present\n",
- __func__);
- retval = -ENODEV;
- goto exit;
- }
-
- /* pull out the necessary data */
- dev = vstdev->usb_dev;
-
- switch (cmd) {
-
- case IOCTL_VSTUSB_CONFIG_RW:
-
- vstdev->rd_pipe = usb_data.rd_pipe;
- vstdev->rd_timeout_ms = usb_data.rd_timeout_ms;
- vstdev->wr_pipe = usb_data.wr_pipe;
- vstdev->wr_timeout_ms = usb_data.wr_timeout_ms;
-
- mutex_unlock(&vstdev->lock);
-
- dev_dbg(&dev->dev, "%s: setting pipes/timeouts, "
- "rdpipe = %d, rdtimeout = %d, "
- "wrpipe = %d, wrtimeout = %d\n", __func__,
- vstdev->rd_pipe, vstdev->rd_timeout_ms,
- vstdev->wr_pipe, vstdev->wr_timeout_ms);
- break;
-
- case IOCTL_VSTUSB_SEND_PIPE:
-
- if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
- mutex_unlock(&vstdev->lock);
- retval = -EINVAL;
- goto exit;
- }
-
- buffer = kmalloc(usb_data.count, GFP_KERNEL);
- if (buffer == NULL) {
- mutex_unlock(&vstdev->lock);
- retval = -ENOMEM;
- goto exit;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- mutex_unlock(&vstdev->lock);
- retval = -ENOMEM;
- goto exit;
- }
-
- timeout = usb_data.timeout_ms;
-
- pipe = usb_sndbulkpipe(dev, usb_data.pipe);
-
- if (copy_from_user(buffer, usb_data.buffer, usb_data.count)) {
- dev_err(&dev->dev, "%s: can't copy_from_user\n",
- __func__);
- mutex_unlock(&vstdev->lock);
- retval = -EFAULT;
- goto exit;
- }
-
- usb_anchor_urb(urb, &vstdev->submitted);
- retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
- usb_data.count, &done);
- mutex_unlock(&vstdev->lock);
- if (retval) {
- usb_unanchor_urb(urb);
- dev_err(&dev->dev,
- "%s: error %d filling and sending urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
- if (retval) {
- dev_err(&dev->dev, "%s: error %d completing urb %d\n",
- __func__, retval, pipe);
- }
-
- break;
- case IOCTL_VSTUSB_RECV_PIPE:
-
- if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
- mutex_unlock(&vstdev->lock);
- retval = -EINVAL;
- goto exit;
- }
-
- buffer = kmalloc(usb_data.count, GFP_KERNEL);
- if (buffer == NULL) {
- mutex_unlock(&vstdev->lock);
- retval = -ENOMEM;
- goto exit;
- }
-
- urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- mutex_unlock(&vstdev->lock);
- retval = -ENOMEM;
- goto exit;
- }
-
- timeout = usb_data.timeout_ms;
-
- pipe = usb_rcvbulkpipe(dev, usb_data.pipe);
-
- usb_anchor_urb(urb, &vstdev->submitted);
- retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
- usb_data.count, &done);
- mutex_unlock(&vstdev->lock);
- if (retval) {
- usb_unanchor_urb(urb);
- dev_err(&dev->dev,
- "%s: error %d filling and sending urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
- if (retval) {
- dev_err(&dev->dev, "%s: error %d completing urb %d\n",
- __func__, retval, pipe);
- goto exit;
- }
-
- if (copy_to_user(usb_data.buffer, buffer, cnt)) {
- dev_err(&dev->dev, "%s: can't copy_to_user\n",
- __func__);
- retval = -EFAULT;
- goto exit;
- }
-
- usb_data.count = cnt;
- if (copy_to_user(data, &usb_data, sizeof(struct vstusb_args))) {
- dev_err(&dev->dev, "%s: can't copy_to_user\n",
- __func__);
- retval = -EFAULT;
- } else {
- dev_dbg(&dev->dev, "%s: recv %zd bytes from pipe %d\n",
- __func__, usb_data.count, usb_data.pipe);
- }
-
- break;
-
- default:
- mutex_unlock(&vstdev->lock);
- dev_warn(&dev->dev, "ioctl_vstusb: invalid ioctl cmd %x\n",
- cmd);
- return -EINVAL;
- break;
- }
-exit:
- usb_free_urb(urb);
- kfree(buffer);
- return retval;
-}
-
-static const struct file_operations vstusb_fops = {
- .owner = THIS_MODULE,
- .read = vstusb_read,
- .write = vstusb_write,
- .unlocked_ioctl = vstusb_ioctl,
- .compat_ioctl = vstusb_ioctl,
- .open = vstusb_open,
- .release = vstusb_release,
-};
-
-static struct usb_class_driver usb_vstusb_class = {
- .name = "usb/vstusb%d",
- .fops = &vstusb_fops,
- .minor_base = VSTUSB_MINOR_BASE,
-};
-
-static int vstusb_probe(struct usb_interface *intf,
- const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct vstusb_device *vstdev;
- int i;
- int retval = 0;
-
- /* allocate memory for our device state and intialize it */
-
- vstdev = kzalloc(sizeof(*vstdev), GFP_KERNEL);
- if (vstdev == NULL)
- return -ENOMEM;
-
- /* must do usb_get_dev() prior to kref_init() since the kref_put()
- * release function will do a usb_put_dev() */
- usb_get_dev(dev);
- kref_init(&vstdev->kref);
- mutex_init(&vstdev->lock);
-
- i = dev->descriptor.bcdDevice;
-
- dev_dbg(&intf->dev, "Version %1d%1d.%1d%1d found at address %d\n",
- (i & 0xF000) >> 12, (i & 0xF00) >> 8,
- (i & 0xF0) >> 4, (i & 0xF), dev->devnum);
-
- vstdev->present = 1;
- vstdev->isopen = 0;
- vstdev->usb_dev = dev;
- init_usb_anchor(&vstdev->submitted);
-
- usb_set_intfdata(intf, vstdev);
- retval = usb_register_dev(intf, &usb_vstusb_class);
- if (retval) {
- dev_err(&intf->dev,
- "%s: Not able to get a minor for this device.\n",
- __func__);
- usb_set_intfdata(intf, NULL);
- kref_put(&vstdev->kref, vstusb_delete);
- return retval;
- }
-
- /* let the user know what node this device is now attached to */
- dev_info(&intf->dev,
- "VST USB Device #%d now attached to major %d minor %d\n",
- (intf->minor - VSTUSB_MINOR_BASE), USB_MAJOR, intf->minor);
-
- dev_info(&intf->dev, "%s, %s\n", DRIVER_DESC, DRIVER_VERSION);
-
- return retval;
-}
-
-static void vstusb_disconnect(struct usb_interface *intf)
-{
- struct vstusb_device *vstdev = usb_get_intfdata(intf);
-
- usb_deregister_dev(intf, &usb_vstusb_class);
- usb_set_intfdata(intf, NULL);
-
- if (vstdev) {
-
- mutex_lock(&vstdev->lock);
- vstdev->present = 0;
-
- usb_kill_anchored_urbs(&vstdev->submitted);
-
- mutex_unlock(&vstdev->lock);
-
- kref_put(&vstdev->kref, vstusb_delete);
- }
-
-}
-
-static int vstusb_suspend(struct usb_interface *intf, pm_message_t message)
-{
- struct vstusb_device *vstdev = usb_get_intfdata(intf);
- int time;
- if (!vstdev)
- return 0;
-
- mutex_lock(&vstdev->lock);
- time = usb_wait_anchor_empty_timeout(&vstdev->submitted, 1000);
- if (!time)
- usb_kill_anchored_urbs(&vstdev->submitted);
- mutex_unlock(&vstdev->lock);
-
- return 0;
-}
-
-static int vstusb_resume(struct usb_interface *intf)
-{
- return 0;
-}
-
-static struct usb_driver vstusb_driver = {
- .name = "vstusb",
- .probe = vstusb_probe,
- .disconnect = vstusb_disconnect,
- .suspend = vstusb_suspend,
- .resume = vstusb_resume,
- .id_table = id_table,
-};
-
-static int __init vstusb_init(void)
-{
- int rc;
-
- rc = usb_register(&vstusb_driver);
- if (rc)
- printk(KERN_ERR "%s: failed to register (%d)", __func__, rc);
-
- return rc;
-}
-
-static void __exit vstusb_exit(void)
-{
- usb_deregister(&vstusb_driver);
-}
-
-module_init(vstusb_init);
-module_exit(vstusb_exit);
-
-MODULE_AUTHOR("Dennis O'Brien/Stephen Ware");
-MODULE_DESCRIPTION(DRIVER_VERSION);
-MODULE_LICENSE("GPL");