Commit 1abc088a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes for -rc4.

  The usual suspects of gadget, xhci, and dwc2/3 are in here, along with
  some reverts of reported problem changes, and a number of build
  documentation warning fixes. Full details are in the shortlog.

  All of these have been in linux-next with no reported issues"

* tag 'usb-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (28 commits)
  Revert "cdc-acm: implement put_char() and flush_chars()"
  usb: Change usb_of_get_companion_dev() place to usb/common
  usb: xhci: fix interrupt transfer error happened on MTK platforms
  usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()
  usb: misc: uss720: Fix two sleep-in-atomic-context bugs
  usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame()
  usb: Avoid use-after-free by flushing endpoints early in usb_set_interface()
  linux/mod_devicetable.h: fix kernel-doc missing notation for typec_device_id
  usb/typec: fix kernel-doc notation warning for typec_match_altmode
  usb: Don't die twice if PCI xhci host is not responding in resume
  usb: mtu3: fix error of xhci port id when enable U3 dual role
  usb: uas: add support for more quirk flags
  USB: Add quirk to support DJI CineSSD
  usb: typec: fix kernel-doc parameter warning
  usb/dwc3/gadget: fix kernel-doc parameter warning
  USB: yurex: Check for truncation in yurex_read()
  USB: yurex: Fix buffer over-read in yurex_write()
  usb: host: xhci-plat: Iterate over parent nodes for finding quirks
  xhci: Fix use after free for URB cancellation on a reallocated endpoint
  USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller
  ...
