From f4c8f03ca31a9cf4c122780ea693d145658ba397 Mon Sep 17 00:00:00 2001 From: Lu Baolu Date: Fri, 11 Nov 2016 15:13:25 +0200 Subject: [PATCH] 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 Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 46 +++++++++++++++++------------------- drivers/usb/host/xhci.h | 2 -- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0e7faea2276c..26be80dba9dc 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1180,7 +1180,7 @@ static void xhci_handle_cmd_nec_get_fw(struct xhci_hcd *xhci, 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, @@ -1322,14 +1322,13 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, 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; } @@ -1415,7 +1414,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, 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; } @@ -1516,10 +1515,10 @@ static void handle_port_status(struct xhci_hcd *xhci, 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); @@ -2522,18 +2521,17 @@ static int xhci_handle_event(struct xhci_hcd *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 @@ -2541,7 +2539,7 @@ static int xhci_handle_event(struct xhci_hcd *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; @@ -2551,9 +2549,7 @@ static int xhci_handle_event(struct xhci_hcd *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): @@ -2564,7 +2560,9 @@ static int xhci_handle_event(struct xhci_hcd *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. diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f945380035d0..0751c6ad52e6 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1618,8 +1618,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) -- 2.39.5