Merge tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB patches from Greg KH: "Here's the big pull request for the USB driver tree for 3.20-rc1. Nothing major happening here, just lots of gadget driver updates, new device ids, and a bunch of cleanups. All of these have been in linux-next for a while with no reported issues" * tag 'usb-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (299 commits) usb: musb: fix device hotplug behind hub usb: dwc2: Fix a bug in reading the endpoint directions from reg. staging: emxx_udc: fix the build error usb: Retry port status check on resume to work around RH bugs Revert "usb: Reset USB-3 devices on USB-3 link bounce" uhci-hub: use HUB_CHAR_* usb: kconfig: replace PPC_OF with PPC ehci-pci: disable for Intel MID platforms (update) usb: gadget: Kconfig: use bool instead of boolean usb: musb: blackfin: remove incorrect __exit_p() USB: fix use-after-free bug in usb_hcd_unlink_urb() ehci-pci: disable for Intel MID platforms usb: host: pci_quirks: joing string literals USB: add flag for HCDs that can't receive wakeup requests (isp1760-hcd) USB: usbfs: allow URBs to be reaped after disconnection cdc-acm: kill unnecessary messages cdc-acm: add sanity checks usb: phy: phy-generic: Fix USB PHY gpio reset usb: dwc2: fix USB core dependencies usb: renesas_usbhs: fix NULL pointer dereference in dma_release_channel() ...
This commit is contained in:
@@ -22,17 +22,25 @@
|
||||
*/
|
||||
|
||||
/* FIXME tune these based on pool statistics ... */
|
||||
static const size_t pool_max[HCD_BUFFER_POOLS] = {
|
||||
/* platforms without dma-friendly caches might need to
|
||||
* prevent cacheline sharing...
|
||||
*/
|
||||
32,
|
||||
128,
|
||||
512,
|
||||
PAGE_SIZE / 2
|
||||
/* bigger --> allocate pages */
|
||||
static size_t pool_max[HCD_BUFFER_POOLS] = {
|
||||
32, 128, 512, 2048,
|
||||
};
|
||||
|
||||
void __init usb_init_pool_max(void)
|
||||
{
|
||||
/*
|
||||
* The pool_max values must never be smaller than
|
||||
* ARCH_KMALLOC_MINALIGN.
|
||||
*/
|
||||
if (ARCH_KMALLOC_MINALIGN <= 32)
|
||||
; /* Original value is okay */
|
||||
else if (ARCH_KMALLOC_MINALIGN <= 64)
|
||||
pool_max[0] = 64;
|
||||
else if (ARCH_KMALLOC_MINALIGN <= 128)
|
||||
pool_max[0] = 0; /* Don't use this pool */
|
||||
else
|
||||
BUILD_BUG(); /* We don't allow this */
|
||||
}
|
||||
|
||||
/* SETUP primitives */
|
||||
|
||||
|
@@ -1689,7 +1689,7 @@ static struct async *reap_as(struct usb_dev_state *ps)
|
||||
for (;;) {
|
||||
__set_current_state(TASK_INTERRUPTIBLE);
|
||||
as = async_getcompleted(ps);
|
||||
if (as)
|
||||
if (as || !connected(ps))
|
||||
break;
|
||||
if (signal_pending(current))
|
||||
break;
|
||||
@@ -1712,7 +1712,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg)
|
||||
}
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -EIO;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)
|
||||
@@ -1721,10 +1721,11 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)
|
||||
struct async *as;
|
||||
|
||||
as = async_getcompleted(ps);
|
||||
retval = -EAGAIN;
|
||||
if (as) {
|
||||
retval = processcompl(as, (void __user * __user *)arg);
|
||||
free_async(as);
|
||||
} else {
|
||||
retval = (connected(ps) ? -EAGAIN : -ENODEV);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -1854,7 +1855,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg)
|
||||
}
|
||||
if (signal_pending(current))
|
||||
return -EINTR;
|
||||
return -EIO;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *arg)
|
||||
@@ -1862,11 +1863,12 @@ static int proc_reapurbnonblock_compat(struct usb_dev_state *ps, void __user *ar
|
||||
int retval;
|
||||
struct async *as;
|
||||
|
||||
retval = -EAGAIN;
|
||||
as = async_getcompleted(ps);
|
||||
if (as) {
|
||||
retval = processcompl_compat(as, (void __user * __user *)arg);
|
||||
free_async(as);
|
||||
} else {
|
||||
retval = (connected(ps) ? -EAGAIN : -ENODEV);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -2038,7 +2040,8 @@ static int proc_get_capabilities(struct usb_dev_state *ps, void __user *arg)
|
||||
{
|
||||
__u32 caps;
|
||||
|
||||
caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM;
|
||||
caps = USBDEVFS_CAP_ZERO_PACKET | USBDEVFS_CAP_NO_PACKET_SIZE_LIM |
|
||||
USBDEVFS_CAP_REAP_AFTER_DISCONNECT;
|
||||
if (!ps->dev->bus->no_stop_on_short)
|
||||
caps |= USBDEVFS_CAP_BULK_CONTINUATION;
|
||||
if (ps->dev->bus->sg_tablesize)
|
||||
@@ -2138,6 +2141,32 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
return -EPERM;
|
||||
|
||||
usb_lock_device(dev);
|
||||
|
||||
/* Reap operations are allowed even after disconnection */
|
||||
switch (cmd) {
|
||||
case USBDEVFS_REAPURB:
|
||||
snoop(&dev->dev, "%s: REAPURB\n", __func__);
|
||||
ret = proc_reapurb(ps, p);
|
||||
goto done;
|
||||
|
||||
case USBDEVFS_REAPURBNDELAY:
|
||||
snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__);
|
||||
ret = proc_reapurbnonblock(ps, p);
|
||||
goto done;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case USBDEVFS_REAPURB32:
|
||||
snoop(&dev->dev, "%s: REAPURB32\n", __func__);
|
||||
ret = proc_reapurb_compat(ps, p);
|
||||
goto done;
|
||||
|
||||
case USBDEVFS_REAPURBNDELAY32:
|
||||
snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__);
|
||||
ret = proc_reapurbnonblock_compat(ps, p);
|
||||
goto done;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!connected(ps)) {
|
||||
usb_unlock_device(dev);
|
||||
return -ENODEV;
|
||||
@@ -2231,16 +2260,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
inode->i_mtime = CURRENT_TIME;
|
||||
break;
|
||||
|
||||
case USBDEVFS_REAPURB32:
|
||||
snoop(&dev->dev, "%s: REAPURB32\n", __func__);
|
||||
ret = proc_reapurb_compat(ps, p);
|
||||
break;
|
||||
|
||||
case USBDEVFS_REAPURBNDELAY32:
|
||||
snoop(&dev->dev, "%s: REAPURBNDELAY32\n", __func__);
|
||||
ret = proc_reapurbnonblock_compat(ps, p);
|
||||
break;
|
||||
|
||||
case USBDEVFS_IOCTL32:
|
||||
snoop(&dev->dev, "%s: IOCTL32\n", __func__);
|
||||
ret = proc_ioctl_compat(ps, ptr_to_compat(p));
|
||||
@@ -2252,16 +2271,6 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
ret = proc_unlinkurb(ps, p);
|
||||
break;
|
||||
|
||||
case USBDEVFS_REAPURB:
|
||||
snoop(&dev->dev, "%s: REAPURB\n", __func__);
|
||||
ret = proc_reapurb(ps, p);
|
||||
break;
|
||||
|
||||
case USBDEVFS_REAPURBNDELAY:
|
||||
snoop(&dev->dev, "%s: REAPURBNDELAY\n", __func__);
|
||||
ret = proc_reapurbnonblock(ps, p);
|
||||
break;
|
||||
|
||||
case USBDEVFS_DISCSIGNAL:
|
||||
snoop(&dev->dev, "%s: DISCSIGNAL\n", __func__);
|
||||
ret = proc_disconnectsignal(ps, p);
|
||||
@@ -2304,6 +2313,8 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
|
||||
ret = proc_free_streams(ps, p);
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
usb_unlock_device(dev);
|
||||
if (ret >= 0)
|
||||
inode->i_atime = CURRENT_TIME;
|
||||
|
@@ -275,21 +275,6 @@ static int usb_unbind_device(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel any pending scheduled resets
|
||||
*
|
||||
* [see usb_queue_reset_device()]
|
||||
*
|
||||
* Called after unconfiguring / when releasing interfaces. See
|
||||
* comments in __usb_queue_reset_device() regarding
|
||||
* udev->reset_running.
|
||||
*/
|
||||
static void usb_cancel_queued_reset(struct usb_interface *iface)
|
||||
{
|
||||
if (iface->reset_running == 0)
|
||||
cancel_work_sync(&iface->reset_ws);
|
||||
}
|
||||
|
||||
/* called from driver core with dev locked */
|
||||
static int usb_probe_interface(struct device *dev)
|
||||
{
|
||||
@@ -380,7 +365,6 @@ static int usb_probe_interface(struct device *dev)
|
||||
usb_set_intfdata(intf, NULL);
|
||||
intf->needs_remote_wakeup = 0;
|
||||
intf->condition = USB_INTERFACE_UNBOUND;
|
||||
usb_cancel_queued_reset(intf);
|
||||
|
||||
/* If the LPM disable succeeded, balance the ref counts. */
|
||||
if (!lpm_disable_error)
|
||||
@@ -425,7 +409,6 @@ static int usb_unbind_interface(struct device *dev)
|
||||
usb_disable_interface(udev, intf, false);
|
||||
|
||||
driver->disconnect(intf);
|
||||
usb_cancel_queued_reset(intf);
|
||||
|
||||
/* Free streams */
|
||||
for (i = 0, j = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
|
||||
@@ -1797,6 +1780,18 @@ static int autosuspend_check(struct usb_device *udev)
|
||||
dev_dbg(&udev->dev, "remote wakeup needed for autosuspend\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device is a direct child of the root hub and the HCD
|
||||
* doesn't handle wakeup requests, don't allow autosuspend when
|
||||
* wakeup is needed.
|
||||
*/
|
||||
if (w && udev->parent == udev->bus->root_hub &&
|
||||
bus_to_hcd(udev->bus)->cant_recv_wakeups) {
|
||||
dev_dbg(&udev->dev, "HCD doesn't handle wakeup requests\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
udev->do_remote_wakeup = w;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1618,6 +1618,7 @@ static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status)
|
||||
int usb_hcd_unlink_urb (struct urb *urb, int status)
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
struct usb_device *udev = urb->dev;
|
||||
int retval = -EIDRM;
|
||||
unsigned long flags;
|
||||
|
||||
@@ -1629,20 +1630,19 @@ int usb_hcd_unlink_urb (struct urb *urb, int status)
|
||||
spin_lock_irqsave(&hcd_urb_unlink_lock, flags);
|
||||
if (atomic_read(&urb->use_count) > 0) {
|
||||
retval = 0;
|
||||
usb_get_dev(urb->dev);
|
||||
usb_get_dev(udev);
|
||||
}
|
||||
spin_unlock_irqrestore(&hcd_urb_unlink_lock, flags);
|
||||
if (retval == 0) {
|
||||
hcd = bus_to_hcd(urb->dev->bus);
|
||||
retval = unlink1(hcd, urb, status);
|
||||
usb_put_dev(urb->dev);
|
||||
if (retval == 0)
|
||||
retval = -EINPROGRESS;
|
||||
else if (retval != -EIDRM && retval != -EBUSY)
|
||||
dev_dbg(&udev->dev, "hcd_unlink_urb %p fail %d\n",
|
||||
urb, retval);
|
||||
usb_put_dev(udev);
|
||||
}
|
||||
|
||||
if (retval == 0)
|
||||
retval = -EINPROGRESS;
|
||||
else if (retval != -EIDRM && retval != -EBUSY)
|
||||
dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n",
|
||||
urb, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@@ -2896,10 +2896,12 @@ static int port_is_suspended(struct usb_hub *hub, unsigned portstatus)
|
||||
*/
|
||||
static int check_port_resume_type(struct usb_device *udev,
|
||||
struct usb_hub *hub, int port1,
|
||||
int status, unsigned portchange, unsigned portstatus)
|
||||
int status, u16 portchange, u16 portstatus)
|
||||
{
|
||||
struct usb_port *port_dev = hub->ports[port1 - 1];
|
||||
int retries = 3;
|
||||
|
||||
retry:
|
||||
/* Is a warm reset needed to recover the connection? */
|
||||
if (status == 0 && udev->reset_resume
|
||||
&& hub_port_warm_reset_required(hub, port1, portstatus)) {
|
||||
@@ -2907,10 +2909,17 @@ static int check_port_resume_type(struct usb_device *udev,
|
||||
}
|
||||
/* Is the device still present? */
|
||||
else if (status || port_is_suspended(hub, portstatus) ||
|
||||
!port_is_power_on(hub, portstatus) ||
|
||||
!(portstatus & USB_PORT_STAT_CONNECTION)) {
|
||||
!port_is_power_on(hub, portstatus)) {
|
||||
if (status >= 0)
|
||||
status = -ENODEV;
|
||||
} else if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
|
||||
if (retries--) {
|
||||
usleep_range(200, 300);
|
||||
status = hub_port_status(hub, port1, &portstatus,
|
||||
&portchange);
|
||||
goto retry;
|
||||
}
|
||||
status = -ENODEV;
|
||||
}
|
||||
|
||||
/* Can't do a normal resume if the port isn't enabled,
|
||||
@@ -4643,9 +4652,13 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
|
||||
if (!(portstatus & USB_PORT_STAT_CONNECTION) ||
|
||||
test_bit(port1, hub->removed_bits)) {
|
||||
|
||||
/* maybe switch power back on (e.g. root hub was reset) */
|
||||
/*
|
||||
* maybe switch power back on (e.g. root hub was reset)
|
||||
* but only if the port isn't owned by someone else.
|
||||
*/
|
||||
if (hub_is_port_power_switchable(hub)
|
||||
&& !port_is_power_on(hub, portstatus))
|
||||
&& !port_is_power_on(hub, portstatus)
|
||||
&& !port_dev->port_owner)
|
||||
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
|
||||
|
||||
if (portstatus & USB_PORT_STAT_ENABLE)
|
||||
@@ -4870,7 +4883,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
|
||||
static void port_event(struct usb_hub *hub, int port1)
|
||||
__must_hold(&port_dev->status_lock)
|
||||
{
|
||||
int connect_change, reset_device = 0;
|
||||
int connect_change;
|
||||
struct usb_port *port_dev = hub->ports[port1 - 1];
|
||||
struct usb_device *udev = port_dev->child;
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
@@ -4958,30 +4971,14 @@ static void port_event(struct usb_hub *hub, int port1)
|
||||
if (hub_port_reset(hub, port1, NULL,
|
||||
HUB_BH_RESET_TIME, true) < 0)
|
||||
hub_port_disable(hub, port1, 1);
|
||||
} else
|
||||
reset_device = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* On disconnect USB3 protocol ports transit from U0 to
|
||||
* SS.Inactive to Rx.Detect. If this happens a warm-
|
||||
* reset is not needed, but a (re)connect may happen
|
||||
* before hub_wq runs and sees the disconnect, and the
|
||||
* device may be an unknown state.
|
||||
*
|
||||
* If the port went through SS.Inactive without hub_wq
|
||||
* seeing it the C_LINK_STATE change flag will be set,
|
||||
* and we reset the dev to put it in a known state.
|
||||
*/
|
||||
if (reset_device || (udev && hub_is_superspeed(hub->hdev)
|
||||
&& (portchange & USB_PORT_STAT_C_LINK_STATE)
|
||||
&& (portstatus & USB_PORT_STAT_CONNECTION))) {
|
||||
usb_unlock_port(port_dev);
|
||||
usb_lock_device(udev);
|
||||
usb_reset_device(udev);
|
||||
usb_unlock_device(udev);
|
||||
usb_lock_port(port_dev);
|
||||
connect_change = 0;
|
||||
} else {
|
||||
usb_unlock_port(port_dev);
|
||||
usb_lock_device(udev);
|
||||
usb_reset_device(udev);
|
||||
usb_unlock_device(udev);
|
||||
usb_lock_port(port_dev);
|
||||
connect_change = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (connect_change)
|
||||
@@ -5577,26 +5574,19 @@ EXPORT_SYMBOL_GPL(usb_reset_device);
|
||||
* possible; depending on how the driver attached to each interface
|
||||
* handles ->pre_reset(), the second reset might happen or not.
|
||||
*
|
||||
* - If a driver is unbound and it had a pending reset, the reset will
|
||||
* be cancelled.
|
||||
* - If the reset is delayed so long that the interface is unbound from
|
||||
* its driver, the reset will be skipped.
|
||||
*
|
||||
* - This function can be called during .probe() or .disconnect()
|
||||
* times. On return from .disconnect(), any pending resets will be
|
||||
* cancelled.
|
||||
*
|
||||
* There is no no need to lock/unlock the @reset_ws as schedule_work()
|
||||
* does its own.
|
||||
*
|
||||
* NOTE: We don't do any reference count tracking because it is not
|
||||
* needed. The lifecycle of the work_struct is tied to the
|
||||
* usb_interface. Before destroying the interface we cancel the
|
||||
* work_struct, so the fact that work_struct is queued and or
|
||||
* running means the interface (and thus, the device) exist and
|
||||
* are referenced.
|
||||
* - This function can be called during .probe(). It can also be called
|
||||
* during .disconnect(), but doing so is pointless because the reset
|
||||
* will not occur. If you really want to reset the device during
|
||||
* .disconnect(), call usb_reset_device() directly -- but watch out
|
||||
* for nested unbinding issues!
|
||||
*/
|
||||
void usb_queue_reset_device(struct usb_interface *iface)
|
||||
{
|
||||
schedule_work(&iface->reset_ws);
|
||||
if (schedule_work(&iface->reset_ws))
|
||||
usb_get_intf(iface);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_queue_reset_device);
|
||||
|
||||
|
@@ -1551,6 +1551,7 @@ static void usb_release_interface(struct device *dev)
|
||||
altsetting_to_usb_interface_cache(intf->altsetting);
|
||||
|
||||
kref_put(&intfc->ref, usb_release_interface_cache);
|
||||
usb_put_dev(interface_to_usbdev(intf));
|
||||
kfree(intf);
|
||||
}
|
||||
|
||||
@@ -1626,24 +1627,6 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
|
||||
|
||||
/*
|
||||
* Internal function to queue a device reset
|
||||
*
|
||||
* This is initialized into the workstruct in 'struct
|
||||
* usb_device->reset_ws' that is launched by
|
||||
* message.c:usb_set_configuration() when initializing each 'struct
|
||||
* usb_interface'.
|
||||
*
|
||||
* It is safe to get the USB device without reference counts because
|
||||
* the life cycle of @iface is bound to the life cycle of @udev. Then,
|
||||
* this function will be ran only if @iface is alive (and before
|
||||
* freeing it any scheduled instances of it will have been cancelled).
|
||||
*
|
||||
* We need to set a flag (usb_dev->reset_running) because when we call
|
||||
* the reset, the interfaces might be unbound. The current interface
|
||||
* cannot try to remove the queued work as it would cause a deadlock
|
||||
* (you cannot remove your work from within your executing
|
||||
* workqueue). This flag lets it know, so that
|
||||
* usb_cancel_queued_reset() doesn't try to do it.
|
||||
*
|
||||
* See usb_queue_reset_device() for more details
|
||||
*/
|
||||
static void __usb_queue_reset_device(struct work_struct *ws)
|
||||
@@ -1655,11 +1638,10 @@ static void __usb_queue_reset_device(struct work_struct *ws)
|
||||
|
||||
rc = usb_lock_device_for_reset(udev, iface);
|
||||
if (rc >= 0) {
|
||||
iface->reset_running = 1;
|
||||
usb_reset_device(udev);
|
||||
iface->reset_running = 0;
|
||||
usb_unlock_device(udev);
|
||||
}
|
||||
usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */
|
||||
}
|
||||
|
||||
|
||||
@@ -1854,6 +1836,7 @@ free_interfaces:
|
||||
dev_set_name(&intf->dev, "%d-%s:%d.%d",
|
||||
dev->bus->busnum, dev->devpath,
|
||||
configuration, alt->desc.bInterfaceNumber);
|
||||
usb_get_dev(dev);
|
||||
}
|
||||
kfree(new_interfaces);
|
||||
|
||||
|
@@ -1049,6 +1049,7 @@ static int __init usb_init(void)
|
||||
pr_info("%s: USB support disabled\n", usbcore_name);
|
||||
return 0;
|
||||
}
|
||||
usb_init_pool_max();
|
||||
|
||||
retval = usb_debugfs_init();
|
||||
if (retval)
|
||||
|
Reference in New Issue
Block a user