aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/message.c
diff options
context:
space:
mode:
authorCraig W. Nadler <craig@nadler.us>2007-06-15 23:14:35 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 19:34:40 -0400
commit165fe97ed6107d3cde63592d5ac36400a5eb9f6f (patch)
tree824bb475b4f36af465989c5dac62f4097a1bd01c /drivers/usb/core/message.c
parent50d2dc7266573dfbdc84fc207494dd21315782ef (diff)
USB: add IAD support to usbfs and sysfs
USB_IAD: Adds support for USB Interface Association Descriptors. This patch adds support to the USB host stack for parsing, storing, and displaying Interface Association Descriptors. In /proc/bus/usb/devices lines starting with A: show the fields in an IAD. In sysfs if an interface on a USB device is referenced by an IAD the following files will be added to the sysfs directory for that interface: iad_bFirstInterface, iad_bInterfaceCount, iad_bFunctionClass, and iad_bFunctionSubClass, iad_bFunctionProtocol Signed-off-by: Craig W. Nadler <craig@nadler.us> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/message.c')
-rw-r--r--drivers/usb/core/message.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 4c1432314711..530e854961ce 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1384,6 +1384,36 @@ struct device_type usb_if_device_type = {
1384 .uevent = usb_if_uevent, 1384 .uevent = usb_if_uevent,
1385}; 1385};
1386 1386
1387static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev,
1388 struct usb_host_config *config,
1389 u8 inum)
1390{
1391 struct usb_interface_assoc_descriptor *retval = NULL;
1392 struct usb_interface_assoc_descriptor *intf_assoc;
1393 int first_intf;
1394 int last_intf;
1395 int i;
1396
1397 for (i = 0; (i < USB_MAXIADS && config->intf_assoc[i]); i++) {
1398 intf_assoc = config->intf_assoc[i];
1399 if (intf_assoc->bInterfaceCount == 0)
1400 continue;
1401
1402 first_intf = intf_assoc->bFirstInterface;
1403 last_intf = first_intf + (intf_assoc->bInterfaceCount - 1);
1404 if (inum >= first_intf && inum <= last_intf) {
1405 if (!retval)
1406 retval = intf_assoc;
1407 else
1408 dev_err(&dev->dev, "Interface #%d referenced"
1409 " by multiple IADs\n", inum);
1410 }
1411 }
1412
1413 return retval;
1414}
1415
1416
1387/* 1417/*
1388 * usb_set_configuration - Makes a particular device setting be current 1418 * usb_set_configuration - Makes a particular device setting be current
1389 * @dev: the device whose configuration is being updated 1419 * @dev: the device whose configuration is being updated
@@ -1530,6 +1560,7 @@ free_interfaces:
1530 intfc = cp->intf_cache[i]; 1560 intfc = cp->intf_cache[i];
1531 intf->altsetting = intfc->altsetting; 1561 intf->altsetting = intfc->altsetting;
1532 intf->num_altsetting = intfc->num_altsetting; 1562 intf->num_altsetting = intfc->num_altsetting;
1563 intf->intf_assoc = find_iad(dev, cp, i);
1533 kref_get(&intfc->ref); 1564 kref_get(&intfc->ref);
1534 1565
1535 alt = usb_altnum_to_altsetting(intf, 0); 1566 alt = usb_altnum_to_altsetting(intf, 0);