• Sarah Sharp's avatar
    USB: Set usb_hcd->state and flags for shared roothubs. · ff9d78b3
    Sarah Sharp authored
    The hcd->flags are in a sorry state.  Some of them are clearly specific to
    the particular roothub (HCD_POLL_RH, HCD_POLL_PENDING, and
    HCD_WAKEUP_PENDING), but some flags are related to PCI device state
    (HCD_HW_ACCESSIBLE and HCD_SAW_IRQ).  This is an issue when one PCI device
    can have two roothubs that share the same IRQ line and hardware.
    
    Make sure to set HCD_FLAG_SAW_IRQ for both roothubs when an interrupt is
    serviced, or an URB is unlinked without an interrupt.  (We can't tell if
    the host actually serviced an interrupt for a particular bus, but we can
    tell it serviced some interrupt.)
    
    HCD_HW_ACCESSIBLE is set once by usb_add_hcd(), which is set for both
    roothubs as they are added, so it doesn't need to be modified.
    HCD_POLL_RH and HCD_POLL_PENDING are only checked by the USB core, and
    they are never set by the xHCI driver, since the roothub never needs to be
    polled.
    
    The usb_hcd's state field is a similar mess.  Sometimes the state applies
    to the underlying hardware: HC_STATE_HALT, HC_STATE_RUNNING, and
    HC_STATE_QUIESCING.  But sometimes the state refers to the roothub state:
    HC_STATE_RESUMING and HC_STATE_SUSPENDED.
    
    Alan Stern recently made the USB core not rely on the hcd->state variable.
    Internally, the xHCI driver still checks for HC_STATE_SUSPENDED, so leave
    that code in.  Remove all references to HC_STATE_HALT, since the xHCI
    driver only sets and doesn't test those variables.  We still have to set
    HC_STATE_RUNNING, since Alan's patch has a bug that means the roothub
    won't get registered if we don't set that.
    
    Alan's patch made the USB core check a different variable when trying to
    determine whether to suspend a roothub.  The xHCI host has a split
    roothub, where two buses are registered for one PCI device.  Each bus in
    the xHCI split roothub can be suspended separately, but both buses must be
    suspended before the PCI device can be suspended.  Therefore, make sure
    that the USB core checks HCD_RH_RUNNING() for both roothubs before
    suspending the PCI host.
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    ff9d78b3
hcd.c 75.6 KB