diff --git a/include/libopencm3/usb/usbd.h b/include/libopencm3/usb/usbd.h index e4b35785..9da83796 100644 --- a/include/libopencm3/usb/usbd.h +++ b/include/libopencm3/usb/usbd.h @@ -38,7 +38,7 @@ extern u8 usbd_control_buffer[]; extern int usbd_init(const usbd_driver *driver, const struct usb_device_descriptor *dev, const struct usb_config_descriptor *conf, - const char **strings); + const char **strings, int num_strings); extern void usbd_set_control_buffer_size(u16 size); extern void usbd_register_reset_callback(void (*callback)(void)); diff --git a/lib/usb/usb.c b/lib/usb/usb.c index 1ebb6ec5..d5ec9800 100644 --- a/lib/usb/usb.c +++ b/lib/usb/usb.c @@ -45,12 +45,14 @@ u8 usbd_control_buffer[128] __attribute__((weak)); */ int usbd_init(const usbd_driver *driver, const struct usb_device_descriptor *dev, - const struct usb_config_descriptor *conf, const char **strings) + const struct usb_config_descriptor *conf, + const char **strings, int num_strings) { _usbd_device.driver = driver; _usbd_device.desc = dev; _usbd_device.config = conf; _usbd_device.strings = strings; + _usbd_device.num_strings = num_strings; _usbd_device.ctrl_buf = usbd_control_buffer; _usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer); diff --git a/lib/usb/usb_private.h b/lib/usb/usb_private.h index a1e5e4c8..238f14f3 100644 --- a/lib/usb/usb_private.h +++ b/lib/usb/usb_private.h @@ -29,6 +29,7 @@ extern struct _usbd_device { const struct usb_device_descriptor *desc; const struct usb_config_descriptor *config; const char **strings; + int num_strings; u8 *ctrl_buf; /**< Internal buffer used for control transfers */ u16 ctrl_buf_len; diff --git a/lib/usb/usb_standard.c b/lib/usb/usb_standard.c index 2d7c619e..1c8b952e 100644 --- a/lib/usb/usb_standard.c +++ b/lib/usb/usb_standard.c @@ -90,7 +90,7 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len) static int usb_standard_get_descriptor(struct usb_setup_data *req, u8 **buf, u16 *len) { - int i; + int i, index; struct usb_string_descriptor *sd; switch (req->wValue >> 8) { @@ -105,16 +105,20 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req, case USB_DT_STRING: sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf; + /* Send sane Language ID descriptor... */ + if ((req->wValue & 0xff) == 0) + sd->wData[0] = 0x409; + + index = (req->wValue & 0xff) - 1; + if (!_usbd_device.strings) return 0; /* Device doesn't support strings. */ /* Check that string index is in range. */ - for (i = 0; i <= (req->wValue & 0xff); i++) - if (_usbd_device.strings[i] == NULL) - return 0; + if (index >= _usbd_device.num_strings) + return 0; - sd->bLength = strlen(_usbd_device.strings[req->wValue & 0xff]) - * 2 + 2; + sd->bLength = strlen(_usbd_device.strings[index]) * 2 + 2; sd->bDescriptorType = USB_DT_STRING; *buf = (u8 *)sd; @@ -122,11 +126,7 @@ static int usb_standard_get_descriptor(struct usb_setup_data *req, for (i = 0; i < (*len / 2) - 1; i++) sd->wData[i] = - _usbd_device.strings[req->wValue & 0xff][i]; - - /* Send sane Language ID descriptor... */ - if ((req->wValue & 0xff) == 0) - sd->wData[0] = 0x409; + _usbd_device.strings[index][i]; return 1; }