Skip to content

Commit

Permalink
usb/hcd: Send a uevent signaling that the host controller had died
Browse files Browse the repository at this point in the history
This change will send an OFFLINE event to udev with the ERROR=DEAD
environment variable set when the HC dies.

By notifying user space the appropriate policies can be applied.
i.e.,
 * Collect error logs.
 * Notify the user that USB is no longer functional.
 * Perform a graceful reboot.

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Raul E Rangel authored and Greg Kroah-Hartman committed Apr 25, 2019
1 parent cf28369 commit a4d6a29
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
27 changes: 27 additions & 0 deletions Documentation/ABI/testing/usb-uevent
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
What: Raise a uevent when a USB Host Controller has died
Date: 2019-04-17
KernelVersion: 5.2
Contact: linux-usb@vger.kernel.org
Description: When the USB Host Controller has entered a state where it is no
longer functional a uevent will be raised. The uevent will
contain ACTION=offline and ERROR=DEAD.

Here is an example taken using udevadm monitor -p:

KERNEL[130.428945] offline /devices/pci0000:00/0000:00:10.0/usb2 (usb)
ACTION=offline
BUSNUM=002
DEVNAME=/dev/bus/usb/002/001
DEVNUM=001
DEVPATH=/devices/pci0000:00/0000:00:10.0/usb2
DEVTYPE=usb_device
DRIVER=usb
ERROR=DEAD
MAJOR=189
MINOR=128
PRODUCT=1d6b/2/414
SEQNUM=2168
SUBSYSTEM=usb
TYPE=9/0/1

Users: chromium-os-dev@chromium.org
24 changes: 24 additions & 0 deletions drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2435,6 +2435,19 @@ EXPORT_SYMBOL_GPL(usb_hcd_irq);

/*-------------------------------------------------------------------------*/

/* Workqueue routine for when the root-hub has died. */
static void hcd_died_work(struct work_struct *work)
{
struct usb_hcd *hcd = container_of(work, struct usb_hcd, died_work);
static char *env[] = {
"ERROR=DEAD",
NULL
};

/* Notify user space that the host controller has died */
kobject_uevent_env(&hcd->self.root_hub->dev.kobj, KOBJ_OFFLINE, env);
}

/**
* usb_hc_died - report abnormal shutdown of a host controller (bus glue)
* @hcd: pointer to the HCD representing the controller
Expand Down Expand Up @@ -2475,6 +2488,13 @@ void usb_hc_died (struct usb_hcd *hcd)
usb_kick_hub_wq(hcd->self.root_hub);
}
}

/* Handle the case where this function gets called with a shared HCD */
if (usb_hcd_is_primary_hcd(hcd))
schedule_work(&hcd->died_work);
else
schedule_work(&hcd->primary_hcd->died_work);

spin_unlock_irqrestore (&hcd_root_hub_lock, flags);
/* Make sure that the other roothub is also deallocated. */
}
Expand Down Expand Up @@ -2542,6 +2562,8 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver,
INIT_WORK(&hcd->wakeup_work, hcd_resume_work);
#endif

INIT_WORK(&hcd->died_work, hcd_died_work);

hcd->driver = driver;
hcd->speed = driver->flags & HCD_MASK;
hcd->product_desc = (driver->product_desc) ? driver->product_desc :
Expand Down Expand Up @@ -2895,6 +2917,7 @@ int usb_add_hcd(struct usb_hcd *hcd,
#ifdef CONFIG_PM
cancel_work_sync(&hcd->wakeup_work);
#endif
cancel_work_sync(&hcd->died_work);
mutex_lock(&usb_bus_idr_lock);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
mutex_unlock(&usb_bus_idr_lock);
Expand Down Expand Up @@ -2955,6 +2978,7 @@ void usb_remove_hcd(struct usb_hcd *hcd)
#ifdef CONFIG_PM
cancel_work_sync(&hcd->wakeup_work);
#endif
cancel_work_sync(&hcd->died_work);

mutex_lock(&usb_bus_idr_lock);
usb_disconnect(&rhdev); /* Sets rhdev to NULL */
Expand Down
1 change: 1 addition & 0 deletions include/linux/usb/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct usb_hcd {
#ifdef CONFIG_PM
struct work_struct wakeup_work; /* for remote wakeup */
#endif
struct work_struct died_work; /* for when the device dies */

/*
* hardware info/state
Expand Down

0 comments on commit a4d6a29

Please sign in to comment.