# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.471   -> 1.472  
#	drivers/usb/core/hcd.h	1.9     -> 1.10   
#	drivers/usb/core/hcd-pci.c	1.1     -> 1.2    
#	drivers/usb/core/hcd.c	1.23    -> 1.24   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/06/07	greg@kroah.com	1.472
# USB: hcd cleanups and documentation
# 
# Implement many of the hcd cleanups that David Brownell had previously submitted.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
--- a/drivers/usb/core/hcd-pci.c	Sat Jun  8 15:15:58 2002
+++ b/drivers/usb/core/hcd-pci.c	Sat Jun  8 15:15:58 2002
@@ -1,10 +1,4 @@
 /*
- * (C) Copyright Linus Torvalds 1999
- * (C) Copyright Johannes Erdfelt 1999-2001
- * (C) Copyright Andreas Gal 1999
- * (C) Copyright Gregory P. Smith 1999
- * (C) Copyright Deti Fliegl 1999
- * (C) Copyright Randy Dunlap 2000
  * (C) Copyright David Brownell 2000-2002
  * 
  * This program is free software; you can redistribute it and/or modify it
@@ -39,8 +33,6 @@
 
 /* PCI-based HCs are normal, but custom bus glue should be ok */
 
-static void hcd_irq (int irq, void *__hcd, struct pt_regs *r);
-static void hc_died (struct usb_hcd *hcd);
 
 /*-------------------------------------------------------------------------*/
 
@@ -156,7 +148,7 @@
 #else
 	bufp = __irq_itoa(dev->irq);
 #endif
-	if (request_irq (dev->irq, hcd_irq, SA_SHIRQ, hcd->description, hcd)
+	if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
 			!= 0) {
 		err ("request interrupt %s failed", bufp);
 		retval = -EBUSY;
@@ -171,8 +163,8 @@
 		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
 		base);
 
-	usb_init_bus (&hcd->self);
-	hcd->self.op = &hcd_operations;
+	usb_bus_init (&hcd->self);
+	hcd->self.op = &usb_hcd_operations;
 	hcd->self.hcpriv = (void *) hcd;
 	hcd->self.bus_name = dev->slot_name;
 	hcd->product_desc = dev->name;
