aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-14 12:20:37 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-14 12:20:37 -0400
commitfa286188ce0fce994c3fc2bddcafeb948834591f (patch)
tree72abc08a625c4341fc6606fdd547ed320b81fc66 /drivers/usb/core
parente44694e858ed000ef11ee37861c7f7c86d8ddbda (diff)
Revert "usb: move struct usb_device->children to struct usb_hub_port->child"
This reverts commit bebc56d58dc780539777d2b1ca80df5566e2ad87. The call here is fragile and not well thought out, so revert it, it's not fully baked yet and I don't want this to go into 3.5. Cc: Lan Tianyu <tianyu.lan@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/devices.c3
-rw-r--r--drivers/usb/core/hub.c67
2 files changed, 28 insertions, 42 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index a83962b1ccee..d95696584762 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -590,8 +590,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,
590 590
591 /* Now look at all of this device's children. */ 591 /* Now look at all of this device's children. */
592 for (chix = 0; chix < usbdev->maxchild; chix++) { 592 for (chix = 0; chix < usbdev->maxchild; chix++) {
593 struct usb_device *childdev = 593 struct usb_device *childdev = usbdev->children[chix];
594 usb_get_hub_child_device(usbdev, chix + 1);
595 594
596 if (childdev) { 595 if (childdev) {
597 usb_lock_device(childdev); 596 usb_lock_device(childdev);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6bf7124fdf96..0c17d5a91d79 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -39,7 +39,6 @@
39 39
40struct usb_hub_port { 40struct usb_hub_port {
41 void *port_owner; 41 void *port_owner;
42 struct usb_device *child;
43}; 42};
44 43
45struct usb_hub { 44struct usb_hub {
@@ -94,7 +93,7 @@ static inline int hub_is_superspeed(struct usb_device *hdev)
94 return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS); 93 return (hdev->descriptor.bDeviceProtocol == USB_HUB_PR_SS);
95} 94}
96 95
97/* Protect struct usb_device->state and struct usb_hub_port->child members 96/* Protect struct usb_device->state and ->children members
98 * Note: Both are also protected by ->dev.sem, except that ->state can 97 * Note: Both are also protected by ->dev.sem, except that ->state can
99 * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */ 98 * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
100static DEFINE_SPINLOCK(device_state_lock); 99static DEFINE_SPINLOCK(device_state_lock);
@@ -177,7 +176,7 @@ static inline char *portspeed(struct usb_hub *hub, int portstatus)
177/* Note that hdev or one of its children must be locked! */ 176/* Note that hdev or one of its children must be locked! */
178static struct usb_hub *hdev_to_hub(struct usb_device *hdev) 177static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
179{ 178{
180 if (!hdev || !hdev->actconfig || !hdev->maxchild) 179 if (!hdev || !hdev->actconfig)
181 return NULL; 180 return NULL;
182 return usb_get_intfdata(hdev->actconfig->interface[0]); 181 return usb_get_intfdata(hdev->actconfig->interface[0]);
183} 182}
@@ -650,8 +649,8 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
650 struct usb_device *hdev = hub->hdev; 649 struct usb_device *hdev = hub->hdev;
651 int ret = 0; 650 int ret = 0;
652 651
653 if (hub->port_data[port1-1].child && set_state) 652 if (hdev->children[port1-1] && set_state)
654 usb_set_device_state(hub->port_data[port1-1].child, 653 usb_set_device_state(hdev->children[port1-1],
655 USB_STATE_NOTATTACHED); 654 USB_STATE_NOTATTACHED);
656 if (!hub->error && !hub_is_superspeed(hub->hdev)) 655 if (!hub->error && !hub_is_superspeed(hub->hdev))
657 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE); 656 ret = clear_port_feature(hdev, port1, USB_PORT_FEAT_ENABLE);
@@ -807,7 +806,7 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
807 * which ports need attention. 806 * which ports need attention.
808 */ 807 */
809 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 808 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
810 struct usb_device *udev = hub->port_data[port1-1].child; 809 struct usb_device *udev = hdev->children[port1-1];
811 u16 portstatus, portchange; 810 u16 portstatus, portchange;
812 811
813 portstatus = portchange = 0; 812 portstatus = portchange = 0;
@@ -972,8 +971,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
972 if (type != HUB_SUSPEND) { 971 if (type != HUB_SUSPEND) {
973 /* Disconnect all the children */ 972 /* Disconnect all the children */
974 for (i = 0; i < hdev->maxchild; ++i) { 973 for (i = 0; i < hdev->maxchild; ++i) {
975 if (hub->port_data[i].child) 974 if (hdev->children[i])
976 usb_disconnect(&hub->port_data[i].child); 975 usb_disconnect(&hdev->children[i]);
977 } 976 }
978 } 977 }
979 978
@@ -1052,9 +1051,11 @@ static int hub_configure(struct usb_hub *hub,
1052 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, 1051 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
1053 (hdev->maxchild == 1) ? "" : "s"); 1052 (hdev->maxchild == 1) ? "" : "s");
1054 1053
1054 hdev->children = kzalloc(hdev->maxchild *
1055 sizeof(struct usb_device *), GFP_KERNEL);
1055 hub->port_data = kzalloc(hdev->maxchild * sizeof(struct usb_hub_port), 1056 hub->port_data = kzalloc(hdev->maxchild * sizeof(struct usb_hub_port),
1056 GFP_KERNEL); 1057 GFP_KERNEL);
1057 if (!hub->port_data) { 1058 if (!hub->port_data || !hdev->children) {
1058 ret = -ENOMEM; 1059 ret = -ENOMEM;
1059 goto fail; 1060 goto fail;
1060 } 1061 }
@@ -1286,6 +1287,7 @@ static unsigned highspeed_hubs;
1286static void hub_disconnect(struct usb_interface *intf) 1287static void hub_disconnect(struct usb_interface *intf)
1287{ 1288{
1288 struct usb_hub *hub = usb_get_intfdata(intf); 1289 struct usb_hub *hub = usb_get_intfdata(intf);
1290 struct usb_device *hdev = interface_to_usbdev(intf);
1289 1291
1290 /* Take the hub off the event list and don't let it be added again */ 1292 /* Take the hub off the event list and don't let it be added again */
1291 spin_lock_irq(&hub_event_lock); 1293 spin_lock_irq(&hub_event_lock);
@@ -1307,6 +1309,7 @@ static void hub_disconnect(struct usb_interface *intf)
1307 highspeed_hubs--; 1309 highspeed_hubs--;
1308 1310
1309 usb_free_urb(hub->urb); 1311 usb_free_urb(hub->urb);
1312 kfree(hdev->children);
1310 kfree(hub->port_data); 1313 kfree(hub->port_data);
1311 kfree(hub->descriptor); 1314 kfree(hub->descriptor);
1312 kfree(hub->status); 1315 kfree(hub->status);
@@ -1394,7 +1397,6 @@ static int
1394hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data) 1397hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1395{ 1398{
1396 struct usb_device *hdev = interface_to_usbdev (intf); 1399 struct usb_device *hdev = interface_to_usbdev (intf);
1397 struct usb_hub *hub = usb_get_intfdata(intf);
1398 1400
1399 /* assert ifno == 0 (part of hub spec) */ 1401 /* assert ifno == 0 (part of hub spec) */
1400 switch (code) { 1402 switch (code) {
@@ -1408,11 +1410,11 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1408 else { 1410 else {
1409 info->nports = hdev->maxchild; 1411 info->nports = hdev->maxchild;
1410 for (i = 0; i < info->nports; i++) { 1412 for (i = 0; i < info->nports; i++) {
1411 if (hub->port_data[i].child == NULL) 1413 if (hdev->children[i] == NULL)
1412 info->port[i] = 0; 1414 info->port[i] = 0;
1413 else 1415 else
1414 info->port[i] = 1416 info->port[i] =
1415 hub->port_data[i].child->devnum; 1417 hdev->children[i]->devnum;
1416 } 1418 }
1417 } 1419 }
1418 spin_unlock_irq(&device_state_lock); 1420 spin_unlock_irq(&device_state_lock);
@@ -1499,13 +1501,11 @@ bool usb_device_is_owned(struct usb_device *udev)
1499 1501
1500static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1502static void recursively_mark_NOTATTACHED(struct usb_device *udev)
1501{ 1503{
1502 struct usb_hub *hub = hdev_to_hub(udev);
1503 int i; 1504 int i;
1504 1505
1505 for (i = 0; i < udev->maxchild; ++i) { 1506 for (i = 0; i < udev->maxchild; ++i) {
1506 if (hub->port_data[i].child) 1507 if (udev->children[i])
1507 recursively_mark_NOTATTACHED( 1508 recursively_mark_NOTATTACHED(udev->children[i]);
1508 hub->port_data[i].child);
1509 } 1509 }
1510 if (udev->state == USB_STATE_SUSPENDED) 1510 if (udev->state == USB_STATE_SUSPENDED)
1511 udev->active_duration -= jiffies; 1511 udev->active_duration -= jiffies;
@@ -1669,7 +1669,6 @@ static void hub_free_dev(struct usb_device *udev)
1669void usb_disconnect(struct usb_device **pdev) 1669void usb_disconnect(struct usb_device **pdev)
1670{ 1670{
1671 struct usb_device *udev = *pdev; 1671 struct usb_device *udev = *pdev;
1672 struct usb_hub *hub = hdev_to_hub(udev);
1673 int i; 1672 int i;
1674 1673
1675 /* mark the device as inactive, so any further urb submissions for 1674 /* mark the device as inactive, so any further urb submissions for
@@ -1684,8 +1683,8 @@ void usb_disconnect(struct usb_device **pdev)
1684 1683
1685 /* Free up all the children before we remove this device */ 1684 /* Free up all the children before we remove this device */
1686 for (i = 0; i < udev->maxchild; i++) { 1685 for (i = 0; i < udev->maxchild; i++) {
1687 if (hub->port_data[i].child) 1686 if (udev->children[i])
1688 usb_disconnect(&hub->port_data[i].child); 1687 usb_disconnect(&udev->children[i]);
1689 } 1688 }
1690 1689
1691 /* deallocate hcd/hardware state ... nuking all pending urbs and 1690 /* deallocate hcd/hardware state ... nuking all pending urbs and
@@ -2766,7 +2765,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
2766 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 2765 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
2767 struct usb_device *udev; 2766 struct usb_device *udev;
2768 2767
2769 udev = hub->port_data[port1-1].child; 2768 udev = hdev->children [port1-1];
2770 if (udev && udev->can_submit) { 2769 if (udev && udev->can_submit) {
2771 dev_warn(&intf->dev, "port %d nyet suspended\n", port1); 2770 dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
2772 if (PMSG_IS_AUTO(msg)) 2771 if (PMSG_IS_AUTO(msg))
@@ -3267,7 +3266,7 @@ hub_power_remaining (struct usb_hub *hub)
3267 3266
3268 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent; 3267 remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
3269 for (port1 = 1; port1 <= hdev->maxchild; ++port1) { 3268 for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
3270 struct usb_device *udev = hub->port_data[port1 - 1].child; 3269 struct usb_device *udev = hdev->children[port1 - 1];
3271 int delta; 3270 int delta;
3272 3271
3273 if (!udev) 3272 if (!udev)
@@ -3331,7 +3330,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3331#endif 3330#endif
3332 3331
3333 /* Try to resuscitate an existing device */ 3332 /* Try to resuscitate an existing device */
3334 udev = hub->port_data[port1-1].child; 3333 udev = hdev->children[port1-1];
3335 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && 3334 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
3336 udev->state != USB_STATE_NOTATTACHED) { 3335 udev->state != USB_STATE_NOTATTACHED) {
3337 usb_lock_device(udev); 3336 usb_lock_device(udev);
@@ -3360,7 +3359,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3360 3359
3361 /* Disconnect any existing devices under this port */ 3360 /* Disconnect any existing devices under this port */
3362 if (udev) 3361 if (udev)
3363 usb_disconnect(&hub->port_data[port1-1].child); 3362 usb_disconnect(&hdev->children[port1-1]);
3364 clear_bit(port1, hub->change_bits); 3363 clear_bit(port1, hub->change_bits);
3365 3364
3366 /* We can forget about a "removed" device when there's a physical 3365 /* We can forget about a "removed" device when there's a physical
@@ -3475,7 +3474,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3475 && highspeed_hubs != 0) 3474 && highspeed_hubs != 0)
3476 check_highspeed (hub, udev, port1); 3475 check_highspeed (hub, udev, port1);
3477 3476
3478 /* Store the hub port's child pointer. At this point 3477 /* Store the parent's children[] pointer. At this point
3479 * udev becomes globally accessible, although presumably 3478 * udev becomes globally accessible, although presumably
3480 * no one will look at it until hdev is unlocked. 3479 * no one will look at it until hdev is unlocked.
3481 */ 3480 */
@@ -3489,7 +3488,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3489 if (hdev->state == USB_STATE_NOTATTACHED) 3488 if (hdev->state == USB_STATE_NOTATTACHED)
3490 status = -ENOTCONN; 3489 status = -ENOTCONN;
3491 else 3490 else
3492 hub->port_data[port1-1].child = udev; 3491 hdev->children[port1-1] = udev;
3493 spin_unlock_irq(&device_state_lock); 3492 spin_unlock_irq(&device_state_lock);
3494 3493
3495 /* Run it through the hoops (find a driver, etc) */ 3494 /* Run it through the hoops (find a driver, etc) */
@@ -3497,7 +3496,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
3497 status = usb_new_device(udev); 3496 status = usb_new_device(udev);
3498 if (status) { 3497 if (status) {
3499 spin_lock_irq(&device_state_lock); 3498 spin_lock_irq(&device_state_lock);
3500 hub->port_data[port1-1].child = NULL; 3499 hdev->children[port1-1] = NULL;
3501 spin_unlock_irq(&device_state_lock); 3500 spin_unlock_irq(&device_state_lock);
3502 } 3501 }
3503 } 3502 }
@@ -3543,7 +3542,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
3543 int ret; 3542 int ret;
3544 3543
3545 hdev = hub->hdev; 3544 hdev = hub->hdev;
3546 udev = hub->port_data[port - 1].child; 3545 udev = hdev->children[port-1];
3547 if (!hub_is_superspeed(hdev)) { 3546 if (!hub_is_superspeed(hdev)) {
3548 if (!(portchange & USB_PORT_STAT_C_SUSPEND)) 3547 if (!(portchange & USB_PORT_STAT_C_SUSPEND))
3549 return 0; 3548 return 0;
@@ -3697,7 +3696,7 @@ static void hub_events(void)
3697 */ 3696 */
3698 if (!(portstatus & USB_PORT_STAT_ENABLE) 3697 if (!(portstatus & USB_PORT_STAT_ENABLE)
3699 && !connect_change 3698 && !connect_change
3700 && hub->port_data[i-1].child) { 3699 && hdev->children[i-1]) {
3701 dev_err (hub_dev, 3700 dev_err (hub_dev,
3702 "port %i " 3701 "port %i "
3703 "disabled by hub (EMI?), " 3702 "disabled by hub (EMI?), "
@@ -4235,15 +4234,3 @@ void usb_queue_reset_device(struct usb_interface *iface)
4235 schedule_work(&iface->reset_ws); 4234 schedule_work(&iface->reset_ws);
4236} 4235}
4237EXPORT_SYMBOL_GPL(usb_queue_reset_device); 4236EXPORT_SYMBOL_GPL(usb_queue_reset_device);
4238
4239struct usb_device *usb_get_hub_child_device(struct usb_device *hdev,
4240 int port1)
4241{
4242 struct usb_hub *hub = hdev_to_hub(hdev);
4243
4244 if (!hub || port1 > hdev->maxchild || port1 < 1)
4245 return NULL;
4246 return hub->port_data[port1 - 1].child;
4247}
4248EXPORT_SYMBOL_GPL(usb_get_hub_child_device);
4249