From d01f87c0ffa96cb44faa78710711eb6e974b891c Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Thu, 4 Oct 2012 09:53:43 -0700 Subject: USB: Enable LPM after a failed probe. Before a driver is probed, we want to disable USB 3.0 Link Power Management (LPM), in case the driver needs hub-initiated LPM disabled. After the probe finishes, we want to attempt to re-enable LPM, order to balance the LPM ref count. When a probe fails (such as when libusual doesn't want to bind to a USB 3.0 mass storage device), make sure to balance the LPM ref counts by re-enabling LPM. This patch should be backported to kernels as old as 3.5, that contain the commit 8306095fd2c1100e8244c09bf560f97aca5a311d "USB: Disable USB 3.0 LPM in critical sections." Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/core/driver.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ddd820d2528..6056db7af41 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev) intf->condition = USB_INTERFACE_UNBOUND; usb_cancel_queued_reset(intf); + /* If the LPM disable succeeded, balance the ref counts. */ + if (!lpm_disable_error) + usb_unlocked_enable_lpm(udev); + /* Unbound interfaces are always runtime-PM-disabled and -suspended */ if (driver->supports_autosuspend) pm_runtime_disable(dev); -- cgit v1.2.3-70-g09d2 From ae8963adb4ad8c5f2a89ca1d99fb7bb721e7599f Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Wed, 3 Oct 2012 11:18:05 -0700 Subject: usb: Don't enable LPM if the exit latency is zero. Some USB 3.0 devices signal that they don't implement Link PM by having all zeroes in the U1/U2 exit latencies in their SuperSpeed BOS descriptor. Don found that a Western Digital device he has experiences transfer errors when LPM is enabled. The lsusb shows the U1/U2 exit latencies are set to zero: Binary Object Store Descriptor: bLength 5 bDescriptorType 15 wTotalLength 22 bNumDeviceCaps 2 SuperSpeed USB Device Capability: bLength 10 bDescriptorType 16 bDevCapabilityType 3 bmAttributes 0x00 Latency Tolerance Messages (LTM) Supported wSpeedsSupported 0x000e Device can operate at Full Speed (12Mbps) Device can operate at High Speed (480Mbps) Device can operate at SuperSpeed (5Gbps) bFunctionalitySupport 1 Lowest fully-functional device speed is Full Speed (12Mbps) bU1DevExitLat 0 micro seconds bU2DevExitLat 0 micro seconds The fix is to not enable LPM for a particular link state if we find its corresponding exit latency is zero. This patch should be backported to kernels as old as 3.5, that contain the commit 1ea7e0e8e3d0f50901d335ea4178ab2aa8c88201 "USB: Add support to enable/disable USB3 link states." Signed-off-by: Sarah Sharp Reported-by: Don Zickus Tested-by: Don Zickus Cc: stable@vger.kernel.org --- drivers/usb/core/hub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 673ee469626..8f047870932 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3415,6 +3415,16 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { int timeout; + __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; + __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; + + /* If the device says it doesn't have *any* exit latency to come out of + * U1 or U2, it's probably lying. Assume it doesn't implement that link + * state. + */ + if ((state == USB3_LPM_U1 && u1_mel == 0) || + (state == USB3_LPM_U2 && u2_mel == 0)) + return; /* We allow the host controller to set the U1/U2 timeout internally * first, so that it can change its schedule to account for the -- cgit v1.2.3-70-g09d2 From 65a95b75bc5afa7bbb844e222481044c1c4767eb Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 5 Oct 2012 10:32:07 -0700 Subject: usb: Send Set SEL before enabling parent U1/U2 timeout. The Set SEL control transfer tells a device the exit latencies associated with a device-initated U1 or U2 exit. Since a parent hub may initiate a transition to U1 soon after a downstream port's U1 timeout is set, we need to make sure the device receives the Set SEL transfer before the parent hub timeout is set. This patch should be backported to kernels as old as 3.5, that contain the commit 1ea7e0e8e3d0f50901d335ea4178ab2aa8c88201 "USB: Add support to enable/disable USB3 link states." Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/core/hub.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8f047870932..b8e11fff17b 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3319,16 +3319,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev, } if (enable) { - /* - * First, let the device know about the exit latencies - * associated with the link state we're about to enable. - */ - ret = usb_req_set_sel(udev, state); - if (ret < 0) { - dev_warn(&udev->dev, "Set SEL for device-initiated " - "%s failed.\n", usb3_lpm_names[state]); - return -EBUSY; - } /* * Now send the control transfer to enable device-initiated LPM * for either U1 or U2. @@ -3414,7 +3404,7 @@ static int usb_set_lpm_timeout(struct usb_device *udev, static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { - int timeout; + int timeout, ret; __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; @@ -3426,6 +3416,17 @@ static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, (state == USB3_LPM_U2 && u2_mel == 0)) return; + /* + * First, let the device know about the exit latencies + * associated with the link state we're about to enable. + */ + ret = usb_req_set_sel(udev, state); + if (ret < 0) { + dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n", + usb3_lpm_names[state]); + return; + } + /* We allow the host controller to set the U1/U2 timeout internally * first, so that it can change its schedule to account for the * additional latency to send data to a device in a lower power -- cgit v1.2.3-70-g09d2 From 1510a1a2d0946b34422fe8816187f274a5086904 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 5 Oct 2012 10:30:35 -0700 Subject: usb: trival: Fix debugging units mistake. SEL and PEL are in microseconds, not milliseconds. Also, fix a split string that will trigger checkpatch warnings. Signed-off-by: Sarah Sharp --- drivers/usb/core/hub.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b8e11fff17b..64854d76f52 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3241,8 +3241,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) (state == USB3_LPM_U2 && (u2_sel > USB3_LPM_MAX_U2_SEL_PEL || u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { - dev_dbg(&udev->dev, "Device-initiated %s disabled due " - "to long SEL %llu ms or PEL %llu ms\n", + dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n", usb3_lpm_names[state], u1_sel, u1_pel); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From 041d81f493d90c940ec41f0ec98bc7c4f2fba431 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 4 Oct 2012 11:58:00 +0300 Subject: usb: dwc3: gadget: fix 'endpoint always busy' bug If a USB transfer has already been started, meaning we have already issued StartTransfer command to that particular endpoint, DWC3_EP_BUSY flag has also already been set. When we try to cancel this transfer which is already in controller's cache, we will not receive XferComplete event and we must clear DWC3_EP_BUSY in order to allow subsequent requests to be properly started. The best place to clear that flag is right after issuing DWC3_DEPCMD_ENDTRANSFER. Cc: stable@vger.kernel.org # v3.4 v3.5 v3.6 Reported-by: Moiz Sonasath Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c9e729a4bf6..7b7deddf6a5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); WARN_ON_ONCE(ret); dep->resource_index = 0; - + dep->flags &= ~DWC3_EP_BUSY; udelay(100); } -- cgit v1.2.3-70-g09d2 From 6ff1f3d3bd7c69c62ca5773b1b684bce42eff06a Mon Sep 17 00:00:00 2001 From: Stefano Babic Date: Mon, 15 Oct 2012 11:20:22 +0200 Subject: usb: musb: am35xx: drop spurious unplugging a device On AM3517, tx and rx interrupt are detected together with the disconnect event. This generates a kernel panic in musb_interrupt, because rx / tx are handled after disconnect. This issue was seen on a Technexion's TAM3517 SOM. Unplugging a device, tx / rx interrupts together with disconnect are detected. This brings to kernel panic like this: [ 68.526153] Unable to handle kernel NULL pointer dereference at virtual address 00000011 [ 68.534698] pgd = c0004000 [ 68.537536] [00000011] *pgd=00000000 [ 68.541351] Internal error: Oops: 17 [#1] ARM [ 68.545928] Modules linked in: [ 68.549163] CPU: 0 Not tainted (3.6.0-rc5-00020-g9e05905 #178) [ 68.555694] PC is at rxstate+0x8/0xdc [ 68.559539] LR is at musb_interrupt+0x98/0x858 [ 68.564239] pc : [] lr : [] psr: 40000193 [ 68.564239] sp : ce83fb40 ip : d0906410 fp : 00000000 [ 68.576293] r10: 00000000 r9 : cf3b0e40 r8 : 00000002 [ 68.581817] r7 : 00000019 r6 : 00000001 r5 : 00000001 r4 : 000000d4 [ 68.588684] r3 : 00000000 r2 : 00000000 r1 : ffffffcc r0 : cf23c108 [ 68.595550] Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment ke Note: this behavior is not seen with a USB hub, while it is easy to reproduce connecting a USB-pen directly to the USB-A of the board. Drop tx / rx interrupts if disconnect is detected. Signed-off-by: Stefano Babic CC: Felipe Balbi Cc: stable@vger.kernel.org # 3.5 3.6 Tested-by: Dmitry Lifshitz Tested-by: Igor Grinberg Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 457f25e62c5..c964d6af178 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) ret = IRQ_HANDLED; } + /* Drop spurious RX and TX if device is disconnected */ + if (musb->int_usb & MUSB_INTR_DISCONNECT) { + musb->int_tx = 0; + musb->int_rx = 0; + } + if (musb->int_tx || musb->int_rx || musb->int_usb) ret |= musb_interrupt(musb); -- cgit v1.2.3-70-g09d2 From 01b8daf71b2fd2f6ece5f063a089abf4b13f1d6e Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Sat, 13 Oct 2012 19:20:18 +0530 Subject: usb: dwc3: shutdown usb_phy when removing the device We call usb_phy_init() from dwc3_core_init() during probe, so adding usb_phy_shutdown() to dwc3_core_exit() while removing the device so we don't keep PHYs turned on, consuming power, unnecessarily. Signed-off-by: Vivek Gautam Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b415c0c859d..c14ebc975ba 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc) { dwc3_event_buffers_cleanup(dwc); dwc3_free_event_buffers(dwc); + + usb_phy_shutdown(dwc->usb2_phy); + usb_phy_shutdown(dwc->usb3_phy); + } #define DWC3_ALIGN_MASK (16 - 1) -- cgit v1.2.3-70-g09d2 From 0b2ffb78c0ef83bb03f594fec2adc13ac6ac427b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 4 Oct 2012 02:32:41 +0200 Subject: usb: gadget: Make webcam gadget select USB_LIBCOMPOSITE Composite gadget support is now available as a library instead of being built with each gadget. Composite drivers need to select USB_LIBCOMPOSITE. Signed-off-by: Laurent Pinchart Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index dfb51a45496..e0ff51b8952 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -952,6 +952,7 @@ endif config USB_G_WEBCAM tristate "USB Webcam Gadget" depends on VIDEO_DEV + select USB_LIBCOMPOSITE help The Webcam Gadget acts as a composite USB Audio and Video Class device. It provides a userspace API to process UVC control requests -- cgit v1.2.3-70-g09d2 From c2fa3edc58a262dfcb7aea78e24661e90e00098c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 15 Oct 2012 23:24:55 -0700 Subject: usb: renesas_usbhs: fixup __usbhs_for_each_pipe 1st pos __usbhs_for_each_pipe() is the macro which moves around each pipe, but it has a bug which didn't care about 1st pipe's position. Because of this bug, it moves around pipe0, pipe2, pipe3 ... even though it requested pipe1, pipe2, pipe3... This patch modifies it. Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/pipe.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 08786c06dcf..3d80c7b1fd1 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -54,7 +54,7 @@ struct usbhs_pipe_info { * pipe list */ #define __usbhs_for_each_pipe(start, pos, info, i) \ - for (i = start, pos = (info)->pipe; \ + for (i = start, pos = (info)->pipe + i; \ i < (info)->size; \ i++, pos = (info)->pipe + i) -- cgit v1.2.3-70-g09d2 From d5c6a1e024dd5acd6ad2e1a6eb6a2fd5c15c50f1 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 11 Oct 2012 21:49:38 -0700 Subject: usb: renesas_usbhs: fixup interrupt status clear method When interrupt happened, renesas_usbhs driver gets irq status by usbhs_status_get_each_irq(), and cleared all status by using 0. But, this method is incorrect, since extra interrupt might occur between them. This patch cleared corresponding bits only Signed-off-by: Kuninori Morimoto Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/mod.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 35c5208f324..61933a90e5b 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); - usbhs_write(priv, BRDYSTS, 0); - usbhs_write(priv, NRDYSTS, 0); - usbhs_write(priv, BEMPSTS, 0); + usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); + usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); + usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); /* * call irq callback functions -- cgit v1.2.3-70-g09d2 From 69da85edbab5cd42909d3ba65b3dad1c1fb40206 Mon Sep 17 00:00:00 2001 From: Alexandre Pereira da Silva Date: Mon, 15 Oct 2012 09:47:35 -0300 Subject: usb: gadget: lpc32xx_udc: Fix compatibility with STOTG04 The STOTG04 is an replacement for ISP1301. Most of the registers on STOTG04 are the same as on ISP1301, but the register ISP1301_I2C_OTG_CONTROL_2 (address 0x10) doesn't exist on the ST part. This is a work around for this by using the interrupt source register that should behave the same on both parts and has the needed information. Tested-by: Roland Stigge Signed-off-by: Alexandre Pereira da Silva Signed-off-by: Felipe Balbi --- drivers/usb/gadget/lpc32xx_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index f696fb9b136..21a9861dabf 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work) /* Get the VBUS status from the transceiver */ value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client, - ISP1301_I2C_OTG_CONTROL_2); + ISP1301_I2C_INTERRUPT_SOURCE); /* VBUS on or off? */ - if (value & OTG_B_SESS_VLD) + if (value & INT_SESS_VLD) udc->vbus = 1; else udc->vbus = 0; -- cgit v1.2.3-70-g09d2 From 7bdce71822f471433dd3014692e9096996c7b5f0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 15 Oct 2012 18:20:52 +0200 Subject: USB: ark3116: fix NULL-pointer dereference Fix NULL-pointer dereference at release by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is NULL when release is called. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ark3116.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index cf2522c397d..bd50a8a41a0 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -125,9 +125,6 @@ static inline int calc_divisor(int bps) static int ark3116_attach(struct usb_serial *serial) { - struct usb_serial_port *port = serial->port[0]; - struct ark3116_private *priv; - /* make sure we have our end-points */ if ((serial->num_bulk_in == 0) || (serial->num_bulk_out == 0) || @@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial) return -EINVAL; } - priv = kzalloc(sizeof(struct ark3116_private), - GFP_KERNEL); + return 0; +} + +static int ark3116_port_probe(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct ark3116_private *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial) return 0; } -static void ark3116_release(struct usb_serial *serial) +static int ark3116_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct ark3116_private *priv = usb_get_serial_port_data(port); /* device is closed, so URBs and DMA should be down */ - - usb_set_serial_port_data(port, NULL); - mutex_destroy(&priv->hw_lock); - kfree(priv); + + return 0; } static void ark3116_init_termios(struct tty_struct *tty) @@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = { .id_table = id_table, .num_ports = 1, .attach = ark3116_attach, - .release = ark3116_release, + .port_probe = ark3116_port_probe, + .port_remove = ark3116_port_remove, .set_termios = ark3116_set_termios, .init_termios = ark3116_init_termios, .ioctl = ark3116_ioctl, -- cgit v1.2.3-70-g09d2 From a9556040119a63d06fd5238d47f5b683fba4178b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 15 Oct 2012 18:20:54 +0200 Subject: USB: cyberjack: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the write waitqueue was initialised but never used. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cyberjack.c | 49 ++++++++++++++++-------------------------- 1 file changed, 19 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 2a7aecc7223..4ee77dcbe69 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -55,9 +55,9 @@ #define CYBERJACK_PRODUCT_ID 0x0100 /* Function prototypes */ -static int cyberjack_startup(struct usb_serial *serial); static void cyberjack_disconnect(struct usb_serial *serial); -static void cyberjack_release(struct usb_serial *serial); +static int cyberjack_port_probe(struct usb_serial_port *port); +static int cyberjack_port_remove(struct usb_serial_port *port); static int cyberjack_open(struct tty_struct *tty, struct usb_serial_port *port); static void cyberjack_close(struct usb_serial_port *port); @@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = { .description = "Reiner SCT Cyberjack USB card reader", .id_table = id_table, .num_ports = 1, - .attach = cyberjack_startup, .disconnect = cyberjack_disconnect, - .release = cyberjack_release, + .port_probe = cyberjack_port_probe, + .port_remove = cyberjack_port_remove, .open = cyberjack_open, .close = cyberjack_close, .write = cyberjack_write, @@ -107,56 +107,45 @@ struct cyberjack_private { short wrsent; /* Data already sent */ }; -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int cyberjack_startup(struct usb_serial *serial) +static int cyberjack_port_probe(struct usb_serial_port *port) { struct cyberjack_private *priv; - int i; + int result; - /* allocate the private data structure */ priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); if (!priv) return -ENOMEM; - /* set initial values */ spin_lock_init(&priv->lock); priv->rdtodo = 0; priv->wrfilled = 0; priv->wrsent = 0; - usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port[0]->write_wait); + usb_set_serial_port_data(port, priv); - for (i = 0; i < serial->num_ports; ++i) { - int result; - result = usb_submit_urb(serial->port[i]->interrupt_in_urb, - GFP_KERNEL); - if (result) - dev_err(&serial->dev->dev, - "usb_submit_urb(read int) failed\n"); - dev_dbg(&serial->dev->dev, "%s - usb_submit_urb(int urb)\n", - __func__); - } + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) + dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); return 0; } -static void cyberjack_disconnect(struct usb_serial *serial) +static int cyberjack_port_remove(struct usb_serial_port *port) { - int i; + struct cyberjack_private *priv; - for (i = 0; i < serial->num_ports; ++i) - usb_kill_urb(serial->port[i]->interrupt_in_urb); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } -static void cyberjack_release(struct usb_serial *serial) +static void cyberjack_disconnect(struct usb_serial *serial) { int i; - for (i = 0; i < serial->num_ports; ++i) { - /* My special items, the standard routines free my urbs */ - kfree(usb_get_serial_port_data(serial->port[i])); - } + for (i = 0; i < serial->num_ports; ++i) + usb_kill_urb(serial->port[i]->interrupt_in_urb); } static int cyberjack_open(struct tty_struct *tty, -- cgit v1.2.3-70-g09d2 From fa919751a2d26a88140fc5810124dd81644efe51 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 15 Oct 2012 18:20:53 +0200 Subject: USB: belkin_sa: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the write waitqueue was initialised but never used. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/belkin_sa.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 99449424193..ea29556f0d7 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -45,8 +45,8 @@ #define DRIVER_DESC "USB Belkin Serial converter driver" /* function prototypes for a Belkin USB Serial Adapter F5U103 */ -static int belkin_sa_startup(struct usb_serial *serial); -static void belkin_sa_release(struct usb_serial *serial); +static int belkin_sa_port_probe(struct usb_serial_port *port); +static int belkin_sa_port_remove(struct usb_serial_port *port); static int belkin_sa_open(struct tty_struct *tty, struct usb_serial_port *port); static void belkin_sa_close(struct usb_serial_port *port); @@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = { .break_ctl = belkin_sa_break_ctl, .tiocmget = belkin_sa_tiocmget, .tiocmset = belkin_sa_tiocmset, - .attach = belkin_sa_startup, - .release = belkin_sa_release, + .port_probe = belkin_sa_port_probe, + .port_remove = belkin_sa_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -118,17 +118,15 @@ struct belkin_sa_private { (c), BELKIN_SA_SET_REQUEST_TYPE, \ (v), 0, NULL, 0, WDR_TIMEOUT) -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int belkin_sa_startup(struct usb_serial *serial) +static int belkin_sa_port_probe(struct usb_serial_port *port) { - struct usb_device *dev = serial->dev; + struct usb_device *dev = port->serial->dev; struct belkin_sa_private *priv; - /* allocate the private data structure */ priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); if (!priv) - return -1; /* error */ - /* set initial values for control structures */ + return -ENOMEM; + spin_lock_init(&priv->lock); priv->control_state = 0; priv->last_lsr = 0; @@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial) le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control); - init_waitqueue_head(&serial->port[0]->write_wait); - usb_set_serial_port_data(serial->port[0], priv); + usb_set_serial_port_data(port, priv); return 0; } -static void belkin_sa_release(struct usb_serial *serial) +static int belkin_sa_port_remove(struct usb_serial_port *port) { - int i; + struct belkin_sa_private *priv; - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int belkin_sa_open(struct tty_struct *tty, -- cgit v1.2.3-70-g09d2 From 4295fe7791a1b20c90cbaaa6f23f2fb94218b8a7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 15 Oct 2012 15:47:20 +0200 Subject: USB: cp210x: fix port-data memory leak Fix port data memory leak by replacing port private data with serial private data. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release. The private data is used to store the control interface number, but as this is the same for all ports on an interface it should be stored as usb-serial data anyway. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 28af5acc336..eb033fc92a1 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); -struct cp210x_port_private { +struct cp210x_serial_private { __u8 bInterfaceNumber; }; @@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + struct cp210x_serial_private *spriv = usb_get_serial_data(serial); __le32 *buf; int result, i, length; @@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_INTERFACE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, + spriv->bInterfaceNumber, buf, size, USB_CTRL_GET_TIMEOUT); /* Convert data into an array of integers */ @@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + struct cp210x_serial_private *spriv = usb_get_serial_data(serial); __le32 *buf; int result, i, length; @@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, 0x0000, - port_priv->bInterfaceNumber, buf, size, + spriv->bInterfaceNumber, buf, size, USB_CTRL_SET_TIMEOUT); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, data[0], - port_priv->bInterfaceNumber, NULL, 0, + spriv->bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) static int cp210x_startup(struct usb_serial *serial) { - struct cp210x_port_private *port_priv; - int i; + struct usb_host_interface *cur_altsetting; + struct cp210x_serial_private *spriv; /* cp210x buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); - for (i = 0; i < serial->num_ports; i++) { - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) - return -ENOMEM; + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); + if (!spriv) + return -ENOMEM; - port_priv->bInterfaceNumber = - serial->interface->cur_altsetting->desc.bInterfaceNumber; + cur_altsetting = serial->interface->cur_altsetting; + spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber; - usb_set_serial_port_data(serial->port[i], port_priv); - } + usb_set_serial_data(serial, spriv); return 0; } static void cp210x_release(struct usb_serial *serial) { - struct cp210x_port_private *port_priv; - int i; + struct cp210x_serial_private *spriv; - for (i = 0; i < serial->num_ports; i++) { - port_priv = usb_get_serial_port_data(serial->port[i]); - kfree(port_priv); - usb_set_serial_port_data(serial->port[i], NULL); - } + spriv = usb_get_serial_data(serial); + kfree(spriv); } module_usb_serial_driver(serial_drivers, id_table); -- cgit v1.2.3-70-g09d2 From 8bf769eb5f6efc33f95088850f33fcc05d28b508 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 15 Oct 2012 15:47:21 +0200 Subject: USB: pl2303: fix port-data memory leak Fix port-data memory leak by allocating and freeing port data in port_probe/remove rather than in attach/release, and by introducing serial private data to store the device type which is interface rather than port specific. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 90 +++++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 892ebdc7a36..60024190136 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -133,12 +133,15 @@ enum pl2303_type { HX, /* HX version of the pl2303 chip */ }; +struct pl2303_serial_private { + enum pl2303_type type; +}; + struct pl2303_private { spinlock_t lock; wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; - enum pl2303_type type; }; static int pl2303_vendor_read(__u16 value, __u16 index, @@ -167,14 +170,19 @@ static int pl2303_vendor_write(__u16 value, __u16 index, static int pl2303_startup(struct usb_serial *serial) { - struct pl2303_private *priv; + struct pl2303_serial_private *spriv; enum pl2303_type type = type_0; unsigned char *buf; - int i; + + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); + if (!spriv) + return -ENOMEM; buf = kmalloc(10, GFP_KERNEL); - if (buf == NULL) + if (!buf) { + kfree(spriv); return -ENOMEM; + } if (serial->dev->descriptor.bDeviceClass == 0x02) type = type_0; @@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial) type = type_1; dev_dbg(&serial->interface->dev, "device type: %d\n", type); - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i], priv); - } + spriv->type = type; + usb_set_serial_data(serial, spriv); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 0, serial); @@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial) kfree(buf); return 0; +} -cleanup: - kfree(buf); - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; +static void pl2303_release(struct usb_serial *serial) +{ + struct pl2303_serial_private *spriv; + + spriv = usb_get_serial_data(serial); + kfree(spriv); +} + +static int pl2303_port_probe(struct usb_serial_port *port) +{ + struct pl2303_private *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + + return 0; +} + +static int pl2303_port_remove(struct usb_serial_port *port) +{ + struct pl2303_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int set_control_lines(struct usb_device *dev, u8 value) @@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { struct usb_serial *serial = port->serial; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int cflag; @@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty, } if (baud > 1228800) { /* type_0, type_1 only support up to 1228800 baud */ - if (priv->type != HX) + if (spriv->type != HX) baud = 1228800; else if (baud > 6000000) baud = 6000000; @@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); if (cflag & CRTSCTS) { - if (priv->type == HX) + if (spriv->type == HX) pl2303_vendor_write(0x0, 0x61, serial); else pl2303_vendor_write(0x0, 0x41, serial); @@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) { struct ktermios tmp_termios; struct usb_serial *serial = port->serial; - struct pl2303_private *priv = usb_get_serial_port_data(port); + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int result; - if (priv->type != HX) { + if (spriv->type != HX) { usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); } else { @@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) dev_err(&port->dev, "error sending break = %d\n", result); } -static void pl2303_release(struct usb_serial *serial) -{ - int i; - struct pl2303_private *priv; - - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } -} - static void pl2303_update_line_status(struct usb_serial_port *port, unsigned char *data, unsigned int actual_length) @@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = { .read_int_callback = pl2303_read_int_callback, .attach = pl2303_startup, .release = pl2303_release, + .port_probe = pl2303_port_probe, + .port_remove = pl2303_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3-70-g09d2 From db5c8b524444d4fc6b1f32d368a50a3729e50002 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 10 Oct 2012 14:10:21 -0400 Subject: USB: fix port probing and removal in garmin_gps This patch (as1615) fixes a bug in the Garmin USB serial driver. It uses attach, disconnect, and release routines to carry out actions that should be handled by port_probe and port_remove routines, because they access port-specific data. The bug causes an oops when the device in unplugged, because the private data for each port structure now gets erased when the port is unbound from the driver, resulting in a null-pointer dereference. Signed-off-by: Alan Stern Reported--by: Markus Schauler Tested-by: Markus Schauler Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/garmin_gps.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 3ee92648c02..203358d7e7b 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data) -static int garmin_attach(struct usb_serial *serial) +static int garmin_port_probe(struct usb_serial_port *port) { - int status = 0; - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = NULL; + int status; + struct garmin_data *garmin_data_p; garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { @@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial) } -static void garmin_disconnect(struct usb_serial *serial) +static int garmin_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); usb_kill_urb(port->interrupt_in_urb); del_timer_sync(&garmin_data_p->timer); -} - - -static void garmin_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - kfree(garmin_data_p); + return 0; } @@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = { .close = garmin_close, .throttle = garmin_throttle, .unthrottle = garmin_unthrottle, - .attach = garmin_attach, - .disconnect = garmin_disconnect, - .release = garmin_release, + .port_probe = garmin_port_probe, + .port_remove = garmin_port_remove, .write = garmin_write, .write_room = garmin_write_room, .write_bulk_callback = garmin_write_bulk_callback, -- cgit v1.2.3-70-g09d2 From 014639003c77a51fc319c9fdf225e7747cb6e18d Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 13 Oct 2012 12:20:36 +0200 Subject: usbdevfs: Fix broken scatter-gather transfer The handling of large output bulk transfers is broken; the same user page is read over and over again. Fixed with this patch. Cc: stable Acked-by: Peter Stuge Acked-by: Hans de Goede Acked-by: Alan Stern Signed-off-by: Henrik Rydberg Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e0356cb859b..b78fbe222b7 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ret = -EFAULT; goto error; } + uurb->buffer += u; } totlen -= u; } -- cgit v1.2.3-70-g09d2 From c5211187f7ff8e8dbff4ebf7c011ac4c0ffe319c Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Tue, 16 Oct 2012 21:21:21 +0800 Subject: USB: cdc-acm: fix pipe type of write endpoint If the write endpoint is interrupt type, usb_sndintpipe() should be passed to usb_fill_int_urb() instead of usb_sndbulkpipe(). Cc: Oliver Neukum Signed-off-by: Ming Lei Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 981f2132d12..572f4e7bd3f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1233,7 +1233,7 @@ made_compressed_probe: if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, - usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); else usb_fill_bulk_urb(snd->urb, usb_dev, -- cgit v1.2.3-70-g09d2 From 09eeffb70c086692064f4224490d1cd2ffe43bdd Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Sun, 14 Oct 2012 16:22:34 +1300 Subject: usb: Missing dma_mask in uhci-platform.c when probed from device-tree Device-tree probed devices don't get a dev.dma_mask set. This patch sets a default 32bit mask on platforms using devicetree. Without this patch, arch-vt8500 cannot detect uhci attached devices. Signed-off-by: Tony Prisk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-platform.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index e4780491df4..68ebf20e151 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = { .hub_control = uhci_hub_control, }; +static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32); static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) { @@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &platform_uhci_dma_mask; + hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev, pdev->name); if (!hcd) -- cgit v1.2.3-70-g09d2 From 6e1babb3ff2651376f2e9843569fcb39cfe4686b Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Sun, 14 Oct 2012 16:22:35 +1300 Subject: usb: Missing dma_mask in ehci-vt8500.c when probed from device-tree Device-tree probed devices don't get a dev.dma_mask set. This patch sets a default 32bit mask on arch-vt8500 when using devicetree. Without this patch, arch-vt8500 cannot detect ehci attached devices. Signed-off-by: Tony Prisk Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-vt8500.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 96722bfebc8..d3c9a3e397b 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; +static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32); + static int vt8500_ehci_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd; @@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &vt8500_ehci_dma_mask; + if (pdev->resource[1].flags != IORESOURCE_IRQ) { pr_debug("resource[1] is not IORESOURCE_IRQ"); return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 301a29da6e891e7eb95c843af0ecdbe86d01f723 Mon Sep 17 00:00:00 2001 From: Nicolas Boullis Date: Tue, 16 Oct 2012 00:06:23 +0200 Subject: usb: acm: fix the computation of the number of data bits The current code assumes that CSIZE is 0000060, which appears to be wrong on some arches (such as powerpc). Signed-off-by: Nicolas Boullis Acked-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 572f4e7bd3f..6e49ec6f3ad 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = { 2500000, 3000000, 3500000, 4000000 }; -static const __u8 acm_tty_size[] = { - 5, 6, 7, 8 -}; - static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) { @@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty, newline.bParityType = termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; - newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; + switch (termios->c_cflag & CSIZE) { + case CS5: + newline.bDataBits = 5; + break; + case CS6: + newline.bDataBits = 6; + break; + case CS7: + newline.bDataBits = 7; + break; + case CS8: + default: + newline.bDataBits = 8; + break; + } /* FIXME: Needs to clear unsupported bits in the termios */ acm->clocal = ((termios->c_cflag & CLOCAL) != 0); -- cgit v1.2.3-70-g09d2 From 5c1a0f418d8d985f3a62849bcac43fc5404cc592 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:34:55 +0200 Subject: USB: cypress_m8: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cypress_m8.c | 75 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 1befce21e17..f0da1279c11 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -123,10 +123,10 @@ struct cypress_private { }; /* function prototypes for the Cypress USB to serial device */ -static int cypress_earthmate_startup(struct usb_serial *serial); -static int cypress_hidcom_startup(struct usb_serial *serial); -static int cypress_ca42v2_startup(struct usb_serial *serial); -static void cypress_release(struct usb_serial *serial); +static int cypress_earthmate_port_probe(struct usb_serial_port *port); +static int cypress_hidcom_port_probe(struct usb_serial_port *port); +static int cypress_ca42v2_port_probe(struct usb_serial_port *port); +static int cypress_port_remove(struct usb_serial_port *port); static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); static void cypress_close(struct usb_serial_port *port); static void cypress_dtr_rts(struct usb_serial_port *port, int on); @@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = { .description = "DeLorme Earthmate USB", .id_table = id_table_earthmate, .num_ports = 1, - .attach = cypress_earthmate_startup, - .release = cypress_release, + .port_probe = cypress_earthmate_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = { .description = "HID->COM RS232 Adapter", .id_table = id_table_cyphidcomrs232, .num_ports = 1, - .attach = cypress_hidcom_startup, - .release = cypress_release, + .port_probe = cypress_hidcom_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { .description = "Nokia CA-42 V2 Adapter", .id_table = id_table_nokiaca42v2, .num_ports = 1, - .attach = cypress_ca42v2_startup, - .release = cypress_release, + .port_probe = cypress_ca42v2_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port) *****************************************************************************/ -static int generic_startup(struct usb_serial *serial) +static int cypress_generic_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); if (!priv) @@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial) } -static int cypress_earthmate_startup(struct usb_serial *serial) +static int cypress_earthmate_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); @@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial) } return 0; -} /* cypress_earthmate_startup */ - +} -static int cypress_hidcom_startup(struct usb_serial *serial) +static int cypress_hidcom_port_probe(struct usb_serial_port *port) { struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); priv->chiptype = CT_CYPHIDCOM; return 0; -} /* cypress_hidcom_startup */ - +} -static int cypress_ca42v2_startup(struct usb_serial *serial) +static int cypress_ca42v2_port_probe(struct usb_serial_port *port) { struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); priv->chiptype = CT_CA42V2; return 0; -} /* cypress_ca42v2_startup */ - +} -static void cypress_release(struct usb_serial *serial) +static int cypress_port_remove(struct usb_serial_port *port) { struct cypress_private *priv; - /* all open ports are closed at this point */ - priv = usb_get_serial_port_data(serial->port[0]); + priv = usb_get_serial_port_data(port); - if (priv) { - kfifo_free(&priv->write_fifo); - kfree(priv); - } -} + kfifo_free(&priv->write_fifo); + kfree(priv); + return 0; +} static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) { -- cgit v1.2.3-70-g09d2 From 95940a04bfe8a4d246f4ca17c6a3b00148bdead0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:35:02 +0200 Subject: USB: kobil_sct: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/kobil_sct.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 5c4d2fbd4e1..c9ca7a5b12e 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -54,8 +54,8 @@ /* Function prototypes */ -static int kobil_startup(struct usb_serial *serial); -static void kobil_release(struct usb_serial *serial); +static int kobil_port_probe(struct usb_serial_port *probe); +static int kobil_port_remove(struct usb_serial_port *probe); static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); static void kobil_close(struct usb_serial_port *port); static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = { .description = "KOBIL USB smart card terminal", .id_table = id_table, .num_ports = 1, - .attach = kobil_startup, - .release = kobil_release, + .port_probe = kobil_port_probe, + .port_remove = kobil_port_remove, .ioctl = kobil_ioctl, .set_termios = kobil_set_termios, .init_termios = kobil_init_termios, @@ -117,9 +117,10 @@ struct kobil_private { }; -static int kobil_startup(struct usb_serial *serial) +static int kobil_port_probe(struct usb_serial_port *port) { int i; + struct usb_serial *serial = port->serial; struct kobil_private *priv; struct usb_device *pdev; struct usb_host_config *actconfig; @@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial) dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n"); break; } - usb_set_serial_port_data(serial->port[0], priv); + usb_set_serial_port_data(port, priv); /* search for the necessary endpoints */ pdev = serial->dev; @@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial) } -static void kobil_release(struct usb_serial *serial) +static int kobil_port_remove(struct usb_serial_port *port) { - int i; + struct kobil_private *priv; - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static void kobil_init_termios(struct tty_struct *tty) -- cgit v1.2.3-70-g09d2 From c27f3efc56080a246f6ab7f57f0a6f56d256d769 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:34:57 +0200 Subject: USB: io_edgeport: fix port-data memory leak Fix port-data memory leak by moving port data allocation and deallocation to port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_edgeport.c | 54 +++++++++++++++++++++------------------- drivers/usb/serial/io_tables.h | 8 ++++++ 2 files changed, 37 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 8e6faaf3580..5acc0d13864 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty, static int edge_startup(struct usb_serial *serial); static void edge_disconnect(struct usb_serial *serial); static void edge_release(struct usb_serial *serial); +static int edge_port_probe(struct usb_serial_port *port); +static int edge_port_remove(struct usb_serial_port *port); #include "io_tables.h" /* all of the devices that this driver supports */ @@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial) static int edge_startup(struct usb_serial *serial) { struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; struct usb_device *dev; struct device *ddev = &serial->dev->dev; - int i, j; + int i; int response; bool interrupt_in_found; bool bulk_in_found; @@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial) /* we set up the pointers to the endpoints in the edge_open function, * as the structures aren't created yet. */ - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(ddev, "%s - Out of memory\n", __func__); - for (j = 0; j < i; ++j) { - kfree(usb_get_serial_port_data(serial->port[j])); - usb_set_serial_port_data(serial->port[j], - NULL); - } - usb_set_serial_data(serial, NULL); - kfree(edge_serial); - return -ENOMEM; - } - spin_lock_init(&edge_port->ep_lock); - edge_port->port = serial->port[i]; - usb_set_serial_port_data(serial->port[i], edge_port); - } - response = 0; if (edge_serial->is_epic) { @@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial) static void edge_release(struct usb_serial *serial) { struct edgeport_serial *edge_serial = usb_get_serial_data(serial); - int i; - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); kfree(edge_serial); } +static int edge_port_probe(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + if (!edge_port) + return -ENOMEM; + + spin_lock_init(&edge_port->ep_lock); + edge_port->port = port; + + usb_set_serial_port_data(port, edge_port); + + return 0; +} + +static int edge_port_remove(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = usb_get_serial_port_data(port); + kfree(edge_port); + + return 0; +} + module_usb_serial_driver(serial_drivers, id_table_combined); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 350afddb55b..1511dd0ad32 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, -- cgit v1.2.3-70-g09d2 From 3124d1d71d3df59d40b913b5481df58099e811d1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:34:56 +0200 Subject: USB: f81232: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/f81232.c | 43 +++++++++++++++++-------------------------- 1 file changed, 17 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 244477107e2..6e4eb57d017 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } -static int f81232_startup(struct usb_serial *serial) +static int f81232_port_probe(struct usb_serial_port *port) { struct f81232_private *priv; - int i; - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[i], priv); - } - return 0; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + + return 0; } -static void f81232_release(struct usb_serial *serial) +static int f81232_port_remove(struct usb_serial_port *port) { - int i; struct f81232_private *priv; - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static struct usb_serial_driver f81232_device = { @@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = { .tiocmset = f81232_tiocmset, .process_read_urb = f81232_process_read_urb, .read_int_callback = f81232_read_int_callback, - .attach = f81232_startup, - .release = f81232_release, + .port_probe = f81232_port_probe, + .port_remove = f81232_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3-70-g09d2 From 94ab71ce288921490ca857e25ad174e1921b1e29 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:35:00 +0200 Subject: USB: keyspan_pda: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the write waitqueue was initialised but never used. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/keyspan_pda.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ca43ecb4a2b..bb87e29c4ac 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); #endif -static int keyspan_pda_startup(struct usb_serial *serial) +static int keyspan_pda_port_probe(struct usb_serial_port *port) { struct keyspan_pda_private *priv; - /* allocate the private data structures for all ports. Well, for all - one ports. */ - priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); if (!priv) - return 1; /* error */ - usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port[0]->write_wait); + return -ENOMEM; + INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); - priv->serial = serial; - priv->port = serial->port[0]; + priv->serial = port->serial; + priv->port = port; + + usb_set_serial_port_data(port, priv); + return 0; } -static void keyspan_pda_release(struct usb_serial *serial) +static int keyspan_pda_port_remove(struct usb_serial_port *port) { - kfree(usb_get_serial_port_data(serial->port[0])); + struct keyspan_pda_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } #ifdef KEYSPAN @@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = { .break_ctl = keyspan_pda_break_ctl, .tiocmget = keyspan_pda_tiocmget, .tiocmset = keyspan_pda_tiocmset, - .attach = keyspan_pda_startup, - .release = keyspan_pda_release, + .port_probe = keyspan_pda_port_probe, + .port_remove = keyspan_pda_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3-70-g09d2 From 003615302a16579531932576bcd9582ddeba9018 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:34:58 +0200 Subject: USB: io_ti: fix port-data memory leak Fix port-data memory leak by moving port data allocation and deallocation to port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 91 +++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index a2209cd4509..9ae65d679f0 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state) static int edge_startup(struct usb_serial *serial) { struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - struct usb_device *dev; int status; - int i; - - dev = serial->dev; /* create our private serial structure */ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); @@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial) return status; } - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - goto cleanup; - } - spin_lock_init(&edge_port->ep_lock); - if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - kfree(edge_port); - goto cleanup; - } - edge_port->port = serial->port[i]; - edge_port->edge_serial = edge_serial; - usb_set_serial_port_data(serial->port[i], edge_port); - edge_port->bUartMode = default_uart_mode; - } - return 0; - -cleanup: - for (--i; i >= 0; --i) { - edge_port = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&edge_port->write_fifo); - kfree(edge_port); - usb_set_serial_port_data(serial->port[i], NULL); - } - kfree(edge_serial); - usb_set_serial_data(serial, NULL); - return -ENOMEM; } static void edge_disconnect(struct usb_serial *serial) @@ -2597,17 +2559,54 @@ static void edge_disconnect(struct usb_serial *serial) static void edge_release(struct usb_serial *serial) { - int i; + kfree(usb_get_serial_data(serial)); +} + +static int edge_port_probe(struct usb_serial_port *port) +{ struct edgeport_port *edge_port; + int ret; - for (i = 0; i < serial->num_ports; ++i) { - edge_port = usb_get_serial_port_data(serial->port[i]); + edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + if (!edge_port) + return -ENOMEM; + + ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, + GFP_KERNEL); + if (ret) { + kfree(edge_port); + return -ENOMEM; + } + + ret = edge_create_sysfs_attrs(port); + if (ret) { kfifo_free(&edge_port->write_fifo); kfree(edge_port); + return ret; } - kfree(usb_get_serial_data(serial)); + + spin_lock_init(&edge_port->ep_lock); + edge_port->port = port; + edge_port->edge_serial = usb_get_serial_data(port->serial); + edge_port->bUartMode = default_uart_mode; + + usb_set_serial_port_data(port, edge_port); + + return 0; } +static int edge_port_remove(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = usb_get_serial_port_data(port); + + edge_remove_sysfs_attrs(port); + kfifo_free(&edge_port->write_fifo); + kfree(edge_port); + + return 0; +} /* Sysfs Attributes */ @@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, -- cgit v1.2.3-70-g09d2 From 99a6f73c495c420df826e5b267fb073fd6766fc3 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:35:01 +0200 Subject: USB: kl5kusb105: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Note that the write waitqueue was initialised but never used. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/kl5kusb105.c | 68 +++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 3f6d7376c02..1f4517864cd 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -60,8 +60,8 @@ /* * Function prototypes */ -static int klsi_105_startup(struct usb_serial *serial); -static void klsi_105_release(struct usb_serial *serial); +static int klsi_105_port_probe(struct usb_serial_port *port); +static int klsi_105_port_remove(struct usb_serial_port *port); static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); static void klsi_105_close(struct usb_serial_port *port); static void klsi_105_set_termios(struct tty_struct *tty, @@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = { /*.break_ctl = klsi_105_break_ctl,*/ .tiocmget = klsi_105_tiocmget, .tiocmset = klsi_105_tiocmset, - .attach = klsi_105_startup, - .release = klsi_105_release, + .port_probe = klsi_105_port_probe, + .port_remove = klsi_105_port_remove, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, .process_read_urb = klsi_105_process_read_urb, @@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, * Driver's tty interface functions */ -static int klsi_105_startup(struct usb_serial *serial) +static int klsi_105_port_probe(struct usb_serial_port *port) { struct klsi_105_private *priv; - int i; - /* check if we support the product id (see keyspan.c) - * FIXME - */ + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; - /* allocate the private data structure */ - for (i = 0; i < serial->num_ports; i++) { - priv = kmalloc(sizeof(struct klsi_105_private), - GFP_KERNEL); - if (!priv) { - dev_dbg(&serial->interface->dev, - "%s - kmalloc for klsi_105_private failed.\n", - __func__); - i--; - goto err_cleanup; - } - /* set initial values for control structures */ - priv->cfg.pktlen = 5; - priv->cfg.baudrate = kl5kusb105a_sio_b9600; - priv->cfg.databits = kl5kusb105a_dtb_8; - priv->cfg.unknown1 = 0; - priv->cfg.unknown2 = 1; + /* set initial values for control structures */ + priv->cfg.pktlen = 5; + priv->cfg.baudrate = kl5kusb105a_sio_b9600; + priv->cfg.databits = kl5kusb105a_dtb_8; + priv->cfg.unknown1 = 0; + priv->cfg.unknown2 = 1; - priv->line_state = 0; + priv->line_state = 0; - usb_set_serial_port_data(serial->port[i], priv); + spin_lock_init(&priv->lock); - spin_lock_init(&priv->lock); + /* priv->termios is left uninitialized until port opening */ - /* priv->termios is left uninitialized until port opening */ - init_waitqueue_head(&serial->port[i]->write_wait); - } + usb_set_serial_port_data(port, priv); return 0; - -err_cleanup: - for (; i >= 0; i--) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; } -static void klsi_105_release(struct usb_serial *serial) +static int klsi_105_port_remove(struct usb_serial_port *port) { - int i; + struct klsi_105_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + return 0; } static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) -- cgit v1.2.3-70-g09d2 From 53636555b9190f88320d9d46cf142f8797895456 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 13:34:59 +0200 Subject: USB: iuu_phoenix: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/iuu_phoenix.c | 62 ++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 01da3ea36e8..959f71e31dc 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -72,63 +72,45 @@ struct iuu_private { u32 clk; }; - -static void iuu_free_buf(struct iuu_private *priv) -{ - kfree(priv->buf); - kfree(priv->writebuf); -} - -static int iuu_alloc_buf(struct usb_serial *serial, struct iuu_private *priv) -{ - priv->buf = kzalloc(256, GFP_KERNEL); - priv->writebuf = kzalloc(256, GFP_KERNEL); - if (!priv->buf || !priv->writebuf) { - iuu_free_buf(priv); - dev_dbg(&serial->dev->dev, "%s problem allocation buffer\n", __func__); - return -ENOMEM; - } - dev_dbg(&serial->dev->dev, "%s - Privates buffers allocation success\n", __func__); - return 0; -} - -static int iuu_startup(struct usb_serial *serial) +static int iuu_port_probe(struct usb_serial_port *port) { struct iuu_private *priv; priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); - dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__); if (!priv) return -ENOMEM; - if (iuu_alloc_buf(serial, priv)) { + + priv->buf = kzalloc(256, GFP_KERNEL); + if (!priv->buf) { kfree(priv); return -ENOMEM; } + + priv->writebuf = kzalloc(256, GFP_KERNEL); + if (!priv->writebuf) { + kfree(priv->buf); + kfree(priv); + return -ENOMEM; + } + priv->vcc = vcc_default; spin_lock_init(&priv->lock); init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[0], priv); + + usb_set_serial_port_data(port, priv); + return 0; } -/* Release function */ -static void iuu_release(struct usb_serial *serial) +static int iuu_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct iuu_private *priv = usb_get_serial_port_data(port); - if (!port) - return; - - if (priv) { - iuu_free_buf(priv); - dev_dbg(&port->dev, "%s - I will free all\n", __func__); - usb_set_serial_port_data(port, NULL); - dev_dbg(&port->dev, "%s - priv is not anymore in port structure\n", __func__); - kfree(priv); + kfree(priv->writebuf); + kfree(priv->buf); + kfree(priv); - dev_dbg(&port->dev, "%s priv is now kfree\n", __func__); - } + return 0; } static int iuu_tiocmset(struct tty_struct *tty, @@ -1225,8 +1207,8 @@ static struct usb_serial_driver iuu_device = { .tiocmset = iuu_tiocmset, .set_termios = iuu_set_termios, .init_termios = iuu_init_termios, - .attach = iuu_startup, - .release = iuu_release, + .port_probe = iuu_port_probe, + .port_remove = iuu_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { -- cgit v1.2.3-70-g09d2 From 289b076f89c2c3260e914dad18ae12f193ea86d5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 16:31:32 +0200 Subject: USB: oti6858: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/oti6858.c | 68 ++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 933241f03fd..cee9a52ca89 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int oti6858_startup(struct usb_serial *serial); -static void oti6858_release(struct usb_serial *serial); +static int oti6858_port_probe(struct usb_serial_port *port); +static int oti6858_port_remove(struct usb_serial_port *port); /* device info */ static struct usb_serial_driver oti6858_device = { @@ -161,8 +161,8 @@ static struct usb_serial_driver oti6858_device = { .write_bulk_callback = oti6858_write_bulk_callback, .write_room = oti6858_write_room, .chars_in_buffer = oti6858_chars_in_buffer, - .attach = oti6858_startup, - .release = oti6858_release, + .port_probe = oti6858_port_probe, + .port_remove = oti6858_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -331,36 +331,33 @@ static void send_data(struct work_struct *work) usb_serial_port_softint(port); } -static int oti6858_startup(struct usb_serial *serial) +static int oti6858_port_probe(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct oti6858_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); - if (!priv) - break; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->intr_wait); -/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ -/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ - priv->port = port; - INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); - INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); - - usb_set_serial_port_data(serial->port[i], priv); - } - if (i == serial->num_ports) - return 0; - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->intr_wait); + priv->port = port; + INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); + INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); + + usb_set_serial_port_data(port, priv); + + return 0; +} + +static int oti6858_port_remove(struct usb_serial_port *port) +{ + struct oti6858_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } - -static void oti6858_release(struct usb_serial *serial) -{ - int i; - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - static void oti6858_read_int_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; -- cgit v1.2.3-70-g09d2 From 51ef847df74632e7cfdf952afc3887de105b8b35 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 16:31:35 +0200 Subject: USB: ti_usb_3410_5052: fix port-data memory leak Fix port-data memory leak by moving port data allocation and deallocation to port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ti_usb_3410_5052.c | 88 +++++++++++++++++------------------ 1 file changed, 43 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 6f49392cda5..f2530d2ef3c 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -97,6 +97,8 @@ struct ti_device { static int ti_startup(struct usb_serial *serial); static void ti_release(struct usb_serial *serial); +static int ti_port_probe(struct usb_serial_port *port); +static int ti_port_remove(struct usb_serial_port *port); static int ti_open(struct tty_struct *tty, struct usb_serial_port *port); static void ti_close(struct usb_serial_port *port); static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = { .num_ports = 1, .attach = ti_startup, .release = ti_release, + .port_probe = ti_port_probe, + .port_remove = ti_port_remove, .open = ti_open, .close = ti_close, .write = ti_write, @@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = { .num_ports = 2, .attach = ti_startup, .release = ti_release, + .port_probe = ti_port_probe, + .port_remove = ti_port_remove, .open = ti_open, .close = ti_close, .write = ti_write, @@ -347,11 +353,8 @@ module_exit(ti_exit); static int ti_startup(struct usb_serial *serial) { struct ti_device *tdev; - struct ti_port *tport; struct usb_device *dev = serial->dev; int status; - int i; - dev_dbg(&dev->dev, "%s - product 0x%4X, num configurations %d, configuration value %d", @@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial) goto free_tdev; } - /* set up port structures */ - for (i = 0; i < serial->num_ports; ++i) { - tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); - if (tport == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - status = -ENOMEM; - goto free_tports; - } - spin_lock_init(&tport->tp_lock); - tport->tp_uart_base_addr = (i == 0 ? - TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); - tport->tp_closing_wait = closing_wait; - init_waitqueue_head(&tport->tp_msr_wait); - init_waitqueue_head(&tport->tp_write_wait); - if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - kfree(tport); - status = -ENOMEM; - goto free_tports; - } - tport->tp_port = serial->port[i]; - tport->tp_tdev = tdev; - usb_set_serial_port_data(serial->port[i], tport); - tport->tp_uart_mode = 0; /* default is RS232 */ - } - return 0; -free_tports: - for (--i; i >= 0; --i) { - tport = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&tport->write_fifo); - kfree(tport); - usb_set_serial_port_data(serial->port[i], NULL); - } free_tdev: kfree(tdev); usb_set_serial_data(serial, NULL); @@ -444,21 +413,50 @@ free_tdev: static void ti_release(struct usb_serial *serial) { - int i; struct ti_device *tdev = usb_get_serial_data(serial); + + kfree(tdev); +} + +static int ti_port_probe(struct usb_serial_port *port) +{ struct ti_port *tport; - for (i = 0; i < serial->num_ports; ++i) { - tport = usb_get_serial_port_data(serial->port[i]); - if (tport) { - kfifo_free(&tport->write_fifo); - kfree(tport); - } + tport = kzalloc(sizeof(*tport), GFP_KERNEL); + if (!tport) + return -ENOMEM; + + spin_lock_init(&tport->tp_lock); + if (port == port->serial->port[0]) + tport->tp_uart_base_addr = TI_UART1_BASE_ADDR; + else + tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; + tport->tp_closing_wait = closing_wait; + init_waitqueue_head(&tport->tp_msr_wait); + init_waitqueue_head(&tport->tp_write_wait); + if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { + kfree(tport); + return -ENOMEM; } + tport->tp_port = port; + tport->tp_tdev = usb_get_serial_data(port->serial); + tport->tp_uart_mode = 0; /* default is RS232 */ - kfree(tdev); + usb_set_serial_port_data(port, tport); + + return 0; } +static int ti_port_remove(struct usb_serial_port *port) +{ + struct ti_port *tport; + + tport = usb_get_serial_port_data(port); + kfifo_free(&tport->write_fifo); + kfree(tport); + + return 0; +} static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) { -- cgit v1.2.3-70-g09d2 From 638b9e15233c9570bce65301aa9877235316b9f0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 16:31:34 +0200 Subject: USB: ssu100: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ssu100.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 015810b3785..868d1e6852e 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -67,13 +67,6 @@ struct ssu100_port_private { struct async_icount icount; }; -static void ssu100_release(struct usb_serial *serial) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port); - - kfree(priv); -} - static inline int ssu100_control_msg(struct usb_device *dev, u8 request, u16 data, u16 index) { @@ -441,22 +434,34 @@ static int ssu100_ioctl(struct tty_struct *tty, } static int ssu100_attach(struct usb_serial *serial) +{ + return ssu100_initdevice(serial->dev); +} + +static int ssu100_port_probe(struct usb_serial_port *port) { struct ssu100_port_private *priv; - struct usb_serial_port *port = *serial->port; priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, - sizeof(*priv)); + if (!priv) return -ENOMEM; - } spin_lock_init(&priv->status_lock); init_waitqueue_head(&priv->delta_msr_wait); + usb_set_serial_port_data(port, priv); - return ssu100_initdevice(serial->dev); + return 0; +} + +static int ssu100_port_remove(struct usb_serial_port *port) +{ + struct ssu100_port_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int ssu100_tiocmget(struct tty_struct *tty) @@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = { .open = ssu100_open, .close = ssu100_close, .attach = ssu100_attach, - .release = ssu100_release, + .port_probe = ssu100_port_probe, + .port_remove = ssu100_port_remove, .dtr_rts = ssu100_dtr_rts, .process_read_urb = ssu100_process_read_urb, .tiocmget = ssu100_tiocmget, -- cgit v1.2.3-70-g09d2 From bf90ff5f3b8f67e5b42df4ea4fd543f8010a2676 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 17 Oct 2012 16:31:33 +0200 Subject: USB: spcp8x5: fix port-data memory leak Fix port-data memory leak by replacing attach and release with port_probe and port_remove. Since commit 0998d0631001288 (device-core: Ensure drvdata = NULL when no driver is bound) the port private data is no longer freed at release as it is no longer accessible. Compile-only tested. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/spcp8x5.c | 46 +++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 9716efe9295..769c137f897 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -157,13 +157,10 @@ struct spcp8x5_private { u8 line_status; }; -/* desc : when device plug in,this function would be called. - * thanks to usb_serial subsystem,then do almost every things for us. And what - * we should do just alloc the buffer */ -static int spcp8x5_startup(struct usb_serial *serial) +static int spcp8x5_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct spcp8x5_private *priv; - int i; enum spcp8x5_type type = SPCP825_007_TYPE; u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); @@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial) type = SPCP825_PHILIP_TYPE; dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); - if (!priv) - goto cleanup; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i] , priv); - } + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + priv->type = type; + + usb_set_serial_port_data(port , priv); return 0; -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i] , NULL); - } - return -ENOMEM; } -/* call when the device plug out. free all the memory alloced by probe */ -static void spcp8x5_release(struct usb_serial *serial) +static int spcp8x5_port_remove(struct usb_serial_port *port) { - int i; + struct spcp8x5_private *priv; - for (i = 0; i < serial->num_ports; i++) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } /* set the modem control line of the device. @@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = { .ioctl = spcp8x5_ioctl, .tiocmget = spcp8x5_tiocmget, .tiocmset = spcp8x5_tiocmset, - .attach = spcp8x5_startup, - .release = spcp8x5_release, + .port_probe = spcp8x5_port_probe, + .port_remove = spcp8x5_port_remove, .process_read_urb = spcp8x5_process_read_urb, }; -- cgit v1.2.3-70-g09d2 From 0978c9499944d0670338fd048a3bdb1624dc66dc Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 18 Oct 2012 10:52:17 +0200 Subject: USB: iuu_phoenix: fix sysfs-attribute creation Make sure sysfs attributes are created at port probe. A recent patch ("USB: iuu_phoenix: fix port-data memory leak") removed the sysfs-attribute creation by mistake. Reported-by: Yuanhan Liu Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/iuu_phoenix.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 959f71e31dc..cd5533e81de 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -53,6 +53,8 @@ static int iuu_cardout; static bool xmas; static int vcc_default = 5; +static int iuu_create_sysfs_attrs(struct usb_serial_port *port); +static int iuu_remove_sysfs_attrs(struct usb_serial_port *port); static void read_rxcmd_callback(struct urb *urb); struct iuu_private { @@ -75,6 +77,7 @@ struct iuu_private { static int iuu_port_probe(struct usb_serial_port *port) { struct iuu_private *priv; + int ret; priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); if (!priv) @@ -99,6 +102,14 @@ static int iuu_port_probe(struct usb_serial_port *port) usb_set_serial_port_data(port, priv); + ret = iuu_create_sysfs_attrs(port); + if (ret) { + kfree(priv->writebuf); + kfree(priv->buf); + kfree(priv); + return ret; + } + return 0; } @@ -106,6 +117,7 @@ static int iuu_port_remove(struct usb_serial_port *port) { struct iuu_private *priv = usb_get_serial_port_data(port); + iuu_remove_sysfs_attrs(port); kfree(priv->writebuf); kfree(priv->buf); kfree(priv); @@ -1197,8 +1209,6 @@ static struct usb_serial_driver iuu_device = { .num_ports = 1, .bulk_in_size = 512, .bulk_out_size = 512, - .port_probe = iuu_create_sysfs_attrs, - .port_remove = iuu_remove_sysfs_attrs, .open = iuu_open, .close = iuu_close, .write = iuu_uart_write, -- cgit v1.2.3-70-g09d2 From 5d8c61bc283826827e1f06816c146bfc507d3834 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 18 Oct 2012 11:43:28 +0200 Subject: USB: io_ti: fix sysfs-attribute creation Make sure port data is initialised before creating sysfs attributes to avoid a race. A recent patch ("USB: io_ti: fix port-data memory leak") got the sysfs-attribute creation and port-data initialisation ordering wrong. Cc: Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 9ae65d679f0..60023c2d2a3 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2578,13 +2578,6 @@ static int edge_port_probe(struct usb_serial_port *port) return -ENOMEM; } - ret = edge_create_sysfs_attrs(port); - if (ret) { - kfifo_free(&edge_port->write_fifo); - kfree(edge_port); - return ret; - } - spin_lock_init(&edge_port->ep_lock); edge_port->port = port; edge_port->edge_serial = usb_get_serial_data(port->serial); @@ -2592,6 +2585,13 @@ static int edge_port_probe(struct usb_serial_port *port) usb_set_serial_port_data(port, edge_port); + ret = edge_create_sysfs_attrs(port); + if (ret) { + kfifo_free(&edge_port->write_fifo); + kfree(edge_port); + return ret; + } + return 0; } -- cgit v1.2.3-70-g09d2 From 470809741a28c3092279f4e1f3f432e534d46068 Mon Sep 17 00:00:00 2001 From: "Alexis R. Cortes" Date: Wed, 17 Oct 2012 14:09:12 -0500 Subject: usb: host: xhci: New system added for Compliance Mode Patch on SN65LVPE502CP This minor change adds a new system to which the "Fix Compliance Mode on SN65LVPE502CP Hardware" patch has to be applied also. System added: Vendor: Hewlett-Packard. System Model: Z1 Signed-off-by: Alexis R. Cortes Acked-by: Sarah Sharp Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d7fcbbe6ad..7d462bf2009 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) if (strstr(dmi_product_name, "Z420") || strstr(dmi_product_name, "Z620") || - strstr(dmi_product_name, "Z820")) + strstr(dmi_product_name, "Z820") || + strstr(dmi_product_name, "Z1")) return true; return false; -- cgit v1.2.3-70-g09d2 From 1452df6f1b7e396d89c2a1fdbdc0e0e839f97671 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 18 Oct 2012 17:19:53 +0200 Subject: USB: option: blacklist net interface on ZTE devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on information from the ZTE Windows drivers. Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 68 ++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 30cff03e9f0..7e46894d784 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -503,11 +503,19 @@ static const struct option_blacklist_info net_intf5_blacklist = { .reserved = BIT(5), }; +static const struct option_blacklist_info net_intf6_blacklist = { + .reserved = BIT(6), +}; + static const struct option_blacklist_info zte_mf626_blacklist = { .sendsetup = BIT(0) | BIT(1), .reserved = BIT(4), }; +static const struct option_blacklist_info zte_1255_blacklist = { + .reserved = BIT(3) | BIT(4), +}; + static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -853,13 +861,19 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, @@ -872,7 +886,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, @@ -886,7 +901,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1002,18 +1018,24 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, @@ -1071,15 +1093,21 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, -- cgit v1.2.3-70-g09d2 From 4b35f1c52943851b310afb09047bfe991ac8f5ae Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 18 Oct 2012 17:14:17 +0200 Subject: USB: option: add more ZTE devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7e46894d784..54d4148d01d 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -895,6 +895,12 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), @@ -903,6 +909,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1080,8 +1088,16 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, -- cgit v1.2.3-70-g09d2