diff options
Diffstat (limited to 'drivers/usb/core/hcd.c')
-rw-r--r-- | drivers/usb/core/hcd.c | 37 |
1 files changed, 26 insertions, 11 deletions
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. |