upgrade to fedora-2.6.12-1.1398.FC4 + vserver 2.0.rc7
[linux-2.6.git] / drivers / usb / core / hcd.h
index 12a2b9f..f67cf1e 100644 (file)
@@ -63,24 +63,23 @@ struct usb_hcd {    /* usb_bus.hcpriv points to this */
        struct usb_bus          self;           /* hcd is-a bus */
 
        const char              *product_desc;  /* product/vendor string */
-       const char              *description;   /* "ehci-hcd" etc */
+       char                    irq_descr[24];  /* driver + bus # */
 
        struct timer_list       rh_timer;       /* drives root hub */
-       struct list_head        dev_list;       /* devices on this bus */
 
        /*
         * hardware info/state
         */
-       struct hc_driver        *driver;        /* hw-specific hooks */
+       const struct hc_driver  *driver;        /* hw-specific hooks */
        unsigned                saw_irq : 1;
        unsigned                can_wakeup:1;   /* hw supports wakeup? */
        unsigned                remote_wakeup:1;/* sw should use wakeup? */
+       unsigned                rh_registered:1;/* is root hub registered? */
+
        int                     irq;            /* irq allocated */
        void __iomem            *regs;          /* device memory/io */
-
-#ifdef CONFIG_PCI
-       int                     region;         /* pci region for regs */
-#endif
+       u64                     rsrc_start;     /* memory/io resource start */
+       u64                     rsrc_len;       /* memory/io resource length */
 
 #define HCD_BUFFER_POOLS       4
        struct dma_pool         *pool [HCD_BUFFER_POOLS];
@@ -90,20 +89,26 @@ struct usb_hcd {    /* usb_bus.hcpriv points to this */
 #      define  __SUSPEND               0x04
 #      define  __TRANSIENT             0x80
 
-#      define  USB_STATE_HALT          0
-#      define  USB_STATE_RUNNING       (__ACTIVE)
-#      define  USB_STATE_QUIESCING     (__SUSPEND|__TRANSIENT|__ACTIVE)
-#      define  USB_STATE_RESUMING      (__SUSPEND|__TRANSIENT)
-#      define  HCD_STATE_SUSPENDED     (__SUSPEND)
+#      define  HC_STATE_HALT           0
+#      define  HC_STATE_RUNNING        (__ACTIVE)
+#      define  HC_STATE_QUIESCING      (__SUSPEND|__TRANSIENT|__ACTIVE)
+#      define  HC_STATE_RESUMING       (__SUSPEND|__TRANSIENT)
+#      define  HC_STATE_SUSPENDED      (__SUSPEND)
 
-#define        HCD_IS_RUNNING(state) ((state) & __ACTIVE)
-#define        HCD_IS_SUSPENDED(state) ((state) & __SUSPEND)
+#define        HC_IS_RUNNING(state) ((state) & __ACTIVE)
+#define        HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
 
        /* more shared queuing code would be good; it should support
         * smarter scheduling, handle transaction translators, etc;
         * input size of periodic table to an interrupt scheduler. 
         * (ohci 32, uhci 1024, ehci 256/512/1024).
         */
+
+       /* The HC driver's private data is stored at the end of
+        * this structure.
+        */
+       unsigned long hcd_priv[0]
+                       __attribute__ ((aligned (sizeof(unsigned long))));
 };
 
 /* 2.4 does this a bit differently ... */
@@ -113,14 +118,6 @@ static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
 }
 
 
