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
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel