aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/hub.c')
-rw-r--r--drivers/usb/core/hub.c126
1 files changed, 108 insertions, 18 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 71f86c60d83c..5ce839137ad6 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -78,6 +78,7 @@ struct usb_hub {
78 u8 indicator[USB_MAXCHILDREN]; 78 u8 indicator[USB_MAXCHILDREN];
79 struct delayed_work leds; 79 struct delayed_work leds;
80 struct delayed_work init_work; 80 struct delayed_work init_work;
81 void **port_owners;
81}; 82};
82 83
83 84
@@ -162,8 +163,10 @@ static inline char *portspeed(int portstatus)
162} 163}
163 164
164/* Note that hdev or one of its children must be locked! */ 165/* Note that hdev or one of its children must be locked! */
165static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev) 166static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
166{ 167{
168 if (!hdev || !hdev->actconfig)
169 return NULL;
167 return usb_get_intfdata(hdev->actconfig->interface[0]); 170 return usb_get_intfdata(hdev->actconfig->interface[0]);
168} 171}
169 172
@@ -372,7 +375,7 @@ static void kick_khubd(struct usb_hub *hub)
372 unsigned long flags; 375 unsigned long flags;
373 376
374 /* Suppress autosuspend until khubd runs */ 377 /* Suppress autosuspend until khubd runs */
375 to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; 378 atomic_set(&to_usb_interface(hub->intfdev)->pm_usage_cnt, 1);
376 379
377 spin_lock_irqsave(&hub_event_lock, flags); 380 spin_lock_irqsave(&hub_event_lock, flags);
378 if (!hub->disconnected && list_empty(&hub->event_list)) { 381 if (!hub->disconnected && list_empty(&hub->event_list)) {
@@ -384,8 +387,10 @@ static void kick_khubd(struct usb_hub *hub)
384 387
385void usb_kick_khubd(struct usb_device *hdev) 388void usb_kick_khubd(struct usb_device *hdev)
386{ 389{
387 /* FIXME: What if hdev isn't bound to the hub driver? */ 390 struct usb_hub *hub = hdev_to_hub(hdev);
388 kick_khubd(hdev_to_hub(hdev)); 391
392 if (hub)
393 kick_khubd(hub);
389} 394}
390 395
391 396
@@ -677,7 +682,8 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
677 msecs_to_jiffies(delay)); 682 msecs_to_jiffies(delay));
678 683
679 /* Suppress autosuspend until init is done */ 684 /* Suppress autosuspend until init is done */
680 to_usb_interface(hub->intfdev)->pm_usage_cnt = 1; 685 atomic_set(&to_usb_interface(hub->intfdev)->
686 pm_usage_cnt, 1);
681 return; /* Continues at init2: below */ 687 return; /* Continues at init2: below */
682 } else { 688 } else {
683 hub_power_on(hub, true); 689 hub_power_on(hub, true);
@@ -854,25 +860,24 @@ static int hub_post_reset(struct usb_interface *intf)
854static int hub_configure(struct usb_hub *hub, 860static int hub_configure(struct usb_hub *hub,
855 struct usb_endpoint_descriptor *endpoint) 861 struct usb_endpoint_descriptor *endpoint)
856{ 862{
863 struct usb_hcd *hcd;
857 struct usb_device *hdev = hub->hdev; 864 struct usb_device *hdev = hub->hdev;
858 struct device *hub_dev = hub->intfdev; 865 struct device *hub_dev = hub->intfdev;
859 u16 hubstatus, hubchange; 866 u16 hubstatus, hubchange;
860 u16 wHubCharacteristics; 867 u16 wHubCharacteristics;
861 unsigned int pipe; 868 unsigned int pipe;
862 int maxp, ret; 869 int maxp, ret;
863 char *message; 870 char *message = "out of memory";
864 871
865 hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL, 872 hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,
866 &hub->buffer_dma); 873 &hub->buffer_dma);
867 if (!hub->buffer) { 874 if (!hub->buffer) {
868 message = "can't allocate hub irq buffer";
869 ret = -ENOMEM; 875 ret = -ENOMEM;
870 goto fail; 876 goto fail;
871 } 877 }
872 878
873 hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL); 879 hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);
874 if (!hub->status) { 880 if (!hub->status) {
875 message = "can't kmalloc hub status buffer";
876 ret = -ENOMEM; 881 ret = -ENOMEM;
877 goto fail; 882 goto fail;
878 } 883 }
@@ -880,7 +885,6 @@ static int hub_configure(struct usb_hub *hub,
880 885
881 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); 886 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
882 if (!hub->descriptor) { 887 if (!hub->descriptor) {
883 message = "can't kmalloc hub descriptor";
884 ret = -ENOMEM; 888 ret = -ENOMEM;
885 goto fail; 889 goto fail;
886 } 890 }
@@ -904,6 +908,12 @@ static int hub_configure(struct usb_hub *hub,
904 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild, 908 dev_info (hub_dev, "%d port%s detected\n", hdev->maxchild,
905 (hdev->maxchild == 1) ? "" : "s"); 909 (hdev->maxchild == 1) ? "" : "s");
906 910
911 hub->port_owners = kzalloc(hdev->maxchild * sizeof(void *), GFP_KERNEL);
912 if (!hub->port_owners) {
913 ret = -ENOMEM;
914 goto fail;
915 }
916
907 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics); 917 wHubCharacteristics = le16_to_cpu(hub->descriptor->wHubCharacteristics);
908 918
909 if (wHubCharacteristics & HUB_CHAR_COMPOUND) { 919 if (wHubCharacteristics & HUB_CHAR_COMPOUND) {
@@ -1052,6 +1062,19 @@ static int hub_configure(struct usb_hub *hub,
1052 dev_dbg(hub_dev, "%umA bus power budget for each child\n", 1062 dev_dbg(hub_dev, "%umA bus power budget for each child\n",
1053 hub->mA_per_port); 1063 hub->mA_per_port);
1054 1064
1065 /* Update the HCD's internal representation of this hub before khubd
1066 * starts getting port status changes for devices under the hub.
1067 */
1068 hcd = bus_to_hcd(hdev->bus);
1069 if (hcd->driver->update_hub_device) {
1070 ret = hcd->driver->update_hub_device(hcd, hdev,
1071 &hub->tt, GFP_KERNEL);
1072 if (ret < 0) {
1073 message = "can't update HCD hub info";
1074 goto fail;
1075 }
1076 }
1077
1055 ret = hub_hub_status(hub, &hubstatus, &hubchange); 1078 ret = hub_hub_status(hub, &hubstatus, &hubchange);
1056 if (ret < 0) { 1079 if (ret < 0) {
1057 message = "can't get hub status"; 1080 message = "can't get hub status";
@@ -1082,7 +1105,6 @@ static int hub_configure(struct usb_hub *hub,
1082 1105
1083 hub->urb = usb_alloc_urb(0, GFP_KERNEL); 1106 hub->urb = usb_alloc_urb(0, GFP_KERNEL);
1084 if (!hub->urb) { 1107 if (!hub->urb) {
1085 message = "couldn't allocate interrupt urb";
1086 ret = -ENOMEM; 1108 ret = -ENOMEM;
1087 goto fail; 1109 goto fail;
1088 } 1110 }
@@ -1131,11 +1153,13 @@ static void hub_disconnect(struct usb_interface *intf)
1131 hub_quiesce(hub, HUB_DISCONNECT); 1153 hub_quiesce(hub, HUB_DISCONNECT);
1132 1154
1133 usb_set_intfdata (intf, NULL); 1155 usb_set_intfdata (intf, NULL);
1156 hub->hdev->maxchild = 0;
1134 1157
1135 if (hub->hdev->speed == USB_SPEED_HIGH) 1158 if (hub->hdev->speed == USB_SPEED_HIGH)
1136 highspeed_hubs--; 1159 highspeed_hubs--;
1137 1160
1138 usb_free_urb(hub->urb); 1161 usb_free_urb(hub->urb);
1162 kfree(hub->port_owners);
1139 kfree(hub->descriptor); 1163 kfree(hub->descriptor);
1140 kfree(hub->status); 1164 kfree(hub->status);
1141 usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer, 1165 usb_buffer_free(hub->hdev, sizeof(*hub->buffer), hub->buffer,
@@ -1250,6 +1274,79 @@ hub_ioctl(struct usb_interface *intf, unsigned int code, void *user_data)
1250 } 1274 }
1251} 1275}
1252 1276
1277/*
1278 * Allow user programs to claim ports on a hub. When a device is attached
1279 * to one of these "claimed" ports, the program will "own" the device.
1280 */
1281static int find_port_owner(struct usb_device *hdev, unsigned port1,
1282 void ***ppowner)
1283{
1284 if (hdev->state == USB_STATE_NOTATTACHED)
1285 return -ENODEV;
1286 if (port1 == 0 || port1 > hdev->maxchild)
1287 return -EINVAL;
1288
1289 /* This assumes that devices not managed by the hub driver
1290 * will always have maxchild equal to 0.
1291 */
1292 *ppowner = &(hdev_to_hub(hdev)->port_owners[port1 - 1]);
1293 return 0;
1294}
1295
1296/* In the following three functions, the caller must hold hdev's lock */
1297int usb_hub_claim_port(struct usb_device *hdev, unsigned port1, void *owner)
1298{
1299 int rc;
1300 void **powner;
1301
1302 rc = find_port_owner(hdev, port1, &powner);
1303 if (rc)
1304 return rc;
1305 if (*powner)
1306 return -EBUSY;
1307 *powner = owner;
1308 return rc;
1309}
1310
1311int usb_hub_release_port(struct usb_device *hdev, unsigned port1, void *owner)
1312{
1313 int rc;
1314 void **powner;
1315
1316 rc = find_port_owner(hdev, port1, &powner);
1317 if (rc)
1318 return rc;
1319 if (*powner != owner)
1320 return -ENOENT;
1321 *powner = NULL;
1322 return rc;
1323}
1324
1325void usb_hub_release_all_ports(struct usb_device *hdev, void *owner)
1326{
1327 int n;
1328 void **powner;
1329
1330 n = find_port_owner(hdev, 1, &powner);
1331 if (n == 0) {
1332 for (; n < hdev->maxchild; (++n, ++powner)) {
1333 if (*powner == owner)
1334 *powner = NULL;
1335 }
1336 }
1337}
1338
1339/* The caller must hold udev's lock */
1340bool usb_device_is_owned(struct usb_device *udev)
1341{
1342 struct usb_hub *hub;
1343
1344 if (udev->state == USB_STATE_NOTATTACHED || !udev->parent)
1345 return false;
1346 hub = hdev_to_hub(udev->parent);
1347 return !!hub->port_owners[udev->portnum - 1];
1348}
1349
1253 1350
1254static void recursively_mark_NOTATTACHED(struct usb_device *udev) 1351static void recursively_mark_NOTATTACHED(struct usb_device *udev)
1255{ 1352{
@@ -2849,14 +2946,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
2849 /* For a suspended device, treat this as a 2946 /* For a suspended device, treat this as a
2850 * remote wakeup event. 2947 * remote wakeup event.
2851 */ 2948 */
2852 if (udev->do_remote_wakeup) 2949 status = remote_wakeup(udev);
2853 status = remote_wakeup(udev);
2854
2855 /* Otherwise leave it be; devices can't tell the
2856 * difference between suspended and disabled.
2857 */
2858 else
2859 status = 0;
2860#endif 2950#endif
2861 2951
2862 } else { 2952 } else {