From a7ee4b448513641bf143239c0a397037dcbd2904 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Fri, 17 Jul 2020 20:51:18 +0200 Subject: USB: serial: qcserial: add EM7305 QDL product ID commit d2a4309c1ab6df424b2239fe2920d6f26f808d17 upstream. When running qmi-firmware-update on the Sierra Wireless EM7305 in a Toshiba laptop, it changed product ID to 0x9062 when entering QDL mode: usb 2-4: new high-speed USB device number 78 using xhci_hcd usb 2-4: New USB device found, idVendor=1199, idProduct=9062, bcdDevice= 0.00 usb 2-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 2-4: Product: EM7305 usb 2-4: Manufacturer: Sierra Wireless, Incorporated The upgrade could complete after running # echo 1199 9062 > /sys/bus/usb-serial/drivers/qcserial/new_id qcserial 2-4:1.0: Qualcomm USB modem converter detected usb 2-4: Qualcomm USB modem converter now attached to ttyUSB0 Signed-off-by: Erik Ekman Link: https://lore.kernel.org/r/20200717185118.3640219-1-erik@kryo.se Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index d147feae83e6..0f60363c1bbc 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -155,6 +155,7 @@ static const struct usb_device_id id_table[] = { {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */ {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */ {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */ + {DEVICE_SWI(0x1199, 0x9062)}, /* Sierra Wireless EM7305 QDL */ {DEVICE_SWI(0x1199, 0x9063)}, /* Sierra Wireless EM7305 */ {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */ {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */ -- cgit v1.2.3 From 3d73faca68faf89f515e3a8e3a1019ca426cf683 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 26 Jul 2020 11:49:39 +0200 Subject: USB: iowarrior: fix up report size handling for some devices commit 17a82716587e9d7c3b246a789add490b2b5dcab6 upstream. In previous patches that added support for new iowarrior devices, the handling of the report size was not done correct. Fix that up and update the copyright date for the driver Reworked from an original patch written by Christoph Jung. Fixes: bab5417f5f01 ("USB: misc: iowarrior: add support for the 100 device") Fixes: 5f6f8da2d7b5 ("USB: misc: iowarrior: add support for the 28 and 28L devices") Fixes: 461d8deb26a7 ("USB: misc: iowarrior: add support for 2 OEMed devices") Cc: stable Reported-by: Christoph Jung Link: https://lore.kernel.org/r/20200726094939.1268978-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/iowarrior.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index dce20301e367..103c69c692ba 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -2,8 +2,9 @@ /* * Native support for the I/O-Warrior USB devices * - * Copyright (c) 2003-2005 Code Mercenaries GmbH - * written by Christian Lucht + * Copyright (c) 2003-2005, 2020 Code Mercenaries GmbH + * written by Christian Lucht and + * Christoph Jung * * based on @@ -802,14 +803,28 @@ static int iowarrior_probe(struct usb_interface *interface, /* we have to check the report_size often, so remember it in the endianness suitable for our machine */ dev->report_size = usb_endpoint_maxp(dev->int_in_endpoint); - if ((dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) && - ((dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56) || - (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW56AM) || - (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW28) || - (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW28L) || - (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW100))) - /* IOWarrior56 has wMaxPacketSize different from report size */ - dev->report_size = 7; + + /* + * Some devices need the report size to be different than the + * endpoint size. + */ + if (dev->interface->cur_altsetting->desc.bInterfaceNumber == 0) { + switch (dev->product_id) { + case USB_DEVICE_ID_CODEMERCS_IOW56: + case USB_DEVICE_ID_CODEMERCS_IOW56AM: + dev->report_size = 7; + break; + + case USB_DEVICE_ID_CODEMERCS_IOW28: + case USB_DEVICE_ID_CODEMERCS_IOW28L: + dev->report_size = 4; + break; + + case USB_DEVICE_ID_CODEMERCS_IOW100: + dev->report_size = 13; + break; + } + } /* create the urb and buffer for reading */ dev->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); -- cgit v1.2.3 From 2ef10b5be9a54817aa49d4610acb60e31233ae11 Mon Sep 17 00:00:00 2001 From: Forest Crossman Date: Mon, 27 Jul 2020 23:24:07 -0500 Subject: usb: xhci: define IDs for various ASMedia host controllers commit 1841cb255da41e87bed9573915891d056f80e2e7 upstream. Not all ASMedia host controllers have a device ID that matches its part number. #define some of these IDs to make it clearer at a glance which chips require what quirks. Acked-by: Mathias Nyman Signed-off-by: Forest Crossman Link: https://lore.kernel.org/r/20200728042408.180529-2-cyrozap@gmail.com Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 9234c82e70e4..baa5af88ca67 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -57,7 +57,9 @@ #define PCI_DEVICE_ID_AMD_PROMONTORYA_3 0x43ba #define PCI_DEVICE_ID_AMD_PROMONTORYA_2 0x43bb #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc +#define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 +#define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 static const char hcd_name[] = "xhci_hcd"; @@ -260,13 +262,13 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_LPM_SUPPORT; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == 0x1042) + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) xhci->quirks |= XHCI_BROKEN_STREAMS; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == 0x1142) + pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) xhci->quirks |= XHCI_TRUST_TX_LENGTH; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == 0x2142) + pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI) xhci->quirks |= XHCI_NO_64BIT_SUPPORT; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && -- cgit v1.2.3 From a7e7da4400925c04474bf8f2e0e5d517e0bfb18e Mon Sep 17 00:00:00 2001 From: Forest Crossman Date: Mon, 27 Jul 2020 23:24:08 -0500 Subject: usb: xhci: Fix ASMedia ASM1142 DMA addressing commit ec37198acca7b4c17b96247697406e47aafe0605 upstream. I've confirmed that the ASMedia ASM1142 has the same problem as the ASM2142/ASM3142, in that it too reports that it supports 64-bit DMA addresses when in fact it does not. As with the ASM2142/ASM3142, this can cause problems on systems where the upper bits matter, and adding the XHCI_NO_64BIT_SUPPORT quirk completely fixes the issue. Acked-by: Mathias Nyman Signed-off-by: Forest Crossman Cc: stable Link: https://lore.kernel.org/r/20200728042408.180529-3-cyrozap@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index baa5af88ca67..3feaafebfe58 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -59,6 +59,7 @@ #define PCI_DEVICE_ID_AMD_PROMONTORYA_1 0x43bc #define PCI_DEVICE_ID_ASMEDIA_1042_XHCI 0x1042 #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 +#define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 static const char hcd_name[] = "xhci_hcd"; @@ -268,7 +269,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) xhci->quirks |= XHCI_TRUST_TX_LENGTH; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && - pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI) + (pdev->device == PCI_DEVICE_ID_ASMEDIA_1142_XHCI || + pdev->device == PCI_DEVICE_ID_ASMEDIA_2142_XHCI)) xhci->quirks |= XHCI_NO_64BIT_SUPPORT; if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && -- cgit v1.2.3 From f2ea1e1877d02f7605a1cf1ecaf03aa0db8a85ee Mon Sep 17 00:00:00 2001 From: Chunfeng Yun Date: Mon, 27 Jul 2020 15:14:59 +0800 Subject: usb: mtu3: clear dual mode of u3port when disable device [ Upstream commit f1e51e99ed498d4aa9ae5df28e43d558ea627781 ] If not clear u3port's dual mode when disable device, the IP will fail to enter sleep mode when suspend. Signed-off-by: Chunfeng Yun Link: https://lore.kernel.org/r/1595834101-13094-10-git-send-email-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/mtu3/mtu3_core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index 9dd02160cca9..e3780d4d6514 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -131,8 +131,12 @@ static void mtu3_device_disable(struct mtu3 *mtu) mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN); - if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) + if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) { mtu3_clrbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL); + if (mtu->is_u3_ip) + mtu3_clrbits(ibase, SSUSB_U3_CTRL(0), + SSUSB_U3_PORT_DUAL_MODE); + } mtu3_setbits(ibase, U3D_SSUSB_IP_PW_CTRL2, SSUSB_IP_DEV_PDN); } -- cgit v1.2.3 From 7677cbd18b99568993e79941c3d2e272db970a7d Mon Sep 17 00:00:00 2001 From: Evgeny Novikov Date: Tue, 21 Jul 2020 23:15:58 +0300 Subject: usb: gadget: net2280: fix memory leak on probe error handling paths [ Upstream commit 2468c877da428ebfd701142c4cdfefcfb7d4c00e ] Driver does not release memory for device on error handling paths in net2280_probe() when gadget_release() is not registered yet. The patch fixes the bug like in other similar drivers. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Evgeny Novikov Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/net2280.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 5eff85eeaa5a..7530bd9a08c4 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -3781,8 +3781,10 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; done: - if (dev) + if (dev) { net2280_remove(pdev); + kfree(dev); + } return retval; } -- cgit v1.2.3 From 8415df3d6eb1ad078c70c3838a650f7b612f27ba Mon Sep 17 00:00:00 2001 From: Sasi Kumar Date: Wed, 22 Jul 2020 13:07:42 -0400 Subject: bdc: Fix bug causing crash after multiple disconnects [ Upstream commit a95bdfd22076497288868c028619bc5995f5cc7f ] Multiple connects/disconnects can cause a crash on the second disconnect. The driver had a problem where it would try to send endpoint commands after it was disconnected which is not allowed by the hardware. The fix is to only allow the endpoint commands when the endpoint is connected. This will also fix issues that showed up when using configfs to create gadgets. Signed-off-by: Sasi Kumar Signed-off-by: Al Cooper Acked-by: Florian Fainelli Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/bdc/bdc_core.c | 4 ++++ drivers/usb/gadget/udc/bdc/bdc_ep.c | 16 ++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index 02a3a774670b..5fde5a8b065c 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -282,6 +282,7 @@ static void bdc_mem_init(struct bdc *bdc, bool reinit) * in that case reinit is passed as 1 */ if (reinit) { + int i; /* Enable interrupts */ temp = bdc_readl(bdc->regs, BDC_BDCSC); temp |= BDC_GIE; @@ -291,6 +292,9 @@ static void bdc_mem_init(struct bdc *bdc, bool reinit) /* Initialize SRR to 0 */ memset(bdc->srr.sr_bds, 0, NUM_SR_ENTRIES * sizeof(struct bdc_bd)); + /* clear ep flags to avoid post disconnect stops/deconfigs */ + for (i = 1; i < bdc->num_eps; ++i) + bdc->bdc_ep_array[i]->flags = 0; } else { /* One time initiaization only */ /* Enable status report function pointers */ diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index d49c6dc1082d..9ddc0b4e92c9 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -615,7 +615,6 @@ int bdc_ep_enable(struct bdc_ep *ep) } bdc_dbg_bd_list(bdc, ep); /* only for ep0: config ep is called for ep0 from connect event */ - ep->flags |= BDC_EP_ENABLED; if (ep->ep_num == 1) return ret; @@ -759,10 +758,13 @@ static int ep_dequeue(struct bdc_ep *ep, struct bdc_req *req) __func__, ep->name, start_bdi, end_bdi); dev_dbg(bdc->dev, "ep_dequeue ep=%p ep->desc=%p\n", ep, (void *)ep->usb_ep.desc); - /* Stop the ep to see where the HW is ? */ - ret = bdc_stop_ep(bdc, ep->ep_num); - /* if there is an issue with stopping ep, then no need to go further */ - if (ret) + /* if still connected, stop the ep to see where the HW is ? */ + if (!(bdc_readl(bdc->regs, BDC_USPC) & BDC_PST_MASK)) { + ret = bdc_stop_ep(bdc, ep->ep_num); + /* if there is an issue, then no need to go further */ + if (ret) + return 0; + } else return 0; /* @@ -1911,7 +1913,9 @@ static int bdc_gadget_ep_disable(struct usb_ep *_ep) __func__, ep->name, ep->flags); if (!(ep->flags & BDC_EP_ENABLED)) { - dev_warn(bdc->dev, "%s is already disabled\n", ep->name); + if (bdc->gadget.speed != USB_SPEED_UNKNOWN) + dev_warn(bdc->dev, "%s is already disabled\n", + ep->name); return 0; } spin_lock_irqsave(&bdc->lock, flags); -- cgit v1.2.3 From 2f92047fea41b49d906e652020861cec78f68f04 Mon Sep 17 00:00:00 2001 From: Danesh Petigara Date: Wed, 22 Jul 2020 13:07:45 -0400 Subject: usb: bdc: Halt controller on suspend [ Upstream commit 5fc453d7de3d0c345812453823a3a56783c5f82c ] GISB bus error kernel panics have been observed during S2 transition tests on the 7271t platform. The errors are a result of the BDC interrupt handler trying to access BDC register space after the system's suspend callbacks have completed. Adding a suspend hook to the BDC driver that halts the controller before S2 entry thus preventing unwanted access to the BDC register space during this transition. Signed-off-by: Danesh Petigara Signed-off-by: Al Cooper Acked-by: Florian Fainelli Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/udc/bdc/bdc_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index 5fde5a8b065c..2dca11f0a744 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -603,9 +603,14 @@ static int bdc_remove(struct platform_device *pdev) static int bdc_suspend(struct device *dev) { struct bdc *bdc = dev_get_drvdata(dev); + int ret; - clk_disable_unprepare(bdc->clk); - return 0; + /* Halt the controller */ + ret = bdc_stop(bdc); + if (!ret) + clk_disable_unprepare(bdc->clk); + + return ret; } static int bdc_resume(struct device *dev) -- cgit v1.2.3 From ef54393965e4fa9b052056fbce3d0039b3ec0357 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 16 Jul 2020 10:50:55 +0200 Subject: USB: serial: iuu_phoenix: fix led-activity helpers [ Upstream commit de37458f8c2bfc465500a1dd0d15dbe96d2a698c ] The set-led command is eight bytes long and starts with a command byte followed by six bytes of RGB data and ends with a byte encoding a frequency (see iuu_led() and iuu_rgbf_fill_buffer()). The led activity helpers had a few long-standing bugs which corrupted the command packets by inserting a second command byte and thereby offsetting the RGB data and dropping the frequency in non-xmas mode. In xmas mode, a related off-by-one error left the frequency field uninitialised. Fixes: 60a8fc017103 ("USB: add iuu_phoenix driver") Reported-by: George Spelvin Link: https://lore.kernel.org/r/20200716085056.31471-1-johan@kernel.org Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Sasha Levin --- drivers/usb/serial/iuu_phoenix.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index b8dfeb4fb2ed..ffbb2a8901b2 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -353,10 +353,11 @@ static void iuu_led_activity_on(struct urb *urb) struct usb_serial_port *port = urb->context; int result; char *buf_ptr = port->write_urb->transfer_buffer; - *buf_ptr++ = IUU_SET_LED; + if (xmas) { - get_random_bytes(buf_ptr, 6); - *(buf_ptr+7) = 1; + buf_ptr[0] = IUU_SET_LED; + get_random_bytes(buf_ptr + 1, 6); + buf_ptr[7] = 1; } else { iuu_rgbf_fill_buffer(buf_ptr, 255, 255, 0, 0, 0, 0, 255); } @@ -374,13 +375,14 @@ static void iuu_led_activity_off(struct urb *urb) struct usb_serial_port *port = urb->context; int result; char *buf_ptr = port->write_urb->transfer_buffer; + if (xmas) { iuu_rxcmd(urb); return; - } else { - *buf_ptr++ = IUU_SET_LED; - iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); } + + iuu_rgbf_fill_buffer(buf_ptr, 0, 0, 255, 255, 0, 0, 255); + usb_fill_bulk_urb(port->write_urb, port->serial->dev, usb_sndbulkpipe(port->serial->dev, port->bulk_out_endpointAddress), -- cgit v1.2.3 From 99075b81545cbad9dd7419cc6f4491a582f32417 Mon Sep 17 00:00:00 2001 From: Kars Mulder Date: Tue, 7 Jul 2020 16:43:50 +0200 Subject: usb: core: fix quirks_param_set() writing to a const pointer [ Upstream commit b1b6bed3b5036509b449b5965285d5057ba42527 ] The function quirks_param_set() takes as argument a const char* pointer to the new value of the usbcore.quirks parameter. It then casts this pointer to a non-const char* pointer and passes it to the strsep() function, which overwrites the value. Fix this by creating a copy of the value using kstrdup() and letting that copy be written to by strsep(). Fixes: 027bd6cafd9a ("usb: core: Add "quirks" parameter for usbcore") Signed-off-by: Kars Mulder Link: https://lore.kernel.org/r/5ee2-5f048a00-21-618c5c00@230659773 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- drivers/usb/core/quirks.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index e0b77674869c..c96c50faccf7 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -25,17 +25,23 @@ static unsigned int quirk_count; static char quirks_param[128]; -static int quirks_param_set(const char *val, const struct kernel_param *kp) +static int quirks_param_set(const char *value, const struct kernel_param *kp) { - char *p, *field; + char *val, *p, *field; u16 vid, pid; u32 flags; size_t i; int err; + val = kstrdup(value, GFP_KERNEL); + if (!val) + return -ENOMEM; + err = param_set_copystring(val, kp); - if (err) + if (err) { + kfree(val); return err; + } mutex_lock(&quirk_mutex); @@ -60,10 +66,11 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp) if (!quirk_list) { quirk_count = 0; mutex_unlock(&quirk_mutex); + kfree(val); return -ENOMEM; } - for (i = 0, p = (char *)val; p && *p;) { + for (i = 0, p = val; p && *p;) { /* Each entry consists of VID:PID:flags */ field = strsep(&p, ":"); if (!field) @@ -144,6 +151,7 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp) unlock: mutex_unlock(&quirk_mutex); + kfree(val); return 0; } -- cgit v1.2.3 From 816adf48d9fffde87f769812f0f4a4d81b79d026 Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Mon, 13 Jul 2020 12:05:22 -0400 Subject: usb: dwc3: meson-g12a: fix shared reset control use [ Upstream commit 7a410953d1fb4dbe91ffcfdee9cbbf889d19b0d7 ] The reset is a shared reset line, but reset_control_reset is still used and reset_control_deassert is not guaranteed to have been called before the first reset_control_assert call. When suspending the following warning may be seen: WARNING: CPU: 1 PID: 5530 at drivers/reset/core.c:355 reset_control_assert+0x184/0x19c Hardware name: Hardkernel ODROID-N2 (DT) [..] pc : reset_control_assert+0x184/0x19c lr : dwc3_meson_g12a_suspend+0x68/0x7c [..] Call trace: reset_control_assert+0x184/0x19c dwc3_meson_g12a_suspend+0x68/0x7c platform_pm_suspend+0x28/0x54 __device_suspend+0x590/0xabc dpm_suspend+0x104/0x404 dpm_suspend_start+0x84/0x1bc suspend_devices_and_enter+0xc4/0x4fc pm_suspend+0x198/0x2d4 Fixes: 6d9fa35a347a87 ("usb: dwc3: meson-g12a: get the reset as shared") Signed-off-by: Dan Robertson Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/dwc3/dwc3-meson-g12a.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index 1f7f4d88ed9d..88b75b5a039c 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -737,13 +737,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) goto err_disable_clks; } - ret = reset_control_reset(priv->reset); + ret = reset_control_deassert(priv->reset); if (ret) - goto err_disable_clks; + goto err_assert_reset; ret = dwc3_meson_g12a_get_phys(priv); if (ret) - goto err_disable_clks; + goto err_assert_reset; ret = priv->drvdata->setup_regmaps(priv, base); if (ret) @@ -752,7 +752,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) if (priv->vbus) { ret = regulator_enable(priv->vbus); if (ret) - goto err_disable_clks; + goto err_assert_reset; } /* Get dr_mode */ @@ -765,13 +765,13 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) ret = priv->drvdata->usb_init(priv); if (ret) - goto err_disable_clks; + goto err_assert_reset; /* Init PHYs */ for (i = 0 ; i < PHY_COUNT ; ++i) { ret = phy_init(priv->phys[i]); if (ret) - goto err_disable_clks; + goto err_assert_reset; } /* Set PHY Power */ @@ -809,6 +809,9 @@ err_phys_exit: for (i = 0 ; i < PHY_COUNT ; ++i) phy_exit(priv->phys[i]); +err_assert_reset: + reset_control_assert(priv->reset); + err_disable_clks: clk_bulk_disable_unprepare(priv->drvdata->num_clks, priv->drvdata->clks); -- cgit v1.2.3 From 88dcd13872b11bd60e6d4cb6317821e1d367e524 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Thu, 16 Jul 2020 14:09:48 +0200 Subject: usb: dwc2: Fix error path in gadget registration [ Upstream commit 33a06f1300a79cfd461cea0268f05e969d4f34ec ] When gadget registration fails, one should not call usb_del_gadget_udc(). Ensure this by setting gadget->udc to NULL. Also in case of a failure there is no need to disable low-level hardware, so return immiedetly instead of jumping to error_init label. This fixes the following kernel NULL ptr dereference on gadget failure (can be easily triggered with g_mass_storage without any module parameters): dwc2 12480000.hsotg: dwc2_check_params: Invalid parameter besl=1 dwc2 12480000.hsotg: dwc2_check_params: Invalid parameter g_np_tx_fifo_size=1024 dwc2 12480000.hsotg: EPs: 16, dedicated fifos, 7808 entries in SPRAM Mass Storage Function, version: 2009/09/11 LUN: removable file: (no medium) no file given for LUN0 g_mass_storage 12480000.hsotg: failed to start g_mass_storage: -22 8<--- cut here --- Unable to handle kernel NULL pointer dereference at virtual address 00000104 pgd = (ptrval) [00000104] *pgd=00000000 Internal error: Oops: 805 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 12 Comm: kworker/0:1 Not tainted 5.8.0-rc5 #3133 Hardware name: Samsung Exynos (Flattened Device Tree) Workqueue: events deferred_probe_work_func PC is at usb_del_gadget_udc+0x38/0xc4 LR is at __mutex_lock+0x31c/0xb18 ... Process kworker/0:1 (pid: 12, stack limit = 0x(ptrval)) Stack: (0xef121db0 to 0xef122000) ... [] (usb_del_gadget_udc) from [] (dwc2_hsotg_remove+0x10/0x20) [] (dwc2_hsotg_remove) from [] (dwc2_driver_probe+0x57c/0x69c) [] (dwc2_driver_probe) from [] (platform_drv_probe+0x6c/0xa4) [] (platform_drv_probe) from [] (really_probe+0x200/0x48c) [] (really_probe) from [] (driver_probe_device+0x78/0x1fc) [] (driver_probe_device) from [] (bus_for_each_drv+0x74/0xb8) [] (bus_for_each_drv) from [] (__device_attach+0xd4/0x16c) [] (__device_attach) from [] (bus_probe_device+0x88/0x90) [] (bus_probe_device) from [] (deferred_probe_work_func+0x3c/0xd0) [] (deferred_probe_work_func) from [] (process_one_work+0x234/0x7dc) [] (process_one_work) from [] (worker_thread+0x44/0x51c) [] (worker_thread) from [] (kthread+0x158/0x1a0) [] (kthread) from [] (ret_from_fork+0x14/0x20) Exception stack(0xef121fb0 to 0xef121ff8) ... ---[ end trace 9724c2fc7cc9c982 ]--- While fixing this also fix the double call to dwc2_lowlevel_hw_disable() if dr_mode is set to USB_DR_MODE_PERIPHERAL. In such case low-level hardware is already disabled before calling usb_add_gadget_udc(). That function correctly preserves low-level hardware state, there is no need for the second unconditional dwc2_lowlevel_hw_disable() call. Fixes: 207324a321a8 ("usb: dwc2: Postponed gadget registration to the udc class driver") Acked-by: Minas Harutyunyan Signed-off-by: Marek Szyprowski Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/dwc2/platform.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index cb8ddbd53718..db9fd4bd1a38 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -582,6 +582,7 @@ static int dwc2_driver_probe(struct platform_device *dev) if (hsotg->gadget_enabled) { retval = usb_add_gadget_udc(hsotg->dev, &hsotg->gadget); if (retval) { + hsotg->gadget.udc = NULL; dwc2_hsotg_remove(hsotg); goto error_init; } @@ -593,7 +594,8 @@ error_init: if (hsotg->params.activate_stm_id_vb_detection) regulator_disable(hsotg->usb33d); error: - dwc2_lowlevel_hw_disable(hsotg); + if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); return retval; } -- cgit v1.2.3 From 1bcba06e588890cfc60366e14f83e0e61ea3c4b4 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Fri, 3 Jul 2020 16:49:03 +0300 Subject: usb: gadget: f_uac2: fix AC Interface Header Descriptor wTotalLength [ Upstream commit a9cf8715180b18c62addbfe6f6267b8101903119 ] As per UAC2 spec (ch. 4.7.2), wTotalLength of AC Interface Header Descriptor "includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors." Thus add its size to its wTotalLength. Also after recent changes wTotalLength is calculated dynamically, update static definition of uac2_ac_header_descriptor accordingly Fixes: 132fcb460839 ("usb: gadget: Add Audio Class 2.0 Driver") Signed-off-by: Ruslan Bilovol Signed-off-by: Felipe Balbi Signed-off-by: Sasha Levin --- drivers/usb/gadget/function/f_uac2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index db2d4980cb35..3633df6d7610 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -215,10 +215,7 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = { .bDescriptorSubtype = UAC_MS_HEADER, .bcdADC = cpu_to_le16(0x200), .bCategory = UAC2_FUNCTION_IO_BOX, - .wTotalLength = cpu_to_le16(sizeof in_clk_src_desc - + sizeof out_clk_src_desc + sizeof usb_out_it_desc - + sizeof io_in_it_desc + sizeof usb_in_ot_desc - + sizeof io_out_ot_desc), + /* .wTotalLength = DYNAMIC */ .bmControls = 0, }; @@ -501,7 +498,7 @@ static void setup_descriptor(struct f_uac2_opts *opts) as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; iad_desc.bInterfaceCount = 1; - ac_hdr_desc.wTotalLength = 0; + ac_hdr_desc.wTotalLength = cpu_to_le16(sizeof(ac_hdr_desc)); if (EPIN_EN(opts)) { u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength); -- cgit v1.2.3 From bd5cc29fca5e7b65e5cb811bcf2e83865b3c894f Mon Sep 17 00:00:00 2001 From: Brant Merryman Date: Fri, 26 Jun 2020 04:24:20 +0000 Subject: USB: serial: cp210x: re-enable auto-RTS on open commit c7614ff9b73a1e6fb2b1b51396da132ed22fecdb upstream. CP210x hardware disables auto-RTS but leaves auto-CTS when in hardware flow control mode and UART on cp210x hardware is disabled. When re-opening the port, if auto-CTS is enabled on the cp210x, then auto-RTS must be re-enabled in the driver. Signed-off-by: Brant Merryman Co-developed-by: Phu Luu Signed-off-by: Phu Luu Link: https://lore.kernel.org/r/ECCF8E73-91F3-4080-BE17-1714BC8818FB@silabs.com [ johan: fix up tags and problem description ] Fixes: 39a66b8d22a3 ("[PATCH] USB: CP2101 Add support for flow control") Cc: stable # 2.6.12 Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index f5143eedbc48..22c5ad23b1cd 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -915,6 +915,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, u32 baud; u16 bits; u32 ctl_hs; + u32 flow_repl; cp210x_read_u32_reg(port, CP210X_GET_BAUDRATE, &baud); @@ -1015,6 +1016,22 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, ctl_hs = le32_to_cpu(flow_ctl.ulControlHandshake); if (ctl_hs & CP210X_SERIAL_CTS_HANDSHAKE) { dev_dbg(dev, "%s - flow control = CRTSCTS\n", __func__); + /* + * When the port is closed, the CP210x hardware disables + * auto-RTS and RTS is deasserted but it leaves auto-CTS when + * in hardware flow control mode. When re-opening the port, if + * auto-CTS is enabled on the cp210x, then auto-RTS must be + * re-enabled in the driver. + */ + flow_repl = le32_to_cpu(flow_ctl.ulFlowReplace); + flow_repl &= ~CP210X_SERIAL_RTS_MASK; + flow_repl |= CP210X_SERIAL_RTS_SHIFT(CP210X_SERIAL_RTS_FLOW_CTL); + flow_ctl.ulFlowReplace = cpu_to_le32(flow_repl); + cp210x_write_reg_block(port, + CP210X_SET_FLOW, + &flow_ctl, + sizeof(flow_ctl)); + cflag |= CRTSCTS; } else { dev_dbg(dev, "%s - flow control = NONE\n", __func__); -- cgit v1.2.3 From 1425bf7b1be0825556fc2e72e90532531ad1ef12 Mon Sep 17 00:00:00 2001 From: Brant Merryman Date: Fri, 26 Jun 2020 04:22:58 +0000 Subject: USB: serial: cp210x: enable usb generic throttle/unthrottle commit 4387b3dbb079d482d3c2b43a703ceed4dd27ed28 upstream. Assign the .throttle and .unthrottle functions to be generic function in the driver structure to prevent data loss that can otherwise occur if the host does not enable USB throttling. Signed-off-by: Brant Merryman Co-developed-by: Phu Luu Signed-off-by: Phu Luu Link: https://lore.kernel.org/r/57401AF3-9961-461F-95E1-F8AFC2105F5E@silabs.com [ johan: fix up tags ] Fixes: 39a66b8d22a3 ("[PATCH] USB: CP2101 Add support for flow control") Cc: stable # 2.6.12 Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 22c5ad23b1cd..a90801ef0055 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -272,6 +272,8 @@ static struct usb_serial_driver cp210x_device = { .break_ctl = cp210x_break_ctl, .set_termios = cp210x_set_termios, .tx_empty = cp210x_tx_empty, + .throttle = usb_serial_generic_throttle, + .unthrottle = usb_serial_generic_unthrottle, .tiocmget = cp210x_tiocmget, .tiocmset = cp210x_tiocmset, .attach = cp210x_attach, -- cgit v1.2.3 From 56448553974fe3616c641f29ae32ea182b80e23c Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 22 Jul 2020 11:06:19 +0800 Subject: usb: cdns3: gadget: always zeroed TRB buffer when enable endpoint commit 95f5acfc4f58f01a22b66d8c9c0ffb72aa96271c upstream. During the endpoint dequeue operation, it changes dequeued TRB as link TRB, when the endpoint is disabled and re-enabled, the DMA fetches the TRB before the link TRB, after it handles current TRB, the DMA pointer will advance to the TRB after link TRB, but enqueue and dequene variables don't know it due to no hardware interrupt at the time, when the next TRB is added to link TRB position, the DMA will not handle this TRB due to its pointer is already at the next TRB. See the trace log like below: file-storage-675 [001] d..1 86.585657: usb_ep_queue: ep0: req 00000000df9b3a4f length 0/0 sgs 0/0 stream 0 zsI status 0 --> 0 file-storage-675 [001] d..1 86.585663: cdns3_ep_queue: ep1out: req: 000000002ebce364, req buff 00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr (null)], flags:0 SID: 0 file-storage-675 [001] d..1 86.585671: cdns3_prepare_trb: ep1out: trb 000000007f770303, dma buf: 0xbd195800, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0 file-storage-675 [001] d..1 86.585676: cdns3_ring: Ring contents for ep1out: Ring deq index: 0, trb: 000000007f770303 (virt), 0xc4003000 (dma) Ring enq index: 1, trb: 0000000049c1ba21 (virt), 0xc400300c (dma) free trbs: 38, CCS=1, PCS=1 @0x00000000c4003000 bd195800 80020400 00000425 @0x00000000c400300c c4003018 80020400 00001811 @0x00000000c4003018 bcfcc000 0000001f 00000426 @0x00000000c4003024 bcfce800 0000001f 00000426 ... irq/144-5b13000-698 [000] d... 87.619286: usb_gadget_giveback_request: ep1in: req 0000000031b832eb length 13/13 sgs 0/0 stream 0 zsI status 0 --> 0 file-storage-675 [001] d..1 87.619287: cdns3_ep_queue: ep1out: req: 000000002ebce364, req buff 00000000f5bc96b4, length: 0/1024 zsi, status: -115, trb: [start:0, end:0: virt addr 0x80020400c400300c], flags:0 SID: 0 file-storage-675 [001] d..1 87.619294: cdns3_prepare_trb: ep1out: trb 0000000049c1ba21, dma buf: 0xbd198000, size: 1024, burst: 128 ctrl: 0x00000425 (C=1, T=0, ISP, IOC, Normal) SID:0 LAST_SID:0 file-storage-675 [001] d..1 87.619297: cdns3_ring: Ring contents for ep1out: Ring deq index: 1, trb: 0000000049c1ba21 (virt), 0xc400300c (dma) Ring enq index: 2, trb: 0000000059b34b67 (virt), 0xc4003018 (dma) free trbs: 38, CCS=1, PCS=1 @0x00000000c4003000 bd195800 0000001f 00000427 @0x00000000c400300c bd198000 80020400 00000425 @0x00000000c4003018 bcfcc000 0000001f 00000426 @0x00000000c4003024 bcfce800 0000001f 00000426 ... file-storage-675 [001] d..1 87.619305: cdns3_doorbell_epx: ep1out, ep_trbaddr c4003018 file-storage-675 [001] .... 87.619308: usb_ep_queue: ep1out: req 000000002ebce364 length 0/1024 sgs 0/0 stream 0 zsI status -115 --> 0 irq/144-5b13000-698 [000] d..1 87.619315: cdns3_epx_irq: IRQ for ep1out: 01000c80 TRBERR , ep_traddr: c4003018 ep_last_sid: 00000000 use_streams: 0 irq/144-5b13000-698 [000] d..1 87.619395: cdns3_usb_irq: IRQ 00000008 = Hot Reset Fixes: f616c3bda47e ("usb: cdns3: Fix dequeue implementation") Cc: stable Signed-off-by: Peter Chen Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/gadget.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb') diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 5e24c2e57c0d..37ae7fc5f8dd 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -242,9 +242,10 @@ int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep) return -ENOMEM; priv_ep->alloc_ring_size = ring_size; - memset(priv_ep->trb_pool, 0, ring_size); } + memset(priv_ep->trb_pool, 0, ring_size); + priv_ep->num_trbs = num_trbs; if (!priv_ep->num) -- cgit v1.2.3 From 0c7343c9432efed2f071e09df42e74a8fff5a799 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 8 Jul 2020 14:49:51 +0200 Subject: USB: serial: ftdi_sio: make process-packet buffer unsigned [ Upstream commit ab4cc4ef6724ea588e835fc1e764c4b4407a70b7 ] Use an unsigned type for the process-packet buffer argument and give it a more apt name. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Sasha Levin --- drivers/usb/serial/ftdi_sio.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 9ad44a96dfe3..96b9e2768ac5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2480,12 +2480,12 @@ static int ftdi_prepare_write_buffer(struct usb_serial_port *port, #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE) static int ftdi_process_packet(struct usb_serial_port *port, - struct ftdi_private *priv, char *packet, int len) + struct ftdi_private *priv, unsigned char *buf, int len) { + unsigned char status; + unsigned char *ch; int i; - char status; char flag; - char *ch; if (len < 2) { dev_dbg(&port->dev, "malformed packet\n"); @@ -2495,7 +2495,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, /* Compare new line status to the old one, signal if different/ N.B. packet may be processed more than once, but differences are only processed once. */ - status = packet[0] & FTDI_STATUS_B0_MASK; + status = buf[0] & FTDI_STATUS_B0_MASK; if (status != priv->prev_status) { char diff_status = status ^ priv->prev_status; @@ -2521,7 +2521,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, } /* save if the transmitter is empty or not */ - if (packet[1] & FTDI_RS_TEMT) + if (buf[1] & FTDI_RS_TEMT) priv->transmit_empty = 1; else priv->transmit_empty = 0; @@ -2535,29 +2535,29 @@ static int ftdi_process_packet(struct usb_serial_port *port, * data payload to avoid over-reporting. */ flag = TTY_NORMAL; - if (packet[1] & FTDI_RS_ERR_MASK) { + if (buf[1] & FTDI_RS_ERR_MASK) { /* Break takes precedence over parity, which takes precedence * over framing errors */ - if (packet[1] & FTDI_RS_BI) { + if (buf[1] & FTDI_RS_BI) { flag = TTY_BREAK; port->icount.brk++; usb_serial_handle_break(port); - } else if (packet[1] & FTDI_RS_PE) { + } else if (buf[1] & FTDI_RS_PE) { flag = TTY_PARITY; port->icount.parity++; - } else if (packet[1] & FTDI_RS_FE) { + } else if (buf[1] & FTDI_RS_FE) { flag = TTY_FRAME; port->icount.frame++; } /* Overrun is special, not associated with a char */ - if (packet[1] & FTDI_RS_OE) { + if (buf[1] & FTDI_RS_OE) { port->icount.overrun++; tty_insert_flip_char(&port->port, 0, TTY_OVERRUN); } } port->icount.rx += len; - ch = packet + 2; + ch = buf + 2; if (port->port.console && port->sysrq) { for (i = 0; i < len; i++, ch++) { -- cgit v1.2.3 From 541992e8b0c7ce720ac0bd26727531b195a8b03d Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 8 Jul 2020 14:49:52 +0200 Subject: USB: serial: ftdi_sio: clean up receive processing [ Upstream commit ce054039ba5e47b75a3be02a00274e52b06a6456 ] Clean up receive processing by dropping the character pointer and keeping the length argument unchanged throughout the function. Also make it more apparent that sysrq processing can consume a characters by adding an explicit continue. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold Signed-off-by: Sasha Levin --- drivers/usb/serial/ftdi_sio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 96b9e2768ac5..33f1cca7eaa6 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2483,7 +2483,6 @@ static int ftdi_process_packet(struct usb_serial_port *port, struct ftdi_private *priv, unsigned char *buf, int len) { unsigned char status; - unsigned char *ch; int i; char flag; @@ -2526,8 +2525,7 @@ static int ftdi_process_packet(struct usb_serial_port *port, else priv->transmit_empty = 0; - len -= 2; - if (!len) + if (len == 2) return 0; /* status only */ /* @@ -2556,19 +2554,20 @@ static int ftdi_process_packet(struct usb_serial_port *port, } } - port->icount.rx += len; - ch = buf + 2; + port->icount.rx += len - 2; if (port->port.console && port->sysrq) { - for (i = 0; i < len; i++, ch++) { - if (!usb_serial_handle_sysrq_char(port, *ch)) - tty_insert_flip_char(&port->port, *ch, flag); + for (i = 2; i < len; i++) { + if (usb_serial_handle_sysrq_char(port, buf[i])) + continue; + tty_insert_flip_char(&port->port, buf[i], flag); } } else { - tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len); + tty_insert_flip_string_fixed_flag(&port->port, buf + 2, flag, + len - 2); } - return len; + return len - 2; } static void ftdi_process_read_urb(struct urb *urb) -- cgit v1.2.3