usb: Validate and accept set_configuration properly
Setting the same configuration again should act as a lightweight reset, not be ignored. This resulted in data toggle bits not being reset and alternet settings not being reset. Further, completely invalid configurations were accepted, when they should have result in a stall. (Section 9.4.7 of USB 2.0 spec) fixes Github issue #302 Tested-by: Karl Palsson <karlp@tweak.net.au>
This commit is contained in:
parent
eb18cc19cb
commit
7cd7212577
@ -245,18 +245,38 @@ static int usb_standard_set_configuration(usbd_device *usbd_dev,
|
||||
struct usb_setup_data *req,
|
||||
uint8_t **buf, uint16_t *len)
|
||||
{
|
||||
int i;
|
||||
unsigned i;
|
||||
int found_index = -1;
|
||||
const struct usb_config_descriptor *cfg;
|
||||
|
||||
(void)req;
|
||||
(void)buf;
|
||||
(void)len;
|
||||
|
||||
/* Is this correct, or should we reset alternate settings. */
|
||||
if (req->wValue == usbd_dev->current_config) {
|
||||
return 1;
|
||||
if(req->wValue > 0) {
|
||||
for (i = 0; i < usbd_dev->desc->bNumConfigurations; i++) {
|
||||
if (req->wValue == usbd_dev->config[i].bConfigurationValue) {
|
||||
found_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found_index < 0) {
|
||||
return USBD_REQ_NOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
usbd_dev->current_config = req->wValue;
|
||||
usbd_dev->current_config = found_index + 1;
|
||||
|
||||
if (usbd_dev->current_config > 0) {
|
||||
cfg = &usbd_dev->config[usbd_dev->current_config - 1];
|
||||
|
||||
/* reset all alternate settings configuration */
|
||||
for (i = 0; i < cfg->bNumInterfaces; i++) {
|
||||
if (cfg->interface[i].cur_altsetting) {
|
||||
*cfg->interface[i].cur_altsetting = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset all endpoints. */
|
||||
usbd_dev->driver->ep_reset(usbd_dev);
|
||||
|
Loading…
x
Reference in New Issue
Block a user