USB: xhci: No-op command queueing and irq handler.

xHCI host controllers can optionally implement a no-op test.  This
simple test ensures the OS has correctly setup all basic data structures
and can correctly respond to interrupts from the host controller
hardware.

There are two rings exercised by the no-op test:  the command ring, and
the event ring.

The host controller driver writes a no-op command TRB to the command
ring, and rings the doorbell for the command ring (the first entry in
the doorbell array).  The hardware receives this event, places a command
completion event on the event ring, and fires an interrupt.

The host controller driver sees the interrupt, and checks the event ring
for TRBs it can process, and sees the command completion event.  (See
the rules in xhci-ring.c for who "owns" a TRB.  This is a simplified set
of rules, and may not contain all the details that are in the xHCI 0.95
spec.)

A timer fires every 60 seconds to debug the state of the hardware and
command and event rings.  This timer only runs if
CONFIG_USB_XHCI_HCD_DEBUGGING is 'y'.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index f168fca..66be134 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -24,6 +24,7 @@
 #define __LINUX_XHCI_HCD_H
 
 #include <linux/usb.h>
+#include <linux/timer.h>
 
 #include "../core/hcd.h"
 /* Code sharing between pci-quirks and xhci hcd */
@@ -377,6 +378,7 @@
 /* irq_pending bitmasks */
 #define	ER_IRQ_PENDING(p)	((p) & 0x1)
 /* bits 2:31 need to be preserved */
+/* THIS IS BUGGY - FIXME - IP IS WRITE 1 TO CLEAR */
 #define	ER_IRQ_CLEAR(p)		((p) & 0xfffffffe)
 #define	ER_IRQ_ENABLE(p)	((ER_IRQ_CLEAR(p)) | 0x2)
 #define	ER_IRQ_DISABLE(p)	((ER_IRQ_CLEAR(p)) & ~(0x2))
@@ -699,11 +701,14 @@
 /* control bitfields */
 #define LINK_TOGGLE	(0x1<<1)
 
+/* Command completion event TRB */
+struct xhci_event_cmd {
+	/* Pointer to command TRB, or the value passed by the event data trb */
+	u32 cmd_trb[2];
+	u32 status;
+	u32 flags;
+} __attribute__ ((packed));
 
-union xhci_trb {
-	struct xhci_link_trb		link;
-	struct xhci_transfer_event	trans_event;
-};
 
 /* Normal TRB fields */
 /* transfer_len bitmasks - bits 0:16 */
@@ -737,6 +742,17 @@
 /* Control transfer TRB specific fields */
 #define TRB_DIR_IN		(1<<16)
 
+struct xhci_generic_trb {
+	u32 field[4];
+} __attribute__ ((packed));
+
+union xhci_trb {
+	struct xhci_link_trb		link;
+	struct xhci_transfer_event	trans_event;
+	struct xhci_event_cmd		event_cmd;
+	struct xhci_generic_trb		generic;
+};
+
 /* TRB bit mask */
 #define	TRB_TYPE_BITMASK	(0xfc00)
 #define TRB_TYPE(p)		((p) << 10)
@@ -825,7 +841,11 @@
 struct xhci_ring {
 	struct xhci_segment	*first_seg;
 	union  xhci_trb		*enqueue;
+	struct xhci_segment	*enq_seg;
+	unsigned int		enq_updates;
 	union  xhci_trb		*dequeue;
+	struct xhci_segment	*deq_seg;
+	unsigned int		deq_updates;
 	/*
 	 * Write the cycle state into the TRB cycle field to give ownership of
 	 * the TRB to the host controller (if we are the producer), or to check
@@ -861,6 +881,8 @@
 #define	ERST_SIZE	64
 /* Initial number of event segment rings allocated */
 #define	ERST_ENTRIES	1
+/* Poll every 60 seconds */
+#define	POLL_TIMEOUT	60
 /* XXX: Make these module parameters */
 
 
@@ -907,8 +929,21 @@
 	/* DMA pools */
 	struct dma_pool	*device_pool;
 	struct dma_pool	*segment_pool;
+
+#ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
+	/* Poll the rings - for debugging */
+	struct timer_list	event_ring_timer;
+	int			zombie;
+#endif
+	/* Statistics */
+	int			noops_submitted;
+	int			noops_handled;
+	int			error_bitmask;
 };
 
+/* For testing purposes */
+#define NUM_TEST_NOOPS	0
+
 /* convert between an HCD pointer and the corresponding EHCI_HCD */
 static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd)
 {
@@ -956,9 +991,11 @@
 void xhci_print_registers(struct xhci_hcd *xhci);
 void xhci_dbg_regs(struct xhci_hcd *xhci);
 void xhci_print_run_regs(struct xhci_hcd *xhci);
+void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg);
 void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring);
 void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
 void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
+void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
 
 /* xHCI memory managment */
 void xhci_mem_cleanup(struct xhci_hcd *xhci);
@@ -978,5 +1015,13 @@
 void xhci_stop(struct usb_hcd *hcd);
 void xhci_shutdown(struct usb_hcd *hcd);
 int xhci_get_frame(struct usb_hcd *hcd);
+irqreturn_t xhci_irq(struct usb_hcd *hcd);
+
+/* xHCI ring, segment, TRB, and TD functions */
+dma_addr_t trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
+void ring_cmd_db(struct xhci_hcd *xhci);
+void *setup_one_noop(struct xhci_hcd *xhci);
+void handle_event(struct xhci_hcd *xhci);
+void set_hc_event_deq(struct xhci_hcd *xhci);
 
 #endif /* __LINUX_XHCI_HCD_H */