parents c284cf06 df3aa13c
...@@ -780,20 +780,9 @@ static int acm_tty_write(struct tty_struct *tty, ...@@ -780,20 +780,9 @@ static int acm_tty_write(struct tty_struct *tty,
} }
if (acm->susp_count) { if (acm->susp_count) {
if (acm->putbuffer) {
/* now to preserve order */
usb_anchor_urb(acm->putbuffer->urb, &acm->delayed);
acm->putbuffer = NULL;
}
usb_anchor_urb(wb->urb, &acm->delayed); usb_anchor_urb(wb->urb, &acm->delayed);
spin_unlock_irqrestore(&acm->write_lock, flags); spin_unlock_irqrestore(&acm->write_lock, flags);
return count; return count;
} else {
if (acm->putbuffer) {
/* at this point there is no good way to handle errors */
acm_start_wb(acm, acm->putbuffer);
acm->putbuffer = NULL;
}
} }
stat = acm_start_wb(acm, wb); stat = acm_start_wb(acm, wb);
...@@ -804,66 +793,6 @@ static int acm_tty_write(struct tty_struct *tty, ...@@ -804,66 +793,6 @@ static int acm_tty_write(struct tty_struct *tty,
return count; return count;
} }
static void acm_tty_flush_chars(struct tty_struct *tty)
{
struct acm *acm = tty->driver_data;
struct acm_wb *cur;
int err;
unsigned long flags;
spin_lock_irqsave(&acm->write_lock, flags);
cur = acm->putbuffer;
if (!cur) /* nothing to do */
goto out;
acm->putbuffer = NULL;
err = usb_autopm_get_interface_async(acm->control);
if (err < 0) {
cur->use = 0;
acm->putbuffer = cur;
goto out;
}
if (acm->susp_count)
usb_anchor_urb(cur->urb, &acm->delayed);
else
acm_start_wb(acm, cur);
out:
spin_unlock_irqrestore(&acm->write_lock, flags);
return;
}
static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
struct acm *acm = tty->driver_data;
struct acm_wb *cur;
int wbn;
unsigned long flags;
overflow:
cur = acm->putbuffer;
if (!cur) {
spin_lock_irqsave(&acm->write_lock, flags);
wbn = acm_wb_alloc(acm);
if (wbn >= 0) {
cur = &acm->wb[wbn];
acm->putbuffer = cur;
}
spin_unlock_irqrestore(&acm->write_lock, flags);
if (!cur)
return 0;
}
if (cur->len == acm->writesize) {
acm_tty_flush_chars(tty);
goto overflow;
}
cur->buf[cur->len++] = ch;
return 1;
}
static int acm_tty_write_room(struct tty_struct *tty) static int acm_tty_write_room(struct tty_struct *tty)
{ {
struct acm *acm = tty->driver_data; struct acm *acm = tty->driver_data;
...@@ -1987,8 +1916,6 @@ static const struct tty_operations acm_ops = { ...@@ -1987,8 +1916,6 @@ static const struct tty_operations acm_ops = {
.cleanup = acm_tty_cleanup, .cleanup = acm_tty_cleanup,
.hangup = acm_tty_hangup, .hangup = acm_tty_hangup,
.write = acm_tty_write, .write = acm_tty_write,
.put_char = acm_tty_put_char,
.flush_chars = acm_tty_flush_chars,
.write_room = acm_tty_write_room, .write_room = acm_tty_write_room,
.ioctl = acm_tty_ioctl, .ioctl = acm_tty_ioctl,
.throttle = acm_tty_throttle, .throttle = acm_tty_throttle,
......
...@@ -96,7 +96,6 @@ struct acm { ...@@ -96,7 +96,6 @@ struct acm {
unsigned long read_urbs_free; unsigned long read_urbs_free;
struct urb *read_urbs[ACM_NR]; struct urb *read_urbs[ACM_NR];
struct acm_rb read_buffers[ACM_NR]; struct acm_rb read_buffers[ACM_NR];
struct acm_wb *putbuffer; /* for acm_tty_put_char() */
int rx_buflimit; int rx_buflimit;
spinlock_t read_lock; spinlock_t read_lock;
u8 *notification_buffer; /* to reassemble fragmented notifications */ u8 *notification_buffer; /* to reassemble fragmented notifications */
......
...@@ -460,7 +460,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc) ...@@ -460,7 +460,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
set_bit(WDM_RESPONDING, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags);
spin_unlock_irq(&desc->iuspin); spin_unlock_irq(&desc->iuspin);
rv = usb_submit_urb(desc->response, GFP_KERNEL); rv = usb_submit_urb(desc->response, GFP_ATOMIC);
spin_lock_irq(&desc->iuspin); spin_lock_irq(&desc->iuspin);
if (rv) { if (rv) {
dev_err(&desc->intf->dev, dev_err(&desc->intf->dev,
......
...@@ -246,6 +246,31 @@ int of_usb_update_otg_caps(struct device_node *np, ...@@ -246,6 +246,31 @@ int of_usb_update_otg_caps(struct device_node *np,
} }
EXPORT_SYMBOL_GPL(of_usb_update_otg_caps); EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);
/**
* usb_of_get_companion_dev - Find the companion device
* @dev: the device pointer to find a companion
*
* Find the companion device from platform bus.
*
* Takes a reference to the returned struct device which needs to be dropped
* after use.
*
* Return: On success, a pointer to the companion device, %NULL on failure.
*/
struct device *usb_of_get_companion_dev(struct device *dev)
{
struct device_node *node;
struct platform_device *pdev = NULL;
node = of_parse_phandle(dev->of_node, "companion", 0);
if (node)
pdev = of_find_device_by_node(node);
of_node_put(node);
return pdev ? &pdev->dev : NULL;
}
EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
#endif #endif
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -515,8 +515,6 @@ static int resume_common(struct device *dev, int event) ...@@ -515,8 +515,6 @@ static int resume_common(struct device *dev, int event)
event == PM_EVENT_RESTORE); event == PM_EVENT_RESTORE);
if (retval) { if (retval) {
dev_err(dev, "PCI post-resume error %d!\n", retval); dev_err(dev, "PCI post-resume error %d!\n", retval);
if (hcd->shared_hcd)
usb_hc_died(hcd->shared_hcd);
usb_hc_died(hcd); usb_hc_died(hcd);
} }
} }
......
...@@ -1341,6 +1341,11 @@ void usb_enable_interface(struct usb_device *dev, ...@@ -1341,6 +1341,11 @@ void usb_enable_interface(struct usb_device *dev,
* is submitted that needs that bandwidth. Some other operating systems * is submitted that needs that bandwidth. Some other operating systems
* allocate bandwidth early, when a configuration is chosen. * allocate bandwidth early, when a configuration is chosen.
* *
* xHCI reserves bandwidth and configures the alternate setting in
* usb_hcd_alloc_bandwidth(). If it fails the original interface altsetting
* may be disabled. Drivers cannot rely on any particular alternate
* setting being in effect after a failure.
*
* This call is synchronous, and may not be used in an interrupt context. * This call is synchronous, and may not be used in an interrupt context.
* Also, drivers must not change altsettings while urbs are scheduled for * Also, drivers must not change altsettings while urbs are scheduled for
* endpoints in that interface; all such urbs must first be completed * endpoints in that interface; all such urbs must first be completed
...@@ -1376,6 +1381,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) ...@@ -1376,6 +1381,12 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
alternate); alternate);
return -EINVAL; return -EINVAL;
} }
/*
* usb3 hosts configure the interface in usb_hcd_alloc_bandwidth,
* including freeing dropped endpoint ring buffers.
* Make sure the interface endpoints are flushed before that
*/
usb_disable_interface(dev, iface, false);
/* Make sure we have enough bandwidth for this alternate interface. /* Make sure we have enough bandwidth for this alternate interface.
* Remove the current alt setting and add the new alt setting. * Remove the current alt setting and add the new alt setting.
......
...@@ -105,29 +105,3 @@ usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum) ...@@ -105,29 +105,3 @@ usb_of_get_interface_node(struct usb_device *udev, u8 config, u8 ifnum)
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(usb_of_get_interface_node); EXPORT_SYMBOL_GPL(usb_of_get_interface_node);
/**
* usb_of_get_companion_dev - Find the companion device
* @dev: the device pointer to find a companion
*
* Find the companion device from platform bus.
*
* Takes a reference to the returned struct device which needs to be dropped
* after use.
*
* Return: On success, a pointer to the companion device, %NULL on failure.
*/
struct device *usb_of_get_companion_dev(struct device *dev)
{
struct device_node *node;
struct platform_device *pdev = NULL;
node = of_parse_phandle(dev->of_node, "companion", 0);
if (node)
pdev = of_find_device_by_node(node);
of_node_put(node);
return pdev ? &pdev->dev : NULL;
}
EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
...@@ -178,6 +178,10 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -178,6 +178,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* CBM - Flash disk */ /* CBM - Flash disk */
{ USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME },
/* WORLDE Controller KS49 or Prodipe MIDI 49C USB controller */
{ USB_DEVICE(0x0218, 0x0201), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
/* WORLDE easy key (easykey.25) MIDI controller */ /* WORLDE easy key (easykey.25) MIDI controller */
{ USB_DEVICE(0x0218, 0x0401), .driver_info = { USB_DEVICE(0x0218, 0x0401), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS }, USB_QUIRK_CONFIG_INTF_STRINGS },
...@@ -406,6 +410,9 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -406,6 +410,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x2040, 0x7200), .driver_info = { USB_DEVICE(0x2040, 0x7200), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS }, USB_QUIRK_CONFIG_INTF_STRINGS },
/* DJI CineSSD */
{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
/* INTEL VALUE SSD */ /* INTEL VALUE SSD */
{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
......
...@@ -412,8 +412,6 @@ static int dwc2_driver_probe(struct platform_device *dev) ...@@ -412,8 +412,6 @@ static int dwc2_driver_probe(struct platform_device *dev)
dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n", dev_dbg(&dev->dev, "mapped PA %08lx to VA %p\n",
(unsigned long)res->start, hsotg->regs); (unsigned long)res->start, hsotg->regs);
hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
retval = dwc2_lowlevel_hw_init(hsotg); retval = dwc2_lowlevel_hw_init(hsotg);
if (retval) if (retval)
return retval; return retval;
...@@ -438,6 +436,8 @@ static int dwc2_driver_probe(struct platform_device *dev) ...@@ -438,6 +436,8 @@ static int dwc2_driver_probe(struct platform_device *dev)
if (retval) if (retval)
return retval; return retval;
hsotg->needs_byte_swap = dwc2_check_core_endianness(hsotg);
retval = dwc2_get_dr_mode(hsotg); retval = dwc2_get_dr_mode(hsotg);
if (retval) if (retval)
goto error; goto error;
......
...@@ -180,8 +180,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev) ...@@ -180,8 +180,7 @@ static int dwc3_of_simple_remove(struct platform_device *pdev)
return 0; return 0;
} }
#ifdef CONFIG_PM static int __maybe_unused dwc3_of_simple_runtime_suspend(struct device *dev)
static int dwc3_of_simple_runtime_suspend(struct device *dev)
{ {
struct dwc3_of_simple *simple = dev_get_drvdata(dev); struct dwc3_of_simple *simple = dev_get_drvdata(dev);
int i; int i;
...@@ -192,7 +191,7 @@ static int dwc3_of_simple_runtime_suspend(struct device *dev) ...@@ -192,7 +191,7 @@ static int dwc3_of_simple_runtime_suspend(struct device *dev)
return 0; return 0;
} }
static int dwc3_of_simple_runtime_resume(struct device *dev) static int __maybe_unused dwc3_of_simple_runtime_resume(struct device *dev)
{ {
struct dwc3_of_simple *simple = dev_get_drvdata(dev); struct dwc3_of_simple *simple = dev_get_drvdata(dev);
int ret; int ret;
...@@ -210,7 +209,7 @@ static int dwc3_of_simple_runtime_resume(struct device *dev) ...@@ -210,7 +209,7 @@ static int dwc3_of_simple_runtime_resume(struct device *dev)
return 0; return 0;
} }
static int dwc3_of_simple_suspend(struct device *dev) static int __maybe_unused dwc3_of_simple_suspend(struct device *dev)
{ {
struct dwc3_of_simple *simple = dev_get_drvdata(dev); struct dwc3_of_simple *simple = dev_get_drvdata(dev);
...@@ -220,7 +219,7 @@ static int dwc3_of_simple_suspend(struct device *dev) ...@@ -220,7 +219,7 @@ static int dwc3_of_simple_suspend(struct device *dev)
return 0; return 0;
} }
static int dwc3_of_simple_resume(struct device *dev) static int __maybe_unused dwc3_of_simple_resume(struct device *dev)
{ {
struct dwc3_of_simple *simple = dev_get_drvdata(dev); struct dwc3_of_simple *simple = dev_get_drvdata(dev);
...@@ -229,7 +228,6 @@ static int dwc3_of_simple_resume(struct device *dev) ...@@ -229,7 +228,6 @@ static int dwc3_of_simple_resume(struct device *dev)
return 0; return 0;
} }
#endif
static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = { static const struct dev_pm_ops dwc3_of_simple_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_of_simple_suspend, dwc3_of_simple_resume) SET_SYSTEM_SLEEP_PM_OPS(dwc3_of_simple_suspend, dwc3_of_simple_resume)
......
...@@ -85,8 +85,8 @@ static int dwc3_byt_enable_ulpi_refclock(struct pci_dev *pci) ...@@ -85,8 +85,8 @@ static int dwc3_byt_enable_ulpi_refclock(struct pci_dev *pci)
u32 value; u32 value;
reg = pcim_iomap(pci, GP_RWBAR, 0); reg = pcim_iomap(pci, GP_RWBAR, 0);
if (IS_ERR(reg)) if (!reg)
return PTR_ERR(reg); return -ENOMEM;
value = readl(reg + GP_RWREG1); value = readl(reg + GP_RWREG1);
if (!(value & GP_RWREG1_ULPI_REFCLK_DISABLE)) if (!(value & GP_RWREG1_ULPI_REFCLK_DISABLE))
......
...@@ -473,7 +473,6 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep) ...@@ -473,7 +473,6 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep)
/** /**
* dwc3_gadget_start_config - configure ep resources * dwc3_gadget_start_config - configure ep resources
* @dwc: pointer to our controller context structure
* @dep: endpoint that is being enabled * @dep: endpoint that is being enabled
* *
* Issue a %DWC3_DEPCMD_DEPSTARTCFG command to @dep. After the command's * Issue a %DWC3_DEPCMD_DEPSTARTCFG command to @dep. After the command's
......
...@@ -1063,12 +1063,15 @@ static const struct usb_gadget_ops fotg210_gadget_ops = { ...@@ -1063,12 +1063,15 @@ static const struct usb_gadget_ops fotg210_gadget_ops = {
static int fotg210_udc_remove(struct platform_device *pdev) static int fotg210_udc_remove(struct platform_device *pdev)
{ {
struct fotg210_udc *fotg210 = platform_get_drvdata(pdev); struct fotg210_udc *fotg210 = platform_get_drvdata(pdev);
int i;
usb_del_gadget_udc(&fotg210->gadget); usb_del_gadget_udc(&fotg210->gadget);
iounmap(fotg210->reg); iounmap(fotg210->reg);
free_irq(platform_get_irq(pdev, 0), fotg210); free_irq(platform_get_irq(pdev, 0), fotg210);
fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req); fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
kfree(fotg210->ep[i]);
kfree(fotg210); kfree(fotg210);
return 0; return 0;
...@@ -1099,7 +1102,7 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1099,7 +1102,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
/* initialize udc */ /* initialize udc */
fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL);
if (fotg210 == NULL) if (fotg210 == NULL)
goto err_alloc; goto err;
for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { for (i = 0; i < FOTG210_MAX_NUM_EP; i++) {
_ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); _ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL);
...@@ -1111,7 +1114,7 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1111,7 +1114,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
fotg210->reg = ioremap(res->start, resource_size(res)); fotg210->reg = ioremap(res->start, resource_size(res));
if (fotg210->reg == NULL) { if (fotg210->reg == NULL) {
pr_err("ioremap error.\n"); pr_err("ioremap error.\n");
goto err_map; goto err_alloc;
} }
spin_lock_init(&fotg210->lock); spin_lock_init(&fotg210->lock);
...@@ -1159,7 +1162,7 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1159,7 +1162,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
fotg210->ep0_req = fotg210_ep_alloc_request(&fotg210->ep[0]->ep, fotg210->ep0_req = fotg210_ep_alloc_request(&fotg210->ep[0]->ep,
GFP_KERNEL); GFP_KERNEL);
if (fotg210->ep0_req == NULL) if (fotg210->ep0_req == NULL)
goto err_req; goto err_map;
fotg210_init(fotg210); fotg210_init(fotg210);
...@@ -1187,12 +1190,14 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1187,12 +1190,14 @@ static int fotg210_udc_probe(struct platform_device *pdev)
fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req); fotg210_ep_free_request(&fotg210->ep[0]->ep, fotg210->ep0_req);
err_map: err_map:
if (fotg210->reg) iounmap(fotg210->reg);
iounmap(fotg210->reg);
err_alloc: err_alloc:
for (i = 0; i < FOTG210_MAX_NUM_EP; i++)
kfree(fotg210->ep[i]);
kfree(fotg210); kfree(fotg210);
err:
return ret; return ret;
} }
......
...@@ -1545,11 +1545,14 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on) ...@@ -1545,11 +1545,14 @@ static int net2280_pullup(struct usb_gadget *_gadget, int is_on)
writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); writel(tmp | BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
} else { } else {
writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl); writel(tmp & ~BIT(USB_DETECT_ENABLE), &dev->usb->usbctl);
stop_activity(dev, dev->driver); stop_activity(dev, NULL);
} }
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
if (!is_on && dev->driver)
dev->driver->disconnect(&dev->gadget);
return 0; return 0;
} }
...@@ -2466,8 +2469,11 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver) ...@@ -2466,8 +2469,11 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
nuke(&dev->ep[i]); nuke(&dev->ep[i]);
/* report disconnect; the driver is already quiesced */ /* report disconnect; the driver is already quiesced */
if (driver) if (driver) {
spin_unlock(&dev->lock);
driver->disconnect(&dev->gadget); driver->disconnect(&dev->gadget);
spin_lock(&dev->lock);
}
usb_reinit(dev); usb_reinit(dev);
} }
...@@ -3341,6 +3347,8 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat) ...@@ -3341,6 +3347,8 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
BIT(PCI_RETRY_ABORT_INTERRUPT)) BIT(PCI_RETRY_ABORT_INTERRUPT))
static void handle_stat1_irqs(struct net2280 *dev, u32 stat) static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
__releases(dev->lock)
__acquires(dev->lock)
{ {
struct net2280_ep *ep; struct net2280_ep *ep;
u32 tmp, num, mask, scratch; u32 tmp, num, mask, scratch;
...@@ -3381,12 +3389,14 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) ...@@ -3381,12 +3389,14 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
if (disconnect || reset) { if (disconnect || reset) {
stop_activity(dev, dev->driver); stop_activity(dev, dev->driver);
ep0_start(dev); ep0_start(dev);
spin_unlock(&dev->lock);
if (reset) if (reset)
usb_gadget_udc_reset usb_gadget_udc_reset
(&dev->gadget, dev->driver); (&dev->gadget, dev->driver);
else else
(dev->driver->disconnect) (dev->driver->disconnect)
(&dev->gadget); (&dev->gadget);
spin_lock(&dev->lock);
return; return;
} }
} }
...@@ -3405,6 +3415,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) ...@@ -3405,6 +3415,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT); tmp = BIT(SUSPEND_REQUEST_CHANGE_INTERRUPT);
if (stat & tmp) { if (stat & tmp) {
writel(tmp, &dev->regs->irqstat1); writel(tmp, &dev->regs->irqstat1);
spin_unlock(&dev->lock);
if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) { if (stat & BIT(SUSPEND_REQUEST_INTERRUPT)) {
if (dev->driver->suspend) if (dev->driver->suspend)
dev->driver->suspend(&dev->gadget); dev->driver->suspend(&dev->gadget);
...@@ -3415,6 +3426,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat) ...@@ -3415,6 +3426,7 @@ static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
dev->driver->resume(&dev->gadget); dev->driver->resume(&dev->gadget);
/* at high speed, note erratum 0133 */ /* at high speed, note erratum 0133 */
} }
spin_lock(&dev->lock);
stat &= ~tmp; stat &= ~tmp;
} }
......
...@@ -812,12 +812,15 @@ static void usb3_irq_epc_int_1_speed(struct renesas_usb3 *usb3) ...@@ -812,12 +812,15 @@ static void usb3_irq_epc_int_1_speed(struct renesas_usb3 *usb3)
switch (speed) { switch (speed) {
case USB_STA_SPEED_SS: case USB_STA_SPEED_SS:
usb3->gadget.speed = USB_SPEED_SUPER; usb3->gadget.speed = USB_SPEED_SUPER;
usb3->gadget.ep0->maxpacket = USB3_EP0_SS_MAX_PACKET_SIZE;
break; break;
case USB_STA_SPEED_HS: case USB_STA_SPEED_HS:
usb3->gadget.speed = USB_SPEED_HIGH; usb3->gadget.speed = USB_SPEED_HIGH;
usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE;
break; break;
case USB_STA_SPEED_FS: case USB_STA_SPEED_FS:
usb3->gadget.speed = USB_SPEED_FULL; usb3->gadget.speed = USB_SPEED_FULL;
usb3->gadget.ep0->maxpacket = USB3_EP0_HSFS_MAX_PACKET_SIZE;
break; break;
default: default:
usb3->gadget.speed = USB_SPEED_UNKNOWN; usb3->gadget.speed = USB_SPEED_UNKNOWN;
...@@ -2513,7 +2516,7 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, ...@@ -2513,7 +2516,7 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev,
/* for control pipe */ /* for control pipe */
usb3->gadget.ep0 = &usb3_ep->ep; usb3->gadget.ep0 = &usb3_ep->ep;
usb_ep_set_maxpacket_limit(&usb3_ep->ep, usb_ep_set_maxpacket_limit(&usb3_ep->ep,
USB3_EP0_HSFS_MAX_PACKET_SIZE); USB3_EP0_SS_MAX_PACKET_SIZE);
usb3_ep->ep.caps.type_control = true; usb3_ep->ep.caps.type_control = true;
usb3_ep->ep.caps.dir_in = true; usb3_ep->ep.caps.dir_in = true;
usb3_ep->ep.caps.dir_out = true; usb3_ep->ep.caps.dir_out = true;
......
...@@ -2555,7 +2555,7 @@ static int u132_get_frame(struct usb_hcd *hcd) ...@@ -2555,7 +2555,7 @@ static int u132_get_frame(struct usb_hcd *hcd)
} else { } else {
int frame = 0; int frame = 0;
dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n"); dev_err(&u132->platform_dev->dev, "TODO: u132_get_frame\n");
msleep(100); mdelay(100);
return frame; return frame;
} }
} }
......
...@@ -1613,6 +1613,10 @@ void xhci_endpoint_copy(struct xhci_hcd *xhci, ...@@ -1613,6 +1613,10 @@ void xhci_endpoint_copy(struct xhci_hcd *xhci,
in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2; in_ep_ctx->ep_info2 = out_ep_ctx->ep_info2;
in_ep_ctx->deq = out_ep_ctx->deq; in_ep_ctx->deq = out_ep_ctx->deq;
in_ep_ctx->tx_info = out_ep_ctx->tx_info; in_ep_ctx->tx_info = out_ep_ctx->tx_info;
if (xhci->quirks & XHCI_MTK_HOST) {
in_ep_ctx->reserved[0] = out_ep_ctx->reserved[0];
in_ep_ctx->reserved[1] = out_ep_ctx->reserved[1];
}
} }
/* Copy output xhci_slot_ctx to the input xhci_slot_ctx. /* Copy output xhci_slot_ctx to the input xhci_slot_ctx.
......
...@@ -153,7 +153,7 @@ static int xhci_plat_probe(struct platform_device *pdev) ...@@ -153,7 +153,7 @@ static int xhci_plat_probe(struct platform_device *pdev)
{ {
const struct xhci_plat_priv *priv_match; const struct xhci_plat_priv *priv_match;
const struct hc_driver *driver; const struct hc_driver *driver;
struct device *sysdev; struct device *sysdev, *tmpdev;
struct xhci_hcd *xhci; struct xhci_hcd *xhci;
struct resource *res; struct resource *res;
struct usb_hcd *hcd; struct usb_hcd *hcd;
...@@ -273,19 +273,24 @@ static int xhci_plat_probe(struct platform_device *pdev) ...@@ -273,19 +273,24 @@ static int xhci_plat_probe(struct platform_device *pdev)
goto disable_clk; goto disable_clk;
} }
if (device_property_read_bool(sysdev, "usb2-lpm-disable")) /* imod_interval is the interrupt moderation value in nanoseconds. */
xhci->quirks |= XHCI_HW_LPM_DISABLE; xhci->imod_interval = 40000;
if (device_property_read_bool(sysdev, "usb3-lpm-capable")) /* Iterate over all parent nodes for finding quirks */
xhci->quirks |= XHCI_LPM_SUPPORT; for (tmpdev = &pdev->dev; tmpdev; tmpdev = tmpdev->parent) {
if (device_property_read_bool(&pdev->dev, "quirk-broken-port-ped")) if (device_property_read_bool(tmpdev, "usb2-lpm-disable"))
xhci->quirks |= XHCI_BROKEN_PORT_PED; xhci->quirks |= XHCI_HW_LPM_DISABLE;
/* imod_interval is the interrupt moderation value in nanoseconds. */ if (device_property_read_bool(tmpdev, "usb3-lpm-capable"))
xhci->imod_interval = 40000; xhci->quirks |= XHCI_LPM_SUPPORT;
device_property_read_u32(sysdev, "imod-interval-ns",
&xhci->imod_interval); if (device_property_read_bool(tmpdev, "quirk-broken-port-ped"))
xhci->quirks |= XHCI_BROKEN_PORT_PED;
device_property_read_u32(tmpdev, "imod-interval-ns",
&xhci->imod_interval);
}
hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0); hcd->usb_phy = devm_usb_get_phy_by_phandle(sysdev, "usb-phy", 0);
if (IS_ERR(hcd->usb_phy)) { if (IS_ERR(hcd->usb_phy)) {
......
...@@ -37,6 +37,21 @@ static unsigned long long quirks; ...@@ -37,6 +37,21 @@ static unsigned long long quirks;
module_param(quirks, ullong, S_IRUGO); module_param(quirks, ullong, S_IRUGO);
MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default"); MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
{
struct xhci_segment *seg = ring->first_seg;
if (!td || !td->start_seg)
return false;
do {
if (seg == td->start_seg)
return true;
seg = seg->next;
} while (seg && seg != ring->first_seg);
return false;
}
/* TODO: copied from ehci-hcd.c - can this be refactored? */ /* TODO: copied from ehci-hcd.c - can this be refactored? */
/* /*
* xhci_handshake - spin reading hc until handshake completes or fails * xhci_handshake - spin reading hc until handshake completes or fails
...@@ -1571,6 +1586,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) ...@@ -1571,6 +1586,21 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done; goto done;
} }
/*
* check ring is not re-allocated since URB was enqueued. If it is, then
* make sure none of the ring related pointers in this URB private data
* are touched, such as td_list, otherwise we overwrite freed data
*/
if (!td_on_ring(&urb_priv->td[0], ep_ring)) {
xhci_err(xhci, "Canceled URB td not found on endpoint ring");
for (i = urb_priv->num_tds_done; i < urb_priv->num_tds; i++) {
td = &urb_priv->td[i];
if (!list_empty(&td->cancelled_td_list))
list_del_init(&td->cancelled_td_list);
}
goto err_giveback;
}
if (xhci->xhc_state & XHCI_STATE_HALTED) { if (xhci->xhc_state & XHCI_STATE_HALTED) {
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"HC halted, freeing TD manually."); "HC halted, freeing TD manually.");
......
...@@ -369,7 +369,7 @@ static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned ch ...@@ -369,7 +369,7 @@ static unsigned char parport_uss720_frob_control(struct parport *pp, unsigned ch
mask &= 0x0f; mask &= 0x0f;
val &= 0x0f; val &= 0x0f;
d = (priv->reg[1] & (~mask)) ^ val; d = (priv->reg[1] & (~mask)) ^ val;
if (set_1284_register(pp, 2, d, GFP_KERNEL)) if (set_1284_register(pp, 2, d, GFP_ATOMIC))
return 0; return 0;
priv->reg[1] = d; priv->reg[1] = d;
return d & 0xf; return d & 0xf;
...@@ -379,7 +379,7 @@ static unsigned char parport_uss720_read_status(struct parport *pp) ...@@ -379,7 +379,7 @@ static unsigned char parport_uss720_read_status(struct parport *pp)
{ {
unsigned char ret; unsigned char ret;
if (get_1284_register(pp, 1, &ret, GFP_KERNEL)) if (get_1284_register(pp, 1, &ret, GFP_ATOMIC))
return 0; return 0;
return ret & 0xf8; return ret & 0xf8;
} }
......
...@@ -413,6 +413,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count, ...@@ -413,6 +413,9 @@ static ssize_t yurex_read(struct file *file, char __user *buffer, size_t count,
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
mutex_unlock(&dev->io_mutex); mutex_unlock(&dev->io_mutex);
if (WARN_ON_ONCE(len >= sizeof(in_buffer)))
return -EIO;
return simple_read_from_buffer(buffer, count, ppos, in_buffer, len); return simple_read_from_buffer(buffer, count, ppos, in_buffer, len);
} }
...@@ -421,13 +424,13 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, ...@@ -421,13 +424,13 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
{ {
struct usb_yurex *dev; struct usb_yurex *dev;
int i, set = 0, retval = 0; int i, set = 0, retval = 0;
char buffer[16]; char buffer[16 + 1];
char *data = buffer; char *data = buffer;
unsigned long long c, c2 = 0; unsigned long long c, c2 = 0;
signed long timeout = 0; signed long timeout = 0;
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
count = min(sizeof(buffer), count); count = min(sizeof(buffer) - 1, count);
dev = file->private_data; dev = file->private_data;
/* verify that we actually have some data to write */ /* verify that we actually have some data to write */
...@@ -446,6 +449,7 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer, ...@@ -446,6 +449,7 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
retval = -EFAULT; retval = -EFAULT;
goto error; goto error;
} }
buffer[count] = 0;
memset(dev->cntl_buffer, CMD_PADDING, YUREX_BUF_SIZE); memset(dev->cntl_buffer, CMD_PADDING, YUREX_BUF_SIZE);
switch (buffer[0]) { switch (buffer[0]) {
......
...@@ -107,8 +107,12 @@ static int mtu3_device_enable(struct mtu3 *mtu) ...@@ -107,8 +107,12 @@ static int mtu3_device_enable(struct mtu3 *mtu)
(SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN | (SSUSB_U2_PORT_DIS | SSUSB_U2_PORT_PDN |
SSUSB_U2_PORT_HOST_SEL)); SSUSB_U2_PORT_HOST_SEL));
if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) if (mtu->ssusb->dr_mode == USB_DR_MODE_OTG) {
mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL); mtu3_setbits(ibase, SSUSB_U2_CTRL(0), SSUSB_U2_PORT_OTG_SEL);
if (mtu->is_u3_ip)
mtu3_setbits(ibase, SSUSB_U3_CTRL(0),
SSUSB_U3_PORT_DUAL_MODE);
}
return ssusb_check_clocks(mtu->ssusb, check_clk); return ssusb_check_clocks(mtu->ssusb, check_clk);
} }
......
...@@ -459,6 +459,7 @@ ...@@ -459,6 +459,7 @@
/* U3D_SSUSB_U3_CTRL_0P */ /* U3D_SSUSB_U3_CTRL_0P */
#define SSUSB_U3_PORT_SSP_SPEED BIT(9) #define SSUSB_U3_PORT_SSP_SPEED BIT(9)
#define SSUSB_U3_PORT_DUAL_MODE BIT(7)
#define SSUSB_U3_PORT_HOST_SEL BIT(2) #define SSUSB_U3_PORT_HOST_SEL BIT(2)
#define SSUSB_U3_PORT_PDN BIT(1) #define SSUSB_U3_PORT_PDN BIT(1)
#define SSUSB_U3_PORT_DIS BIT(0) #define SSUSB_U3_PORT_DIS BIT(0)
......
...@@ -173,7 +173,7 @@ struct ump_interrupt { ...@@ -173,7 +173,7 @@ struct ump_interrupt {
} __attribute__((packed)); } __attribute__((packed));
#define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 4) - 3) #define TIUMP_GET_PORT_FROM_CODE(c) (((c) >> 6) & 0x01)
#define TIUMP_GET_FUNC_FROM_CODE(c) ((c) & 0x0f) #define TIUMP_GET_FUNC_FROM_CODE(c) ((c) & 0x0f)
#define TIUMP_INTERRUPT_CODE_LSR 0x03 #define TIUMP_INTERRUPT_CODE_LSR 0x03
#define TIUMP_INTERRUPT_CODE_MSR 0x04 #define TIUMP_INTERRUPT_CODE_MSR 0x04
......
...@@ -1119,7 +1119,7 @@ static void ti_break(struct tty_struct *tty, int break_state) ...@@ -1119,7 +1119,7 @@ static void ti_break(struct tty_struct *tty, int break_state)
static int ti_get_port_from_code(unsigned char code) static int ti_get_port_from_code(unsigned char code)
{ {
return (code >> 4) - 3; return (code >> 6) & 0x01;
} }
static int ti_get_func_from_code(unsigned char code) static int ti_get_func_from_code(unsigned char code)
......
...@@ -376,6 +376,15 @@ static int queuecommand_lck(struct scsi_cmnd *srb, ...@@ -376,6 +376,15 @@ static int queuecommand_lck(struct scsi_cmnd *srb,
return 0; return 0;
} }
if ((us->fflags & US_FL_NO_ATA_1X) &&
(srb->cmnd[0] == ATA_12 || srb->cmnd[0] == ATA_16)) {
memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
sizeof(usb_stor_sense_invalidCDB));
srb->result = SAM_STAT_CHECK_CONDITION;
done(srb);
return 0;
}
/* enqueue the command and wake up the control thread */ /* enqueue the command and wake up the control thread */
srb->scsi_done = done; srb->scsi_done = done;
us->srb = srb; us->srb = srb;
......
...@@ -842,6 +842,27 @@ static int uas_slave_configure(struct scsi_device *sdev) ...@@ -842,6 +842,27 @@ static int uas_slave_configure(struct scsi_device *sdev)
sdev->skip_ms_page_8 = 1; sdev->skip_ms_page_8 = 1;
sdev->wce_default_on = 1; sdev->wce_default_on = 1;
} }
/*
* Some disks return the total number of blocks in response
* to READ CAPACITY rather than the highest block number.
* If this device makes that mistake, tell the sd driver.
*/
if (devinfo->flags & US_FL_FIX_CAPACITY)
sdev->fix_capacity = 1;
/*
* Some devices don't like MODE SENSE with page=0x3f,
* which is the command used for checking if a device
* is write-protected. Now that we tell the sd driver
* to do a 192-byte transfer with this command the
* majority of devices work fine, but a few still can't
* handle it. The sd driver will simply assume those
* devices are write-enabled.
*/
if (devinfo->flags & US_FL_NO_WP_DETECT)
sdev->skip_ms_page_3f = 1;
scsi_change_queue_depth(sdev, devinfo->qdepth - 2); scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
return 0; return 0;
} }
......
...@@ -2288,6 +2288,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, ...@@ -2288,6 +2288,13 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_GO_SLOW ), US_FL_GO_SLOW ),
/* Reported-by: Tim Anderson <tsa@biglakesoftware.com> */
UNUSUAL_DEV( 0x2ca3, 0x0031, 0x0000, 0x9999,
"DJI",
"CineSSD",
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_ATA_1X),
/* /*
* Reported by Frederic Marchal <frederic.marchal@wowcompany.com> * Reported by Frederic Marchal <frederic.marchal@wowcompany.com>
* Mio Moov 330 * Mio Moov 330
......
...@@ -255,12 +255,13 @@ EXPORT_SYMBOL_GPL(typec_altmode_unregister_driver); ...@@ -255,12 +255,13 @@ EXPORT_SYMBOL_GPL(typec_altmode_unregister_driver);
/* API for the port drivers */ /* API for the port drivers */
/** /**
* typec_match_altmode - Match SVID to an array of alternate modes * typec_match_altmode - Match SVID and mode to an array of alternate modes
* @altmodes: Array of alternate modes * @altmodes: Array of alternate modes
* @n: Number of elements in the array, or -1 for NULL termiated arrays * @n: Number of elements in the array, or -1 for NULL terminated arrays
* @svid: Standard or Vendor ID to match with * @svid: Standard or Vendor ID to match with
* @mode: Mode to match with
* *
* Return pointer to an alternate mode with SVID mathing @svid, or NULL when no * Return pointer to an alternate mode with SVID matching @svid, or NULL when no
* match is found. * match is found.
*/ */
struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes, struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
......
...@@ -1484,7 +1484,6 @@ EXPORT_SYMBOL_GPL(typec_set_mode); ...@@ -1484,7 +1484,6 @@ EXPORT_SYMBOL_GPL(typec_set_mode);
* typec_port_register_altmode - Register USB Type-C Port Alternate Mode * typec_port_register_altmode - Register USB Type-C Port Alternate Mode
* @port: USB Type-C Port that supports the alternate mode * @port: USB Type-C Port that supports the alternate mode
* @desc: Description of the alternate mode * @desc: Description of the alternate mode
* @drvdata: Private pointer to driver specific info
* *
* This routine is used to register an alternate mode that @port is capable of * This routine is used to register an alternate mode that @port is capable of
* supporting. * supporting.
......
...@@ -754,6 +754,7 @@ struct tb_service_id { ...@@ -754,6 +754,7 @@ struct tb_service_id {
* struct typec_device_id - USB Type-C alternate mode identifiers * struct typec_device_id - USB Type-C alternate mode identifiers
* @svid: Standard or Vendor ID * @svid: Standard or Vendor ID
* @mode: Mode index * @mode: Mode index
* @driver_data: Driver specific data
*/ */
struct typec_device_id { struct typec_device_id {
__u16 svid; __u16 svid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment