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];
# 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 ... */
}
-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 */
*/
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);
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 *);
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);
* 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);
/* 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);
};
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;
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 */
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);
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);
/*-------------------------------------------------------------------------*/
+#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