Skip to content

Commit

Permalink
Merge tag 'usb-4.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB fixes for 4.12-rc2

  Most of them come from Johan, in his valiant quest to fix up all
  drivers that could be affected by "malicious" USB devices. There's
  also some fixes for more "obscure" drivers to handle some of the
  vmalloc stack fallout (which for USB drivers, was always the case, but
  very few people actually ran those systems...)

  Other than that, the normal set of xhci and gadget and musb driver
  fixes as well.

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

* tag 'usb-4.12-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (42 commits)
  usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  usb: musb: Fix trying to suspend while active for OTG configurations
  usb: host: xhci-plat: propagate return value of platform_get_irq()
  xhci: Fix command ring stop regression in 4.11
  xhci: remove GFP_DMA flag from allocation
  USB: xhci: fix lock-inversion problem
  usb: host: xhci-ring: don't need to clear interrupt pending for MSI enabled hcd
  usb: host: xhci-mem: allocate zeroed Scratchpad Buffer
  xhci: apply PME_STUCK_QUIRK and MISSING_CAS quirk for Denverton
  usb: xhci: trace URB before giving it back instead of after
  USB: serial: qcserial: add more Lenovo EM74xx device IDs
  USB: host: xhci: use max-port define
  USB: hub: fix SS max number of ports
  USB: hub: fix non-SS hub-descriptor handling
  USB: hub: fix SS hub-descriptor handling
  USB: usbip: fix nonconforming hub descriptor
  USB: gadget: dummy_hcd: fix hub-descriptor removable fields
  doc-rst: fixed kernel-doc directives in usb/typec.rst
  USB: core: of: document reference taken by companion helper
  USB: ehci-platform: fix companion-device leak
  ...
  • Loading branch information
Linus Torvalds committed May 20, 2017
2 parents 331da10 + b51e0ce commit 3202629
Show file tree
Hide file tree
Showing 38 changed files with 232 additions and 126 deletions.
6 changes: 2 additions & 4 deletions Documentation/usb/typec.rst
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ the details during registration. The class offers the following API for
registering/unregistering cables and their plugs:

.. kernel-doc:: drivers/usb/typec/typec.c
:functions: typec_register_cable typec_unregister_cable typec_register_plug
typec_unregister_plug
:functions: typec_register_cable typec_unregister_cable typec_register_plug typec_unregister_plug

The class will provide a handle to struct typec_cable and struct typec_plug if
the registration is successful, or NULL if it isn't.
Expand All @@ -137,8 +136,7 @@ during connection of a partner or cable, the port driver must use the following
APIs to report it to the class:

.. kernel-doc:: drivers/usb/typec/typec.c
:functions: typec_set_data_role typec_set_pwr_role typec_set_vconn_role
typec_set_pwr_opmode
:functions: typec_set_data_role typec_set_pwr_role typec_set_vconn_role typec_set_pwr_opmode

Alternate Modes
~~~~~~~~~~~~~~~
Expand Down
14 changes: 7 additions & 7 deletions drivers/usb/core/devio.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,11 +475,11 @@ static void snoop_urb(struct usb_device *udev,

if (userurb) { /* Async */
if (when == SUBMIT)
dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
"length %u\n",
userurb, ep, t, d, length);
else
dev_info(&udev->dev, "userurb %p, ep%d %s-%s, "
dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
"actual_length %u status %d\n",
userurb, ep, t, d, length,
timeout_or_status);
Expand Down Expand Up @@ -1895,7 +1895,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg)
if (as) {
int retval;

snoop(&ps->dev->dev, "reap %p\n", as->userurb);
snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
retval = processcompl(as, (void __user * __user *)arg);
free_async(as);
return retval;
Expand All @@ -1912,7 +1912,7 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)

