lkml.org 
[lkml]   [2015]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.2 151/221] usb: xhci: handle Config Error Change (CEC) in xhci driver
    3.2.69-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Lu Baolu <baolu.lu@linux.intel.com>

    commit 9425183d177aa4a2f09d01a74925124f0778b595 upstream.

    Linux xHCI driver doesn't report and handle port cofig error change.
    If Port Configure Error for root hub port occurs, CEC bit in PORTSC
    would be set by xHC and remains 1. This happends when the root port
    fails to configure its link partner, e.g. the port fails to exchange
    port capabilities information using Port Capability LMPs.

    Then the Port Status Change Events will be blocked until all status
    change bits(CEC is one of the change bits) are cleared('0') (refer to
    xHCI spec 4.19.2). Otherwise, the port status change event for this
    root port will not be generated anymore, then root port would look
    like dead for user and can't be recovered until a Host Controller
    Reset(HCRST).

    This patch is to check CEC bit in PORTSC in xhci_get_port_status()
    and set a Config Error in the return status if CEC is set. This will
    cause a ClearPortFeature request, where CEC bit is cleared in
    xhci_clear_port_change_bit().

    [The commit log is based on initial Marvell patch posted at
    http://marc.info/?l=linux-kernel&m=142323612321434&w=2]

    Reported-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
    Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
    Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    [bwh: Backported to 3.2:
    - Fix indentation
    - s/raw_port_status/temp/]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/usb/host/xhci-hub.c | 9 ++++++++-
    1 file changed, 8 insertions(+), 1 deletion(-)

    --- a/drivers/usb/host/xhci-hub.c
    +++ b/drivers/usb/host/xhci-hub.c
    @@ -385,6 +385,10 @@ static void xhci_clear_port_change_bit(s
    status = PORT_PLC;
    port_change_bit = "link state";
    break;
    + case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
    + status = PORT_CEC;
    + port_change_bit = "config error";
    + break;
    default:
    /* Should never happen */
    return;
    @@ -592,6 +596,8 @@ int xhci_hub_control(struct usb_hcd *hcd
    status |= USB_PORT_STAT_C_LINK_STATE << 16;
    if ((temp & PORT_WRC))
    status |= USB_PORT_STAT_C_BH_RESET << 16;
    + if ((temp & PORT_CEC))
    + status |= USB_PORT_STAT_C_CONFIG_ERROR << 16;
    }

    if (hcd->speed != HCD_USB3) {
    @@ -868,6 +874,7 @@ int xhci_hub_control(struct usb_hcd *hcd
    case USB_PORT_FEAT_C_OVER_CURRENT:
    case USB_PORT_FEAT_C_ENABLE:
    case USB_PORT_FEAT_C_PORT_LINK_STATE:
    + case USB_PORT_FEAT_C_PORT_CONFIG_ERROR:
    xhci_clear_port_change_bit(xhci, wValue, wIndex,
    port_array[wIndex], temp);
    break;
    @@ -916,7 +923,7 @@ int xhci_hub_status_data(struct usb_hcd
    memset(buf, 0, retval);
    status = 0;

    - mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC;
    + mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC | PORT_WRC | PORT_CEC;

    spin_lock_irqsave(&xhci->lock, flags);
    /* For each port, did anything change? If so, set that bit in buf. */


    \
     
     \ /
      Last update: 2015-05-05 04:21    [W:4.123 / U:0.228 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site