diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2010-10-28 18:40:26 -0400 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2011-03-13 21:23:06 -0400 |
commit | c56354378426e550aaf6ddf3983f502a8fddeab5 (patch) | |
tree | 35464da7692b5ac096bc05841b2dc4761e711117 /include/linux/usb | |
parent | 83de4b2b90887b5b317d8313864fe4cc5db35280 (diff) |
usb: Make core allocate resources per PCI-device.
Introduce the notion of a PCI device that may be associated with more than
one USB host controller driver (struct usb_hcd). This patch is the start
of the work to separate the xHCI host controller into two roothubs: a USB
3.0 roothub with SuperSpeed-only ports, and a USB 2.0 roothub with
HS/FS/LS ports.
One usb_hcd structure is designated to be the "primary HCD", and a pointer
is added to the usb_hcd structure to keep track of that. A new function
call, usb_hcd_is_primary_hcd() is added to check whether the USB hcd is
marked as the primary HCD (or if it is not part of a roothub pair). To
allow the USB core and xHCI driver to access either roothub in a pair, a
"shared_hcd" pointer is added to the usb_hcd structure.
Add a new function, usb_create_shared_hcd(), that does roothub allocation
for paired roothubs. It will act just like usb_create_hcd() did if the
primary_hcd pointer argument is NULL. If it is passed a non-NULL
primary_hcd pointer, it sets usb_hcd->shared_hcd and usb_hcd->primary_hcd
fields. It will also skip the bandwidth_mutex allocation, and set the
secondary hcd's bandwidth_mutex pointer to the primary HCD's mutex.
IRQs are only allocated once for the primary roothub.
Introduce a new usb_hcd driver flag that indicates the host controller
driver wants to create two roothubs. If the HCD_SHARED flag is set, then
the USB core PCI probe methods will allocate a second roothub, and make
sure that second roothub gets freed during rmmod and in initialization
error paths.
When usb_hc_died() is called with the primary HCD, make sure that any
roothubs that share that host controller are also marked as being dead.
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'include/linux/usb')
-rw-r--r-- | include/linux/usb/hcd.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index b8bb6934f30b..0097136ba45d 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
@@ -147,6 +147,8 @@ struct usb_hcd { | |||
147 | * to the device, or resetting the bandwidth after a failed attempt. | 147 | * to the device, or resetting the bandwidth after a failed attempt. |
148 | */ | 148 | */ |
149 | struct mutex *bandwidth_mutex; | 149 | struct mutex *bandwidth_mutex; |
150 | struct usb_hcd *shared_hcd; | ||
151 | struct usb_hcd *primary_hcd; | ||
150 | 152 | ||
151 | 153 | ||
152 | #define HCD_BUFFER_POOLS 4 | 154 | #define HCD_BUFFER_POOLS 4 |
@@ -209,6 +211,7 @@ struct hc_driver { | |||
209 | int flags; | 211 | int flags; |
210 | #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ | 212 | #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ |
211 | #define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ | 213 | #define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ |
214 | #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ | ||
212 | #define HCD_USB11 0x0010 /* USB 1.1 */ | 215 | #define HCD_USB11 0x0010 /* USB 1.1 */ |
213 | #define HCD_USB2 0x0020 /* USB 2.0 */ | 216 | #define HCD_USB2 0x0020 /* USB 2.0 */ |
214 | #define HCD_USB3 0x0040 /* USB 3.0 */ | 217 | #define HCD_USB3 0x0040 /* USB 3.0 */ |
@@ -370,8 +373,12 @@ extern int usb_hcd_get_frame_number(struct usb_device *udev); | |||
370 | 373 | ||
371 | extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, | 374 | extern struct usb_hcd *usb_create_hcd(const struct hc_driver *driver, |
372 | struct device *dev, const char *bus_name); | 375 | struct device *dev, const char *bus_name); |
376 | extern struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver, | ||
377 | struct device *dev, const char *bus_name, | ||
378 | struct usb_hcd *shared_hcd); | ||
373 | extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); | 379 | extern struct usb_hcd *usb_get_hcd(struct usb_hcd *hcd); |
374 | extern void usb_put_hcd(struct usb_hcd *hcd); | 380 | extern void usb_put_hcd(struct usb_hcd *hcd); |
381 | extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd); | ||
375 | extern int usb_add_hcd(struct usb_hcd *hcd, | 382 | extern int usb_add_hcd(struct usb_hcd *hcd, |
376 | unsigned int irqnum, unsigned long irqflags); | 383 | unsigned int irqnum, unsigned long irqflags); |
377 | extern void usb_remove_hcd(struct usb_hcd *hcd); | 384 | extern void usb_remove_hcd(struct usb_hcd *hcd); |