diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c index 54a2c8ebe39f..d41a54f0cc0b 100644 --- a/sys/dev/usb/if_cdce.c +++ b/sys/dev/usb/if_cdce.c @@ -280,7 +280,8 @@ cdce_attach(device_t self) ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev, UDESC_INTERFACE, UDESCSUB_CDC_ENF); - if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str)) { + if (!ue || usbd_get_string(dev, ue->iMacAddress, eaddr_str, + sizeof(eaddr_str))) { /* Fake MAC address */ device_printf(sc->cdce_dev, "faking MAC address\n"); eaddr[0]= 0x2a; diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index 26defca9e003..86fbba216e77 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -655,7 +655,8 @@ uhub_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, found_dev: /* XXX can sleep */ - (void)usbd_get_string(dev, dev->ddesc.iSerialNumber, &serial[0]); + (void)usbd_get_string(dev, dev->ddesc.iSerialNumber, serial, + sizeof(serial)); if (dev->ifacenums == NULL) { snprintf(buf, buflen, "vendor=0x%04x product=0x%04x " "devclass=0x%02x devsubclass=0x%02x " diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 4822aa02d8d0..575b111ff101 100644 --- a/sys/dev/usb/usb_subr.c +++ b/sys/dev/usb/usb_subr.c @@ -213,12 +213,14 @@ usbd_devinfo_vp(usbd_device_handle dev, char *v, char *p, int usedev) } if (usedev) { - if (usbd_get_string(dev, udd->iManufacturer, v)) + if (usbd_get_string(dev, udd->iManufacturer, v, + USB_MAX_STRING_LEN)) vendor = NULL; else vendor = v; usbd_trim_spaces(vendor); - if (usbd_get_string(dev, udd->iProduct, p)) + if (usbd_get_string(dev, udd->iProduct, p, + USB_MAX_STRING_LEN)) product = NULL; else product = p; @@ -1052,6 +1054,20 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, up->device = dev; + if (up->parent && speed > up->parent->speed) { +#ifdef USB_DEBUG + printf("%s: maxium speed of attached " + "device, %d, is higher than speed " + "of parent HUB, %d.\n", + __FUNCTION__, speed, up->parent->speed); +#endif + /* + * Reduce the speed, otherwise we won't setup the + * proper transfer methods. + */ + speed = up->parent->speed; + } + /* Locate port on upstream high speed hub */ for (adev = dev, hub = up->parent; hub != NULL && hub->speed != USB_SPEED_HIGH; diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 480658dc14d7..35c201cca5ee 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1310,7 +1310,7 @@ usb_desc_iter_next(usbd_desc_iter_t *iter) } usbd_status -usbd_get_string(usbd_device_handle dev, int si, char *buf) +usbd_get_string(usbd_device_handle dev, int si, char *buf, size_t len) { int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; usb_string_descriptor_t us; @@ -1321,6 +1321,8 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf) int size; buf[0] = '\0'; + if (len == 0) + return (USBD_NORMAL_COMPLETION); if (si == 0) return (USBD_INVAL); if (dev->quirks->uq_flags & UQ_NO_STRINGS) @@ -1342,7 +1344,7 @@ usbd_get_string(usbd_device_handle dev, int si, char *buf) return (err); s = buf; n = size / 2 - 1; - for (i = 0; i < n; i++) { + for (i = 0; i < n && i < len - 1; i++) { c = UGETW(us.bString[i]); /* Convert from Unicode, handle buggy strings. */ if ((c & 0xff00) == 0) diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 52f2a01f091c..b3b26cff757b 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -173,7 +173,8 @@ usbd_status usbd_reload_device_desc(usbd_device_handle); int usbd_ratecheck(struct timeval *last); -usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf); +usbd_status usbd_get_string(usbd_device_handle dev, int si, char *buf, + size_t len); /* An iterator for descriptors. */ typedef struct {