From 11e1abb453690a907ea26c07043987165a4f277f Mon Sep 17 00:00:00 2001 From: David Ludlow Date: Mon, 25 Feb 2008 17:30:52 -0500 Subject: [PATCH 01/12] usb: Add support for the mos7820/7840-based B&B USB/RS485 converter to mos7840.c Add support for the mos7820/7840-based B&B USOPTL4_2/USOPTL4_4 USB/RS485 converter to mos7840.c Signed-off-by: Dave Ludlow Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/mos7840.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 869ecd374cb4..aeeb9cb20999 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -110,11 +110,20 @@ /* vendor id and device id defines */ +/* The native mos7840/7820 component */ #define USB_VENDOR_ID_MOSCHIP 0x9710 #define MOSCHIP_DEVICE_ID_7840 0x7840 #define MOSCHIP_DEVICE_ID_7820 0x7820 +/* The native component can have its vendor/device id's overridden + * in vendor-specific implementations. Such devices can be handled + * by making a change here, in moschip_port_id_table, and in + * moschip_id_table_combined + */ +#define USB_VENDOR_ID_BANDB 0x0856 +#define BANDB_DEVICE_ID_USOPTL4_4 0xAC44 +#define BANDB_DEVICE_ID_USOPTL4_2 0xAC42 -/* Interrupt Rotinue Defines */ +/* Interrupt Routine Defines */ #define SERIAL_IIR_RLS 0x06 #define SERIAL_IIR_MS 0x00 @@ -159,12 +168,16 @@ static struct usb_device_id moschip_port_id_table[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {} /* terminating entry */ }; static __devinitdata struct usb_device_id moschip_id_table_combined[] = { {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7840)}, {USB_DEVICE(USB_VENDOR_ID_MOSCHIP, MOSCHIP_DEVICE_ID_7820)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_4)}, + {USB_DEVICE(USB_VENDOR_ID_BANDB, BANDB_DEVICE_ID_USOPTL4_2)}, {} /* terminating entry */ }; From c2c8d1fdadda4abc90efdb7176f44cb903634511 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 25 Feb 2008 11:43:32 -0500 Subject: [PATCH 02/12] USB: update Kconfig entry for USB_SUSPEND This patch (as1039) updates the Kconfig entry for USB_SUSPEND. The out-of-date reference to "power/state" is fixed, autosuspend is mentioned, and the dependency on EXPERIMENTAL is removed. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/Kconfig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 5c33cdb9cac7..a2b0aa48b8ea 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig @@ -87,12 +87,13 @@ config USB_DYNAMIC_MINORS If you are unsure about this, say N here. config USB_SUSPEND - bool "USB selective suspend/resume and wakeup (EXPERIMENTAL)" - depends on USB && PM && EXPERIMENTAL + bool "USB selective suspend/resume and wakeup" + depends on USB && PM help If you say Y here, you can use driver calls or the sysfs - "power/state" file to suspend or resume individual USB - peripherals. + "power/level" file to suspend or resume individual USB + peripherals and to enable or disable autosuspend (see + Documentation/usb/power-management.txt for more details). Also, USB "remote wakeup" signaling is supported, whereby some USB devices (like keyboards and network adapters) can wake up From d6d914f52b15d5a8e81ad481e02d9ab30d412a29 Mon Sep 17 00:00:00 2001 From: Lei Ming Date: Mon, 25 Feb 2008 18:07:28 +0800 Subject: [PATCH 03/12] USB: fix comment of struct usb_interface update the comment for the removed "driver" field and being out-of-order of @cur_altsetting and @num_altsetting. Signed-off-by: Lei Ming Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 5bd3ae8aaaf4..583e0481dfa0 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -94,10 +94,9 @@ enum usb_interface_condition { * @altsetting: array of interface structures, one for each alternate * setting that may be selected. Each one includes a set of * endpoint configurations. They will be in no particular order. - * @num_altsetting: number of altsettings defined. * @cur_altsetting: the current altsetting. + * @num_altsetting: number of altsettings defined. * @intf_assoc: interface association descriptor - * @driver: the USB driver that is bound to this interface. * @minor: the minor number assigned to this interface, if this * interface is bound to a driver that uses the USB major number. * If this interface does not use the USB major, this field should From 14f3546f32d69adaa303b72e5a999e85abe83f9a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 27 Feb 2008 15:43:47 -0500 Subject: [PATCH 04/12] USB: spruce up the device blacklist This patch (as1040) fixes up the blacklist of USB device quirks. A couple of lines are broken to comply with the 80-column rule, and entries are sorted into the proper numerical order. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f90ab5e94c58..d9d1eb19f2a1 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -28,35 +28,38 @@ * devices is broken... */ static const struct usb_device_id usb_quirk_list[] = { - /* Action Semiconductor flash disk */ - { USB_DEVICE(0x10d6, 0x2200), .driver_info = USB_QUIRK_STRING_FETCH_255}, - /* CBM - Flash disk */ { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, + /* HP 5300/5370C scanner */ - { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + { USB_DEVICE(0x03f0, 0x0701), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Philips PSC805 audio device */ + { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Roland SC-8820 */ { USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME }, /* Edirol SD-20 */ { USB_DEVICE(0x0582, 0x0027), .driver_info = USB_QUIRK_RESET_RESUME }, - /* INTEL VALUE SSD */ - { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, - /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Philips PSC805 audio device */ - { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Action Semiconductor flash disk */ + { USB_DEVICE(0x10d6, 0x2200), .driver_info = + USB_QUIRK_STRING_FETCH_255 }, /* SKYMEDI USB_DRIVE */ { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, + /* INTEL VALUE SSD */ + { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, + { } /* terminating entry must be last */ }; From b5f7a0ec11694e60c99d682549dfaf8a03d7ad97 Mon Sep 17 00:00:00 2001 From: Misha Zhilin Date: Wed, 27 Feb 2008 18:05:24 -0800 Subject: [PATCH 05/12] USB: ehci: handle large bulk URBs correctly (again) USB: ehci: Fixes completion for multi-qtd URB the short read case When use of urb->status in the EHCI driver was reworked last August (commit 14c04c0f88f228fee1f412be91d6edcb935c78aa), a bug was inserted in the handling of early completion for bulk transactions that need more than one qTD (e.g. more than 20KB in one URB). This patch resolves that problem by ensuring that the early completion status is preserved until the URB is handed back to its submitter, instead of resetting it after each qTD. Signed-off-by: Misha Zhilin Signed-off-by: David Brownell Acked-by: Alan Stern Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 776a97f33914..2e49de820b14 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -319,10 +319,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) if (likely (last->urb != urb)) { ehci_urb_done(ehci, last->urb, last_status); count++; + last_status = -EINPROGRESS; } ehci_qtd_free (ehci, last); last = NULL; - last_status = -EINPROGRESS; } /* ignore urbs submitted during completions we reported */ From 0ed930bffab2ec98ee8f43f579a30755c13dd5ea Mon Sep 17 00:00:00 2001 From: Anti Sullin Date: Mon, 3 Mar 2008 15:39:54 +0200 Subject: [PATCH 06/12] USB: isp116x: fix enumeration on boot This patch removes the buffering of the status register. USB core behavior has changed a bit and this buffering was not refreshed at the right time. The core got buffered old value of HCRHPORT and it did not detect any devices on boot. Signed-off-by: Anti Sullin Acked by: Olav Kongas Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/isp116x-hcd.c | 15 ++++++--------- drivers/usb/host/isp116x.h | 1 - 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 0130fd8571e4..d7071c855758 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -911,8 +911,7 @@ static int isp116x_hub_status_data(struct usb_hcd *hcd, char *buf) buf[0] = 0; for (i = 0; i < ports; i++) { - u32 status = isp116x->rhport[i] = - isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); + u32 status = isp116x_read_reg32(isp116x, i ? HCRHPORT2 : HCRHPORT1); if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC)) { @@ -1031,7 +1030,9 @@ static int isp116x_hub_control(struct usb_hcd *hcd, DBG("GetPortStatus\n"); if (!wIndex || wIndex > ports) goto error; - tmp = isp116x->rhport[--wIndex]; + spin_lock_irqsave(&isp116x->lock, flags); + tmp = isp116x_read_reg32(isp116x, (--wIndex) ? HCRHPORT2 : HCRHPORT1); + spin_unlock_irqrestore(&isp116x->lock, flags); *(__le32 *) buf = cpu_to_le32(tmp); DBG("GetPortStatus: port[%d] %08x\n", wIndex + 1, tmp); break; @@ -1080,8 +1081,6 @@ static int isp116x_hub_control(struct usb_hcd *hcd, spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, tmp); - isp116x->rhport[wIndex] = - isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); spin_unlock_irqrestore(&isp116x->lock, flags); break; case SetPortFeature: @@ -1095,24 +1094,22 @@ static int isp116x_hub_control(struct usb_hcd *hcd, spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, RH_PS_PSS); + spin_unlock_irqrestore(&isp116x->lock, flags); break; case USB_PORT_FEAT_POWER: DBG("USB_PORT_FEAT_POWER\n"); spin_lock_irqsave(&isp116x->lock, flags); isp116x_write_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1, RH_PS_PPS); + spin_unlock_irqrestore(&isp116x->lock, flags); break; case USB_PORT_FEAT_RESET: DBG("USB_PORT_FEAT_RESET\n"); root_port_reset(isp116x, wIndex); - spin_lock_irqsave(&isp116x->lock, flags); break; default: goto error; } - isp116x->rhport[wIndex] = - isp116x_read_reg32(isp116x, wIndex ? HCRHPORT2 : HCRHPORT1); - spin_unlock_irqrestore(&isp116x->lock, flags); break; default: diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index b91e2edd9c5c..595b90a99848 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h @@ -270,7 +270,6 @@ struct isp116x { u32 rhdesca; u32 rhdescb; u32 rhstatus; - u32 rhport[2]; /* async schedule: control, bulk */ struct list_head async; From 6d512a80c26d87f8599057c86dc920fbfe0aa3aa Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 22 Feb 2008 17:00:06 -0500 Subject: [PATCH 07/12] usb-storage: update earlier scatter-gather bug fix This patch (as1037) makes a small update to the earlier as1035 patch. The minimum-length computation shouldn't be done in usb_stor_access_xfer_buf(), since that routine can be called multiple times for a single transfer. It should be done in usb_stor_set_xfer_buf() instead, which gets called only once. The way it is now isn't really _wrong_, but it isn't really _right_ either. Moving the statement will be an improvement. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 958f5b17847c..b9b8ede61fb3 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -170,7 +170,6 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, if (!sg) sg = scsi_sglist(srb); - buflen = min(buflen, scsi_bufflen(srb)); /* This loop handles a single s-g list entry, which may * include multiple pages. Find the initial page structure @@ -232,6 +231,7 @@ void usb_stor_set_xfer_buf(unsigned char *buffer, unsigned int offset = 0; struct scatterlist *sg = NULL; + buflen = min(buflen, scsi_bufflen(srb)); buflen = usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset, TO_XFER_BUF); if (buflen < scsi_bufflen(srb)) From 85fb62a001278270f9fffbdc3508ef23d5f3693d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Koz=C3=A1k?= Date: Tue, 4 Mar 2008 18:54:53 +0100 Subject: [PATCH 08/12] USB: Add support for AXESSTEL MV110H CDMA modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add entry for Axesstel MV110H CDMA modem (ID: 1726:1000) to option driver Signed-off-by: Daniel Kozák Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index af2674c57414..828a4377ec6a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -120,6 +120,9 @@ static int option_send_setup(struct usb_serial_port *port); #define ANYDATA_PRODUCT_ADU_E100A 0x6501 #define ANYDATA_PRODUCT_ADU_500A 0x6502 +#define AXESSTEL_VENDOR_ID 0x1726 +#define AXESSTEL_PRODUCT_MV110H 0x1000 + #define BANDRICH_VENDOR_ID 0x1A8D #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 @@ -192,6 +195,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, + { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, From 546d7eec389a3df3173b3131d92829c14e614601 Mon Sep 17 00:00:00 2001 From: Kevin Vance Date: Sat, 1 Mar 2008 13:49:59 -0500 Subject: [PATCH 09/12] USB: ftdi_sio: Workaround for broken Matrix Orbital serial port Workaround for the FT232RL-based, Matrix Orbital VK204-25-USB serial port added to the ftdi_sio driver. The device has an invalid endpoint descriptor, which must be modified before it can be used. Signed-off-by: Kevin Vance Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 24 ++++++++++++++++++++++++ drivers/usb/serial/ftdi_sio.h | 7 +++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 76db2fef4657..17b2cc071ed8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -92,6 +92,7 @@ struct ftdi_sio_quirk { }; static int ftdi_jtag_probe (struct usb_serial *serial); +static int ftdi_mtxorb_hack_setup (struct usb_serial *serial); static void ftdi_USB_UIRT_setup (struct ftdi_private *priv); static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv); @@ -99,6 +100,10 @@ static struct ftdi_sio_quirk ftdi_jtag_quirk = { .probe = ftdi_jtag_probe, }; +static struct ftdi_sio_quirk ftdi_mtxorb_hack_quirk = { + .probe = ftdi_mtxorb_hack_setup, +}; + static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { .port_probe = ftdi_USB_UIRT_setup, }; @@ -161,6 +166,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, + { USB_DEVICE(MTXORB_VK_VID, MTXORB_VK_PID), + .driver_info = (kernel_ulong_t)&ftdi_mtxorb_hack_quirk }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, @@ -1088,6 +1095,23 @@ static int ftdi_jtag_probe(struct usb_serial *serial) return 0; } +/* + * The Matrix Orbital VK204-25-USB has an invalid IN endpoint. + * We have to correct it if we want to read from it. + */ +static int ftdi_mtxorb_hack_setup(struct usb_serial *serial) +{ + struct usb_host_endpoint *ep = serial->dev->ep_in[1]; + struct usb_endpoint_descriptor *ep_desc = &ep->desc; + + if (ep->enabled && ep_desc->wMaxPacketSize == 0) { + ep_desc->wMaxPacketSize = 0x40; + info("Fixing invalid wMaxPacketSize on read pipe"); + } + + return 0; +} + /* ftdi_shutdown is called from usbserial:usb_serial_disconnect * it is called when the usb device is disconnected * diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 6eee2ab914ec..e1eb742abcd5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -102,6 +102,13 @@ * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ #define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ +/* + * The following are the values for the Matrix Orbital VK204-25-USB + * display, which use the FT232RL. + */ +#define MTXORB_VK_VID 0x1b3d +#define MTXORB_VK_PID 0x0158 + /* Interbiometrics USB I/O Board */ /* Developed for Interbiometrics by Rudolf Gugler */ #define INTERBIOMETRICS_VID 0x1209 From 64cc2dd937298324c77c7d584495052547c64a6a Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 22 Feb 2008 17:17:19 -0800 Subject: [PATCH 10/12] USB: pxa2xx_udc: fix misuse of clock enable/disable calls Fix pxa2xx_udc to balance calls to clk_enable/clk_disable. [db: remove inline #ifdefs for IXP non-support of calls] Signed-off-by: Dmitry Baryshkov dbaryshkov@gmail.com Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/pxa2xx_udc.c | 88 +++++++++++++++++++-------------- drivers/usb/gadget/pxa2xx_udc.h | 4 +- 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 4402d6f042d9..096c41cc40d1 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -103,6 +103,12 @@ static const char ep0name [] = "ep0"; #error "Can't configure both IXP and PXA" #endif +/* IXP doesn't yet support */ +#define clk_get(dev,name) NULL +#define clk_enable(clk) do { } while (0) +#define clk_disable(clk) do { } while (0) +#define clk_put(clk) do { } while (0) + #endif #include "pxa2xx_udc.h" @@ -934,20 +940,31 @@ static void udc_disable(struct pxa2xx_udc *); /* We disable the UDC -- and its 48 MHz clock -- whenever it's not * in active use. */ -static int pullup(struct pxa2xx_udc *udc, int is_active) +static int pullup(struct pxa2xx_udc *udc) { - is_active = is_active && udc->vbus && udc->pullup; + int is_active = udc->vbus && udc->pullup && !udc->suspended; DMSG("%s\n", is_active ? "active" : "inactive"); - if (is_active) - udc_enable(udc); - else { - if (udc->gadget.speed != USB_SPEED_UNKNOWN) { - DMSG("disconnect %s\n", udc->driver - ? udc->driver->driver.name - : "(no driver)"); - stop_activity(udc, udc->driver); + if (is_active) { + if (!udc->active) { + udc->active = 1; + /* Enable clock for USB device */ + clk_enable(udc->clk); + udc_enable(udc); } - udc_disable(udc); + } else { + if (udc->active) { + if (udc->gadget.speed != USB_SPEED_UNKNOWN) { + DMSG("disconnect %s\n", udc->driver + ? udc->driver->driver.name + : "(no driver)"); + stop_activity(udc, udc->driver); + } + udc_disable(udc); + /* Disable clock for USB device */ + clk_disable(udc->clk); + udc->active = 0; + } + } return 0; } @@ -958,9 +975,9 @@ static int pxa2xx_udc_vbus_session(struct usb_gadget *_gadget, int is_active) struct pxa2xx_udc *udc; udc = container_of(_gadget, struct pxa2xx_udc, gadget); - udc->vbus = is_active = (is_active != 0); + udc->vbus = (is_active != 0); DMSG("vbus %s\n", is_active ? "supplied" : "inactive"); - pullup(udc, is_active); + pullup(udc); return 0; } @@ -975,9 +992,8 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) if (!udc->mach->gpio_pullup && !udc->mach->udc_command) return -EOPNOTSUPP; - is_active = (is_active != 0); - udc->pullup = is_active; - pullup(udc, is_active); + udc->pullup = (is_active != 0); + pullup(udc); return 0; } @@ -997,7 +1013,7 @@ static const struct usb_gadget_ops pxa2xx_udc_ops = { #ifdef CONFIG_USB_GADGET_DEBUG_FS static int -udc_seq_show(struct seq_file *m, void *d) +udc_seq_show(struct seq_file *m, void *_d) { struct pxa2xx_udc *dev = m->private; unsigned long flags; @@ -1146,11 +1162,6 @@ static void udc_disable(struct pxa2xx_udc *dev) udc_clear_mask_UDCCR(UDCCR_UDE); -#ifdef CONFIG_ARCH_PXA - /* Disable clock for USB device */ - clk_disable(dev->clk); -#endif - ep0_idle (dev); dev->gadget.speed = USB_SPEED_UNKNOWN; } @@ -1191,11 +1202,6 @@ static void udc_enable (struct pxa2xx_udc *dev) { udc_clear_mask_UDCCR(UDCCR_UDE); -#ifdef CONFIG_ARCH_PXA - /* Enable clock for USB device */ - clk_enable(dev->clk); -#endif - /* try to clear these bits before we enable the udc */ udc_ack_int_UDCCR(UDCCR_SUSIR|/*UDCCR_RSTIR|*/UDCCR_RESIR); @@ -1286,7 +1292,7 @@ fail: * for set_configuration as well as eventual disconnect. */ DMSG("registered gadget driver '%s'\n", driver->driver.name); - pullup(dev, 1); + pullup(dev); dump_state(dev); return 0; } @@ -1329,7 +1335,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) return -EINVAL; local_irq_disable(); - pullup(dev, 0); + dev->pullup = 0; + pullup(dev); stop_activity(dev, driver); local_irq_enable(); @@ -2131,13 +2138,11 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev) if (irq < 0) return -ENODEV; -#ifdef CONFIG_ARCH_PXA dev->clk = clk_get(&pdev->dev, "UDCCLK"); if (IS_ERR(dev->clk)) { retval = PTR_ERR(dev->clk); goto err_clk; } -#endif pr_debug("%s: IRQ %d%s%s\n", driver_name, irq, dev->has_cfr ? "" : " (!cfr)", @@ -2250,10 +2255,8 @@ lubbock_fail0: if (dev->mach->gpio_vbus) gpio_free(dev->mach->gpio_vbus); err_gpio_vbus: -#ifdef CONFIG_ARCH_PXA clk_put(dev->clk); err_clk: -#endif return retval; } @@ -2269,7 +2272,9 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) if (dev->driver) return -EBUSY; - udc_disable(dev); + dev->pullup = 0; + pullup(dev); + remove_debug_files(dev); if (dev->got_irq) { @@ -2289,9 +2294,7 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) if (dev->mach->gpio_pullup) gpio_free(dev->mach->gpio_pullup); -#ifdef CONFIG_ARCH_PXA clk_put(dev->clk); -#endif platform_set_drvdata(pdev, NULL); the_controller = NULL; @@ -2317,10 +2320,15 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); + unsigned long flags; if (!udc->mach->gpio_pullup && !udc->mach->udc_command) WARN("USB host won't detect disconnect!\n"); - pullup(udc, 0); + udc->suspended = 1; + + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); return 0; } @@ -2328,8 +2336,12 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) static int pxa2xx_udc_resume(struct platform_device *dev) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); + unsigned long flags; - pullup(udc, 1); + udc->suspended = 0; + local_irq_save(flags); + pullup(udc); + local_irq_restore(flags); return 0; } diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index b67e3ff5e4eb..e2c19e88c875 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h @@ -119,7 +119,9 @@ struct pxa2xx_udc { has_cfr : 1, req_pending : 1, req_std : 1, - req_config : 1; + req_config : 1, + suspended : 1, + active : 1; #define start_watchdog(dev) mod_timer(&dev->timer, jiffies + (HZ/200)) struct timer_list timer; From 350351006426471458fe50b1de1160200a1ba138 Mon Sep 17 00:00:00 2001 From: Tony Jones Date: Fri, 22 Feb 2008 00:13:36 +0100 Subject: [PATCH 11/12] USB: remove incorrect struct class_device from the printer gadget This field does nothing, and should not be allowed to stick around incase someone gets any other ideas... Signed-off-by: Tony Jones Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/printer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 4f6bfa100f2a..2c32bd08ee7d 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c @@ -92,7 +92,6 @@ struct printer_dev { u8 *current_rx_buf; u8 printer_status; u8 reset_printer; - struct class_device *printer_class_dev; struct cdev printer_cdev; struct device *pdev; u8 printer_cdev_open; From 4ae897df80019db433cd46cdd50d3b48463757d9 Mon Sep 17 00:00:00 2001 From: Sven Andersen Date: Tue, 4 Mar 2008 22:09:11 +0100 Subject: [PATCH 12/12] USB: ftdi_sio - really enable EM1010PC Add EM1010PC to ftdi_sio.c Signed-off-by: Sven Andersen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 17b2cc071ed8..91dc433dbcf1 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -281,6 +281,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },