aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
authorLan Tianyu <tianyu.lan@intel.com>2012-09-05 01:44:32 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-10 15:59:42 -0400
commitff823c79a5c33194c2e5594f7c4686ea3547910c (patch)
tree0685b5aee627d7f3440dc09865a7715406cfee54 /drivers/usb/core/hub.c
parentfa2a9566257a3b62c328ea5d621ccf5952079dac (diff)
usb: move children to struct usb_port
The usb_device structure contains an array of usb_device "children". This array is only valid if the usb_device is a hub, so it makes no sense to store it there. Instead, store the usb_device child in its parent usb_port structure. Since usb_port is an internal USB core structure, add a new function to get the USB device child, usb_hub_find_child(). Add a new macro, usb_hub_get_each_child(), to iterate over all the children attached to a particular USB hub. Remove the printing the USB children array pointer from the usb-ip driver, since it's really not necessary. Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 87df22eef491..cdbade148995 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -40,6 +40,7 @@
40#endif 40#endif
41 41
42struct usb_port { 42struct usb_port {
43 struct usb_device *child;
43 struct device dev; 44 struct device dev;
44 struct dev_state *port_owner; 45 struct dev_state *port_owner;
45}; 46};
@@ -181,7 +182,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
181/* Note that hdev or one of its children must be locked! */ 182/* Note that hdev or one of its children must be locked! */
182static struct usb_hub *hdev_to_hub(struct usb_device *hdev) 183static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
183{ 184{
184 if (!hdev || !hdev->actconfig) 185 if (!hdev || !hdev->actconfig || !hdev->maxchild)
185 return NULL; 186 return NULL;
186 return usb_get_intfdata(hdev->actconfig->interface[0]); 187 return usb_get_intfdata(hdev->actconfig->interface[0]);
187} 188}
@@ -876,8 +877,8 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
876 struct usb_device *hdev = hub->hdev; 877 struct usb_device *hdev = hub->hdev;
877 int ret = 0; 878 int ret = 0;
878 879
879 if (hdev->children[port1-1] && set_state) 880 if (hub->ports[port1 - 1]->child && set_state)
880 usb_set_device_state(hdev->children[port1-1], 881 usb_set_device_state(hub->ports[port1 - 1]->child,
881 USB_STATE_NOTATTACHED); 882 USB_STATE_NOTATTACHED);
882 if (!hub->error && !hub_is_superspeed(hub->hdev)) 883 if (!hub->error && !hub_is_superspeed(hub->hdev))
883 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); 884 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
@@ -1033,7 +1034,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
1033 * which ports need attention. 1034 * which ports need attention.
1034 */ 1035 */
1035 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 1036 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
1036 struct usb_device *udev = hdev->children[port1-1]; 1037 struct usb_device *udev = hub->ports[port1 - 1]->child;
1037 u16 portstatus, portchange; 1038 u16 portstatus, portchange;
1038 1039
1039 portstatus = portchange = 0; 1040 portstatus = portchange = 0;
@@ -1198,8 +1199,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
1198 if (type != HUB_SUSPEND) { 1199 if (type != HUB_SUSPEND) {
1199 /* Disconnect all the children */ 1200 /* Disconnect all the children */
1200 for (i = 0; i < hdev->maxchild; ++i) { 1201 for (i = 0; i < hdev->maxchild; ++i) {
1201 if (hdev->children[i]) 1202 if (hub->ports[i]->child)
1202 usb_disconnect(&hdev->children[i]); 1203 usb_disconnect(&hub->ports[i]->child);
1203 } 1204 }
1204 } 1205 }
1205 1206
@@ -1324,11 +1325,9 @@ static int hub_configure(struct usb_hub *hub,
1324 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, 1325 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
1325 (hdev->maxchild == 1) ? "" : "s"); 1326 (hdev->maxchild == 1) ? "" : "s");
1326 1327
1327 hdev->children = kzalloc(hdev->maxchild *
1328 sizeof(struct usb_device *), GFP_KERNEL);
1329 hub->ports = kzalloc(hdev->maxchild * sizeof(struct usb_port *), 1328 hub->ports = kzalloc(hdev->maxchild * sizeof(struct usb_port *),
1330 GFP_KERNEL); 1329 GFP_KERNEL);
1331 if (!hdev->children || !hub->ports) { 1330 if (!hub->ports) {
1332 ret = -ENOMEM; 1331 ret = -ENOMEM;
1333 goto fail; 1332 goto fail;
1334 } 1333 }
@@ -1591,7 +1590,6 @@ static void hub_disconnect(struct usb_interface *intf)
1591 highspeed_hubs--; 1590 highspeed_hubs--;
1592 1591
1593 usb_free_urb(hub->urb); 1592 usb_free_urb(hub->urb);
1594 kfree(hdev->children);
1595 kfree(hub->ports); 1593 kfree(hub->ports);
1596 kfree(hub->descriptor); 1594 kfree(hub->descriptor);
1597 kfree(hub->status); 1595 kfree(hub->status);
@@ -1679,6 +1677,7 @@ static int
1679hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) 1677hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1680{ 1678{
1681 struct usb_device *hdev = interface_to_usbdev (intf); 1679 struct usb_device *hdev = interface_to_usbdev (intf);
1680 struct usb_hub *hub = hdev_to_hub(hdev);
1682 1681
1683 /* assert ifno == 0 (part of hub spec) */ 1682 /* assert ifno == 0 (part of hub spec) */
1684 switch (code) { 1683 switch (code) {
@@ -1692,11 +1691,11 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1692 else { 1691 else {
1693 info->nports = hdev->maxchild; 1692 info->nports = hdev->maxchild;
1694 for (i = 0; i < info->nports; i++) { 1693 for (i = 0; i < info->nports; i++) {
1695 if (hdev->children[i] == NULL) 1694 if (hub->ports[i]->child == NULL)
1696 info->port[i] = 0; 1695 info->port[i] = 0;
1697 else 1696 else
1698 info->port[i] = 1697 info->port[i] =
1699 hdev->children[i]->devnum; 1698 hub->ports[i]->child->devnum;
1700 } 1699 }
1701 } 1700 }
1702 spin_unlock_irq(&device_state_lock); 1701 spin_unlock_irq(&device_state_lock);
@@ -1784,11 +1783,12 @@ bool usb_device_is_owned(struct usb_device *udev)
1784 1783
1785static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1784static void recursively_mark_NOTATTACHED(struct usb_device *udev)
1786{ 1785{
1786 struct usb_hub *hub = hdev_to_hub(udev);
1787 int i; 1787 int i;
1788 1788
1789 for (i = 0; i < udev->maxchild; ++i) { 1789 for (i = 0; i < udev->maxchild; ++i) {
1790 if (udev->children[i]) 1790 if (hub->ports[i]->child)
1791 recursively_mark_NOTATTACHED(udev->children[i]); 1791 recursively_mark_NOTATTACHED(hub->ports[i]->child);
1792 } 1792 }
1793 if (udev->state == USB_STATE_SUSPENDED) 1793 if (udev->state == USB_STATE_SUSPENDED)
1794 udev->active_duration -= jiffies; 1794 udev->active_duration -= jiffies;
@@ -1952,6 +1952,7 @@ static void hub_free_dev(struct usb_device *udev)
1952void usb_disconnect(struct usb_device **pdev) 1952void usb_disconnect(struct usb_device **pdev)
1953{ 1953{
1954 struct usb_device *udev = *pdev; 1954 struct usb_device *udev = *pdev;
1955 struct usb_hub *hub = hdev_to_hub(udev);
1955 int i; 1956 int i;
1956 1957
1957 /* mark the device as inactive, so any further urb submissions for 1958 /* mark the device as inactive, so any further urb submissions for
@@ -1966,8 +1967,8 @@ void usb_disconnect(struct usb_device **pdev)
1966 1967
1967 /* Free up all the children before we remove this device */ 1968 /* Free up all the children before we remove this device */
1968 for (i = 0; i < udev->maxchild; i++) { 1969 for (i = 0; i < udev->maxchild; i++) {
1969 if (udev->children[i]) 1970 if (hub->ports[i]->child)
1970 usb_disconnect(&udev->children[i]); 1971 usb_disconnect(&hub->ports[i]->child);
1971 } 1972 }
1972 1973
1973 /* deallocate hcd/hardware state ... nuking all pending urbs and 1974 /* deallocate hcd/hardware state ... nuking all pending urbs and
@@ -3131,7 +3132,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
3131 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 3132 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
3132 struct usb_device *udev; 3133 struct usb_device *udev;
3133 3134
3134 udev = hdev->children [port1-1]; 3135 udev = hub->ports[port1 - 1]->child;
3135 if (udev && udev->can_submit) { 3136 if (udev && udev->can_submit) {
3136 dev_warn(&intf->dev, "port %d nyet suspended\n", port1); 3137 dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
3137 if (PMSG_IS_AUTO(msg)) 3138 if (PMSG_IS_AUTO(msg))
@@ -4058,7 +4059,7 @@ hub_power_remaining (struct usb_hub *hub)
4058 4059
4059 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; 4060 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
4060 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 4061 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
4061 struct usb_device *udev = hdev->children[port1 - 1]; 4062 struct usb_device *udev = hub->ports[port1 - 1]->child;
4062 int delta; 4063 int delta;
4063 4064
4064 if (!udev) 4065 if (!udev)
@@ -4122,7 +4123,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4122#endif 4123#endif
4123 4124
4124 /* Try to resuscitate an existing device */ 4125 /* Try to resuscitate an existing device */
4125 udev = hdev->children[port1-1]; 4126 udev = hub->ports[port1 - 1]->child;
4126 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && 4127 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
4127 udev->state != USB_STATE_NOTATTACHED) { 4128 udev->state != USB_STATE_NOTATTACHED) {
4128 usb_lock_device(udev); 4129 usb_lock_device(udev);
@@ -4151,7 +4152,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4151 4152
4152 /* Disconnect any existing devices under this port */ 4153 /* Disconnect any existing devices under this port */
4153 if (udev) 4154 if (udev)
4154 usb_disconnect(&hdev->children[port1-1]); 4155 usb_disconnect(&hub->ports[port1 - 1]->child);
4155 clear_bit(port1, hub->change_bits); 4156 clear_bit(port1, hub->change_bits);
4156 4157
4157 /* We can forget about a "removed" device when there's a physical 4158 /* We can forget about a "removed" device when there's a physical
@@ -4287,7 +4288,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4287 if (hdev->state == USB_STATE_NOTATTACHED) 4288 if (hdev->state == USB_STATE_NOTATTACHED)
4288 status = -ENOTCONN; 4289 status = -ENOTCONN;
4289 else 4290 else
4290 hdev->children[port1-1] = udev; 4291 hub->ports[port1 - 1]->child = udev;
4291 spin_unlock_irq(&device_state_lock); 4292 spin_unlock_irq(&device_state_lock);
4292 4293
4293 /* Run it through the hoops (find a driver, etc) */ 4294 /* Run it through the hoops (find a driver, etc) */
@@ -4295,7 +4296,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4295 status = usb_new_device(udev); 4296 status = usb_new_device(udev);
4296 if (status) { 4297 if (status) {
4297 spin_lock_irq(&device_state_lock); 4298 spin_lock_irq(&device_state_lock);
4298 hdev->children[port1-1] = NULL; 4299 hub->ports[port1 - 1]->child = NULL;
4299 spin_unlock_irq(&device_state_lock); 4300 spin_unlock_irq(&device_state_lock);
4300 } 4301 }
4301 } 4302 }
@@ -4341,7 +4342,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
4341 int ret; 4342 int ret;
4342 4343
4343 hdev = hub->hdev; 4344 hdev = hub->hdev;
4344 udev = hdev->children[port-1]; 4345 udev = hub->ports[port - 1]->child;
4345 if (!hub_is_superspeed(hdev)) { 4346 if (!hub_is_superspeed(hdev)) {
4346 if (!(portchange & USB_PORT_STAT_C_SUSPEND)) 4347 if (!(portchange & USB_PORT_STAT_C_SUSPEND))
4347 return 0; 4348 return 0;
@@ -4495,7 +4496,7 @@ static void hub_events(void)
4495 */ 4496 */
4496 if (!(portstatus & USB_PORT_STAT_ENABLE) 4497 if (!(portstatus & USB_PORT_STAT_ENABLE)
4497 && !connect_change 4498 && !connect_change
4498 && hdev->children[i-1]) { 4499 && hub->ports[i - 1]->child) {
4499 dev_err (hub_dev, 4500 dev_err (hub_dev,
4500 "port %i " 4501 "port %i "
4501 "disabled by hub (EMI?), " 4502 "disabled by hub (EMI?), "
@@ -5052,3 +5053,27 @@ void usb_queue_reset_device(struct usb_interface *iface)
5052 schedule_work(&iface->reset_ws); 5053 schedule_work(&iface->reset_ws);
5053} 5054}
5054EXPORT_SYMBOL_GPL(usb_queue_reset_device); 5055EXPORT_SYMBOL_GPL(usb_queue_reset_device);
5056
5057/**
5058 * usb_hub_find_child - Get the pointer of child device
5059 * attached to the port which is specified by @port1.
5060 * @hdev: USB device belonging to the usb hub
5061 * @port1: port num to indicate which port the child device
5062 * is attached to.
5063 *
5064 * USB drivers call this function to get hub's child device
5065 * pointer.
5066 *
5067 * Return NULL if input param is invalid and
5068 * child's usb_device pointer if non-NULL.
5069 */
5070struct usb_device *usb_hub_find_child(struct usb_device *hdev,
5071 int port1)
5072{
5073 struct usb_hub *hub = hdev_to_hub(hdev);
5074
5075 if (port1 < 1 || port1 > hdev->maxchild)
5076 return NULL;
5077 return hub->ports[port1 - 1]->child;
5078}
5079EXPORT_SYMBOL_GPL(usb_hub_find_child);