libpayload: usb: Fix several minor USB stack bugs
This patch fixes the following minor bugs in the USB stack: 1. Ensure that all dynamically allocated device structures are cleaned on detachment, and that the device address is correctly released again. 2. Make sure MSC and HID drivers notice missing endpoints and actually detach the device in that case (to prevent it from being used). 3. Make sure XHCI-specific set_address() cleans up all data structures on failure. 4. Fix broken Slot ID range check that prevented XHCI devices from being correctly cleaned up. BUG=chrome-os-partner:22139 TEST=Manual Change-Id: I7b2b9c8cd6c5e93cb19abcf01425bcd85d2e1f22 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/170665 Reviewed-by: Stefan Reinauer <reinauer@google.com> Commit-Queue: Ronald Minnich <rminnich@chromium.org> Tested-by: Ronald Minnich <rminnich@chromium.org>
This commit is contained in:
parent
f160d4439c
commit
9671472263
4 changed files with 21 additions and 9 deletions
|
|
@ -575,10 +575,14 @@ usb_detach_device(hci_t *controller, int devno)
|
|||
been called yet by the usb class driver */
|
||||
if (controller->devices[devno]) {
|
||||
controller->devices[devno]->destroy (controller->devices[devno]);
|
||||
free(controller->devices[devno]);
|
||||
controller->devices[devno] = NULL;
|
||||
if (controller->destroy_device)
|
||||
controller->destroy_device(controller, devno);
|
||||
if (controller->devices[devno]->configuration)
|
||||
free(controller->devices[devno]->configuration);
|
||||
if (controller->devices[devno]->descriptor)
|
||||
free(controller->devices[devno]->descriptor);
|
||||
free(controller->devices[devno]);
|
||||
controller->devices[devno] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -467,15 +467,18 @@ usb_hid_init (usbdev_t *dev)
|
|||
dev->destroy = usb_hid_destroy;
|
||||
dev->poll = usb_hid_poll;
|
||||
int i;
|
||||
for (i = 0; i <= dev->num_endp; i++) {
|
||||
if (dev->endpoints[i].endpoint == 0)
|
||||
continue;
|
||||
for (i = 1; i < dev->num_endp; i++) {
|
||||
if (dev->endpoints[i].type != INTERRUPT)
|
||||
continue;
|
||||
if (dev->endpoints[i].direction != IN)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (i >= dev->num_endp) {
|
||||
usb_debug ("Could not find HID endpoint\n");
|
||||
usb_detach_device (dev->controller, dev->address);
|
||||
return;
|
||||
}
|
||||
usb_debug (" found endpoint %x for interrupt-in\n", i);
|
||||
/* 20 buffers of 8 bytes, for every 10 msecs */
|
||||
HID_INST(dev)->queue = dev->controller->create_intr_queue (&dev->endpoints[i], 8, 20, 10);
|
||||
|
|
|
|||
|
|
@ -598,6 +598,7 @@ usb_msc_init (usbdev_t *dev)
|
|||
|
||||
if (interface->bInterfaceProtocol != 0x50) {
|
||||
usb_debug (" Protocol not supported.\n");
|
||||
usb_detach_device (dev->controller, dev->address);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -606,6 +607,7 @@ usb_msc_init (usbdev_t *dev)
|
|||
(interface->bInterfaceSubClass != 6)) { // SCSI
|
||||
/* Other protocols, such as ATAPI don't seem to be very popular. looks like ATAPI would be really easy to add, if necessary. */
|
||||
usb_debug (" Interface SubClass not supported.\n");
|
||||
usb_detach_device (dev->controller, dev->address);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -632,11 +634,13 @@ usb_msc_init (usbdev_t *dev)
|
|||
}
|
||||
|
||||
if (MSC_INST (dev)->bulk_in == 0) {
|
||||
usb_debug("couldn't find bulk-in endpoint");
|
||||
usb_debug("couldn't find bulk-in endpoint.\n");
|
||||
usb_detach_device (dev->controller, dev->address);
|
||||
return;
|
||||
}
|
||||
if (MSC_INST (dev)->bulk_out == 0) {
|
||||
usb_debug("couldn't find bulk-out endpoint");
|
||||
usb_debug("couldn't find bulk-out endpoint.\n");
|
||||
usb_detach_device (dev->controller, dev->address);
|
||||
return;
|
||||
}
|
||||
usb_debug (" using endpoint %x as in, %x as out\n",
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ xhci_set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr)
|
|||
di = &xhci->dev[slot_id];
|
||||
void *dma_buffer = dma_memalign(64, NUM_EPS * ctxsize);
|
||||
if (!dma_buffer)
|
||||
goto _free_return;
|
||||
goto _disable_return;
|
||||
memset(dma_buffer, 0, NUM_EPS * ctxsize);
|
||||
for (i = 0; i < NUM_EPS; i++, dma_buffer += ctxsize)
|
||||
di->ctx.ep[i] = dma_buffer;
|
||||
|
|
@ -219,6 +219,7 @@ xhci_set_address (hci_t *controller, usb_speed speed, int hubport, int hubaddr)
|
|||
_disable_return:
|
||||
xhci_cmd_disable_slot(xhci, slot_id);
|
||||
xhci->dcbaa[slot_id] = 0;
|
||||
usb_detach_device(controller, slot_id);
|
||||
_free_return:
|
||||
if (tr)
|
||||
free((void *)tr->ring);
|
||||
|
|
@ -395,7 +396,7 @@ xhci_destroy_dev(hci_t *const controller, const int slot_id)
|
|||
{
|
||||
xhci_t *const xhci = XHCI_INST(controller);
|
||||
|
||||
if (slot_id <= 0 || xhci->max_slots_en > slot_id)
|
||||
if (slot_id <= 0 || slot_id > xhci->max_slots_en)
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue