Greg:

This patch adds a reboot notifier to uhci-hcd so that it can quiesce the 
controller hardware during a reboot.  This is mainly to benefit programs 
like kexec, which expect the hardware to be idle, not doing DMA or 
generating IRQs.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

Index: usb-2.6/drivers/usb/host/uhci-hcd.h
===================================================================
--- usb-2.6.orig/drivers/usb/host/uhci-hcd.h
+++ usb-2.6/drivers/usb/host/uhci-hcd.h
@@ -410,6 +410,7 @@ struct uhci_hcd {
        struct timer_list stall_timer;
 
        wait_queue_head_t waitqh;               /* endpoint_disable waiters */
+       struct notifier_block reboot_notifier;  /* Quiesce for reboot */
 };
 
 /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */
Index: usb-2.6/drivers/usb/host/uhci-hcd.c
===================================================================
--- usb-2.6.orig/drivers/usb/host/uhci-hcd.c
+++ usb-2.6/drivers/usb/host/uhci-hcd.c
@@ -47,6 +47,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/usb.h>
 #include <linux/bitops.h>
+#include <linux/reboot.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -153,7 +154,8 @@ static void reset_hc(struct uhci_hcd *uh
 }
 
 /*
- * Last rites for a defunct/nonfunctional controller
+ * Last rites for a defunct/nonfunctional controller,
+ * or one we don't want to use any more.
  */
 static void hc_died(struct uhci_hcd *uhci)
 {
@@ -525,6 +527,21 @@ static int uhci_reset(struct usb_hcd *hc
        return 0;
 }
 
+/* Reboot notifier makes sure the controller is quiescent and that
+ * we're not using it any more.  This is mainly for the benefit
+ * of programs like kexec, which expect the hardware to be idle,
+ * not doing DMA, or generating IRQs.
+ */
+static int uhci_reboot(struct notifier_block *nb, unsigned long val,
+               void *v)
+{
+       struct uhci_hcd *uhci = container_of(nb, struct uhci_hcd,
+                       reboot_notifier);
+
+       hc_died(uhci);
+       return 0;
+}
+
 /*
  * Allocate a frame list, and then setup the skeleton
  *
@@ -689,6 +706,9 @@ static int uhci_start(struct usb_hcd *hc
 
        configure_hc(uhci);
        start_rh(uhci);
+
+       uhci->reboot_notifier.notifier_call = uhci_reboot;
+       register_reboot_notifier(&uhci->reboot_notifier);
        return 0;
 
 /*
@@ -729,6 +749,8 @@ static void uhci_stop(struct usb_hcd *hc
 {
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
 
+       unregister_reboot_notifier(&uhci->reboot_notifier);
+
        spin_lock_irq(&uhci->lock);
        reset_hc(uhci);
        uhci_scan_schedule(uhci, NULL);



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to