[RFC 10/10] NOT for merge: xhci command cancellation stress test.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch added some code to the xHCI driver to make it stall every
other Set Address command, and stop ringing the doorbells of bulk
endpoints after two URBs were submitted to the host.

This made it easy to test the command cancellation code, to ensure that:

1. Commands that weren't at the dequeue of the command ring would wait on
the previously submitted command.

2. The Stop Endpoint watchdog timer would re-queue itself the command
wasn't the first on the command ring.

This code is NOT to be merged, it simply shows what I've tested.

Not-signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-ring.c |   11 +++++++++++
 drivers/usb/host/xhci.c      |   12 ++++++++++--
 drivers/usb/host/xhci.h      |    2 ++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 3601cdf..6a984d4 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3345,6 +3345,8 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	int running_total, trb_buff_len, ret;
 	unsigned int total_packet_count;
 	u64 addr;
+	unsigned int ep_state;
+	struct xhci_virt_ep *ep;
 
 	if (urb->num_sgs)
 		return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
@@ -3352,6 +3354,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	ep_ring = xhci_urb_to_transfer_ring(xhci, urb);
 	if (!ep_ring)
 		return -EINVAL;
+	ep = &xhci->devs[slot_id]->eps[ep_index];
 
 	num_trbs = 0;
 	/* How much data is (potentially) left before the 64KB boundary? */
@@ -3462,8 +3465,16 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 	} while (running_total < urb->transfer_buffer_length);
 
 	check_trb_math(urb, num_trbs, running_total);
+	if (xhci->num_bulk_urbs > 2) {
+		ep_state = ep->ep_state;
+		ep->ep_state |= EP_HALTED;
+		xhci_dbg(xhci, "TEST, TEST! Don't ring bulk doorbell.\n");
+	}
 	giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id,
 			start_cycle, start_trb);
+	if (xhci->num_bulk_urbs > 2)
+		ep->ep_state = ep_state;
+	xhci->num_bulk_urbs++;
 	return 0;
 }
 
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 51a8c55..390ef93 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -3732,11 +3732,19 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
 		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
 		return ret;
 	}
-	xhci_ring_cmd_db(xhci);
+	/* XXX: testing purposes: stall Set Address on every other command. */
+	if ((xhci->num_set_addrs % 2) == 0)
+		xhci_ring_cmd_db(xhci);
+	else {
+		xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
+		xhci_dbg(xhci, "TEST, TEST! Stalling Set Address for 60 seconds.\n");
+	}
+	xhci->num_set_addrs++;
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
 	timeleft = xhci_wait_for_command(xhci, &xhci->addr_dev, cmd_trb,
-			"set address", XHCI_CMD_DEFAULT_TIMEOUT);
+			"set address", 60 * HZ);
+	xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
 	/* FIXME: From section 4.3.4: "Software shall be responsible for timing
 	 * the SetAddress() "recovery interval" required by USB and aborting the
 	 * command on a timeout.
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f66ce67..f5a64e7 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1534,6 +1534,8 @@ struct xhci_hcd {
 	u32			port_status_u0;
 /* Compliance Mode Timer Triggered every 2 seconds */
 #define COMP_MODE_RCVRY_MSECS 2000
+	unsigned int		num_set_addrs;
+	unsigned int		num_bulk_urbs;
 };
 
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux