aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libopencm3/usb/usbstd.h19
-rw-r--r--lib/usb/usb_standard.c12
2 files changed, 30 insertions, 1 deletions
diff --git a/include/libopencm3/usb/usbstd.h b/include/libopencm3/usb/usbstd.h
index ee65b70..e77d5f8 100644
--- a/include/libopencm3/usb/usbstd.h
+++ b/include/libopencm3/usb/usbstd.h
@@ -75,6 +75,10 @@ struct usb_setup_data {
#define USB_DT_DEVICE_QUALIFIER 6
#define USB_DT_OTHER_SPEED_CONFIGURATION 7
#define USB_DT_INTERFACE_POWER 8
+/* From ECNs */
+#define USB_DT_OTG 9
+#define USB_DT_DEBUG 10
+#define USB_DT_INTERFACE_ASSOCIATION 11
/* USB Standard Feature Selectors - Table 9-6 */
#define USB_FEAT_ENDPOINT_HALT 0
@@ -134,6 +138,7 @@ struct usb_config_descriptor {
/* Descriptor ends here. The following are used internally: */
const struct usb_interface {
int num_altsetting;
+ const struct usb_iface_assoc_descriptor *iface_assoc;
const struct usb_interface_descriptor *altsetting;
} *interface;
} __attribute__((packed));
@@ -201,4 +206,18 @@ struct usb_string_descriptor {
u16 wData[];
} __attribute__((packed));
+/* From ECN: Interface Association Descriptors, Table 9-Z */
+struct usb_iface_assoc_descriptor {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bFirstInterface;
+ u8 bInterfaceCount;
+ u8 bFunctionClass;
+ u8 bFunctionSubClass;
+ u8 bFunctionProtocol;
+ u8 iFunction;
+} __attribute__((packed));
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
+ sizeof(struct usb_iface_assoc_descriptor)
+
#endif
diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c
index 1021fa8..455d3e7 100644
--- a/lib/usb/usb_standard.c
+++ b/lib/usb/usb_standard.c
@@ -41,10 +41,20 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
/* For each interface... */
for (i = 0; i < cfg->bNumInterfaces; i++) {
+ /* Interface Association Descriptor, if any */
+ if (cfg->interface[i].iface_assoc) {
+ const struct usb_iface_assoc_descriptor *assoc =
+ cfg->interface[i].iface_assoc;
+ memcpy(buf, assoc, count = MIN(len, assoc->bLength));
+ buf += count;
+ len -= count;
+ total += count;
+ totallen += assoc->bLength;
+ }
/* For each alternate setting... */
for (j = 0; j < cfg->interface[i].num_altsetting; j++) {
const struct usb_interface_descriptor *iface =
- &cfg->interface[i].altsetting[j];
+ &cfg->interface[i].altsetting[j];
/* Copy interface descriptor. */
memcpy(buf, iface, count = MIN(len, iface->bLength));
buf += count;