Skip to contentSkip to conversation

xhci: Make xHCI driver endian-safe

PATCH New Matt Evans 1 participant 1 message Mar 29, 2011

Subsystems (2)
lore
Share & tools
lore

Matt Evans

author
#0 lore raw

PATCH v3 1/4 xhci: Make xHCI driver endian-safe

This patch changes the struct members defining access to xHCI device-visible memory to use __le32/__le64 where appropriate, and then adds swaps where required. Checked with sparse that all accesses are correct.

MMIO accesses use readl/writel so already are performed LE, but prototypes now reflect this with __le*.

There were a couple of (debug) instances of DMA pointers being truncated to 32bits which have been fixed too.

---
 drivers/usb/host/xhci-dbg.c  |   51 ++++----
 drivers/usb/host/xhci-hub.c  |   18 ++--
 drivers/usb/host/xhci-mem.c  |  122 ++++++++++----------
 drivers/usb/host/xhci-ring.c |  267 ++++++++++++++++++++++--------------------
 drivers/usb/host/xhci.c      |  109 +++++++++--------
 drivers/usb/host/xhci.h      |  134 +++++++++++-----------
 6 files changed, 360 insertions(+), 341 deletions(-)
drivers/usb/host/xhci-dbg.c +26 -25
index 0231814..2e04861 100644
@@ -147,7 +147,7 @@ static void xhci_print_op_regs(struct xhci_hcd *xhci)
 
 static void xhci_print_ports(struct xhci_hcd *xhci)
 {
-	u32 __iomem *addr;
+	__le32 __iomem *addr;
 	int i, j;
 	int ports;
 	char *names[NUM_PORT_REGS] = {
@@ -253,27 +253,27 @@ void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb)
 void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
 {
 	u64	address;
-	u32	type = xhci_readl(xhci, &trb->link.control) & TRB_TYPE_BITMASK;
+	u32	type = le32_to_cpu(trb->link.control) & TRB_TYPE_BITMASK;
 
 	switch (type) {
 	case TRB_TYPE(TRB_LINK):
 		xhci_dbg(xhci, "Link TRB:\n");
 		xhci_print_trb_offsets(xhci, trb);
 
-		address = trb->link.segment_ptr;
+		address = le64_to_cpu(trb->link.segment_ptr);
 		xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address);
 
 		xhci_dbg(xhci, "Interrupter target = 0x%x\n",
-				GET_INTR_TARGET(trb->link.intr_target));
+			 GET_INTR_TARGET(le32_to_cpu(trb->link.intr_target)));
 		xhci_dbg(xhci, "Cycle bit = %u\n",
-				(unsigned int) (trb->link.control & TRB_CYCLE));
+			 (unsigned int) (le32_to_cpu(trb->link.control) & TRB_CYCLE));
 		xhci_dbg(xhci, "Toggle cycle bit = %u\n",
-				(unsigned int) (trb->link.control & LINK_TOGGLE));
+			 (unsigned int) (le32_to_cpu(trb->link.control) & LINK_TOGGLE));
 		xhci_dbg(xhci, "No Snoop bit = %u\n",
-				(unsigned int) (trb->link.control & TRB_NO_SNOOP));
+			 (unsigned int) (le32_to_cpu(trb->link.control) & TRB_NO_SNOOP));
 		break;
 	case TRB_TYPE(TRB_TRANSFER):
