|  | @@ -43,6 +43,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
		
	
		
			
			| 43 | 43 |  /** List of USB buses */
 | 
		
	
		
			
			| 44 | 44 |  struct list_head usb_buses = LIST_HEAD_INIT ( usb_buses );
 | 
		
	
		
			
			| 45 | 45 |  
 | 
		
	
		
			
			|  | 46 | +/** List of changed ports */
 | 
		
	
		
			
			|  | 47 | +static struct list_head usb_changed = LIST_HEAD_INIT ( usb_changed );
 | 
		
	
		
			
			|  | 48 | +
 | 
		
	
		
			
			|  | 49 | +/** List of halted endpoints */
 | 
		
	
		
			
			|  | 50 | +static struct list_head usb_halted = LIST_HEAD_INIT ( usb_halted );
 | 
		
	
		
			
			|  | 51 | +
 | 
		
	
		
			
			| 46 | 52 |  /******************************************************************************
 | 
		
	
		
			
			| 47 | 53 |   *
 | 
		
	
		
			
			| 48 | 54 |   * Utility functions
 | 
		
	
	
		
			
			|  | @@ -560,7 +566,6 @@ int usb_stream ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 560 | 566 |  void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 561 | 567 |  			int rc ) {
 | 
		
	
		
			
			| 562 | 568 |  	struct usb_device *usb = ep->usb;
 | 
		
	
		
			
			| 563 |  | -	struct usb_bus *bus = usb->port->hub->bus;
 | 
		
	
		
			
			| 564 | 569 |  
 | 
		
	
		
			
			| 565 | 570 |  	/* Decrement fill level */
 | 
		
	
		
			
			| 566 | 571 |  	assert ( ep->fill > 0 );
 | 
		
	
	
		
			
			|  | @@ -572,7 +577,7 @@ void usb_complete_err ( struct usb_endpoint *ep, struct io_buffer *iobuf,
 | 
		
	
		
			
			| 572 | 577 |  		       usb->name, usb_endpoint_name ( ep->address ),
 | 
		
	
		
			
			| 573 | 578 |  		       strerror ( rc ) );
 | 
		
	
		
			
			| 574 | 579 |  		list_del ( &ep->halted );
 | 
		
	
		
			
			| 575 |  | -		list_add_tail ( &ep->halted, &bus->halted );
 | 
		
	
		
			
			|  | 580 | +		list_add_tail ( &ep->halted, &usb_halted );
 | 
		
	
		
			
			| 576 | 581 |  	}
 | 
		
	
		
			
			| 577 | 582 |  
 | 
		
	
		
			
			| 578 | 583 |  	/* Report completion */
 | 
		
	
	
		
			
			|  | @@ -1576,12 +1581,12 @@ static void usb_detached ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1576 | 1581 |  }
 | 
		
	
		
			
			| 1577 | 1582 |  
 | 
		
	
		
			
			| 1578 | 1583 |  /**
 | 
		
	
		
			
			| 1579 |  | - * Handle newly attached or detached USB devices
 | 
		
	
		
			
			|  | 1584 | + * Handle newly attached or detached USB device
 | 
		
	
		
			
			| 1580 | 1585 |   *
 | 
		
	
		
			
			| 1581 | 1586 |   * @v port		USB port
 | 
		
	
		
			
			| 1582 | 1587 |   * @ret rc		Return status code
 | 
		
	
		
			
			| 1583 | 1588 |   */
 | 
		
	
		
			
			| 1584 |  | -static int usb_hotplug ( struct usb_port *port ) {
 | 
		
	
		
			
			|  | 1589 | +static int usb_hotplugged ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1585 | 1590 |  	struct usb_hub *hub = port->hub;
 | 
		
	
		
			
			| 1586 | 1591 |  	int rc;
 | 
		
	
		
			
			| 1587 | 1592 |  
 | 
		
	
	
		
			
			|  | @@ -1621,43 +1626,26 @@ static int usb_hotplug ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1621 | 1626 |   * @v port		USB port
 | 
		
	
		
			
			| 1622 | 1627 |   */
 | 
		
	
		
			
			| 1623 | 1628 |  void usb_port_changed ( struct usb_port *port ) {
 | 
		
	
		
			
			| 1624 |  | -	struct usb_hub *hub = port->hub;
 | 
		
	
		
			
			| 1625 |  | -	struct usb_bus *bus = hub->bus;
 | 
		
	
		
			
			| 1626 | 1629 |  
 | 
		
	
		
			
			| 1627 | 1630 |  	/* Record hub port status change */
 | 
		
	
		
			
			| 1628 | 1631 |  	list_del ( &port->changed );
 | 
		
	
		
			
			| 1629 |  | -	list_add_tail ( &port->changed, &bus->changed );
 | 
		
	
		
			
			|  | 1632 | +	list_add_tail ( &port->changed, &usb_changed );
 | 
		
	
		
			
			| 1630 | 1633 |  }
 | 
		
	
		
			
			| 1631 | 1634 |  
 | 
		
	
		
			
			| 1632 | 1635 |  /**
 | 
		
	
		
			
			| 1633 |  | - * USB process
 | 
		
	
		
			
			|  | 1636 | + * Handle newly attached or detached USB device
 | 
		
	
		
			
			| 1634 | 1637 |   *
 | 
		
	
		
			
			| 1635 |  | - * @v bus		USB bus
 | 
		
	
		
			
			| 1636 | 1638 |   */
 | 
		
	
		
			
			| 1637 |  | -static void usb_step ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1638 |  | -	struct usb_endpoint *ep;
 | 
		
	
		
			
			|  | 1639 | +static void usb_hotplug ( void ) {
 | 
		
	
		
			
			| 1639 | 1640 |  	struct usb_port *port;
 | 
		
	
		
			
			| 1640 | 1641 |  
 | 
		
	
		
			
			| 1641 |  | -	/* Poll bus */
 | 
		
	
		
			
			| 1642 |  | -	usb_poll ( bus );
 | 
		
	
		
			
			| 1643 |  | -
 | 
		
	
		
			
			| 1644 |  | -	/* Attempt to reset first halted endpoint in list, if any.  We
 | 
		
	
		
			
			| 1645 |  | -	 * do not attempt to process the complete list, since this
 | 
		
	
		
			
			| 1646 |  | -	 * would require extra code to allow for the facts that the
 | 
		
	
		
			
			| 1647 |  | -	 * halted endpoint list may change as we do so, and that
 | 
		
	
		
			
			| 1648 |  | -	 * resetting an endpoint may fail.
 | 
		
	
		
			
			| 1649 |  | -	 */
 | 
		
	
		
			
			| 1650 |  | -	if ( ( ep = list_first_entry ( &bus->halted, struct usb_endpoint,
 | 
		
	
		
			
			| 1651 |  | -				       halted ) ) != NULL )
 | 
		
	
		
			
			| 1652 |  | -		usb_endpoint_reset ( ep );
 | 
		
	
		
			
			| 1653 |  | -
 | 
		
	
		
			
			| 1654 | 1642 |  	/* Handle any changed ports, allowing for the fact that the
 | 
		
	
		
			
			| 1655 | 1643 |  	 * port list may change as we perform hotplug actions.
 | 
		
	
		
			
			| 1656 | 1644 |  	 */
 | 
		
	
		
			
			| 1657 |  | -	while ( ! list_empty ( &bus->changed ) ) {
 | 
		
	
		
			
			|  | 1645 | +	while ( ! list_empty ( &usb_changed ) ) {
 | 
		
	
		
			
			| 1658 | 1646 |  
 | 
		
	
		
			
			| 1659 | 1647 |  		/* Get first changed port */
 | 
		
	
		
			
			| 1660 |  | -		port = list_first_entry ( &bus->changed, struct usb_port,
 | 
		
	
		
			
			|  | 1648 | +		port = list_first_entry ( &usb_changed, struct usb_port,
 | 
		
	
		
			
			| 1661 | 1649 |  					  changed );
 | 
		
	
		
			
			| 1662 | 1650 |  		assert ( port != NULL );
 | 
		
	
		
			
			| 1663 | 1651 |  
 | 
		
	
	
		
			
			|  | @@ -1666,13 +1654,39 @@ static void usb_step ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1666 | 1654 |  		INIT_LIST_HEAD ( &port->changed );
 | 
		
	
		
			
			| 1667 | 1655 |  
 | 
		
	
		
			
			| 1668 | 1656 |  		/* Perform appropriate hotplug action */
 | 
		
	
		
			
			| 1669 |  | -		usb_hotplug ( port );
 | 
		
	
		
			
			|  | 1657 | +		usb_hotplugged ( port );
 | 
		
	
		
			
			| 1670 | 1658 |  	}
 | 
		
	
		
			
			| 1671 | 1659 |  }
 | 
		
	
		
			
			| 1672 | 1660 |  
 | 
		
	
		
			
			|  | 1661 | +/**
 | 
		
	
		
			
			|  | 1662 | + * USB process
 | 
		
	
		
			
			|  | 1663 | + *
 | 
		
	
		
			
			|  | 1664 | + * @v process		USB process
 | 
		
	
		
			
			|  | 1665 | + */
 | 
		
	
		
			
			|  | 1666 | +static void usb_step ( struct process *process __unused ) {
 | 
		
	
		
			
			|  | 1667 | +	struct usb_bus *bus;
 | 
		
	
		
			
			|  | 1668 | +	struct usb_endpoint *ep;
 | 
		
	
		
			
			|  | 1669 | +
 | 
		
	
		
			
			|  | 1670 | +	/* Poll all buses */
 | 
		
	
		
			
			|  | 1671 | +	for_each_usb_bus ( bus )
 | 
		
	
		
			
			|  | 1672 | +		usb_poll ( bus );
 | 
		
	
		
			
			|  | 1673 | +
 | 
		
	
		
			
			|  | 1674 | +	/* Attempt to reset first halted endpoint in list, if any.  We
 | 
		
	
		
			
			|  | 1675 | +	 * do not attempt to process the complete list, since this
 | 
		
	
		
			
			|  | 1676 | +	 * would require extra code to allow for the facts that the
 | 
		
	
		
			
			|  | 1677 | +	 * halted endpoint list may change as we do so, and that
 | 
		
	
		
			
			|  | 1678 | +	 * resetting an endpoint may fail.
 | 
		
	
		
			
			|  | 1679 | +	 */
 | 
		
	
		
			
			|  | 1680 | +	if ( ( ep = list_first_entry ( &usb_halted, struct usb_endpoint,
 | 
		
	
		
			
			|  | 1681 | +				       halted ) ) != NULL )
 | 
		
	
		
			
			|  | 1682 | +		usb_endpoint_reset ( ep );
 | 
		
	
		
			
			|  | 1683 | +
 | 
		
	
		
			
			|  | 1684 | +	/* Handle any changed ports */
 | 
		
	
		
			
			|  | 1685 | +	usb_hotplug();
 | 
		
	
		
			
			|  | 1686 | +}
 | 
		
	
		
			
			|  | 1687 | +
 | 
		
	
		
			
			| 1673 | 1688 |  /** USB process */
 | 
		
	
		
			
			| 1674 |  | -static struct process_descriptor usb_process_desc =
 | 
		
	
		
			
			| 1675 |  | -	PROC_DESC ( struct usb_bus, process, usb_step );
 | 
		
	
		
			
			|  | 1689 | +PERMANENT_PROCESS ( usb_process, usb_step );
 | 
		
	
		
			
			| 1676 | 1690 |  
 | 
		
	
		
			
			| 1677 | 1691 |  /******************************************************************************
 | 
		
	
		
			
			| 1678 | 1692 |   *
 | 
		
	
	
		
			
			|  | @@ -1755,10 +1769,10 @@ int register_usb_hub ( struct usb_hub *hub ) {
 | 
		
	
		
			
			| 1755 | 1769 |  	/* Delay to allow ports to stabilise */
 | 
		
	
		
			
			| 1756 | 1770 |  	mdelay ( USB_PORT_DELAY_MS );
 | 
		
	
		
			
			| 1757 | 1771 |  
 | 
		
	
		
			
			| 1758 |  | -	/* Attach any devices already present */
 | 
		
	
		
			
			|  | 1772 | +	/* Mark all ports as changed */
 | 
		
	
		
			
			| 1759 | 1773 |  	for ( i = 1 ; i <= hub->ports ; i++ ) {
 | 
		
	
		
			
			| 1760 | 1774 |  		port = usb_port ( hub, i );
 | 
		
	
		
			
			| 1761 |  | -		usb_hotplug ( port );
 | 
		
	
		
			
			|  | 1775 | +		usb_port_changed ( port );
 | 
		
	
		
			
			| 1762 | 1776 |  	}
 | 
		
	
		
			
			| 1763 | 1777 |  
 | 
		
	
		
			
			| 1764 | 1778 |  	/* Some hubs seem to defer reporting device connections until
 | 
		
	
	
		
			
			|  | @@ -1766,7 +1780,10 @@ int register_usb_hub ( struct usb_hub *hub ) {
 | 
		
	
		
			
			| 1766 | 1780 |  	 * Poll the bus once now in order to pick up any such
 | 
		
	
		
			
			| 1767 | 1781 |  	 * connections.
 | 
		
	
		
			
			| 1768 | 1782 |  	 */
 | 
		
	
		
			
			| 1769 |  | -	usb_step ( bus );
 | 
		
	
		
			
			|  | 1783 | +	usb_poll ( bus );
 | 
		
	
		
			
			|  | 1784 | +
 | 
		
	
		
			
			|  | 1785 | +	/* Attach any devices already present */
 | 
		
	
		
			
			|  | 1786 | +	usb_hotplug();
 | 
		
	
		
			
			| 1770 | 1787 |  
 | 
		
	
		
			
			| 1771 | 1788 |  	return 0;
 | 
		
	
		
			
			| 1772 | 1789 |  
 | 
		
	
	
		
			
			|  | @@ -1862,9 +1879,6 @@ struct usb_bus * alloc_usb_bus ( struct device *dev, unsigned int ports,
 | 
		
	
		
			
			| 1862 | 1879 |  	bus->op = op;
 | 
		
	
		
			
			| 1863 | 1880 |  	INIT_LIST_HEAD ( &bus->devices );
 | 
		
	
		
			
			| 1864 | 1881 |  	INIT_LIST_HEAD ( &bus->hubs );
 | 
		
	
		
			
			| 1865 |  | -	INIT_LIST_HEAD ( &bus->changed );
 | 
		
	
		
			
			| 1866 |  | -	INIT_LIST_HEAD ( &bus->halted );
 | 
		
	
		
			
			| 1867 |  | -	process_init_stopped ( &bus->process, &usb_process_desc, NULL );
 | 
		
	
		
			
			| 1868 | 1882 |  	bus->host = &bus->op->bus;
 | 
		
	
		
			
			| 1869 | 1883 |  
 | 
		
	
		
			
			| 1870 | 1884 |  	/* Allocate root hub */
 | 
		
	
	
		
			
			|  | @@ -1904,9 +1918,6 @@ int register_usb_bus ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1904 | 1918 |  	if ( ( rc = register_usb_hub ( bus->hub ) ) != 0 )
 | 
		
	
		
			
			| 1905 | 1919 |  		goto err_register_hub;
 | 
		
	
		
			
			| 1906 | 1920 |  
 | 
		
	
		
			
			| 1907 |  | -	/* Start bus process */
 | 
		
	
		
			
			| 1908 |  | -	process_add ( &bus->process );
 | 
		
	
		
			
			| 1909 |  | -
 | 
		
	
		
			
			| 1910 | 1921 |  	return 0;
 | 
		
	
		
			
			| 1911 | 1922 |  
 | 
		
	
		
			
			| 1912 | 1923 |  	unregister_usb_hub ( bus->hub );
 | 
		
	
	
		
			
			|  | @@ -1926,10 +1937,6 @@ void unregister_usb_bus ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1926 | 1937 |  
 | 
		
	
		
			
			| 1927 | 1938 |  	/* Sanity checks */
 | 
		
	
		
			
			| 1928 | 1939 |  	assert ( bus->hub != NULL );
 | 
		
	
		
			
			| 1929 |  | -	assert ( process_running ( &bus->process ) );
 | 
		
	
		
			
			| 1930 |  | -
 | 
		
	
		
			
			| 1931 |  | -	/* Stop bus process */
 | 
		
	
		
			
			| 1932 |  | -	process_del ( &bus->process );
 | 
		
	
		
			
			| 1933 | 1940 |  
 | 
		
	
		
			
			| 1934 | 1941 |  	/* Unregister root hub */
 | 
		
	
		
			
			| 1935 | 1942 |  	unregister_usb_hub ( bus->hub );
 | 
		
	
	
		
			
			|  | @@ -1943,7 +1950,6 @@ void unregister_usb_bus ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1943 | 1950 |  	/* Sanity checks */
 | 
		
	
		
			
			| 1944 | 1951 |  	assert ( list_empty ( &bus->devices ) );
 | 
		
	
		
			
			| 1945 | 1952 |  	assert ( list_empty ( &bus->hubs ) );
 | 
		
	
		
			
			| 1946 |  | -	assert ( ! process_running ( &bus->process ) );
 | 
		
	
		
			
			| 1947 | 1953 |  }
 | 
		
	
		
			
			| 1948 | 1954 |  
 | 
		
	
		
			
			| 1949 | 1955 |  /**
 | 
		
	
	
		
			
			|  | @@ -1952,11 +1958,16 @@ void unregister_usb_bus ( struct usb_bus *bus ) {
 | 
		
	
		
			
			| 1952 | 1958 |   * @v bus		USB bus
 | 
		
	
		
			
			| 1953 | 1959 |   */
 | 
		
	
		
			
			| 1954 | 1960 |  void free_usb_bus ( struct usb_bus *bus ) {
 | 
		
	
		
			
			|  | 1961 | +	struct usb_endpoint *ep;
 | 
		
	
		
			
			|  | 1962 | +	struct usb_port *port;
 | 
		
	
		
			
			| 1955 | 1963 |  
 | 
		
	
		
			
			| 1956 | 1964 |  	/* Sanity checks */
 | 
		
	
		
			
			| 1957 | 1965 |  	assert ( list_empty ( &bus->devices ) );
 | 
		
	
		
			
			| 1958 | 1966 |  	assert ( list_empty ( &bus->hubs ) );
 | 
		
	
		
			
			| 1959 |  | -	assert ( ! process_running ( &bus->process ) );
 | 
		
	
		
			
			|  | 1967 | +	list_for_each_entry ( ep, &usb_halted, halted )
 | 
		
	
		
			
			|  | 1968 | +		assert ( ep->usb->port->hub->bus != bus );
 | 
		
	
		
			
			|  | 1969 | +	list_for_each_entry ( port, &usb_changed, changed )
 | 
		
	
		
			
			|  | 1970 | +		assert ( port->hub->bus != bus );
 | 
		
	
		
			
			| 1960 | 1971 |  
 | 
		
	
		
			
			| 1961 | 1972 |  	/* Free root hub */
 | 
		
	
		
			
			| 1962 | 1973 |  	free_usb_hub ( bus->hub );
 |