diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/driver.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 4 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 40 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 5 |
4 files changed, 30 insertions, 21 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 98760553bc95..d0a21a5f8201 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -284,7 +284,7 @@ static int usb_unbind_interface(struct device *dev) | |||
284 | * supports "soft" unbinding. | 284 | * supports "soft" unbinding. |
285 | */ | 285 | */ |
286 | if (!driver->soft_unbind) | 286 | if (!driver->soft_unbind) |
287 | usb_disable_interface(udev, intf); | 287 | usb_disable_interface(udev, intf, false); |
288 | 288 | ||
289 | driver->disconnect(intf); | 289 | driver->disconnect(intf); |
290 | usb_cancel_queued_reset(intf); | 290 | usb_cancel_queued_reset(intf); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 94d5ee263c20..cd50d86029e7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2382,8 +2382,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1) | |||
2382 | 2382 | ||
2383 | void usb_ep0_reinit(struct usb_device *udev) | 2383 | void usb_ep0_reinit(struct usb_device *udev) |
2384 | { | 2384 | { |
2385 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); | 2385 | usb_disable_endpoint(udev, 0 + USB_DIR_IN, true); |
2386 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); | 2386 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true); |
2387 | usb_enable_endpoint(udev, &udev->ep0, true); | 2387 | usb_enable_endpoint(udev, &udev->ep0, true); |
2388 | } | 2388 | } |
2389 | EXPORT_SYMBOL_GPL(usb_ep0_reinit); | 2389 | EXPORT_SYMBOL_GPL(usb_ep0_reinit); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index de51667dd64d..31fb204f44c6 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1039,14 +1039,15 @@ static void remove_intf_ep_devs(struct usb_interface *intf) | |||
1039 | * @dev: the device whose endpoint is being disabled | 1039 | * @dev: the device whose endpoint is being disabled |
1040 | * @epaddr: the endpoint's address. Endpoint number for output, | 1040 | * @epaddr: the endpoint's address. Endpoint number for output, |
1041 | * endpoint number + USB_DIR_IN for input | 1041 | * endpoint number + USB_DIR_IN for input |
1042 | * @reset_hardware: flag to erase any endpoint state stored in the | ||
1043 | * controller hardware | ||
1042 | * | 1044 | * |
1043 | * Deallocates hcd/hardware state for this endpoint ... and nukes all | 1045 | * Disables the endpoint for URB submission and nukes all pending URBs. |
1044 | * pending urbs. | 1046 | * If @reset_hardware is set then also deallocates hcd/hardware state |
1045 | * | 1047 | * for the endpoint. |
1046 | * If the HCD hasn't registered a disable() function, this sets the | ||
1047 | * endpoint's maxpacket size to 0 to prevent further submissions. | ||
1048 | */ | 1048 | */ |
1049 | void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | 1049 | void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, |
1050 | bool reset_hardware) | ||
1050 | { | 1051 | { |
1051 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | 1052 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; |
1052 | struct usb_host_endpoint *ep; | 1053 | struct usb_host_endpoint *ep; |
@@ -1056,15 +1057,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1056 | 1057 | ||
1057 | if (usb_endpoint_out(epaddr)) { | 1058 | if (usb_endpoint_out(epaddr)) { |
1058 | ep = dev->ep_out[epnum]; | 1059 | ep = dev->ep_out[epnum]; |
1059 | dev->ep_out[epnum] = NULL; | 1060 | if (reset_hardware) |
1061 | dev->ep_out[epnum] = NULL; | ||
1060 | } else { | 1062 | } else { |
1061 | ep = dev->ep_in[epnum]; | 1063 | ep = dev->ep_in[epnum]; |
1062 | dev->ep_in[epnum] = NULL; | 1064 | if (reset_hardware) |
1065 | dev->ep_in[epnum] = NULL; | ||
1063 | } | 1066 | } |
1064 | if (ep) { | 1067 | if (ep) { |
1065 | ep->enabled = 0; | 1068 | ep->enabled = 0; |
1066 | usb_hcd_flush_endpoint(dev, ep); | 1069 | usb_hcd_flush_endpoint(dev, ep); |
1067 | usb_hcd_disable_endpoint(dev, ep); | 1070 | if (reset_hardware) |
1071 | usb_hcd_disable_endpoint(dev, ep); | ||
1068 | } | 1072 | } |
1069 | } | 1073 | } |
1070 | 1074 | ||
@@ -1072,17 +1076,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1072 | * usb_disable_interface -- Disable all endpoints for an interface | 1076 | * usb_disable_interface -- Disable all endpoints for an interface |
1073 | * @dev: the device whose interface is being disabled | 1077 | * @dev: the device whose interface is being disabled |
1074 | * @intf: pointer to the interface descriptor | 1078 | * @intf: pointer to the interface descriptor |
1079 | * @reset_hardware: flag to erase any endpoint state stored in the | ||
1080 | * controller hardware | ||
1075 | * | 1081 | * |
1076 | * Disables all the endpoints for the interface's current altsetting. | 1082 | * Disables all the endpoints for the interface's current altsetting. |
1077 | */ | 1083 | */ |
1078 | void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) | 1084 | void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, |
1085 | bool reset_hardware) | ||
1079 | { | 1086 | { |
1080 | struct usb_host_interface *alt = intf->cur_altsetting; | 1087 | struct usb_host_interface *alt = intf->cur_altsetting; |
1081 | int i; | 1088 | int i; |
1082 | 1089 | ||
1083 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) { | 1090 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) { |
1084 | usb_disable_endpoint(dev, | 1091 | usb_disable_endpoint(dev, |
1085 | alt->endpoint[i].desc.bEndpointAddress); | 1092 | alt->endpoint[i].desc.bEndpointAddress, |
1093 | reset_hardware); | ||
1086 | } | 1094 | } |
1087 | } | 1095 | } |
1088 | 1096 | ||
@@ -1103,8 +1111,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1103 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, | 1111 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, |
1104 | skip_ep0 ? "non-ep0" : "all"); | 1112 | skip_ep0 ? "non-ep0" : "all"); |
1105 | for (i = skip_ep0; i < 16; ++i) { | 1113 | for (i = skip_ep0; i < 16; ++i) { |
1106 | usb_disable_endpoint(dev, i); | 1114 | usb_disable_endpoint(dev, i, true); |
1107 | usb_disable_endpoint(dev, i + USB_DIR_IN); | 1115 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
1108 | } | 1116 | } |
1109 | dev->toggle[0] = dev->toggle[1] = 0; | 1117 | dev->toggle[0] = dev->toggle[1] = 0; |
1110 | 1118 | ||
@@ -1274,7 +1282,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1274 | remove_intf_ep_devs(iface); | 1282 | remove_intf_ep_devs(iface); |
1275 | usb_remove_sysfs_intf_files(iface); | 1283 | usb_remove_sysfs_intf_files(iface); |
1276 | } | 1284 | } |
1277 | usb_disable_interface(dev, iface); | 1285 | usb_disable_interface(dev, iface, true); |
1278 | 1286 | ||
1279 | iface->cur_altsetting = alt; | 1287 | iface->cur_altsetting = alt; |
1280 | 1288 | ||
@@ -1353,8 +1361,8 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1353 | */ | 1361 | */ |
1354 | 1362 | ||
1355 | for (i = 1; i < 16; ++i) { | 1363 | for (i = 1; i < 16; ++i) { |
1356 | usb_disable_endpoint(dev, i); | 1364 | usb_disable_endpoint(dev, i, true); |
1357 | usb_disable_endpoint(dev, i + USB_DIR_IN); | 1365 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
1358 | } | 1366 | } |
1359 | 1367 | ||
1360 | config = dev->actconfig; | 1368 | config = dev->actconfig; |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 386177867a8a..9d0f33fe8719 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -15,9 +15,10 @@ extern void usb_enable_endpoint(struct usb_device *dev, | |||
15 | struct usb_host_endpoint *ep, bool reset_toggle); | 15 | struct usb_host_endpoint *ep, bool reset_toggle); |
16 | extern void usb_enable_interface(struct usb_device *dev, | 16 | extern void usb_enable_interface(struct usb_device *dev, |
17 | struct usb_interface *intf, bool reset_toggles); | 17 | struct usb_interface *intf, bool reset_toggles); |
18 | extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr); | 18 | extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, |
19 | bool reset_hardware); | ||
19 | extern void usb_disable_interface(struct usb_device *dev, | 20 | extern void usb_disable_interface(struct usb_device *dev, |
20 | struct usb_interface *intf); | 21 | struct usb_interface *intf, bool reset_hardware); |
21 | extern void usb_release_interface_cache(struct kref *ref); | 22 | extern void usb_release_interface_cache(struct kref *ref); |
22 | extern void usb_disable_device(struct usb_device *dev, int skip_ep0); | 23 | extern void usb_disable_device(struct usb_device *dev, int skip_ep0); |
23 | extern int usb_deauthorize_device(struct usb_device *); | 24 | extern int usb_deauthorize_device(struct usb_device *); |