From 18577a6184efbd95a72562c0c590218460d6ea33 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Fri, 23 Jun 2006 11:55:43 +0100 Subject: [PATCH 01/44] [PATCH] USB: au1xxx: compile fixes for OHCI for au1200 Compile fixes for au1200 ohci. First part looks a bit hackish... but it works for me. Signed-off-by: Domen Puncer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-au1xxx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 689261e44018..f7a975d5db09 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -101,9 +101,11 @@ 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__ @@ -157,9 +159,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 From d14feb5ee4a46218f92b21ed52338b64130a151b Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Fri, 23 Jun 2006 21:36:07 +0100 Subject: [PATCH 02/44] [PATCH] USB: au1200: EHCI and OHCI fixes I received an DBAU1200 eval kit from AMD a few days ago and tried to enable the USB2 port, but the current linux-2.6 GIT did not even compile with CONFIG_SOC_1200, CONFIG_SOC_AU1X00, CONFIG_USB_EHCI and CONFIG_USB_OHCI set. Furthermore, in ehci-hcd.c, platform_driver_register() was called with an improper argument of type 'struct device_driver *' which of course ended up in a kernel oops. How could that ever have worked on your machines? Anyway, here's a trivial patch that makes the USB subsystem working on my board for both OHCI and EHCI. It also removes the /* FIXME use "struct platform_driver" */. Signed-off-by: Daniel Mack Signed-off-by: Ralf Baechle Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-au1xxx.c | 23 ++++++++++------------- drivers/usb/host/ohci-au1xxx.c | 1 + 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index d66867aa527e..26ed757d22a6 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/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index f7a975d5db09..822914e2f43b 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c @@ -110,6 +110,7 @@ static void au1xxx_start_ohc(struct platform_device *dev) printk(KERN_DEBUG __FILE__ ": Clock to USB host has been enabled \n"); +#endif } static void au1xxx_stop_ohc(struct platform_device *dev) From a5b7474a0364507d168c7ff473e2d82deb676b08 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 23 Jun 2006 23:02:01 +0200 Subject: [PATCH 03/44] [PATCH] USB: ohci bits for the cirrus ep93xx This patch adds OHCI glue bits for the USB host interface in the Cirrus ep93xx (arm920t) CPU. Signed-off-by: Lennert Buytenhek Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + drivers/usb/host/ohci-ep93xx.c | 225 +++++++++++++++++++++++++++++++++ drivers/usb/host/ohci-hcd.c | 5 + 3 files changed, 231 insertions(+) create mode 100644 drivers/usb/host/ohci-ep93xx.c diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7fdbc5dad5fd..2ee742d40c43 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/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c new file mode 100644 index 000000000000..6531c4d26527 --- /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 + * (C) Copyright 2000-2002 David Brownell + * (C) Copyright 2002 Hewlett-Packard Company + * + * Bus Glue for ep93xx. + * + * Written by Christopher Hoover + * Based on fragments of previous driver by Russell King et al. + * + * Modified for LH7A404 from ohci-sa1111.c + * by Durgesh Pattamatta + * + * Modified for pxa27x from ohci-lh7a404.c + * by Nick Bane 26-8-2004 + * + * Modified for ep93xx from ohci-pxa27x.c + * by Lennert Buytenhek 28-2-2006 + * Based on an earlier driver by Ray Lehtiniemi + * + * This file is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include +#include + +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 8fb842ed5f6e..afef5ac35b4a 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) \ From 7fac9a3348921e0fc626c7856ce3d1a9746b2b39 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 22 Jun 2006 15:12:41 -0700 Subject: [PATCH 04/44] [PATCH] USB: fix usb kernel-doc Warning(/var/linsrc/linux-2617-g4//include/linux/usb.h:66): No description found for parameter 'ep_dev' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 8dead32e7ebf..c944e8f06a4a 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -48,7 +48,7 @@ struct ep_device; * @urb_list: urbs queued to this endpoint; maintained by usbcore * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH) * with one or more transfer descriptors (TDs) per urb - * @kobj: kobject for sysfs info + * @ep_dev: ep_device for sysfs info * @extra: descriptors following this endpoint in the configuration * @extralen: how many bytes of "extra" are valid * From 3d861494729c70d9ebeb7d93caa107897925c355 Mon Sep 17 00:00:00 2001 From: Peter Moulder Date: Mon, 19 Jun 2006 22:47:49 +1000 Subject: [PATCH 05/44] [PATCH] USB: Addition of vendor/product id pair for pl2303 driver Text from the back of the box, for your information/amusement: USB DATA CABLE FOR K700 Series The USB Cable is an ideal link between your mobile phone and PC. Employing the user-friendiy [sic] USB standard,its capacity for rapid data transfer enables functions such as synchronization of phone book and calendar,as well as Internet browsing via a modem-enabled phone.Autual [sic] connection speed is dependent on phone capacity. MADE IN CHINA From: Peter Moulder Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/usb-serial.txt | 4 ++-- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt index f001cd93b79b..02b0f7beb6d1 100644 --- a/Documentation/usb/usb-serial.txt +++ b/Documentation/usb/usb-serial.txt @@ -399,10 +399,10 @@ REINER SCT cyberJack pinpad/e-com USB chipcard reader Prolific PL2303 Driver - This driver support any device that has the PL2303 chip from Prolific + This driver supports any device that has the PL2303 chip from Prolific in it. This includes a number of single port USB to serial converters and USB GPS devices. Devices from Aten (the UC-232) and - IO-Data work with this driver. + IO-Data work with this driver, as does the DCU-11 mobile-phone cable. For any questions or problems with this driver, please contact Greg Kroah-Hartman at greg@kroah.com diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index de93a2b909e7..93d623a0d092 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -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) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index 7f29e81d3e35..cb2abad3a37e 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 From 48437486c69b4baf68ee98530d8119897148c602 Mon Sep 17 00:00:00 2001 From: "D. Peter Siddons" Date: Sat, 17 Jun 2006 18:09:15 -0400 Subject: [PATCH 06/44] [PATCH] USB: new device id for Thorlabs motor driver Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 8a74b19f1283..5facb022cedc 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -500,6 +500,7 @@ 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) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6ab2ac845bd7..459539220770 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -442,6 +442,11 @@ */ #define FTDI_YEI_SERVOCENTER31_PID 0xE050 /* YEI ServoCenter3.1 USB */ +/* + * ThorLabs USB motor drivers + */ +#define FTDI_THORLABS_PID 0xfaf0 /* ThorLabs USB motor drivers */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ From c0f8d56197f7d15f841e7d9d6f88909f4feba678 Mon Sep 17 00:00:00 2001 From: Christophe Mariac Date: Fri, 23 Jun 2006 17:36:21 +0200 Subject: [PATCH 07/44] [PATCH] USB: new device ids for ftdi_sio driver Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5facb022cedc..9cf4069895c1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -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) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 459539220770..024e5512d600 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 */ From 92164c5dd1ade33f4e90b72e407910de6694de49 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 21 Jun 2006 22:26:09 -0700 Subject: [PATCH 08/44] [PATCH] USB: OHCI hub code unaligned access I noticed this while debugging something unrelated on sparc64. Signed-off-by: David S. Miller Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-hub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 0bb972b58336..5b0a23fd798b 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 */ From 34f8e761724ecbfe46246f3faa4c7dbfc3555c26 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Wed, 21 Jun 2006 15:00:45 -0700 Subject: [PATCH 09/44] [PATCH] USB: fix usb-serial leaks, oopses on disconnect This fix addresses two issues: - Unattached port structures were not freed - My initial fix for crash when eventd runs a work in a freed port did not go far enough Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b59a0536ea5c..5be79cf06fa9 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -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); } From bd97c4f035b47c1a3ae5cc5ceccdda028b25e9d5 Mon Sep 17 00:00:00 2001 From: Pete Zaitcev Date: Wed, 21 Jun 2006 15:03:40 -0700 Subject: [PATCH 10/44] [PATCH] USB: fix visor leaks This patch fixes blatant leaks in visor driver and makes it report mode sensible things in ->write_room (this is only needed if your visor is a terminal though). It is made to fit into 80 columns with a temporary variable. Might even save a few instructions... Signed-off-by: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 95a2936e902e..cbc21465f4fb 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -435,13 +435,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 +770,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 +895,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) From 5b5daf77a6250f2b1983d092d8237cb169488774 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Mon, 19 Jun 2006 18:19:01 -0700 Subject: [PATCH 11/44] [PATCH] USB: Add some basic WUSB definitions This patch adds basic Wireless USB 1.0 definitions to usb_ch9.h that fit into the existing set of declarations. Boils down to two new recipients for requests (ports and remote pipes), rpipe reset and abort request codes and wire adapter and remote pipe descriptor types. Wire adapters are the USB <-> Wireless USB adaptors; remote pipes are used by those adapters to pipe the host <-> endpoint traffic. Signed-off-by: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- include/linux/usb_ch9.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index a2aacfc7af2f..c720d107ff29 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h @@ -51,6 +51,9 @@ #define USB_RECIP_INTERFACE 0x01 #define USB_RECIP_ENDPOINT 0x02 #define USB_RECIP_OTHER 0x03 +/* From Wireless USB 1.0 */ +#define USB_RECIP_PORT 0x04 +#define USB_RECIP_RPIPE 0x05 /* * Standard requests, for the bRequest field of a SETUP packet. @@ -73,7 +76,9 @@ #define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */ #define USB_REQ_GET_ENCRYPTION 0x0E +#define USB_REQ_RPIPE_ABORT 0x0E #define USB_REQ_SET_HANDSHAKE 0x0F +#define USB_REQ_RPIPE_RESET 0x0F #define USB_REQ_GET_HANDSHAKE 0x10 #define USB_REQ_SET_CONNECTION 0x11 #define USB_REQ_SET_SECURITY_DATA 0x12 @@ -159,6 +164,8 @@ struct usb_ctrlrequest { #define USB_DT_BOS 0x0f #define USB_DT_DEVICE_CAPABILITY 0x10 #define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 +#define USB_DT_WIRE_ADAPTER 0x21 +#define USB_DT_RPIPE 0x22 /* conventional codes for class-specific descriptors */ #define USB_DT_CS_DEVICE 0x21 From 3b92847425a98d26ad9d2b8682d3ce6020c90752 Mon Sep 17 00:00:00 2001 From: Matthew Meno Date: Wed, 21 Jun 2006 15:25:53 -0400 Subject: [PATCH 12/44] [PATCH] USB: Support for Susteen Datapilot Universal-2 cable in pl2303 The Susteen Datapilot cable (http://www.susteen.com/productdetail/71/producthl/Notempty) has an internal pl2303 to communicate with a set of dummy connector-ends that connect to a variety of cell phones. I've found that it works right out of the box by simply adding the product/vendor id to the pl2303 driver. Signed-off-by: Matt Meno Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 1 + drivers/usb/serial/pl2303.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 93d623a0d092..559330eb3126 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -80,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 cb2abad3a37e..d9c1e6e0b4b3 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -85,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 From 58a5b0a6346b71bf01f0d49cfcc91d3225a373aa Mon Sep 17 00:00:00 2001 From: Zoran Marceta Date: Thu, 22 Jun 2006 13:28:11 -0400 Subject: [PATCH 13/44] [PATCH] usbfs: use the correct signal number for disconnection usbfs stores the wrong signal number in the siginfo structure used for notifying user programs about device disconnect. This patch (as726) fixes it. From: Zoran Marceta Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index f48c3dbc367a..3182c2224ba2 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; From 9189bfc2df0fd87e0e537fe7ad4cf3b66a440fe4 Mon Sep 17 00:00:00 2001 From: Oliver Bock Date: Thu, 22 Jun 2006 19:04:47 +0200 Subject: [PATCH 14/44] [PATCH] USB: rename Cypress CY7C63xxx driver to proper name and fix up some tiny things This is a new driver for the Cypress CY7C63xxx mirco controller series. It currently supports the pre-programmed CYC63001A-PC by AK Modul-Bus GmbH. It's based on a kernel 2.4 driver (cyport) by Marcus Maul which I ported to kernel 2.6 using sysfs. I intend to support more controllers of this family (and more features) as soon as I get hold of the required IDs etc. Please see the source code's header for more information. Signed-off-by: Oliver Bock Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 +- drivers/usb/misc/Kconfig | 10 +- drivers/usb/misc/Makefile | 2 +- drivers/usb/misc/cy7c63.c | 244 -------------------------- drivers/usb/misc/cypress_cy7c63.c | 279 ++++++++++++++++++++++++++++++ 5 files changed, 286 insertions(+), 251 deletions(-) delete mode 100644 drivers/usb/misc/cy7c63.c create mode 100644 drivers/usb/misc/cypress_cy7c63.c diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index c7123bf71c58..4710eb02ed64 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/misc/Kconfig b/drivers/usb/misc/Kconfig index daa486dde8cf..88928a4be805 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 f25a97227297..2927260c5812 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 8a1c10b89b76..000000000000 --- 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 -#include -#include -#include - -#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 000000000000..e091d327bd9e --- /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 +#include +#include +#include + +#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"); From 3dd2ae81f70f191f5b6751d18fdfe61dbafda7e8 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 23 Jun 2006 09:14:17 +0200 Subject: [PATCH 15/44] [PATCH] USB: update for acm in quirks and debug this adds better debugging output & an update of the quirk list to the acm driver Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 49 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 3670d77e912c..ca90326f2f5c 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) }, From eecd11ed47c8c9bd8e7e3dff35baccae18dd0d84 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 19 Jun 2006 14:50:15 -0400 Subject: [PATCH 16/44] [PATCH] usb-storage: fix race between reset and disconnect My recent patch converting usb-storage to use usb_reset_composite_device() added a bug, a race between reset and disconnect. It was necessary to drop the private lock while executing a reset, and if a disconnect occurs at that time it will cause a crash. This patch (as722) fixes the problem by explicitly checking for an early termination after executing each command. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 1185acac4b21..04c3bec81201 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -373,8 +373,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); @@ -836,32 +840,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 */ From b40b7a905ce57608ca93c5032d5ab1f5508d2f11 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 19 Jun 2006 15:12:38 -0400 Subject: [PATCH 17/44] [PATCH] USB hub: don't return status > 0 from resume finish_device_resume() in the hub driver isn't careful always to return a negative code in all the error pathways. It also doesn't return 0 in all the success pathways. This patch (as724) fixes the behavior. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 875596e98e42..41531bba4321 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); From 0ddc0634714552af355a1fa11bad6051e6cb12ff Mon Sep 17 00:00:00 2001 From: Davide Perini Date: Mon, 19 Jun 2006 17:07:39 -0400 Subject: [PATCH 18/44] [PATCH] usb-storage: unusual_devs entry for Motorola RAZR V3x This patch (as725) adds an unusual_devs entry for the Motorola RAZR V3x. From: Davide Perini Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c7e84e653df9..15833fd910d1 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1227,6 +1227,15 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* patch submitted by Davide Perini + * and Renato Perini + */ +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 */ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, "MPIO", From d8840d60218ac80c74af3b35adbc4cee93c25f18 Mon Sep 17 00:00:00 2001 From: Ernis Date: Mon, 26 Jun 2006 16:02:43 -0400 Subject: [PATCH 19/44] [PATCH] USB: unusual_devs entry for Samsung MP3 player This patch (as730) contains an unusual_devs entry for a Samsung MP3 device. From: Ernis Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 15833fd910d1..c8800651da97 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -112,6 +112,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Submitted by Ernestas Vaiciukevicius */ +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 Christian Leber */ UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, "TrekStor", From 20307949469269ceea6262aaa306dcb55cf43b25 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 28 Jun 2006 11:20:41 -0400 Subject: [PATCH 20/44] [PATCH] usbcore: fixes for hub_port_resume This patch (as731) makes a couple of small fixes to the hub_port_resume routine: Don't return status >= 0 when an error occurs; Clear the port-change-suspend status indicator after resuming a device. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 41531bba4321..26c8cb5f3e67 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1882,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) From 883d989a7edf7a62e38e9150990b56209420e9e5 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sat, 24 Jun 2006 17:27:10 -0700 Subject: [PATCH 21/44] [PATCH] USB Storage: US_FL_MAX_SECTORS_64 flag This patch adds a US_FL_MAX_SECTORS_64 and removes the Genesys special-cases for this that were in scsiglue.c. It also adds the flag to other devices reported to need it. Signed-off-by: Phil Dibowitz Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/scsiglue.c | 12 +++++------- drivers/usb/storage/unusual_devs.h | 16 ++++++++++++++-- drivers/usb/storage/usb.h | 4 ---- include/linux/usb_usual.h | 2 ++ 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 5715291ba540..a4b7df9ff8c1 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/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index c8800651da97..b6a0eb8dc7e2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -715,18 +715,22 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, * They were originally reported by Alexander Oltu * and Peter Marks * respectively. + * + * US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz + * 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 * Taken from the Lycoris Kernel */ @@ -1203,6 +1207,14 @@ UNUSUAL_DEV( 0x0ea0, 0x6828, 0x0110, 0x0110, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Benjamin Schiller + * 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 */ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, "Sony Ericsson", diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 5284abe1b5eb..21f3ddbc9080 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 diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h index 608487a62c98..f38f43f20fae 100644 --- a/include/linux/usb_usual.h +++ b/include/linux/usb_usual.h @@ -43,6 +43,8 @@ /* Need delay after Command phase */ \ US_FLAG(NO_WP_DETECT, 0x00000200) \ /* Don't check for write-protect */ \ + US_FLAG(MAX_SECTORS_64, 0x00000400) \ + /* Sets max_sectors to 64 */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; From 5650b4dd141e823c2b1bc248cb9ad3e9ac88cf19 Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Sat, 24 Jun 2006 17:27:54 -0700 Subject: [PATCH 22/44] [PATCH] USB Storage: Uname in PR/SC Unneeded message This patch adds the kernel version to the usb-storage Protocol/SubClass unneeded message in order to help us troubleshoot such problems. Signed-off-by: Phil Dibowitz Signed-off-by: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 04c3bec81201..5ee19be52f65 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include @@ -528,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 " "\n", le16_to_cpu(ddesc->idVendor), @@ -536,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); } } From 00d6058ac93048b525b86fa48b413dcb87ac2728 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Jun 2006 11:44:22 +0100 Subject: [PATCH 23/44] [PATCH] USB serial visor: fix race in open/close The anti user-DoS mechanism in the USB serial 'visor' driver can fail in the following way: visor_open: priv->outstanding_urbs = 0 visor_write: ++priv->outstanding_urbs visor_close: visor_open: priv->outstanding_urbs = 0 visor_write_bulk_callback: --priv->outstanding_urbs So priv->outstanding_urbs ends up as (unsigned long)(-1). Not good! I haven't seen this happen with the visor driver as I don't have the hardware, but I have seen it while testing a patch to implement the same functionality in the ftdi_sio driver (patch not yet submitted). The fix is pretty simple: don't reinitialize outstanding_urbs in visor_open. (Again, I haven't tested the fix in visor, but I have tested it in ftdi_sio.) Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index cbc21465f4fb..32c3c6288985 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -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); From 224654004ca688af67cec44d9300e8c3f647577c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 26 Jun 2006 12:59:17 +0100 Subject: [PATCH 24/44] [PATCH] USB serial ftdi_sio: Prevent userspace DoS This patch limits the amount of outstanding 'write' data that can be queued up for the ftdi_sio driver, to prevent userspace DoS attacks (or simple accidents) that use up all the system memory by writing lots of data to the serial port. The original patch was by Guillaume Autran, who in turn based it on the same mechanism implemented in the 'visor' driver. I (Ian Abbott) re-targeted the patch to the latest sources, fixed a couple of errors, renamed his new structure members, and updated the implementations of the 'write_room' and 'chars_in_buffer' methods to take account of the number of outstanding 'write' bytes. It seems to work fine, though at low baud rates it is still possible to queue up an amount of data that takes an age to shift (a job for another day!). Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 103 +++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 13 deletions(-) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9cf4069895c1..ff06c01a555b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -550,11 +550,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 */ @@ -628,6 +634,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 @@ -1158,6 +1167,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 */ @@ -1272,6 +1282,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; @@ -1374,6 +1391,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); @@ -1381,6 +1399,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); @@ -1447,6 +1472,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 @@ -1462,7 +1493,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); @@ -1474,34 +1509,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 */ @@ -1511,6 +1579,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__, @@ -1545,6 +1615,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 */ From c1b45f247a2901de3982f33196d5caf8ca5b9799 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Sun, 25 Jun 2006 18:45:29 -0400 Subject: [PATCH 25/44] [PATCH] USB: Kill compiler warning in quirk_usb_handoff_ohci Move variables only used on !__hppa__ into that #ifndef section. This cleans up a compiler warning on parisc. Problem pointed out by Joel Soete. Signed-off-by: Kyle McMartin Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/pci-quirks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dff60568b4a1..20861650905e 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 /* From 053be305d3a5ae0152991f25c6579127fb48710c Mon Sep 17 00:00:00 2001 From: Eric Sesterhenn Date: Tue, 27 Jun 2006 00:57:42 +0200 Subject: [PATCH 26/44] [PATCH] USB: fix pointer dereference in drivers/usb/misc/usblcd coverity spotted (id #185) that we still use urb, if the allocation fails in the error path. This patch fixes this by returning directly. Signed-off-by: Eric Sesterhenn Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/usblcd.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index c82c402285a0..e095772dd8e9 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) { From 69de51fdda3fd984541978313b66e4f2c44cc23e Mon Sep 17 00:00:00 2001 From: Kevin Lloyd Date: Fri, 30 Jun 2006 11:17:55 -0700 Subject: [PATCH 27/44] [PATCH] USB: add driver for non-composite Sierra Wireless devices This patch creates a new driver, sierra.c, that supports the new non-composite Sierra Wireless WWAN devices. The older Sierra Wireless and Airprime devices are supported in airprime.c. Signed-off-by: Kevin Lloyd Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/Kconfig | 11 ++++++ drivers/usb/serial/Makefile | 1 + drivers/usb/serial/sierra.c | 75 +++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 drivers/usb/serial/sierra.c diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 8bd44fda5eaf..ac33bd47cfce 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 5a0960fc9d3e..35d4acc7f1d3 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/sierra.c b/drivers/usb/serial/sierra.c new file mode 100644 index 000000000000..8da056ae64dd --- /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 + * Original Copyright (C) 2005-2006 Greg Kroah-Hartman + * + * 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 +#include +#include +#include +#include +#include "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"); From b972b68c396cfa9f8af7e0b314e22705251bc218 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 30 Jun 2006 02:34:42 -0700 Subject: [PATCH 28/44] [PATCH] USB: ehci: fix bogus alteration of a local variable In a rare and all-but-unused path, the EHCI driver could reuse a variable in a way that'd make trouble. Specifically, if the first root hub port gets an overcurrent event (rare) during a remote wakeup scenario (all but unused in today's Linux, except for folk working with suspend-to-RAM and similar sleep states), that would look like a fatal error which would shut down the controller. Fix by not reusing that variable. Spotted by Per Hallsmark Fixes http://bugzilla.kernel.org/show_bug.cgi?id=6661 Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index cee6f538de0a..85b0b4ad4c16 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; From b512504e5671f83638be0ddb085c4b1832f623d3 Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Fri, 30 Jun 2006 02:34:44 -0700 Subject: [PATCH 29/44] [PATCH] USB: ipaq.c bugfixes This patch fixes several problems in the ipaq.c driver with connecting and disconnecting pocketpc devices: * The read urb stayed active if the connect failed, causing nullpointer dereferences later on. * If a write failed, the driver continued as if nothing happened. Now it handles that case the same way as other usb serial devices (fix by Luiz Fernando N. Capitulino ) Signed-off-by: Frank Gevaerts Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index dbcfe172a5cc..c021905f0637 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -651,11 +651,6 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) 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,6 +665,11 @@ 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; } } @@ -854,6 +854,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); From b33488eb5c27c13c3e88cdf29d344ccdcb0859f2 Mon Sep 17 00:00:00 2001 From: Frank Gevaerts Date: Fri, 30 Jun 2006 02:34:45 -0700 Subject: [PATCH 30/44] [PATCH] USB: ipaq.c timing parameters Adds configurable waiting periods to the ipaq connection code. These are not needed when the pocketpc device is running normally when plugged in, but they need extra delays if they are physically connected while rebooting. There are two parameters : * initial_wait : this is the delay before the driver attemts to start the connection. This is needed because the pocktpc device takes much longer to boot if the driver starts sending control packets too soon. * connect_retries : this is the number of times the control urb is retried before finally giving up. The patch also adds a 1 second delay between retries. I'm not sure if the cases where this patch is useful are general enough to include this in the kernel. Signed-off-by: Frank Gevaerts Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index c021905f0637..65beea6e54d1 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -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,6 +648,7 @@ 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), @@ -672,6 +675,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) } return 0; } + msleep(1000); } err("%s - failed doing control urb, error %d", __FUNCTION__, result); goto error; @@ -967,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)"); From 028d2a39d1cbcf17242a915f0852acdd36660822 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 30 Jun 2006 02:34:47 -0700 Subject: [PATCH 31/44] [PATCH] USB: remove empty destructor from drivers/usb/mon/mon_text.c Remove destructor and call kmem_cache_create with NULL for the destructor. Acked-by: Pekka Enberg Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Cc: Pete Zaitcev Signed-off-by: Greg Kroah-Hartman --- drivers/usb/mon/mon_text.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index e02c1a30c4cd..f961a770cee2 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) -{ - ; -} From 49e523b90741b936c874c376b5d140add5c0084d Mon Sep 17 00:00:00 2001 From: Michal Piotrowski Date: Mon, 3 Jul 2006 14:20:39 +0200 Subject: [PATCH 32/44] [PATCH] USB: remove devfs information from Kconfig Devfs is gone. We can remove that information. Signed-off-by: Michal Piotrowski Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index a08787e253aa..6e3b5358a760 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 . - 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 From b2f1b0d4649a6597c7320bf359e71014653c630d Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Sun, 2 Jul 2006 15:07:10 +1200 Subject: [PATCH 33/44] [PATCH] USB: ipw.c driver fix The below patch fixes the ipw module in kernel 2.6.17 for me; without this change it simply does not work at all (all but the first writes are refused because write_urb_busy is always 1). This problem was there in 2.6.15 as well, but at that point I used the (updated) ipw.c, version 0.4, from http://www.neology.co.za/products/opensource/ipwireless/ which no longer compiles with 2.6.17. It can be made to after a few changes but obviously it's easier if the built-in ipw driver works instead of having to download one from the neology site. From: Bart Oldeman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipw.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index a4a0bfeaab00..4d5275e4dead 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -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); From b857c651e7e369c12098007772549f817b3bf961 Mon Sep 17 00:00:00 2001 From: Navaho Gunleg Date: Fri, 30 Jun 2006 09:44:03 +0200 Subject: [PATCH 34/44] [PATCH] USB: add support for WiseGroup., Ltd SmartJoy Dual PLUS Adapter This patch is to get the WiseGroup.,Ltd SmartJoy Dual Plus PS2-to-USB Adapter [0x6677:0x8802] correctly detected. It sets the NOGET and MULTI_INPUT quirks to make 2 joystick nodes appear in stead of only one. (As of yet, only confirmed working by myself.) Signed-off-by: Navaho Gunleg Signed-off-by: Greg Kroah-Hartman --- drivers/usb/input/hid-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index b9fb9687f926..8ea9c915fbf9 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 }, From e37de9e0d6591706a76cff63582cbc721c317333 Mon Sep 17 00:00:00 2001 From: Matthias Urlichs Date: Thu, 6 Jul 2006 13:12:53 +0200 Subject: [PATCH 35/44] [PATCH] USB: Option driver: new product ID Yet another "same name, somewhat different hardware" product. Signed-Off-By: Matthias Urlichs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 78ad4b3126a6..96e641941e50 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 @@ -53,7 +54,7 @@ device features. */ -#define DRIVER_VERSION "v0.7.0" +#define DRIVER_VERSION "v0.7.1" #define DRIVER_AUTHOR "Matthias Urlichs " #define DRIVER_DESC "USB Driver for GSM modems" @@ -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) }, From b6c2799dec0c9f6f6de35c2161b246c910108204 Mon Sep 17 00:00:00 2001 From: Dan Streetman Date: Wed, 5 Jul 2006 19:17:27 -0400 Subject: [PATCH 36/44] [PATCH] USB: add ZyXEL vendor/product ID to rtl8150 driver I just got a "ZyXEL Prestige USB Adapter" that is actually RTL8150 adapter. Here is the relevant /proc/bus/usb/devices output (after adding the vendor/product IDs to the driver): T: Bus=01 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=119 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1 P: Vendor=0586 ProdID=401a Rev= 1.00 S: Manufacturer=ZyXEL S: Product=Prestige USB Adapter S: SerialNumber=1027 C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=120mA I: If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=ff Driver=rtl8150 E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=1ms This patch adds the ZyXEL vendor ID to the rtl8150.c driver. The device has absolutely no identifying marks on the outside for model type, just a serial number, and I can't find anything on ZyXEL's website, so I called the product ID PRODUCT_ID_PRESTIGE to match the product string. Signed-off-by: Dan Streetman Acked-by: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/net/rtl8150.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 718f8e2b552b..e5e6e4f3ef87 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)}, {} }; From 9a01355e1779356a69d80d917aef009eda44284a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 7 Jul 2006 13:45:13 -0400 Subject: [PATCH 37/44] [PATCH] USB: unusual_devs entry for Nokia N91 This patch (as745) adds an unusual_devs entry for the Nokia N91, just like the entry for the N80 added a couple of weeks ago. Apparently Nokia isn't using very good firmware these days... Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b6a0eb8dc7e2..91ad1a4123e2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -139,6 +139,14 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Sumedha Swamy and + * Einar Th. Einarsson */ +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 and * Rene C. Castberg */ UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100, From 57b01b1e393b8b874421fb77d4f078b8ce725e63 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 10 Jul 2006 11:51:12 -0400 Subject: [PATCH 38/44] [PATCH] USB: unusual_devs entry for Nokia E61 This patch (as748) adds an unusual_devs entry for the Nokia E61 mobile phone. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 91ad1a4123e2..4150b5825559 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -155,6 +155,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 */ +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 from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", From 7e3bd120e52971d5e255ca800f7de6bf83d8f2d1 Mon Sep 17 00:00:00 2001 From: Lars Jacob Date: Mon, 10 Jul 2006 11:53:58 -0400 Subject: [PATCH 39/44] [PATCH] USB: unusual_devs entry for Sony DSC-H5 This patch (as749) extends the unusual_devs entry for the Sony DSC-T1 and T5 to cover the H5 as well. From: Lars Jacob Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 4150b5825559..b7f520e054ec 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -495,10 +495,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 + * 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 ), From e1979fef347f534c3797eaa3e10825235ed72766 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Tue, 11 Jul 2006 11:36:43 +0200 Subject: [PATCH 40/44] [PATCH] USB: Add one VID/PID to ftdi_sio This patch adds the Testo USB interface to the list of devices recognized by the ftdi_sio module. This device is based on a FT232BL chip, and is used as an interface to get data from digital sensors (thermometer, etc). See http://www.testo.com/ Signed-off-by: Colin Leroy Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + drivers/usb/serial/ftdi_sio.h | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ff06c01a555b..0b9baaf0da90 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -502,6 +502,7 @@ static struct usb_device_id id_table_combined [] = { { 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 */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 024e5512d600..04ef90fcb876 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -450,6 +450,13 @@ */ #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 */ From 5501a48c15d4a3b81bee1358eb195e26c798d78f Mon Sep 17 00:00:00 2001 From: Phil Dibowitz Date: Tue, 4 Jul 2006 12:46:43 -0700 Subject: [PATCH 41/44] [PATCH] USB: another unusual device Please add the attached device to unusual_devs.h. Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b7f520e054ec..a5ca449f6e64 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -119,6 +119,12 @@ UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Orgad Shaneh */ +UNUSUAL_DEV( 0x0419, 0xaace, 0x0100, 0x0100, + "Samsung", "MP3 Player", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* Reported by Christian Leber */ UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100, "TrekStor", From a353678d3136306c1d00f0d2319de1dac8a6b1db Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 6 Jul 2006 15:48:53 -0700 Subject: [PATCH 42/44] [PATCH] USB: gadget section fixups Recent section changes broke gadget builds on some platforms. This patch is the best fix that's available until better section markings exist: - There's a lot of cleanup code that gets used in both init and exit paths; stop marking it as "__exit". (Best fix for this would be an "__init_or_exit" section marking, putting the cleanup in __init when __exit sections get discarded else in __exit.) - Stop marking the use-once probe routines as "__init" since references to those routines are not allowed from driver structures. They're now marked "__devinit", which in practice is a net lose. (Best fix for this is likely to separate such use-once probe routines from the driver structure ... but in general, all busses that aren't hotpluggable will be forced to waste memory for all probe-only code.) In general these broken section rules waste an average of two to four kBytes per driver of code bloat ... because none of the relevant code can ever be reused after module initialization. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/epautoconf.c | 16 ++++++++-------- drivers/usb/gadget/ether.c | 8 ++++---- drivers/usb/gadget/file_storage.c | 2 +- drivers/usb/gadget/rndis.c | 2 +- drivers/usb/gadget/rndis.h | 2 +- drivers/usb/gadget/serial.c | 2 +- drivers/usb/gadget/zero.c | 2 +- include/linux/usb_gadget.h | 4 ++-- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index f7c6d758e1b0..53d584589c26 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 8320fcef0425..4fe1bec1c255 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 b1a9cf06f3e6..8d7f1e84cd7b 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 354670d12308..408c3380d602 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 2956608be751..4c3c7259f019 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 30d7664d449d..e762aa19ab0a 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 3a08a7ab4ce0..b7018ee487ea 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/include/linux/usb_gadget.h b/include/linux/usb_gadget.h index 1d78870ed8af..e17186dbcdca 100644 --- a/include/linux/usb_gadget.h +++ b/include/linux/usb_gadget.h @@ -872,9 +872,9 @@ int usb_gadget_config_buf(const struct usb_config_descriptor *config, /* utility wrapping a simple endpoint selection policy */ extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, - struct usb_endpoint_descriptor *) __init; + struct usb_endpoint_descriptor *) __devinit; -extern void usb_ep_autoconfig_reset (struct usb_gadget *) __init; +extern void usb_ep_autoconfig_reset (struct usb_gadget *) __devinit; #endif /* __KERNEL__ */ From 166ffccfd4556ac6a777982d193ae145bb0a21e0 Mon Sep 17 00:00:00 2001 From: "Luiz Fernando N. Capitulino" Date: Tue, 11 Jul 2006 14:19:25 -0300 Subject: [PATCH 43/44] [PATCH] USB: Anydata: Fixes wrong URB callback. Anydata is using usb_serial_generic_write_bulk_callback() for its read URB, but it should use usb_serial_generic_read_bulk_callback() instead (it's a read URB, isn't it?). Reported by Jon K Hellan . Signed-off-by: Luiz Fernando N. Capitulino Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/anydata.c | 2 +- drivers/usb/serial/generic.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/anydata.c b/drivers/usb/serial/anydata.c index 343f6f228220..dadf2838f942 100644 --- a/drivers/usb/serial/anydata.c +++ b/drivers/usb/serial/anydata.c @@ -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/generic.c b/drivers/usb/serial/generic.c index 945b8bb38c92..99872e13ba2d 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -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) { From a969888ce91673c7f4b86520d851a6f0d5a5fa7d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jul 2006 21:22:58 -0700 Subject: [PATCH 44/44] [PATCH] USB: move usb-serial.h to include/linux/usb/ USB serial outside of the kernel tree can not build properly due to usb-serial.h being buried down in the source tree. This patch moves the location of the file to include/linux/usb and fixes up all of the usb serial drivers to handle the move properly. Cc: Sergei Organov Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 2 +- drivers/usb/serial/anydata.c | 2 +- drivers/usb/serial/ark3116.c | 2 +- drivers/usb/serial/belkin_sa.c | 2 +- drivers/usb/serial/bus.c | 2 +- drivers/usb/serial/console.c | 3 +-- drivers/usb/serial/cp2101.c | 2 +- drivers/usb/serial/cyberjack.c | 2 +- drivers/usb/serial/cypress_m8.c | 2 +- drivers/usb/serial/digi_acceleport.c | 2 +- drivers/usb/serial/empeg.c | 2 +- drivers/usb/serial/ezusb.c | 2 +- drivers/usb/serial/ftdi_sio.c | 2 +- drivers/usb/serial/funsoft.c | 2 +- drivers/usb/serial/garmin_gps.c | 3 +-- drivers/usb/serial/generic.c | 2 +- drivers/usb/serial/hp4x.c | 2 +- drivers/usb/serial/io_edgeport.c | 2 +- drivers/usb/serial/io_ti.c | 2 +- drivers/usb/serial/ipaq.c | 2 +- drivers/usb/serial/ipw.c | 2 +- drivers/usb/serial/ir-usb.c | 2 +- drivers/usb/serial/keyspan.c | 2 +- drivers/usb/serial/keyspan_pda.c | 3 +-- drivers/usb/serial/kl5kusb105.c | 2 +- drivers/usb/serial/kobil_sct.c | 2 +- drivers/usb/serial/mct_u232.c | 2 +- drivers/usb/serial/navman.c | 2 +- drivers/usb/serial/omninet.c | 2 +- drivers/usb/serial/option.c | 2 +- drivers/usb/serial/pl2303.c | 2 +- drivers/usb/serial/safe_serial.c | 2 +- drivers/usb/serial/sierra.c | 2 +- drivers/usb/serial/ti_usb_3410_5052.c | 2 +- drivers/usb/serial/usb-serial.c | 2 +- drivers/usb/serial/visor.c | 2 +- drivers/usb/serial/whiteheat.c | 2 +- .../usb/serial/usb-serial.h => include/linux/usb/serial.h | 6 +++--- 38 files changed, 40 insertions(+), 43 deletions(-) rename drivers/usb/serial/usb-serial.h => include/linux/usb/serial.h (99%) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 94b9ba0ff875..62082532a8b3 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -13,7 +13,7 @@ #include #include #include -#include "usb-serial.h" +#include 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 dadf2838f942..01843ef8c11e 100644 --- a/drivers/usb/serial/anydata.c +++ b/drivers/usb/serial/anydata.c @@ -13,7 +13,7 @@ #include #include #include -#include "usb-serial.h" +#include static struct usb_device_id id_table [] = { { USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */ diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 8dec796222a0..970d9ef0a7a5 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -21,7 +21,7 @@ #include #include #include -#include "usb-serial.h" +#include static int debug; diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 3faa7aa0111a..70ece9e01ce4 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -74,7 +74,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "belkin_sa.h" static int debug; diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index f2d993b70c18..6542f220468f 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c @@ -13,7 +13,7 @@ #include #include #include -#include "usb-serial.h" +#include 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 3d456b32c316..3a9073dbfe6a 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -17,11 +17,10 @@ #include #include #include +#include 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 df0a4f98b4ae..486c7411b9a7 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -26,7 +26,7 @@ #include #include #include -#include "usb-serial.h" +#include /* * Version Information diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 49b51ab0d4cb..6286aba86fae 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -39,7 +39,7 @@ #include #include #include -#include "usb-serial.h" +#include #define CYBERJACK_LOCAL_BUF_SIZE 32 diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 4ff2dfb299bd..ee70fddcab60 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -59,11 +59,11 @@ #include #include #include +#include #include #include #include -#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 6953d3ef5738..9b225183fc7a 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -246,7 +246,7 @@ #include #include #include -#include "usb-serial.h" +#include /* Defines */ diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 1e2b31eeb497..daafe405d86d 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c @@ -62,7 +62,7 @@ #include #include #include -#include "usb-serial.h" +#include static int debug; diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c index debc3b0f9662..5169c2d154ab 100644 --- a/drivers/usb/serial/ezusb.c +++ b/drivers/usb/serial/ezusb.c @@ -15,7 +15,7 @@ #include #include #include -#include "usb-serial.h" +#include /* 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 0b9baaf0da90..b458aedc5fb6 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -257,7 +257,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "ftdi_sio.h" /* diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 803721b97e2e..77b977206a8c 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c @@ -13,7 +13,7 @@ #include #include #include -#include "usb-serial.h" +#include 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 1f5d1620baa1..727852634be9 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -35,6 +35,7 @@ #include #include #include +#include /* 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 99872e13ba2d..172713556393 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -17,8 +17,8 @@ #include #include #include +#include #include -#include "usb-serial.h" static int debug; diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index 7e06358b0310..ebcac701b069 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c @@ -17,7 +17,7 @@ #include #include #include -#include "usb-serial.h" +#include /* * Version Information diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index bd2c05dac2a9..c49976c3ad52 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -44,7 +44,7 @@ #include #include #include -#include "usb-serial.h" +#include #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 723a12ae87b5..17c5b1d2311a 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -39,8 +39,8 @@ #include #include #include +#include -#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 65beea6e54d1..59c5d999009a 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -55,7 +55,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "ipaq.h" #define KP_RETRIES 100 diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 4d5275e4dead..87306cb6f9f5 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -46,8 +46,8 @@ #include #include #include +#include #include -#include "usb-serial.h" /* * Version Information diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 2cf1fed3de43..1738b0b6a376 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -57,7 +57,7 @@ #include #include #include -#include "usb-serial.h" +#include /* * Version Information diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index d7c58f1bc960..015ad6cc1bbb 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -107,7 +107,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "keyspan.h" static int debug; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index 03ab3c0f3cce..49b8dc039d1f 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -78,6 +78,7 @@ #include #include #include +#include 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 b45ff3e7ab40..2a2f3e2da055 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -55,7 +55,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "kl5kusb105.h" static int debug; diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 457733374772..d50dce034958 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -46,8 +46,8 @@ #include #include #include +#include #include -#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 ca05d3275f3e..f4d4305c2c02 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -75,7 +75,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "mct_u232.h" /* diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 7f544081032e..ac3f8b5d2c49 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c @@ -14,7 +14,7 @@ #include #include #include -#include "usb-serial.h" +#include static int debug; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index cfb711a21a45..e49f40913c27 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -46,7 +46,7 @@ #include #include #include -#include "usb-serial.h" +#include static int debug; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 96e641941e50..f0530c1d7b7a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -65,7 +65,7 @@ #include #include #include -#include "usb-serial.h" +#include /* Function prototypes */ static int option_open(struct usb_serial_port *port, struct file *filp); diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 559330eb3126..259db31b65c1 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -27,7 +27,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "pl2303.h" /* diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 897d8447252b..789771ecdb11 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -71,7 +71,7 @@ #include #include #include -#include "usb-serial.h" +#include #ifndef CONFIG_USB_SAFE_PADDED diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 8da056ae64dd..d29638daa987 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -14,7 +14,7 @@ #include #include #include -#include "usb-serial.h" +#include static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a9afff31a921..ac9b8ee52d44 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -83,8 +83,8 @@ #include #include #include +#include -#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 5be79cf06fa9..12c1694d322e 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -31,7 +31,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "pl2303.h" /* diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 32c3c6288985..88949f7884ca 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -25,7 +25,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "visor.h" /* diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 540438c3f381..6e6c7934be32 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -79,7 +79,7 @@ #include #include #include -#include "usb-serial.h" +#include #include "whiteheat_fw.h" /* firmware for the ConnectTech WhiteHEAT device */ #include "whiteheat.h" /* WhiteHEAT specific commands */ diff --git a/drivers/usb/serial/usb-serial.h b/include/linux/usb/serial.h similarity index 99% rename from drivers/usb/serial/usb-serial.h rename to include/linux/usb/serial.h index 0f2802a60194..91c983eef899 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/include/linux/usb/serial.h @@ -1,12 +1,12 @@ /* - * USB Serial Converter driver + * USB Serial Converter stuff * * 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. + * the Free Software Foundation; version 2 of the License. * */ @@ -171,7 +171,7 @@ static inline void usb_set_serial_data (struct usb_serial *serial, void *data) * 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 + * 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