|
@@ -2587,13 +2587,28 @@ static void xhci_device_close ( struct usb_device *usb ) {
|
2587
|
2587
|
struct xhci_device *xhci = slot->xhci;
|
2588
|
2588
|
size_t len = xhci_device_context_offset ( xhci, XHCI_CTX_END );
|
2589
|
2589
|
unsigned int id = slot->id;
|
|
2590
|
+ int rc;
|
2590
|
2591
|
|
2591
|
2592
|
/* Disable slot */
|
2592
|
|
- xhci_disable_slot ( xhci, id );
|
|
2593
|
+ if ( ( rc = xhci_disable_slot ( xhci, id ) ) != 0 ) {
|
|
2594
|
+ /* Slot is still enabled. Leak the slot context,
|
|
2595
|
+ * since the controller may still write to this
|
|
2596
|
+ * memory, and leave the DCBAA entry intact.
|
|
2597
|
+ *
|
|
2598
|
+ * If the controller later reports that this same slot
|
|
2599
|
+ * has been re-enabled, then some assertions will be
|
|
2600
|
+ * triggered.
|
|
2601
|
+ */
|
|
2602
|
+ DBGC ( xhci, "XHCI %p slot %d leaking context memory\n",
|
|
2603
|
+ xhci, slot->id );
|
|
2604
|
+ slot->context = NULL;
|
|
2605
|
+ }
|
2593
|
2606
|
|
2594
|
2607
|
/* Free slot */
|
2595
|
|
- free_dma ( slot->context, len );
|
2596
|
|
- xhci->dcbaa[id] = 0;
|
|
2608
|
+ if ( slot->context ) {
|
|
2609
|
+ free_dma ( slot->context, len );
|
|
2610
|
+ xhci->dcbaa[id] = 0;
|
|
2611
|
+ }
|
2597
|
2612
|
xhci->slot[id] = NULL;
|
2598
|
2613
|
free ( slot );
|
2599
|
2614
|
}
|