From db4753e92445d1a6008e8bf6ab6afdfc12ff874a Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Thu, 6 Sep 2007 07:17:54 +0000 Subject: usb stack: add support for standard request get string git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14626 a1c6a512-1295-4272-9138-f99709370657 --- firmware/usbstack/core/utils.c | 51 ++++++++++++++++++++++++++ firmware/usbstack/drivers/device/usb_serial.c | 41 ++++++++++++++------- firmware/usbstack/drivers/device/usb_storage.c | 32 +++++++++++++--- 3 files changed, 106 insertions(+), 18 deletions(-) diff --git a/firmware/usbstack/core/utils.c b/firmware/usbstack/core/utils.c index cd32fb3292..d43bd9290f 100644 --- a/firmware/usbstack/core/utils.c +++ b/firmware/usbstack/core/utils.c @@ -9,6 +9,9 @@ * * Copyright (C) 2007 by Christian Gmeiner * + * Based on linux/drivers/usb/gadget/usbstring.c + * Copyright (C) 2003 David Brownell + * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * @@ -123,3 +126,51 @@ void into_usb_ctrlrequest(struct usb_ctrlrequest* request) logf(" -> e: %s", extra); } } + +int usb_stack_get_string(struct usb_string* strings, int id, uint8_t* buf) +{ + struct usb_string* tmp; + char* sp, *dp; + int len; + + /* if id is 0, then we need to send back all supported + * languages. In our case we only support one + * language: en-us (0x0409) */ + if (id == 0) { + buf [0] = 4; + buf [1] = USB_DT_STRING; + buf [2] = (uint8_t) 0x0409; + buf [3] = (uint8_t) (0x0409 >> 8); + return 4; + } + + /* look for string */ + for (tmp = strings; tmp && tmp->s; tmp++) { + if (tmp->id == id) { + break; + } + } + + /* did we found it? */ + if (!tmp || !tmp->s) { + return -EINVAL; + } + + len = MIN ((size_t) 126, strlen (tmp->s)); + memset(buf + 2, 0, 2 * len); + + /* convert to utf-16le */ + sp = (char*)tmp->s; + dp = (char*)&buf[2]; + + while (*sp) { + *dp++ = *sp++; + *dp++ = 0; + } + + /* write len and tag */ + buf [0] = (len + 1) * 2; + buf [1] = USB_DT_STRING; + + return buf[0]; +} diff --git a/firmware/usbstack/drivers/device/usb_serial.c b/firmware/usbstack/drivers/device/usb_serial.c index a37813b01c..0c66cf68fe 100644 --- a/firmware/usbstack/drivers/device/usb_serial.c +++ b/firmware/usbstack/drivers/device/usb_serial.c @@ -35,14 +35,22 @@ struct usb_device_driver usb_serial_driver = { /*-------------------------------------------------------------------------*/ /* usb descriptors */ -/* TODO: implement strings */ -#define GS_MANUFACTURER_STR_ID 0 -#define GS_PRODUCT_STR_ID 0 -#define GS_SERIAL_STR_ID 0 -#define GS_BULK_CONFIG_STR_ID 0 -#define GS_DATA_STR_ID 0 +#define MANUFACTURER_STR_ID 1 +#define PRODUCT_STR_ID 2 +#define SERIAL_STR_ID 3 +#define BULK_CONFIG_STR_ID 4 +#define DATA_STR_ID 5 + +/* static strings, in UTF-8 */ +static struct usb_string strings[] = { + { MANUFACTURER_STR_ID, "RockBox" }, + { PRODUCT_STR_ID, "RockBox Serial Driver" }, + { SERIAL_STR_ID, "0" }, + { BULK_CONFIG_STR_ID, "Serial Bulk" }, + { DATA_STR_ID, "Serial Data" }, +}; -#define GS_BULK_CONFIG_ID 1 +#define BULK_CONFIG_ID 1 static struct usb_device_descriptor serial_device_desc = { .bLength = USB_DT_DEVICE_SIZE, @@ -53,9 +61,9 @@ static struct usb_device_descriptor serial_device_desc = { .bDeviceProtocol = 0, .idVendor = 0x0525, .idProduct = 0xa4a6, - .iManufacturer = GS_MANUFACTURER_STR_ID, - .iProduct = GS_PRODUCT_STR_ID, - .iSerialNumber = GS_SERIAL_STR_ID, + .iManufacturer = MANUFACTURER_STR_ID, + .iProduct = PRODUCT_STR_ID, + .iSerialNumber = SERIAL_STR_ID, .bNumConfigurations = 1, }; @@ -64,8 +72,8 @@ static struct usb_config_descriptor serial_bulk_config_desc = { .bDescriptorType = USB_DT_CONFIG, .bNumInterfaces = 1, - .bConfigurationValue = GS_BULK_CONFIG_ID, - .iConfiguration = GS_BULK_CONFIG_STR_ID, + .bConfigurationValue = BULK_CONFIG_ID, + .iConfiguration = BULK_CONFIG_STR_ID, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bMaxPower = 1, }; @@ -78,7 +86,7 @@ static struct usb_interface_descriptor serial_bulk_interface_desc = { .bInterfaceClass = USB_CLASS_CDC_DATA, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, - .iInterface = GS_DATA_STR_ID, + .iInterface = DATA_STR_ID, }; static struct usb_endpoint_descriptor serial_fs_in_desc = { @@ -261,6 +269,13 @@ int usb_serial_driver_request(struct usb_ctrlrequest* request) ret = MIN(sizeof(struct usb_debug_descriptor), request->wLength); res.buf = &serial_debug_desc; break; + + case USB_DT_STRING: + logf("usb serial: sending string desc"); + ret = usb_stack_get_string(strings, request->wValue & 0xff, buf); + ret = MIN(ret, request->wLength); + res.buf = buf; + break; } break; diff --git a/firmware/usbstack/drivers/device/usb_storage.c b/firmware/usbstack/drivers/device/usb_storage.c index 49644e5805..45fd5c14b7 100644 --- a/firmware/usbstack/drivers/device/usb_storage.c +++ b/firmware/usbstack/drivers/device/usb_storage.c @@ -46,6 +46,21 @@ struct usb_device_driver usb_storage_driver = { /*-------------------------------------------------------------------------*/ /* usb descriptors */ +#define MANUFACTURER_STR_ID 1 +#define PRODUCT_STR_ID 2 +#define SERIAL_STR_ID 3 +#define CONFIG_STR_ID 4 +#define DATA_STR_ID 5 + +/* static strings, in UTF-8 */ +static struct usb_string strings[] = { + { MANUFACTURER_STR_ID, "RockBox" }, + { PRODUCT_STR_ID, "RockBox Storage Driver" }, + { SERIAL_STR_ID, "0" }, + { CONFIG_STR_ID, "Storage Bulk" }, + { DATA_STR_ID, "Storage Data" }, +}; + static struct usb_device_descriptor storage_device_desc = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, @@ -55,9 +70,9 @@ static struct usb_device_descriptor storage_device_desc = { .bDeviceProtocol = 0, .idVendor = 0xffff, .idProduct = 0x0001, - .iManufacturer = 0, - .iProduct = 0, - .iSerialNumber = 0, + .iManufacturer = MANUFACTURER_STR_ID, + .iProduct = PRODUCT_STR_ID, + .iSerialNumber = SERIAL_STR_ID, .bNumConfigurations = 1, }; @@ -67,7 +82,7 @@ static struct usb_config_descriptor storage_config_desc = { .bNumInterfaces = 1, .bConfigurationValue = 1, - .iConfiguration = 0, + .iConfiguration = CONFIG_STR_ID, .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, .bMaxPower = 1, }; @@ -80,7 +95,7 @@ static struct usb_interface_descriptor storage_interface_desc = { .bInterfaceClass = USB_CLASS_MASS_STORAGE, .bInterfaceSubClass = SUBCL_SCSI, .bInterfaceProtocol = PROTO_BULK, - .iInterface = 0, + .iInterface = DATA_STR_ID, }; static struct usb_endpoint_descriptor storage_fs_bulk_in_desc = { @@ -246,6 +261,13 @@ int usb_storage_driver_request(struct usb_ctrlrequest* request) } res.buf = buf; break; + + case USB_DT_STRING: + logf("usb storage: sending string desc"); + ret = usb_stack_get_string(strings, request->wValue & 0xff, buf); + ret = MIN(ret, request->wLength); + res.buf = buf; + break; } break; -- cgit v1.2.3