summaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/Kconfig1
-rw-r--r--drivers/usb/Makefile2
-rw-r--r--drivers/usb/class/cdc-acm.c49
-rw-r--r--drivers/usb/core/Kconfig3
-rw-r--r--drivers/usb/core/hub.c10
-rw-r--r--drivers/usb/core/inode.c2
-rw-r--r--drivers/usb/gadget/epautoconf.c16
-rw-r--r--drivers/usb/gadget/ether.c8
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/rndis.c2
-rw-r--r--drivers/usb/gadget/rndis.h2
-rw-r--r--drivers/usb/gadget/serial.c2
-rw-r--r--drivers/usb/gadget/zero.c2
-rw-r--r--drivers/usb/host/ehci-au1xxx.c23
-rw-r--r--drivers/usb/host/ehci-hcd.c7
-rw-r--r--drivers/usb/host/ohci-au1xxx.c7
-rw-r--r--drivers/usb/host/ohci-ep93xx.c225
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-hub.c4
-rw-r--r--drivers/usb/host/pci-quirks.c8
-rw-r--r--drivers/usb/input/hid-core.c4
-rw-r--r--drivers/usb/misc/Kconfig10
-rw-r--r--drivers/usb/misc/Makefile2
-rw-r--r--drivers/usb/misc/cy7c63.c244
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c279
-rw-r--r--drivers/usb/misc/usblcd.c6
-rw-r--r--drivers/usb/mon/mon_text.c7
-rw-r--r--drivers/usb/net/rtl8150.c3
-rw-r--r--drivers/usb/serial/Kconfig11
-rw-r--r--drivers/usb/serial/Makefile1
-rw-r--r--drivers/usb/serial/airprime.c2
-rw-r--r--drivers/usb/serial/anydata.c4
-rw-r--r--drivers/usb/serial/ark3116.c2
-rw-r--r--drivers/usb/serial/belkin_sa.c2
-rw-r--r--drivers/usb/serial/bus.c2
-rw-r--r--drivers/usb/serial/console.c3
-rw-r--r--drivers/usb/serial/cp2101.c2
-rw-r--r--drivers/usb/serial/cyberjack.c2
-rw-r--r--drivers/usb/serial/cypress_m8.c2
-rw-r--r--drivers/usb/serial/digi_acceleport.c2
-rw-r--r--drivers/usb/serial/empeg.c2
-rw-r--r--drivers/usb/serial/ezusb.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c108
-rw-r--r--drivers/usb/serial/ftdi_sio.h15
-rw-r--r--drivers/usb/serial/funsoft.c2
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/generic.c3
-rw-r--r--drivers/usb/serial/hp4x.c2
-rw-r--r--drivers/usb/serial/io_edgeport.c2
-rw-r--r--drivers/usb/serial/io_ti.c2
-rw-r--r--drivers/usb/serial/ipaq.c25
-rw-r--r--drivers/usb/serial/ipw.c4
-rw-r--r--drivers/usb/serial/ir-usb.c2
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/keyspan_pda.c3
-rw-r--r--drivers/usb/serial/kl5kusb105.c2
-rw-r--r--drivers/usb/serial/kobil_sct.c2
-rw-r--r--drivers/usb/serial/mct_u232.c2
-rw-r--r--drivers/usb/serial/navman.c2
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/option.c8
-rw-r--r--drivers/usb/serial/pl2303.c4
-rw-r--r--drivers/usb/serial/pl2303.h5
-rw-r--r--drivers/usb/serial/safe_serial.c2
-rw-r--r--drivers/usb/serial/sierra.c75
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c2
-rw-r--r--drivers/usb/serial/usb-serial.c25
-rw-r--r--drivers/usb/serial/usb-serial.h300
-rw-r--r--drivers/usb/serial/visor.c39
-rw-r--r--drivers/usb/serial/whiteheat.c2
-rw-r--r--drivers/usb/storage/scsiglue.c12
-rw-r--r--drivers/usb/storage/transport.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h60
-rw-r--r--drivers/usb/storage/usb.c29
-rw-r--r--drivers/usb/storage/usb.h4
75 files changed, 991 insertions, 735 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index 7fdbc5dad5f..2ee742d40c4 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -23,6 +23,7 @@ config USB_ARCH_HAS_OHCI
default y if ARCH_LH7A404
default y if ARCH_S3C2410
default y if PXA27x
+ default y if ARCH_EP93XX
default y if ARCH_AT91RM9200
# PPC:
default y if STB03xxx
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index c7123bf71c5..4710eb02ed6 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -48,7 +48,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/
obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_AUERSWALD) += misc/
-obj-$(CONFIG_USB_CY7C63) += misc/
+obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/
obj-$(CONFIG_USB_EMI62) += misc/
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 3670d77e912..ca90326f2f5 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -291,13 +291,13 @@ static void acm_read_bulk(struct urb *urb, struct pt_regs *regs)
struct acm_ru *rcv = urb->context;
struct acm *acm = rcv->instance;
int status = urb->status;
- dbg("Entering acm_read_bulk with status %d\n", urb->status);
+ dbg("Entering acm_read_bulk with status %d", urb->status);
if (!ACM_READY(acm))
return;
if (status)
- dev_dbg(&acm->data->dev, "bulk rx status %d\n", status);
+ dev_dbg(&acm->data->dev, "bulk rx status %d", status);
buf = rcv->buffer;
buf->size = urb->actual_length;
@@ -343,7 +343,7 @@ next_buffer:
list_del(&buf->list);
spin_unlock(&acm->read_lock);
- dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d\n", buf, buf->size);
+ dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
tty_buffer_request_room(tty, buf->size);
if (!acm->throttle)
@@ -394,7 +394,7 @@ urbs:
rcv->urb->transfer_dma = buf->dma;
rcv->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
- dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p\n", rcv->urb, rcv, buf);
+ dbg("acm_rx_tasklet: sending urb 0x%p, rcv 0x%p, buf 0x%p", rcv->urb, rcv, buf);
/* This shouldn't kill the driver as unsuccessful URBs are returned to the
free-urbs-pool and resubmited ASAP */
@@ -413,7 +413,7 @@ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
{
struct acm *acm = (struct acm *)urb->context;
- dbg("Entering acm_write_bulk with status %d\n", urb->status);
+ dbg("Entering acm_write_bulk with status %d", urb->status);
acm_write_done(acm);
acm_write_start(acm);
@@ -424,7 +424,7 @@ static void acm_write_bulk(struct urb *urb, struct pt_regs *regs)
static void acm_softint(void *private)
{
struct acm *acm = private;
- dbg("Entering acm_softint.\n");
+ dbg("Entering acm_softint.");
if (!ACM_READY(acm))
return;
@@ -440,7 +440,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
struct acm *acm;
int rv = -EINVAL;
int i;
- dbg("Entering acm_tty_open.\n");
+ dbg("Entering acm_tty_open.");
mutex_lock(&open_mutex);
@@ -541,7 +541,7 @@ static int acm_tty_write(struct tty_struct *tty, const unsigned char *buf, int c
int wbn;
struct acm_wb *wb;
- dbg("Entering acm_tty_write to write %d bytes,\n", count);
+ dbg("Entering acm_tty_write to write %d bytes,", count);
if (!ACM_READY(acm))
return -EINVAL;
@@ -793,7 +793,7 @@ static int acm_probe (struct usb_interface *intf,
if (!buflen) {
if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) {
- dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n");
+ dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint");
buflen = intf->cur_altsetting->endpoint->extralen;
buffer = intf->cur_altsetting->endpoint->extra;
} else {
@@ -842,24 +842,24 @@ next_desc:
if (!union_header) {
if (call_interface_num > 0) {
- dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n");
+ dev_dbg(&intf->dev,"No union descriptor, using call management descriptor");
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num));
control_interface = intf;
} else {
- dev_dbg(&intf->dev,"No union descriptor, giving up\n");
+ dev_dbg(&intf->dev,"No union descriptor, giving up");
return -ENODEV;
}
} else {
control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0);
data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0));
if (!control_interface || !data_interface) {
- dev_dbg(&intf->dev,"no interfaces\n");
+ dev_dbg(&intf->dev,"no interfaces");
return -ENODEV;
}
}
if (data_interface_num != call_interface_num)
- dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n");
+ dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.");
skip_normal_probe:
@@ -867,7 +867,7 @@ skip_normal_probe:
if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) {
if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) {
struct usb_interface *t;
- dev_dbg(&intf->dev,"Your device has switched interfaces.\n");
+ dev_dbg(&intf->dev,"Your device has switched interfaces.");
t = control_interface;
control_interface = data_interface;
@@ -878,7 +878,7 @@ skip_normal_probe:
}
if (usb_interface_claimed(data_interface)) { /* valid in this context */
- dev_dbg(&intf->dev,"The data interface isn't available\n");
+ dev_dbg(&intf->dev,"The data interface isn't available");
return -EBUSY;
}
@@ -895,7 +895,7 @@ skip_normal_probe:
if ((epread->bEndpointAddress & USB_DIR_IN) != USB_DIR_IN) {
/* descriptors are swapped */
struct usb_endpoint_descriptor *t;
- dev_dbg(&intf->dev,"The data interface has switched endpoints\n");
+ dev_dbg(&intf->dev,"The data interface has switched endpoints");
t = epread;
epread = epwrite;
@@ -910,7 +910,7 @@ skip_normal_probe:
}
if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n");
+ dev_dbg(&intf->dev, "out of memory (acm kzalloc)");
goto alloc_fail;
}
@@ -936,26 +936,26 @@ skip_normal_probe:
buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf) {
- dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n");
+ dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)");
goto alloc_fail2;
}
acm->ctrl_buffer = buf;
if (acm_write_buffers_alloc(acm) < 0) {
- dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n");
+ dev_dbg(&intf->dev, "out of memory (write buffer alloc)");
goto alloc_fail4;
}
acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->ctrlurb) {
- dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n");
+ dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)");
goto alloc_fail5;
}
for (i = 0; i < num_rx_buf; i++) {
struct acm_ru *rcv = &(acm->ru[i]);
if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) {
- dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n");
+ dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)");
goto alloc_fail7;
}
@@ -966,13 +966,13 @@ skip_normal_probe:
struct acm_rb *buf = &(acm->rb[i]);
if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) {
- dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n");
+ dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)");
goto alloc_fail7;
}
}
acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
if (!acm->writeurb) {
- dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n");
+ dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)");
goto alloc_fail7;
}
@@ -1086,6 +1086,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
.driver_info = SINGLE_RX_URB, /* firmware bug */
},
+ { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
+ .driver_info = SINGLE_RX_URB, /* firmware bug */
+ },
/* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index a08787e253a..6e3b5358a76 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -31,9 +31,6 @@ config USB_DEVICEFS
For the format of the various /proc/bus/usb/ files, please read
<file:Documentation/usb/proc_usb_info.txt>.
- Please note that this code is completely unrelated to devfs, the
- "/dev file system support".
-
Most users want to say Y here.
config USB_BANDWIDTH
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 875596e98e4..26c8cb5f3e6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1790,7 +1790,10 @@ static int finish_device_resume(struct usb_device *udev)
* and device drivers will know about any resume quirks.
*/
status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
- if (status < 2)
+ if (status >= 0)
+ status = (status == 2 ? 0 : -ENODEV);
+
+ if (status)
dev_dbg(&udev->dev,
"gone after usb resume? status %d\n",
status);
@@ -1879,7 +1882,12 @@ hub_port_resume(struct usb_hub *hub, int port1, struct usb_device *udev)
dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
port1, portchange, devstatus, status);
+ if (status >= 0)
+ status = -ENODEV;
} else {
+ if (portchange & USB_PORT_STAT_C_SUSPEND)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_SUSPEND);
/* TRSMRCY = 10 msec */
msleep(10);
if (udev)
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index f48c3dbc367..3182c2224ba 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -695,7 +695,7 @@ static void usbfs_remove_device(struct usb_device *dev)
wake_up_all(&ds->wait);
list_del_init(&ds->list);
if (ds->discsignr) {
- sinfo.si_signo = SIGPIPE;
+ sinfo.si_signo = ds->discsignr;
sinfo.si_errno = EPIPE;
sinfo.si_code = SI_ASYNCIO;
sinfo.si_addr = ds->disccontext;
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
index f7c6d758e1b..53d584589c2 100644
--- a/drivers/usb/gadget/epautoconf.c
+++ b/drivers/usb/gadget/epautoconf.c
@@ -34,12 +34,12 @@
/* we must assign addresses for configurable endpoints (like net2280) */
-static __initdata unsigned epnum;
+static __devinitdata unsigned epnum;
// #define MANY_ENDPOINTS
#ifdef MANY_ENDPOINTS
/* more than 15 configurable endpoints */
-static __initdata unsigned in_epnum;
+static __devinitdata unsigned in_epnum;
#endif
@@ -59,7 +59,7 @@ static __initdata unsigned in_epnum;
* NOTE: each endpoint is unidirectional, as specified by its USB
* descriptor; and isn't specific to a configuration or altsetting.
*/
-static int __init
+static int __devinit
ep_matches (
struct usb_gadget *gadget,
struct usb_ep *ep,
@@ -73,7 +73,7 @@ ep_matches (
/* endpoint already claimed? */
if (0 != ep->driver_data)
return 0;
-
+
/* only support ep0 for portable CONTROL traffic */
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
if (USB_ENDPOINT_XFER_CONTROL == type)
@@ -186,7 +186,7 @@ ep_matches (
return 1;
}
-static struct usb_ep * __init
+static struct usb_ep * __devinit
find_ep (struct usb_gadget *gadget, const char *name)
{
struct usb_ep *ep;
@@ -228,7 +228,7 @@ find_ep (struct usb_gadget *gadget, const char *name)
*
* On failure, this returns a null endpoint descriptor.
*/
-struct usb_ep * __init usb_ep_autoconfig (
+struct usb_ep * __devinit usb_ep_autoconfig (
struct usb_gadget *gadget,
struct usb_endpoint_descriptor *desc
)
@@ -276,7 +276,7 @@ struct usb_ep * __init usb_ep_autoconfig (
return ep;
}
- /* Second, look at endpoints until an unclaimed one looks usable */
+ /* Second, look at endpoints until an unclaimed one looks usable */
list_for_each_entry (ep, &gadget->ep_list, ep_list) {
if (ep_matches (gadget, ep, desc))
return ep;
@@ -295,7 +295,7 @@ struct usb_ep * __init usb_ep_autoconfig (
* state such as ep->driver_data and the record of assigned endpoints
* used by usb_ep_autoconfig().
*/
-void __init usb_ep_autoconfig_reset (struct usb_gadget *gadget)
+void __devinit usb_ep_autoconfig_reset (struct usb_gadget *gadget)
{
struct usb_ep *ep;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 8320fcef042..4fe1bec1c25 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -2131,7 +2131,7 @@ eth_req_free (struct usb_ep *ep, struct usb_request *req)
}
-static void __exit
+static void /* __init_or_exit */
eth_unbind (struct usb_gadget *gadget)
{
struct eth_dev *dev = get_gadget_data (gadget);
@@ -2158,7 +2158,7 @@ eth_unbind (struct usb_gadget *gadget)
set_gadget_data (gadget, NULL);
}
-static u8 __init nibble (unsigned char c)
+static u8 __devinit nibble (unsigned char c)
{
if (likely (isdigit (c)))
return c - '0';
@@ -2168,7 +2168,7 @@ static u8 __init nibble (unsigned char c)
return 0;
}
-static int __init get_ether_addr(const char *str, u8 *dev_addr)
+static int __devinit get_ether_addr(const char *str, u8 *dev_addr)
{
if (str) {
unsigned i;
@@ -2189,7 +2189,7 @@ static int __init get_ether_addr(const char *str, u8 *dev_addr)
return 1;
}
-static int __init
+static int __devinit
eth_bind (struct usb_gadget *gadget)
{
struct eth_dev *dev;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index b1a9cf06f3e..8d7f1e84cd7 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3691,7 +3691,7 @@ static void lun_release(struct device *dev)
kref_put(&fsg->ref, fsg_release);
}
-static void __exit fsg_unbind(struct usb_gadget *gadget)
+static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
{
struct fsg_dev *fsg = get_gadget_data(gadget);
int i;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 354670d1230..408c3380d60 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -1398,7 +1398,7 @@ static struct proc_dir_entry *rndis_connect_state [RNDIS_MAX_CONFIGS];
#endif /* CONFIG_USB_GADGET_DEBUG_FILES */
-int __init rndis_init (void)
+int __devinit rndis_init (void)
{
u8 i;
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index 2956608be75..4c3c7259f01 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -264,7 +264,7 @@ int rndis_signal_disconnect (int configNr);
int rndis_state (int configNr);
extern void rndis_set_host_mac (int configNr, const u8 *addr);
-int __init rndis_init (void);
+int __devinit rndis_init (void);
void rndis_exit (void);
#endif /* _LINUX_RNDIS_H */
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index 30d7664d449..e762aa19ab0 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -1473,7 +1473,7 @@ autoconf_fail:
* Called on module unload. Frees the control request and device
* structure.
*/
-static void __exit gs_unbind(struct usb_gadget *gadget)
+static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget)
{
struct gs_dev *dev = get_gadget_data(gadget);
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 3a08a7ab4ce..b7018ee487e 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -1121,7 +1121,7 @@ zero_autoresume (unsigned long _dev)
/*-------------------------------------------------------------------------*/
-static void __exit
+static void /* __init_or_exit */
zero_unbind (struct usb_gadget *gadget)
{
struct zero_dev *dev = get_gadget_data (gadget);
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index d66867aa527..26ed757d22a 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -41,8 +41,6 @@
#endif
#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
-#endif /* Au1200 */
-
extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
@@ -107,9 +105,9 @@ int usb_ehci_au1xxx_probe(const struct hc_driver *driver,
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
- pr_info("%s: this is chip revision AB!\n", dev->dev.name);
+ pr_info("%s: this is chip revision AB!\n", dev->name);
pr_info("%s: update your board or re-configure the kernel\n",
- dev->dev.name);
+ dev->name);
return -ENODEV;
}
#endif
@@ -228,9 +226,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
/*-------------------------------------------------------------------------*/
-static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
+static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
struct usb_hcd *hcd = NULL;
int ret;
@@ -243,10 +240,9 @@ static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
return ret;
}
-static int ehci_hcd_au1xxx_drv_remove(struct device *dev)
+static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(dev);
- struct usb_hcd *hcd = dev_get_drvdata(dev);
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_ehci_au1xxx_remove(hcd, pdev);
return 0;
@@ -269,12 +265,13 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
}
*/
MODULE_ALIAS("au1xxx-ehci");
-/* FIXME use "struct platform_driver" */
-static struct device_driver ehci_hcd_au1xxx_driver = {
- .name = "au1xxx-ehci",
- .bus = &platform_bus_type,
+static struct platform_driver ehci_hcd_au1xxx_driver = {
.probe = ehci_hcd_au1xxx_drv_probe,
.remove = ehci_hcd_au1xxx_drv_remove,
/*.suspend = ehci_hcd_au1xxx_drv_suspend, */
/*.resume = ehci_hcd_au1xxx_drv_resume, */
+ .driver = {
+ .name = "au1xxx-ehci",
+ .bus = &platform_bus_type
+ }
};
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index cee6f538de0..85b0b4ad4c1 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -625,10 +625,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
writel (status | CMD_RUN, &ehci->regs->command);
while (i--) {
- status = readl (&ehci->regs->port_status [i]);
- if (status & PORT_OWNER)
+ int pstatus = readl (&ehci->regs->port_status [i]);
+
+ if (pstatus & PORT_OWNER)
continue;
- if (!(status & PORT_RESUME)
+ if (!(pstatus & PORT_RESUME)
|| ehci->reset_done [i] != 0)
continue;
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 689261e4401..822914e2f43 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -101,13 +101,16 @@ static void au1xxx_start_ohc(struct platform_device *dev)
#endif /* Au1200 */
+#ifndef CONFIG_SOC_AU1200
/* wait for reset complete (read register twice; see au1500 errata) */
while (au_readl(USB_HOST_CONFIG),
!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
+#endif
udelay(1000);
printk(KERN_DEBUG __FILE__
": Clock to USB host has been enabled \n");
+#endif
}
static void au1xxx_stop_ohc(struct platform_device *dev)
@@ -157,9 +160,9 @@ static int usb_ohci_au1xxx_probe(const struct hc_driver *driver,
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
pr_info("%s: this is chip revision AB !!\n",
- dev->dev.name);
+ dev->name);
pr_info("%s: update your board or re-configure the kernel\n",
- dev->dev.name);
+ dev->name);
return -ENODEV;
}
#endif
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
new file mode 100644
index 00000000000..6531c4d2652
--- /dev/null
+++ b/drivers/usb/host/ohci-ep93xx.c
@@ -0,0 +1,225 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
+ * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
+ * (C) Copyright 2002 Hewlett-Packard Company
+ *
+ * Bus Glue for ep93xx.
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ * Based on fragments of previous driver by Russell King et al.
+ *
+ * Modified for LH7A404 from ohci-sa1111.c
+ * by Durgesh Pattamatta <pattamattad@sharpsec.com>
+ *
+ * Modified for pxa27x from ohci-lh7a404.c
+ * by Nick Bane <nick@cecomputing.co.uk> 26-8-2004
+ *
+ * Modified for ep93xx from ohci-pxa27x.c
+ * by Lennert Buytenhek <buytenh@wantstofly.org> 28-2-2006
+ * Based on an earlier driver by Ray Lehtiniemi
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+
+static struct clk *usb_host_clock;
+
+static void ep93xx_start_hc(struct device *dev)
+{
+ clk_enable(usb_host_clock);
+}
+
+static void ep93xx_stop_hc(struct device *dev)
+{
+ clk_disable(usb_host_clock);
+}
+
+static int usb_hcd_ep93xx_probe(const struct hc_driver *driver,
+ struct platform_device *pdev)
+{
+ int retval;
+ struct usb_hcd *hcd;
+
+ if (pdev->resource[1].flags != IORESOURCE_IRQ) {
+ pr_debug("resource[1] is not IORESOURCE_IRQ");
+ return -ENOMEM;
+ }
+
+ hcd = usb_create_hcd(driver, &pdev->dev, "ep93xx");
+ if (hcd == NULL)
+ return -ENOMEM;
+
+ hcd->rsrc_start = pdev->resource[0].start;
+ hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ usb_put_hcd(hcd);
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (hcd->regs == NULL) {
+ pr_debug("ioremap failed");
+ retval = -ENOMEM;
+ goto err2;
+ }
+
+ usb_host_clock = clk_get(&pdev->dev, "usb_host");
+ ep93xx_start_hc(&pdev->dev);
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT);
+ if (retval == 0)
+ return retval;
+
+ ep93xx_stop_hc(&pdev->dev);
+ iounmap(hcd->regs);
+err2:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err1:
+ usb_put_hcd(hcd);
+
+ return retval;
+}
+
+static void usb_hcd_ep93xx_remove(struct usb_hcd *hcd,
+ struct platform_device *pdev)
+{
+ usb_remove_hcd(hcd);
+ ep93xx_stop_hc(&pdev->dev);
+ clk_put(usb_host_clock);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ep93xx_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ if ((ret = ohci_init(ohci)) < 0)
+ return ret;
+
+ if ((ret = ohci_run(ohci)) < 0) {
+ err("can't start %s", hcd->self.bus_name);
+ ohci_stop(hcd);
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct hc_driver ohci_ep93xx_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "EP93xx OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+ .start = ohci_ep93xx_start,
+ .stop = ohci_stop,
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+ .get_frame_number = ohci_get_frame,
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+ .start_port_reset = ohci_start_port_reset,
+};
+
+extern int usb_disabled(void);
+
+static int ohci_hcd_ep93xx_drv_probe(struct platform_device *pdev)
+{
+ int ret;
+
+ ret = -ENODEV;
+ if (!usb_disabled())
+ ret = usb_hcd_ep93xx_probe(&ohci_ep93xx_hc_driver, pdev);
+
+ return ret;
+}
+
+static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_hcd_ep93xx_remove(hcd, pdev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ochi_hcd *ohci = hcd_to_ohci(hcd);
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+ ep93xx_stop_hc(&pdev->dev);
+ hcd->state = HC_STATE_SUSPENDED;
+ pdev->dev.power.power_state = PMSG_SUSPEND;
+
+ return 0;
+}
+
+static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int status;
+
+ if (time_before(jiffies, ohci->next_statechange))
+ msleep(5);
+ ohci->next_statechange = jiffies;
+
+ ep93xx_start_hc(&pdev->dev);
+ pdev->dev.power.power_state = PMSG_ON;
+ usb_hcd_resume_root_hub(hcd);
+
+ return 0;
+}
+#endif
+
+
+static struct platform_driver ohci_hcd_ep93xx_driver = {
+ .probe = ohci_hcd_ep93xx_drv_probe,
+ .remove = ohci_hcd_ep93xx_drv_remove,
+#ifdef CONFIG_PM
+ .suspend = ohci_hcd_ep93xx_drv_suspend,
+ .resume = ohci_hcd_ep93xx_drv_resume,
+#endif
+ .driver = {
+ .name = "ep93xx-ohci",
+ },
+};
+
+static int __init ohci_hcd_ep93xx_init(void)
+{
+ return platform_driver_register(&ohci_hcd_ep93xx_driver);
+}
+
+static void __exit ohci_hcd_ep93xx_cleanup(void)
+{
+ platform_driver_unregister(&ohci_hcd_ep93xx_driver);
+}
+
+module_init(ohci_hcd_ep93xx_init);
+module_exit(ohci_hcd_ep93xx_cleanup);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 8fb842ed5f6..afef5ac35b4 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -901,6 +901,10 @@ MODULE_LICENSE ("GPL");
#include "ohci-pxa27x.c"
#endif
+#ifdef CONFIG_ARCH_EP93XX
+#include "ohci-ep93xx.c"
+#endif
+
#ifdef CONFIG_SOC_AU1X00
#include "ohci-au1xxx.c"
#endif
@@ -919,6 +923,7 @@ MODULE_LICENSE ("GPL");
|| defined(CONFIG_ARCH_OMAP) \
|| defined (CONFIG_ARCH_LH7A404) \
|| defined (CONFIG_PXA27x) \
+ || defined (CONFIG_ARCH_EP93XX) \
|| defined (CONFIG_SOC_AU1X00) \
|| defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
|| defined (CONFIG_ARCH_AT91RM9200) \
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 0bb972b5833..5b0a23fd798 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -581,14 +581,14 @@ static int ohci_hub_control (
break;
case GetHubStatus:
temp = roothub_status (ohci) & ~(RH_HS_CRWE | RH_HS_DRWE);
- *(__le32 *) buf = cpu_to_le32 (temp);
+ put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
break;
case GetPortStatus:
if (!wIndex || wIndex > ports)
goto error;
wIndex--;
temp = roothub_portstatus (ohci, wIndex);
- *(__le32 *) buf = cpu_to_le32 (temp);
+ put_unaligned(cpu_to_le32 (temp), (__le32 *) buf);
#ifndef OHCI_VERBOSE_DEBUG
if (*(u16*)(buf+2)) /* only if wPortChange is interesting */
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index dff60568b4a..20861650905 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -167,8 +167,6 @@ static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx)
static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
{
void __iomem *base;
- int wait_time;
- u32 control;
if (!mmio_resource_enabled(pdev, 0))
return;
@@ -179,9 +177,10 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
/* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
#ifndef __hppa__
- control = readl(base + OHCI_CONTROL);
+{
+ u32 control = readl(base + OHCI_CONTROL);
if (control & OHCI_CTRL_IR) {
- wait_time = 500; /* arbitrary; 5 seconds */
+ int wait_time = 500; /* arbitrary; 5 seconds */
writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
writel(OHCI_OCR, base + OHCI_CMDSTATUS);
while (wait_time > 0 &&
@@ -198,6 +197,7 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
/* reset controller, preserving RWC */
writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
}
+}
#endif
/*
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index b9fb9687f92..8ea9c915fbf 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1507,6 +1507,9 @@ void hid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_4_PHIDGETSERVO_20 0x8104
#define USB_DEVICE_ID_DUAL_USB_JOYPAD 0x8866
+#define USB_VENDOR_ID_WISEGROUP_LTD 0x6677
+#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
+
#define USB_VENDOR_ID_CODEMERCS 0x07c0
#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
@@ -1670,6 +1673,7 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
+ { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index daa486dde8c..88928a4be80 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -88,19 +88,19 @@ config USB_LED
To compile this driver as a module, choose M here: the
module will be called usbled.
-config USB_CY7C63
+config USB_CYPRESS_CY7C63
tristate "Cypress CY7C63xxx USB driver support"
depends on USB
help
Say Y here if you want to connect a Cypress CY7C63xxx
- micro controller to your computer's USB port. This driver
- supports the pre-programmed devices (incl. firmware) by
- AK Modul-Bus Computer GmbH.
+ micro controller to your computer's USB port. Currently this
+ driver supports the pre-programmed devices (incl. firmware)
+ by AK Modul-Bus Computer GmbH.
Please see: http://www.ak-modul-bus.de/stat/mikrocontroller.html
To compile this driver as a module, choose M here: the
- module will be called cy7c63.
+ module will be called cypress_cy7c63.
config USB_CYTHERM
tristate "Cypress USB thermometer driver support"
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index f25a9722729..2927260c581 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -4,7 +4,7 @@
#
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
-obj-$(CONFIG_USB_CY7C63) += cy7c63.o
+obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o
obj-$(CONFIG_USB_EMI26) += emi26.o
obj-$(CONFIG_USB_EMI62) += emi62.o
diff --git a/drivers/usb/misc/cy7c63.c b/drivers/usb/misc/cy7c63.c
deleted file mode 100644
index 8a1c10b89b7..00000000000
--- a/drivers/usb/misc/cy7c63.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-* cy7c63.c
-*
-* Copyright (c) 2006 Oliver Bock (bock@fh-wolfenbuettel.de)
-*
-* This driver is based on the Cypress Thermometer USB Driver by
-* Marcus Maul and the 2.0 version of Greg Kroah-Hartman's
-* USB Skeleton driver.
-*
-* Is is a generic driver for the Cypress CY7C63000 family.
-* For the time being it enables you to toggle the single I/O ports
-* of the device.
-*
-* Supported vendors: AK Modul-Bus Computer GmbH
-* Supported devices: CY7C63001A-PC (to be continued...)
-* Supported functions: Read/Write Ports (to be continued...)
-*
-* Chipsets families: CY7C63000, CY7C63001, CY7C63100, CY7C63101
-*
-*
-* 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.
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/usb.h>
-
-#define DRIVER_AUTHOR "Oliver Bock (bock@fh-wolfenbuettel.de)"
-#define DRIVER_DESC "Cypress CY7C63xxx USB driver"
-
-#define CY7C63_VENDOR_ID 0xa2c
-#define CY7C63_PRODUCT_ID 0x8
-
-#define CY7C63_READ_PORT 0x4
-#define CY7C63_WRITE_PORT 0x5
-#define CY7C63_READ_RAM 0x2
-#define CY7C63_WRITE_RAM 0x3
-#define CY7C63_READ_ROM 0x1
-
-#define CY7C63_READ_PORT_ID0 0
-#define CY7C63_WRITE_PORT_ID0 0
-#define CY7C63_READ_PORT_ID1 0x2
-#define CY7C63_WRITE_PORT_ID1 1
-
-#define CY7C63_MAX_REQSIZE 8
-
-
-/* table of devices that work with this driver */
-static struct usb_device_id cy7c63_table [] = {
- { USB_DEVICE(CY7C63_VENDOR_ID, CY7C63_PRODUCT_ID) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, cy7c63_table);
-
-/* structure to hold all of our device specific stuff */
-struct cy7c63 {
- struct usb_device * udev;
- char port0;
- char port1;
-};
-
-/* used to send usb control messages to device */
-int vendor_command(struct cy7c63 *dev, unsigned char request,
- unsigned char address, unsigned char data) {
-
- int retval = 0;
- unsigned int pipe;
- unsigned char *iobuf;
-
- /* allocate some memory for the i/o buffer*/
- iobuf = kzalloc(CY7C63_MAX_REQSIZE, GFP_KERNEL);
- if (!iobuf) {
- dev_err(&dev->udev->dev, "Out of memory!\n");
- retval = -ENOMEM;
- goto error;
- }
-
- dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
-
- /* prepare usb control message and send it upstream */
- pipe = usb_rcvctrlpipe(dev->udev, 0);
- retval = usb_control_msg(dev->udev, pipe, request,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
- address, data, iobuf, CY7C63_MAX_REQSIZE,
- USB_CTRL_GET_TIMEOUT);
-
- /* store returned data (more READs to be added!) */
- switch (request) {
- case CY7C63_READ_PORT:
- if (address == CY7C63_READ_PORT_ID0) {
- dev->port0 = iobuf[1];
- dev_dbg(&dev->udev->dev,
- "READ_PORT0 returned: %d\n",dev->port0);
- }
- else if (address == CY7C63_READ_PORT_ID1) {
- dev->port1 = iobuf[1];
- dev_dbg(&dev->udev->dev,
- "READ_PORT1 returned: %d\n",dev->port1);
- }
- break;
- }
-
- kfree(iobuf);
-error:
- return retval;
-}
-
-#define get_set_port(num,read_id,write_id) \
-static ssize_t set_port##num(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t count) { \
- \
- int value; \
- int result = 0; \
- \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct cy7c63 *cyp = usb_get_intfdata(intf); \
- \
- dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", num); \
- \
- /* validate input data */ \
- if (sscanf(buf, "%d", &value) < 1) { \
- result = -EINVAL; \
- goto error; \
- } \
- if (value>255 || value<0) { \
- result = -EINVAL; \
- goto error; \
- } \
- \
- result = vendor_command(cyp, CY7C63_WRITE_PORT, write_id, \
- (unsigned char)value); \
- \
- dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n",result); \
-error: \
- return result < 0 ? result : count; \
-} \
- \
-static ssize_t get_port##num(struct device *dev, \
- struct device_attribute *attr, char *buf) { \
- \
- int result = 0; \
- \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct cy7c63 *cyp = usb_get_intfdata(intf); \
- \
- dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", num); \
- \
- result = vendor_command(cyp, CY7C63_READ_PORT, read_id, 0); \
- \
- dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result); \
- \
- return sprintf(buf, "%d", cyp->port##num); \
-} \
-static DEVICE_ATTR(port##num, S_IWUGO | S_IRUGO, get_port##num, set_port##num);
-
-get_set_port(0, CY7C63_READ_PORT_ID0, CY7C63_WRITE_PORT_ID0);
-get_set_port(1, CY7C63_READ_PORT_ID1, CY7C63_WRITE_PORT_ID1);
-
-static int cy7c63_probe(struct usb_interface *interface,
- const struct usb_device_id *id) {
-
- struct cy7c63 *dev = NULL;
- int retval = -ENOMEM;
-
- /* allocate memory for our device state and initialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (dev == NULL) {
- dev_err(&dev->udev->dev, "Out of memory!\n");
- goto error;
- }
-
- dev->udev = usb_get_dev(interface_to_usbdev(interface));
-
- /* save our data pointer in this interface device */
- usb_set_intfdata(interface, dev);
-
- /* create device attribute files */
- device_create_file(&interface->dev, &dev_attr_port0);
- device_create_file(&interface->dev, &dev_attr_port1);
-
- /* let the user know what node this device is now attached to */
- dev_info(&interface->dev,
- "Cypress CY7C63xxx device now attached\n");
-
- retval = 0;
-error:
- return retval;
-}
-
-static void cy7c63_disconnect(struct usb_interface *interface) {
-
- struct cy7c63 *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);
-
- usb_put_dev(dev->udev);
-
- dev_info(&interface->dev,
- "Cypress CY7C63xxx device now disconnected\n");
-
- kfree(dev);
-}
-
-static struct usb_driver cy7c63_driver = {
- .name = "cy7c63",
- .probe = cy7c63_probe,
- .disconnect = cy7c63_disconnect,
- .id_table = cy7c63_table,
-};
-
-static int __init cy7c63_init(void) {
-
- int result;
-
- /* register this driver with the USB subsystem */
- result = usb_register(&cy7c63_driver);
- if (result) {
- err("Function usb_register failed! Error number: %d\n", result);
- }
-
- return result;
-}
-
-static void __exit cy7c63_exit(void) {
-
- /* deregister this driver with the USB subsystem */
- usb_deregister(&cy7c63_driver);
-}
-
-module_init(cy7c63_init);
-module_exit(cy7c63_exit);
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
new file mode 100644
index 00000000000..e091d327bd9
--- /dev/null
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -0,0 +1,279 @@
+/*
+* cypress_cy7c63.c
+*
+* Copyright (c) 2006 Oliver Bock (o.bock@fh-wolfenbuettel.de)
+*
+* This driver is based on the Cypress USB Driver by Marcus Maul
+* (cyport) and the 2.0 version of Greg Kroah-Hartman's
+* USB Skeleton driver.
+*
+* This is a generic driver for the Cypress CY7C63xxx family.
+* For the time being it enables you to read from and write to
+* the single I/O ports of the device.
+*
+* Supported vendors: AK Modul-Bus Computer GmbH
+* Supported devices: CY7C63001A-PC (to be continued...)
+* Supported functions: Read/Write Ports (to be continued...)
+*
+*
+* 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.
+*/
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/usb.h>
+
+#define DRIVER_AUTHOR "Oliver Bock (o.bock@fh-wolfenbuettel.de)"
+#define DRIVER_DESC "Cypress CY7C63xxx USB driver"
+
+#define CYPRESS_VENDOR_ID 0xa2c
+#define CYPRESS_PRODUCT_ID 0x8
+
+#define CYPRESS_READ_PORT 0x4
+#define CYPRESS_WRITE_PORT 0x5
+
+#define CYPRESS_READ_RAM 0x2
+#define CYPRESS_WRITE_RAM 0x3
+#define CYPRESS_READ_ROM 0x1
+
+#define CYPRESS_READ_PORT_ID0 0
+#define CYPRESS_WRITE_PORT_ID0 0
+#define CYPRESS_READ_PORT_ID1 0x2
+#define CYPRESS_WRITE_PORT_ID1 1
+
+#define CYPRESS_MAX_REQSIZE 8
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id cypress_table [] = {
+ { USB_DEVICE(CYPRESS_VENDOR_ID, CYPRESS_PRODUCT_ID) },
+ { }
+};
+MODULE_DEVICE_TABLE(usb, cypress_table);
+
+/* structure to hold all of our device specific stuff */
+struct cypress {
+ struct usb_device * udev;
+ unsigned char port[2];
+};
+
+/* used to send usb control messages to device */
+static int vendor_command(struct cypress *dev, unsigned char request,
+ unsigned char address, unsigned char data)
+{
+ int retval = 0;
+ unsigned int pipe;
+ unsigned char *iobuf;
+
+ /* allocate some memory for the i/o buffer*/
+ iobuf = kzalloc(CYPRESS_MAX_REQSIZE, GFP_KERNEL);
+ if (!iobuf) {
+ dev_err(&dev->udev->dev, "Out of memory!\n");
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ dev_dbg(&dev->udev->dev, "Sending usb_control_msg (data: %d)\n", data);
+
+ /* prepare usb control message and send it upstream */
+ pipe = usb_rcvctrlpipe(dev->udev, 0);
+ retval = usb_control_msg(dev->udev, pipe, request,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
+ address, data, iobuf, CYPRESS_MAX_REQSIZE,
+ USB_CTRL_GET_TIMEOUT);
+
+ /* store returned data (more READs to be added) */
+ switch (request) {
+ case CYPRESS_READ_PORT:
+ if (address == CYPRESS_READ_PORT_ID0) {
+ dev->port[0] = iobuf[1];
+ dev_dbg(&dev->udev->dev,
+ "READ_PORT0 returned: %d\n",
+ dev->port[0]);
+ }
+ else if (address == CYPRESS_READ_PORT_ID1) {
+ dev->port[1] = iobuf[1];
+ dev_dbg(&dev->udev->dev,
+ "READ_PORT1 returned: %d\n",
+ dev->port[1]);
+ }
+ break;
+ }
+
+ kfree(iobuf);
+error:
+ return retval;
+}
+
+/* write port value */
+static ssize_t write_port(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count,
+ int port_num, int write_id)
+{
+ int value = -1;
+ int result = 0;
+
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct cypress *cyp = usb_get_intfdata(intf);
+
+ dev_dbg(&cyp->udev->dev, "WRITE_PORT%d called\n", port_num);
+
+ /* validate input data */
+ if (sscanf(buf, "%d", &value) < 1) {
+ result = -EINVAL;
+ goto error;
+ }
+ if (value < 0 || value > 255) {
+ result = -EINVAL;
+ goto error;
+ }
+
+ result = vendor_command(cyp, CYPRESS_WRITE_PORT, write_id,
+ (unsigned char)value);
+
+ dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
+error:
+ return result < 0 ? result : count;
+}
+
+/* attribute callback handler (write) */
+static ssize_t set_port0_handler(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return write_port(dev, attr, buf, count, 0, CYPRESS_WRITE_PORT_ID0);
+}
+
+/* attribute callback handler (write) */
+static ssize_t set_port1_handler(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return write_port(dev, attr, buf, count, 1, CYPRESS_WRITE_PORT_ID1);
+}
+
+/* read port value */
+static ssize_t read_port(struct device *dev, struct device_attribute *attr,
+ char *buf, int port_num, int read_id)
+{
+ int result = 0;
+
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct cypress *cyp = usb_get_intfdata(intf);
+
+ dev_dbg(&cyp->udev->dev, "READ_PORT%d called\n", port_num);
+
+ result = vendor_command(cyp, CYPRESS_READ_PORT, read_id, 0);
+
+ dev_dbg(&cyp->udev->dev, "Result of vendor_command: %d\n\n", result);
+
+ return sprintf(buf, "%d", cyp->port[port_num]);
+}
+
+/* attribute callback handler (read) */
+static ssize_t get_port0_handler(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return read_port(dev, attr, buf, 0, CYPRESS_READ_PORT_ID0);
+}
+
+/* attribute callback handler (read) */
+static ssize_t get_port1_handler(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return read_port(dev, attr, buf, 1, CYPRESS_READ_PORT_ID1);
+}
+
+static DEVICE_ATTR(port0, S_IWUGO | S_IRUGO,
+ get_port0_handler, set_port0_handler);
+
+static DEVICE_ATTR(port1, S_IWUGO | S_IRUGO,
+ get_port1_handler, set_port1_handler);
+
+
+static int cypress_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct cypress *dev = NULL;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&dev->udev->dev, "Out of memory!\n");
+ goto error;
+ }
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+
+ /* create device attribute files */
+ device_create_file(&interface->dev, &dev_attr_port0);
+ device_create_file(&interface->dev, &dev_attr_port1);
+
+ /* let the user know that the device is now attached */
+ dev_info(&interface->dev,
+ "Cypress CY7C63xxx device now attached\n");
+
+ retval = 0;
+error:
+ return retval;
+}
+
+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);
+
+ usb_put_dev(dev->udev);
+
+ dev_info(&interface->dev,
+ "Cypress CY7C63xxx device now disconnected\n");
+
+ kfree(dev);
+}
+
+static struct usb_driver cypress_driver = {
+ .name = "cypress_cy7c63",
+ .probe = cypress_probe,
+ .disconnect = cypress_disconnect,
+ .id_table = cypress_table,
+};
+
+static int __init cypress_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&cypress_driver);
+ if (result) {
+ err("Function usb_register failed! Error number: %d\n", result);
+ }
+
+ return result;
+}
+
+static void __exit cypress_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&cypress_driver);
+}
+
+module_init(cypress_init);
+module_exit(cypress_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index c82c402285a..e095772dd8e 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -200,10 +200,8 @@ static ssize_t lcd_write(struct file *file, const char __user * user_buffer, siz
/* create a urb, and a buffer for it, and copy the data to the urb */
urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!urb) {
- retval = -ENOMEM;
- goto error;
- }
+ if (!urb)
+ return -ENOMEM;
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c
index e02c1a30c4c..f961a770cee 100644
--- a/drivers/usb/mon/mon_text.c
+++ b/drivers/usb/mon/mon_text.c
@@ -64,7 +64,6 @@ struct mon_reader_text {
};
static void mon_text_ctor(void *, kmem_cache_t *, unsigned long);
-static void mon_text_dtor(void *, kmem_cache_t *, unsigned long);
/*
* mon_text_submit
@@ -268,7 +267,7 @@ static int mon_text_open(struct inode *inode, struct file *file)
(long)rp);
rp->e_slab = kmem_cache_create(rp->slab_name,
sizeof(struct mon_event_text), sizeof(long), 0,
- mon_text_ctor, mon_text_dtor);
+ mon_text_ctor, NULL);
if (rp->e_slab == NULL) {
rc = -ENOMEM;
goto err_slab;
@@ -459,7 +458,3 @@ static void mon_text_ctor(void *mem, kmem_cache_t *slab, unsigned long sflags)
memset(mem, 0xe5, sizeof(struct mon_event_text));
}
-static void mon_text_dtor(void *mem, kmem_cache_t *slab, unsigned long sflags)
-{
- ;
-}
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
index 718f8e2b552..e5e6e4f3ef8 100644
--- a/drivers/usb/net/rtl8150.c
+++ b/drivers/usb/net/rtl8150.c
@@ -128,11 +128,13 @@
#define VENDOR_ID_MELCO 0x0411
#define VENDOR_ID_MICRONET 0x3980
#define VENDOR_ID_LONGSHINE 0x07b8
+#define VENDOR_ID_ZYXEL 0x0586
#define PRODUCT_ID_RTL8150 0x8150
#define PRODUCT_ID_LUAKTX 0x0012
#define PRODUCT_ID_LCS8138TX 0x401a
#define PRODUCT_ID_SP128AR 0x0003
+#define PRODUCT_ID_PRESTIGE 0x401a
#undef EEPROM_WRITE
@@ -142,6 +144,7 @@ static struct usb_device_id rtl8150_table[] = {
{USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)},
{USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)},
{USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)},
+ {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)},
{}
};
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 8bd44fda5ea..ac33bd47cfc 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -456,6 +456,17 @@ config USB_SERIAL_SAFE_PADDED
bool "USB Secure Encapsulated Driver - Padded"
depends on USB_SERIAL_SAFE
+config USB_SERIAL_SIERRAWIRELESS
+ tristate "USB Sierra Wireless Driver"
+ depends on USB_SERIAL
+ help
+ Say M here if you want to use a Sierra Wireless device (if
+ using an PC 5220 or AC580 please use the Airprime driver
+ instead).
+
+ To compile this driver as a module, choose M here: the
+ module will be called sierra.
+
config USB_SERIAL_TI
tristate "USB TI 3410/5052 Serial Driver"
depends on USB_SERIAL
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile
index 5a0960fc9d3..35d4acc7f1d 100644
--- a/drivers/usb/serial/Makefile
+++ b/drivers/usb/serial/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o
obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
+obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 94b9ba0ff87..62082532a8b 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c
index 343f6f22822..01843ef8c11 100644
--- a/drivers/usb/serial/anydata.c
+++ b/drivers/usb/serial/anydata.c
@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */
@@ -71,7 +71,7 @@ static int anydata_open(struct usb_serial_port *port, struct file *filp)
port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer,
port->read_urb->transfer_buffer_length,
- usb_serial_generic_write_bulk_callback, port);
+ usb_serial_generic_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
dev_err(&port->dev,
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 8dec796222a..970d9ef0a7a 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -21,7 +21,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int debug;
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 3faa7aa0111..70ece9e01ce 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -74,7 +74,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "belkin_sa.h"
static int debug;
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index f2d993b70c1..6542f220468 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int usb_serial_device_match (struct device *dev, struct device_driver *drv)
{
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 3d456b32c31..3a9073dbfe6 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -17,11 +17,10 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
static int debug;
-#include "usb-serial.h"
-
struct usbcons_info {
int magic;
int break_flag;
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index df0a4f98b4a..486c7411b9a 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -26,7 +26,7 @@
#include <linux/moduleparam.h>
#include <linux/usb.h>
#include <asm/uaccess.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/*
* Version Information
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 49b51ab0d4c..6286aba86fa 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -39,7 +39,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#define CYBERJACK_LOCAL_BUF_SIZE 32
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 4ff2dfb299b..ee70fddcab6 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -59,11 +59,11 @@
#include <linux/moduleparam.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
#include <linux/serial.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
-#include "usb-serial.h"
#include "cypress_m8.h"
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 6953d3ef573..9b225183fc7 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -246,7 +246,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/wait.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/* Defines */
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 1e2b31eeb49..daafe405d86 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -62,7 +62,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int debug;
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
index debc3b0f966..5169c2d154a 100644
--- a/drivers/usb/serial/ezusb.c
+++ b/drivers/usb/serial/ezusb.c
@@ -15,7 +15,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
#define CPUCS_REG 0x7F92
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 8a74b19f128..b458aedc5fb 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -257,7 +257,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/serial.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "ftdi_sio.h"
/*
@@ -313,6 +313,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) },
{ USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) },
@@ -500,6 +501,8 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(PAPOUCH_VID, PAPOUCH_TMU_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ACG_HFDUAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_YEI_SERVOCENTER31_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_THORLABS_PID) },
+ { USB_DEVICE(TESTO_VID, TESTO_USB_INTERFACE_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -548,11 +551,17 @@ struct ftdi_private {
spinlock_t rx_lock; /* spinlock for receive state */
struct work_struct rx_work;
int rx_processed;
+ unsigned long rx_bytes;
__u16 interface; /* FT2232C port interface (0 for FT232/245) */
int force_baud; /* if non-zero, force the baud rate to this value */
int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
+
+ spinlock_t tx_lock; /* spinlock for transmit state */
+ unsigned long tx_bytes;
+ unsigned long tx_outstanding_bytes;
+ unsigned long tx_outstanding_urbs;
};
/* Used for TIOCMIWAIT */
@@ -626,6 +635,9 @@ static struct usb_serial_driver ftdi_sio_device = {
#define HIGH 1
#define LOW 0
+/* number of outstanding urbs to prevent userspace DoS from happening */
+#define URB_UPPER_LIMIT 42
+
/*
* ***************************************************************************
* Utlity functions
@@ -1156,6 +1168,7 @@ static int ftdi_sio_attach (struct usb_serial *serial)
}
spin_lock_init(&priv->rx_lock);
+ spin_lock_init(&priv->tx_lock);
init_waitqueue_head(&priv->delta_msr_wait);
/* This will push the characters through immediately rather
than queue a task to deliver them */
@@ -1270,6 +1283,13 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
dbg("%s", __FUNCTION__);
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ priv->tx_bytes = 0;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ spin_lock_irqsave(&priv->rx_lock, flags);
+ priv->rx_bytes = 0;
+ spin_unlock_irqrestore(&priv->rx_lock, flags);
+
if (port->tty)
port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
@@ -1372,6 +1392,7 @@ static int ftdi_write (struct usb_serial_port *port,
int data_offset ; /* will be 1 for the SIO and 0 otherwise */
int status;
int transfer_size;
+ unsigned long flags;
dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
@@ -1379,6 +1400,13 @@ static int ftdi_write (struct usb_serial_port *port,
dbg("write request of 0 bytes");
return 0;
}
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ dbg("%s - write limit hit\n", __FUNCTION__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
data_offset = priv->write_offset;
dbg("data_offset set to %d",data_offset);
@@ -1445,6 +1473,12 @@ static int ftdi_write (struct usb_serial_port *port,
err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
count = status;
kfree (buffer);
+ } else {
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ ++priv->tx_outstanding_urbs;
+ priv->tx_outstanding_bytes += count;
+ priv->tx_bytes += count;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
}
/* we are done with this urb, so let the host driver
@@ -1460,7 +1494,11 @@ static int ftdi_write (struct usb_serial_port *port,
static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
+ unsigned long flags;
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct ftdi_private *priv;
+ int data_offset; /* will be 1 for the SIO and 0 otherwise */
+ unsigned long countback;
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
@@ -1472,34 +1510,67 @@ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
return;
}
+ priv = usb_get_serial_port_data(port);
+ if (!priv) {
+ dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
+ return;
+ }
+ /* account for transferred data */
+ countback = urb->actual_length;
+ data_offset = priv->write_offset;
+ if (data_offset > 0) {
+ /* Subtract the control bytes */
+ countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
+ }
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ --priv->tx_outstanding_urbs;
+ priv->tx_outstanding_bytes -= countback;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
usb_serial_port_softint(port);
} /* ftdi_write_bulk_callback */
static int ftdi_write_room( struct usb_serial_port *port )
{
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int room;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We really can take anything the user throws at us
- * but let's pick a nice big number to tell the tty
- * layer that we have lots of free space
- */
- return 2048;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
+ /*
+ * We really can take anything the user throws at us
+ * but let's pick a nice big number to tell the tty
+ * layer that we have lots of free space
+ */
+ room = 2048;
+ } else {
+ room = 0;
+ }
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ return room;
} /* ftdi_write_room */
static int ftdi_chars_in_buffer (struct usb_serial_port *port)
{ /* ftdi_chars_in_buffer */
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ int buffered;
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
- /*
- * We can't really account for how much data we
- * have sent out, but hasn't made it through to the
- * device, so just tell the tty layer that everything
- * is flushed.
- */
- return 0;
+ spin_lock_irqsave(&priv->tx_lock, flags);
+ buffered = (int)priv->tx_outstanding_bytes;
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ if (buffered < 0) {
+ err("%s outstanding tx bytes is negative!", __FUNCTION__);
+ buffered = 0;
+ }
+ return buffered;
} /* ftdi_chars_in_buffer */
@@ -1509,6 +1580,8 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct tty_struct *tty;
struct ftdi_private *priv;
+ unsigned long countread;
+ unsigned long flags;
if (urb->number_of_packets > 0) {
err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
@@ -1543,6 +1616,13 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
return;
}
+ /* count data bytes, but not status bytes */
+ countread = urb->actual_length;
+ countread -= 2 * ((countread + (PKTSZ - 1)) / PKTSZ);
+ spin_lock_irqsave(&priv->rx_lock, flags);
+ priv->rx_bytes += countread;
+ spin_unlock_irqrestore(&priv->rx_lock, flags);
+
ftdi_process_read(port);
} /* ftdi_read_bulk_callback */
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 6ab2ac845bd..04ef90fcb87 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -36,6 +36,9 @@
#define FTDI_ACTZWAVE_PID 0xF2D0
+/* www.starting-point-systems.com µChameleon device */
+#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */
+
/* www.irtrans.de device */
#define FTDI_IRTRANS_PID 0xFC60 /* Product Id */
@@ -442,6 +445,18 @@
*/
#define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */
+/*
+ * ThorLabs USB motor drivers
+ */
+#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */
+
+/*
+ * Testo products (http://www.testo.com/)
+ * Submitted by Colin Leroy
+ */
+#define TESTO_VID 0x128D
+#define TESTO_USB_INTERFACE_PID 0x0001
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c
index 803721b97e2..77b977206a8 100644
--- a/drivers/usb/serial/funsoft.c
+++ b/drivers/usb/serial/funsoft.c
@@ -13,7 +13,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1404, 0xcddc) },
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 1f5d1620baa..727852634be 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
/* the mode to be set when the port ist opened */
static int initial_mode = 1;
@@ -42,8 +43,6 @@ static int initial_mode = 1;
/* debug flag */
static int debug = 0;
-#include "usb-serial.h"
-
#define GARMIN_VENDOR_ID 0x091E
/*
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 945b8bb38c9..17271355639 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -17,8 +17,8 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
#include <asm/uaccess.h>
-#include "usb-serial.h"
static int debug;
@@ -285,6 +285,7 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *reg
if (result)
dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
}
+EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
{
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index 7e06358b031..ebcac701b06 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -17,7 +17,7 @@
#include <linux/tty.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/*
* Version Information
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index bd2c05dac2a..c49976c3ad5 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -44,7 +44,7 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "io_edgeport.h"
#include "io_ionsp.h" /* info for the iosp messages */
#include "io_16654.h" /* 16654 UART defines */
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 723a12ae87b..17c5b1d2311 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -39,8 +39,8 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
-#include "usb-serial.h"
#include "io_16654.h"
#include "io_usbvend.h"
#include "io_ti.h"
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index dbcfe172a5c..59c5d999009 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -55,7 +55,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "ipaq.h"
#define KP_RETRIES 100
@@ -70,6 +70,8 @@
static __u16 product, vendor;
static int debug;
+static int connect_retries = KP_RETRIES;
+static int initial_wait;
/* Function prototypes for an ipaq */
static int ipaq_open (struct usb_serial_port *port, struct file *filp);
@@ -582,7 +584,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
struct ipaq_private *priv;
struct ipaq_packet *pkt;
int i, result = 0;
- int retries = KP_RETRIES;
+ int retries = connect_retries;
dbg("%s - port %d", __FUNCTION__, port->number);
@@ -646,16 +648,12 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
port->read_urb->transfer_buffer_length = URBDATA_SIZE;
port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
+ msleep(1000*initial_wait);
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
ipaq_read_bulk_callback, port);
- result = usb_submit_urb(port->read_urb, GFP_KERNEL);
- if (result) {
- err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
- goto error;
- }
/*
* Send out control message observed in win98 sniffs. Not sure what
@@ -670,8 +668,14 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
0x1, 0, NULL, 0, 100);
if (result == 0) {
+ result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+ if (result) {
+ err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
+ goto error;
+ }
return 0;
}
+ msleep(1000);
}
err("%s - failed doing control urb, error %d", __FUNCTION__, result);
goto error;
@@ -854,6 +858,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
if (urb->status) {
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+ return;
}
spin_lock_irqsave(&write_list_lock, flags);
@@ -966,3 +971,9 @@ MODULE_PARM_DESC(vendor, "User specified USB idVendor");
module_param(product, ushort, 0);
MODULE_PARM_DESC(product, "User specified USB idProduct");
+
+module_param(connect_retries, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(connect_retries, "Maximum number of connect retries (one second each)");
+
+module_param(initial_wait, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initial_wait, "Time to wait before attempting a connection (in seconds)");
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index a4a0bfeaab0..87306cb6f9f 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -46,8 +46,8 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
#include <asm/uaccess.h>
-#include "usb-serial.h"
/*
* Version Information
@@ -373,6 +373,8 @@ static void ipw_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s", __FUNCTION__);
+ port->write_urb_busy = 0;
+
if (urb->status)
dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 2cf1fed3de4..1738b0b6a37 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -57,7 +57,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/*
* Version Information
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index d7c58f1bc96..015ad6cc1bb 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -107,7 +107,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "keyspan.h"
static int debug;
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 03ab3c0f3cc..49b8dc039d1 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -78,6 +78,7 @@
#include <linux/workqueue.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
static int debug;
@@ -107,8 +108,6 @@ struct ezusb_hex_record {
#include "xircom_pgs_fw.h"
#endif
-#include "usb-serial.h"
-
/*
* Version Information
*/
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index b45ff3e7ab4..2a2f3e2da05 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -55,7 +55,7 @@
#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "kl5kusb105.h"
static int debug;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index 45773337477..d50dce03495 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -46,8 +46,8 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
#include <linux/ioctl.h>
-#include "usb-serial.h"
#include "kobil_sct.h"
static int debug;
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index ca05d3275f3..f4d4305c2c0 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -75,7 +75,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "mct_u232.h"
/*
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index 7f544081032..ac3f8b5d2c4 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -14,7 +14,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int debug;
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index cfb711a21a4..e49f40913c2 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -46,7 +46,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
static int debug;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 78ad4b3126a..f0530c1d7b7 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -35,6 +35,7 @@
2006-06-01 v0.6.2 add backwards-compatibility stuff
2006-06-01 v0.6.3 add Novatel Wireless
2006-06-01 v0.7 Option => GSM
+ 2006-06-01 v0.7.1 add COBRA2
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
@@ -53,7 +54,7 @@
device features.
*/
-#define DRIVER_VERSION "v0.7.0"
+#define DRIVER_VERSION "v0.7.1"
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
#define DRIVER_DESC "USB Driver for GSM modems"
@@ -64,7 +65,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
/* Function prototypes */
static int option_open(struct usb_serial_port *port, struct file *filp);
@@ -102,6 +103,7 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
#define OPTION_PRODUCT_COBRA 0x6500
+#define OPTION_PRODUCT_COBRA2 0x6600
#define HUAWEI_PRODUCT_E600 0x1001
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802
@@ -112,6 +114,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) },
@@ -124,6 +127,7 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) },
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index de93a2b909e..259db31b65c 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -27,7 +27,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "pl2303.h"
/*
@@ -52,6 +52,7 @@ struct pl2303_buf {
static struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ2) },
+ { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
@@ -79,6 +80,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(LEADTEK_VENDOR_ID, LEADTEK_9531_PRODUCT_ID) },
{ USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) },
{ USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) },
+ { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 7f29e81d3e3..d9c1e6e0b4b 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -10,6 +10,7 @@
#define PL2303_VENDOR_ID 0x067b
#define PL2303_PRODUCT_ID 0x2303
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
+#define PL2303_PRODUCT_ID_DCU11 0x1234
#define PL2303_PRODUCT_ID_PHAROS 0xaaa0
#define PL2303_PRODUCT_ID_RSAQ3 0xaaa2
@@ -84,3 +85,7 @@
/* Ours Technology Inc DKU-5 clone, chipset: Prolific Technology Inc */
#define OTI_VENDOR_ID 0x0ea0
#define OTI_PRODUCT_ID 0x6858
+
+/* DATAPILOT Universal-2 Phone Cable */
+#define DATAPILOT_U2_VENDOR_ID 0x0731
+#define DATAPILOT_U2_PRODUCT_ID 0x2003
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 897d8447252..789771ecdb1 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -71,7 +71,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#ifndef CONFIG_USB_SAFE_PADDED
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
new file mode 100644
index 00000000000..d29638daa98
--- /dev/null
+++ b/drivers/usb/serial/sierra.c
@@ -0,0 +1,75 @@
+/*
+ * Sierra Wireless CDMA Wireless Serial USB driver
+ *
+ * Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com>
+ * Original Copyright (C) 2005-2006 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 version
+ * 2 as published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+static struct usb_device_id id_table [] = {
+ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
+ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
+ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
+ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
+ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
+ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
+ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
+ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
+ /* Following devices are supported in the airprime.c driver */
+ /* { USB_DEVICE(0x1199, 0x0112) }, */ /* Sierra Wireless AirCard 580 */
+ /* { USB_DEVICE(0x0F3D, 0x0112) }, */ /* AirPrime/Sierra PC 5220 */
+ { }
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+static struct usb_driver sierra_driver = {
+ .name = "sierra_wireless",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static struct usb_serial_driver sierra_device = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "Sierra_Wireless",
+ },
+ .id_table = id_table,
+ .num_interrupt_in = NUM_DONT_CARE,
+ .num_bulk_in = NUM_DONT_CARE,
+ .num_bulk_out = NUM_DONT_CARE,
+ .num_ports = 3,
+};
+
+static int __init sierra_init(void)
+{
+ int retval;
+
+ retval = usb_serial_register(&sierra_device);
+ if (retval)
+ return retval;
+ retval = usb_register(&sierra_driver);
+ if (retval)
+ usb_serial_deregister(&sierra_device);
+ return retval;
+}
+
+static void __exit sierra_exit(void)
+{
+ usb_deregister(&sierra_driver);
+ usb_serial_deregister(&sierra_device);
+}
+
+module_init(sierra_init);
+module_exit(sierra_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index a9afff31a92..ac9b8ee52d4 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -83,8 +83,8 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/usb.h>
+#include <linux/usb/serial.h>
-#include "usb-serial.h"
#include "ti_usb_3410_5052.h"
#include "ti_fw_3410.h" /* firmware image for 3410 */
#include "ti_fw_5052.h" /* firmware image for 5052 */
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index b59a0536ea5..12c1694d322 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -31,7 +31,7 @@
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "pl2303.h"
/*
@@ -40,6 +40,8 @@
#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
#define DRIVER_DESC "USB Serial Driver core"
+static void port_free(struct usb_serial_port *port);
+
/* Driver structure we register with the USB core */
static struct usb_driver usb_serial_driver = {
.name = "usbserial",
@@ -146,23 +148,10 @@ static void destroy_serial(struct kref *kref)
port = serial->port[i];
if (!port)
continue;
- usb_kill_urb(port->read_urb);
- usb_free_urb(port->read_urb);
- usb_kill_urb(port->write_urb);
- usb_free_urb(port->write_urb);
- usb_kill_urb(port->interrupt_in_urb);
- usb_free_urb(port->interrupt_in_urb);
- usb_kill_urb(port->interrupt_out_urb);
- usb_free_urb(port->interrupt_out_urb);
- kfree(port->bulk_in_buffer);
- kfree(port->bulk_out_buffer);
- kfree(port->interrupt_in_buffer);
- kfree(port->interrupt_out_buffer);
+ port_free(port);
}
}
- flush_scheduled_work(); /* port->work */
-
usb_put_dev(serial->dev);
/* free up any memory that we allocated */
@@ -564,6 +553,11 @@ static void port_release(struct device *dev)
struct usb_serial_port *port = to_usb_serial_port(dev);
dbg ("%s - %s", __FUNCTION__, dev->bus_id);
+ port_free(port);
+}
+
+static void port_free(struct usb_serial_port *port)
+{
usb_kill_urb(port->read_urb);
usb_free_urb(port->read_urb);
usb_kill_urb(port->write_urb);
@@ -576,6 +570,7 @@ static void port_release(struct device *dev)
kfree(port->bulk_out_buffer);
kfree(port->interrupt_in_buffer);
kfree(port->interrupt_out_buffer);
+ flush_scheduled_work(); /* port->work */
kfree(port);
}
diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h
deleted file mode 100644
index 0f2802a6019..00000000000
--- a/drivers/usb/serial/usb-serial.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * USB Serial Converter driver
- *
- * Copyright (C) 1999 - 2005
- * Greg Kroah-Hartman (greg@kroah.com)
- *
- * 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; either version 2 of the License.
- *
- */
-
-
-#ifndef __LINUX_USB_SERIAL_H
-#define __LINUX_USB_SERIAL_H
-
-#include <linux/kref.h>
-#include <linux/mutex.h>
-
-#define SERIAL_TTY_MAJOR 188 /* Nice legal number now */
-#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
-
-#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
-
-/* parity check flag */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-/**
- * usb_serial_port: structure for the specific ports of a device.
- * @serial: pointer back to the struct usb_serial owner of this port.
- * @tty: pointer to the corresponding tty for this port.
- * @lock: spinlock to grab when updating portions of this structure.
- * @mutex: mutex used to synchronize serial_open() and serial_close()
- * access for this port.
- * @number: the number of the port (the minor number).
- * @interrupt_in_buffer: pointer to the interrupt in buffer for this port.
- * @interrupt_in_urb: pointer to the interrupt in struct urb for this port.
- * @interrupt_in_endpointAddress: endpoint address for the interrupt in pipe
- * for this port.
- * @interrupt_out_buffer: pointer to the interrupt out buffer for this port.
- * @interrupt_out_size: the size of the interrupt_out_buffer, in bytes.
- * @interrupt_out_urb: pointer to the interrupt out struct urb for this port.
- * @interrupt_out_endpointAddress: endpoint address for the interrupt out pipe
- * for this port.
- * @bulk_in_buffer: pointer to the bulk in buffer for this port.
- * @read_urb: pointer to the bulk in struct urb for this port.
- * @bulk_in_endpointAddress: endpoint address for the bulk in pipe for this
- * port.
- * @bulk_out_buffer: pointer to the bulk out buffer for this port.
- * @bulk_out_size: the size of the bulk_out_buffer, in bytes.
- * @write_urb: pointer to the bulk out struct urb for this port.
- * @bulk_out_endpointAddress: endpoint address for the bulk out pipe for this
- * port.
- * @write_wait: a wait_queue_head_t used by the port.
- * @work: work queue entry for the line discipline waking up.
- * @open_count: number of times this port has been opened.
- *
- * This structure is used by the usb-serial core and drivers for the specific
- * ports of a device.
- */
-struct usb_serial_port {
- struct usb_serial * serial;
- struct tty_struct * tty;
- spinlock_t lock;
- struct mutex mutex;
- unsigned char number;
-
- unsigned char * interrupt_in_buffer;
- struct urb * interrupt_in_urb;
- __u8 interrupt_in_endpointAddress;
-
- unsigned char * interrupt_out_buffer;
- int interrupt_out_size;
- struct urb * interrupt_out_urb;
- __u8 interrupt_out_endpointAddress;
-
- unsigned char * bulk_in_buffer;
- int bulk_in_size;
- struct urb * read_urb;
- __u8 bulk_in_endpointAddress;
-
- unsigned char * bulk_out_buffer;
- int bulk_out_size;
- struct urb * write_urb;
- int write_urb_busy;
- __u8 bulk_out_endpointAddress;
-
- wait_queue_head_t write_wait;
- struct work_struct work;
- int open_count;
- struct device dev;
-};
-#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
-
-/* get and set the port private data pointer helper functions */
-static inline void *usb_get_serial_port_data (struct usb_serial_port *port)
-{
- return dev_get_drvdata(&port->dev);
-}
-
-static inline void usb_set_serial_port_data (struct usb_serial_port *port, void *data)
-{
- dev_set_drvdata(&port->dev, data);
-}
-
-/**
- * usb_serial - structure used by the usb-serial core for a device
- * @dev: pointer to the struct usb_device for this device
- * @type: pointer to the struct usb_serial_driver for this device
- * @interface: pointer to the struct usb_interface for this device
- * @minor: the starting minor number for this device
- * @num_ports: the number of ports this device has
- * @num_interrupt_in: number of interrupt in endpoints we have
- * @num_interrupt_out: number of interrupt out endpoints we have
- * @num_bulk_in: number of bulk in endpoints we have
- * @num_bulk_out: number of bulk out endpoints we have
- * @port: array of struct usb_serial_port structures for the different ports.
- * @private: place to put any driver specific information that is needed. The
- * usb-serial driver is required to manage this data, the usb-serial core
- * will not touch this. Use usb_get_serial_data() and
- * usb_set_serial_data() to access this.
- */
-struct usb_serial {
- struct usb_device * dev;
- struct usb_serial_driver * type;
- struct usb_interface * interface;
- unsigned char minor;
- unsigned char num_ports;
- unsigned char num_port_pointers;
- char num_interrupt_in;
- char num_interrupt_out;
- char num_bulk_in;
- char num_bulk_out;
- struct usb_serial_port * port[MAX_NUM_PORTS];
- struct kref kref;
- void * private;
-};
-#define to_usb_serial(d) container_of(d, struct usb_serial, kref)
-
-#define NUM_DONT_CARE (-1)
-
-/* get and set the serial private data pointer helper functions */
-static inline void *usb_get_serial_data (struct usb_serial *serial)
-{
- return serial->private;
-}
-
-static inline void usb_set_serial_data (struct usb_serial *serial, void *data)
-{
- serial->private = data;
-}
-
-/**
- * usb_serial_driver - describes a usb serial driver
- * @description: pointer to a string that describes this driver. This string used
- * in the syslog messages when a device is inserted or removed.
- * @id_table: pointer to a list of usb_device_id structures that define all
- * of the devices this structure can support.
- * @num_interrupt_in: the number of interrupt in endpoints this device will
- * have.
- * @num_interrupt_out: the number of interrupt out endpoints this device will
- * have.
- * @num_bulk_in: the number of bulk in endpoints this device will have.
- * @num_bulk_out: the number of bulk out endpoints this device will have.
- * @num_ports: the number of different ports this device will have.
- * @calc_num_ports: pointer to a function to determine how many ports this
- * device has dynamically. It will be called after the probe()
- * callback is called, but before attach()
- * @probe: pointer to the driver's probe function.
- * This will be called when the device is inserted into the system,
- * but before the device has been fully initialized by the usb_serial
- * subsystem. Use this function to download any firmware to the device,
- * or any other early initialization that might be needed.
- * Return 0 to continue on with the initialization sequence. Anything
- * else will abort it.
- * @attach: pointer to the driver's attach function.
- * This will be called when the struct usb_serial structure is fully set
- * set up. Do any local initialization of the device, or any private
- * memory structure allocation at this point in time.
- * @shutdown: pointer to the driver's shutdown function. This will be
- * called when the device is removed from the system.
- *
- * This structure is defines a USB Serial driver. It provides all of
- * the information that the USB serial core code needs. If the function
- * pointers are defined, then the USB serial core code will call them when
- * the corresponding tty port functions are called. If they are not
- * called, the generic serial function will be used instead.
- *
- * The driver.owner field should be set to the module owner of this driver.
- * The driver.name field should be set to the name of this driver (remember
- * it will show up in sysfs, so it needs to be short and to the point.
- * Useing the module name is a good idea.)
- */
-struct usb_serial_driver {
- const char *description;
- const struct usb_device_id *id_table;
- char num_interrupt_in;
- char num_interrupt_out;
- char num_bulk_in;
- char num_bulk_out;
- char num_ports;
-
- struct list_head driver_list;
- struct device_driver driver;
-
- int (*probe) (struct usb_serial *serial, const struct usb_device_id *id);
- int (*attach) (struct usb_serial *serial);
- int (*calc_num_ports) (struct usb_serial *serial);
-
- void (*shutdown) (struct usb_serial *serial);
-
- int (*port_probe) (struct usb_serial_port *port);
- int (*port_remove) (struct usb_serial_port *port);
-
- /* serial function calls */
- int (*open) (struct usb_serial_port *port, struct file * filp);
- void (*close) (struct usb_serial_port *port, struct file * filp);
- int (*write) (struct usb_serial_port *port, const unsigned char *buf, int count);
- int (*write_room) (struct usb_serial_port *port);
- int (*ioctl) (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);
- void (*set_termios) (struct usb_serial_port *port, struct termios * old);
- void (*break_ctl) (struct usb_serial_port *port, int break_state);
- int (*chars_in_buffer) (struct usb_serial_port *port);
- void (*throttle) (struct usb_serial_port *port);
- void (*unthrottle) (struct usb_serial_port *port);
- int (*tiocmget) (struct usb_serial_port *port, struct file *file);
- int (*tiocmset) (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear);
-
- void (*read_int_callback)(struct urb *urb, struct pt_regs *regs);
- void (*write_int_callback)(struct urb *urb, struct pt_regs *regs);
- void (*read_bulk_callback)(struct urb *urb, struct pt_regs *regs);
- void (*write_bulk_callback)(struct urb *urb, struct pt_regs *regs);
-};
-#define to_usb_serial_driver(d) container_of(d, struct usb_serial_driver, driver)
-
-extern int usb_serial_register(struct usb_serial_driver *driver);
-extern void usb_serial_deregister(struct usb_serial_driver *driver);
-extern void usb_serial_port_softint(struct usb_serial_port *port);
-
-extern int usb_serial_probe(struct usb_interface *iface, const struct usb_device_id *id);
-extern void usb_serial_disconnect(struct usb_interface *iface);
-
-extern int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest);
-extern int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit);
-
-/* USB Serial console functions */
-#ifdef CONFIG_USB_SERIAL_CONSOLE
-extern void usb_serial_console_init (int debug, int minor);
-extern void usb_serial_console_exit (void);
-extern void usb_serial_console_disconnect(struct usb_serial *serial);
-#else
-static inline void usb_serial_console_init (int debug, int minor) { }
-static inline void usb_serial_console_exit (void) { }
-static inline void usb_serial_console_disconnect(struct usb_serial *serial) {}
-#endif
-
-/* Functions needed by other parts of the usbserial core */
-extern struct usb_serial *usb_serial_get_by_index (unsigned int minor);
-extern void usb_serial_put(struct usb_serial *serial);
-extern int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp);
-extern int usb_serial_generic_write (struct usb_serial_port *port, const unsigned char *buf, int count);
-extern void usb_serial_generic_close (struct usb_serial_port *port, struct file *filp);
-extern int usb_serial_generic_write_room (struct usb_serial_port *port);
-extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
-extern void usb_serial_generic_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-extern void usb_serial_generic_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
-extern void usb_serial_generic_shutdown (struct usb_serial *serial);
-extern int usb_serial_generic_register (int debug);
-extern void usb_serial_generic_deregister (void);
-
-extern int usb_serial_bus_register (struct usb_serial_driver *device);
-extern void usb_serial_bus_deregister (struct usb_serial_driver *device);
-
-extern struct usb_serial_driver usb_serial_generic_device;
-extern struct bus_type usb_serial_bus_type;
-extern struct tty_driver *usb_serial_tty_driver;
-
-static inline void usb_serial_debug_data(int debug,
- struct device *dev,
- const char *function, int size,
- const unsigned char *data)
-{
- int i;
-
- if (debug) {
- dev_printk(KERN_DEBUG, dev, "%s - length = %d, data = ", function, size);
- for (i = 0; i < size; ++i)
- printk ("%.2x ", data[i]);
- printk ("\n");
- }
-}
-
-/* Use our own dbg macro */
-#undef dbg
-#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG "%s: " format "\n" , __FILE__ , ## arg); } while (0)
-
-
-
-#endif /* ifdef __LINUX_USB_SERIAL_H */
-
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 95a2936e902..88949f7884c 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -25,7 +25,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "visor.h"
/*
@@ -302,7 +302,6 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
spin_lock_irqsave(&priv->lock, flags);
priv->bytes_in = 0;
priv->bytes_out = 0;
- priv->outstanding_urbs = 0;
priv->throttled = 0;
spin_unlock_irqrestore(&priv->lock, flags);
@@ -435,13 +434,25 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
static int visor_write_room (struct usb_serial_port *port)
{
+ struct visor_private *priv = usb_get_serial_port_data(port);
+ unsigned long flags;
+
dbg("%s - port %d", __FUNCTION__, port->number);
/*
* We really can take anything the user throws at us
* but let's pick a nice big number to tell the tty
- * layer that we have lots of free space
+ * layer that we have lots of free space, unless we don't.
*/
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ dbg("%s - write limit hit\n", __FUNCTION__);
+ return 0;
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
return 2048;
}
@@ -758,15 +769,22 @@ static int visor_calc_num_ports (struct usb_serial *serial)
static int generic_startup(struct usb_serial *serial)
{
+ struct usb_serial_port **ports = serial->port;
struct visor_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc (sizeof(*priv), GFP_KERNEL);
- if (!priv)
+ if (!priv) {
+ while (i-- != 0) {
+ priv = usb_get_serial_port_data(ports[i]);
+ usb_set_serial_port_data(ports[i], NULL);
+ kfree(priv);
+ }
return -ENOMEM;
+ }
spin_lock_init(&priv->lock);
- usb_set_serial_port_data(serial->port[i], priv);
+ usb_set_serial_port_data(ports[i], priv);
}
return 0;
}
@@ -876,7 +894,18 @@ static int clie_5_attach (struct usb_serial *serial)
static void visor_shutdown (struct usb_serial *serial)
{
+ struct visor_private *priv;
+ int i;
+
dbg("%s", __FUNCTION__);
+
+ for (i = 0; i < serial->num_ports; i++) {
+ priv = usb_get_serial_port_data(serial->port[i]);
+ if (priv) {
+ usb_set_serial_port_data(serial->port[i], NULL);
+ kfree(priv);
+ }
+ }
}
static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 540438c3f38..6e6c7934be3 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -79,7 +79,7 @@
#include <linux/usb.h>
#include <linux/serial_reg.h>
#include <linux/serial.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
#include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */
#include "whiteheat.h" /* WhiteHEAT specific commands */
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 5715291ba54..a4b7df9ff8c 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -112,13 +112,11 @@ static int slave_configure(struct scsi_device *sdev)
if (sdev->scsi_level < SCSI_2)
sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
- /* According to the technical support people at Genesys Logic,
- * devices using their chips have problems transferring more than
- * 32 KB at a time. In practice people have found that 64 KB
- * works okay and that's what Windows does. But we'll be
- * conservative; people can always use the sysfs interface to
- * increase max_sectors. */
- if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS &&
+ /* Many devices have trouble transfering more than 32KB at a time,
+ * while others have trouble with more than 64K. At this time we
+ * are limiting both to 32K (64 sectores).
+ */
+ if ((us->flags & US_FL_MAX_SECTORS_64) &&
sdev->request_queue->max_sectors > 64)
blk_queue_max_sectors(sdev->request_queue, 64);
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index eb7188b3565..d6acc92a4ae 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -180,7 +180,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout)
if (timeleft <= 0) {
US_DEBUGP("%s -- cancelling URB\n",
timeleft == 0 ? "Timeout" : "Signal");
- usb_unlink_urb(us->current_urb);
+ usb_kill_urb(us->current_urb);
}
/* return the URB status */
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index c7e84e653df..a5ca449f6e6 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -112,6 +112,19 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
+/* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
+UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100,
+ "Samsung Info. Systems America, Inc.",
+ "MP3 Player",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
+/* Reported by Orgad Shaneh <orgads@gmail.com> */
+UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100,
+ "Samsung", "MP3 Player",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
/* Reported by Christian Leber <christian@leber.de> */
UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100,
"TrekStor",
@@ -132,6 +145,14 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
+/* Reported by Sumedha Swamy <sumedhaswamy@gmail.com> and
+ * Einar Th. Einarsson <einarthered@gmail.com> */
+UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100,
+ "Nokia",
+ "N91",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+
/* Reported by Jiri Slaby <jirislaby@gmail.com> and
* Rene C. Castberg <Rene@Castberg.org> */
UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100,
@@ -140,6 +161,13 @@ UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+/* Reported by Matthew Bloch <matthew@bytemark.co.uk> */
+UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100,
+ "Nokia",
+ "E61",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ),
+
/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
"SMSC",
@@ -473,10 +501,11 @@ UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
US_SC_SCSI, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN | US_FL_NOT_LOCKABLE | US_FL_NO_WP_DETECT ),
-/* This entry is needed because the device reports Sub=ff */
-UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0600,
+/* Submitted by Lars Jacob <jacob.lars@googlemail.com>
+ * This entry is needed because the device reports Sub=ff */
+UNUSUAL_DEV( 0x054c, 0x0010, 0x0500, 0x0610,
"Sony",
- "DSC-T1/T5",
+ "DSC-T1/T5/H5",
US_SC_8070, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN ),
@@ -708,18 +737,22 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113,
* They were originally reported by Alexander Oltu
* <alexander@all-2.com> and Peter Marks <peter.marks@turner.com>
* respectively.
+ *
+ * US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz
+ * <phil@ipom.com> as these flags were made and hard-coded
+ * special-cases were pulled from scsiglue.c.
*/
UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Optical",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
"Genesys Logic",
"USB to IDE Disk",
US_SC_DEVICE, US_PR_DEVICE, NULL,
- US_FL_GO_SLOW ),
+ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
/* Reported by Hanno Boeck <hanno@gmx.de>
* Taken from the Lycoris Kernel */
@@ -1196,6 +1229,14 @@ UNUSUAL_DEV( 0x0ea0, 0x6828, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
+/* Reported by Benjamin Schiller <sbenni@gmx.de>
+ * It is also sold by Easylite as DJ 20 */
+UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
+ "Typhoon",
+ "My DJ 1820",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
+
/* Reported by Michael Stattmann <michael@stattmann.com> */
UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
"Sony Ericsson",
@@ -1227,6 +1268,15 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
+/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
+ * and Renato Perini <rperini@email.it>
+ */
+UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x0001,
+ "Motorola",
+ "RAZR V3x",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
+
/* Reported by Radovan Garabik <garabik@kassiopeia.juls.savba.sk> */
UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
"MPIO",
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 1185acac4b2..5ee19be52f6 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -55,6 +55,7 @@
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/mutex.h>
+#include <linux/utsrelease.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
@@ -373,8 +374,12 @@ static int usb_stor_control_thread(void * __us)
/* lock access to the state */
scsi_lock(host);
+ /* did the command already complete because of a disconnect? */
+ if (!us->srb)
+ ; /* nothing to do */
+
/* indicate that the command is done */
- if (us->srb->result != DID_ABORT << 16) {
+ else if (us->srb->result != DID_ABORT << 16) {
US_DEBUGP("scsi cmd done, result=0x%x\n",
us->srb->result);
us->srb->scsi_done(us->srb);
@@ -524,7 +529,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
printk(KERN_NOTICE USB_STORAGE "This device "
"(%04x,%04x,%04x S %02x P %02x)"
- " has %s in unusual_devs.h\n"
+ " has %s in unusual_devs.h (kernel"
+ " %s)\n"
" Please send a copy of this message to "
"<linux-usb-devel@lists.sourceforge.net>\n",
le16_to_cpu(ddesc->idVendor),
@@ -532,7 +538,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id)
le16_to_cpu(ddesc->bcdDevice),
idesc->bInterfaceSubClass,
idesc->bInterfaceProtocol,
- msgs[msg]);
+ msgs[msg],
+ UTS_RELEASE);
}
}
@@ -836,32 +843,34 @@ static void dissociate_dev(struct us_data *us)
* the host */
static void quiesce_and_remove_host(struct us_data *us)
{
+ struct Scsi_Host *host = us_to_host(us);
+
/* Prevent new USB transfers, stop the current command, and
* interrupt a SCSI-scan or device-reset delay */
+ scsi_lock(host);
set_bit(US_FLIDX_DISCONNECTING, &us->flags);
+ scsi_unlock(host);
usb_stor_stop_transport(us);
wake_up(&us->delay_wait);
/* It doesn't matter if the SCSI-scanning thread is still running.
* The thread will exit when it sees the DISCONNECTING flag. */
- /* Wait for the current command to finish, then remove the host */
- mutex_lock(&us->dev_mutex);
- mutex_unlock(&us->dev_mutex);
-
/* queuecommand won't accept any new commands and the control
* thread won't execute a previously-queued command. If there
* is such a command pending, complete it with an error. */
+ mutex_lock(&us->dev_mutex);
if (us->srb) {
us->srb->result = DID_NO_CONNECT << 16;
- scsi_lock(us_to_host(us));
+ scsi_lock(host);
us->srb->scsi_done(us->srb);
us->srb = NULL;
- scsi_unlock(us_to_host(us));
+ scsi_unlock(host);
}
+ mutex_unlock(&us->dev_mutex);
/* Now we own no commands so it's safe to remove the SCSI host */
- scsi_remove_host(us_to_host(us));
+ scsi_remove_host(host);
}
/* Second stage of disconnect processing: deallocate all resources */
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 5284abe1b5e..21f3ddbc908 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -176,8 +176,4 @@ extern void fill_inquiry_response(struct us_data *us,
#define scsi_unlock(host) spin_unlock_irq(host->host_lock)
#define scsi_lock(host) spin_lock_irq(host->host_lock)
-
-/* Vendor ID list for devices that require special handling */
-#define USB_VENDOR_ID_GENESYS 0x05e3 /* Genesys Logic */
-
#endif