Pull USB fixes from Greg KH: "Here are a number of small USB driver fixes for 5.11-rc3. Include in here are: - USB gadget driver fixes for reported issues - new usb-serial driver ids - dma from stack bugfixes - typec bugfixes - dwc3 bugfixes - xhci driver bugfixes - other small misc usb driver bugfixes All of these have been in linux-next with no reported issues" * tag 'usb-5.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (35 commits) usb: dwc3: gadget: Clear wait flag on dequeue usb: typec: Send uevent for num_altmodes update usb: typec: Fix copy paste error for NVIDIA alt-mode description usb: gadget: enable super speed plus kcov, usb: hide in_serving_softirq checks in __usb_hcd_giveback_urb usb: uas: Add PNY USB Portable SSD to unusual_uas usb: gadget: configfs: Preserve function ordering after bind failure usb: gadget: select CONFIG_CRC32 usb: gadget: core: change the comment for usb_gadget_connect usb: gadget: configfs: Fix use-after-free issue with udc_name usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup usb: usbip: vhci_hcd: protect shift size USB: usblp: fix DMA to stack USB: serial: iuu_phoenix: fix DMA from stack USB: serial: option: add LongSung M5710 module support USB: serial: option: add Quectel EM160R-GL USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug usb: gadget: f_uac2: reset wMaxPacketSize usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one ...
Unified · Split
| @@ -11,8 +11,12 @@ maintainers: · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | properties: | 12 | properties: |
| 13 | compatible: | 13 | compatible: |
| 14 | items: | 14 | oneOf: |
| 15 | - const: ti,j721e-usb | 15 | - const: ti,j721e-usb |
| 16 | - const: ti,am64-usb | ||
| 17 | - items: | ||
| 18 | - const: ti,j721e-usb | ||
| 19 | - const: ti,am64-usb | ||
| 16 | 20 | ||
| 17 | reg: | 21 | reg: |
| 18 | description: module registers | 22 | description: module registers |
| @@ -3883,7 +3883,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c · 3882 unmodified lines | |||
| 3883 | CADENCE USB3 DRD IP DRIVER | 3883 | CADENCE USB3 DRD IP DRIVER |
| 3884 | M: Peter Chen <peter.chen@nxp.com> | 3884 | M: Peter Chen <peter.chen@nxp.com> |
| 3885 | M: Pawel Laszczak <pawell@cadence.com> | 3885 | M: Pawel Laszczak <pawell@cadence.com> |
| 3886 | M: Roger Quadros <rogerq@ti.com> | 3886 | R: Roger Quadros <rogerq@kernel.org> |
| 3887 | R: Aswath Govindraju <a-govindraju@ti.com> | 3887 | R: Aswath Govindraju <a-govindraju@ti.com> |
| 3888 | L: linux-usb@vger.kernel.org | 3888 | L: linux-usb@vger.kernel.org |
| 3889 | S: Maintained | 3889 | S: Maintained |
| @@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) · 138 unmodified lines | |||
| 139 | misc_pdev = of_find_device_by_node(args.np); | 139 | misc_pdev = of_find_device_by_node(args.np); |
| 140 | of_node_put(args.np); | 140 | of_node_put(args.np); |
| 141 | 141 | ||
| 142 | if (!misc_pdev || !platform_get_drvdata(misc_pdev)) | 142 | if (!misc_pdev) |
| 143 | return ERR_PTR(-EPROBE_DEFER); | 143 | return ERR_PTR(-EPROBE_DEFER); |
| 144 | 144 | ||
| 145 | if (!platform_get_drvdata(misc_pdev)) { | ||
| 146 | put_device(&misc_pdev->dev); | ||
| 147 | return ERR_PTR(-EPROBE_DEFER); | ||
| 148 | } | ||
| 145 | data->dev = &misc_pdev->dev; | 149 | data->dev = &misc_pdev->dev; |
| 146 | 150 | ||
| 147 | /* | 151 | /* |
| @@ -1895,6 +1895,10 @@ static const struct usb_device_id acm_ids[] = { · 1894 unmodified lines | |||
| 1895 | { USB_DEVICE(0x04d8, 0xfd08), | 1895 | { USB_DEVICE(0x04d8, 0xfd08), |
| 1896 | .driver_info = IGNORE_DEVICE, | 1896 | .driver_info = IGNORE_DEVICE, |
| 1897 | }, | 1897 | }, |
| 1898 | |||
| 1899 | { USB_DEVICE(0x04d8, 0xf58b), | ||
| 1900 | .driver_info = IGNORE_DEVICE, | ||
| 1901 | }, | ||
| 1898 | #endif | 1902 | #endif |
| 1899 | 1903 | ||
| 1900 | /*Samsung phone in firmware update mode */ | 1904 | /*Samsung phone in firmware update mode */ |
| @@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc) · 464 unmodified lines | |||
| 465 | if (!desc->resp_count || !--desc->resp_count) | 465 | if (!desc->resp_count || !--desc->resp_count) |
| 466 | goto out; | 466 | goto out; |
| 467 | 467 | ||
| 468 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
| 469 | rv = -ENODEV; | ||
| 470 | goto out; | ||
| 471 | } | ||
| 472 | if (test_bit(WDM_RESETTING, &desc->flags)) { | ||
| 473 | rv = -EIO; | ||
| 474 | goto out; | ||
| 475 | } | ||
| 476 | |||
| 468 | set_bit(WDM_RESPONDING, &desc->flags); | 477 | set_bit(WDM_RESPONDING, &desc->flags); |
| 469 | spin_unlock_irq(&desc->iuspin); | 478 | spin_unlock_irq(&desc->iuspin); |
| 470 | rv = usb_submit_urb(desc->response, GFP_KERNEL); | 479 | rv = usb_submit_urb(desc->response, GFP_KERNEL); |
| 471 | spin_lock_irq(&desc->iuspin); | 480 | spin_lock_irq(&desc->iuspin); |
| 472 | if (rv) { | 481 | if (rv) { |
| 473 | dev_err(&desc->intf->dev, | 482 | if (!test_bit(WDM_DISCONNECTING, &desc->flags)) |
| 474 | "usb_submit_urb failed with result %d\n", rv); | 483 | dev_err(&desc->intf->dev, |
| 484 | "usb_submit_urb failed with result %d\n", rv); | ||
| 475 | 485 | ||
| 476 | /* make sure the next notification trigger a submit */ | 486 | /* make sure the next notification trigger a submit */ |
| 477 | clear_bit(WDM_RESPONDING, &desc->flags); | 487 | clear_bit(WDM_RESPONDING, &desc->flags); |
| @@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf) · 549 unmodified lines | |||
| 1027 | wake_up_all(&desc->wait); | 1037 | wake_up_all(&desc->wait); |
| 1028 | mutex_lock(&desc->rlock); | 1038 | mutex_lock(&desc->rlock); |
| 1029 | mutex_lock(&desc->wlock); | 1039 | mutex_lock(&desc->wlock); |
| 1030 | kill_urbs(desc); | ||
| 1031 | cancel_work_sync(&desc->rxwork); | 1040 | cancel_work_sync(&desc->rxwork); |
| 1032 | cancel_work_sync(&desc->service_outs_intr); | 1041 | cancel_work_sync(&desc->service_outs_intr); |
| 1042 | kill_urbs(desc); | ||
| 1033 | mutex_unlock(&desc->wlock); | 1043 | mutex_unlock(&desc->wlock); |
| 1034 | mutex_unlock(&desc->rlock); | 1044 | mutex_unlock(&desc->rlock); |
| 1035 | 1045 | ||
| @@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i · 273 unmodified lines | |||
| 274 | #define usblp_reset(usblp)\ | 274 | #define usblp_reset(usblp)\ |
| 275 | usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) | 275 | usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0) |
| 276 | 276 | ||
| 277 | #define usblp_hp_channel_change_request(usblp, channel, buffer) \ | 277 | static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) |
| 278 | usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) | 278 | { |
| 279 | u8 *buf; | ||
| 280 | int ret; | ||
| 281 | |||
| 282 | buf = kzalloc(1, GFP_KERNEL); | ||
| 283 | if (!buf) | ||
| 284 | return -ENOMEM; | ||
| 285 | |||
| 286 | ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, | ||
| 287 | USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, | ||
| 288 | channel, buf, 1); | ||
| 289 | if (ret == 0) | ||
| 290 | *new_channel = buf[0]; | ||
| 291 | |||
| 292 | kfree(buf); | ||
| 293 | |||
| 294 | return ret; | ||
| 295 | } | ||
| 279 | 296 | ||
| 280 | /* | 297 | /* |
| 281 | * See the description for usblp_select_alts() below for the usage | 298 | * See the description for usblp_select_alts() below for the usage |
| @@ -1649,14 +1649,12 @@ static void __usb_hcd_giveback_urb(struct urb *urb) · 1648 unmodified lines | |||
| 1649 | urb->status = status; | 1649 | urb->status = status; |
| 1650 | /* | 1650 | /* |
| 1651 | * This function can be called in task context inside another remote | 1651 | * This function can be called in task context inside another remote |
| 1652 | * coverage collection section, but KCOV doesn't support that kind of | 1652 | * coverage collection section, but kcov doesn't support that kind of |
| 1653 | * recursion yet. Only collect coverage in softirq context for now. | 1653 | * recursion yet. Only collect coverage in softirq context for now. |
| 1654 | */ | 1654 | */ |
| 1655 | if (in_serving_softirq()) | 1655 | kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); |
| 1656 | kcov_remote_start_usb((u64)urb->dev->bus->busnum); | ||
| 1657 | urb->complete(urb); | 1656 | urb->complete(urb); |
| 1658 | if (in_serving_softirq()) | 1657 | kcov_remote_stop_softirq(); |
| 1659 | kcov_remote_stop(); | ||
| 1660 | 1658 | ||
| 1661 | usb_anchor_resume_wakeups(anchor); | 1659 | usb_anchor_resume_wakeups(anchor); |
| 1662 | atomic_dec(&urb->use_count); | 1660 | atomic_dec(&urb->use_count); |
| @@ -285,6 +285,7 @@ · 284 unmodified lines | |||
| 285 | 285 | ||
| 286 | /* Global USB2 PHY Vendor Control Register */ | 286 | /* Global USB2 PHY Vendor Control Register */ |
| 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) | 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) |
| 288 | #define DWC3_GUSB2PHYACC_DONE BIT(24) | ||
| 288 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) | 289 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) |
| 289 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) | 290 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) |
| 290 | #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) | 291 | #define DWC3_GUSB2PHYACC_ADDR(n) (n << 16) |
| @@ -754,7 +754,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) · 753 unmodified lines | |||
| 754 | 754 | ||
| 755 | ret = priv->drvdata->setup_regmaps(priv, base); | 755 | ret = priv->drvdata->setup_regmaps(priv, base); |
| 756 | if (ret) | 756 | if (ret) |
| 757 | return ret; | 757 | goto err_disable_clks; |
| 758 | 758 | ||
| 759 | if (priv->vbus) { | 759 | if (priv->vbus) { |
| 760 | ret = regulator_enable(priv->vbus); | 760 | ret = regulator_enable(priv->vbus); |
| @@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, · 1762 unmodified lines | |||
| 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) | 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) |
| 1764 | dwc3_gadget_move_cancelled_request(r); | 1764 | dwc3_gadget_move_cancelled_request(r); |
| 1765 | 1765 | ||
| 1766 | dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; | ||
| 1767 | |||
| 1766 | goto out; | 1768 | goto out; |
| 1767 | } | 1769 | } |
| 1768 | } | 1770 | } |
| @@ -2083,6 +2085,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend) · 314 unmodified lines | |||
| 2083 | 2085 | ||
| 2084 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); | 2086 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); |
| 2085 | static void __dwc3_gadget_stop(struct dwc3 *dwc); | 2087 | static void __dwc3_gadget_stop(struct dwc3 *dwc); |
| 2088 | static int __dwc3_gadget_start(struct dwc3 *dwc); | ||
| 2086 | 2089 | ||
| 2087 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) | 2090 | static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) |
| 2088 | { | 2091 | { |
| @@ -2145,6 +2148,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) · 56 unmodified lines | |||
| 2145 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % | 2148 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
| 2146 | dwc->ev_buf->length; | 2149 | dwc->ev_buf->length; |
| 2147 | } | 2150 | } |
| 2151 | } else { | ||
| 2152 | __dwc3_gadget_start(dwc); | ||
| 2148 | } | 2153 | } |
| 2149 | 2154 | ||
| 2150 | ret = dwc3_gadget_run_stop(dwc, is_on, false); | 2155 | ret = dwc3_gadget_run_stop(dwc, is_on, false); |
| @@ -2319,10 +2324,6 @@ static int dwc3_gadget_start(struct usb_gadget *g, · 168 unmodified lines | |||
| 2319 | } | 2324 | } |
| 2320 | 2325 | ||
| 2321 | dwc->gadget_driver = driver; | 2326 | dwc->gadget_driver = driver; |
| 2322 | |||
| 2323 | if (pm_runtime_active(dwc->dev)) | ||
| 2324 | __dwc3_gadget_start(dwc); | ||
| 2325 | |||
| 2326 | spin_unlock_irqrestore(&dwc->lock, flags); | 2327 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2327 | 2328 | ||
| 2328 | return 0; | 2329 | return 0; |
| @@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) · 19 unmodified lines | |||
| 2348 | unsigned long flags; | 2349 | unsigned long flags; |
| 2349 | 2350 | ||
| 2350 | spin_lock_irqsave(&dwc->lock, flags); | 2351 | spin_lock_irqsave(&dwc->lock, flags); |
| 2351 | |||
| 2352 | if (pm_runtime_suspended(dwc->dev)) | ||
| 2353 | goto out; | ||
| 2354 | |||
| 2355 | __dwc3_gadget_stop(dwc); | ||
| 2356 | |||
| 2357 | out: | ||
| 2358 | dwc->gadget_driver = NULL; | 2352 | dwc->gadget_driver = NULL; |
| 2359 | spin_unlock_irqrestore(&dwc->lock, flags); | 2353 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2360 | 2354 | ||
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> | 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/delay.h> | ||
| 11 | #include <linux/time64.h> | ||
| 10 | #include <linux/ulpi/regs.h> | 12 | #include <linux/ulpi/regs.h> |
| 11 | 13 | ||
| 12 | #include "core.h" | 14 | #include "core.h" |
| @@ -17,14 +19,28 @@ · 4 unmodified lines | |||
| 17 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ | 19 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ |
| 18 | DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) | 20 | DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) |
| 19 | 21 | ||
| 20 | static int dwc3_ulpi_busyloop(struct dwc3 *dwc) | 22 | #define DWC3_ULPI_BASE_DELAY DIV_ROUND_UP(NSEC_PER_SEC, 60000000L) |
| 23 | |||
| 24 | static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read) | ||
| 21 | { | 25 | { |
| 22 | unsigned int count = 1000; | 26 | unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY; |
| 27 | unsigned int count = 10000; | ||
| 23 | u32 reg; | 28 | u32 reg; |
| 24 | 29 | ||
| 30 | if (addr >= ULPI_EXT_VENDOR_SPECIFIC) | ||
| 31 | ns += DWC3_ULPI_BASE_DELAY; | ||
| 32 | |||
| 33 | if (read) | ||
| 34 | ns += DWC3_ULPI_BASE_DELAY; | ||
| 35 | |||
| 36 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 37 | if (reg & DWC3_GUSB2PHYCFG_SUSPHY) | ||
| 38 | usleep_range(1000, 1200); | ||
| 39 | |||
| 25 | while (count--) { | 40 | while (count--) { |
| 41 | ndelay(ns); | ||
| 26 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | 42 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); |
| 27 | if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | 43 | if (reg & DWC3_GUSB2PHYACC_DONE) |
| 28 | return 0; | 44 | return 0; |
| 29 | cpu_relax(); | 45 | cpu_relax(); |
| 30 | } | 46 | } |
| @@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr) · 7 unmodified lines | |||
| 38 | u32 reg; | 54 | u32 reg; |
| 39 | int ret; | 55 | int ret; |
| 40 | 56 | ||
| 41 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 42 | if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { | ||
| 43 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | ||
| 44 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
| 45 | } | ||
| 46 | |||
| 47 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | 57 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 48 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | 58 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); |
| 49 | 59 | ||
| 50 | ret = dwc3_ulpi_busyloop(dwc); | 60 | ret = dwc3_ulpi_busyloop(dwc, addr, true); |
| 51 | if (ret) | 61 | if (ret) |
| 52 | return ret; | 62 | return ret; |
| 53 | 63 | ||
| @@ -61,17 +71,11 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val) · 7 unmodified lines | |||
| 61 | struct dwc3 *dwc = dev_get_drvdata(dev); | 71 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 62 | u32 reg; | 72 | u32 reg; |
| 63 | 73 | ||
| 64 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | ||
| 65 | if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { | ||
| 66 | reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; | ||
| 67 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); | ||
| 68 | } | ||
| 69 | |||
| 70 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | 74 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 71 | reg |= DWC3_GUSB2PHYACC_WRITE | val; | 75 | reg |= DWC3_GUSB2PHYACC_WRITE | val; |
| 72 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | 76 | dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); |
| 73 | 77 | ||
| 74 | return dwc3_ulpi_busyloop(dwc); | 78 | return dwc3_ulpi_busyloop(dwc, addr, false); |
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | static const struct ulpi_ops dwc3_ulpi_ops = { | 81 | static const struct ulpi_ops dwc3_ulpi_ops = { |
| @@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM · 264 unmodified lines | |||
| 265 | depends on NET | 265 | depends on NET |
| 266 | select USB_U_ETHER | 266 | select USB_U_ETHER |
| 267 | select USB_F_NCM | 267 | select USB_F_NCM |
| 268 | select CRC32 | ||
| 268 | help | 269 | help |
| 269 | NCM is an advanced protocol for Ethernet encapsulation, allows | 270 | NCM is an advanced protocol for Ethernet encapsulation, allows |
| 270 | grouping of several ethernet frames into one USB transfer and | 271 | grouping of several ethernet frames into one USB transfer and |
| @@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM · 43 unmodified lines | |||
| 314 | depends on NET | 315 | depends on NET |
| 315 | select USB_U_ETHER | 316 | select USB_U_ETHER |
| 316 | select USB_F_EEM | 317 | select USB_F_EEM |
| 318 | select CRC32 | ||
| 317 | help | 319 | help |
| 318 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM | 320 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM |
| 319 | and therefore can be supported by more hardware. Technically ECM and | 321 | and therefore can be supported by more hardware. Technically ECM and |
| @@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function) · 391 unmodified lines | |||
| 392 | 392 | ||
| 393 | spin_lock_irqsave(&cdev->lock, flags); | 393 | spin_lock_irqsave(&cdev->lock, flags); |
| 394 | 394 | ||
| 395 | if (cdev->deactivations == 0) | 395 | if (cdev->deactivations == 0) { |
| 396 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 396 | status = usb_gadget_deactivate(cdev->gadget); | 397 | status = usb_gadget_deactivate(cdev->gadget); |
| 398 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 399 | } | ||
| 397 | if (status == 0) | 400 | if (status == 0) |
| 398 | cdev->deactivations++; | 401 | cdev->deactivations++; |
| 399 | 402 | ||
| @@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function) · 24 unmodified lines | |||
| 424 | status = -EINVAL; | 427 | status = -EINVAL; |
| 425 | else { | 428 | else { |
| 426 | cdev->deactivations--; | 429 | cdev->deactivations--; |
| 427 | if (cdev->deactivations == 0) | 430 | if (cdev->deactivations == 0) { |
| 431 | spin_unlock_irqrestore(&cdev->lock, flags); | ||
| 428 | status = usb_gadget_activate(cdev->gadget); | 432 | status = usb_gadget_activate(cdev->gadget); |
| 433 | spin_lock_irqsave(&cdev->lock, flags); | ||
| 434 | } | ||
| 429 | } | 435 | } |
| 430 | 436 | ||
| 431 | spin_unlock_irqrestore(&cdev->lock, flags); | 437 | spin_unlock_irqrestore(&cdev->lock, flags); |
| @@ -221,9 +221,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item, · 220 unmodified lines | |||
| 221 | 221 | ||
| 222 | static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) | 222 | static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page) |
| 223 | { | 223 | { |
| 224 | char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name; | 224 | struct gadget_info *gi = to_gadget_info(item); |
| 225 | char *udc_name; | ||
| 226 | int ret; | ||
| 227 | |||
| 228 | mutex_lock(&gi->lock); | ||
| 229 | udc_name = gi->composite.gadget_driver.udc_name; | ||
| 230 | ret = sprintf(page, "%s\n", udc_name ?: ""); | ||
| 231 | mutex_unlock(&gi->lock); | ||
| 225 | 232 | ||
| 226 | return sprintf(page, "%s\n", udc_name ?: ""); | 233 | return ret; |
| 227 | } | 234 | } |
| 228 | 235 | ||
| 229 | static int unregister_gadget(struct gadget_info *gi) | 236 | static int unregister_gadget(struct gadget_info *gi) |
| @@ -1248,9 +1255,9 @@ static void purge_configs_funcs(struct gadget_info *gi) · 1018 unmodified lines | |||
| 1248 | 1255 | ||
| 1249 | cfg = container_of(c, struct config_usb_cfg, c); | 1256 | cfg = container_of(c, struct config_usb_cfg, c); |
| 1250 | 1257 | ||
| 1251 | list_for_each_entry_safe(f, tmp, &c->functions, list) { | 1258 | list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) { |
| 1252 | 1259 | ||
| 1253 | list_move_tail(&f->list, &cfg->func_list); | 1260 | list_move(&f->list, &cfg->func_list); |
| 1254 | if (f->unbind) { | 1261 | if (f->unbind) { |
| 1255 | dev_dbg(&gi->cdev.gadget->dev, | 1262 | dev_dbg(&gi->cdev.gadget->dev, |
| 1256 | "unbind function '%s'/%p\n", | 1263 | "unbind function '%s'/%p\n", |
| @@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = { · 279 unmodified lines | |||
| 1536 | .suspend = configfs_composite_suspend, | 1543 | .suspend = configfs_composite_suspend, |
| 1537 | .resume = configfs_composite_resume, | 1544 | .resume = configfs_composite_resume, |
| 1538 | 1545 | ||
| 1539 | .max_speed = USB_SPEED_SUPER, | 1546 | .max_speed = USB_SPEED_SUPER_PLUS, |
| 1540 | .driver = { | 1547 | .driver = { |
| 1541 | .owner = THIS_MODULE, | 1548 | .owner = THIS_MODULE, |
| 1542 | .name = "configfs-gadget", | 1549 | .name = "configfs-gadget", |
| @@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make( · 33 unmodified lines | |||
| 1576 | gi->composite.unbind = configfs_do_nothing; | 1583 | gi->composite.unbind = configfs_do_nothing; |
| 1577 | gi->composite.suspend = NULL; | 1584 | gi->composite.suspend = NULL; |
| 1578 | gi->composite.resume = NULL; | 1585 | gi->composite.resume = NULL; |
| 1579 | gi->composite.max_speed = USB_SPEED_SUPER; | 1586 | gi->composite.max_speed = USB_SPEED_SUPER_PLUS; |
| 1580 | 1587 | ||
| 1581 | spin_lock_init(&gi->spinlock); | 1588 | spin_lock_init(&gi->spinlock); |
| 1582 | mutex_init(&gi->lock); | 1589 | mutex_init(&gi->lock); |
| @@ -1162,6 +1162,7 @@ fail_tx_reqs: · 1161 unmodified lines | |||
| 1162 | printer_req_free(dev->in_ep, req); | 1162 | printer_req_free(dev->in_ep, req); |
| 1163 | } | 1163 | } |
| 1164 | 1164 | ||
| 1165 | usb_free_all_descriptors(f); | ||
| 1165 | return ret; | 1166 | return ret; |
| 1166 | 1167 | ||
| 1167 | } | 1168 | } |
| @@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { · 270 unmodified lines | |||
| 271 | 271 | ||
| 272 | .bEndpointAddress = USB_DIR_OUT, | 272 | .bEndpointAddress = USB_DIR_OUT, |
| 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 274 | .wMaxPacketSize = cpu_to_le16(1023), | 274 | /* .wMaxPacketSize = DYNAMIC */ |
| 275 | .bInterval = 1, | 275 | .bInterval = 1, |
| 276 | }; | 276 | }; |
| 277 | 277 | ||
| @@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { · 2 unmodified lines | |||
| 280 | .bDescriptorType = USB_DT_ENDPOINT, | 280 | .bDescriptorType = USB_DT_ENDPOINT, |
| 281 | 281 | ||
| 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 283 | .wMaxPacketSize = cpu_to_le16(1024), | 283 | /* .wMaxPacketSize = DYNAMIC */ |
| 284 | .bInterval = 4, | 284 | .bInterval = 4, |
| 285 | }; | 285 | }; |
| 286 | 286 | ||
| @@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = { · 61 unmodified lines | |||
| 348 | 348 | ||
| 349 | .bEndpointAddress = USB_DIR_IN, | 349 | .bEndpointAddress = USB_DIR_IN, |
| 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 351 | .wMaxPacketSize = cpu_to_le16(1023), | 351 | /* .wMaxPacketSize = DYNAMIC */ |
| 352 | .bInterval = 1, | 352 | .bInterval = 1, |
| 353 | }; | 353 | }; |
| 354 | 354 | ||
| @@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { · 2 unmodified lines | |||
| 357 | .bDescriptorType = USB_DT_ENDPOINT, | 357 | .bDescriptorType = USB_DT_ENDPOINT, |
| 358 | 358 | ||
| 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, | 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 360 | .wMaxPacketSize = cpu_to_le16(1024), | 360 | /* .wMaxPacketSize = DYNAMIC */ |
| 361 | .bInterval = 4, | 361 | .bInterval = 4, |
| 362 | }; | 362 | }; |
| 363 | 363 | ||
| @@ -444,12 +444,28 @@ struct cntrl_range_lay3 { · 80 unmodified lines | |||
| 444 | __le32 dRES; | 444 | __le32 dRES; |
| 445 | } __packed; | 445 | } __packed; |
| 446 | 446 | ||
| 447 | static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, | 447 | static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, |
| 448 | struct usb_endpoint_descriptor *ep_desc, | 448 | struct usb_endpoint_descriptor *ep_desc, |
| 449 | unsigned int factor, bool is_playback) | 449 | enum usb_device_speed speed, bool is_playback) |
| 450 | { | 450 | { |
| 451 | int chmask, srate, ssize; | 451 | int chmask, srate, ssize; |
| 452 | u16 max_packet_size; | 452 | u16 max_size_bw, max_size_ep; |
| 453 | unsigned int factor; | ||
| 454 | |||
| 455 | switch (speed) { | ||
| 456 | case USB_SPEED_FULL: | ||
| 457 | max_size_ep = 1023; | ||
| 458 | factor = 1000; | ||
| 459 | break; | ||
| 460 | |||
| 461 | case USB_SPEED_HIGH: | ||
| 462 | max_size_ep = 1024; | ||
| 463 | factor = 8000; | ||
| 464 | break; | ||
| 465 | |||
| 466 | default: | ||
| 467 | return -EINVAL; | ||
| 468 | } | ||
| 453 | 469 | ||
| 454 | if (is_playback) { | 470 | if (is_playback) { |
| 455 | chmask = uac2_opts->p_chmask; | 471 | chmask = uac2_opts->p_chmask; |
| @@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, · 5 unmodified lines | |||
| 461 | ssize = uac2_opts->c_ssize; | 477 | ssize = uac2_opts->c_ssize; |
| 462 | } | 478 | } |
| 463 | 479 | ||
| 464 | max_packet_size = num_channels(chmask) * ssize * | 480 | max_size_bw = num_channels(chmask) * ssize * |
| 465 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); | 481 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); |
| 466 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, | 482 | ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, |
| 467 | le16_to_cpu(ep_desc->wMaxPacketSize))); | 483 | max_size_ep)); |
| 484 | |||
| 485 | return 0; | ||
| 468 | } | 486 | } |
| 469 | 487 | ||
| 470 | /* Use macro to overcome line length limitation */ | 488 | /* Use macro to overcome line length limitation */ |
| @@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) · 199 unmodified lines | |||
| 670 | } | 688 | } |
| 671 | 689 | ||
| 672 | /* Calculate wMaxPacketSize according to audio bandwidth */ | 690 | /* Calculate wMaxPacketSize according to audio bandwidth */ |
| 673 | set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); | 691 | ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, |
| 674 | set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); | 692 | true); |
| 675 | set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); | 693 | if (ret < 0) { |
| 676 | set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); | 694 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); |
| 695 | return ret; | ||
| 696 | } | ||
| 697 | |||
| 698 | ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL, | ||
| 699 | false); | ||
| 700 | if (ret < 0) { | ||
| 701 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | ||
| 702 | return ret; | ||
| 703 | } | ||
| 704 | |||
| 705 | ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH, | ||
| 706 | true); | ||
| 707 | if (ret < 0) { | ||
| 708 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | ||
| 709 | return ret; | ||
| 710 | } | ||
| 711 | |||
| 712 | ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH, | ||
| 713 | false); | ||
| 714 | if (ret < 0) { | ||
| 715 | dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); | ||
| 716 | return ret; | ||
| 717 | } | ||
| 677 | 718 | ||
| 678 | if (EPOUT_EN(uac2_opts)) { | 719 | if (EPOUT_EN(uac2_opts)) { |
| 679 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); | 720 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); |
| @@ -45,9 +45,10 @@ · 44 unmodified lines | |||
| 45 | #define UETH__VERSION "29-May-2008" | 45 | #define UETH__VERSION "29-May-2008" |
| 46 | 46 | ||
| 47 | /* Experiments show that both Linux and Windows hosts allow up to 16k | 47 | /* Experiments show that both Linux and Windows hosts allow up to 16k |
| 48 | * frame sizes. Set the max size to 15k+52 to prevent allocating 32k | 48 | * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k |
| 49 | * blocks and still have efficient handling. */ | 49 | * blocks and still have efficient handling. */ |
| 50 | #define GETHER_MAX_ETH_FRAME_LEN 15412 | 50 | #define GETHER_MAX_MTU_SIZE 15412 |
| 51 | #define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN) | ||
| 51 | 52 | ||
| 52 | struct eth_dev { | 53 | struct eth_dev { |
| 53 | /* lock is held while accessing port_usb | 54 | /* lock is held while accessing port_usb |
| @@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, · 732 unmodified lines | |||
| 786 | 787 | ||
| 787 | /* MTU range: 14 - 15412 */ | 788 | /* MTU range: 14 - 15412 */ |
| 788 | net->min_mtu = ETH_HLEN; | 789 | net->min_mtu = ETH_HLEN; |
| 789 | net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; | 790 | net->max_mtu = GETHER_MAX_MTU_SIZE; |
| 790 | 791 | ||
| 791 | dev->gadget = g; | 792 | dev->gadget = g; |
| 792 | SET_NETDEV_DEV(net, &g->dev); | 793 | SET_NETDEV_DEV(net, &g->dev); |
| @@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname) · 55 unmodified lines | |||
| 848 | 849 | ||
| 849 | /* MTU range: 14 - 15412 */ | 850 | /* MTU range: 14 - 15412 */ |
| 850 | net->min_mtu = ETH_HLEN; | 851 | net->min_mtu = ETH_HLEN; |
| 851 | net->max_mtu = GETHER_MAX_ETH_FRAME_LEN; | 852 | net->max_mtu = GETHER_MAX_MTU_SIZE; |
| 852 | 853 | ||
| 853 | return net; | 854 | return net; |
| 854 | } | 855 | } |
| @@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) · 199 unmodified lines | |||
| 200 | struct usb_descriptor_header *usb_desc; | 200 | struct usb_descriptor_header *usb_desc; |
| 201 | 201 | ||
| 202 | usb_desc = usb_otg_descriptor_alloc(gadget); | 202 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 203 | if (!usb_desc) | 203 | if (!usb_desc) { |
| 204 | status = -ENOMEM; | ||
| 204 | goto fail_string_ids; | 205 | goto fail_string_ids; |
| 206 | } | ||
| 205 | usb_otg_descriptor_init(gadget, usb_desc); | 207 | usb_otg_descriptor_init(gadget, usb_desc); |
| 206 | otg_desc[0] = usb_desc; | 208 | otg_desc[0] = usb_desc; |
| 207 | otg_desc[1] = NULL; | 209 | otg_desc[1] = NULL; |
| @@ -90,7 +90,7 @@ config USB_BCM63XX_UDC · 89 unmodified lines | |||
| 90 | 90 | ||
| 91 | config USB_FSL_USB2 | 91 | config USB_FSL_USB2 |
| 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" | 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" |
| 93 | depends on FSL_SOC || ARCH_MXC | 93 | depends on FSL_SOC |
| 94 | help | 94 | help |
| 95 | Some of Freescale PowerPC and i.MX processors have a High Speed | 95 | Some of Freescale PowerPC and i.MX processors have a High Speed |
| 96 | Dual-Role(DR) USB controller, which supports device mode. | 96 | Dual-Role(DR) USB controller, which supports device mode. |
| @@ -23,7 +23,6 @@ obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o · 22 unmodified lines | |||
| 23 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o | 23 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o |
| 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
| 25 | fsl_usb2_udc-y := fsl_udc_core.o | 25 | fsl_usb2_udc-y := fsl_udc_core.o |
| 26 | fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | ||
| 27 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o | 26 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o |
| 28 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 27 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
| 29 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o | 28 | obj-$(CONFIG_USB_R8A66597) += r8a66597-udc.o |
| @@ -659,8 +659,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect); · 658 unmodified lines | |||
| 659 | * | 659 | * |
| 660 | * Enables the D+ (or potentially D-) pullup. The host will start | 660 | * Enables the D+ (or potentially D-) pullup. The host will start |
| 661 | * enumerating this gadget when the pullup is active and a VBUS session | 661 | * enumerating this gadget when the pullup is active and a VBUS session |
| 662 | * is active (the link is powered). This pullup is always enabled unless | 662 | * is active (the link is powered). |
| 663 | * usb_gadget_disconnect() has been used to disable it. | ||
| 664 | * | 663 | * |
| 665 | * Returns zero on success, else negative errno. | 664 | * Returns zero on success, else negative errno. |
| 666 | */ | 665 | */ |
| @@ -2118,9 +2118,21 @@ static int dummy_hub_control( · 2117 unmodified lines | |||
| 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; | 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; |
| 2119 | set_link_state(dum_hcd); | 2119 | set_link_state(dum_hcd); |
| 2120 | break; | 2120 | break; |
| 2121 | default: | 2121 | case USB_PORT_FEAT_ENABLE: |
| 2122 | case USB_PORT_FEAT_C_ENABLE: | ||
| 2123 | case USB_PORT_FEAT_C_SUSPEND: | ||
| 2124 | /* Not allowed for USB-3 */ | ||
| 2125 | if (hcd->speed == HCD_USB3) | ||
| 2126 | goto error; | ||
| 2127 | fallthrough; | ||
| 2128 | case USB_PORT_FEAT_C_CONNECTION: | ||
| 2129 | case USB_PORT_FEAT_C_RESET: | ||
| 2122 | dum_hcd->port_status &= ~(1 << wValue); | 2130 | dum_hcd->port_status &= ~(1 << wValue); |
| 2123 | set_link_state(dum_hcd); | 2131 | set_link_state(dum_hcd); |
| 2132 | break; | ||
| 2133 | default: | ||
| 2134 | /* Disallow INDICATOR and C_OVER_CURRENT */ | ||
| 2135 | goto error; | ||
| 2124 | } | 2136 | } |
| 2125 | break; | 2137 | break; |
| 2126 | case GetHubDescriptor: | 2138 | case GetHubDescriptor: |
| @@ -2281,18 +2293,17 @@ static int dummy_hub_control( · 154 unmodified lines | |||
| 2281 | */ | 2293 | */ |
| 2282 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); | 2294 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); |
| 2283 | fallthrough; | 2295 | fallthrough; |
| 2296 | case USB_PORT_FEAT_C_CONNECTION: | ||
| 2297 | case USB_PORT_FEAT_C_RESET: | ||
| 2298 | case USB_PORT_FEAT_C_ENABLE: | ||
| 2299 | case USB_PORT_FEAT_C_SUSPEND: | ||
| 2300 | /* Not allowed for USB-3, and ignored for USB-2 */ | ||
| 2301 | if (hcd->speed == HCD_USB3) | ||
| 2302 | goto error; | ||
| 2303 | break; | ||
| 2284 | default: | 2304 | default: |
| 2285 | if (hcd->speed == HCD_USB3) { | 2305 | /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ |
| 2286 | if ((dum_hcd->port_status & | 2306 | goto error; |
| 2287 | USB_SS_PORT_STAT_POWER) != 0) { | ||
| 2288 | dum_hcd->port_status |= (1 << wValue); | ||
| 2289 | } | ||
| 2290 | } else | ||
| 2291 | if ((dum_hcd->port_status & | ||
| 2292 | USB_PORT_STAT_POWER) != 0) { | ||
| 2293 | dum_hcd->port_status |= (1 << wValue); | ||
| 2294 | } | ||
| 2295 | set_link_state(dum_hcd); | ||
| 2296 | } | 2307 | } |
| 2297 | break; | 2308 | break; |
| 2298 | case GetPortErrorCount: | 2309 | case GetPortErrorCount: |
| @@ -1,122 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2009 | ||
| 4 | * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de> | ||
| 5 | * | ||
| 6 | * Description: | ||
| 7 | * Helper routines for i.MX3x SoCs from Freescale, needed by the fsl_usb2_udc.c | ||
| 8 | * driver to function correctly on these systems. | ||
| 9 | */ | ||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/delay.h> | ||
| 12 | #include <linux/err.h> | ||
| 13 | #include <linux/fsl_devices.h> | ||
| 14 | #include <linux/mod_devicetable.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | |||
| 18 | #include "fsl_usb2_udc.h" | ||
| 19 | |||
| 20 | static struct clk *mxc_ahb_clk; | ||
| 21 | static struct clk *mxc_per_clk; | ||
| 22 | static struct clk *mxc_ipg_clk; | ||
| 23 | |||
| 24 | /* workaround ENGcm09152 for i.MX35 */ | ||
| 25 | #define MX35_USBPHYCTRL_OFFSET 0x600 | ||
| 26 | #define USBPHYCTRL_OTGBASE_OFFSET 0x8 | ||
| 27 | #define USBPHYCTRL_EVDO (1 << 23) | ||
| 28 | |||
| 29 | int fsl_udc_clk_init(struct platform_device *pdev) | ||
| 30 | { | ||
| 31 | struct fsl_usb2_platform_data *pdata; | ||
| 32 | unsigned long freq; | ||
| 33 | int ret; | ||
| 34 | |||
| 35 | pdata = dev_get_platdata(&pdev->dev); | ||
| 36 | |||
| 37 | mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg"); | ||
| 38 | if (IS_ERR(mxc_ipg_clk)) { | ||
| 39 | dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n"); | ||
| 40 | return PTR_ERR(mxc_ipg_clk); | ||
| 41 | } | ||
| 42 | |||
| 43 | mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb"); | ||
| 44 | if (IS_ERR(mxc_ahb_clk)) { | ||
| 45 | dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n"); | ||
| 46 | return PTR_ERR(mxc_ahb_clk); | ||
| 47 | } | ||
| 48 | |||
| 49 | mxc_per_clk = devm_clk_get(&pdev->dev, "per"); | ||
| 50 | if (IS_ERR(mxc_per_clk)) { | ||
| 51 | dev_err(&pdev->dev, "clk_get(\"per\") failed\n"); | ||
| 52 | return PTR_ERR(mxc_per_clk); | ||
| 53 | } | ||
| 54 | |||
| 55 | clk_prepare_enable(mxc_ipg_clk); | ||
| 56 | clk_prepare_enable(mxc_ahb_clk); | ||
| 57 | clk_prepare_enable(mxc_per_clk); | ||
| 58 | |||
| 59 | /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */ | ||
| 60 | if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) { | ||
| 61 | freq = clk_get_rate(mxc_per_clk); | ||
| 62 | if (pdata->phy_mode != FSL_USB2_PHY_ULPI && | ||
| 63 | (freq < 59999000 || freq > 60001000)) { | ||
| 64 | dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq); | ||
| 65 | ret = -EINVAL; | ||
| 66 | goto eclkrate; | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | return 0; | ||
| 71 | |||
| 72 | eclkrate: | ||
| 73 | clk_disable_unprepare(mxc_ipg_clk); | ||
| 74 | clk_disable_unprepare(mxc_ahb_clk); | ||
| 75 | clk_disable_unprepare(mxc_per_clk); | ||
| 76 | mxc_per_clk = NULL; | ||
| 77 | return ret; | ||
| 78 | } | ||
| 79 | |||
| 80 | int fsl_udc_clk_finalize(struct platform_device *pdev) | ||
| 81 | { | ||
| 82 | struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
| 83 | int ret = 0; | ||
| 84 | |||
| 85 | /* workaround ENGcm09152 for i.MX35 */ | ||
| 86 | if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) { | ||
| 87 | unsigned int v; | ||
| 88 | struct resource *res = platform_get_resource | ||
| 89 | (pdev, IORESOURCE_MEM, 0); | ||
| 90 | void __iomem *phy_regs = ioremap(res->start + | ||
| 91 | MX35_USBPHYCTRL_OFFSET, 512); | ||
| 92 | if (!phy_regs) { | ||
| 93 | dev_err(&pdev->dev, "ioremap for phy address fails\n"); | ||
| 94 | ret = -EINVAL; | ||
| 95 | goto ioremap_err; | ||
| 96 | } | ||
| 97 | |||
| 98 | v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | ||
| 99 | writel(v | USBPHYCTRL_EVDO, | ||
| 100 | phy_regs + USBPHYCTRL_OTGBASE_OFFSET); | ||
| 101 | |||
| 102 | iounmap(phy_regs); | ||
| 103 | } | ||
| 104 | |||
| 105 | |||
| 106 | ioremap_err: | ||
| 107 | /* ULPI transceivers don't need usbpll */ | ||
| 108 | if (pdata->phy_mode == FSL_USB2_PHY_ULPI) { | ||
| 109 | clk_disable_unprepare(mxc_per_clk); | ||
| 110 | mxc_per_clk = NULL; | ||
| 111 | } | ||
| 112 | |||
| 113 | return ret; | ||
| 114 | } | ||
| 115 | |||
| 116 | void fsl_udc_clk_release(void) | ||
| 117 | { | ||
| 118 | if (mxc_per_clk) | ||
| 119 | clk_disable_unprepare(mxc_per_clk); | ||
| 120 | clk_disable_unprepare(mxc_ahb_clk); | ||
| 121 | clk_disable_unprepare(mxc_ipg_clk); | ||
| 122 | } | ||
| @@ -4770,19 +4770,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, · 4769 unmodified lines | |||
| 4770 | { | 4770 | { |
| 4771 | unsigned long long timeout_ns; | 4771 | unsigned long long timeout_ns; |
| 4772 | 4772 | ||
| 4773 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4774 | timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | ||
| 4775 | else | ||
| 4776 | timeout_ns = udev->u1_params.sel; | ||
| 4777 | |||
| 4773 | /* Prevent U1 if service interval is shorter than U1 exit latency */ | 4778 | /* Prevent U1 if service interval is shorter than U1 exit latency */ |
| 4774 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | 4779 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { |
| 4775 | if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { | 4780 | if (xhci_service_interval_to_ns(desc) <= timeout_ns) { |
| 4776 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); | 4781 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); |
| 4777 | return USB3_LPM_DISABLED; | 4782 | return USB3_LPM_DISABLED; |
| 4778 | } | 4783 | } |
| 4779 | } | 4784 | } |
| 4780 | 4785 | ||
| 4781 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4782 | timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); | ||
| 4783 | else | ||
| 4784 | timeout_ns = udev->u1_params.sel; | ||
| 4785 | |||
| 4786 | /* The U1 timeout is encoded in 1us intervals. | 4786 | /* The U1 timeout is encoded in 1us intervals. |
| 4787 | * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. | 4787 | * Don't return a timeout of zero, because that's USB3_LPM_DISABLED. |
| 4788 | */ | 4788 | */ |
| @@ -4834,19 +4834,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, · 45 unmodified lines | |||
| 4834 | { | 4834 | { |
| 4835 | unsigned long long timeout_ns; | 4835 | unsigned long long timeout_ns; |
| 4836 | 4836 | ||
| 4837 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4838 | timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | ||
| 4839 | else | ||
| 4840 | timeout_ns = udev->u2_params.sel; | ||
| 4841 | |||
| 4837 | /* Prevent U2 if service interval is shorter than U2 exit latency */ | 4842 | /* Prevent U2 if service interval is shorter than U2 exit latency */ |
| 4838 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { | 4843 | if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { |
| 4839 | if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { | 4844 | if (xhci_service_interval_to_ns(desc) <= timeout_ns) { |
| 4840 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); | 4845 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); |
| 4841 | return USB3_LPM_DISABLED; | 4846 | return USB3_LPM_DISABLED; |
| 4842 | } | 4847 | } |
| 4843 | } | 4848 | } |
| 4844 | 4849 | ||
| 4845 | if (xhci->quirks & XHCI_INTEL_HOST) | ||
| 4846 | timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); | ||
| 4847 | else | ||
| 4848 | timeout_ns = udev->u2_params.sel; | ||
| 4849 | |||
| 4850 | /* The U2 timeout is encoded in 256us intervals */ | 4850 | /* The U2 timeout is encoded in 256us intervals */ |
| 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); | 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); |
| 4852 | /* If the necessary timeout value is bigger than what we can set in the | 4852 | /* If the necessary timeout value is bigger than what we can set in the |
| @@ -496,6 +496,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, · 495 unmodified lines | |||
| 496 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); | 496 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); |
| 497 | finish_wait(&dev->waitq, &wait); | 497 | finish_wait(&dev->waitq, &wait); |
| 498 | 498 | ||
| 499 | /* make sure URB is idle after timeout or (spurious) CMD_ACK */ | ||
| 500 | usb_kill_urb(dev->cntl_urb); | ||
| 501 | |||
| 499 | mutex_unlock(&dev->io_mutex); | 502 | mutex_unlock(&dev->io_mutex); |
| 500 | 503 | ||
| 501 | if (retval < 0) { | 504 | if (retval < 0) { |
| @@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 531 unmodified lines | |||
| 532 | struct device *dev = &port->dev; | 532 | struct device *dev = &port->dev; |
| 533 | int i; | 533 | int i; |
| 534 | int status; | 534 | int status; |
| 535 | u8 rxcmd = IUU_UART_RX; | 535 | u8 *rxcmd; |
| 536 | struct iuu_private *priv = usb_get_serial_port_data(port); | 536 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 537 | 537 | ||
| 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) | 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) |
| 539 | return -EIO; | 539 | return -EIO; |
| 540 | 540 | ||
| 541 | rxcmd = kmalloc(1, GFP_KERNEL); | ||
| 542 | if (!rxcmd) | ||
| 543 | return -ENOMEM; | ||
| 544 | |||
| 545 | rxcmd[0] = IUU_UART_RX; | ||
| 546 | |||
| 541 | for (i = 0; i < 2; i++) { | 547 | for (i = 0; i < 2; i++) { |
| 542 | status = bulk_immediate(port, &rxcmd, 1); | 548 | status = bulk_immediate(port, rxcmd, 1); |
| 543 | if (status != IUU_OPERATION_OK) { | 549 | if (status != IUU_OPERATION_OK) { |
| 544 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); | 550 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); |
| 545 | return status; | 551 | goto out_free; |
| 546 | } | 552 | } |
| 547 | 553 | ||
| 548 | status = read_immediate(port, &priv->len, 1); | 554 | status = read_immediate(port, &priv->len, 1); |
| 549 | if (status != IUU_OPERATION_OK) { | 555 | if (status != IUU_OPERATION_OK) { |
| 550 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); | 556 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 551 | return status; | 557 | goto out_free; |
| 552 | } | 558 | } |
| 553 | 559 | ||
| 554 | if (priv->len > 0) { | 560 | if (priv->len > 0) { |
| @@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 1 unmodified line | |||
| 556 | status = read_immediate(port, priv->buf, priv->len); | 562 | status = read_immediate(port, priv->buf, priv->len); |
| 557 | if (status != IUU_OPERATION_OK) { | 563 | if (status != IUU_OPERATION_OK) { |
| 558 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); | 564 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 559 | return status; | 565 | goto out_free; |
| 560 | } | 566 | } |
| 561 | } | 567 | } |
| 562 | } | 568 | } |
| 563 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); | 569 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); |
| 564 | iuu_led(port, 0, 0xF000, 0, 0xFF); | 570 | iuu_led(port, 0, 0xF000, 0, 0xFF); |
| 571 | |||
| 572 | out_free: | ||
| 573 | kfree(rxcmd); | ||
| 574 | |||
| 565 | return status; | 575 | return status; |
| 566 | } | 576 | } |
| 567 | 577 | ||
| @@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = { · 1116 unmodified lines | |||
| 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), | 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, | 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1119 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, | 1119 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) }, |
| 1120 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */ | ||
| 1121 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) }, | ||
| 1120 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, | 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, |
| 1121 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, | 1123 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, |
| 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), | 1124 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10), |
| @@ -2057,6 +2059,7 @@ static const struct usb_device_id option_ids[] = { · 934 unmodified lines | |||
| 2057 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ | 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
| 2058 | .driver_info = RSVD(6) }, | 2060 | .driver_info = RSVD(6) }, |
| 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ | 2061 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) }, /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */ |
| 2062 | { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ | ||
| 2060 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ | 2063 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
| 2061 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ | 2064 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ |
| 2062 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ | 2065 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) }, /* GosunCn GM500 ECM/NCM */ |
| @@ -90,6 +90,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999, · 89 unmodified lines | |||
| 90 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 90 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 91 | US_FL_BROKEN_FUA), | 91 | US_FL_BROKEN_FUA), |
| 92 | 92 | ||
| 93 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ | ||
| 94 | UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999, | ||
| 95 | "PNY", | ||
| 96 | "Pro Elite SSD", | ||
| 97 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
| 98 | US_FL_NO_ATA_1X), | ||
| 99 | |||
| 93 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ | 100 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ |
| 94 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, | 101 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, |
| 95 | "PNY", | 102 | "PNY", |
| @@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE · 19 unmodified lines | |||
| 20 | to enable support for VirtualLink devices with NVIDIA GPUs. | 20 | to enable support for VirtualLink devices with NVIDIA GPUs. |
| 21 | 21 | ||
| 22 | To compile this driver as a module, choose M here: the | 22 | To compile this driver as a module, choose M here: the |
| 23 | module will be called typec_displayport. | 23 | module will be called typec_nvidia. |
| 24 | 24 | ||
| 25 | endmenu | 25 | endmenu |
| @@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod · 765 unmodified lines | |||
| 766 | return ret; | 766 | return ret; |
| 767 | 767 | ||
| 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); | 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); |
| 769 | kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); | ||
| 769 | 770 | ||
| 770 | return 0; | 771 | return 0; |
| 771 | } | 772 | } |
| @@ -923,6 +924,7 @@ int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes) · 151 unmodified lines | |||
| 923 | return ret; | 924 | return ret; |
| 924 | 925 | ||
| 925 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); | 926 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); |
| 927 | kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE); | ||
| 926 | 928 | ||
| 927 | return 0; | 929 | return 0; |
| 928 | } | 930 | } |
| @@ -207,10 +207,21 @@ static int · 206 unmodified lines | |||
| 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) | 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) |
| 208 | { | 208 | { |
| 209 | u8 msg[2] = { }; | 209 | u8 msg[2] = { }; |
| 210 | int ret; | ||
| 210 | 211 | ||
| 211 | msg[0] = PMC_USB_DP_HPD; | 212 | msg[0] = PMC_USB_DP_HPD; |
| 212 | msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; | 213 | msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT; |
| 213 | 214 | ||
| 215 | /* Configure HPD first if HPD,IRQ comes together */ | ||
| 216 | if (!IOM_PORT_HPD_ASSERTED(port->iom_status) && | ||
| 217 | dp->status & DP_STATUS_IRQ_HPD && | ||
| 218 | dp->status & DP_STATUS_HPD_STATE) { | ||
| 219 | msg[1] = PMC_USB_DP_HPD_LVL; | ||
| 220 | ret = pmc_usb_command(port, msg, sizeof(msg)); | ||
| 221 | if (ret) | ||
| 222 | return ret; | ||
| 223 | } | ||
| 224 | |||
| 214 | if (dp->status & DP_STATUS_IRQ_HPD) | 225 | if (dp->status & DP_STATUS_IRQ_HPD) |
| 215 | msg[1] = PMC_USB_DP_HPD_IRQ; | 226 | msg[1] = PMC_USB_DP_HPD_IRQ; |
| 216 | 227 | ||
| @@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, · 395 unmodified lines | |||
| 396 | default: | 396 | default: |
| 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", | 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", |
| 398 | wValue); | 398 | wValue); |
| 399 | if (wValue >= 32) | ||
| 400 | goto error; | ||
| 399 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); | 401 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); |
| 400 | break; | 402 | break; |
| 401 | } | 403 | } |
| @@ -52,6 +52,25 @@ static inline void kcov_remote_start_usb(u64 id) · 51 unmodified lines | |||
| 52 | kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id)); | 52 | kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id)); |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | /* | ||
| 56 | * The softirq flavor of kcov_remote_*() functions is introduced as a temporary | ||
| 57 | * work around for kcov's lack of nested remote coverage sections support in | ||
| 58 | * task context. Adding suport for nested sections is tracked in: | ||
| 59 | * https://bugzilla.kernel.org/show_bug.cgi?id=210337 | ||
| 60 | */ | ||
| 61 | |||
| 62 | static inline void kcov_remote_start_usb_softirq(u64 id) | ||
| 63 | { | ||
| 64 | if (in_serving_softirq()) | ||
| 65 | kcov_remote_start_usb(id); | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void kcov_remote_stop_softirq(void) | ||
| 69 | { | ||
| 70 | if (in_serving_softirq()) | ||
| 71 | kcov_remote_stop(); | ||
| 72 | } | ||
| 73 | |||
| 55 | #else | 74 | #else |
| 56 | 75 | ||
| 57 | static inline void kcov_task_init(struct task_struct *t) {} | 76 | static inline void kcov_task_init(struct task_struct *t) {} |
| @@ -66,6 +85,8 @@ static inline u64 kcov_common_handle(void) · 8 unmodified lines | |||
| 66 | } | 85 | } |
| 67 | static inline void kcov_remote_start_common(u64 id) {} | 86 | static inline void kcov_remote_start_common(u64 id) {} |
| 68 | static inline void kcov_remote_start_usb(u64 id) {} | 87 | static inline void kcov_remote_start_usb(u64 id) {} |
| 88 | static inline void kcov_remote_start_usb_softirq(u64 id) {} | ||
| 89 | static inline void kcov_remote_stop_softirq(void) {} | ||
| 69 | 90 | ||
| 70 | #endif /* CONFIG_KCOV */ | 91 | #endif /* CONFIG_KCOV */ |
| 71 | #endif /* _LINUX_KCOV_H */ | 92 | #endif /* _LINUX_KCOV_H */ |