diff options
author | Craig W. Nadler <craig@nadler.us> | 2007-06-15 23:14:35 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-07-12 19:34:40 -0400 |
commit | 165fe97ed6107d3cde63592d5ac36400a5eb9f6f (patch) | |
tree | 824bb475b4f36af465989c5dac62f4097a1bd01c /drivers/usb/core/message.c | |
parent | 50d2dc7266573dfbdc84fc207494dd21315782ef (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.c | 31 |
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 | ||
1387 | static 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); |