-		address = trb->trans_event.buffer;
+		address = le64_to_cpu(trb->trans_event.buffer);
 		/*
 		 * FIXME: look at flags to figure out if it's an address or if
 		 * the data is directly in the buffer field.
@@ -281,11 +281,12 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
 		xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
 		break;
 	case TRB_TYPE(TRB_COMPLETION):
-		address = trb->event_cmd.cmd_trb;
+		address = le64_to_cpu(trb->event_cmd.cmd_trb);
 		xhci_dbg(xhci, "Command TRB pointer = %llu\n", address);
 		xhci_dbg(xhci, "Completion status = %u\n",
-				(unsigned int) GET_COMP_CODE(trb->event_cmd.status));
-		xhci_dbg(xhci, "Flags = 0x%x\n", (unsigned int) trb->event_cmd.flags);
+			 (unsigned int) GET_COMP_CODE(le32_to_cpu(trb->event_cmd.status)));
+		xhci_dbg(xhci, "Flags = 0x%x\n",
+			 (unsigned int) le32_to_cpu(trb->event_cmd.flags));
 		break;
 	default:
 		xhci_dbg(xhci, "Unknown TRB with TRB type ID %u\n",
@@ -311,16 +312,16 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
 void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
 {
 	int i;
-	u32 addr = (u32) seg->dma;
+	u64 addr = seg->dma;
 	union xhci_trb *trb = seg->trbs;
 
 	for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
 		trb = &seg->trbs[i];
-		xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr,
-				lower_32_bits(trb->link.segment_ptr),
-				upper_32_bits(trb->link.segment_ptr),
-				(unsigned int) trb->link.intr_target,
-				(unsigned int) trb->link.control);
+		xhci_dbg(xhci, "@%016llx %08x %08x %08x %08x\n", addr,
+			 (u32)lower_32_bits(le64_to_cpu(trb->link.segment_ptr)),
+			 (u32)upper_32_bits(le64_to_cpu(trb->link.segment_ptr)),
+			 (unsigned int) le32_to_cpu(trb->link.intr_target),
+			 (unsigned int) le32_to_cpu(trb->link.control));
 		addr += sizeof(*trb);
 	}
 }
@@ -391,18 +392,18 @@ void xhci_dbg_ep_rings(struct xhci_hcd *xhci,
 
 void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
 {
-	u32 addr = (u32) erst->erst_dma_addr;
+	u64 addr = erst->erst_dma_addr;
 	int i;
 	struct xhci_erst_entry *entry;
 
 	for (i = 0; i < erst->num_entries; ++i) {
 		entry = &erst->entries[i];
-		xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n",
-				(unsigned int) addr,
-				lower_32_bits(entry->seg_addr),
-				upper_32_bits(entry->seg_addr),
-				(unsigned int) entry->seg_size,
-				(unsigned int) entry->rsvd);
+		xhci_dbg(xhci, "@%016llx %08x %08x %08x %08x\n",
+			 addr,
+			 lower_32_bits(le64_to_cpu(entry->seg_addr)),
+			 upper_32_bits(le64_to_cpu(entry->seg_addr)),
+			 (unsigned int) le32_to_cpu(entry->seg_size),
+			 (unsigned int) le32_to_cpu(entry->rsvd));
 		addr += sizeof(*entry);
 	}
 }
@@ -436,7 +437,7 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci,
 {
 	struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
 
-	switch (GET_SLOT_STATE(slot_ctx->dev_state)) {
+	switch (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state))) {
 	case 0:
 		return "enabled/disabled";
 	case 1:
drivers/usb/host/xhci-hub.c +9 -9
index a78f2eb..ae1d24c 100644
@@ -50,7 +50,7 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,
 	temp |= 0x0008;
 	/* Bits 6:5 - no TTs in root ports */
 	/* Bit  7 - no port indicators */
-	desc->wHubCharacteristics = (__force __u16) cpu_to_le16(temp);
+	desc->wHubCharacteristics = cpu_to_le16(temp);
 }
 
 /* Fill in the USB 2.0 roothub descriptor */
@@ -314,7 +314,7 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id)
 }
 
 static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
-		u16 wIndex, u32 __iomem *addr, u32 port_status)
+		u16 wIndex, __le32 __iomem *addr, u32 port_status)
 {
 	/* Don't allow the USB core to disable SuperSpeed ports. */
 	if (hcd->speed == HCD_USB3) {
@@ -331,7 +331,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci,
 }
 
 static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
-		u16 wIndex, u32 __iomem *addr, u32 port_status)
+		u16 wIndex, __le32 __iomem *addr, u32 port_status)
 {
 	char *port_change_bit;
 	u32 status;
@@ -376,7 +376,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 	unsigned long flags;
 	u32 temp, temp1, status;
 	int retval = 0;
-	u32 __iomem **port_array;
+	__le32 __iomem **port_array;
 	int slot_id;
 	struct xhci_bus_state *bus_state;
 
@@ -664,7 +664,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 	int i, retval;
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int ports;
-	u32 __iomem **port_array;
+	__le32 __iomem **port_array;
 	struct xhci_bus_state *bus_state;
 
 	if (hcd->speed == HCD_USB3) {
@@ -709,7 +709,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int max_ports, port_index;
-	u32 __iomem **port_array;
+	__le32 __iomem **port_array;
 	struct xhci_bus_state *bus_state;
 	unsigned long flags;
 
@@ -779,7 +779,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 
 		if (DEV_HIGHSPEED(t1)) {
 			/* enable remote wake up for USB 2.0 */
-			u32 __iomem *addr;
+			__le32 __iomem *addr;
 			u32 tmp;
 
 			/* Add one to the port status register address to get
@@ -801,7 +801,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
 	int max_ports, port_index;
-	u32 __iomem **port_array;
+	__le32 __iomem **port_array;
 	struct xhci_bus_state *bus_state;
 	u32 temp;
 	unsigned long flags;
@@ -875,7 +875,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 
 		if (DEV_HIGHSPEED(temp)) {
 			/* disable remote wake up for USB 2.0 */
-			u32 __iomem *addr;
+			__le32 __iomem *addr;
 			u32 tmp;
 
 			/* Add one to the port status register address to get
drivers/usb/host/xhci-mem.c +61 -61

300 lines not on this page · raw message

drivers/usb/host/xhci-ring.c +140 -127

693 lines not on this page · raw message

drivers/usb/host/xhci.c +57 -52

254 lines not on this page · raw message

drivers/usb/host/xhci.h +67 -67

263 lines not on this page · raw message

Signature · 1 line
1.7.0.4