qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>, Brad Hards <bradh@frogmouth.net>
Subject: [Qemu-devel] [PATCH 04/18] usb: add support for "grouped" interfaces and the Interface Association Descriptor
Date: Mon, 16 May 2011 21:56:08 +0200	[thread overview]
Message-ID: <1305575782-31766-5-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1305575782-31766-1-git-send-email-kraxel@redhat.com>

From: Brad Hards <bradh@frogmouth.net>

This is used for some devices that have multiple interfaces that form a logic
device. An example is Video Class, which has a Control interface and a
Streaming interface. There can be additional interfaces on the same (physical)
devices (e.g. a microphone), and Interface Association Descriptor handles this
case.

Signed-off-by: Brad Hards <bradh@frogmouth.net>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/usb-desc.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/usb-desc.h |   20 ++++++++++++++++++++
 hw/usb.h      |    1 +
 3 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index a784155..8367c45 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -91,6 +91,18 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len)
     dest[0x08] = conf->bMaxPower;
     wTotalLength += bLength;
 
+    /* handle grouped interfaces if any*/
+    for (i = 0; i < conf->nif_groups; i++) {
+        rc = usb_desc_iface_group(&(conf->if_groups[i]),
+                                  dest + wTotalLength,
+                                  len - wTotalLength);
+        if (rc < 0) {
+            return rc;
+        }
+        wTotalLength += rc;
+    }
+
+    /* handle normal (ungrouped / no IAD) interfaces if any */
     for (i = 0; i < conf->nif; i++) {
         rc = usb_desc_iface(conf->ifs + i, dest + wTotalLength, len - wTotalLength);
         if (rc < 0) {
@@ -104,6 +116,41 @@ int usb_desc_config(const USBDescConfig *conf, uint8_t *dest, size_t len)
     return wTotalLength;
 }
 
+int usb_desc_iface_group(const USBDescIfaceAssoc *iad, uint8_t *dest,
+                         size_t len)
+{
+    int pos = 0;
+    int i = 0;
+
+    /* handle interface association descriptor */
+    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;
+    pos += bLength;
+
+    /* handle associated interfaces in this group */
+    for (i = 0; i < iad->nif; i++) {
+        int rc = usb_desc_iface(&(iad->ifs[i]), dest + pos, len - pos);
+        if (rc < 0) {
+            return rc;
+        }
+        pos += rc;
+    }
+
+    return pos;
+}
+
 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..a612515 100644
--- a/hw/usb-desc.h
+++ b/hw/usb-desc.h
@@ -30,6 +30,24 @@ struct USBDescConfig {
     uint8_t                   bmAttributes;
     uint8_t                   bMaxPower;
 
+    /* grouped interfaces */
+    uint8_t                   nif_groups;
+    const USBDescIfaceAssoc   *if_groups;
+
+    /* "normal" interfaces */
+    uint8_t                   nif;
+    const USBDescIface        *ifs;
+};
+
+/* conceptually an Interface Association Descriptor, and releated interfaces */
+struct USBDescIfaceAssoc {
+    uint8_t                   bFirstInterface;
+    uint8_t                   bInterfaceCount;
+    uint8_t                   bFunctionClass;
+    uint8_t                   bFunctionSubClass;
+    uint8_t                   bFunctionProtocol;
+    uint8_t                   iFunction;
+
     uint8_t                   nif;
     const USBDescIface        *ifs;
 };
@@ -75,6 +93,8 @@ 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_iface_group(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.h b/hw/usb.h
index ca06bf8..e0961ac 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -141,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;
-- 
1.7.1

  parent reply	other threads:[~2011-05-16 19:56 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-16 19:56 [Qemu-devel] [PATCH 00/18] usb patch queue: add usb 2.0 Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 01/18] usb: Add Interface Association Descriptor descriptor type Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 02/18] usb: update config descriptors to identify number of interfaces Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 03/18] usb: remove fallback to bNumInterfaces if no .nif Gerd Hoffmann
2011-05-16 19:56 ` Gerd Hoffmann [this message]
2011-05-16 19:56 ` [Qemu-devel] [PATCH 05/18] Bug #757654: UHCI fails to signal stall response patch Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 06/18] usb: Pass the packet to the device's handle_control callback Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 07/18] usb-linux: use usb_generic_handle_packet() Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 08/18] usb-linux: fix device path aka physical port handling Gerd Hoffmann
2011-05-17 16:38   ` Markus Armbruster
2011-05-16 19:56 ` [Qemu-devel] [PATCH 09/18] usb-linux: add hostport property Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 10/18] usb-linux: track aurbs in list Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 11/18] usb-linux: walk async urb list in cancel Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 12/18] usb-linux: split large xfers Gerd Hoffmann
2011-05-17  2:45   ` David Ahern
2011-05-17  7:10     ` Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 13/18] usb-linux: fix max_packet_size for highspeed Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 14/18] usb: add usb_handle_packet Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 15/18] usb: keep track of packet owner Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 16/18] usb: move cancel callback to USBDeviceInfo Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 17/18] usb-storage: don't call usb_packet_complete twice Gerd Hoffmann
2011-05-16 19:56 ` [Qemu-devel] [PATCH 18/18] usb: add ehci adapter Gerd Hoffmann
2011-05-17  2:47   ` David Ahern
2011-05-17  7:20     ` Gerd Hoffmann
2011-05-17 12:42       ` David Ahern
2011-05-17 13:46         ` Gerd Hoffmann
2011-05-17 14:19           ` David Ahern
2011-05-17 14:36             ` Gerd Hoffmann
2011-05-17 17:15             ` Erik Rull
2011-05-17 13:52         ` David Ahern
2011-05-17 15:02           ` Gerd Hoffmann
2011-05-17 17:05             ` David Ahern
2011-05-17 17:36               ` Hans de Goede
2011-05-17 17:43                 ` [Qemu-devel] USB streaming [Re: [PATCH 18/18] usb: add ehci adapter] David Ahern
2011-05-17 18:44                   ` Hans de Goede
2011-05-17 19:10                     ` David Ahern
2011-05-17 19:18                       ` David Ahern
2011-05-18  8:25                         ` Hans de Goede
2011-05-17 17:33             ` [Qemu-devel] [PATCH 18/18] usb: add ehci adapter Hans de Goede
2011-05-17 17:00       ` David Ahern
2011-05-17 20:39     ` Blue Swirl
2011-05-17 20:51       ` David Ahern
2011-05-21 10:34       ` Andreas Färber
2011-05-16 20:04 ` [Qemu-devel] [PATCH 00/18] usb patch queue: add usb 2.0 Anthony Liguori
2011-05-17  7:36   ` Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2011-05-23  9:43 [Qemu-devel] [PULL] usb patch queue: initial usb 2.0 support Gerd Hoffmann
2011-05-23  9:43 ` [Qemu-devel] [PATCH 04/18] usb: add support for "grouped" interfaces and the Interface Association Descriptor Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1305575782-31766-5-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=bradh@frogmouth.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).