--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -91,6 +91,15 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, 
size_t len)
     dest[0x08] = conf->bMaxPower;
     wTotalLength += bLength;
 
+    /* handle Interface Association Descriptor, if present */
+    if (conf->niad != 0) {
+        rc = usb_desc_iad(conf->iad, dest + wTotalLength, len - 
wTotalLength);
+        if (rc < 0) {
+            return rc;
+        }
+        wTotalLength += rc;
+    }
+    
     count = conf->nif ? conf->nif : conf->bNumInterfaces;
     for (i = 0; i < count; i++) {
         rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - 
wTotalLength);
@@ -105,6 +114,26 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t 
*dest, size_t len)
     return wTotalLength;
 }
 
+int usb_desc_iad(const USBDescIfaceAssoc *iad, uint8_t *dest, size_t len)
+{
+    uint8_t bLength = 0x08;
+    
+    if (len < bLength) {
+        return -1;
+    }
+    
+    dest[0x00] = bLength;
+    dest[0x01] = USB_DT_INTERFACE_ASSOC;
+    dest[0x02] = iad->bFirstInterface;
+    dest[0x03] = iad->bInterfaceCount;
+    dest[0x04] = iad->bFunctionClass;
+    dest[0x05] = iad->bFunctionSubClass;
+    dest[0x06] = iad->bFunctionProtocol;
+    dest[0x07] = iad->iFunction;
+    
+    return bLength;
+}
+
 int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len)
 {
     uint8_t bLength = 0x09;
diff --git a/hw/usb-desc.h b/hw/usb-desc.h
index ac734ab..cf5f794 100644
--- a/hw/usb-desc.h
+++ b/hw/usb-desc.h
@@ -30,10 +30,22 @@ struct USBDescConfig {
     uint8_t                   bmAttributes;
     uint8_t                   bMaxPower;
 
+    uint8_t                   niad; /* 0 or 1 for now */
+    const USBDescIfaceAssoc   *iad;
+
     uint8_t                   nif;
     const USBDescIface        *ifs;
 };
 
+struct USBDescIfaceAssoc {
+    uint8_t                   bFirstInterface;
+    uint8_t                   bInterfaceCount;
+    uint8_t                   bFunctionClass;
+    uint8_t                   bFunctionSubClass;
+    uint8_t                   bFunctionProtocol;
+    uint8_t                   iFunction;
+};
+
 struct USBDescIface {
     uint8_t                   bInterfaceNumber;
     uint8_t                   bAlternateSetting;
@@ -75,6 +87,7 @@ int usb_desc_device(const USBDescID *id, const USBDescDevice 
*dev,
 int usb_desc_device_qualifier(const USBDescDevice *dev,
                               uint8_t *dest, size_t len);
 int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len);
+int usb_desc_iad(const USBDescIfaceAssoc *iad, uint8_t *dest, size_t len);
 int usb_desc_iface(const USBDescIface *iface, uint8_t *dest, size_t len);
 int usb_desc_endpoint(const USBDescEndpoint *ep, uint8_t *dest, size_t len);
 int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index c25362c..acbcddc 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -211,6 +211,7 @@ static const USBDescDevice desc_device_mouse = {
             .iConfiguration        = STR_CONFIG_MOUSE,
             .bmAttributes          = 0xa0,
             .bMaxPower             = 50,
+            .niad                  = 0,
             .ifs = &desc_iface_mouse,
         },
     },
@@ -227,6 +228,7 @@ static const USBDescDevice desc_device_tablet = {
             .iConfiguration        = STR_CONFIG_TABLET,
             .bmAttributes          = 0xa0,
             .bMaxPower             = 50,
+            .niad                  = 0,
             .ifs = &desc_iface_tablet,
         },
     },
@@ -243,6 +245,7 @@ static const USBDescDevice desc_device_keyboard = {
             .iConfiguration        = STR_CONFIG_KEYBOARD,
             .bmAttributes          = 0xa0,
             .bMaxPower             = 50,
+            .niad                  = 0,
             .ifs = &desc_iface_keyboard,
         },
     },
diff --git a/hw/usb-hub.c b/hw/usb-hub.c
index 3dd31ba..bc06a01 100644
--- a/hw/usb-hub.c
+++ b/hw/usb-hub.c
@@ -119,6 +119,7 @@ static const USBDescDevice desc_device_hub = {
             .bNumInterfaces        = 1,
             .bConfigurationValue   = 1,
             .bmAttributes          = 0xe0,
+            .niad                  = 0,
             .ifs = &desc_iface_hub,
         },
     },
diff --git a/hw/usb.h b/hw/usb.h
index d3d755d..b1e8879 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -124,6 +124,7 @@
 #define USB_DT_ENDPOINT                        0x05
 #define USB_DT_DEVICE_QUALIFIER         0x06
 #define USB_DT_OTHER_SPEED_CONFIG       0x07
+#define USB_DT_INTERFACE_ASSOC  0x0B
 
 #define USB_ENDPOINT_XFER_CONTROL      0
 #define USB_ENDPOINT_XFER_ISOC         1
@@ -140,6 +141,7 @@ typedef struct USBDesc USBDesc;
 typedef struct USBDescID USBDescID;
 typedef struct USBDescDevice USBDescDevice;
 typedef struct USBDescConfig USBDescConfig;
+typedef struct USBDescIfaceAssoc USBDescIfaceAssoc;
 typedef struct USBDescIface USBDescIface;
 typedef struct USBDescEndpoint USBDescEndpoint;
 typedef struct USBDescOther USBDescOther;