-struct hcd_dev {       /* usb_device.hcpriv points to this */
-       struct list_head        dev_list;       /* on this hcd */
-       struct list_head        urb_list;       /* pending on this dev */
-
-       /* per-configuration HC/HCD state, such as QH or ED */
-       void                    *ep[32];
-};
-
 // urb.hcpriv is really hardware-specific
 
 struct hcd_timeout {   /* timeouts we allocate */
@@ -136,8 +133,6 @@ struct hcd_timeout {        /* timeouts we allocate */
  */
 
 struct usb_operations {
-       int (*allocate)(struct usb_device *);
-       int (*deallocate)(struct usb_device *);
        int (*get_frame_number) (struct usb_device *usb_dev);
        int (*submit_urb) (struct urb *urb, int mem_flags);
        int (*unlink_urb) (struct urb *urb, int status);
@@ -149,7 +144,8 @@ struct usb_operations {
        void (*buffer_free)(struct usb_bus *bus, size_t size,
                        void *addr, dma_addr_t dma);
 
-       void (*disable)(struct usb_device *udev, int bEndpointAddress);
+       void (*disable)(struct usb_device *udev,
+                       struct usb_host_endpoint *ep);
 
        /* global suspend/resume of bus */
        int (*hub_suspend)(struct usb_bus *);
@@ -162,6 +158,8 @@ struct pt_regs;
 
 struct hc_driver {
        const char      *description;   /* "ehci-hcd" etc */
+       const char      *product_desc;  /* product/vendor string */
+       size_t          hcd_priv_size;  /* size of private data */
 
        /* irq handler */
        irqreturn_t     (*irq) (struct usb_hcd *hcd, struct pt_regs *regs);
@@ -179,7 +177,7 @@ struct hc_driver {
         * a whole, not just the root hub; they're for bus glue.
         */
        /* called after all devices were suspended */
-       int     (*suspend) (struct usb_hcd *hcd, u32 state);
+       int     (*suspend) (struct usb_hcd *hcd, pm_message_t message);
 
        /* called before any devices get resumed */
        int     (*resume) (struct usb_hcd *hcd);
@@ -190,23 +188,16 @@ struct hc_driver {
        /* return current frame number */
        int     (*get_frame_number) (struct usb_hcd *hcd);
 
-       /* memory lifecycle */
-       /* Note: The absence of hcd_free reflects a temporary situation;
-        * in the near future hcd_alloc will disappear as well and all
-        * allocations/deallocations will be handled by usbcore.  For the
-        * moment, drivers are required to return a pointer that the core
-        * can pass to kfree, i.e., the struct usb_hcd must be the _first_
-        * member of a larger driver-specific structure. */
-       struct usb_hcd  *(*hcd_alloc) (void);
-
        /* manage i/o requests, device state */
-       int     (*urb_enqueue) (struct usb_hcd *hcd, struct urb *urb,
+       int     (*urb_enqueue) (struct usb_hcd *hcd,
+                                       struct usb_host_endpoint *ep,
+                                       struct urb *urb,
                                        int mem_flags);
        int     (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
 
        /* hw synch, freeing endpoint resources that urb_dequeue can't */
        void    (*endpoint_disable)(struct usb_hcd *hcd,
-                       struct hcd_dev *dev, int bEndpointAddress);
+                       struct usb_host_endpoint *ep);
 
        /* root hub support */
        int             (*hub_status_data) (struct usb_hcd *hcd, char *buf);
@@ -219,7 +210,13 @@ struct hc_driver {
 };
 
 extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs);
-extern void usb_bus_init (struct usb_bus *bus);
+
+extern struct usb_hcd *usb_create_hcd (const struct hc_driver *driver,
+               struct device *dev, char *bus_name);
+extern void usb_put_hcd (struct usb_hcd *hcd);
+extern int usb_add_hcd(struct usb_hcd *hcd,
+               unsigned int irqnum, unsigned long irqflags);
+extern void usb_remove_hcd(struct usb_hcd *hcd);
 
 #ifdef CONFIG_PCI
 struct pci_dev;
@@ -229,7 +226,7 @@ extern int usb_hcd_pci_probe (struct pci_dev *dev,
 extern void usb_hcd_pci_remove (struct pci_dev *dev);
 
 #ifdef CONFIG_PM
-extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state);
+extern int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t state);
 extern int usb_hcd_pci_resume (struct pci_dev *dev);
 #endif /* CONFIG_PM */
 
@@ -245,7 +242,6 @@ void hcd_buffer_free (struct usb_bus *bus, size_t size,
        void *addr, dma_addr_t dma);
 
 /* generic bus glue, needed for host controllers that don't use PCI */
-extern struct usb_operations usb_hcd_operations;
 extern irqreturn_t usb_hcd_irq (int irq, void *__hcd, struct pt_regs *r);
 extern void usb_hc_died (struct usb_hcd *hcd);
 
@@ -345,27 +341,10 @@ extern long usb_calc_bus_time (int speed, int is_input,
 
 extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
 
-extern int usb_register_bus (struct usb_bus *);
-extern void usb_deregister_bus (struct usb_bus *);
-
-extern int usb_register_root_hub (struct usb_device *usb_dev,
-               struct device *parent_dev);
+extern int usb_hcd_register_root_hub (struct usb_device *usb_dev,
+               struct usb_hcd *hcd);
 
-static inline int hcd_register_root (struct usb_device *usb_dev,
-               struct usb_hcd *hcd)
-{
-       /* hcd->driver->start() reported can_wakeup, probably with
-        * assistance from board's boot firmware.
-        * NOTE:  normal devices won't enable wakeup by default.
-        */
-       if (hcd->can_wakeup)
-               dev_dbg (hcd->self.controller, "supports USB remote wakeup\n");
-       hcd->remote_wakeup = hcd->can_wakeup;
-
-       return usb_register_root_hub (usb_dev, hcd->self.controller);
-}
-
-extern void usb_hcd_release (struct usb_bus *);
+extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd);
 
 extern void usb_set_device_state(struct usb_device *udev,
                enum usb_device_state new_state);
@@ -420,6 +399,66 @@ static inline void usbfs_cleanup(void) { }
 
 /*-------------------------------------------------------------------------*/
 
+#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
+
+struct usb_mon_operations {
+       void (*urb_submit)(struct usb_bus *bus, struct urb *urb);
+       void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err);
+       void (*urb_complete)(struct usb_bus *bus, struct urb *urb);
+       /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */
+       void (*bus_add)(struct usb_bus *bus);
+       void (*bus_remove)(struct usb_bus *bus);
+};
+
+extern struct usb_mon_operations *mon_ops;
+
+static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb)
+{
+       if (bus->monitored)
+               (*mon_ops->urb_submit)(bus, urb);
+}
+
+static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
+    int error)
+{
+       if (bus->monitored)
+               (*mon_ops->urb_submit_error)(bus, urb, error);
+}
+
+static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb)
+{
+       if (bus->monitored)
+               (*mon_ops->urb_complete)(bus, urb);
+}
+static inline void usbmon_notify_bus_add(struct usb_bus *bus)
+{
+       if (mon_ops)
+               (*mon_ops->bus_add)(bus);
+}
+
+static inline void usbmon_notify_bus_remove(struct usb_bus *bus)
+{
+       if (mon_ops)
+               (*mon_ops->bus_remove)(bus);
+}
+
+int usb_mon_register(struct usb_mon_operations *ops);
+void usb_mon_deregister(void);
+
+#else
+
+static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {}
+static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb,
+    int error) {}
+static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {}
+static inline void usbmon_notify_bus_add(struct usb_bus *bus) {}
+static inline void usbmon_notify_bus_remove(struct usb_bus *bus) {}
+
+#endif /* CONFIG_USB_MON */
+
+/*-------------------------------------------------------------------------*/
+
 /* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
 // bleech -- resurfaced in 2.4.11 or 2.4.12
 #define bitmap         DeviceRemovable