Commit dbc26546 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge branch 'for-usb-next' of...

Merge branch 'for-usb-next' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-next

* 'for-usb-next' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci:
  xhci 1.0: Set transfer burst last packet count field.
  xhci 1.0: Set transfer burst count field.
  xhci 1.0: Update TD size field format.
  xhci 1.0: Only interrupt on short packet for IN EPs.
  xhci: Remove sparse warning about cmd_status.
  usbcore: warm reset USB3 port in SS.Inactive state
  usbcore: Refine USB3.0 device suspend and resume
  xHCI: report USB3.0 portstatus comply with USB3.0 specification
  xHCI: Set link state support
  xHCI: Clear link state change support
  xHCI: warm reset support
  usb/ch9: use proper endianess for wBytesPerInterval
  xhci: Remove recursive call to xhci_handle_event
  xhci: Add an assertion to check for virt_dev=0 bug.
  xhci: Add rmb() between reading event validity & event data access.
  xhci: Make xHCI driver endian-safe
parents 71a9f9d2 b61d378f
...@@ -129,7 +129,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, ...@@ -129,7 +129,7 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1);
else else
max_tx = 999999; max_tx = 999999;
if (desc->wBytesPerInterval > max_tx) { if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) {
dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in "
"config %d interface %d altsetting %d ep %d: " "config %d interface %d altsetting %d ep %d: "
"setting to %d\n", "setting to %d\n",
......
...@@ -379,15 +379,6 @@ static int hub_port_status(struct usb_hub *hub, int port1, ...@@ -379,15 +379,6 @@ static int hub_port_status(struct usb_hub *hub, int port1,
*status = le16_to_cpu(hub->status->port.wPortStatus); *status = le16_to_cpu(hub->status->port.wPortStatus);
*change = le16_to_cpu(hub->status->port.wPortChange); *change = le16_to_cpu(hub->status->port.wPortChange);
if ((hub->hdev->parent != NULL) &&
hub_is_superspeed(hub->hdev)) {
/* Translate the USB 3 port status */
u16 tmp = *status & USB_SS_PORT_STAT_MASK;
if (*status & USB_SS_PORT_STAT_POWER)
tmp |= USB_PORT_STAT_POWER;
*status = tmp;
}
ret = 0; ret = 0;
} }
mutex_unlock(&hub->status_mutex); mutex_unlock(&hub->status_mutex);
...@@ -2160,11 +2151,76 @@ static int hub_port_reset(struct usb_hub *hub, int port1, ...@@ -2160,11 +2151,76 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
return status; return status;
} }
/* Warm reset a USB3 protocol port */
static int hub_port_warm_reset(struct usb_hub *hub, int port)
{
int ret;
u16 portstatus, portchange;
if (!hub_is_superspeed(hub->hdev)) {
dev_err(hub->intfdev, "only USB3 hub support warm reset\n");
return -EINVAL;
}
/* Warm reset the port */
ret = set_port_feature(hub->hdev,
port, USB_PORT_FEAT_BH_PORT_RESET);
if (ret) {
dev_err(hub->intfdev, "cannot warm reset port %d\n", port);
return ret;
}
msleep(20);
ret = hub_port_status(hub, port, &portstatus, &portchange);
if (portchange & USB_PORT_STAT_C_RESET)
clear_port_feature(hub->hdev, port, USB_PORT_FEAT_C_RESET);
if (portchange & USB_PORT_STAT_C_BH_RESET)
clear_port_feature(hub->hdev, port,
USB_PORT_FEAT_C_BH_PORT_RESET);
if (portchange & USB_PORT_STAT_C_LINK_STATE)
clear_port_feature(hub->hdev, port,
USB_PORT_FEAT_C_PORT_LINK_STATE);
return ret;
}
/* Check if a port is power on */
static int port_is_power_on(struct usb_hub *hub, unsigned portstatus)
{
int ret = 0;
if (hub_is_superspeed(hub->hdev)) {
if (portstatus & USB_SS_PORT_STAT_POWER)
ret = 1;
} else {
if (portstatus & USB_PORT_STAT_POWER)
ret = 1;
}
return ret;
}
#ifdef CONFIG_PM #ifdef CONFIG_PM
#define MASK_BITS (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION | \ /* Check if a port is suspended(USB2.0 port) or in U3 state(USB3.0 port) */
USB_PORT_STAT_SUSPEND) static int port_is_suspended(struct usb_hub *hub, unsigned portstatus)
#define WANT_BITS (USB_PORT_STAT_POWER | USB_PORT_STAT_CONNECTION) {
int ret = 0;
if (hub_is_superspeed(hub->hdev)) {
if ((portstatus & USB_PORT_STAT_LINK_STATE)
== USB_SS_PORT_LS_U3)
ret = 1;
} else {
if (portstatus & USB_PORT_STAT_SUSPEND)
ret = 1;
}
return ret;
}
/* Determine whether the device on a port is ready for a normal resume, /* Determine whether the device on a port is ready for a normal resume,
* is ready for a reset-resume, or should be disconnected. * is ready for a reset-resume, or should be disconnected.
...@@ -2174,7 +2230,9 @@ static int check_port_resume_type(struct usb_device *udev, ...@@ -2174,7 +2230,9 @@ static int check_port_resume_type(struct usb_device *udev,
int status, unsigned portchange, unsigned portstatus) int status, unsigned portchange, unsigned portstatus)
{ {
/* Is the device still present? */ /* Is the device still present? */
if (status || (portstatus & MASK_BITS) != WANT_BITS) { if (status || port_is_suspended(hub, portstatus) ||
!port_is_power_on(hub, portstatus) ||
!(portstatus & USB_PORT_STAT_CONNECTION)) {
if (status >= 0) if (status >= 0)
status = -ENODEV; status = -ENODEV;
} }
...@@ -2285,14 +2343,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) ...@@ -2285,14 +2343,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
} }
/* see 7.1.7.6 */ /* see 7.1.7.6 */
/* Clear PORT_POWER if it's a USB3.0 device connected to USB 3.0 if (hub_is_superspeed(hub->hdev))
* external hub. status = set_port_feature(hub->hdev,
* FIXME: this is a temporary workaround to make the system able port1 | (USB_SS_PORT_LS_U3 << 3),
* to suspend/resume. USB_PORT_FEAT_LINK_STATE);
*/
if ((hub->hdev->parent != NULL) && hub_is_superspeed(hub->hdev))
status = clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_POWER);
else else
status = set_port_feature(hub->hdev, port1, status = set_port_feature(hub->hdev, port1,
USB_PORT_FEAT_SUSPEND); USB_PORT_FEAT_SUSPEND);
...@@ -2439,7 +2493,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) ...@@ -2439,7 +2493,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
/* Skip the initial Clear-Suspend step for a remote wakeup */ /* Skip the initial Clear-Suspend step for a remote wakeup */
status = hub_port_status(hub, port1, &portstatus, &portchange); status = hub_port_status(hub, port1, &portstatus, &portchange);
if (status == 0 && !(portstatus & USB_PORT_STAT_SUSPEND)) if (status == 0 && !port_is_suspended(hub, portstatus))
goto SuspendCleared; goto SuspendCleared;
// dev_dbg(hub->intfdev, "resume port %d\n", port1); // dev_dbg(hub->intfdev, "resume port %d\n", port1);
...@@ -2447,6 +2501,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) ...@@ -2447,6 +2501,11 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
set_bit(port1, hub->busy_bits); set_bit(port1, hub->busy_bits);
/* see 7.1.7.7; affects power usage, but not budgeting */ /* see 7.1.7.7; affects power usage, but not budgeting */
if (hub_is_superspeed(hub->hdev))
status = set_port_feature(hub->hdev,
port1 | (USB_SS_PORT_LS_U0 << 3),
USB_PORT_FEAT_LINK_STATE);
else
status = clear_port_feature(hub->hdev, status = clear_port_feature(hub->hdev,
port1, USB_PORT_FEAT_SUSPEND); port1, USB_PORT_FEAT_SUSPEND);
if (status) { if (status) {
...@@ -2470,10 +2529,16 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg) ...@@ -2470,10 +2529,16 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
SuspendCleared: SuspendCleared:
if (status == 0) { if (status == 0) {
if (hub_is_superspeed(hub->hdev)) {
if (portchange & USB_PORT_STAT_C_LINK_STATE)
clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_PORT_LINK_STATE);
} else {
if (portchange & USB_PORT_STAT_C_SUSPEND) if (portchange & USB_PORT_STAT_C_SUSPEND)
clear_port_feature(hub->hdev, port1, clear_port_feature(hub->hdev, port1,
USB_PORT_FEAT_C_SUSPEND); USB_PORT_FEAT_C_SUSPEND);
} }
}
clear_bit(port1, hub->busy_bits); clear_bit(port1, hub->busy_bits);
...@@ -3147,7 +3212,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, ...@@ -3147,7 +3212,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
/* maybe switch power back on (e.g. root hub was reset) */ /* maybe switch power back on (e.g. root hub was reset) */
if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
&& !(portstatus & USB_PORT_STAT_POWER)) && !port_is_power_on(hub, portstatus))
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
if (portstatus & USB_PORT_STAT_ENABLE) if (portstatus & USB_PORT_STAT_ENABLE)
...@@ -3490,6 +3555,16 @@ static void hub_events(void) ...@@ -3490,6 +3555,16 @@ static void hub_events(void)
USB_PORT_FEAT_C_PORT_CONFIG_ERROR); USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
} }
/* Warm reset a USB3 protocol port if it's in
* SS.Inactive state.
*/
if (hub_is_superspeed(hub->hdev) &&
(portstatus & USB_PORT_STAT_LINK_STATE)
== USB_SS_PORT_LS_SS_INACTIVE) {
dev_dbg(hub_dev, "warm reset port %d\n", i);
hub_port_warm_reset(hub, i);
}
if (connect_change) if (connect_change)
hub_port_connect_change(hub, i, hub_port_connect_change(hub, i,
portstatus, portchange); portstatus, portchange);
......
...@@ -147,7 +147,7 @@ static void xhci_print_op_regs(struct xhci_hcd *xhci) ...@@ -147,7 +147,7 @@ static void xhci_print_op_regs(struct xhci_hcd *xhci)
static void xhci_print_ports(struct xhci_hcd *xhci) static void xhci_print_ports(struct xhci_hcd *xhci)
{ {
u32 __iomem *addr; __le32 __iomem *addr;
int i, j; int i, j;
int ports; int ports;
char *names[NUM_PORT_REGS] = { char *names[NUM_PORT_REGS] = {
...@@ -253,27 +253,27 @@ void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb) ...@@ -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) void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
{ {
u64 address; 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) { switch (type) {
case TRB_TYPE(TRB_LINK): case TRB_TYPE(TRB_LINK):
xhci_dbg(xhci, "Link TRB:\n"); xhci_dbg(xhci, "Link TRB:\n");
xhci_print_trb_offsets(xhci, trb); 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, "Next ring segment DMA address = 0x%llx\n", address);
xhci_dbg(xhci, "Interrupter target = 0x%x\n", 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", 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", 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", 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; break;
case TRB_TYPE(TRB_TRANSFER): 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 * FIXME: look at flags to figure out if it's an address or if
* the data is directly in the buffer field. * the data is directly in the buffer field.
...@@ -281,11 +281,12 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb) ...@@ -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); xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
break; break;
case TRB_TYPE(TRB_COMPLETION): 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, "Command TRB pointer = %llu\n", address);
xhci_dbg(xhci, "Completion status = %u\n", xhci_dbg(xhci, "Completion status = %u\n",
(unsigned int) GET_COMP_CODE(trb->event_cmd.status)); (unsigned int) GET_COMP_CODE(le32_to_cpu(trb->event_cmd.status)));
xhci_dbg(xhci, "Flags = 0x%x\n", (unsigned int) trb->event_cmd.flags); xhci_dbg(xhci, "Flags = 0x%x\n",
(unsigned int) le32_to_cpu(trb->event_cmd.flags));
break; break;
default: default:
xhci_dbg(xhci, "Unknown TRB with TRB type ID %u\n", 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) ...@@ -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) void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
{ {
int i; int i;
u32 addr = (u32) seg->dma; u64 addr = seg->dma;
union xhci_trb *trb = seg->trbs; union xhci_trb *trb = seg->trbs;
for (i = 0; i < TRBS_PER_SEGMENT; ++i) { for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
trb = &seg->trbs[i]; trb = &seg->trbs[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr, xhci_dbg(xhci, "@%016llx %08x %08x %08x %08x\n", addr,
lower_32_bits(trb->link.segment_ptr), (u32)lower_32_bits(le64_to_cpu(trb->link.segment_ptr)),
upper_32_bits(trb->link.segment_ptr), (u32)upper_32_bits(le64_to_cpu(trb->link.segment_ptr)),
(unsigned int) trb->link.intr_target, (unsigned int) le32_to_cpu(trb->link.intr_target),
(unsigned int) trb->link.control); (unsigned int) le32_to_cpu(trb->link.control));
addr += sizeof(*trb); addr += sizeof(*trb);
} }
} }
...@@ -391,18 +392,18 @@ void xhci_dbg_ep_rings(struct xhci_hcd *xhci, ...@@ -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) 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; int i;
struct xhci_erst_entry *entry; struct xhci_erst_entry *entry;
for (i = 0; i < erst->num_entries; ++i) { for (i = 0; i < erst->num_entries; ++i) {
entry = &erst->entries[i]; entry = &erst->entries[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", xhci_dbg(xhci, "@%016llx %08x %08x %08x %08x\n",
(unsigned int) addr, addr,
lower_32_bits(entry->seg_addr), lower_32_bits(le64_to_cpu(entry->seg_addr)),
upper_32_bits(entry->seg_addr), upper_32_bits(le64_to_cpu(entry->seg_addr)),
(unsigned int) entry->seg_size, (unsigned int) le32_to_cpu(entry->seg_size),
(unsigned int) entry->rsvd); (unsigned int) le32_to_cpu(entry->rsvd));
addr += sizeof(*entry); addr += sizeof(*entry);
} }
} }
...@@ -436,7 +437,7 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci, ...@@ -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); 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: case 0:
return "enabled/disabled"; return "enabled/disabled";
case 1: case 1:
......
...@@ -50,7 +50,7 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci, ...@@ -50,7 +50,7 @@ static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,
temp |= 0x0008; temp |= 0x0008;
/* Bits 6:5 - no TTs in root ports */ /* Bits 6:5 - no TTs in root ports */
/* Bit 7 - no port indicators */ /* 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 */ /* Fill in the USB 2.0 roothub descriptor */
...@@ -314,7 +314,7 @@ void xhci_ring_device(struct xhci_hcd *xhci, int slot_id) ...@@ -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, 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. */ /* Don't allow the USB core to disable SuperSpeed ports. */
if (hcd->speed == HCD_USB3) { if (hcd->speed == HCD_USB3) {
...@@ -331,7 +331,7 @@ static void xhci_disable_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, ...@@ -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, 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; char *port_change_bit;
u32 status; u32 status;
...@@ -341,6 +341,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, ...@@ -341,6 +341,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
status = PORT_RC; status = PORT_RC;
port_change_bit = "reset"; port_change_bit = "reset";
break; break;
case USB_PORT_FEAT_C_BH_PORT_RESET:
status = PORT_WRC;
port_change_bit = "warm(BH) reset";
break;
case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_CONNECTION:
status = PORT_CSC; status = PORT_CSC;
port_change_bit = "connect"; port_change_bit = "connect";
...@@ -357,6 +361,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue, ...@@ -357,6 +361,10 @@ static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
status = PORT_PLC; status = PORT_PLC;
port_change_bit = "suspend/resume"; port_change_bit = "suspend/resume";
break; break;
case USB_PORT_FEAT_C_PORT_LINK_STATE:
status = PORT_PLC;
port_change_bit = "link state";
break;
default: default:
/* Should never happen */ /* Should never happen */
return; return;
...@@ -376,9 +384,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -376,9 +384,10 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
unsigned long flags; unsigned long flags;
u32 temp, temp1, status; u32 temp, temp1, status;
int retval = 0; int retval = 0;
u32 __iomem **port_array; __le32 __iomem **port_array;
int slot_id; int slot_id;
struct xhci_bus_state *bus_state; struct xhci_bus_state *bus_state;
u16 link_state = 0;
if (hcd->speed == HCD_USB3) { if (hcd->speed == HCD_USB3) {
ports = xhci->num_usb3_ports; ports = xhci->num_usb3_ports;
...@@ -422,9 +431,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -422,9 +431,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
} }
xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp); xhci_dbg(xhci, "get port status, actual port %d status = 0x%x\n", wIndex, temp);
/* FIXME - should we return a port status value like the USB
* 3.0 external hubs do?
*/
/* wPortChange bits */ /* wPortChange bits */
if (temp & PORT_CSC) if (temp & PORT_CSC)
status |= USB_PORT_STAT_C_CONNECTION << 16; status |= USB_PORT_STAT_C_CONNECTION << 16;
...@@ -432,13 +438,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -432,13 +438,21 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
status |= USB_PORT_STAT_C_ENABLE << 16; status |= USB_PORT_STAT_C_ENABLE << 16;
if ((temp & PORT_OCC)) if ((temp & PORT_OCC))
status |= USB_PORT_STAT_C_OVERCURRENT << 16; status |= USB_PORT_STAT_C_OVERCURRENT << 16;
/* if ((temp & PORT_RC))
* FIXME ignoring reset and USB 2.1/3.0 specific status |= USB_PORT_STAT_C_RESET << 16;
* changes /* USB3.0 only */
*/ if (hcd->speed == HCD_USB3) {
if ((temp & PORT_PLC))
status |= USB_PORT_STAT_C_LINK_STATE << 16;
if ((temp & PORT_WRC))
status |= USB_PORT_STAT_C_BH_RESET << 16;
}
if (hcd->speed != HCD_USB3) {
if ((temp & PORT_PLS_MASK) == XDEV_U3 if ((temp & PORT_PLS_MASK) == XDEV_U3
&& (temp & PORT_POWER)) && (temp & PORT_POWER))
status |= 1 << USB_PORT_FEAT_SUSPEND; status |= USB_PORT_STAT_SUSPEND;
}
if ((temp & PORT_PLS_MASK) == XDEV_RESUME) { if ((temp & PORT_PLS_MASK) == XDEV_RESUME) {
if ((temp & PORT_RESET) || !(temp & PORT_PE)) if ((temp & PORT_RESET) || !(temp & PORT_PE))
goto error; goto error;
...@@ -469,6 +483,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -469,6 +483,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
&& (temp & PORT_POWER) && (temp & PORT_POWER)
&& (bus_state->suspended_ports & (1 << wIndex))) { && (bus_state->suspended_ports & (1 << wIndex))) {
bus_state->suspended_ports &= ~(1 << wIndex); bus_state->suspended_ports &= ~(1 << wIndex);
if (hcd->speed != HCD_USB3)
bus_state->port_c_suspend |= 1 << wIndex; bus_state->port_c_suspend |= 1 << wIndex;
} }
if (temp & PORT_CONNECT) { if (temp & PORT_CONNECT) {
...@@ -481,14 +496,28 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -481,14 +496,28 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
status |= USB_PORT_STAT_OVERCURRENT; status |= USB_PORT_STAT_OVERCURRENT;
if (temp & PORT_RESET) if (temp & PORT_RESET)
status |= USB_PORT_STAT_RESET; status |= USB_PORT_STAT_RESET;
if (temp & PORT_POWER) if (temp & PORT_POWER) {
if (hcd->speed == HCD_USB3)
status |= USB_SS_PORT_STAT_POWER;
else
status |= USB_PORT_STAT_POWER; status |= USB_PORT_STAT_POWER;
}
/* Port Link State */
if (hcd->speed == HCD_USB3) {
/* resume state is a xHCI internal state.
* Do not report it to usb core.
*/
if ((temp & PORT_PLS_MASK) != XDEV_RESUME)
status |= (temp & PORT_PLS_MASK);
}
if (bus_state->port_c_suspend & (1 << wIndex)) if (bus_state->port_c_suspend & (1 << wIndex))
status |= 1 << USB_PORT_FEAT_C_SUSPEND; status |= 1 << USB_PORT_FEAT_C_SUSPEND;
xhci_dbg(xhci, "Get port status returned 0x%x\n", status); xhci_dbg(xhci, "Get port status returned 0x%x\n", status);
put_unaligned(cpu_to_le32(status), (__le32 *) buf); put_unaligned(cpu_to_le32(status), (__le32 *) buf);
break; break;
case SetPortFeature: case SetPortFeature:
if (wValue == USB_PORT_FEAT_LINK_STATE)
link_state = (wIndex & 0xff00) >> 3;
wIndex &= 0xff; wIndex &= 0xff;
if (!wIndex || wIndex > ports) if (!wIndex || wIndex > ports)
goto error; goto error;
...@@ -537,6 +566,44 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -537,6 +566,44 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_readl(xhci, port_array[wIndex]); temp = xhci_readl(xhci, port_array[wIndex]);
bus_state->suspended_ports |= 1 << wIndex; bus_state->suspended_ports |= 1 << wIndex;
break; break;
case USB_PORT_FEAT_LINK_STATE:
temp = xhci_readl(xhci, port_array[wIndex]);
/* Software should not attempt to set
* port link state above '5' (Rx.Detect) and the port
* must be enabled.
*/
if ((temp & PORT_PE) == 0 ||
(link_state > USB_SS_PORT_LS_RX_DETECT)) {
xhci_warn(xhci, "Cannot set link state.\n");
goto error;
}
if (link_state == USB_SS_PORT_LS_U3) {
slot_id = xhci_find_slot_id_by_port(hcd, xhci,
wIndex + 1);
if (slot_id) {
/* unlock to execute stop endpoint
* commands */
spin_unlock_irqrestore(&xhci->lock,
flags);
xhci_stop_device(xhci, slot_id, 1);
spin_lock_irqsave(&xhci->lock, flags);
}
}
temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | link_state;
xhci_writel(xhci, temp, port_array[wIndex]);
spin_unlock_irqrestore(&xhci->lock, flags);
msleep(20); /* wait device to enter */
spin_lock_irqsave(&xhci->lock, flags);
temp = xhci_readl(xhci, port_array[wIndex]);
if (link_state == USB_SS_PORT_LS_U3)
bus_state->suspended_ports |= 1 << wIndex;
break;
case USB_PORT_FEAT_POWER: case USB_PORT_FEAT_POWER:
/* /*
* Turn on ports, even if there isn't per-port switching. * Turn on ports, even if there isn't per-port switching.
...@@ -557,6 +624,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -557,6 +624,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_readl(xhci, port_array[wIndex]); temp = xhci_readl(xhci, port_array[wIndex]);
xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp); xhci_dbg(xhci, "set port reset, actual port %d status = 0x%x\n", wIndex, temp);
break; break;
case USB_PORT_FEAT_BH_PORT_RESET:
temp |= PORT_WR;
xhci_writel(xhci, temp, port_array[wIndex]);
temp = xhci_readl(xhci, port_array[wIndex]);
break;
default: default:
goto error; goto error;
} }
...@@ -584,14 +657,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -584,14 +657,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
if (temp & XDEV_U3) { if (temp & XDEV_U3) {
if ((temp & PORT_PE) == 0) if ((temp & PORT_PE) == 0)
goto error; goto error;
if (DEV_SUPERSPEED(temp)) {
temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | XDEV_U0;
xhci_writel(xhci, temp,
port_array[wIndex]);
xhci_readl(xhci, port_array[wIndex]);
} else {
temp = xhci_port_state_to_neutral(temp); temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK; temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | XDEV_RESUME; temp |= PORT_LINK_STROBE | XDEV_RESUME;
...@@ -612,7 +678,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -612,7 +678,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
port_array[wIndex]); port_array[wIndex]);
} }
bus_state->port_c_suspend |= 1 << wIndex; bus_state->port_c_suspend |= 1 << wIndex;
}
slot_id = xhci_find_slot_id_by_port(hcd, xhci, slot_id = xhci_find_slot_id_by_port(hcd, xhci,
wIndex + 1); wIndex + 1);
...@@ -625,9 +690,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, ...@@ -625,9 +690,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
case USB_PORT_FEAT_C_SUSPEND: case USB_PORT_FEAT_C_SUSPEND:
bus_state->port_c_suspend &= ~(1 << wIndex); bus_state->port_c_suspend &= ~(1 << wIndex);
case USB_PORT_FEAT_C_RESET: case USB_PORT_FEAT_C_RESET:
case USB_PORT_FEAT_C_BH_PORT_RESET:
case USB_PORT_FEAT_C_CONNECTION: case USB_PORT_FEAT_C_CONNECTION:
case USB_PORT_FEAT_C_OVER_CURRENT: case USB_PORT_FEAT_C_OVER_CURRENT:
case USB_PORT_FEAT_C_ENABLE: case USB_PORT_FEAT_C_ENABLE:
case USB_PORT_FEAT_C_PORT_LINK_STATE:
xhci_clear_port_change_bit(xhci, wValue, wIndex, xhci_clear_port_change_bit(xhci, wValue, wIndex,
port_array[wIndex], temp); port_array[wIndex], temp);
break; break;
...@@ -664,7 +731,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) ...@@ -664,7 +731,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
int i, retval; int i, retval;
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int ports; int ports;
u32 __iomem **port_array; __le32 __iomem **port_array;
struct xhci_bus_state *bus_state; struct xhci_bus_state *bus_state;
if (hcd->speed == HCD_USB3) { if (hcd->speed == HCD_USB3) {
...@@ -681,7 +748,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf) ...@@ -681,7 +748,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
memset(buf, 0, retval); memset(buf, 0, retval);
status = 0; status = 0;
mask = PORT_CSC | PORT_PEC | PORT_OCC; mask = PORT_CSC | PORT_PEC | PORT_OCC | PORT_PLC;
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
/* For each port, did anything change? If so, set that bit in buf. */ /* For each port, did anything change? If so, set that bit in buf. */
...@@ -709,7 +776,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) ...@@ -709,7 +776,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
{ {
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int max_ports, port_index; int max_ports, port_index;
u32 __iomem **port_array; __le32 __iomem **port_array;
struct xhci_bus_state *bus_state; struct xhci_bus_state *bus_state;
unsigned long flags; unsigned long flags;
...@@ -779,7 +846,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) ...@@ -779,7 +846,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
if (DEV_HIGHSPEED(t1)) { if (DEV_HIGHSPEED(t1)) {
/* enable remote wake up for USB 2.0 */ /* enable remote wake up for USB 2.0 */
u32 __iomem *addr; __le32 __iomem *addr;
u32 tmp; u32 tmp;
/* Add one to the port status register address to get /* Add one to the port status register address to get
...@@ -801,7 +868,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) ...@@ -801,7 +868,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
{ {
struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int max_ports, port_index; int max_ports, port_index;
u32 __iomem **port_array; __le32 __iomem **port_array;
struct xhci_bus_state *bus_state; struct xhci_bus_state *bus_state;
u32 temp; u32 temp;
unsigned long flags; unsigned long flags;
...@@ -875,7 +942,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) ...@@ -875,7 +942,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
if (DEV_HIGHSPEED(temp)) { if (DEV_HIGHSPEED(temp)) {
/* disable remote wake up for USB 2.0 */ /* disable remote wake up for USB 2.0 */
u32 __iomem *addr; __le32 __iomem *addr;
u32 tmp; u32 tmp;
/* Add one to the port status register address to get /* Add one to the port status register address to get
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -57,13 +57,13 @@ ...@@ -57,13 +57,13 @@
* @run_regs_off: RTSOFF - Runtime register space offset * @run_regs_off: RTSOFF - Runtime register space offset
*/ */
struct xhci_cap_regs { struct xhci_cap_regs {
u32 hc_capbase; __le32 hc_capbase;
u32 hcs_params1; __le32 hcs_params1;
u32 hcs_params2; __le32 hcs_params2;
u32 hcs_params3; __le32 hcs_params3;
u32 hcc_params; __le32 hcc_params;
u32 db_off; __le32 db_off;
u32 run_regs_off; __le32 run_regs_off;
/* Reserved up to (CAPLENGTH - 0x1C) */ /* Reserved up to (CAPLENGTH - 0x1C) */
}; };
...@@ -155,26 +155,26 @@ struct xhci_cap_regs { ...@@ -155,26 +155,26 @@ struct xhci_cap_regs {
* devices. * devices.
*/ */
struct xhci_op_regs { struct xhci_op_regs {
u32 command; __le32 command;
u32 status; __le32 status;
u32 page_size; __le32 page_size;
u32 reserved1; __le32 reserved1;
u32 reserved2; __le32 reserved2;
u32 dev_notification; __le32 dev_notification;
u64 cmd_ring; __le64 cmd_ring;
/* rsvd: offset 0x20-2F */ /* rsvd: offset 0x20-2F */
u32 reserved3[4]; __le32 reserved3[4];
u64 dcbaa_ptr; __le64 dcbaa_ptr;
u32 config_reg; __le32 config_reg;
/* rsvd: offset 0x3C-3FF */ /* rsvd: offset 0x3C-3FF */
u32 reserved4[241]; __le32 reserved4[241];
/* port 1 registers, which serve as a base address for other ports */ /* port 1 registers, which serve as a base address for other ports */
u32 port_status_base; __le32 port_status_base;
u32 port_power_base; __le32 port_power_base;
u32 port_link_base; __le32 port_link_base;
u32 reserved5; __le32 reserved5;
/* registers for ports 2-255 */ /* registers for ports 2-255 */
u32 reserved6[NUM_PORT_REGS*254]; __le32 reserved6[NUM_PORT_REGS*254];
}; };
/* USBCMD - USB command - command bitmasks */ /* USBCMD - USB command - command bitmasks */
...@@ -382,12 +382,12 @@ struct xhci_op_regs { ...@@ -382,12 +382,12 @@ struct xhci_op_regs {
* updates the dequeue pointer. * updates the dequeue pointer.
*/ */
struct xhci_intr_reg { struct xhci_intr_reg {
u32 irq_pending; __le32 irq_pending;
u32 irq_control; __le32 irq_control;
u32 erst_size; __le32 erst_size;
u32 rsvd; __le32 rsvd;
u64 erst_base; __le64 erst_base;
u64 erst_dequeue; __le64 erst_dequeue;
}; };
/* irq_pending bitmasks */ /* irq_pending bitmasks */
...@@ -432,8 +432,8 @@ struct xhci_intr_reg { ...@@ -432,8 +432,8 @@ struct xhci_intr_reg {
* or larger accesses" * or larger accesses"
*/ */
struct xhci_run_regs { struct xhci_run_regs {
u32 microframe_index; __le32 microframe_index;
u32 rsvd[7]; __le32 rsvd[7];
struct xhci_intr_reg ir_set[128]; struct xhci_intr_reg ir_set[128];
}; };
...@@ -447,7 +447,7 @@ struct xhci_run_regs { ...@@ -447,7 +447,7 @@ struct xhci_run_regs {
* Section 5.6 * Section 5.6
*/ */
struct xhci_doorbell_array { struct xhci_doorbell_array {
u32 doorbell[256]; __le32 doorbell[256];
}; };
#define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16)) #define DB_VALUE(ep, stream) ((((ep) + 1) & 0xff) | ((stream) << 16))
...@@ -504,12 +504,12 @@ struct xhci_container_ctx { ...@@ -504,12 +504,12 @@ struct xhci_container_ctx {
* reserved at the end of the slot context for HC internal use. * reserved at the end of the slot context for HC internal use.
*/ */
struct xhci_slot_ctx { struct xhci_slot_ctx {
u32 dev_info; __le32 dev_info;
u32 dev_info2; __le32 dev_info2;
u32 tt_info; __le32 tt_info;
u32 dev_state; __le32 dev_state;
/* offset 0x10 to 0x1f reserved for HC internal use */ /* offset 0x10 to 0x1f reserved for HC internal use */
u32 reserved[4]; __le32 reserved[4];
}; };
/* dev_info bitmasks */ /* dev_info bitmasks */
...@@ -580,12 +580,12 @@ struct xhci_slot_ctx { ...@@ -580,12 +580,12 @@ struct xhci_slot_ctx {
* reserved at the end of the endpoint context for HC internal use. * reserved at the end of the endpoint context for HC internal use.
*/ */
struct xhci_ep_ctx { struct xhci_ep_ctx {
u32 ep_info; __le32 ep_info;
u32 ep_info2; __le32 ep_info2;
u64 deq; __le64 deq;
u32 tx_info; __le32 tx_info;
/* offset 0x14 - 0x1f reserved for HC internal use */ /* offset 0x14 - 0x1f reserved for HC internal use */
u32 reserved[3]; __le32 reserved[3];
}; };
/* ep_info bitmasks */ /* ep_info bitmasks */
...@@ -660,9 +660,9 @@ struct xhci_ep_ctx { ...@@ -660,9 +660,9 @@ struct xhci_ep_ctx {
* @add_context: set the bit of the endpoint context you want to enable * @add_context: set the bit of the endpoint context you want to enable
*/ */
struct xhci_input_control_ctx { struct xhci_input_control_ctx {
u32 drop_flags; __le32 drop_flags;
u32 add_flags; __le32 add_flags;
u32 rsvd2[6]; __le32 rsvd2[6];
}; };
/* Represents everything that is needed to issue a command on the command ring. /* Represents everything that is needed to issue a command on the command ring.
...@@ -688,9 +688,9 @@ struct xhci_command { ...@@ -688,9 +688,9 @@ struct xhci_command {
struct xhci_stream_ctx { struct xhci_stream_ctx {
/* 64-bit stream ring address, cycle state, and stream type */ /* 64-bit stream ring address, cycle state, and stream type */
u64 stream_ring; __le64 stream_ring;
/* offset 0x14 - 0x1f reserved for HC internal use */ /* offset 0x14 - 0x1f reserved for HC internal use */
u32 reserved[2]; __le32 reserved[2];
}; };
/* Stream Context Types (section 6.4.1) - bits 3:1 of stream ctx deq ptr */ /* Stream Context Types (section 6.4.1) - bits 3:1 of stream ctx deq ptr */
...@@ -803,7 +803,7 @@ struct xhci_virt_device { ...@@ -803,7 +803,7 @@ struct xhci_virt_device {
*/ */
struct xhci_device_context_array { struct xhci_device_context_array {
/* 64-bit device addresses; we only write 32-bit addresses */ /* 64-bit device addresses; we only write 32-bit addresses */
u64 dev_context_ptrs[MAX_HC_SLOTS]; __le64 dev_context_ptrs[MAX_HC_SLOTS];
/* private xHCD pointers */ /* private xHCD pointers */
dma_addr_t dma; dma_addr_t dma;
}; };
...@@ -816,10 +816,10 @@ struct xhci_device_context_array { ...@@ -816,10 +816,10 @@ struct xhci_device_context_array {
struct xhci_transfer_event { struct xhci_transfer_event {
/* 64-bit buffer address, or immediate data */ /* 64-bit buffer address, or immediate data */
u64 buffer; __le64 buffer;
u32 transfer_len; __le32 transfer_len;
/* This field is interpreted differently based on the type of TRB */ /* This field is interpreted differently based on the type of TRB */
u32 flags; __le32 flags;
}; };
/** Transfer Event bit fields **/ /** Transfer Event bit fields **/
...@@ -898,9 +898,9 @@ struct xhci_transfer_event { ...@@ -898,9 +898,9 @@ struct xhci_transfer_event {
struct xhci_link_trb { struct xhci_link_trb {
/* 64-bit segment pointer*/ /* 64-bit segment pointer*/
u64 segment_ptr; __le64 segment_ptr;
u32 intr_target; __le32 intr_target;
u32 control; __le32 control;
}; };
/* control bitfields */ /* control bitfields */
...@@ -909,9 +909,9 @@ struct xhci_link_trb { ...@@ -909,9 +909,9 @@ struct xhci_link_trb {
/* Command completion event TRB */ /* Command completion event TRB */
struct xhci_event_cmd { struct xhci_event_cmd {
/* Pointer to command TRB, or the value passed by the event data trb */ /* Pointer to command TRB, or the value passed by the event data trb */
u64 cmd_trb; __le64 cmd_trb;
u32 status; __le32 status;
u32 flags; __le32 flags;
}; };
/* flags bitmasks */ /* flags bitmasks */
...@@ -943,6 +943,8 @@ struct xhci_event_cmd { ...@@ -943,6 +943,8 @@ struct xhci_event_cmd {
/* Interrupter Target - which MSI-X vector to target the completion event at */ /* Interrupter Target - which MSI-X vector to target the completion event at */
#define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22)
#define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff)
#define TRB_TBC(p) (((p) & 0x3) << 7)
#define TRB_TLBPC(p) (((p) & 0xf) << 16)
/* Cycle bit - indicates TRB ownership by HC or HCD */ /* Cycle bit - indicates TRB ownership by HC or HCD */
#define TRB_CYCLE (1<<0) #define TRB_CYCLE (1<<0)
...@@ -970,7 +972,7 @@ struct xhci_event_cmd { ...@@ -970,7 +972,7 @@ struct xhci_event_cmd {
#define TRB_SIA (1<<31) #define TRB_SIA (1<<31)
struct xhci_generic_trb { struct xhci_generic_trb {
u32 field[4]; __le32 field[4];
}; };
union xhci_trb { union xhci_trb {
...@@ -1118,10 +1120,10 @@ struct xhci_ring { ...@@ -1118,10 +1120,10 @@ struct xhci_ring {
struct xhci_erst_entry { struct xhci_erst_entry {
/* 64-bit event ring segment address */ /* 64-bit event ring segment address */
u64 seg_addr; __le64 seg_addr;
u32 seg_size; __le32 seg_size;
/* Set to zero */ /* Set to zero */
u32 rsvd; __le32 rsvd;
}; };
struct xhci_erst { struct xhci_erst {
...@@ -1286,10 +1288,10 @@ struct xhci_hcd { ...@@ -1286,10 +1288,10 @@ struct xhci_hcd {
/* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */
u8 *port_array; u8 *port_array;
/* Array of pointers to USB 3.0 PORTSC registers */ /* Array of pointers to USB 3.0 PORTSC registers */
u32 __iomem **usb3_ports; __le32 __iomem **usb3_ports;
unsigned int num_usb3_ports; unsigned int num_usb3_ports;
/* Array of pointers to USB 2.0 PORTSC registers */ /* Array of pointers to USB 2.0 PORTSC registers */
u32 __iomem **usb2_ports; __le32 __iomem **usb2_ports;
unsigned int num_usb2_ports; unsigned int num_usb2_ports;
}; };
...@@ -1322,12 +1324,12 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) ...@@ -1322,12 +1324,12 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
/* TODO: copied from ehci.h - can be refactored? */ /* TODO: copied from ehci.h - can be refactored? */
/* xHCI spec says all registers are little endian */ /* xHCI spec says all registers are little endian */
static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, static inline unsigned int xhci_readl(const struct xhci_hcd *xhci,
__u32 __iomem *regs) __le32 __iomem *regs)
{ {
return readl(regs); return readl(regs);
} }
static inline void xhci_writel(struct xhci_hcd *xhci, static inline void xhci_writel(struct xhci_hcd *xhci,
const unsigned int val, __u32 __iomem *regs) const unsigned int val, __le32 __iomem *regs)
{ {
xhci_dbg(xhci, xhci_dbg(xhci,
"`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n",
...@@ -1345,7 +1347,7 @@ static inline void xhci_writel(struct xhci_hcd *xhci, ...@@ -1345,7 +1347,7 @@ static inline void xhci_writel(struct xhci_hcd *xhci,
* the high dword, and write order is irrelevant. * the high dword, and write order is irrelevant.
*/ */
static inline u64 xhci_read_64(const struct xhci_hcd *xhci, static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
__u64 __iomem *regs) __le64 __iomem *regs)
{ {
__u32 __iomem *ptr = (__u32 __iomem *) regs; __u32 __iomem *ptr = (__u32 __iomem *) regs;
u64 val_lo = readl(ptr); u64 val_lo = readl(ptr);
...@@ -1353,7 +1355,7 @@ static inline u64 xhci_read_64(const struct xhci_hcd *xhci, ...@@ -1353,7 +1355,7 @@ static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
return val_lo + (val_hi << 32); return val_lo + (val_hi << 32);
} }
static inline void xhci_write_64(struct xhci_hcd *xhci, static inline void xhci_write_64(struct xhci_hcd *xhci,
const u64 val, __u64 __iomem *regs) const u64 val, __le64 __iomem *regs)
{ {
__u32 __iomem *ptr = (__u32 __iomem *) regs; __u32 __iomem *ptr = (__u32 __iomem *) regs;
u32 val_lo = lower_32_bits(val); u32 val_lo = lower_32_bits(val);
......
...@@ -579,7 +579,7 @@ struct usb_ss_ep_comp_descriptor { ...@@ -579,7 +579,7 @@ struct usb_ss_ep_comp_descriptor {
__u8 bMaxBurst; __u8 bMaxBurst;
__u8 bmAttributes; __u8 bmAttributes;
__u16 wBytesPerInterval; __le16 wBytesPerInterval;
} __attribute__ ((packed)); } __attribute__ ((packed));
#define USB_DT_SS_EP_COMP_SIZE 6 #define USB_DT_SS_EP_COMP_SIZE 6
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment