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 | 12 | properties: |
| 13 | 13 | compatible: |
| 14 | − items: | |
| 14 | + oneOf: | |
| 15 | 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 | 21 | reg: |
| 18 | 22 | description: module registers |
| @@ -3883,7 +3883,7 @@ F: drivers/mtd/nand/raw/cadence-nand-controller.c · 3882 unmodified lines | ||
| 3883 | 3883 | CADENCE USB3 DRD IP DRIVER |
| 3884 | 3884 | M: Peter Chen <peter.chen@nxp.com> |
| 3885 | 3885 | M: Pawel Laszczak <pawell@cadence.com> |
| 3886 | −M: Roger Quadros <rogerq@ti.com> | |
| 3886 | +R: Roger Quadros <rogerq@kernel.org> | |
| 3887 | 3887 | R: Aswath Govindraju <a-govindraju@ti.com> |
| 3888 | 3888 | L: linux-usb@vger.kernel.org |
| 3889 | 3889 | S: Maintained |
| @@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev) · 138 unmodified lines | ||
| 139 | 139 | misc_pdev = of_find_device_by_node(args.np); |
| 140 | 140 | of_node_put(args.np); |
| 141 | 141 | |
| 142 | − if (!misc_pdev || !platform_get_drvdata(misc_pdev)) | |
| 142 | + if (!misc_pdev) | |
| 143 | 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 | 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 | 1895 | { USB_DEVICE(0x04d8, 0xfd08), |
| 1896 | 1896 | .driver_info = IGNORE_DEVICE, |
| 1897 | 1897 | }, |
| 1898 | + | |
| 1899 | + { USB_DEVICE(0x04d8, 0xf58b), | |
| 1900 | + .driver_info = IGNORE_DEVICE, | |
| 1901 | + }, | |
| 1898 | 1902 | #endif |
| 1899 | 1903 | |
| 1900 | 1904 | /*Samsung phone in firmware update mode */ |
| @@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc) · 464 unmodified lines | ||
| 465 | 465 | if (!desc->resp_count || !--desc->resp_count) |
| 466 | 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 | 477 | set_bit(WDM_RESPONDING, &desc->flags); |
| 469 | 478 | spin_unlock_irq(&desc->iuspin); |
| 470 | 479 | rv = usb_submit_urb(desc->response, GFP_KERNEL); |
| 471 | 480 | spin_lock_irq(&desc->iuspin); |
| 472 | 481 | if (rv) { |
| 473 | − dev_err(&desc->intf->dev, | |
| 474 | − "usb_submit_urb failed with result %d\n", rv); | |
| 482 | + if (!test_bit(WDM_DISCONNECTING, &desc->flags)) | |
| 483 | + dev_err(&desc->intf->dev, | |
| 484 | + "usb_submit_urb failed with result %d\n", rv); | |
| 475 | 485 | |
| 476 | 486 | /* make sure the next notification trigger a submit */ |
| 477 | 487 | clear_bit(WDM_RESPONDING, &desc->flags); |
| @@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf) · 549 unmodified lines | ||
| 1027 | 1037 | wake_up_all(&desc->wait); |
| 1028 | 1038 | mutex_lock(&desc->rlock); |
| 1029 | 1039 | mutex_lock(&desc->wlock); |
| 1030 | − kill_urbs(desc); | |
| 1031 | 1040 | cancel_work_sync(&desc->rxwork); |
| 1032 | 1041 | cancel_work_sync(&desc->service_outs_intr); |
| 1042 | + kill_urbs(desc); | |
| 1033 | 1043 | mutex_unlock(&desc->wlock); |
| 1034 | 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 | 274 | #define usblp_reset(usblp)\ |
| 275 | 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) \ | |
| 278 | − usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1) | |
| 277 | +static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel) | |
| 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 | 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 | 1649 | urb->status = status; |
| 1650 | 1650 | /* |
| 1651 | 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 | 1653 | * recursion yet. Only collect coverage in softirq context for now. |
| 1654 | 1654 | */ |
| 1655 | − if (in_serving_softirq()) | |
| 1656 | − kcov_remote_start_usb((u64)urb->dev->bus->busnum); | |
| 1655 | + kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum); | |
| 1657 | 1656 | urb->complete(urb); |
| 1658 | − if (in_serving_softirq()) | |
| 1659 | − kcov_remote_stop(); | |
| 1657 | + kcov_remote_stop_softirq(); | |
| 1660 | 1658 | |
| 1661 | 1659 | usb_anchor_resume_wakeups(anchor); |
| 1662 | 1660 | atomic_dec(&urb->use_count); |
| @@ -285,6 +285,7 @@ · 284 unmodified lines | ||
| 285 | 285 | |
| 286 | 286 | /* Global USB2 PHY Vendor Control Register */ |
| 287 | 287 | #define DWC3_GUSB2PHYACC_NEWREGREQ BIT(25) |
| 288 | +#define DWC3_GUSB2PHYACC_DONE BIT(24) | |
| 288 | 289 | #define DWC3_GUSB2PHYACC_BUSY BIT(23) |
| 289 | 290 | #define DWC3_GUSB2PHYACC_WRITE BIT(22) |
| 290 | 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 | 755 | ret = priv->drvdata->setup_regmaps(priv, base); |
| 756 | 756 | if (ret) |
| 757 | − return ret; | |
| 757 | + goto err_disable_clks; | |
| 758 | 758 | |
| 759 | 759 | if (priv->vbus) { |
| 760 | 760 | ret = regulator_enable(priv->vbus); |
| @@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, · 1762 unmodified lines | ||
| 1763 | 1763 | list_for_each_entry_safe(r, t, &dep->started_list, list) |
| 1764 | 1764 | dwc3_gadget_move_cancelled_request(r); |
| 1765 | 1765 | |
| 1766 | + dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE; | |
| 1767 | + | |
| 1766 | 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 | 2086 | static void dwc3_gadget_disable_irq(struct dwc3 *dwc); |
| 2085 | 2087 | static void __dwc3_gadget_stop(struct dwc3 *dwc); |
| 2088 | +static int __dwc3_gadget_start(struct dwc3 *dwc); | |
| 2086 | 2089 | |
| 2087 | 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 | 2148 | dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) % |
| 2146 | 2149 | dwc->ev_buf->length; |
| 2147 | 2150 | } |
| 2151 | + } else { | |
| 2152 | + __dwc3_gadget_start(dwc); | |
| 2148 | 2153 | } |
| 2149 | 2154 | |
| 2150 | 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 | 2326 | dwc->gadget_driver = driver; |
| 2322 | − | |
| 2323 | − if (pm_runtime_active(dwc->dev)) | |
| 2324 | − __dwc3_gadget_start(dwc); | |
| 2325 | − | |
| 2326 | 2327 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2327 | 2328 | |
| 2328 | 2329 | return 0; |
| @@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g) · 19 unmodified lines | ||
| 2348 | 2349 | unsigned long flags; |
| 2349 | 2350 | |
| 2350 | 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 | 2352 | dwc->gadget_driver = NULL; |
| 2359 | 2353 | spin_unlock_irqrestore(&dwc->lock, flags); |
| 2360 | 2354 | |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> |
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | +#include <linux/delay.h> | |
| 11 | +#include <linux/time64.h> | |
| 10 | 12 | #include <linux/ulpi/regs.h> |
| 11 | 13 | |
| 12 | 14 | #include "core.h" |
| @@ -17,14 +19,28 @@ · 4 unmodified lines | ||
| 17 | 19 | DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ |
| 18 | 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 | 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 | 40 | while (count--) { |
| 41 | + ndelay(ns); | |
| 26 | 42 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); |
| 27 | − if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | |
| 43 | + if (reg & DWC3_GUSB2PHYACC_DONE) | |
| 28 | 44 | return 0; |
| 29 | 45 | cpu_relax(); |
| 30 | 46 | } |
| @@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr) · 7 unmodified lines | ||
| 38 | 54 | u32 reg; |
| 39 | 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 | 57 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 48 | 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 | 61 | if (ret) |
| 52 | 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 | 71 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 62 | 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 | 74 | reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); |
| 71 | 75 | reg |= DWC3_GUSB2PHYACC_WRITE | val; |
| 72 | 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 | 81 | static const struct ulpi_ops dwc3_ulpi_ops = { |
| @@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM · 264 unmodified lines | ||
| 265 | 265 | depends on NET |
| 266 | 266 | select USB_U_ETHER |
| 267 | 267 | select USB_F_NCM |
| 268 | + select CRC32 | |
| 268 | 269 | help |
| 269 | 270 | NCM is an advanced protocol for Ethernet encapsulation, allows |
| 270 | 271 | grouping of several ethernet frames into one USB transfer and |
| @@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM · 43 unmodified lines | ||
| 314 | 315 | depends on NET |
| 315 | 316 | select USB_U_ETHER |
| 316 | 317 | select USB_F_EEM |
| 318 | + select CRC32 | |
| 317 | 319 | help |
| 318 | 320 | CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM |
| 319 | 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 | 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 | 397 | status = usb_gadget_deactivate(cdev->gadget); |
| 398 | + spin_lock_irqsave(&cdev->lock, flags); | |
| 399 | + } | |
| 397 | 400 | if (status == 0) |
| 398 | 401 | cdev->deactivations++; |
| 399 | 402 | |
| @@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function) · 24 unmodified lines | ||
| 424 | 427 | status = -EINVAL; |
| 425 | 428 | else { |
| 426 | 429 | cdev->deactivations--; |
| 427 | − if (cdev->deactivations == 0) | |
| 430 | + if (cdev->deactivations == 0) { | |
| 431 | + spin_unlock_irqrestore(&cdev->lock, flags); | |
| 428 | 432 | status = usb_gadget_activate(cdev->gadget); |
| 433 | + spin_lock_irqsave(&cdev->lock, flags); | |
| 434 | + } | |
| 429 | 435 | } |
| 430 | 436 | |
| 431 | 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 | 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 | 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 | 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 | 1261 | if (f->unbind) { |
| 1255 | 1262 | dev_dbg(&gi->cdev.gadget->dev, |
| 1256 | 1263 | "unbind function '%s'/%p\n", |
| @@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = { · 279 unmodified lines | ||
| 1536 | 1543 | .suspend = configfs_composite_suspend, |
| 1537 | 1544 | .resume = configfs_composite_resume, |
| 1538 | 1545 | |
| 1539 | − .max_speed = USB_SPEED_SUPER, | |
| 1546 | + .max_speed = USB_SPEED_SUPER_PLUS, | |
| 1540 | 1547 | .driver = { |
| 1541 | 1548 | .owner = THIS_MODULE, |
| 1542 | 1549 | .name = "configfs-gadget", |
| @@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make( · 33 unmodified lines | ||
| 1576 | 1583 | gi->composite.unbind = configfs_do_nothing; |
| 1577 | 1584 | gi->composite.suspend = NULL; |
| 1578 | 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 | 1588 | spin_lock_init(&gi->spinlock); |
| 1582 | 1589 | mutex_init(&gi->lock); |
| @@ -1162,6 +1162,7 @@ fail_tx_reqs: · 1161 unmodified lines | ||
| 1162 | 1162 | printer_req_free(dev->in_ep, req); |
| 1163 | 1163 | } |
| 1164 | 1164 | |
| 1165 | + usb_free_all_descriptors(f); | |
| 1165 | 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 | 272 | .bEndpointAddress = USB_DIR_OUT, |
| 273 | 273 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 274 | − .wMaxPacketSize = cpu_to_le16(1023), | |
| 274 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 275 | 275 | .bInterval = 1, |
| 276 | 276 | }; |
| 277 | 277 | |
| @@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { · 2 unmodified lines | ||
| 280 | 280 | .bDescriptorType = USB_DT_ENDPOINT, |
| 281 | 281 | |
| 282 | 282 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 283 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 283 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 284 | 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 | 349 | .bEndpointAddress = USB_DIR_IN, |
| 350 | 350 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 351 | − .wMaxPacketSize = cpu_to_le16(1023), | |
| 351 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 352 | 352 | .bInterval = 1, |
| 353 | 353 | }; |
| 354 | 354 | |
| @@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { · 2 unmodified lines | ||
| 357 | 357 | .bDescriptorType = USB_DT_ENDPOINT, |
| 358 | 358 | |
| 359 | 359 | .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, |
| 360 | − .wMaxPacketSize = cpu_to_le16(1024), | |
| 360 | + /* .wMaxPacketSize = DYNAMIC */ | |
| 361 | 361 | .bInterval = 4, |
| 362 | 362 | }; |
| 363 | 363 | |
| @@ -444,12 +444,28 @@ struct cntrl_range_lay3 { · 80 unmodified lines | ||
| 444 | 444 | __le32 dRES; |
| 445 | 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 | 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 | 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 | 470 | if (is_playback) { |
| 455 | 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 | 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 | 481 | DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1))); |
| 466 | − ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size, | |
| 467 | − le16_to_cpu(ep_desc->wMaxPacketSize))); | |
| 482 | + ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw, | |
| 483 | + max_size_ep)); | |
| 484 | + | |
| 485 | + return 0; | |
| 468 | 486 | } |
| 469 | 487 | |
| 470 | 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 | 690 | /* Calculate wMaxPacketSize according to audio bandwidth */ |
| 673 | − set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true); | |
| 674 | − set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false); | |
| 675 | − set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true); | |
| 676 | − set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false); | |
| 691 | + ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, | |
| 692 | + true); | |
| 693 | + if (ret < 0) { | |
| 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 | 719 | if (EPOUT_EN(uac2_opts)) { |
| 679 | 720 | agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); |
| @@ -45,9 +45,10 @@ · 44 unmodified lines | ||
| 45 | 45 | #define UETH__VERSION "29-May-2008" |
| 46 | 46 | |
| 47 | 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 | 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 | 53 | struct eth_dev { |
| 53 | 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 | 788 | /* MTU range: 14 - 15412 */ |
| 788 | 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 | 792 | dev->gadget = g; |
| 792 | 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 | 850 | /* MTU range: 14 - 15412 */ |
| 850 | 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 | 854 | return net; |
| 854 | 855 | } |
| @@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev) · 199 unmodified lines | ||
| 200 | 200 | struct usb_descriptor_header *usb_desc; |
| 201 | 201 | |
| 202 | 202 | usb_desc = usb_otg_descriptor_alloc(gadget); |
| 203 | − if (!usb_desc) | |
| 203 | + if (!usb_desc) { | |
| 204 | + status = -ENOMEM; | |
| 204 | 205 | goto fail_string_ids; |
| 206 | + } | |
| 205 | 207 | usb_otg_descriptor_init(gadget, usb_desc); |
| 206 | 208 | otg_desc[0] = usb_desc; |
| 207 | 209 | otg_desc[1] = NULL; |
| @@ -90,7 +90,7 @@ config USB_BCM63XX_UDC · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | config USB_FSL_USB2 |
| 92 | 92 | tristate "Freescale Highspeed USB DR Peripheral Controller" |
| 93 | − depends on FSL_SOC || ARCH_MXC | |
| 93 | + depends on FSL_SOC | |
| 94 | 94 | help |
| 95 | 95 | Some of Freescale PowerPC and i.MX processors have a High Speed |
| 96 | 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 | 23 | obj-$(CONFIG_USB_BCM63XX_UDC) += bcm63xx_udc.o |
| 24 | 24 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
| 25 | 25 | fsl_usb2_udc-y := fsl_udc_core.o |
| 26 | −fsl_usb2_udc-$(CONFIG_ARCH_MXC) += fsl_mxc_udc.o | |
| 27 | 26 | obj-$(CONFIG_USB_TEGRA_XUDC) += tegra-xudc.o |
| 28 | 27 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
| 29 | 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 | 660 | * Enables the D+ (or potentially D-) pullup. The host will start |
| 661 | 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 | |
| 663 | − * usb_gadget_disconnect() has been used to disable it. | |
| 662 | + * is active (the link is powered). | |
| 664 | 663 | * |
| 665 | 664 | * Returns zero on success, else negative errno. |
| 666 | 665 | */ |
| @@ -2118,9 +2118,21 @@ static int dummy_hub_control( · 2117 unmodified lines | ||
| 2118 | 2118 | dum_hcd->port_status &= ~USB_PORT_STAT_POWER; |
| 2119 | 2119 | set_link_state(dum_hcd); |
| 2120 | 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 | 2130 | dum_hcd->port_status &= ~(1 << wValue); |
| 2123 | 2131 | set_link_state(dum_hcd); |
| 2132 | + break; | |
| 2133 | + default: | |
| 2134 | + /* Disallow INDICATOR and C_OVER_CURRENT */ | |
| 2135 | + goto error; | |
| 2124 | 2136 | } |
| 2125 | 2137 | break; |
| 2126 | 2138 | case GetHubDescriptor: |
| @@ -2281,18 +2293,17 @@ static int dummy_hub_control( · 154 unmodified lines | ||
| 2281 | 2293 | */ |
| 2282 | 2294 | dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50); |
| 2283 | 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 | 2304 | default: |
| 2285 | − if (hcd->speed == HCD_USB3) { | |
| 2286 | − if ((dum_hcd->port_status & | |
| 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); | |
| 2305 | + /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */ | |
| 2306 | + goto error; | |
| 2296 | 2307 | } |
| 2297 | 2308 | break; |
| 2298 | 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 | 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 | 4778 | /* Prevent U1 if service interval is shorter than U1 exit latency */ |
| 4774 | 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 | 4781 | dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); |
| 4777 | 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 | 4786 | /* The U1 timeout is encoded in 1us intervals. |
| 4787 | 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 | 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 | 4842 | /* Prevent U2 if service interval is shorter than U2 exit latency */ |
| 4838 | 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 | 4845 | dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); |
| 4841 | 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 | 4850 | /* The U2 timeout is encoded in 256us intervals */ |
| 4851 | 4851 | timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000); |
| 4852 | 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 | 496 | timeout = schedule_timeout(YUREX_WRITE_TIMEOUT); |
| 497 | 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 | 502 | mutex_unlock(&dev->io_mutex); |
| 500 | 503 | |
| 501 | 504 | if (retval < 0) { |
| @@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 531 unmodified lines | ||
| 532 | 532 | struct device *dev = &port->dev; |
| 533 | 533 | int i; |
| 534 | 534 | int status; |
| 535 | − u8 rxcmd = IUU_UART_RX; | |
| 535 | + u8 *rxcmd; | |
| 536 | 536 | struct iuu_private *priv = usb_get_serial_port_data(port); |
| 537 | 537 | |
| 538 | 538 | if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0) |
| 539 | 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 | 547 | for (i = 0; i < 2; i++) { |
| 542 | − status = bulk_immediate(port, &rxcmd, 1); | |
| 548 | + status = bulk_immediate(port, rxcmd, 1); | |
| 543 | 549 | if (status != IUU_OPERATION_OK) { |
| 544 | 550 | dev_dbg(dev, "%s - uart_flush_write error\n", __func__); |
| 545 | − return status; | |
| 551 | + goto out_free; | |
| 546 | 552 | } |
| 547 | 553 | |
| 548 | 554 | status = read_immediate(port, &priv->len, 1); |
| 549 | 555 | if (status != IUU_OPERATION_OK) { |
| 550 | 556 | dev_dbg(dev, "%s - uart_flush_read error\n", __func__); |
| 551 | − return status; | |
| 557 | + goto out_free; | |
| 552 | 558 | } |
| 553 | 559 | |
| 554 | 560 | if (priv->len > 0) { |
| @@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port) · 1 unmodified line | ||
| 556 | 562 | status = read_immediate(port, priv->buf, priv->len); |
| 557 | 563 | if (status != IUU_OPERATION_OK) { |
| 558 | 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 | 569 | dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__); |
| 564 | 570 | iuu_led(port, 0, 0xF000, 0, 0xFF); |
| 571 | + | |
| 572 | +out_free: | |
| 573 | + kfree(rxcmd); | |
| 574 | + | |
| 565 | 575 | return status; |
| 566 | 576 | } |
| 567 | 577 | |
| @@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = { · 1116 unmodified lines | ||
| 1117 | 1117 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff), |
| 1118 | 1118 | .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, |
| 1119 | 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 | 1122 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) }, |
| 1121 | 1123 | { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) }, |
| 1122 | 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 | 2059 | { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff), /* Fibocom NL678 series */ |
| 2058 | 2060 | .driver_info = RSVD(6) }, |
| 2059 | 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 | 2063 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ |
| 2061 | 2064 | { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */ |
| 2062 | 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 | 90 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
| 91 | 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 | 100 | /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */ |
| 94 | 101 | UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999, |
| 95 | 102 | "PNY", |
| @@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE · 19 unmodified lines | ||
| 20 | 20 | to enable support for VirtualLink devices with NVIDIA GPUs. |
| 21 | 21 | |
| 22 | 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 | 25 | endmenu |
| @@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod · 765 unmodified lines | ||
| 766 | 766 | return ret; |
| 767 | 767 | |
| 768 | 768 | sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes"); |
| 769 | + kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE); | |
| 769 | 770 | |
| 770 | 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 | 924 | return ret; |
| 924 | 925 | |
| 925 | 926 | sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes"); |
| 927 | + kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE); | |
| 926 | 928 | |
| 927 | 929 | return 0; |
| 928 | 930 | } |
| @@ -207,10 +207,21 @@ static int · 206 unmodified lines | ||
| 207 | 207 | pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp) |
| 208 | 208 | { |
| 209 | 209 | u8 msg[2] = { }; |
| 210 | + int ret; | |
| 210 | 211 | |
| 211 | 212 | msg[0] = PMC_USB_DP_HPD; |
| 212 | 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 | 225 | if (dp->status & DP_STATUS_IRQ_HPD) |
| 215 | 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 | 396 | default: |
| 397 | 397 | usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n", |
| 398 | 398 | wValue); |
| 399 | + if (wValue >= 32) | |
| 400 | + goto error; | |
| 399 | 401 | vhci_hcd->port_status[rhport] &= ~(1 << wValue); |
| 400 | 402 | break; |
| 401 | 403 | } |
| @@ -52,6 +52,25 @@ static inline void kcov_remote_start_usb(u64 id) · 51 unmodified lines | ||
| 52 | 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 | 74 | #else |
| 56 | 75 | |
| 57 | 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 | 86 | static inline void kcov_remote_start_common(u64 id) {} |
| 68 | 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 | 91 | #endif /* CONFIG_KCOV */ |
| 71 | 92 | #endif /* _LINUX_KCOV_H */ |