Improve the kernel's USB descriptor reading function.

Some USB devices does not allow a partial descriptor readout.

Found by:	bz@
MFC after:	1 week
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2018-06-27 12:08:12 +00:00
parent 48f3bd63b9
commit b774480cd6

View File

@ -990,7 +990,7 @@ usbd_req_get_desc(struct usb_device *udev,
uint8_t retries)
{
struct usb_device_request req;
uint8_t *buf;
uint8_t *buf = desc;
usb_error_t err;
DPRINTFN(4, "id=%d, type=%d, index=%d, max_len=%d\n",
@ -1012,6 +1012,32 @@ usbd_req_get_desc(struct usb_device *udev,
err = usbd_do_request_flags(udev, mtx, &req,
desc, 0, NULL, 500 /* ms */);
if (err != 0 && err != USB_ERR_TIMEOUT &&
min_len != max_len) {
/* clear descriptor data */
memset(desc, 0, max_len);
/* try to read full descriptor length */
USETW(req.wLength, max_len);
err = usbd_do_request_flags(udev, mtx, &req,
desc, USB_SHORT_XFER_OK, NULL, 500 /* ms */);
if (err == 0) {
/* verify length */
if (buf[0] > max_len)
buf[0] = max_len;
else if (buf[0] < 2)
err = USB_ERR_INVAL;
min_len = buf[0];
/* enforce descriptor type */
buf[1] = type;
goto done;
}
}
if (err) {
if (!retries) {
goto done;
@ -1022,7 +1048,6 @@ usbd_req_get_desc(struct usb_device *udev,
continue;
}
buf = desc;
if (min_len == max_len) {