@@ -336,7 +328,7 @@
 	retval = hcd->driver->resume (hcd);
 	if (!HCD_IS_RUNNING (hcd->state)) {
 		dbg ("resume %s failure, retval %d", hcd->self.bus_name, retval);
-		hc_died (hcd);
+		usb_hc_died (hcd);
 // FIXME:  recover, reset etc.
 	} else {
 		// FIXME for all connected devices, root-to-leaf:
@@ -351,51 +343,5 @@
 EXPORT_SYMBOL (usb_hcd_pci_resume);
 
 #endif	/* CONFIG_PM */
-
-/*-------------------------------------------------------------------------*/
-
-static void hcd_irq (int irq, void *__hcd, struct pt_regs * r)
-{
-	struct usb_hcd		*hcd = __hcd;
-	int			start = hcd->state;
-
-	if (unlikely (hcd->state == USB_STATE_HALT))	/* irq sharing? */
-		return;
-
-	hcd->driver->irq (hcd);
-	if (hcd->state != start && hcd->state == USB_STATE_HALT)
-		hc_died (hcd);
-}
-
-/*-------------------------------------------------------------------------*/
-
-static void hc_died (struct usb_hcd *hcd)
-{
-	struct list_head	*devlist, *urblist;
-	struct hcd_dev		*dev;
-	struct urb		*urb;
-	unsigned long		flags;
-	
-	/* flag every pending urb as done */
-	spin_lock_irqsave (&hcd_data_lock, flags);
-	list_for_each (devlist, &hcd->dev_list) {
-		dev = list_entry (devlist, struct hcd_dev, dev_list);
-		list_for_each (urblist, &dev->urb_list) {
-			urb = list_entry (urblist, struct urb, urb_list);
-			dbg ("shutdown %s urb %p pipe %x, current status %d",
-				hcd->self.bus_name, urb, urb->pipe, urb->status);
-			if (urb->status == -EINPROGRESS)
-				urb->status = -ESHUTDOWN;
-		}
-	}
-	urb = (struct urb *) hcd->rh_timer.data;
-	if (urb)
-		urb->status = -ESHUTDOWN;
-	spin_unlock_irqrestore (&hcd_data_lock, flags);
-
-	if (urb)
-		usb_rh_status_dequeue (hcd, urb);
-	hcd->driver->stop (hcd);
-}
 
 
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Sat Jun  8 15:15:58 2002
+++ b/drivers/usb/core/hcd.c	Sat Jun  8 15:15:58 2002
@@ -92,9 +92,7 @@
 DECLARE_MUTEX (usb_bus_list_lock);	/* exported only for usbfs */
 
 /* used when updating hcd data */
-spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
-
-struct usb_operations hcd_operations;
+static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
 
 /*-------------------------------------------------------------------------*/
 
@@ -571,8 +569,14 @@
 
 /*-------------------------------------------------------------------------*/
 
-/* shared initialization code */
-void usb_init_bus (struct usb_bus *bus)
+/**
+ * usb_bus_init - shared initialization code
+ * @bus: the bus structure being initialized
+ *
+ * This code is used to initialize a usb_bus structure, memory for which is
+ * separately managed.
+ */
+void usb_bus_init (struct usb_bus *bus)
 {
 	memset (&bus->devmap, 0, sizeof(struct usb_devmap));
 
@@ -591,6 +595,7 @@
 
 	atomic_set (&bus->refcnt, 1);
 }
+EXPORT_SYMBOL (usb_bus_init);
 
 /**
  * usb_alloc_bus - creates a new USB host controller structure
@@ -611,7 +616,7 @@
 	bus = kmalloc (sizeof *bus, GFP_KERNEL);
 	if (!bus)
 		return NULL;
-	usb_init_bus (bus);
+	usb_bus_init (bus);
 	bus->op = op;
 	return bus;
 }
@@ -1226,13 +1231,21 @@
 	return 0;
 }
 
-struct usb_operations hcd_operations = {
+/**
+ * usb_hcd_operations - adapts usb_bus framework to HCD framework (bus glue)
+ *
+ * When registering a USB bus through the HCD framework code, use this
+ * usb_operations vector.  The PCI glue layer does so automatically; only
+ * bus glue for non-PCI system busses will need to use this.
+ */
+struct usb_operations usb_hcd_operations = {
 	allocate:		hcd_alloc_dev,
 	get_frame_number:	hcd_get_frame_number,
 	submit_urb:		hcd_submit_urb,
 	unlink_urb:		hcd_unlink_urb,
 	deallocate:		hcd_free_dev,
 };
+EXPORT_SYMBOL (usb_hcd_operations);
 
 /*-------------------------------------------------------------------------*/
 
@@ -1272,3 +1285,70 @@
 	usb_put_urb (urb);
 }
 EXPORT_SYMBOL (usb_hcd_giveback_urb);
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_hcd_irq - hook IRQs to HCD framework (bus glue)
+ * @irq: the IRQ being raised
+ * @__hcd: pointer to the HCD whose IRQ is beinng signaled
+ * @r: saved hardware registers (not passed to HCD)
+ *
+ * When registering a USB bus through the HCD framework code, use this
+ * to handle interrupts.  The PCI glue layer does so automatically; only
+ * bus glue for non-PCI system busses will need to use this.
+ */
+void usb_hcd_irq (int irq, void *__hcd, struct pt_regs * r)
+{
+	struct usb_hcd		*hcd = __hcd;
+	int			start = hcd->state;
+
+	if (unlikely (hcd->state == USB_STATE_HALT))	/* irq sharing? */
+		return;
+
+	hcd->driver->irq (hcd);
+	if (hcd->state != start && hcd->state == USB_STATE_HALT)
+		usb_hc_died (hcd);
+}
+EXPORT_SYMBOL (usb_hcd_irq);
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_hc_died - report abnormal shutdown of a host controller (bus glue)
+ * @hcd: pointer to the HCD representing the controller
+ *
+ * This is called by bus glue to report a USB host controller that died
+ * while operations may still have been pending.  It's called automatically
+ * by the PCI glue, so only glue for non-PCI busses should need to call it. 
+ */
+void usb_hc_died (struct usb_hcd *hcd)
+{
+	struct list_head	*devlist, *urblist;
+	struct hcd_dev		*dev;
+	struct urb		*urb;
+	unsigned long		flags;
+	
+	/* flag every pending urb as done */
+	spin_lock_irqsave (&hcd_data_lock, flags);
+	list_for_each (devlist, &hcd->dev_list) {
+		dev = list_entry (devlist, struct hcd_dev, dev_list);
+		list_for_each (urblist, &dev->urb_list) {
+			urb = list_entry (urblist, struct urb, urb_list);
+			dbg ("shutdown %s urb %p pipe %x, current status %d",
+				hcd->self.bus_name, urb, urb->pipe, urb->status);
+			if (urb->status == -EINPROGRESS)
+				urb->status = -ESHUTDOWN;
+		}
+	}
+	urb = (struct urb *) hcd->rh_timer.data;
+	if (urb)
+		urb->status = -ESHUTDOWN;
+	spin_unlock_irqrestore (&hcd_data_lock, flags);
+
+	if (urb)
+		usb_rh_status_dequeue (hcd, urb);
+	hcd->driver->stop (hcd);
+}
+EXPORT_SYMBOL (usb_hc_died);
+
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h	Sat Jun  8 15:15:58 2002
+++ b/drivers/usb/core/hcd.h	Sat Jun  8 15:15:58 2002
@@ -161,12 +161,9 @@
 };
 
 extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
-extern void usb_init_bus (struct usb_bus *bus);
+extern void usb_bus_init (struct usb_bus *bus);
 extern void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb);
 
-extern spinlock_t hcd_data_lock;
-extern struct usb_operations hcd_operations;
-
 #ifdef CONFIG_PCI
 struct pci_dev;
 struct pci_device_id;
@@ -183,6 +180,11 @@
 #endif /* CONFIG_PM */
 
 #endif /* CONFIG_PCI */
+
+/* generic bus glue, needed for host controllers that don't use PCI */
+extern struct usb_operations usb_hcd_operations;
+extern void usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
+extern void usb_hc_died (struct usb_hcd *hcd);
 
 /* -------------------------------------------------------------------------- */
 