as = async_getcompleted(ps);
if (as) {
snoop(&ps->dev->dev, "reap %p\n", as->userurb);
snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
retval = processcompl(as, (void __user * __user *)arg);
free_async(as);
} else {
Expand Down Expand Up @@ -2043,7 +2043,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg)
if (as) {
int retval;

snoop(&ps->dev->dev, "reap %p\n", as->userurb);
snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
retval = processcompl_compat(as, (void __user * __user *)arg);
free_async(as);
return retval;
Expand All @@ -2060,7 +2060,7 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar

as = async_getcompleted(ps);
if (as) {
snoop(&ps->dev->dev, "reap %p\n", as->userurb);
snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
retval = processcompl_compat(as, (void __user * __user *)arg);
free_async(as);
} else {
Expand Down Expand Up @@ -2489,7 +2489,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
#endif

case USBDEVFS_DISCARDURB:
snoop(&dev->dev, "%s: DISCARDURB %p\n", __func__, p);
snoop(&dev->dev, "%s: DISCARDURB %pK\n", __func__, p);
ret = proc_unlinkurb(ps, p);
break;

Expand Down
5 changes: 3 additions & 2 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
if (retval == 0)
retval = -EINPROGRESS;
else if (retval != -EIDRM && retval != -EBUSY)
dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
dev_dbg(&udev->dev, "hcd_unlink_urb %pK fail %d\n",
urb, retval);
usb_put_dev(udev);
}
Expand Down Expand Up @@ -1890,7 +1890,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
/* kick hcd */
unlink1(hcd, urb, -ESHUTDOWN);
dev_dbg (hcd->self.controller,
"shutdown urb %p ep%d%s%s\n",
"shutdown urb %pK ep%d%s%s\n",
urb, usb_endpoint_num(&ep->desc),
is_in ? "in" : "out",
({ char *s;
Expand Down Expand Up @@ -2520,6 +2520,7 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
GFP_KERNEL);
if (!hcd->bandwidth_mutex) {
kfree(hcd->address0_mutex);
kfree(hcd);
dev_dbg(dev, "hcd bandwidth mutex alloc failed\n");
return NULL;
Expand Down
27 changes: 21 additions & 6 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,8 @@ static void usb_set_lpm_parameters(struct usb_device *udev)
}

/* USB 2.0 spec Section 11.24.4.5 */
static int get_hub_descriptor(struct usb_device *hdev, void *data)
static int get_hub_descriptor(struct usb_device *hdev,
struct usb_hub_descriptor *desc)
{
int i, ret, size;
unsigned dtype;
Expand All @@ -378,10 +379,18 @@ static int get_hub_descriptor(struct usb_device *hdev, void *data)
for (i = 0; i < 3; i++) {
ret = usb_control_msg(hdev, usb_rcvctrlpipe(hdev, 0),
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
dtype << 8, 0, data, size,
dtype << 8, 0, desc, size,
USB_CTRL_GET_TIMEOUT);
if (ret >= (USB_DT_HUB_NONVAR_SIZE + 2))
if (hub_is_superspeed(hdev)) {
if (ret == size)
return ret;
} else if (ret >= USB_DT_HUB_NONVAR_SIZE + 2) {
/* Make sure we have the DeviceRemovable field. */
size = USB_DT_HUB_NONVAR_SIZE + desc->bNbrPorts / 8 + 1;
if (ret < size)
return -EMSGSIZE;
return ret;
}
}
return -EINVAL;
}
Expand Down Expand Up @@ -1313,21 +1322,27 @@ static int hub_configure(struct usb_hub *hub,
}
mutex_init(&hub->status_mutex);

hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL);
if (!hub->descriptor) {
ret = -ENOMEM;
goto fail;
}

/* Request the entire hub descriptor.
* hub->descriptor can handle USB_MAXCHILDREN ports,
* but the hub can/will return fewer bytes here.
* but a (non-SS) hub can/will return fewer bytes here.
*/
ret = get_hub_descriptor(hdev, hub->descriptor);
if (ret < 0) {
message = "can't read hub descriptor";
goto fail;
} else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {
}

maxchild = USB_MAXCHILDREN;
if (hub_is_superspeed(hdev))
maxchild = min_t(unsigned, maxchild, USB_SS_MAXPORTS);

if (hub->descriptor->bNbrPorts > maxchild) {
message = "hub has too many ports!";
ret = -ENODEV;
goto fail;
Expand Down
3 changes: 3 additions & 0 deletions drivers/usb/core/of.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ EXPORT_SYMBOL_GPL(usb_of_get_child_node);
*
* 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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/core/urb.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
if (!urb || !urb->complete)
return -EINVAL;
if (urb->hcpriv) {
WARN_ONCE(1, "URB %p submitted while active\n", urb);
WARN_ONCE(1, "URB %pK submitted while active\n", urb);
return -EBUSY;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/dwc3/dwc3-keystone.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ static int kdwc3_probe(struct platform_device *pdev)
return PTR_ERR(kdwc->usbss);

kdwc->clk = devm_clk_get(kdwc->dev, "usb");
if (IS_ERR(kdwc->clk)) {
dev_err(kdwc->dev, "unable to get usb clock\n");
return PTR_ERR(kdwc->clk);
}

error = clk_prepare_enable(kdwc->clk);
if (error < 0) {
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/dwc3/dwc3-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#define PCI_DEVICE_ID_INTEL_APL 0x5aaa
#define PCI_DEVICE_ID_INTEL_KBP 0xa2b0
#define PCI_DEVICE_ID_INTEL_GLK 0x31aa
#define PCI_DEVICE_ID_INTEL_CNPLP 0x9dee
#define PCI_DEVICE_ID_INTEL_CNPH 0xa36e

#define PCI_INTEL_BXT_DSM_UUID "732b85d5-b7a7-4a1b-9ba0-4bbd00ffd511"
#define PCI_INTEL_BXT_FUNC_PMU_PWR 4
Expand Down Expand Up @@ -270,6 +272,8 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_KBP), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GLK), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPLP), },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CNPH), },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
{ } /* Terminating Entry */
};
Expand Down
21 changes: 20 additions & 1 deletion drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,14 +1261,24 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
__dwc3_gadget_start_isoc(dwc, dep, cur_uf);
dep->flags &= ~DWC3_EP_PENDING_REQUEST;
}
return 0;
}
return 0;

