|  | @@ -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 |  }
 |