aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/buffer.c6
-rw-r--r--drivers/usb/core/config.c1
-rw-r--r--drivers/usb/core/devio.c14
-rw-r--r--drivers/usb/core/driver.c30
-rw-r--r--drivers/usb/core/endpoint.c2
-rw-r--r--drivers/usb/core/generic.c4
-rw-r--r--drivers/usb/core/hcd-pci.c6
-rw-r--r--drivers/usb/core/hcd.c37
-rw-r--r--drivers/usb/core/hub.c3
-rw-r--r--drivers/usb/core/message.c47
-rw-r--r--drivers/usb/core/port.c4
-rw-r--r--drivers/usb/core/quirks.c16
-rw-r--r--drivers/usb/core/sysfs.c14
-rw-r--r--drivers/usb/core/usb.c4
-rw-r--r--drivers/usb/core/usb.h2
15 files changed, 122 insertions, 68 deletions
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c
index 6cf22c27f2d2..fbb087b728dc 100644
--- a/drivers/usb/core/buffer.c
+++ b/drivers/usb/core/buffer.c
@@ -51,7 +51,8 @@ void __init usb_init_pool_max(void)
/**
* hcd_buffer_create - initialize buffer pools
* @hcd: the bus whose buffer pools are to be initialized
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep
*
* Call this as part of initializing a host controller that uses the dma
* memory allocators. It initializes some pools of dma-coherent memory that
@@ -88,7 +89,8 @@ int hcd_buffer_create(struct usb_hcd *hcd)
/**
* hcd_buffer_destroy - deallocate buffer pools
* @hcd: the bus whose buffer pools are to be destroyed
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep
*
* This frees the buffer pools created by hcd_buffer_create().
*/
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 562a730befda..b199eb65f378 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -1076,6 +1076,7 @@ int usb_get_bos_descriptor(struct usb_device *dev)
case USB_PTM_CAP_TYPE:
dev->bos->ptm_cap =
(struct usb_ptm_cap_descriptor *)buffer;
+ break;
default:
break;
}
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index e96a858a1218..533236366a03 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -482,11 +482,11 @@ static void snoop_urb(struct usb_device *udev,
if (userurb) { /* Async */
if (when == SUBMIT)
- dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
+ dev_info(&udev->dev, "userurb %px, ep%d %s-%s, "
"length %u\n",
userurb, ep, t, d, length);
else
- dev_info(&udev->dev, "userurb %pK, ep%d %s-%s, "
+ dev_info(&udev->dev, "userurb %px, ep%d %s-%s, "
"actual_length %u status %d\n",
userurb, ep, t, d, length,
timeout_or_status);
@@ -1997,7 +1997,7 @@ static int proc_reapurb(struct usb_dev_state *ps, void __user *arg)
if (as) {
int retval;
- snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
+ snoop(&ps->dev->dev, "reap %px\n", as->userurb);
retval = processcompl(as, (void __user * __user *)arg);
free_async(as);
return retval;
@@ -2014,7 +2014,7 @@ static int proc_reapurbnonblock(struct usb_dev_state *ps, void __user *arg)
as = async_getcompleted(ps);
if (as) {
- snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
+ snoop(&ps->dev->dev, "reap %px\n", as->userurb);
retval = processcompl(as, (void __user * __user *)arg);
free_async(as);
} else {
@@ -2142,7 +2142,7 @@ static int proc_reapurb_compat(struct usb_dev_state *ps, void __user *arg)
if (as) {
int retval;
- snoop(&ps->dev->dev, "reap %pK\n", as->userurb);
+ snoop(&ps->dev->dev, "reap %px\n", as->userurb);
retval = processcompl_compat(as, (void __user * __user *)arg);
free_async(as);
return retval;
@@ -2159,7 +2159,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 %pK\n", as->userurb);
+ snoop(&ps->dev->dev, "reap %px\n", as->userurb);
retval = processcompl_compat(as, (void __user * __user *)arg);
free_async(as);
} else {
@@ -2624,7 +2624,7 @@ static long usbdev_do_ioctl(struct file *file, unsigned int cmd,
#endif
case USBDEVFS_DISCARDURB:
- snoop(&dev->dev, "%s: DISCARDURB %pK\n", __func__, p);
+ snoop(&dev->dev, "%s: DISCARDURB %px\n", __func__, p);
ret = proc_unlinkurb(ps, p);
break;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 98b7449c11f3..4dfa44d6cc3c 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -839,6 +839,22 @@ const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
return NULL;
}
+bool usb_driver_applicable(struct usb_device *udev,
+ struct usb_device_driver *udrv)
+{
+ if (udrv->id_table && udrv->match)
+ return usb_device_match_id(udev, udrv->id_table) != NULL &&
+ udrv->match(udev);
+
+ if (udrv->id_table)
+ return usb_device_match_id(udev, udrv->id_table) != NULL;
+
+ if (udrv->match)
+ return udrv->match(udev);
+
+ return false;
+}
+
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
/* devices and interfaces are handled separately */
@@ -853,17 +869,14 @@ static int usb_device_match(struct device *dev, struct device_driver *drv)
udev = to_usb_device(dev);
udrv = to_usb_device_driver(drv);
- if (udrv->id_table)
- return usb_device_match_id(udev, udrv->id_table) != NULL;
-
- if (udrv->match)
- return udrv->match(udev);
-
/* If the device driver under consideration does not have a
* id_table or a match function, then let the driver's probe
* function decide.
*/
- return 1;
+ if (!udrv->id_table && !udrv->match)
+ return 1;
+
+ return usb_driver_applicable(udev, udrv);
} else if (is_usb_interface(dev)) {
struct usb_interface *intf;
@@ -941,8 +954,7 @@ static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
return 0;
udev = to_usb_device(dev);
- if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
- (!new_udriver->match || new_udriver->match(udev) == 0))
+ if (!usb_driver_applicable(udev, new_udriver))
return 0;
ret = device_reprobe(dev);
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 1c2c04079676..903426b6d305 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -153,7 +153,7 @@ static struct attribute *ep_dev_attrs[] = {
&dev_attr_direction.attr,
NULL,
};
-static struct attribute_group ep_dev_attr_grp = {
+static const struct attribute_group ep_dev_attr_grp = {
.attrs = ep_dev_attrs,
};
static const struct attribute_group *ep_dev_groups[] = {
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index 22c887f5c497..26f9fb9f67ca 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -205,9 +205,7 @@ static int __check_for_non_generic_match(struct device_driver *drv, void *data)
udrv = to_usb_device_driver(drv);
if (udrv == &usb_generic_driver)
return 0;
- if (usb_device_match_id(udev, udrv->id_table) != NULL)
- return 1;
- return (udrv->match && udrv->match(udev));
+ return usb_driver_applicable(udev, udrv);
}
static bool usb_generic_driver_match(struct usb_device *udev)
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index ec0d6c50610c..d630cccd2e6e 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -160,7 +160,8 @@ static void ehci_wait_for_companions(struct pci_dev *pdev, struct usb_hcd *hcd,
* @dev: USB Host Controller being probed
* @id: pci hotplug id connecting controller to HCD framework
* @driver: USB HC driver handle
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep
*
* Allocates basic PCI resources for this USB host controller, and
* then invokes the start() method for the HCD associated with it
@@ -304,7 +305,8 @@ EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
/**
* usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
* @dev: USB Host Controller being removed
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep
*
* Reverses the effect of usb_hcd_pci_probe(), first invoking
* the HCD's stop() method. It is always called from a thread
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 2c6b9578a7d3..60886a7464c3 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -747,8 +747,7 @@ error:
* driver requests it; otherwise the driver is responsible for
* calling usb_hcd_poll_rh_status() when an event occurs.
*
- * Completions are called in_interrupt(), but they may or may not
- * be in_irq().
+ * Completion handler may not sleep. See usb_hcd_giveback_urb() for details.
*/
void usb_hcd_poll_rh_status(struct usb_hcd *hcd)
{
@@ -904,7 +903,8 @@ static void usb_bus_init (struct usb_bus *bus)
/**
* usb_register_bus - registers the USB host controller with the usb core
* @bus: pointer to the bus to register
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Assigns a bus number, and links the controller into usbcore data
* structures so that it can be seen by scanning the bus list.
@@ -939,7 +939,8 @@ error_find_busnum:
/**
* usb_deregister_bus - deregisters the USB host controller
* @bus: pointer to the bus to deregister
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Recycles the bus number, and unlinks the controller from usbcore data
* structures so that it won't be seen by scanning the bus list.
@@ -1646,9 +1647,16 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
/* pass ownership to the completion handler */
urb->status = status;
- kcov_remote_start_usb((u64)urb->dev->bus->busnum);
+ /*
+ * This function can be called in task context inside another remote
+ * coverage collection section, but KCOV doesn't support that kind of
+ * recursion yet. Only collect coverage in softirq context for now.
+ */
+ if (in_serving_softirq())
+ kcov_remote_start_usb((u64)urb->dev->bus->busnum);
urb->complete(urb);
- kcov_remote_stop();
+ if (in_serving_softirq())
+ kcov_remote_stop();
usb_anchor_resume_wakeups(anchor);
atomic_dec(&urb->use_count);
@@ -1691,7 +1699,11 @@ static void usb_giveback_urb_bh(struct tasklet_struct *t)
* @hcd: host controller returning the URB
* @urb: urb being returned to the USB device driver.
* @status: completion status code for the URB.
- * Context: in_interrupt()
+ *
+ * Context: atomic. The completion callback is invoked in caller's context.
+ * For HCDs with HCD_BH flag set, the completion callback is invoked in tasklet
+ * context (except for URBs submitted to the root hub which always complete in
+ * caller's context).
*
* This hands the URB from HCD to its USB device driver, using its
* completion function. The HCD has freed all per-urb resources
@@ -2268,7 +2280,7 @@ EXPORT_SYMBOL_GPL(usb_hcd_resume_root_hub);
* usb_bus_start_enum - start immediate enumeration (for OTG)
* @bus: the bus (must use hcd framework)
* @port_num: 1-based number of port; usually bus->otg_port
- * Context: in_interrupt()
+ * Context: atomic
*
* Starts enumeration, with an immediate reset followed later by
* hub_wq identifying and possibly configuring the device.
@@ -2474,7 +2486,8 @@ EXPORT_SYMBOL_GPL(__usb_create_hcd);
* @bus_name: value to store in hcd->self.bus_name
* @primary_hcd: a pointer to the usb_hcd structure that is sharing the
* PCI device. Only allocate certain resources for the primary HCD
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Allocate a struct usb_hcd, with extra space at the end for the
* HC driver's private data. Initialize the generic members of the
@@ -2496,7 +2509,8 @@ EXPORT_SYMBOL_GPL(usb_create_shared_hcd);
* @driver: HC driver that will use this hcd
* @dev: device for this HC, stored in hcd->self.controller
* @bus_name: value to store in hcd->self.bus_name
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Allocate a struct usb_hcd, with extra space at the end for the
* HC driver's private data. Initialize the generic members of the
@@ -2830,7 +2844,8 @@ EXPORT_SYMBOL_GPL(usb_add_hcd);
/**
* usb_remove_hcd - shutdown processing for generic HCDs
* @hcd: the usb_hcd structure to remove
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Disconnects the root hub, then reverses the effects of usb_add_hcd(),
* invoking the HCD's stop() method.
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 17202b2ee063..7f71218cc1e5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2171,7 +2171,8 @@ static void hub_disconnect_children(struct usb_device *udev)
/**
* usb_disconnect - disconnect a device (usbcore-internal)
* @pdev: pointer to device being disconnected
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep
*
* Something got disconnected. Get rid of it and all of its children.
*
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 19ebb542befc..30e9e680c74c 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -119,7 +119,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev,
* @timeout: time in msecs to wait for the message to complete before timing
* out (if 0 the wait is forever)
*
- * Context: !in_interrupt ()
+ * Context: task context, might sleep.
*
* This function sends a simple control message to a specified endpoint and
* waits for the message to complete, or timeout.
@@ -204,9 +204,6 @@ int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
int ret;
u8 *data = NULL;
- if (usb_pipe_type_check(dev, pipe))
- return -EINVAL;
-
if (size) {
data = kmemdup(driver_data, size, memflags);
if (!data)
@@ -219,9 +216,8 @@ int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request,
if (ret < 0)
return ret;
- if (ret == size)
- return 0;
- return -EINVAL;
+
+ return 0;
}
EXPORT_SYMBOL_GPL(usb_control_msg_send);
@@ -273,7 +269,7 @@ int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request,
int ret;
u8 *data;
- if (!size || !driver_data || usb_pipe_type_check(dev, pipe))
+ if (!size || !driver_data)
return -EINVAL;
data = kmalloc(size, memflags);
@@ -290,7 +286,7 @@ int usb_control_msg_recv(struct usb_device *dev, __u8 endpoint, __u8 request,
memcpy(driver_data, data, size);
ret = 0;
} else {
- ret = -EINVAL;
+ ret = -EREMOTEIO;
}
exit:
@@ -310,7 +306,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_recv);
* @timeout: time in msecs to wait for the message to complete before
* timing out (if 0 the wait is forever)
*
- * Context: !in_interrupt ()
+ * Context: task context, might sleep.
*
* This function sends a simple interrupt message to a specified endpoint and
* waits for the message to complete, or timeout.
@@ -343,7 +339,7 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg);
* @timeout: time in msecs to wait for the message to complete before
* timing out (if 0 the wait is forever)
*
- * Context: !in_interrupt ()
+ * Context: task context, might sleep.
*
* This function sends a simple bulk message to a specified endpoint
* and waits for the message to complete, or timeout.
@@ -610,7 +606,8 @@ EXPORT_SYMBOL_GPL(usb_sg_init);
* usb_sg_wait - synchronously execute scatter/gather request
* @io: request block handle, as initialized with usb_sg_init().
* some fields become accessible when this call returns.
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* This function blocks until the specified I/O operation completes. It
* leverages the grouping of the related I/O requests to get good transfer
@@ -764,7 +761,8 @@ EXPORT_SYMBOL_GPL(usb_sg_cancel);
* @index: the number of the descriptor
* @buf: where to put the descriptor
* @size: how big is "buf"?
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* Gets a USB descriptor. Convenience functions exist to simplify
* getting some types of descriptors. Use
@@ -812,7 +810,8 @@ EXPORT_SYMBOL_GPL(usb_get_descriptor);
* @index: the number of the descriptor
* @buf: where to put the string
* @size: how big is "buf"?
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* Retrieves a string, encoded using UTF-16LE (Unicode, 16 bits per character,
* in little-endian byte order).
@@ -947,7 +946,8 @@ static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
* @index: the number of the descriptor
* @buf: where to put the string
* @size: how big is "buf"?
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* This converts the UTF-16LE encoded strings returned by devices, from
* usb_get_string_descriptor(), to null-terminated UTF-8 encoded ones
@@ -1036,7 +1036,8 @@ char *usb_cache_string(struct usb_device *udev, int index)
* usb_get_device_descriptor - (re)reads the device descriptor (usbcore)
* @dev: the device whose device descriptor is being updated
* @size: how much of the descriptor to read
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* Updates the copy of the device descriptor stored in the device structure,
* which dedicates space for this purpose.
@@ -1071,7 +1072,7 @@ int usb_get_device_descriptor(struct usb_device *dev, unsigned int size)
/*
* usb_set_isoch_delay - informs the device of the packet transmit delay
* @dev: the device whose delay is to be informed
- * Context: !in_interrupt()
+ * Context: task context, might sleep
*
* Since this is an optional request, we don't bother if it fails.
*/
@@ -1100,7 +1101,8 @@ int usb_set_isoch_delay(struct usb_device *dev)
* @type: USB_STATUS_TYPE_*; for standard or PTM status types
* @target: zero (for device), else interface or endpoint number
* @data: pointer to two bytes of bitmap data
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* Returns device, interface, or endpoint status. Normally only of
* interest to see if the device is self powered, or has enabled the
@@ -1177,7 +1179,8 @@ EXPORT_SYMBOL_GPL(usb_get_status);
* usb_clear_halt - tells device to clear endpoint halt/stall condition
* @dev: device whose endpoint is halted
* @pipe: endpoint "pipe" being cleared
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* This is used to clear halt conditions for bulk and interrupt endpoints,
* as reported by URB completion status. Endpoints that are halted are
@@ -1481,7 +1484,8 @@ void usb_enable_interface(struct usb_device *dev,
* @dev: the device whose interface is being updated
* @interface: the interface being updated
* @alternate: the setting being chosen.
- * Context: !in_interrupt ()
+ *
+ * Context: task context, might sleep.
*
* This is used to enable data transfers on interfaces that may not
* be enabled by default. Not all devices support such configurability.
@@ -1902,7 +1906,8 @@ static void __usb_queue_reset_device(struct work_struct *ws)
* usb_set_configuration - Makes a particular device setting be current
* @dev: the device whose configuration is being updated
* @configuration: the configuration being chosen.
- * Context: !in_interrupt(), caller owns the device lock
+ *
+ * Context: task context, might sleep. Caller holds device lock.
*
* This is used to enable non-default device modes. Not all devices
* use this kind of configurability; many devices only have one
diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c
index 235a7c645503..dfcca9c876c7 100644
--- a/drivers/usb/core/port.c
+++ b/drivers/usb/core/port.c
@@ -155,7 +155,7 @@ static struct attribute *port_dev_attrs[] = {
NULL,
};
-static struct attribute_group port_dev_attr_grp = {
+static const struct attribute_group port_dev_attr_grp = {
.attrs = port_dev_attrs,
};
@@ -169,7 +169,7 @@ static struct attribute *port_dev_usb3_attrs[] = {
NULL,
};
-static struct attribute_group port_dev_usb3_attr_grp = {
+static const struct attribute_group port_dev_usb3_attr_grp = {
.attrs = port_dev_usb3_attrs,
};
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 10574fa3f927..1b4eb7046b07 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -342,12 +342,19 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x06a3, 0x0006), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
+ /* Agfa SNAPSCAN 1212U */
+ { USB_DEVICE(0x06bd, 0x0001), .driver_info = USB_QUIRK_RESET_RESUME },
+
/* Guillemot Webcam Hercules Dualpix Exchange (2nd ID) */
{ USB_DEVICE(0x06f8, 0x0804), .driver_info = USB_QUIRK_RESET_RESUME },
/* Guillemot Webcam Hercules Dualpix Exchange*/
{ USB_DEVICE(0x06f8, 0x3005), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Guillemot Hercules DJ Console audio card (BZ 208357) */
+ { USB_DEVICE(0x06f8, 0xb000), .driver_info =
+ USB_QUIRK_ENDPOINT_IGNORE },
+
/* Midiman M-Audio Keystation 88es */
{ USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME },
@@ -378,6 +385,9 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x0926, 0x3333), .driver_info =
USB_QUIRK_CONFIG_INTF_STRINGS },
+ /* Kingston DataTraveler 3.0 */
+ { USB_DEVICE(0x0951, 0x1666), .driver_info = USB_QUIRK_NO_LPM },
+
/* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
{ USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
@@ -418,6 +428,10 @@ static const struct usb_device_id usb_quirk_list[] = {
{ USB_DEVICE(0x1532, 0x0116), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ /* Lenovo ThinkCenter A630Z TI024Gen3 usb-audio */
+ { USB_DEVICE(0x17ef, 0xa012), .driver_info =
+ USB_QUIRK_DISCONNECT_SUSPEND },
+
/* BUILDWIN Photo Frame */
{ USB_DEVICE(0x1908, 0x1315), .driver_info =
USB_QUIRK_HONOR_BNUMINTERFACES },
@@ -518,6 +532,8 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
* Matched for devices with USB_QUIRK_ENDPOINT_IGNORE.
*/
static const struct usb_device_id usb_endpoint_ignore[] = {
+ { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x01 },
+ { USB_DEVICE_INTERFACE_NUMBER(0x06f8, 0xb000, 5), .driver_info = 0x81 },
{ USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 },
{ USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0208, 1), .driver_info = 0x85 },
{ }
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 8d134193fa0c..d85699bee671 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -641,7 +641,7 @@ static struct attribute *usb2_hardware_lpm_attr[] = {
&dev_attr_usb2_lpm_besl.attr,
NULL,
};
-static struct attribute_group usb2_hardware_lpm_attr_group = {
+static const struct attribute_group usb2_hardware_lpm_attr_group = {
.name = power_group_name,
.attrs = usb2_hardware_lpm_attr,
};
@@ -651,7 +651,7 @@ static struct attribute *usb3_hardware_lpm_attr[] = {
&dev_attr_usb3_hardware_lpm_u2.attr,
NULL,
};
-static struct attribute_group usb3_hardware_lpm_attr_group = {
+static const struct attribute_group usb3_hardware_lpm_attr_group = {
.name = power_group_name,
.attrs = usb3_hardware_lpm_attr,
};
@@ -663,7 +663,7 @@ static struct attribute *power_attrs[] = {
&dev_attr_active_duration.attr,
NULL,
};
-static struct attribute_group power_attr_group = {
+static const struct attribute_group power_attr_group = {
.name = power_group_name,
.attrs = power_attrs,
};
@@ -832,7 +832,7 @@ static struct attribute *dev_attrs[] = {
#endif
NULL,
};
-static struct attribute_group dev_attr_grp = {
+static const struct attribute_group dev_attr_grp = {
.attrs = dev_attrs,
};
@@ -865,7 +865,7 @@ static umode_t dev_string_attrs_are_visible(struct kobject *kobj,
return a->mode;
}
-static struct attribute_group dev_string_attr_grp = {
+static const struct attribute_group dev_string_attr_grp = {
.attrs = dev_string_attrs,
.is_visible = dev_string_attrs_are_visible,
};
@@ -1222,7 +1222,7 @@ static struct attribute *intf_attrs[] = {
&dev_attr_interface_authorized.attr,
NULL,
};
-static struct attribute_group intf_attr_grp = {
+static const struct attribute_group intf_attr_grp = {
.attrs = intf_attrs,
};
@@ -1246,7 +1246,7 @@ static umode_t intf_assoc_attrs_are_visible(struct kobject *kobj,
return a->mode;
}
-static struct attribute_group intf_assoc_attr_grp = {
+static const struct attribute_group intf_assoc_attr_grp = {
.attrs = intf_assoc_attrs,
.is_visible = intf_assoc_attrs_are_visible,
};
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 9b4ac4415f1a..8f07b0516100 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -28,7 +28,6 @@
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/slab.h>
-#include <linux/interrupt.h> /* for in_interrupt() */
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -561,7 +560,8 @@ static bool usb_dev_authorized(struct usb_device *dev, struct usb_hcd *hcd)
* @parent: hub to which device is connected; null to allocate a root hub
* @bus: bus used to access the device
* @port1: one-based index of port; ignored for root hubs
- * Context: !in_interrupt()
+ *
+ * Context: task context, might sleep.
*
* Only hub drivers (including virtual root hub drivers for host
* controllers) should ever call this.
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h
index c893f54a3420..82538daac8b8 100644
--- a/drivers/usb/core/usb.h
+++ b/drivers/usb/core/usb.h
@@ -74,6 +74,8 @@ extern int usb_match_device(struct usb_device *dev,
const struct usb_device_id *id);
extern const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
const struct usb_device_id *id);
+extern bool usb_driver_applicable(struct usb_device *udev,
+ struct usb_device_driver *udrv);
extern void usb_forced_unbind_intf(struct usb_interface *intf);
extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);