if ((dep->flags & DWC3_EP_BUSY) &&
!(dep->flags & DWC3_EP_MISSED_ISOC)) {
WARN_ON_ONCE(!dep->resource_index);
ret = __dwc3_gadget_kick_transfer(dep,
dep->resource_index);
}

goto out;
}

if (!dwc3_calc_trbs_left(dep))
return 0;

ret = __dwc3_gadget_kick_transfer(dep, 0);
out:
if (ret == -EBUSY)
ret = 0;

Expand Down Expand Up @@ -3026,6 +3036,15 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt)
return IRQ_HANDLED;
}

/*
* With PCIe legacy interrupt, test shows that top-half irq handler can
* be called again after HW interrupt deassertion. Check if bottom-half
* irq event handler completes before caching new event to prevent
* losing events.
*/
if (evt->flags & DWC3_EVENT_PENDING)
return IRQ_HANDLED;

count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0));
count &= DWC3_GEVNTCOUNT_MASK;
if (!count)
Expand Down
10 changes: 5 additions & 5 deletions drivers/usb/gadget/function/f_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1858,12 +1858,12 @@ static int ffs_func_eps_enable(struct ffs_function *func)
ep->ep->driver_data = ep;
ep->ep->desc = ds;

comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
USB_DT_ENDPOINT_SIZE);
ep->ep->maxburst = comp_desc->bMaxBurst + 1;

if (needs_comp_desc)
if (needs_comp_desc) {
comp_desc = (struct usb_ss_ep_comp_descriptor *)(ds +
USB_DT_ENDPOINT_SIZE);
ep->ep->maxburst = comp_desc->bMaxBurst + 1;
ep->ep->comp_desc = comp_desc;
}

ret = usb_ep_enable(ep->ep);
if (likely(!ret)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/gadget/function/u_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,7 @@ static void gserial_console_exit(void)
struct gscons_info *info = &gscons_info;

unregister_console(&gserial_cons);
if (info->console_thread != NULL)
if (!IS_ERR_OR_NULL(info->console_thread))
kthread_stop(info->console_thread);
gs_buf_free(&info->con_buf);
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/usb/gadget/udc/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2008,7 +2008,7 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc)
HUB_CHAR_COMMON_OCPM);
desc->bNbrPorts = 1;
desc->u.ss.bHubHdrDecLat = 0x04; /* Worst case: 0.4 micro sec*/
desc->u.ss.DeviceRemovable = 0xffff;
desc->u.ss.DeviceRemovable = 0;
}

