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. | 
