From patchwork Mon Nov 29 16:04:05 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 73450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CFDA71007D1 for ; Tue, 30 Nov 2010 03:23:32 +1100 (EST) Received: from localhost ([127.0.0.1]:46002 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PN6Vl-0007CM-TA for incoming@patchwork.ozlabs.org; Mon, 29 Nov 2010 11:23:29 -0500 Received: from [140.186.70.92] (port=37820 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PN6DS-0008ML-1u for qemu-devel@nongnu.org; Mon, 29 Nov 2010 11:04:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PN6DQ-000406-ED for qemu-devel@nongnu.org; Mon, 29 Nov 2010 11:04:33 -0500 Received: from mx1.redhat.com ([209.132.183.28]:30547) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PN6DQ-0003zo-6E for qemu-devel@nongnu.org; Mon, 29 Nov 2010 11:04:32 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oATG4VFv007473 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 29 Nov 2010 11:04:31 -0500 Received: from rincewind.home.kraxel.org (vpn1-7-192.ams2.redhat.com [10.36.7.192]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oATG4KGS013459; Mon, 29 Nov 2010 11:04:21 -0500 Received: by rincewind.home.kraxel.org (Postfix, from userid 500) id 984D64524D; Mon, 29 Nov 2010 17:04:10 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Mon, 29 Nov 2010 17:04:05 +0100 Message-Id: <1291046649-19353-9-git-send-email-kraxel@redhat.com> In-Reply-To: <1291046649-19353-1-git-send-email-kraxel@redhat.com> References: <1291046649-19353-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 08/12] usb descriptors: add settable strings. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch allows to set usb descriptor strings per device instance. Signed-off-by: Gerd Hoffmann --- hw/usb-bus.c | 1 + hw/usb-desc.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- hw/usb-desc.h | 4 +++- hw/usb.h | 9 +++++++++ 4 files changed, 57 insertions(+), 9 deletions(-) diff --git a/hw/usb-bus.c b/hw/usb-bus.c index b692503..15a42ff 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -46,6 +46,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base) pstrcpy(dev->product_desc, sizeof(dev->product_desc), info->product_desc); dev->info = info; dev->auto_attach = 1; + QLIST_INIT(&dev->strings); rc = dev->info->init(dev); if (rc == 0 && dev->auto_attach) usb_device_attach(dev); diff --git a/hw/usb-desc.c b/hw/usb-desc.c index 22f14bb..59af8e2 100644 --- a/hw/usb-desc.c +++ b/hw/usb-desc.c @@ -150,9 +150,42 @@ int usb_desc_other(const USBDescOther *desc, uint8_t *dest, size_t len) return bLength; } -int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len) +/* ------------------------------------------------------------------ */ + +void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str) +{ + USBDescString *s; + + QLIST_FOREACH(s, &dev->strings, next) { + if (s->index == index) { + break; + } + } + if (s == NULL) { + s = qemu_mallocz(sizeof(*s)); + s->index = index; + QLIST_INSERT_HEAD(&dev->strings, s, next); + } + qemu_free(s->str); + s->str = qemu_strdup(str); +} + +const char *usb_desc_get_string(USBDevice *dev, uint8_t index) +{ + USBDescString *s; + + QLIST_FOREACH(s, &dev->strings, next) { + if (s->index == index) { + return s->str; + } + } + return NULL; +} + +int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len) { uint8_t bLength, pos, i; + const char *str; if (len < 4) { return -1; @@ -167,22 +200,25 @@ int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len return 4; } - if (str[index] == NULL) { - return 0; + str = usb_desc_get_string(dev, index); + if (str == NULL) { + str = dev->info->usb_desc->str[index]; + if (str == NULL) { + return 0; + } } - bLength = strlen(str[index]) * 2 + 2; + + bLength = strlen(str) * 2 + 2; dest[0] = bLength; dest[1] = USB_DT_STRING; i = 0; pos = 2; while (pos+1 < bLength && pos+1 < len) { - dest[pos++] = str[index][i++]; + dest[pos++] = str[i++]; dest[pos++] = 0; } return pos; } -/* ------------------------------------------------------------------ */ - int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len) { const USBDesc *desc = dev->info->usb_desc; @@ -207,7 +243,7 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len case USB_DT_STRING: fprintf(stderr, "%s: %d STRING %d (len %zd)\n", __FUNCTION__, dev->addr, index, len); - ret = usb_desc_string(desc->str, index, buf, sizeof(buf)); + ret = usb_desc_string(dev, index, buf, sizeof(buf)); break; default: fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__, diff --git a/hw/usb-desc.h b/hw/usb-desc.h index d80efdb..20fc400 100644 --- a/hw/usb-desc.h +++ b/hw/usb-desc.h @@ -76,9 +76,11 @@ int usb_desc_config(const USBDescConfig *conf, 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); -int usb_desc_string(const char* const *str, int index, uint8_t *dest, size_t len); /* control message emulation helpers */ +void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str); +const char *usb_desc_get_string(USBDevice *dev, uint8_t index); +int usb_desc_string(USBDevice *dev, int index, uint8_t *dest, size_t len); int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len); int usb_desc_handle_control(USBDevice *dev, int request, int value, int index, int length, uint8_t *data); diff --git a/hw/usb.h b/hw/usb.h index 5430742..47c2957 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -142,6 +142,13 @@ typedef struct USBDescConfig USBDescConfig; typedef struct USBDescIface USBDescIface; typedef struct USBDescEndpoint USBDescEndpoint; typedef struct USBDescOther USBDescOther; +typedef struct USBDescString USBDescString; + +struct USBDescString { + uint8_t index; + char *str; + QLIST_ENTRY(USBDescString) next; +}; /* definition of a USB device */ struct USBDevice { @@ -162,6 +169,8 @@ struct USBDevice { int setup_state; int setup_len; int setup_index; + + QLIST_HEAD(, USBDescString) strings; }; struct USBDeviceInfo {