Fix reading of USB sample rate descriptor for SPL Crimson Rev 1.
Read first one entry, then try to read the full rate descriptor table. PR: 234380 MFC after: 1 week Sponsored by: Mellanox Technologies
This commit is contained in:
parent
abeb9f61f9
commit
a89c806508
@ -1520,7 +1520,8 @@ uaudio20_check_rate(struct usb_device *udev, uint8_t iface_no,
|
||||
{
|
||||
struct usb_device_request req;
|
||||
usb_error_t error;
|
||||
uint8_t data[255];
|
||||
#define UAUDIO20_MAX_RATES 32 /* we support at maxium 32 rates */
|
||||
uint8_t data[2 + UAUDIO20_MAX_RATES * 12];
|
||||
uint16_t actlen;
|
||||
uint16_t rates;
|
||||
uint16_t x;
|
||||
@ -1532,19 +1533,57 @@ uaudio20_check_rate(struct usb_device *udev, uint8_t iface_no,
|
||||
req.bRequest = UA20_CS_RANGE;
|
||||
USETW2(req.wValue, UA20_CS_SAM_FREQ_CONTROL, 0);
|
||||
USETW2(req.wIndex, clockid, iface_no);
|
||||
USETW(req.wLength, 255);
|
||||
/*
|
||||
* Assume there is at least one rate to begin with, else some
|
||||
* devices might refuse to return the USB descriptor:
|
||||
*/
|
||||
USETW(req.wLength, (2 + 1 * 12));
|
||||
|
||||
error = usbd_do_request_flags(udev, NULL, &req, data,
|
||||
error = usbd_do_request_flags(udev, NULL, &req, data,
|
||||
USB_SHORT_XFER_OK, &actlen, USB_DEFAULT_TIMEOUT);
|
||||
|
||||
if (error != 0 || actlen < 2)
|
||||
return (USB_ERR_INVAL);
|
||||
if (error != 0 || actlen < 2) {
|
||||
/*
|
||||
* Likely the descriptor doesn't fit into the supplied
|
||||
* buffer. Try using a larger buffer and see if that
|
||||
* helps:
|
||||
*/
|
||||
rates = MIN(UAUDIO20_MAX_RATES, (255 - 2) / 12);
|
||||
error = USB_ERR_INVAL;
|
||||
} else {
|
||||
rates = UGETW(data);
|
||||
|
||||
if (rates > UAUDIO20_MAX_RATES) {
|
||||
DPRINTF("Too many rates truncating to %d\n", UAUDIO20_MAX_RATES);
|
||||
rates = UAUDIO20_MAX_RATES;
|
||||
error = USB_ERR_INVAL;
|
||||
} else if (rates > 1) {
|
||||
DPRINTF("Need to read full rate descriptor\n");
|
||||
error = USB_ERR_INVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (error != 0) {
|
||||
/*
|
||||
* Try to read full rate descriptor.
|
||||
*/
|
||||
actlen = (2 + rates * 12);
|
||||
|
||||
USETW(req.wLength, actlen);
|
||||
|
||||
error = usbd_do_request_flags(udev, NULL, &req, data,
|
||||
USB_SHORT_XFER_OK, &actlen, USB_DEFAULT_TIMEOUT);
|
||||
|
||||
if (error != 0 || actlen < 2)
|
||||
return (USB_ERR_INVAL);
|
||||
|
||||
rates = UGETW(data);
|
||||
}
|
||||
|
||||
rates = data[0] | (data[1] << 8);
|
||||
actlen = (actlen - 2) / 12;
|
||||
|
||||
if (rates > actlen) {
|
||||
DPRINTF("Too many rates\n");
|
||||
DPRINTF("Too many rates truncating to %d\n", actlen);
|
||||
rates = actlen;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user