|  | @@ -296,9 +296,7 @@ int usb_endpoint_open ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 296 | 296 |  		goto err_already;
 | 
		
	
		
			
			| 297 | 297 |  	}
 | 
		
	
		
			
			| 298 | 298 |  	usb->ep[idx] = ep;
 | 
		
	
		
			
			| 299 |  | -
 | 
		
	
		
			
			| 300 |  | -	/* Clear any stale error status */
 | 
		
	
		
			
			| 301 |  | -	ep->rc = 0;
 | 
		
	
		
			
			|  | 299 | +	INIT_LIST_HEAD ( &ep->halted );
 | 
		
	
		
			
			| 302 | 300 |  
 | 
		
	
		
			
			| 303 | 301 |  	/* Open endpoint */
 | 
		
	
		
			
			| 304 | 302 |  	if ( ( rc = ep->host->open ( ep ) ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -342,6 +340,7 @@ void usb_endpoint_close ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 342 | 340 |  
 | 
		
	
		
			
			| 343 | 341 |  	/* Remove from endpoint list */
 | 
		
	
		
			
			| 344 | 342 |  	usb->ep[idx] = NULL;
 | 
		
	
		
			
			|  | 343 | +	list_del ( &ep->halted );
 | 
		
	
		
			
			| 345 | 344 |  
 | 
		
	
		
			
			| 346 | 345 |  	/* Discard any recycled buffers, if applicable */
 | 
		
	
		
			
			| 347 | 346 |  	if ( ep->max )
 | 
		
	
	
		
			
			|  | @@ -359,6 +358,9 @@ static int usb_endpoint_reset ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 359 | 358 |  	unsigned int type;
 | 
		
	
		
			
			| 360 | 359 |  	int rc;
 | 
		
	
		
			
			| 361 | 360 |  
 | 
		
	
		
			
			|  | 361 | +	/* Sanity check */
 | 
		
	
		
			
			|  | 362 | +	assert ( ! list_empty ( &ep->halted ) );
 | 
		
	
		
			
			|  | 363 | +
 | 
		
	
		
			
			| 362 | 364 |  	/* Reset endpoint */
 | 
		
	
		
			
			| 363 | 365 |  	if ( ( rc = ep->host->reset ( ep ) ) != 0 ) {
 | 
		
	
		
			
			| 364 | 366 |  		DBGC ( usb, "USB %s %s could not reset: %s\n",
 | 
		
	
	
		
			
			|  | @@ -379,8 +381,9 @@ static int usb_endpoint_reset ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 379 | 381 |  		return rc;
 | 
		
	
		
			
			| 380 | 382 |  	}
 | 
		
	
		
			
			| 381 | 383 |  
 | 
		
	
		
			
			| 382 |  | -	/* Clear recorded error */
 | 
		
	
		
			
			| 383 |  | -	ep->rc = 0;
 | 
		
	
		
			
			|  | 384 | +	/* Remove from list of halted endpoints */
 | 
		
	
		
			
			|  | 385 | +	list_del ( &ep->halted );
 | 
		
	
		
			
			|  | 386 | +	INIT_LIST_HEAD ( &ep->halted );
 | 
		
	
		
			
			| 384 | 387 |  
 | 
		
	
		
			
			| 385 | 388 |  	DBGC ( usb, "USB %s %s reset\n",
 | 
		
	
		
			
			| 386 | 389 |  	       usb->name, usb_endpoint_name ( ep->address ) );
 | 
		
	
	
		
			
			|  | @@ -434,7 +437,8 @@ int usb_message ( struct usb_endpoint *ep, unsigned int request,
 | 
		
	
		
			
			| 434 | 437 |  		return -ENODEV;
 | 
		
	
		
			
			| 435 | 438 |  
 | 
		
	
		
			
			| 436 | 439 |  	/* Reset endpoint if required */
 | 
		
	
		
			
			| 437 |  | -	if ( ( ep->rc != 0 ) && ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
 | 
		
	
		
			
			|  | 440 | +	if ( ( ! list_empty ( &ep->halted ) ) &&
 | 
		
	
		
			
			|  | 441 | +	     ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
 | 
		
	
		
			
			| 438 | 442 |  		return rc;
 | 
		
	
		
			
			| 439 | 443 |  
 | 
		
	
		
			
			| 440 | 444 |  	/* Zero input data buffer (if applicable) */
 | 
		
	
	
		
			
			|  | @@ -480,7 +484,8 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 480 | 484 |  		return -ENODEV;
 | 
		
	
		
			
			| 481 | 485 |  
 | 
		
	
		
			
			| 482 | 486 |  	/* Reset endpoint if required */
 | 
		
	
		
			
			| 483 |  | -	if ( ( ep->rc != 0 ) && ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
 | 
		
	
		
			
			|  | 487 | +	if ( ( ! list_empty ( &ep->halted ) ) &&
 | 
		
	
		
			
			|  | 488 | +	     ( ( rc = usb_endpoint_reset ( ep ) ) != 0 ) )
 | 
		
	
		
			
			| 484 | 489 |  		return rc;
 | 
		
	
		
			
			| 485 | 490 |  
 | 
		
	
		
			
			| 486 | 491 |  	/* Enqueue stream transfer */
 | 
		
	
	
		
			
			|  | @@ -507,17 +512,19 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 507 | 512 |  void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 508 | 513 |  			int rc ) {
 | 
		
	
		
			
			| 509 | 514 |  	struct usb_device *usb = ep->usb;
 | 
		
	
		
			
			|  | 515 | +	struct usb_bus *bus = usb->port->hub->bus;
 | 
		
	
		
			
			| 510 | 516 |  
 | 
		
	
		
			
			| 511 | 517 |  	/* Decrement fill level */
 | 
		
	
		
			
			| 512 | 518 |  	assert ( ep->fill > 0 );
 | 
		
	
		
			
			| 513 | 519 |  	ep->fill--;
 | 
		
	
		
			
			| 514 | 520 |  
 | 
		
	
		
			
			| 515 |  | -	/* Record error (if any) */
 | 
		
	
		
			
			| 516 |  | -	ep->rc = rc;
 | 
		
	
		
			
			|  | 521 | +	/* Schedule reset, if applicable */
 | 
		
	
		
			
			| 517 | 522 |  	if ( ( rc != 0 ) && ep->open ) {
 | 
		
	
		
			
			| 518 | 523 |  		DBGC ( usb, "USB %s %s completion failed: %s\n",
 | 
		
	
		
			
			| 519 | 524 |  		       usb->name, usb_endpoint_name ( ep->address ),
 | 
		
	
		
			
			| 520 | 525 |  		       strerror ( rc ) );
 | 
		
	
		
			
			|  | 526 | +		list_del ( &ep->halted );
 | 
		
	
		
			
			|  | 527 | +		list_add_tail ( &ep->halted, &bus->halted );
 | 
		
	
		
			
			| 521 | 528 |  	}
 | 
		
	
		
			
			| 522 | 529 |  
 | 
		
	
		
			
			| 523 | 530 |  	/* Report completion */
 | 
		
	
	
		
			
			|  | @@ -642,6 +649,12 @@ void usb_flush ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 642 | 649 |   ******************************************************************************
 | 
		
	
		
			
			| 643 | 650 |   */
 | 
		
	
		
			
			| 644 | 651 |  
 | 
		
	
		
			
			|  | 652 | +/** USB control transfer pseudo-header */
 | 
		
	
		
			
			|  | 653 | +struct usb_control_pseudo_header {
 | 
		
	
		
			
			|  | 654 | +	/** Completion status */
 | 
		
	
		
			
			|  | 655 | +	int rc;
 | 
		
	
		
			
			|  | 656 | +};
 | 
		
	
		
			
			|  | 657 | +
 | 
		
	
		
			
			| 645 | 658 |  /**
 | 
		
	
		
			
			| 646 | 659 |   * Complete USB control transfer
 | 
		
	
		
			
			| 647 | 660 |   *
 | 
		
	
	
		
			
			|  | @@ -652,13 +665,14 @@ void usb_flush ( struct usb_endpoint *ep ) {
 | 
		
	
		
			
			| 652 | 665 |  static void usb_control_complete ( struct usb_endpoint *ep,
 | 
		
	
		
			
			| 653 | 666 |  				   struct io_buffer *iobuf, int rc ) {
 | 
		
	
		
			
			| 654 | 667 |  	struct usb_device *usb = ep->usb;
 | 
		
	
		
			
			|  | 668 | +	struct usb_control_pseudo_header *pshdr;
 | 
		
	
		
			
			| 655 | 669 |  
 | 
		
	
		
			
			| 656 |  | -	/* Check for failures */
 | 
		
	
		
			
			|  | 670 | +	/* Record completion status in buffer */
 | 
		
	
		
			
			|  | 671 | +	pshdr = iob_push ( iobuf, sizeof ( *pshdr ) );
 | 
		
	
		
			
			|  | 672 | +	pshdr->rc = rc;
 | 
		
	
		
			
			| 657 | 673 |  	if ( rc != 0 ) {
 | 
		
	
		
			
			| 658 | 674 |  		DBGC ( usb, "USB %s control transaction failed: %s\n",
 | 
		
	
		
			
			| 659 | 675 |  		       usb->name, strerror ( rc ) );
 | 
		
	
		
			
			| 660 |  | -		free_iob ( iobuf );
 | 
		
	
		
			
			| 661 |  | -		return;
 | 
		
	
		
			
			| 662 | 676 |  	}
 | 
		
	
		
			
			| 663 | 677 |  
 | 
		
	
		
			
			| 664 | 678 |  	/* Add to list of completed I/O buffers */
 | 
		
	
	
		
			
			|  | @@ -686,17 +700,19 @@ int usb_control ( struct usb_device *usb, unsigned int request,
 | 
		
	
		
			
			| 686 | 700 |  		  size_t len ) {
 | 
		
	
		
			
			| 687 | 701 |  	struct usb_bus *bus = usb->port->hub->bus;
 | 
		
	
		
			
			| 688 | 702 |  	struct usb_endpoint *ep = &usb->control;
 | 
		
	
		
			
			|  | 703 | +	struct usb_control_pseudo_header *pshdr;
 | 
		
	
		
			
			| 689 | 704 |  	struct io_buffer *iobuf;
 | 
		
	
		
			
			| 690 | 705 |  	struct io_buffer *cmplt;
 | 
		
	
		
			
			| 691 | 706 |  	unsigned int i;
 | 
		
	
		
			
			| 692 | 707 |  	int rc;
 | 
		
	
		
			
			| 693 | 708 |  
 | 
		
	
		
			
			| 694 | 709 |  	/* Allocate I/O buffer */
 | 
		
	
		
			
			| 695 |  | -	iobuf = alloc_iob ( len );
 | 
		
	
		
			
			|  | 710 | +	iobuf = alloc_iob ( sizeof ( *pshdr ) + len );
 | 
		
	
		
			
			| 696 | 711 |  	if ( ! iobuf ) {
 | 
		
	
		
			
			| 697 | 712 |  		rc = -ENOMEM;
 | 
		
	
		
			
			| 698 | 713 |  		goto err_alloc;
 | 
		
	
		
			
			| 699 | 714 |  	}
 | 
		
	
		
			
			|  | 715 | +	iob_reserve ( iobuf, sizeof ( *pshdr ) );
 | 
		
	
		
			
			| 700 | 716 |  	iob_put ( iobuf, len );
 | 
		
	
		
			
			| 701 | 717 |  	if ( request & USB_DIR_IN ) {
 | 
		
	
		
			
			| 702 | 718 |  		memset ( data, 0, len );
 | 
		
	
	
		
			
			|  | @@ -722,16 +738,27 @@ int usb_control ( struct usb_device *usb, unsigned int request,
 | 
		
	
		
			
			| 722 | 738 |  			/* Remove from completion list */
 | 
		
	
		
			
			| 723 | 739 |  			list_del ( &cmplt->list );
 | 
		
	
		
			
			| 724 | 740 |  
 | 
		
	
		
			
			|  | 741 | +			/* Extract and strip completion status */
 | 
		
	
		
			
			|  | 742 | +			pshdr = cmplt->data;
 | 
		
	
		
			
			|  | 743 | +			iob_pull ( cmplt, sizeof ( *pshdr ) );
 | 
		
	
		
			
			|  | 744 | +			rc = pshdr->rc;
 | 
		
	
		
			
			|  | 745 | +
 | 
		
	
		
			
			| 725 | 746 |  			/* Discard stale completions */
 | 
		
	
		
			
			| 726 | 747 |  			if ( cmplt != iobuf ) {
 | 
		
	
		
			
			| 727 |  | -				DBGC ( usb, "USB %s stale control "
 | 
		
	
		
			
			| 728 |  | -				       "completion:\n", usb->name );
 | 
		
	
		
			
			|  | 748 | +				DBGC ( usb, "USB %s stale control completion: "
 | 
		
	
		
			
			|  | 749 | +				       "%s\n", usb->name, strerror ( rc ) );
 | 
		
	
		
			
			| 729 | 750 |  				DBGC_HDA ( usb, 0, cmplt->data,
 | 
		
	
		
			
			| 730 | 751 |  					   iob_len ( cmplt ) );
 | 
		
	
		
			
			| 731 | 752 |  				free_iob ( cmplt );
 | 
		
	
		
			
			| 732 | 753 |  				continue;
 | 
		
	
		
			
			| 733 | 754 |  			}
 | 
		
	
		
			
			| 734 | 755 |  
 | 
		
	
		
			
			|  | 756 | +			/* Fail immediately if completion was in error */
 | 
		
	
		
			
			|  | 757 | +			if ( rc != 0 ) {
 | 
		
	
		
			
			|  | 758 | +				free_iob ( cmplt );
 | 
		
	
		
			
			|  | 759 | +				return rc;
 | 
		
	
		
			
			|  | 760 | +			}
 | 
		
	
		
			
			|  | 761 | +
 | 
		
	
		
			
			| 735 | 762 |  			/* Copy completion to data buffer, if applicable */
 | 
		
	
		
			
			| 736 | 763 |  			assert ( iob_len ( cmplt ) <= len );
 | 
		
	
		
			
			| 737 | 764 |  			if ( request & USB_DIR_IN )
 | 
		
	
	
		
			
			|  | @@ -740,10 +767,6 @@ int usb_control ( struct usb_device *usb, unsigned int request,
 | 
		
	
		
			
			| 740 | 767 |  			return 0;
 | 
		
	
		
			
			| 741 | 768 |  		}
 | 
		
	
		
			
			| 742 | 769 |  
 | 
		
	
		
			
			| 743 |  | -		/* Fail immediately if endpoint is in an error state */
 | 
		
	
		
			
			| 744 |  | -		if ( ep->rc )
 | 
		
	
		
			
			| 745 |  | -			return ep->rc;
 | 
		
	
		
			
			| 746 |  | -
 | 
		
	
		
			
			| 747 | 770 |  		/* Delay */
 | 
		
	
		
			
			| 748 | 771 |  		mdelay ( 1 );
 | 
		
	
		
			
			| 749 | 772 |  	}
 | 
		
	
	
		
			
			|  | @@ -1549,8 +1572,8 @@ void usb_port_changed ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1549 | 1572 |  	struct usb_bus *bus = hub->bus;
 | 
		
	
		
			
			| 1550 | 1573 |  
 | 
		
	
		
			
			| 1551 | 1574 |  	/* Record hub port status change */
 | 
		
	
		
			
			| 1552 |  | -	list_del ( &port->list );
 | 
		
	
		
			
			| 1553 |  | -	list_add_tail ( &port->list, &bus->changed );
 | 
		
	
		
			
			|  | 1575 | +	list_del ( &port->changed );
 | 
		
	
		
			
			|  | 1576 | +	list_add_tail ( &port->changed, &bus->changed );
 | 
		
	
		
			
			| 1554 | 1577 |  }
 | 
		
	
		
			
			| 1555 | 1578 |  
 | 
		
	
		
			
			| 1556 | 1579 |  /**
 | 
		
	
	
		
			
			|  | @@ -1559,23 +1582,35 @@ void usb_port_changed ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1559 | 1582 |   * @v bus		USB bus
 | 
		
	
		
			
			| 1560 | 1583 |   */
 | 
		
	
		
			
			| 1561 | 1584 |  static void usb_step ( struct usb_bus *bus ) {
 | 
		
	
		
			
			|  | 1585 | +	struct usb_endpoint *ep;
 | 
		
	
		
			
			| 1562 | 1586 |  	struct usb_port *port;
 | 
		
	
		
			
			| 1563 | 1587 |  
 | 
		
	
		
			
			| 1564 | 1588 |  	/* Poll bus */
 | 
		
	
		
			
			| 1565 | 1589 |  	usb_poll ( bus );
 | 
		
	
		
			
			| 1566 | 1590 |  
 | 
		
	
		
			
			|  | 1591 | +	/* Attempt to reset first halted endpoint in list, if any.  We
 | 
		
	
		
			
			|  | 1592 | +	 * do not attempt to process the complete list, since this
 | 
		
	
		
			
			|  | 1593 | +	 * would require extra code to allow for the facts that the
 | 
		
	
		
			
			|  | 1594 | +	 * halted endpoint list may change as we do so, and that
 | 
		
	
		
			
			|  | 1595 | +	 * resetting an endpoint may fail.
 | 
		
	
		
			
			|  | 1596 | +	 */
 | 
		
	
		
			
			|  | 1597 | +	if ( ( ep = list_first_entry ( &bus->halted, struct usb_endpoint,
 | 
		
	
		
			
			|  | 1598 | +				       halted ) ) != NULL )
 | 
		
	
		
			
			|  | 1599 | +		usb_endpoint_reset ( ep );
 | 
		
	
		
			
			|  | 1600 | +
 | 
		
	
		
			
			| 1567 | 1601 |  	/* Handle any changed ports, allowing for the fact that the
 | 
		
	
		
			
			| 1568 | 1602 |  	 * port list may change as we perform hotplug actions.
 | 
		
	
		
			
			| 1569 | 1603 |  	 */
 | 
		
	
		
			
			| 1570 | 1604 |  	while ( ! list_empty ( &bus->changed ) ) {
 | 
		
	
		
			
			| 1571 | 1605 |  
 | 
		
	
		
			
			| 1572 | 1606 |  		/* Get first changed port */
 | 
		
	
		
			
			| 1573 |  | -		port = list_first_entry ( &bus->changed, struct usb_port, list);
 | 
		
	
		
			
			|  | 1607 | +		port = list_first_entry ( &bus->changed, struct usb_port,
 | 
		
	
		
			
			|  | 1608 | +					  changed );
 | 
		
	
		
			
			| 1574 | 1609 |  		assert ( port != NULL );
 | 
		
	
		
			
			| 1575 | 1610 |  
 | 
		
	
		
			
			| 1576 | 1611 |  		/* Remove from list of changed ports */
 | 
		
	
		
			
			| 1577 |  | -		list_del ( &port->list );
 | 
		
	
		
			
			| 1578 |  | -		INIT_LIST_HEAD ( &port->list );
 | 
		
	
		
			
			|  | 1612 | +		list_del ( &port->changed );
 | 
		
	
		
			
			|  | 1613 | +		INIT_LIST_HEAD ( &port->changed );
 | 
		
	
		
			
			| 1579 | 1614 |  
 | 
		
	
		
			
			| 1580 | 1615 |  		/* Perform appropriate hotplug action */
 | 
		
	
		
			
			| 1581 | 1616 |  		usb_hotplug ( port );
 | 
		
	
	
		
			
			|  | @@ -1628,7 +1663,7 @@ struct usb_hub * alloc_usb_hub ( struct usb_bus *bus, struct usb_device *usb,
 | 
		
	
		
			
			| 1628 | 1663 |  		port->address = i;
 | 
		
	
		
			
			| 1629 | 1664 |  		if ( usb )
 | 
		
	
		
			
			| 1630 | 1665 |  			port->protocol = usb->port->protocol;
 | 
		
	
		
			
			| 1631 |  | -		INIT_LIST_HEAD ( &port->list );
 | 
		
	
		
			
			|  | 1666 | +		INIT_LIST_HEAD ( &port->changed );
 | 
		
	
		
			
			| 1632 | 1667 |  	}
 | 
		
	
		
			
			| 1633 | 1668 |  
 | 
		
	
		
			
			| 1634 | 1669 |  	return hub;
 | 
		
	
	
		
			
			|  | @@ -1702,8 +1737,8 @@ void unregister_usb_hub ( struct usb_hub *hub ) {
 | 
		
	
		
			
			| 1702 | 1737 |  	/* Cancel any pending port status changes */
 | 
		
	
		
			
			| 1703 | 1738 |  	for ( i = 1 ; i <= hub->ports ; i++ ) {
 | 
		
	
		
			
			| 1704 | 1739 |  		port = usb_port ( hub, i );
 | 
		
	
		
			
			| 1705 |  | -		list_del ( &port->list );
 | 
		
	
		
			
			| 1706 |  | -		INIT_LIST_HEAD ( &port->list );
 | 
		
	
		
			
			|  | 1740 | +		list_del ( &port->changed );
 | 
		
	
		
			
			|  | 1741 | +		INIT_LIST_HEAD ( &port->changed );
 | 
		
	
		
			
			| 1707 | 1742 |  	}
 | 
		
	
		
			
			| 1708 | 1743 |  
 | 
		
	
		
			
			| 1709 | 1744 |  	/* Remove from hub list */
 | 
		
	
	
		
			
			|  | @@ -1724,7 +1759,7 @@ void free_usb_hub ( struct usb_hub *hub ) {
 | 
		
	
		
			
			| 1724 | 1759 |  		port = usb_port ( hub, i );
 | 
		
	
		
			
			| 1725 | 1760 |  		assert ( ! port->attached );
 | 
		
	
		
			
			| 1726 | 1761 |  		assert ( port->usb == NULL );
 | 
		
	
		
			
			| 1727 |  | -		assert ( list_empty ( &port->list ) );
 | 
		
	
		
			
			|  | 1762 | +		assert ( list_empty ( &port->changed ) );
 | 
		
	
		
			
			| 1728 | 1763 |  	}
 | 
		
	
		
			
			| 1729 | 1764 |  
 | 
		
	
		
			
			| 1730 | 1765 |  	/* Free hub */
 | 
		
	
	
		
			
			|  | @@ -1762,6 +1797,7 @@ struct usb_bus * alloc_usb_bus ( struct device *dev, unsigned int ports,
 | 
		
	
		
			
			| 1762 | 1797 |  	INIT_LIST_HEAD ( &bus->devices );
 | 
		
	
		
			
			| 1763 | 1798 |  	INIT_LIST_HEAD ( &bus->hubs );
 | 
		
	
		
			
			| 1764 | 1799 |  	INIT_LIST_HEAD ( &bus->changed );
 | 
		
	
		
			
			|  | 1800 | +	INIT_LIST_HEAD ( &bus->halted );
 | 
		
	
		
			
			| 1765 | 1801 |  	process_init_stopped ( &bus->process, &usb_process_desc, NULL );
 | 
		
	
		
			
			| 1766 | 1802 |  	bus->host = &bus->op->bus;
 | 
		
	
		
			
			| 1767 | 1803 |  
 |