diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2005-04-25 11:25:17 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-06-27 17:43:49 -0400 |
commit | 8ec8d20b21f00a36343ca0ebd6c6be9421724a1e (patch) | |
tree | 7b30b39e57579f04adef17375c61cf12a1e18b4c /drivers/usb | |
parent | bc96c0ad1ed0c938fefc0423aa99f086c5a2a1ea (diff) |
[PATCH] usbcore: register root hub in usb_add_hcd
This patch makes usbcore automatically allocate and register the root hub
device for a new host controller when the controller is registered. This
way the HCDs don't all have to include the same boilerplate code. As a
pleasant side benefit, the register_root_hub routine can now be made
static and not EXPORTed.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/hcd.c | 72 | ||||
-rw-r--r-- | drivers/usb/core/hcd.h | 3 |
2 files changed, 49 insertions, 26 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 1180c157b717..83e732a0d64a 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -832,30 +832,22 @@ static void usb_deregister_bus (struct usb_bus *bus) | |||
832 | } | 832 | } |
833 | 833 | ||
834 | /** | 834 | /** |
835 | * usb_hcd_register_root_hub - called by HCD to register its root hub | 835 | * register_root_hub - called by usb_add_hcd() to register a root hub |
836 | * @usb_dev: the usb root hub device to be registered. | 836 | * @usb_dev: the usb root hub device to be registered. |
837 | * @hcd: host controller for this root hub | 837 | * @hcd: host controller for this root hub |
838 | * | 838 | * |
839 | * The USB host controller calls this function to register the root hub | 839 | * This function registers the root hub with the USB subsystem. It sets up |
840 | * properly with the USB subsystem. It sets up the device properly in | 840 | * the device properly in the device tree and stores the root_hub pointer |
841 | * the device tree and stores the root_hub pointer in the bus structure, | 841 | * in the bus structure, then calls usb_new_device() to register the usb |
842 | * then calls usb_new_device() to register the usb device. It also | 842 | * device. It also assigns the root hub's USB address (always 1). |
843 | * assigns the root hub's USB address (always 1). | ||
844 | */ | 843 | */ |
845 | int usb_hcd_register_root_hub (struct usb_device *usb_dev, struct usb_hcd *hcd) | 844 | static int register_root_hub (struct usb_device *usb_dev, |
845 | struct usb_hcd *hcd) | ||
846 | { | 846 | { |
847 | struct device *parent_dev = hcd->self.controller; | 847 | struct device *parent_dev = hcd->self.controller; |
848 | const int devnum = 1; | 848 | const int devnum = 1; |
849 | int retval; | 849 | int retval; |
850 | 850 | ||
851 | /* hcd->driver->start() reported can_wakeup, probably with | ||
852 | * assistance from board's boot firmware. | ||
853 | * NOTE: normal devices won't enable wakeup by default. | ||
854 | */ | ||
855 | if (hcd->can_wakeup) | ||
856 | dev_dbg (parent_dev, "supports USB remote wakeup\n"); | ||
857 | hcd->remote_wakeup = hcd->can_wakeup; | ||
858 | |||
859 | usb_dev->devnum = devnum; | 851 | usb_dev->devnum = devnum; |
860 | usb_dev->bus->devnum_next = devnum + 1; | 852 | usb_dev->bus->devnum_next = devnum + 1; |
861 | memset (&usb_dev->bus->devmap.devicemap, 0, | 853 | memset (&usb_dev->bus->devmap.devicemap, 0, |
@@ -898,7 +890,6 @@ int usb_hcd_register_root_hub (struct usb_device *usb_dev, struct usb_hcd *hcd) | |||
898 | 890 | ||
899 | return retval; | 891 | return retval; |
900 | } | 892 | } |
901 | EXPORT_SYMBOL_GPL(usb_hcd_register_root_hub); | ||
902 | 893 | ||
903 | void usb_enable_root_hub_irq (struct usb_bus *bus) | 894 | void usb_enable_root_hub_irq (struct usb_bus *bus) |
904 | { | 895 | { |
@@ -1724,7 +1715,8 @@ EXPORT_SYMBOL (usb_put_hcd); | |||
1724 | int usb_add_hcd(struct usb_hcd *hcd, | 1715 | int usb_add_hcd(struct usb_hcd *hcd, |
1725 | unsigned int irqnum, unsigned long irqflags) | 1716 | unsigned int irqnum, unsigned long irqflags) |
1726 | { | 1717 | { |
1727 | int retval; | 1718 | int retval; |
1719 | struct usb_device *rhdev; | ||
1728 | 1720 | ||
1729 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); | 1721 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); |
1730 | 1722 | ||
@@ -1740,7 +1732,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1740 | } | 1732 | } |
1741 | 1733 | ||
1742 | if ((retval = usb_register_bus(&hcd->self)) < 0) | 1734 | if ((retval = usb_register_bus(&hcd->self)) < 0) |
1743 | goto err1; | 1735 | goto err_register_bus; |
1744 | 1736 | ||
1745 | if (hcd->driver->irq) { | 1737 | if (hcd->driver->irq) { |
1746 | char buf[8], *bufp = buf; | 1738 | char buf[8], *bufp = buf; |
@@ -1757,7 +1749,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1757 | hcd->irq_descr, hcd)) != 0) { | 1749 | hcd->irq_descr, hcd)) != 0) { |
1758 | dev_err(hcd->self.controller, | 1750 | dev_err(hcd->self.controller, |
1759 | "request interrupt %s failed\n", bufp); | 1751 | "request interrupt %s failed\n", bufp); |
1760 | goto err2; | 1752 | goto err_request_irq; |
1761 | } | 1753 | } |
1762 | hcd->irq = irqnum; | 1754 | hcd->irq = irqnum; |
1763 | dev_info(hcd->self.controller, "irq %s, %s 0x%08llx\n", bufp, | 1755 | dev_info(hcd->self.controller, "irq %s, %s 0x%08llx\n", bufp, |
@@ -1773,21 +1765,55 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1773 | (unsigned long long)hcd->rsrc_start); | 1765 | (unsigned long long)hcd->rsrc_start); |
1774 | } | 1766 | } |
1775 | 1767 | ||
1768 | /* Allocate the root hub before calling hcd->driver->start(), | ||
1769 | * but don't register it until afterward so that the hardware | ||
1770 | * is running. | ||
1771 | */ | ||
1772 | if ((rhdev = usb_alloc_dev(NULL, &hcd->self, 0)) == NULL) { | ||
1773 | dev_err(hcd->self.controller, "unable to allocate root hub\n"); | ||
1774 | retval = -ENOMEM; | ||
1775 | goto err_allocate_root_hub; | ||
1776 | } | ||
1777 | rhdev->speed = (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH : | ||
1778 | USB_SPEED_FULL; | ||
1779 | |||
1780 | /* Although in principle hcd->driver->start() might need to use rhdev, | ||
1781 | * none of the current drivers do. | ||
1782 | */ | ||
1776 | if ((retval = hcd->driver->start(hcd)) < 0) { | 1783 | if ((retval = hcd->driver->start(hcd)) < 0) { |
1777 | dev_err(hcd->self.controller, "startup error %d\n", retval); | 1784 | dev_err(hcd->self.controller, "startup error %d\n", retval); |
1778 | goto err3; | 1785 | goto err_hcd_driver_start; |
1779 | } | 1786 | } |
1780 | 1787 | ||
1788 | /* hcd->driver->start() reported can_wakeup, probably with | ||
1789 | * assistance from board's boot firmware. | ||
1790 | * NOTE: normal devices won't enable wakeup by default. | ||
1791 | */ | ||
1792 | if (hcd->can_wakeup) | ||
1793 | dev_dbg(hcd->self.controller, "supports USB remote wakeup\n"); | ||
1794 | hcd->remote_wakeup = hcd->can_wakeup; | ||
1795 | |||
1796 | if ((retval = register_root_hub(rhdev, hcd)) != 0) | ||
1797 | goto err_register_root_hub; | ||
1798 | |||
1781 | if (hcd->uses_new_polling && hcd->poll_rh) | 1799 | if (hcd->uses_new_polling && hcd->poll_rh) |
1782 | usb_hcd_poll_rh_status(hcd); | 1800 | usb_hcd_poll_rh_status(hcd); |
1783 | return retval; | 1801 | return retval; |
1784 | 1802 | ||
1785 | err3: | 1803 | err_register_root_hub: |
1804 | hcd->driver->stop(hcd); | ||
1805 | |||
1806 | err_hcd_driver_start: | ||
1807 | usb_put_dev(rhdev); | ||
1808 | |||
1809 | err_allocate_root_hub: | ||
1786 | if (hcd->irq >= 0) | 1810 | if (hcd->irq >= 0) |
1787 | free_irq(irqnum, hcd); | 1811 | free_irq(irqnum, hcd); |
1788 | err2: | 1812 | |
1813 | err_request_irq: | ||
1789 | usb_deregister_bus(&hcd->self); | 1814 | usb_deregister_bus(&hcd->self); |
1790 | err1: | 1815 | |
1816 | err_register_bus: | ||
1791 | hcd_buffer_destroy(hcd); | 1817 | hcd_buffer_destroy(hcd); |
1792 | return retval; | 1818 | return retval; |
1793 | } | 1819 | } |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 3837f68bb7b3..8dc13cde2f73 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -353,9 +353,6 @@ extern long usb_calc_bus_time (int speed, int is_input, | |||
353 | 353 | ||
354 | extern struct usb_bus *usb_alloc_bus (struct usb_operations *); | 354 | extern struct usb_bus *usb_alloc_bus (struct usb_operations *); |
355 | 355 | ||
356 | extern int usb_hcd_register_root_hub (struct usb_device *usb_dev, | ||
357 | struct usb_hcd *hcd); | ||
358 | |||
359 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); | 356 | extern void usb_hcd_resume_root_hub (struct usb_hcd *hcd); |
360 | 357 | ||
361 | extern void usb_set_device_state(struct usb_device *udev, | 358 | extern void usb_set_device_state(struct usb_device *udev, |