xhci: Make xHCI driver endian-safe
Subsystems (2)
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.
Signed-off-by Matt Evans <[email protected]>
--- 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
@@ -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
@@ -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