| From c7f48384d9c9da834ddb70cdc4d0d276c3ec7cf3 Mon Sep 17 00:00:00 2001 |
| From: Lu Baolu <baolu.lu@linux.intel.com> |
| Date: Fri, 11 Nov 2016 15:13:25 +0200 |
| Subject: [PATCH 289/299] usb: xhci: clean up error_bitmask usage |
| |
| In xhci_handle_event(), when errors are detected, driver always sets |
| a bit in error_bitmask (one member of the xhci private driver data). |
| That means users have to retrieve and decode the value of error_bitmask |
| in xhci private driver data if they want to know whether those erros |
| ever happened in xhci_handle_event(). Otherwise, those errors are just |
| ignored silently. |
| |
| This patch cleans up this by replacing the setting of error_bitmask |
| with the kernel print functions, so that users can easily check and |
| report the errors happened in xhci_handle_event(). |
| |
| 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> |
| (cherry picked from commit f4c8f03ca31a9cf4c122780ea693d145658ba397) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-ring.c | 46 ++++++++++++++++++++----------------------- |
| drivers/usb/host/xhci.h | 2 - |
| 2 files changed, 22 insertions(+), 26 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -1239,7 +1239,7 @@ static void xhci_handle_cmd_nec_get_fw(s |
| struct xhci_event_cmd *event) |
| { |
| if (!(xhci->quirks & XHCI_NEC_HOST)) { |
| - xhci->error_bitmask |= 1 << 6; |
| + xhci_warn(xhci, "WARN NEC_GET_FW command on non-NEC host\n"); |
| return; |
| } |
| xhci_dbg_trace(xhci, trace_xhci_dbg_quirks, |
| @@ -1342,14 +1342,13 @@ static void handle_cmd_completion(struct |
| cmd_trb = xhci->cmd_ring->dequeue; |
| cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
| cmd_trb); |
| - /* Is the command ring deq ptr out of sync with the deq seg ptr? */ |
| - if (cmd_dequeue_dma == 0) { |
| - xhci->error_bitmask |= 1 << 4; |
| - return; |
| - } |
| - /* Does the DMA address match our internal dequeue pointer address? */ |
| - if (cmd_dma != (u64) cmd_dequeue_dma) { |
| - xhci->error_bitmask |= 1 << 5; |
| + /* |
| + * Check whether the completion event is for our internal kept |
| + * command. |
| + */ |
| + if (!cmd_dequeue_dma || cmd_dma != (u64)cmd_dequeue_dma) { |
| + xhci_warn(xhci, |
| + "ERROR mismatched command completion event\n"); |
| return; |
| } |
| |
| @@ -1438,7 +1437,7 @@ static void handle_cmd_completion(struct |
| break; |
| default: |
| /* Skip over unknown commands on the event ring */ |
| - xhci->error_bitmask |= 1 << 6; |
| + xhci_info(xhci, "INFO unknown command type %d\n", cmd_type); |
| break; |
| } |
| |
| @@ -1541,10 +1540,10 @@ static void handle_port_status(struct xh |
| bool bogus_port_status = false; |
| |
| /* Port status change events always have a successful completion code */ |
| - if (GET_COMP_CODE(le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS) { |
| - xhci_warn(xhci, "WARN: xHC returned failed port status event\n"); |
| - xhci->error_bitmask |= 1 << 8; |
| - } |
| + if (GET_COMP_CODE(le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS) |
| + xhci_warn(xhci, |
| + "WARN: xHC returned failed port status event\n"); |
| + |
| port_id = GET_PORT_ID(le32_to_cpu(event->generic.field[0])); |
| xhci_dbg(xhci, "Port Status Change Event for port %d\n", port_id); |
| |
| @@ -2547,18 +2546,17 @@ static int xhci_handle_event(struct xhci |
| int update_ptrs = 1; |
| int ret; |
| |
| + /* Event ring hasn't been allocated yet. */ |
| if (!xhci->event_ring || !xhci->event_ring->dequeue) { |
| - xhci->error_bitmask |= 1 << 1; |
| - return 0; |
| + xhci_err(xhci, "ERROR event ring not ready\n"); |
| + return -ENOMEM; |
| } |
| |
| event = xhci->event_ring->dequeue; |
| /* Does the HC or OS own the TRB? */ |
| if ((le32_to_cpu(event->event_cmd.flags) & TRB_CYCLE) != |
| - xhci->event_ring->cycle_state) { |
| - xhci->error_bitmask |= 1 << 2; |
| + xhci->event_ring->cycle_state) |
| return 0; |
| - } |
| |
| /* |
| * Barrier between reading the TRB_CYCLE (valid) flag above and any |
| @@ -2566,7 +2564,7 @@ static int xhci_handle_event(struct xhci |
| */ |
| rmb(); |
| /* FIXME: Handle more event types. */ |
| - switch ((le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK)) { |
| + switch (le32_to_cpu(event->event_cmd.flags) & TRB_TYPE_BITMASK) { |
| case TRB_TYPE(TRB_COMPLETION): |
| handle_cmd_completion(xhci, &event->event_cmd); |
| break; |
| @@ -2576,9 +2574,7 @@ static int xhci_handle_event(struct xhci |
| break; |
| case TRB_TYPE(TRB_TRANSFER): |
| ret = handle_tx_event(xhci, &event->trans_event); |
| - if (ret < 0) |
| - xhci->error_bitmask |= 1 << 9; |
| - else |
| + if (ret >= 0) |
| update_ptrs = 0; |
| break; |
| case TRB_TYPE(TRB_DEV_NOTE): |
| @@ -2589,7 +2585,9 @@ static int xhci_handle_event(struct xhci |
| TRB_TYPE(48)) |
| handle_vendor_event(xhci, event); |
| else |
| - xhci->error_bitmask |= 1 << 3; |
| + xhci_warn(xhci, "ERROR unknown event type %d\n", |
| + TRB_FIELD_TO_TYPE( |
| + le32_to_cpu(event->event_cmd.flags))); |
| } |
| /* Any of the above functions may drop and re-acquire the lock, so check |
| * to make sure a watchdog timer didn't mark the host as non-responsive. |
| --- a/drivers/usb/host/xhci.h |
| +++ b/drivers/usb/host/xhci.h |
| @@ -1614,8 +1614,6 @@ struct xhci_hcd { |
| #define XHCI_STATE_DYING (1 << 0) |
| #define XHCI_STATE_HALTED (1 << 1) |
| #define XHCI_STATE_REMOVING (1 << 2) |
| - /* Statistics */ |
| - int error_bitmask; |
| unsigned int quirks; |
| #define XHCI_LINK_TRB_QUIRK (1 << 0) |
| #define XHCI_RESET_EP_QUIRK (1 << 1) |