aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r--drivers/usb/core/message.c164
1 files changed, 140 insertions, 24 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 6d1048faf08e..de51667dd64d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -18,6 +18,8 @@
18#include "hcd.h" /* for usbcore internals */ 18#include "hcd.h" /* for usbcore internals */
19#include "usb.h" 19#include "usb.h"
20 20
21static void cancel_async_set_config(struct usb_device *udev);
22
21struct api_context { 23struct api_context {
22 struct completion done; 24 struct completion done;
23 int status; 25 int status;
@@ -139,9 +141,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request,
139 141
140 dr->bRequestType = requesttype; 142 dr->bRequestType = requesttype;
141 dr->bRequest = request; 143 dr->bRequest = request;
142 dr->wValue = cpu_to_le16p(&value); 144 dr->wValue = cpu_to_le16(value);
143 dr->wIndex = cpu_to_le16p(&index); 145 dr->wIndex = cpu_to_le16(index);
144 dr->wLength = cpu_to_le16p(&size); 146 dr->wLength = cpu_to_le16(size);
145 147
146 /* dbg("usb_control_msg"); */ 148 /* dbg("usb_control_msg"); */
147 149
@@ -1004,6 +1006,34 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
1004} 1006}
1005EXPORT_SYMBOL_GPL(usb_clear_halt); 1007EXPORT_SYMBOL_GPL(usb_clear_halt);
1006 1008
1009static int create_intf_ep_devs(struct usb_interface *intf)
1010{
1011 struct usb_device *udev = interface_to_usbdev(intf);
1012 struct usb_host_interface *alt = intf->cur_altsetting;
1013 int i;
1014
1015 if (intf->ep_devs_created || intf->unregistering)
1016 return 0;
1017
1018 for (i = 0; i < alt->desc.bNumEndpoints; ++i)
1019 (void) usb_create_ep_devs(&intf->dev, &alt->endpoint[i], udev);
1020 intf->ep_devs_created = 1;
1021 return 0;
1022}
1023
1024static void remove_intf_ep_devs(struct usb_interface *intf)
1025{
1026 struct usb_host_interface *alt = intf->cur_altsetting;
1027 int i;
1028
1029 if (!intf->ep_devs_created)
1030 return;
1031
1032 for (i = 0; i < alt->desc.bNumEndpoints; ++i)
1033 usb_remove_ep_devs(&alt->endpoint[i]);
1034 intf->ep_devs_created = 0;
1035}
1036
1007/** 1037/**
1008 * usb_disable_endpoint -- Disable an endpoint by address 1038 * usb_disable_endpoint -- Disable an endpoint by address
1009 * @dev: the device whose endpoint is being disabled 1039 * @dev: the device whose endpoint is being disabled
@@ -1092,7 +1122,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
1092 dev_dbg(&dev->dev, "unregistering interface %s\n", 1122 dev_dbg(&dev->dev, "unregistering interface %s\n",
1093 dev_name(&interface->dev)); 1123 dev_name(&interface->dev));
1094 interface->unregistering = 1; 1124 interface->unregistering = 1;
1095 usb_remove_sysfs_intf_files(interface); 1125 remove_intf_ep_devs(interface);
1096 device_del(&interface->dev); 1126 device_del(&interface->dev);
1097 } 1127 }
1098 1128
@@ -1113,22 +1143,26 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
1113 * usb_enable_endpoint - Enable an endpoint for USB communications 1143 * usb_enable_endpoint - Enable an endpoint for USB communications
1114 * @dev: the device whose interface is being enabled 1144 * @dev: the device whose interface is being enabled
1115 * @ep: the endpoint 1145 * @ep: the endpoint
1146 * @reset_toggle: flag to set the endpoint's toggle back to 0
1116 * 1147 *
1117 * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. 1148 * Resets the endpoint toggle if asked, and sets dev->ep_{in,out} pointers.
1118 * For control endpoints, both the input and output sides are handled. 1149 * For control endpoints, both the input and output sides are handled.
1119 */ 1150 */
1120void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) 1151void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep,
1152 bool reset_toggle)
1121{ 1153{
1122 int epnum = usb_endpoint_num(&ep->desc); 1154 int epnum = usb_endpoint_num(&ep->desc);
1123 int is_out = usb_endpoint_dir_out(&ep->desc); 1155 int is_out = usb_endpoint_dir_out(&ep->desc);
1124 int is_control = usb_endpoint_xfer_control(&ep->desc); 1156 int is_control = usb_endpoint_xfer_control(&ep->desc);
1125 1157
1126 if (is_out || is_control) { 1158 if (is_out || is_control) {
1127 usb_settoggle(dev, epnum, 1, 0); 1159 if (reset_toggle)
1160 usb_settoggle(dev, epnum, 1, 0);
1128 dev->ep_out[epnum] = ep; 1161 dev->ep_out[epnum] = ep;
1129 } 1162 }
1130 if (!is_out || is_control) { 1163 if (!is_out || is_control) {
1131 usb_settoggle(dev, epnum, 0, 0); 1164 if (reset_toggle)
1165 usb_settoggle(dev, epnum, 0, 0);
1132 dev->ep_in[epnum] = ep; 1166 dev->ep_in[epnum] = ep;
1133 } 1167 }
1134 ep->enabled = 1; 1168 ep->enabled = 1;
@@ -1138,17 +1172,18 @@ void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep)
1138 * usb_enable_interface - Enable all the endpoints for an interface 1172 * usb_enable_interface - Enable all the endpoints for an interface
1139 * @dev: the device whose interface is being enabled 1173 * @dev: the device whose interface is being enabled
1140 * @intf: pointer to the interface descriptor 1174 * @intf: pointer to the interface descriptor
1175 * @reset_toggles: flag to set the endpoints' toggles back to 0
1141 * 1176 *
1142 * Enables all the endpoints for the interface's current altsetting. 1177 * Enables all the endpoints for the interface's current altsetting.
1143 */ 1178 */
1144static void usb_enable_interface(struct usb_device *dev, 1179void usb_enable_interface(struct usb_device *dev,
1145 struct usb_interface *intf) 1180 struct usb_interface *intf, bool reset_toggles)
1146{ 1181{
1147 struct usb_host_interface *alt = intf->cur_altsetting; 1182 struct usb_host_interface *alt = intf->cur_altsetting;
1148 int i; 1183 int i;
1149 1184
1150 for (i = 0; i < alt->desc.bNumEndpoints; ++i) 1185 for (i = 0; i < alt->desc.bNumEndpoints; ++i)
1151 usb_enable_endpoint(dev, &alt->endpoint[i]); 1186 usb_enable_endpoint(dev, &alt->endpoint[i], reset_toggles);
1152} 1187}
1153 1188
1154/** 1189/**
@@ -1235,8 +1270,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
1235 */ 1270 */
1236 1271
1237 /* prevent submissions using previous endpoint settings */ 1272 /* prevent submissions using previous endpoint settings */
1238 if (iface->cur_altsetting != alt) 1273 if (iface->cur_altsetting != alt) {
1274 remove_intf_ep_devs(iface);
1239 usb_remove_sysfs_intf_files(iface); 1275 usb_remove_sysfs_intf_files(iface);
1276 }
1240 usb_disable_interface(dev, iface); 1277 usb_disable_interface(dev, iface);
1241 1278
1242 iface->cur_altsetting = alt; 1279 iface->cur_altsetting = alt;
@@ -1271,10 +1308,11 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
1271 * during the SETUP stage - hence EP0 toggles are "don't care" here. 1308 * during the SETUP stage - hence EP0 toggles are "don't care" here.
1272 * (Likewise, EP0 never "halts" on well designed devices.) 1309 * (Likewise, EP0 never "halts" on well designed devices.)
1273 */ 1310 */
1274 usb_enable_interface(dev, iface); 1311 usb_enable_interface(dev, iface, true);
1275 if (device_is_registered(&iface->dev)) 1312 if (device_is_registered(&iface->dev)) {
1276 usb_create_sysfs_intf_files(iface); 1313 usb_create_sysfs_intf_files(iface);
1277 1314 create_intf_ep_devs(iface);
1315 }
1278 return 0; 1316 return 0;
1279} 1317}
1280EXPORT_SYMBOL_GPL(usb_set_interface); 1318EXPORT_SYMBOL_GPL(usb_set_interface);
@@ -1334,7 +1372,6 @@ int usb_reset_configuration(struct usb_device *dev)
1334 struct usb_interface *intf = config->interface[i]; 1372 struct usb_interface *intf = config->interface[i];
1335 struct usb_host_interface *alt; 1373 struct usb_host_interface *alt;
1336 1374
1337 usb_remove_sysfs_intf_files(intf);
1338 alt = usb_altnum_to_altsetting(intf, 0); 1375 alt = usb_altnum_to_altsetting(intf, 0);
1339 1376
1340 /* No altsetting 0? We'll assume the first altsetting. 1377 /* No altsetting 0? We'll assume the first altsetting.
@@ -1345,10 +1382,16 @@ int usb_reset_configuration(struct usb_device *dev)
1345 if (!alt) 1382 if (!alt)
1346 alt = &intf->altsetting[0]; 1383 alt = &intf->altsetting[0];
1347 1384
1385 if (alt != intf->cur_altsetting) {
1386 remove_intf_ep_devs(intf);
1387 usb_remove_sysfs_intf_files(intf);
1388 }
1348 intf->cur_altsetting = alt; 1389 intf->cur_altsetting = alt;
1349 usb_enable_interface(dev, intf); 1390 usb_enable_interface(dev, intf, true);
1350 if (device_is_registered(&intf->dev)) 1391 if (device_is_registered(&intf->dev)) {
1351 usb_create_sysfs_intf_files(intf); 1392 usb_create_sysfs_intf_files(intf);
1393 create_intf_ep_devs(intf);
1394 }
1352 } 1395 }
1353 return 0; 1396 return 0;
1354} 1397}
@@ -1441,6 +1484,46 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
1441 return retval; 1484 return retval;
1442} 1485}
1443 1486
1487
1488/*
1489 * Internal function to queue a device reset
1490 *
1491 * This is initialized into the workstruct in 'struct
1492 * usb_device->reset_ws' that is launched by
1493 * message.c:usb_set_configuration() when initializing each 'struct
1494 * usb_interface'.
1495 *
1496 * It is safe to get the USB device without reference counts because
1497 * the life cycle of @iface is bound to the life cycle of @udev. Then,
1498 * this function will be ran only if @iface is alive (and before
1499 * freeing it any scheduled instances of it will have been cancelled).
1500 *
1501 * We need to set a flag (usb_dev->reset_running) because when we call
1502 * the reset, the interfaces might be unbound. The current interface
1503 * cannot try to remove the queued work as it would cause a deadlock
1504 * (you cannot remove your work from within your executing
1505 * workqueue). This flag lets it know, so that
1506 * usb_cancel_queued_reset() doesn't try to do it.
1507 *
1508 * See usb_queue_reset_device() for more details
1509 */
1510void __usb_queue_reset_device(struct work_struct *ws)
1511{
1512 int rc;
1513 struct usb_interface *iface =
1514 container_of(ws, struct usb_interface, reset_ws);
1515 struct usb_device *udev = interface_to_usbdev(iface);
1516
1517 rc = usb_lock_device_for_reset(udev, iface);
1518 if (rc >= 0) {
1519 iface->reset_running = 1;
1520 usb_reset_device(udev);
1521 iface->reset_running = 0;
1522 usb_unlock_device(udev);
1523 }
1524}
1525
1526
1444/* 1527/*
1445 * usb_set_configuration - Makes a particular device setting be current 1528 * usb_set_configuration - Makes a particular device setting be current
1446 * @dev: the device whose configuration is being updated 1529 * @dev: the device whose configuration is being updated
@@ -1560,6 +1643,9 @@ free_interfaces:
1560 if (dev->state != USB_STATE_ADDRESS) 1643 if (dev->state != USB_STATE_ADDRESS)
1561 usb_disable_device(dev, 1); /* Skip ep0 */ 1644 usb_disable_device(dev, 1); /* Skip ep0 */
1562 1645
1646 /* Get rid of pending async Set-Config requests for this device */
1647 cancel_async_set_config(dev);
1648
1563 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 1649 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1564 USB_REQ_SET_CONFIGURATION, 0, configuration, 0, 1650 USB_REQ_SET_CONFIGURATION, 0, configuration, 0,
1565 NULL, 0, USB_CTRL_SET_TIMEOUT); 1651 NULL, 0, USB_CTRL_SET_TIMEOUT);
@@ -1604,13 +1690,14 @@ free_interfaces:
1604 alt = &intf->altsetting[0]; 1690 alt = &intf->altsetting[0];
1605 1691
1606 intf->cur_altsetting = alt; 1692 intf->cur_altsetting = alt;
1607 usb_enable_interface(dev, intf); 1693 usb_enable_interface(dev, intf, true);
1608 intf->dev.parent = &dev->dev; 1694 intf->dev.parent = &dev->dev;
1609 intf->dev.driver = NULL; 1695 intf->dev.driver = NULL;
1610 intf->dev.bus = &usb_bus_type; 1696 intf->dev.bus = &usb_bus_type;
1611 intf->dev.type = &usb_if_device_type; 1697 intf->dev.type = &usb_if_device_type;
1612 intf->dev.groups = usb_interface_groups; 1698 intf->dev.groups = usb_interface_groups;
1613 intf->dev.dma_mask = dev->dev.dma_mask; 1699 intf->dev.dma_mask = dev->dev.dma_mask;
1700 INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
1614 device_initialize(&intf->dev); 1701 device_initialize(&intf->dev);
1615 mark_quiesced(intf); 1702 mark_quiesced(intf);
1616 dev_set_name(&intf->dev, "%d-%s:%d.%d", 1703 dev_set_name(&intf->dev, "%d-%s:%d.%d",
@@ -1641,17 +1728,21 @@ free_interfaces:
1641 dev_name(&intf->dev), ret); 1728 dev_name(&intf->dev), ret);
1642 continue; 1729 continue;
1643 } 1730 }
1644 usb_create_sysfs_intf_files(intf); 1731 create_intf_ep_devs(intf);
1645 } 1732 }
1646 1733
1647 usb_autosuspend_device(dev); 1734 usb_autosuspend_device(dev);
1648 return 0; 1735 return 0;
1649} 1736}
1650 1737
1738static LIST_HEAD(set_config_list);
1739static DEFINE_SPINLOCK(set_config_lock);
1740
1651struct set_config_request { 1741struct set_config_request {
1652 struct usb_device *udev; 1742 struct usb_device *udev;
1653 int config; 1743 int config;
1654 struct work_struct work; 1744 struct work_struct work;
1745 struct list_head node;
1655}; 1746};
1656 1747
1657/* Worker routine for usb_driver_set_configuration() */ 1748/* Worker routine for usb_driver_set_configuration() */
@@ -1659,14 +1750,35 @@ static void driver_set_config_work(struct work_struct *work)
1659{ 1750{
1660 struct set_config_request *req = 1751 struct set_config_request *req =
1661 container_of(work, struct set_config_request, work); 1752 container_of(work, struct set_config_request, work);
1753 struct usb_device *udev = req->udev;
1754
1755 usb_lock_device(udev);
1756 spin_lock(&set_config_lock);
1757 list_del(&req->node);
1758 spin_unlock(&set_config_lock);
1662 1759
1663 usb_lock_device(req->udev); 1760 if (req->config >= -1) /* Is req still valid? */
1664 usb_set_configuration(req->udev, req->config); 1761 usb_set_configuration(udev, req->config);
1665 usb_unlock_device(req->udev); 1762 usb_unlock_device(udev);
1666 usb_put_dev(req->udev); 1763 usb_put_dev(udev);
1667 kfree(req); 1764 kfree(req);
1668} 1765}
1669 1766
1767/* Cancel pending Set-Config requests for a device whose configuration
1768 * was just changed
1769 */
1770static void cancel_async_set_config(struct usb_device *udev)
1771{
1772 struct set_config_request *req;
1773
1774 spin_lock(&set_config_lock);
1775 list_for_each_entry(req, &set_config_list, node) {
1776 if (req->udev == udev)
1777 req->config = -999; /* Mark as cancelled */
1778 }
1779 spin_unlock(&set_config_lock);
1780}
1781
1670/** 1782/**
1671 * usb_driver_set_configuration - Provide a way for drivers to change device configurations 1783 * usb_driver_set_configuration - Provide a way for drivers to change device configurations
1672 * @udev: the device whose configuration is being updated 1784 * @udev: the device whose configuration is being updated
@@ -1698,6 +1810,10 @@ int usb_driver_set_configuration(struct usb_device *udev, int config)
1698 req->config = config; 1810 req->config = config;
1699 INIT_WORK(&req->work, driver_set_config_work); 1811 INIT_WORK(&req->work, driver_set_config_work);
1700 1812
1813 spin_lock(&set_config_lock);
1814 list_add(&req->node, &set_config_list);
1815 spin_unlock(&set_config_lock);
1816
1701 usb_get_dev(udev); 1817 usb_get_dev(udev);
1702 schedule_work(&req->work); 1818 schedule_work(&req->work);
1703 return 0; 1819 return 0;