aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci.h
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-07-27 15:03:31 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-28 17:31:12 -0400
commit8e595a5d30a5ee4bb745d4da6439d73ed7d91054 (patch)
tree0050cb2c24643b602a8b3c40adef3e7b73fe81fc /drivers/usb/host/xhci.h
parentb11069f5f6ce6e359f853e908b0917303fcdec8f (diff)
USB: xhci: Represent 64-bit addresses with one u64.
There are several xHCI data structures that use two 32-bit fields to represent a 64-bit address. Since some architectures don't support 64-bit PCI writes, the fields need to be written in two 32-bit writes. The xHCI specification says that if a platform is incapable of generating 64-bit writes, software must write the low 32-bits first, then the high 32-bits. Hardware that supports 64-bit addressing will wait for the high 32-bit write before reading the revised value, and hardware that only supports 32-bit writes will ignore the high 32-bit write. Previous xHCI code represented 64-bit addresses with two u32 values. This lead to buggy code that would write the 32-bits in the wrong order, or forget to write the upper 32-bits. Change the two u32s to one u64 and create a function call to write all 64-bit addresses in the proper order. This new function could be modified in the future if all platforms support 64-bit writes. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r--drivers/usb/host/xhci.h65
1 files changed, 45 insertions, 20 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index cde648a524f5..60770c89132b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -25,6 +25,7 @@
25 25
26#include <linux/usb.h> 26#include <linux/usb.h>
27#include <linux/timer.h> 27#include <linux/timer.h>
28#include <linux/kernel.h>
28 29
29#include "../core/hcd.h" 30#include "../core/hcd.h"
30/* Code sharing between pci-quirks and xhci hcd */ 31/* Code sharing between pci-quirks and xhci hcd */
@@ -42,14 +43,6 @@
42 * xHCI register interface. 43 * xHCI register interface.
43 * This corresponds to the eXtensible Host Controller Interface (xHCI) 44 * This corresponds to the eXtensible Host Controller Interface (xHCI)
44 * Revision 0.95 specification 45 * Revision 0.95 specification
45 *
46 * Registers should always be accessed with double word or quad word accesses.
47 *
48 * Some xHCI implementations may support 64-bit address pointers. Registers
49 * with 64-bit address pointers should be written to with dword accesses by
50 * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
51 * xHCI implementations that do not support 64-bit address pointers will ignore
52 * the high dword, and write order is irrelevant.
53 */ 46 */
54 47
55/** 48/**
@@ -166,10 +159,10 @@ struct xhci_op_regs {
166 u32 reserved1; 159 u32 reserved1;
167 u32 reserved2; 160 u32 reserved2;
168 u32 dev_notification; 161 u32 dev_notification;
169 u32 cmd_ring[2]; 162 u64 cmd_ring;
170 /* rsvd: offset 0x20-2F */ 163 /* rsvd: offset 0x20-2F */
171 u32 reserved3[4]; 164 u32 reserved3[4];
172 u32 dcbaa_ptr[2]; 165 u64 dcbaa_ptr;
173 u32 config_reg; 166 u32 config_reg;
174 /* rsvd: offset 0x3C-3FF */ 167 /* rsvd: offset 0x3C-3FF */
175 u32 reserved4[241]; 168 u32 reserved4[241];
@@ -254,7 +247,7 @@ struct xhci_op_regs {
254#define CMD_RING_RUNNING (1 << 3) 247#define CMD_RING_RUNNING (1 << 3)
255/* bits 4:5 reserved and should be preserved */ 248/* bits 4:5 reserved and should be preserved */
256/* Command Ring pointer - bit mask for the lower 32 bits. */ 249/* Command Ring pointer - bit mask for the lower 32 bits. */
257#define CMD_RING_ADDR_MASK (0xffffffc0) 250#define CMD_RING_RSVD_BITS (0x3f)
258 251
259/* CONFIG - Configure Register - config_reg bitmasks */ 252/* CONFIG - Configure Register - config_reg bitmasks */
260/* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */ 253/* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */
@@ -382,8 +375,8 @@ struct xhci_intr_reg {
382 u32 irq_control; 375 u32 irq_control;
383 u32 erst_size; 376 u32 erst_size;
384 u32 rsvd; 377 u32 rsvd;
385 u32 erst_base[2]; 378 u64 erst_base;
386 u32 erst_dequeue[2]; 379 u64 erst_dequeue;
387}; 380};
388 381
389/* irq_pending bitmasks */ 382/* irq_pending bitmasks */
@@ -538,7 +531,7 @@ struct xhci_slot_ctx {
538struct xhci_ep_ctx { 531struct xhci_ep_ctx {
539 u32 ep_info; 532 u32 ep_info;
540 u32 ep_info2; 533 u32 ep_info2;
541 u32 deq[2]; 534 u64 deq;
542 u32 tx_info; 535 u32 tx_info;
543 /* offset 0x14 - 0x1f reserved for HC internal use */ 536 /* offset 0x14 - 0x1f reserved for HC internal use */
544 u32 reserved[3]; 537 u32 reserved[3];
@@ -641,7 +634,7 @@ struct xhci_virt_device {
641 */ 634 */
642struct xhci_device_context_array { 635struct xhci_device_context_array {
643 /* 64-bit device addresses; we only write 32-bit addresses */ 636 /* 64-bit device addresses; we only write 32-bit addresses */
644 u32 dev_context_ptrs[2*MAX_HC_SLOTS]; 637 u64 dev_context_ptrs[MAX_HC_SLOTS];
645 /* private xHCD pointers */ 638 /* private xHCD pointers */
646 dma_addr_t dma; 639 dma_addr_t dma;
647}; 640};
@@ -654,7 +647,7 @@ struct xhci_device_context_array {
654 647
655struct xhci_stream_ctx { 648struct xhci_stream_ctx {
656 /* 64-bit stream ring address, cycle state, and stream type */ 649 /* 64-bit stream ring address, cycle state, and stream type */
657 u32 stream_ring[2]; 650 u64 stream_ring;
658 /* offset 0x14 - 0x1f reserved for HC internal use */ 651 /* offset 0x14 - 0x1f reserved for HC internal use */
659 u32 reserved[2]; 652 u32 reserved[2];
660}; 653};
@@ -662,7 +655,7 @@ struct xhci_stream_ctx {
662 655
663struct xhci_transfer_event { 656struct xhci_transfer_event {
664 /* 64-bit buffer address, or immediate data */ 657 /* 64-bit buffer address, or immediate data */
665 u32 buffer[2]; 658 u64 buffer;
666 u32 transfer_len; 659 u32 transfer_len;
667 /* This field is interpreted differently based on the type of TRB */ 660 /* This field is interpreted differently based on the type of TRB */
668 u32 flags; 661 u32 flags;
@@ -744,7 +737,7 @@ struct xhci_transfer_event {
744 737
745struct xhci_link_trb { 738struct xhci_link_trb {
746 /* 64-bit segment pointer*/ 739 /* 64-bit segment pointer*/
747 u32 segment_ptr[2]; 740 u64 segment_ptr;
748 u32 intr_target; 741 u32 intr_target;
749 u32 control; 742 u32 control;
750}; 743};
@@ -755,7 +748,7 @@ struct xhci_link_trb {
755/* Command completion event TRB */ 748/* Command completion event TRB */
756struct xhci_event_cmd { 749struct xhci_event_cmd {
757 /* Pointer to command TRB, or the value passed by the event data trb */ 750 /* Pointer to command TRB, or the value passed by the event data trb */
758 u32 cmd_trb[2]; 751 u64 cmd_trb;
759 u32 status; 752 u32 status;
760 u32 flags; 753 u32 flags;
761}; 754};
@@ -943,7 +936,7 @@ struct xhci_ring {
943 936
944struct xhci_erst_entry { 937struct xhci_erst_entry {
945 /* 64-bit event ring segment address */ 938 /* 64-bit event ring segment address */
946 u32 seg_addr[2]; 939 u64 seg_addr;
947 u32 seg_size; 940 u32 seg_size;
948 /* Set to zero */ 941 /* Set to zero */
949 u32 rsvd; 942 u32 rsvd;
@@ -1079,6 +1072,38 @@ static inline void xhci_writel(struct xhci_hcd *xhci,
1079 writel(val, regs); 1072 writel(val, regs);
1080} 1073}
1081 1074
1075/*
1076 * Registers should always be accessed with double word or quad word accesses.
1077 *
1078 * Some xHCI implementations may support 64-bit address pointers. Registers
1079 * with 64-bit address pointers should be written to with dword accesses by
1080 * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
1081 * xHCI implementations that do not support 64-bit address pointers will ignore
1082 * the high dword, and write order is irrelevant.
1083 */
1084static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
1085 __u64 __iomem *regs)
1086{
1087 __u32 __iomem *ptr = (__u32 __iomem *) regs;
1088 u64 val_lo = readl(ptr);
1089 u64 val_hi = readl(ptr + 1);
1090 return val_lo + (val_hi << 32);
1091}
1092static inline void xhci_write_64(struct xhci_hcd *xhci,
1093 const u64 val, __u64 __iomem *regs)
1094{
1095 __u32 __iomem *ptr = (__u32 __iomem *) regs;
1096 u32 val_lo = lower_32_bits(val);
1097 u32 val_hi = upper_32_bits(val);
1098
1099 if (!in_interrupt())
1100 xhci_dbg(xhci,
1101 "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n",
1102 regs, (long unsigned int) val);
1103 writel(val_lo, ptr);
1104 writel(val_hi, ptr + 1);
1105}
1106
1082/* xHCI debugging */ 1107/* xHCI debugging */
1083void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); 1108void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
1084void xhci_print_registers(struct xhci_hcd *xhci); 1109void xhci_print_registers(struct xhci_hcd *xhci);