This resolves a problem caused by "reboot" not actually
doing a clean shutdown of drivers. It uses a reboot
notifier to make sure that typical BIOS code (using the
USB 1.1 companion controllers) will see keyboards even
without an EHCI driver being active.
Please merge to Linus' latest, then we can close the
bug filed at OSDL.
- Dave
--- ./drivers/usb-dist/host/ehci.h Mon Feb 10 19:19:21 2003
+++ ./drivers/usb/host/ehci.h Sat Feb 15 09:18:35 2003
@@ -81,8 +82,10 @@
struct pci_pool *sitd_pool; /* sitd per split iso urb */
struct timer_list watchdog;
+ struct notifier_block reboot_notifier;
unsigned stamp;
+ /* irq statistics */
#ifdef EHCI_STATS
struct ehci_stats stats;
# define COUNT(x) do { (x)++; } while (0)
--- ./drivers/usb-dist/host/ehci-hcd.c Mon Feb 10 19:19:21 2003
+++ ./drivers/usb/host/ehci-hcd.c Sat Feb 15 10:00:06 2003
@@ -37,7 +37,7 @@
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
-
+#include <linux/reboot.h>
#include <linux/usb.h>
#include <linux/version.h>
@@ -306,6 +307,19 @@
return 0;
}
+static int
+ehci_reboot (struct notifier_block *self, unsigned long code, void *null)
+{
+ struct ehci_hcd *ehci;
+
+ ehci = container_of (self, struct ehci_hcd, reboot_notifier);
+
+ /* make BIOS/etc use companion controller during reboot */
+ writel (0, &ehci->regs->configured_flag);
+ return 0;
+}
+
+
/* called by khubd or root hub init threads */
static int ehci_start (struct usb_hcd *hcd)
@@ -464,6 +478,9 @@
* are explicitly handed to companion controller(s), so no TT is
* involved with the root hub.
*/
+ ehci->reboot_notifier.notifier_call = ehci_reboot;
+ register_reboot_notifier (&ehci->reboot_notifier);
+
ehci->hcd.state = USB_STATE_READY;
writel (FLAG_CF, &ehci->regs->configured_flag);
readl (&ehci->regs->command); /* unblock posted write */
@@ -520,6 +537,7 @@
/* let companion controllers work when we aren't */
writel (0, &ehci->regs->configured_flag);
+ unregister_reboot_notifier (&ehci->reboot_notifier);
remove_debug_files (ehci);