static inline void hub_descriptor(struct usb_hub_descriptor *desc)
Expand All @@ -2020,8 +2020,8 @@ static inline void hub_descriptor(struct usb_hub_descriptor *desc)
HUB_CHAR_INDV_PORT_LPSM |
HUB_CHAR_COMMON_OCPM);
desc->bNbrPorts = 1;
desc->u.hs.DeviceRemovable[0] = 0xff;
desc->u.hs.DeviceRemovable[1] = 0xff;
desc->u.hs.DeviceRemovable[0] = 0;
desc->u.hs.DeviceRemovable[1] = 0xff; /* PortPwrCtrlMask */
}

static int dummy_hub_control(
Expand Down
4 changes: 3 additions & 1 deletion drivers/usb/host/ehci-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,10 @@ static int ehci_platform_resume(struct device *dev)
}

companion_dev = usb_of_get_companion_dev(hcd->self.controller);
if (companion_dev)
if (companion_dev) {
device_pm_wait_for_dev(hcd->self.controller, companion_dev);
put_device(companion_dev);
}

ehci_resume(hcd, priv->reset_on_resume);
return 0;
Expand Down
6 changes: 4 additions & 2 deletions drivers/usb/host/r8a66597-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
time = 30;
break;
default:
time = 300;
time = 50;
break;
}

Expand Down Expand Up @@ -1785,6 +1785,7 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
pipe = td->pipe;
pipe_stop(r8a66597, pipe);

/* Select a different address or endpoint */
new_td = td;
do {
list_move_tail(&new_td->queue,
Expand All @@ -1794,7 +1795,8 @@ static void r8a66597_td_timer(unsigned long _r8a66597)
new_td = td;
break;
}
} while (td != new_td && td->address == new_td->address);
} while (td != new_td && td->address == new_td->address &&
td->pipe->info.epnum == new_td->pipe->info.epnum);

start_transfer(r8a66597, new_td);

Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/host/xhci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)
wait_for_completion(cmd->completion);

if (cmd->status == COMP_COMMAND_ABORTED ||
cmd->status == COMP_STOPPED) {
cmd->status == COMP_COMMAND_RING_STOPPED) {
xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
ret = -ETIME;
}
Expand Down
11 changes: 6 additions & 5 deletions drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_hcd *xhci,
}

if (max_packet) {
seg->bounce_buf = kzalloc(max_packet, flags | GFP_DMA);
seg->bounce_buf = kzalloc(max_packet, flags);
if (!seg->bounce_buf) {
dma_pool_free(xhci->segment_pool, seg->trbs, dma);
kfree(seg);
Expand Down Expand Up @@ -1724,7 +1724,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma);
for (i = 0; i < num_sp; i++) {
dma_addr_t dma;
void *buf = dma_alloc_coherent(dev, xhci->page_size, &dma,
void *buf = dma_zalloc_coherent(dev, xhci->page_size, &dma,
flags);
if (!buf)
goto fail_sp4;
Expand Down Expand Up @@ -2307,10 +2307,11 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
/* Place limits on the number of roothub ports so that the hub
* descriptors aren't longer than the USB core will allocate.
*/
if (xhci->num_usb3_ports > 15) {
if (xhci->num_usb3_ports > USB_SS_MAXPORTS) {
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Limiting USB 3.0 roothub ports to 15.");
xhci->num_usb3_ports = 15;
"Limiting USB 3.0 roothub ports to %u.",
USB_SS_MAXPORTS);
xhci->num_usb3_ports = USB_SS_MAXPORTS;
}
if (xhci->num_usb2_ports > USB_MAXCHILDREN) {
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
Expand Down
Loading

0 comments on commit 3202629

Please sign in to comment.