summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/Kconfig5
-rw-r--r--drivers/usb/host/ehci-dbg.c161
-rw-r--r--drivers/usb/host/ehci-hcd.c10
-rw-r--r--drivers/usb/host/ehci-mem.c13
-rw-r--r--drivers/usb/host/ehci-q.c92
-rw-r--r--drivers/usb/host/ehci-sched.c248
-rw-r--r--drivers/usb/host/ehci.h205
7 files changed, 432 insertions, 302 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 62711870f8ee..a8faff646ac7 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -72,6 +72,11 @@ config USB_EHCI_BIG_ENDIAN_MMIO
depends on USB_EHCI_HCD
default n
+config USB_EHCI_BIG_ENDIAN_DESC
+ bool
+ depends on USB_EHCI_HCD
+ default n
+
config USB_ISP116X_HCD
tristate "ISP116X HCD support"
depends on USB
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 43eddaecc3dd..5bb3d0962ebe 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -52,7 +52,7 @@ static void dbg_hcs_params (struct ehci_hcd *ehci, char *label)
HCS_INDICATOR (params) ? " ind" : "",
HCS_N_CC (params),
HCS_N_PCC (params),
- HCS_PORTROUTED (params) ? "" : " ordered",
+ HCS_PORTROUTED (params) ? "" : " ordered",
HCS_PPC (params) ? "" : " !ppc",
HCS_N_PORTS (params)
);
@@ -91,20 +91,20 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label)
if (HCC_ISOC_CACHE (params)) {
ehci_dbg (ehci,
- "%s hcc_params %04x caching frame %s%s%s\n",
- label, params,
- HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
- HCC_CANPARK (params) ? " park" : "",
- HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+ "%s hcc_params %04x caching frame %s%s%s\n",
+ label, params,
+ HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+ HCC_CANPARK(params) ? " park" : "",
+ HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
} else {
ehci_dbg (ehci,
- "%s hcc_params %04x thresh %d uframes %s%s%s\n",
- label,
- params,
- HCC_ISOC_THRES (params),
- HCC_PGM_FRAMELISTLEN (params) ? "256/512/1024" : "1024",
- HCC_CANPARK (params) ? " park" : "",
- HCC_64BIT_ADDR (params) ? " 64 bit addr" : "");
+ "%s hcc_params %04x thresh %d uframes %s%s%s\n",
+ label,
+ params,
+ HCC_ISOC_THRES(params),
+ HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
+ HCC_CANPARK(params) ? " park" : "",
+ HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
}
}
#else
@@ -118,17 +118,17 @@ static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {}
static void __attribute__((__unused__))
dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
{
- ehci_dbg (ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
- le32_to_cpup (&qtd->hw_next),
- le32_to_cpup (&qtd->hw_alt_next),
- le32_to_cpup (&qtd->hw_token),
- le32_to_cpup (&qtd->hw_buf [0]));
+ ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+ hc32_to_cpup(ehci, &qtd->hw_next),
+ hc32_to_cpup(ehci, &qtd->hw_alt_next),
+ hc32_to_cpup(ehci, &qtd->hw_token),
+ hc32_to_cpup(ehci, &qtd->hw_buf [0]));
if (qtd->hw_buf [1])
- ehci_dbg (ehci, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
- le32_to_cpup (&qtd->hw_buf [1]),
- le32_to_cpup (&qtd->hw_buf [2]),
- le32_to_cpup (&qtd->hw_buf [3]),
- le32_to_cpup (&qtd->hw_buf [4]));
+ ehci_dbg(ehci, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
+ hc32_to_cpup(ehci, &qtd->hw_buf[1]),
+ hc32_to_cpup(ehci, &qtd->hw_buf[2]),
+ hc32_to_cpup(ehci, &qtd->hw_buf[3]),
+ hc32_to_cpup(ehci, &qtd->hw_buf[4]));
}
static void __attribute__((__unused__))
@@ -144,26 +144,27 @@ static void __attribute__((__unused__))
dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
{
ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n",
- label, itd->frame, itd, le32_to_cpu(itd->hw_next), itd->urb);
+ label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
+ itd->urb);
ehci_dbg (ehci,
" trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
- le32_to_cpu(itd->hw_transaction[0]),
- le32_to_cpu(itd->hw_transaction[1]),
- le32_to_cpu(itd->hw_transaction[2]),
- le32_to_cpu(itd->hw_transaction[3]),
- le32_to_cpu(itd->hw_transaction[4]),
- le32_to_cpu(itd->hw_transaction[5]),
- le32_to_cpu(itd->hw_transaction[6]),
- le32_to_cpu(itd->hw_transaction[7]));
+ hc32_to_cpu(ehci, itd->hw_transaction[0]),
+ hc32_to_cpu(ehci, itd->hw_transaction[1]),
+ hc32_to_cpu(ehci, itd->hw_transaction[2]),
+ hc32_to_cpu(ehci, itd->hw_transaction[3]),
+ hc32_to_cpu(ehci, itd->hw_transaction[4]),
+ hc32_to_cpu(ehci, itd->hw_transaction[5]),
+ hc32_to_cpu(ehci, itd->hw_transaction[6]),
+ hc32_to_cpu(ehci, itd->hw_transaction[7]));
ehci_dbg (ehci,
" buf: %08x %08x %08x %08x %08x %08x %08x\n",
- le32_to_cpu(itd->hw_bufp[0]),
- le32_to_cpu(itd->hw_bufp[1]),
- le32_to_cpu(itd->hw_bufp[2]),
- le32_to_cpu(itd->hw_bufp[3]),
- le32_to_cpu(itd->hw_bufp[4]),
- le32_to_cpu(itd->hw_bufp[5]),
- le32_to_cpu(itd->hw_bufp[6]));
+ hc32_to_cpu(ehci, itd->hw_bufp[0]),
+ hc32_to_cpu(ehci, itd->hw_bufp[1]),
+ hc32_to_cpu(ehci, itd->hw_bufp[2]),
+ hc32_to_cpu(ehci, itd->hw_bufp[3]),
+ hc32_to_cpu(ehci, itd->hw_bufp[4]),
+ hc32_to_cpu(ehci, itd->hw_bufp[5]),
+ hc32_to_cpu(ehci, itd->hw_bufp[6]));
ehci_dbg (ehci, " index: %d %d %d %d %d %d %d %d\n",
itd->index[0], itd->index[1], itd->index[2],
itd->index[3], itd->index[4], itd->index[5],
@@ -174,14 +175,15 @@ static void __attribute__((__unused__))
dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
{
ehci_dbg (ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
- label, sitd->frame, sitd, le32_to_cpu(sitd->hw_next), sitd->urb);
+ label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
+ sitd->urb);
ehci_dbg (ehci,
" addr %08x sched %04x result %08x buf %08x %08x\n",
- le32_to_cpu(sitd->hw_fullspeed_ep),
- le32_to_cpu(sitd->hw_uframe),
- le32_to_cpu(sitd->hw_results),
- le32_to_cpu(sitd->hw_buf [0]),
- le32_to_cpu(sitd->hw_buf [1]));
+ hc32_to_cpu(ehci, sitd->hw_fullspeed_ep),
+ hc32_to_cpu(ehci, sitd->hw_uframe),
+ hc32_to_cpu(ehci, sitd->hw_results),
+ hc32_to_cpu(ehci, sitd->hw_buf[0]),
+ hc32_to_cpu(ehci, sitd->hw_buf[1]));
}
static int __attribute__((__unused__))
@@ -267,8 +269,7 @@ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status)
(status & PORT_PEC) ? " PEC" : "",
(status & PORT_PE) ? " PE" : "",
(status & PORT_CSC) ? " CSC" : "",
- (status & PORT_CONNECT) ? " CONNECT" : ""
- );
+ (status & PORT_CONNECT) ? " CONNECT" : "");
}
#else
@@ -332,9 +333,10 @@ static inline void remove_debug_files (struct ehci_hcd *bus) { }
default: tmp = '?'; break; \
}; tmp; })
-static inline char token_mark (__le32 token)
+static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
{
- __u32 v = le32_to_cpu (token);
+ __u32 v = hc32_to_cpu(ehci, token);
+
if (v & QTD_STS_ACTIVE)
return '*';
if (v & QTD_STS_HALT)
@@ -360,46 +362,48 @@ static void qh_lines (
unsigned size = *sizep;
char *next = *nextp;
char mark;
+ u32 list_end = EHCI_LIST_END(ehci);
- if (qh->hw_qtd_next == EHCI_LIST_END) /* NEC does this */
+ if (qh->hw_qtd_next == list_end) /* NEC does this */
mark = '@';
else
- mark = token_mark (qh->hw_token);
+ mark = token_mark(ehci, qh->hw_token);
if (mark == '/') { /* qh_alt_next controls qh advance? */
- if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
+ if ((qh->hw_alt_next & QTD_MASK(ehci))
+ == ehci->async->hw_alt_next)
mark = '#'; /* blocked */
- else if (qh->hw_alt_next == EHCI_LIST_END)
+ else if (qh->hw_alt_next == list_end)
mark = '.'; /* use hw_qtd_next */
/* else alt_next points to some other qtd */
}
- scratch = le32_to_cpup (&qh->hw_info1);
- hw_curr = (mark == '*') ? le32_to_cpup (&qh->hw_current) : 0;
+ scratch = hc32_to_cpup(ehci, &qh->hw_info1);
+ hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &qh->hw_current) : 0;
temp = scnprintf (next, size,
"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)",
qh, scratch & 0x007f,
speed_char (scratch),
(scratch >> 8) & 0x000f,
- scratch, le32_to_cpup (&qh->hw_info2),
- le32_to_cpup (&qh->hw_token), mark,
- (__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token)
+ scratch, hc32_to_cpup(ehci, &qh->hw_info2),
+ hc32_to_cpup(ehci, &qh->hw_token), mark,
+ (cpu_to_hc32(ehci, QTD_TOGGLE) & qh->hw_token)
? "data1" : "data0",
- (le32_to_cpup (&qh->hw_alt_next) >> 1) & 0x0f);
+ (hc32_to_cpup(ehci, &qh->hw_alt_next) >> 1) & 0x0f);
size -= temp;
next += temp;
/* hc may be modifying the list as we read it ... */
list_for_each (entry, &qh->qtd_list) {
td = list_entry (entry, struct ehci_qtd, qtd_list);
- scratch = le32_to_cpup (&td->hw_token);
+ scratch = hc32_to_cpup(ehci, &td->hw_token);
mark = ' ';
if (hw_curr == td->qtd_dma)
mark = '*';
- else if (qh->hw_qtd_next == cpu_to_le32(td->qtd_dma))
+ else if (qh->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma))
mark = '+';
else if (QTD_LENGTH (scratch)) {
if (td->hw_alt_next == ehci->async->hw_alt_next)
mark = '#';
- else if (td->hw_alt_next != EHCI_LIST_END)
+ else if (td->hw_alt_next != list_end)
mark = '/';
}
temp = snprintf (next, size,
@@ -490,7 +494,7 @@ show_periodic (struct class_device *class_dev, char *buf)
unsigned temp, size, seen_count;
char *next;
unsigned i;
- __le32 tag;
+ __hc32 tag;
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC)))
return 0;
@@ -514,18 +518,19 @@ show_periodic (struct class_device *class_dev, char *buf)
p = ehci->pshadow [i];
if (likely (!p.ptr))
continue;
- tag = Q_NEXT_TYPE (ehci->periodic [i]);
+ tag = Q_NEXT_TYPE(ehci, ehci->periodic [i]);
temp = scnprintf (next, size, "%4d: ", i);
size -= temp;
next += temp;
do {
- switch (tag) {
+ switch (hc32_to_cpu(ehci, tag)) {
case Q_TYPE_QH:
temp = scnprintf (next, size, " qh%d-%04x/%p",
p.qh->period,
- le32_to_cpup (&p.qh->hw_info2)
+ hc32_to_cpup(ehci,
+ &p.qh->hw_info2)
/* uframe masks */
& (QH_CMASK | QH_SMASK),
p.qh);
@@ -543,7 +548,7 @@ show_periodic (struct class_device *class_dev, char *buf)
}
/* show more info the first time around */
if (temp == seen_count && p.ptr) {
- u32 scratch = le32_to_cpup (
+ u32 scratch = hc32_to_cpup(ehci,
&p.qh->hw_info1);
struct ehci_qtd *qtd;
char *type = "";
@@ -554,7 +559,8 @@ show_periodic (struct class_device *class_dev, char *buf)
&p.qh->qtd_list,
qtd_list) {
temp++;
- switch (0x03 & (le32_to_cpu (
+ switch (0x03 & (hc32_to_cpu(
+ ehci,
qtd->hw_token) >> 8)) {
case 0: type = "out"; continue;
case 1: type = "in"; continue;
@@ -576,7 +582,7 @@ show_periodic (struct class_device *class_dev, char *buf)
} else
temp = 0;
if (p.qh) {
- tag = Q_NEXT_TYPE (p.qh->hw_next);
+ tag = Q_NEXT_TYPE(ehci, p.qh->hw_next);
p = p.qh->qh_next;
}
break;
@@ -584,23 +590,23 @@ show_periodic (struct class_device *class_dev, char *buf)
temp = scnprintf (next, size,
" fstn-%8x/%p", p.fstn->hw_prev,
p.fstn);
- tag = Q_NEXT_TYPE (p.fstn->hw_next);
+ tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
p = p.fstn->fstn_next;
break;
case Q_TYPE_ITD:
temp = scnprintf (next, size,
" itd/%p", p.itd);
- tag = Q_NEXT_TYPE (p.itd->hw_next);
+ tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
p = p.itd->itd_next;
break;
case Q_TYPE_SITD:
temp = scnprintf (next, size,
" sitd%d-%04x/%p",
p.sitd->stream->interval,
- le32_to_cpup (&p.sitd->hw_uframe)
+ hc32_to_cpup(ehci, &p.sitd->hw_uframe)
& 0x0000ffff,
p.sitd);
- tag = Q_NEXT_TYPE (p.sitd->hw_next);
+ tag = Q_NEXT_TYPE(ehci, p.sitd->hw_next);
p = p.sitd->sitd_next;
break;
}
@@ -673,7 +679,8 @@ show_registers (struct class_device *class_dev, char *buf)
unsigned count = 256/4;
pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
- offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params));
+ offset = HCC_EXT_CAPS(ehci_readl(ehci,
+ &ehci->caps->hcc_params));
while (offset && count--) {
pci_read_config_dword (pdev, offset, &cap);
switch (cap & 0xff) {
@@ -740,14 +747,16 @@ show_registers (struct class_device *class_dev, char *buf)
for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) {
temp = dbg_port_buf (scratch, sizeof scratch, label, i,
- ehci_readl(ehci, &ehci->regs->port_status [i - 1]));
+ ehci_readl(ehci,
+ &ehci->regs->port_status[i - 1]));
temp = scnprintf (next, size, fmt, temp, scratch);
size -= temp;
next += temp;
if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
temp = scnprintf (next, size,
" debug control %08x\n",
- ehci_readl(ehci, &ehci->debug->control));
+ ehci_readl(ehci,
+ &ehci->debug->control));
size -= temp;
next += temp;
}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 566badb05b34..99ab31e9778b 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -526,12 +526,12 @@ static int ehci_init(struct usb_hcd *hcd)
* from automatically advancing to the next td after short reads.
*/
ehci->async->qh_next.qh = NULL;
- ehci->async->hw_next = QH_NEXT(ehci->async->qh_dma);
- ehci->async->hw_info1 = cpu_to_le32(QH_HEAD);
- ehci->async->hw_token = cpu_to_le32(QTD_STS_HALT);
- ehci->async->hw_qtd_next = EHCI_LIST_END;
+ ehci->async->hw_next = QH_NEXT(ehci, ehci->async->qh_dma);
+ ehci->async->hw_info1 = cpu_to_hc32(ehci, QH_HEAD);
+ ehci->async->hw_token = cpu_to_hc32(ehci, QTD_STS_HALT);
+ ehci->async->hw_qtd_next = EHCI_LIST_END(ehci);
ehci->async->qh_state = QH_STATE_LINKED;
- ehci->async->hw_alt_next = QTD_NEXT(ehci->async->dummy->qtd_dma);
+ ehci->async->hw_alt_next = QTD_NEXT(ehci, ehci->async->dummy->qtd_dma);
/* clear interrupt enables, set irq latency */
if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 5cff6bace5e5..bdb29e618058 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -27,7 +27,7 @@
* need to use dma_pool or dma_alloc_coherent
* - driver buffers, read/written by HC ... single shot DMA mapped
*
- * There's also PCI "register" data, which is memory mapped.
+ * There's also "register" data (e.g. PCI or SOC), which is memory mapped.
* No memory seen by this driver is pageable.
*/
@@ -35,13 +35,14 @@
/* Allocate the key transfer structures from the previously allocated pool */
-static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
+static inline void ehci_qtd_init(struct ehci_hcd *ehci, struct ehci_qtd *qtd,
+ dma_addr_t dma)
{
memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
- qtd->hw_next = EHCI_LIST_END;
- qtd->hw_alt_next = EHCI_LIST_END;
+ qtd->hw_next = EHCI_LIST_END(ehci);
+ qtd->hw_alt_next = EHCI_LIST_END(ehci);
INIT_LIST_HEAD (&qtd->qtd_list);
}
@@ -52,7 +53,7 @@ static struct ehci_qtd *ehci_qtd_alloc (struct ehci_hcd *ehci, gfp_t flags)
qtd = dma_pool_alloc (ehci->qtd_pool, flags, &dma);
if (qtd != NULL) {
- ehci_qtd_init (qtd, dma);
+ ehci_qtd_init(ehci, qtd, dma);
}
return qtd;
}
@@ -220,7 +221,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
goto fail;
}
for (i = 0; i < ehci->periodic_size; i++)
- ehci->periodic [i] = EHCI_LIST_END;
+ ehci->periodic [i] = EHCI_LIST_END(ehci);
/* software shadow of hardware table */
ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags);
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 903510beb299..2284028f8aa5 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -43,15 +43,15 @@
/* fill a qtd, returning how much of the buffer we were able to queue up */
static int
-qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
- int token, int maxpacket)
+qtd_fill(struct ehci_hcd *ehci, struct ehci_qtd *qtd, dma_addr_t buf,
+ size_t len, int token, int maxpacket)
{
int i, count;
u64 addr = buf;
/* one buffer entry per 4K ... first might be short or unaligned */
- qtd->hw_buf [0] = cpu_to_le32 ((u32)addr);
- qtd->hw_buf_hi [0] = cpu_to_le32 ((u32)(addr >> 32));
+ qtd->hw_buf[0] = cpu_to_hc32(ehci, (u32)addr);
+ qtd->hw_buf_hi[0] = cpu_to_hc32(ehci, (u32)(addr >> 32));
count = 0x1000 - (buf & 0x0fff); /* rest of that page */
if (likely (len < count)) /* ... iff needed */
count = len;
@@ -62,8 +62,9 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
/* per-qtd limit: from 16K to 20K (best alignment) */
for (i = 1; count < len && i < 5; i++) {
addr = buf;
- qtd->hw_buf [i] = cpu_to_le32 ((u32)addr);
- qtd->hw_buf_hi [i] = cpu_to_le32 ((u32)(addr >> 32));
+ qtd->hw_buf[i] = cpu_to_hc32(ehci, (u32)addr);
+ qtd->hw_buf_hi[i] = cpu_to_hc32(ehci,
+ (u32)(addr >> 32));
buf += 0x1000;
if ((count + 0x1000) < len)
count += 0x1000;
@@ -75,7 +76,7 @@ qtd_fill (struct ehci_qtd *qtd, dma_addr_t buf, size_t len,
if (count != len)
count -= (count % maxpacket);
}
- qtd->hw_token = cpu_to_le32 ((count << 16) | token);
+ qtd->hw_token = cpu_to_hc32(ehci, (count << 16) | token);
qtd->length = count;
return count;
@@ -89,28 +90,28 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
/* writes to an active overlay are unsafe */
BUG_ON(qh->qh_state != QH_STATE_IDLE);
- qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
- qh->hw_alt_next = EHCI_LIST_END;
+ qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
+ qh->hw_alt_next = EHCI_LIST_END(ehci);
/* Except for control endpoints, we make hardware maintain data
* toggle (like OHCI) ... here (re)initialize the toggle in the QH,
* and set the pseudo-toggle in udev. Only usb_clear_halt() will
* ever clear it.
*/
- if (!(qh->hw_info1 & cpu_to_le32(1 << 14))) {
+ if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
unsigned is_out, epnum;
- is_out = !(qtd->hw_token & cpu_to_le32(1 << 8));
- epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f;
+ is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
+ epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
- qh->hw_token &= ~__constant_cpu_to_le32 (QTD_TOGGLE);
+ qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
usb_settoggle (qh->dev, epnum, is_out, 1);
}
}
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb ();
- qh->hw_token &= __constant_cpu_to_le32 (QTD_TOGGLE | QTD_STS_PING);
+ qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
}
/* if it weren't for a common silicon quirk (writing the dummy into the qh
@@ -128,7 +129,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
qtd = list_entry (qh->qtd_list.next,
struct ehci_qtd, qtd_list);
/* first qtd may already be partially processed */
- if (cpu_to_le32 (qtd->qtd_dma) == qh->hw_current)
+ if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw_current)
qtd = NULL;
}
@@ -222,7 +223,7 @@ __acquires(ehci->lock)
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
/* S-mask in a QH means it's an interrupt urb */
- if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) {
+ if ((qh->hw_info2 & cpu_to_hc32(ehci, QH_SMASK)) != 0) {
/* ... update hc-wide periodic stats (for usbfs) */
ehci_to_hcd(ehci)->self.bandwidth_int_reqs--;
@@ -277,7 +278,6 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
* Chases up to qh->hw_current. Returns number of completions called,
* indicating how much "real" work we did.
*/
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
static unsigned
qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
@@ -287,6 +287,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
unsigned count = 0;
int do_status = 0;
u8 state;
+ u32 halt = HALT_BIT(ehci);
if (unlikely (list_empty (&qh->qtd_list)))
return count;
@@ -334,7 +335,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* hardware copies qtd out of qh overlay */
rmb ();
- token = le32_to_cpu (qtd->hw_token);
+ token = hc32_to_cpu(ehci, qtd->hw_token);
/* always clean up qtds the hc de-activated */
if ((token & QTD_STS_ACTIVE) == 0) {
@@ -346,7 +347,8 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
* that silicon quirk can kick in with this dummy too.
*/
} else if (IS_SHORT_READ (token)
- && !(qtd->hw_alt_next & EHCI_LIST_END)) {
+ && !(qtd->hw_alt_next
+ & EHCI_LIST_END(ehci))) {
stopped = 1;
goto halt;
}
@@ -378,17 +380,17 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* token in overlay may be most current */
if (state == QH_STATE_IDLE
- && cpu_to_le32 (qtd->qtd_dma)
+ && cpu_to_hc32(ehci, qtd->qtd_dma)
== qh->hw_current)
- token = le32_to_cpu (qh->hw_token);
+ token = hc32_to_cpu(ehci, qh->hw_token);
/* force halt for unlinked or blocked qh, so we'll
* patch the qh later and so that completions can't
* activate it while we "know" it's stopped.
*/
- if ((HALT_BIT & qh->hw_token) == 0) {
+ if ((halt & qh->hw_token) == 0) {
halt:
- qh->hw_token |= HALT_BIT;
+ qh->hw_token |= halt;
wmb ();
}
}
@@ -423,7 +425,7 @@ halt:
* it after fault cleanup, or recovering from silicon wrongly
* overlaying the dummy qtd (which reduces DMA chatter).
*/
- if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END) {
+ if (stopped != 0 || qh->hw_qtd_next == EHCI_LIST_END(ehci)) {
switch (state) {
case QH_STATE_IDLE:
qh_refresh(ehci, qh);
@@ -432,7 +434,7 @@ halt:
/* should be rare for periodic transfers,
* except maybe high bandwidth ...
*/
- if ((__constant_cpu_to_le32 (QH_SMASK)
+ if ((cpu_to_hc32(ehci, QH_SMASK)
& qh->hw_info2) != 0) {
intr_deschedule (ehci, qh);
(void) qh_schedule (ehci, qh);
@@ -506,8 +508,9 @@ qh_urb_transaction (
is_input = usb_pipein (urb->pipe);
if (usb_pipecontrol (urb->pipe)) {
/* SETUP pid */
- qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
- token | (2 /* "setup" */ << 8), 8);
+ qtd_fill(ehci, qtd, urb->setup_dma,
+ sizeof (struct usb_ctrlrequest),
+ token | (2 /* "setup" */ << 8), 8);
/* ... and always at least one more pid */
token ^= QTD_TOGGLE;
@@ -516,7 +519,7 @@ qh_urb_transaction (
if (unlikely (!qtd))
goto cleanup;
qtd->urb = urb;
- qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+ qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
list_add_tail (&qtd->qtd_list, head);
/* for zero length DATA stages, STATUS is always IN */
@@ -543,7 +546,7 @@ qh_urb_transaction (
for (;;) {
int this_qtd_len;
- this_qtd_len = qtd_fill (qtd, buf, len, token, maxpacket);
+ this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket);
len -= this_qtd_len;
buf += this_qtd_len;
if (is_input)
@@ -561,7 +564,7 @@ qh_urb_transaction (
if (unlikely (!qtd))
goto cleanup;
qtd->urb = urb;
- qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+ qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
list_add_tail (&qtd->qtd_list, head);
}
@@ -570,7 +573,7 @@ qh_urb_transaction (
*/
if (likely ((urb->transfer_flags & URB_SHORT_NOT_OK) == 0
|| usb_pipecontrol (urb->pipe)))
- qtd->hw_alt_next = EHCI_LIST_END;
+ qtd->hw_alt_next = EHCI_LIST_END(ehci);
/*
* control requests may need a terminating data "status" ack;
@@ -594,17 +597,17 @@ qh_urb_transaction (
if (unlikely (!qtd))
goto cleanup;
qtd->urb = urb;
- qtd_prev->hw_next = QTD_NEXT (qtd->qtd_dma);
+ qtd_prev->hw_next = QTD_NEXT(ehci, qtd->qtd_dma);
list_add_tail (&qtd->qtd_list, head);
/* never any data in such packets */
- qtd_fill (qtd, 0, 0, token, 0);
+ qtd_fill(ehci, qtd, 0, 0, token, 0);
}
}
/* by default, enable interrupt on urb completion */
if (likely (!(urb->transfer_flags & URB_NO_INTERRUPT)))
- qtd->hw_token |= __constant_cpu_to_le32 (QTD_IOC);
+ qtd->hw_token |= cpu_to_hc32(ehci, QTD_IOC);
return head;
cleanup:
@@ -773,8 +776,8 @@ done:
/* init as live, toggle clear, advance to dummy */
qh->qh_state = QH_STATE_IDLE;
- qh->hw_info1 = cpu_to_le32 (info1);
- qh->hw_info2 = cpu_to_le32 (info2);
+ qh->hw_info1 = cpu_to_hc32(ehci, info1);
+ qh->hw_info2 = cpu_to_hc32(ehci, info2);
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
qh_refresh (ehci, qh);
return qh;
@@ -786,7 +789,7 @@ done:
static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
- __le32 dma = QH_NEXT (qh->qh_dma);
+ __hc32 dma = QH_NEXT(ehci, qh->qh_dma);
struct ehci_qh *head;
/* (re)start the async schedule? */
@@ -824,8 +827,6 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
/*-------------------------------------------------------------------------*/
-#define QH_ADDR_MASK __constant_cpu_to_le32(0x7f)
-
/*
* For control/bulk/interrupt, return QH with these TDs appended.
* Allocates and initializes the QH if necessary.
@@ -841,6 +842,7 @@ static struct ehci_qh *qh_append_tds (
)
{
struct ehci_qh *qh = NULL;
+ u32 qh_addr_mask = cpu_to_hc32(ehci, 0x7f);
qh = (struct ehci_qh *) *ptr;
if (unlikely (qh == NULL)) {
@@ -862,7 +864,7 @@ static struct ehci_qh *qh_append_tds (
/* usb_reset_device() briefly reverts to address 0 */
if (usb_pipedevice (urb->pipe) == 0)
- qh->hw_info1 &= ~QH_ADDR_MASK;
+ qh->hw_info1 &= ~qh_addr_mask;
}
/* just one way to queue requests: swap with the dummy qtd.
@@ -871,7 +873,7 @@ static struct ehci_qh *qh_append_tds (
if (likely (qtd != NULL)) {
struct ehci_qtd *dummy;
dma_addr_t dma;
- __le32 token;
+ __hc32 token;
/* to avoid racing the HC, use the dummy td instead of
* the first td of our list (becomes new dummy). both
@@ -879,7 +881,7 @@ static struct ehci_qh *qh_append_tds (
* HC is allowed to fetch the old dummy (4.10.2).
*/
token = qtd->hw_token;
- qtd->hw_token = HALT_BIT;
+ qtd->hw_token = HALT_BIT(ehci);
wmb ();
dummy = qh->dummy;
@@ -891,14 +893,14 @@ static struct ehci_qh *qh_append_tds (
list_add (&dummy->qtd_list, qtd_list);
__list_splice (qtd_list, qh->qtd_list.prev);
- ehci_qtd_init (qtd, qtd->qtd_dma);
+ ehci_qtd_init(ehci, qtd, qtd->qtd_dma);
qh->dummy = qtd;
/* hc must see the new dummy at list end */
dma = qtd->qtd_dma;
qtd = list_entry (qh->qtd_list.prev,
struct ehci_qtd, qtd_list);
- qtd->hw_next = QTD_NEXT (dma);
+ qtd->hw_next = QTD_NEXT(ehci, dma);
/* let the hc process these next qtds */
wmb ();
@@ -974,7 +976,7 @@ static void end_unlink_async (struct ehci_hcd *ehci)
timer_action_done (ehci, TIMER_IAA_WATCHDOG);
- // qh->hw_next = cpu_to_le32 (qh->qh_dma);
+ // qh->hw_next = cpu_to_hc32(qh->qh_dma);
qh->qh_state = QH_STATE_IDLE;
qh->qh_next.qh = NULL;
qh_put (qh); // refcount from reclaim
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 500aebbaa741..d4a8ace49676 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -44,9 +44,10 @@ static int ehci_get_frame (struct usb_hcd *hcd);
* @tag: hardware tag for type of this record
*/
static union ehci_shadow *
-periodic_next_shadow (union ehci_shadow *periodic, __le32 tag)
+periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
+ __hc32 tag)
{
- switch (tag) {
+ switch (hc32_to_cpu(ehci, tag)) {
case Q_TYPE_QH:
return &periodic->qh->qh_next;
case Q_TYPE_FSTN:
@@ -62,13 +63,14 @@ periodic_next_shadow (union ehci_shadow *periodic, __le32 tag)
/* caller must hold ehci->lock */
static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
{
- union ehci_shadow *prev_p = &ehci->pshadow [frame];
- __le32 *hw_p = &ehci->periodic [frame];
+ union ehci_shadow *prev_p = &ehci->pshadow[frame];
+ __hc32 *hw_p = &ehci->periodic[frame];
union ehci_shadow here = *prev_p;
/* find predecessor of "ptr"; hw and shadow lists are in sync */
while (here.ptr && here.ptr != ptr) {
- prev_p = periodic_next_shadow (prev_p, Q_NEXT_TYPE (*hw_p));
+ prev_p = periodic_next_shadow(ehci, prev_p,
+ Q_NEXT_TYPE(ehci, *hw_p));
hw_p = here.hw_next;
here = *prev_p;
}
@@ -79,7 +81,8 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
/* update shadow and hardware lists ... the old "next" pointers
* from ptr may still be in use, the caller updates them.
*/
- *prev_p = *periodic_next_shadow (&here, Q_NEXT_TYPE (*hw_p));
+ *prev_p = *periodic_next_shadow(ehci, &here,
+ Q_NEXT_TYPE(ehci, *hw_p));
*hw_p = *here.hw_next;
}
@@ -87,18 +90,19 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
static unsigned short
periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
{
- __le32 *hw_p = &ehci->periodic [frame];
+ __hc32 *hw_p = &ehci->periodic [frame];
union ehci_shadow *q = &ehci->pshadow [frame];
unsigned usecs = 0;
while (q->ptr) {
- switch (Q_NEXT_TYPE (*hw_p)) {
+ switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
case Q_TYPE_QH:
/* is it in the S-mask? */
- if (q->qh->hw_info2 & cpu_to_le32 (1 << uframe))
+ if (q->qh->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
usecs += q->qh->usecs;
/* ... or C-mask? */
- if (q->qh->hw_info2 & cpu_to_le32 (1 << (8 + uframe)))
+ if (q->qh->hw_info2 & cpu_to_hc32(ehci,
+ 1 << (8 + uframe)))
usecs += q->qh->c_usecs;
hw_p = &q->qh->hw_next;
q = &q->qh->qh_next;
@@ -108,7 +112,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
/* for "save place" FSTNs, count the relevant INTR
* bandwidth from the previous frame
*/
- if (q->fstn->hw_prev != EHCI_LIST_END) {
+ if (q->fstn->hw_prev != EHCI_LIST_END(ehci)) {
ehci_dbg (ehci, "ignoring FSTN cost ...\n");
}
hw_p = &q->fstn->hw_next;
@@ -121,9 +125,10 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
break;
case Q_TYPE_SITD:
/* is it in the S-mask? (count SPLIT, DATA) */
- if (q->sitd->hw_uframe & cpu_to_le32 (1 << uframe)) {
+ if (q->sitd->hw_uframe & cpu_to_hc32(ehci,
+ 1 << uframe)) {
if (q->sitd->hw_fullspeed_ep &
- __constant_cpu_to_le32 (1<<31))
+ cpu_to_hc32(ehci, 1<<31))
usecs += q->sitd->stream->usecs;
else /* worst case for OUT start-split */
usecs += HS_USECS_ISO (188);
@@ -131,7 +136,7 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
/* ... C-mask? (count CSPLIT, DATA) */
if (q->sitd->hw_uframe &
- cpu_to_le32 (1 << (8 + uframe))) {
+ cpu_to_hc32(ehci, 1 << (8 + uframe))) {
/* worst case for IN complete-split */
usecs += q->sitd->stream->c_usecs;
}
@@ -173,9 +178,9 @@ static int same_tt (struct usb_device *dev1, struct usb_device *dev2)
* will cause a transfer in "B-frame" uframe 0. "B-frames" lag
* "H-frames" by 1 uframe. See the EHCI spec sec 4.5 and figure 4.7.
*/
-static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __le32 mask)
+static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
{
- unsigned char smask = QH_SMASK & le32_to_cpu(mask);
+ unsigned char smask = QH_SMASK & hc32_to_cpu(ehci, mask);
if (!smask) {
ehci_err(ehci, "invalid empty smask!\n");
/* uframe 7 can't have bw so this will indicate failure */
@@ -217,14 +222,14 @@ periodic_tt_usecs (
unsigned short tt_usecs[8]
)
{
- __le32 *hw_p = &ehci->periodic [frame];
+ __hc32 *hw_p = &ehci->periodic [frame];
union ehci_shadow *q = &ehci->pshadow [frame];
unsigned char uf;
memset(tt_usecs, 0, 16);
while (q->ptr) {
- switch (Q_NEXT_TYPE(*hw_p)) {
+ switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
case Q_TYPE_ITD:
hw_p = &q->itd->hw_next;
q = &q->itd->itd_next;
@@ -247,8 +252,8 @@ periodic_tt_usecs (
continue;
// case Q_TYPE_FSTN:
default:
- ehci_dbg(ehci,
- "ignoring periodic frame %d FSTN\n", frame);
+ ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n",
+ frame);
hw_p = &q->fstn->hw_next;
q = &q->fstn->fstn_next;
}
@@ -368,41 +373,42 @@ static int tt_no_collision (
*/
for (; frame < ehci->periodic_size; frame += period) {
union ehci_shadow here;
- __le32 type;
+ __hc32 type;
here = ehci->pshadow [frame];
- type = Q_NEXT_TYPE (ehci->periodic [frame]);
+ type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]);
while (here.ptr) {
- switch (type) {
+ switch (hc32_to_cpu(ehci, type)) {
case Q_TYPE_ITD:
- type = Q_NEXT_TYPE (here.itd->hw_next);
+ type = Q_NEXT_TYPE(ehci, here.itd->hw_next);
here = here.itd->itd_next;
continue;
case Q_TYPE_QH:
if (same_tt (dev, here.qh->dev)) {
u32 mask;
- mask = le32_to_cpu (here.qh->hw_info2);
+ mask = hc32_to_cpu(ehci,
+ here.qh->hw_info2);
/* "knows" no gap is needed */
mask |= mask >> 8;
if (mask & uf_mask)
break;
}
- type = Q_NEXT_TYPE (here.qh->hw_next);
+ type = Q_NEXT_TYPE(ehci, here.qh->hw_next);
here = here.qh->qh_next;
continue;
case Q_TYPE_SITD:
if (same_tt (dev, here.sitd->urb->dev)) {
u16 mask;
- mask = le32_to_cpu (here.sitd
+ mask = hc32_to_cpu(ehci, here.sitd
->hw_uframe);
/* FIXME assumes no gap for IN! */
mask |= mask >> 8;
if (mask & uf_mask)
break;
}
- type = Q_NEXT_TYPE (here.sitd->hw_next);
+ type = Q_NEXT_TYPE(ehci, here.sitd->hw_next);
here = here.sitd->sitd_next;
continue;
// case Q_TYPE_FSTN:
@@ -475,13 +481,6 @@ static int disable_periodic (struct ehci_hcd *ehci)
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_CPU_FREQ
-/* ignore/inactivate bit in QH hw_info1 */
-#define INACTIVATE_BIT __constant_cpu_to_le32(QH_INACTIVATE)
-
-#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
-#define ACTIVE_BIT __constant_cpu_to_le32(QTD_STS_ACTIVE)
-#define STATUS_BIT __constant_cpu_to_le32(QTD_STS_STS)
-
static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
{
int now; /* current (frame * 8) + uframe */
@@ -492,8 +491,8 @@ static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3);
- next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) %
- (qh->period << 3);
+ next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now)
+ % (qh->period << 3);
prev_start = (qh->period << 3) - next_start;
/*
@@ -510,7 +509,7 @@ static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh)
*/
if ((next_start > ehci->i_thresh) && (prev_start > 1))
/* safe to set "i" bit if split isn't in progress */
- return (qh->hw_token & STATUS_BIT) ? 0 : 1;
+ return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1;
else
return 0;
}
@@ -520,12 +519,14 @@ static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci)
{
struct ehci_qh *qh;
int not_done, safe;
+ u32 inactivate = INACTIVATE_BIT(ehci);
+ u32 active = ACTIVE_BIT(ehci);
do {
not_done = 0;
list_for_each_entry(qh, &ehci->split_intr_qhs,
- split_intr_qhs) {
- if (qh->hw_info1 & INACTIVATE_BIT)
+ split_intr_qhs) {
+ if (qh->hw_info1 & inactivate)
/* already off */
continue;
/*
@@ -539,8 +540,8 @@ static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci)
if (safe == 0) {
not_done = 1;
} else if (safe > 0) {
- qh->was_active = qh->hw_token & ACTIVE_BIT;
- qh->hw_info1 |= INACTIVATE_BIT;
+ qh->was_active = qh->hw_token & active;
+ qh->hw_info1 |= inactivate;
}
}
} while (not_done);
@@ -552,11 +553,14 @@ static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci)
struct ehci_qh *qh;
u32 token;
int not_done, safe;
+ u32 inactivate = INACTIVATE_BIT(ehci);
+ u32 active = ACTIVE_BIT(ehci);
+ u32 halt = HALT_BIT(ehci);
do {
not_done = 0;
list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) {
- if (!(qh->hw_info1 & INACTIVATE_BIT)) /* already on */
+ if (!(qh->hw_info1 & inactivate)) /* already on */
continue;
/*
* Don't reactivate if cached, or controller might
@@ -568,11 +572,11 @@ static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci)
} else if (safe > 0) {
/* See EHCI 1.0 section 4.15.2.4. */
token = qh->hw_token;
- qh->hw_token = (token | HALT_BIT) & ~ACTIVE_BIT;
+ qh->hw_token = (token | halt) & ~active;
wmb();
- qh->hw_info1 &= ~INACTIVATE_BIT;
+ qh->hw_info1 &= ~inactivate;
wmb();
- qh->hw_token = (token & ~HALT_BIT) | qh->was_active;
+ qh->hw_token = (token & ~halt) | qh->was_active;
}
}
} while (not_done);
@@ -592,7 +596,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
dev_dbg (&qh->dev->dev,
"link qh%d-%04x/%p start %d [%d/%d us]\n",
- period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+ period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
qh, qh->start, qh->usecs, qh->c_usecs);
#ifdef CONFIG_CPU_FREQ
@@ -603,7 +607,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
*/
if (ehci->cpufreq_changing)
if (!(qh->hw_info1 & (cpu_to_le32(1 << 13))))
- qh->hw_info1 |= INACTIVATE_BIT;
+ qh->hw_info1 |= INACTIVATE_BIT(ehci);
#endif
/* high bandwidth, or otherwise every microframe */
@@ -611,17 +615,17 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
period = 1;
for (i = qh->start; i < ehci->periodic_size; i += period) {
- union ehci_shadow *prev = &ehci->pshadow [i];
- __le32 *hw_p = &ehci->periodic [i];
+ union ehci_shadow *prev = &ehci->pshadow[i];
+ __hc32 *hw_p = &ehci->periodic[i];
union ehci_shadow here = *prev;
- __le32 type = 0;
+ __hc32 type = 0;
/* skip the iso nodes at list head */
while (here.ptr) {
- type = Q_NEXT_TYPE (*hw_p);
- if (type == Q_TYPE_QH)
+ type = Q_NEXT_TYPE(ehci, *hw_p);
+ if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
break;
- prev = periodic_next_shadow (prev, type);
+ prev = periodic_next_shadow(ehci, prev, type);
hw_p = &here.qh->hw_next;
here = *prev;
}
@@ -643,7 +647,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
qh->hw_next = *hw_p;
wmb ();
prev->qh = qh;
- *hw_p = QH_NEXT (qh->qh_dma);
+ *hw_p = QH_NEXT (ehci, qh->qh_dma);
}
}
qh->qh_state = QH_STATE_LINKED;
@@ -677,7 +681,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
// and this qh is active in the current uframe
// (and overlay token SplitXstate is false?)
// THEN
- // qh->hw_info1 |= __constant_cpu_to_le32 (1 << 7 /* "ignore" */);
+ // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */);
#ifdef CONFIG_CPU_FREQ
/* remove qh from list of low/full speed interrupt QHs */
@@ -701,7 +705,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
dev_dbg (&qh->dev->dev,
"unlink qh%d-%04x/%p start %d [%d/%d us]\n",
qh->period,
- le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK),
+ hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK),
qh, qh->start, qh->usecs, qh->c_usecs);
/* qh->qh_next still "live" to HC */
@@ -727,7 +731,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
* active high speed queues may need bigger delays...
*/
if (list_empty (&qh->qtd_list)
- || (__constant_cpu_to_le32 (QH_CMASK)
+ || (cpu_to_hc32(ehci, QH_CMASK)
& qh->hw_info2) != 0)
wait = 2;
else
@@ -735,7 +739,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
udelay (wait);
qh->qh_state = QH_STATE_IDLE;
- qh->hw_next = EHCI_LIST_END;
+ qh->hw_next = EHCI_LIST_END(ehci);
wmb ();
}
@@ -792,7 +796,7 @@ static int check_intr_schedule (
unsigned frame,
unsigned uframe,
const struct ehci_qh *qh,
- __le32 *c_maskp
+ __hc32 *c_maskp
)
{
int retval = -ENOSPC;
@@ -824,7 +828,7 @@ static int check_intr_schedule (
retval = 0;
- *c_maskp = cpu_to_le32 (mask << 8);
+ *c_maskp = cpu_to_hc32(ehci, mask << 8);
}
#else
/* Make sure this tt's buffer is also available for CSPLITs.
@@ -835,7 +839,7 @@ static int check_intr_schedule (
* one smart pass...
*/
mask = 0x03 << (uframe + qh->gap_uf);
- *c_maskp = cpu_to_le32 (mask << 8);
+ *c_maskp = cpu_to_hc32(ehci, mask << 8);
mask |= 1 << uframe;
if (tt_no_collision (ehci, qh->period, qh->dev, frame, mask)) {
@@ -855,20 +859,20 @@ done:
/* "first fit" scheduling policy used the first time through,
* or when the previous schedule slot can't be re-used.
*/
-static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
int status;
unsigned uframe;
- __le32 c_mask;
+ __hc32 c_mask;
unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
qh_refresh(ehci, qh);
- qh->hw_next = EHCI_LIST_END;
+ qh->hw_next = EHCI_LIST_END(ehci);
frame = qh->start;
/* reuse the previous schedule slots, if we can */
if (frame < qh->period) {
- uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK);
+ uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK);
status = check_intr_schedule (ehci, frame, --uframe,
qh, &c_mask);
} else {
@@ -904,10 +908,10 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
qh->start = frame;
/* reset S-frame and (maybe) C-frame masks */
- qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK));
+ qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
qh->hw_info2 |= qh->period
- ? cpu_to_le32 (1 << uframe)
- : __constant_cpu_to_le32 (QH_SMASK);
+ ? cpu_to_hc32(ehci, 1 << uframe)
+ : cpu_to_hc32(ehci, QH_SMASK);
qh->hw_info2 |= c_mask;
} else
ehci_dbg (ehci, "reused qh %p schedule\n", qh);
@@ -937,7 +941,7 @@ static int intr_submit (
spin_lock_irqsave (&ehci->lock, flags);
if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE,
- &ehci_to_hcd(ehci)->flags))) {
+ &ehci_to_hcd(ehci)->flags))) {
status = -ESHUTDOWN;
goto done;
}
@@ -1027,9 +1031,9 @@ iso_stream_init (
buf1 |= maxp;
maxp *= multi;
- stream->buf0 = cpu_to_le32 ((epnum << 8) | dev->devnum);
- stream->buf1 = cpu_to_le32 (buf1);
- stream->buf2 = cpu_to_le32 (multi);
+ stream->buf0 = cpu_to_hc32(ehci, (epnum << 8) | dev->devnum);
+ stream->buf1 = cpu_to_hc32(ehci, buf1);
+ stream->buf2 = cpu_to_hc32(ehci, multi);
/* usbfs wants to report the average usecs per frame tied up
* when transfers on this endpoint are scheduled ...
@@ -1072,7 +1076,7 @@ iso_stream_init (
bandwidth /= 1 << (interval + 2);
/* stream->splits gets created from raw_mask later */
- stream->address = cpu_to_le32 (addr);
+ stream->address = cpu_to_hc32(ehci, addr);
}
stream->bandwidth = bandwidth;
@@ -1206,7 +1210,8 @@ iso_sched_alloc (unsigned packets, gfp_t mem_flags)
}
static inline void
-itd_sched_init (
+itd_sched_init(
+ struct ehci_hcd *ehci,
struct ehci_iso_sched *iso_sched,
struct ehci_iso_stream *stream,
struct urb *urb
@@ -1236,7 +1241,7 @@ itd_sched_init (
&& !(urb->transfer_flags & URB_NO_INTERRUPT))
trans |= EHCI_ITD_IOC;
trans |= length << 16;
- uframe->transaction = cpu_to_le32 (trans);
+ uframe->transaction = cpu_to_hc32(ehci, trans);
/* might need to cross a buffer page within a uframe */
uframe->bufp = (buf & ~(u64)0x0fff);
@@ -1278,7 +1283,7 @@ itd_urb_transaction (
if (unlikely (sched == NULL))
return -ENOMEM;
- itd_sched_init (sched, stream, urb);
+ itd_sched_init(ehci, sched, stream, urb);
if (urb->interval < 8)
num_itds = 1 + (sched->span + 7) / 8;
@@ -1296,7 +1301,7 @@ itd_urb_transaction (
/* prefer previously-allocated itds */
if (likely (!list_empty(&stream->free_list))) {
itd = list_entry (stream->free_list.prev,
- struct ehci_itd, itd_list);
+ struct ehci_itd, itd_list);
list_del (&itd->itd_list);
itd_dma = itd->itd_dma;
} else
@@ -1423,7 +1428,7 @@ sitd_slot_ok (
uframe += period_uframes;
} while (uframe < mod);
- stream->splits = cpu_to_le32(stream->raw_mask << (uframe & 7));
+ stream->splits = cpu_to_hc32(ehci, stream->raw_mask << (uframe & 7));
return 1;
}
@@ -1544,12 +1549,13 @@ ready:
/*-------------------------------------------------------------------------*/
static inline void
-itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd)
+itd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream,
+ struct ehci_itd *itd)
{
int i;
/* it's been recently zeroed */
- itd->hw_next = EHCI_LIST_END;
+ itd->hw_next = EHCI_LIST_END(ehci);
itd->hw_bufp [0] = stream->buf0;
itd->hw_bufp [1] = stream->buf1;
itd->hw_bufp [2] = stream->buf2;
@@ -1561,7 +1567,8 @@ itd_init (struct ehci_iso_stream *stream, struct ehci_itd *itd)
}
static inline void
-itd_patch (
+itd_patch(
+ struct ehci_hcd *ehci,
struct ehci_itd *itd,
struct ehci_iso_sched *iso_sched,
unsigned index,
@@ -1576,17 +1583,18 @@ itd_patch (
uframe &= 0x07;
itd->index [uframe] = index;
- itd->hw_transaction [uframe] = uf->transaction;
- itd->hw_transaction [uframe] |= cpu_to_le32 (pg << 12);
- itd->hw_bufp [pg] |= cpu_to_le32 (uf->bufp & ~(u32)0);
- itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(uf->bufp >> 32));
+ itd->hw_transaction[uframe] = uf->transaction;
+ itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12);
+ itd->hw_bufp[pg] |= cpu_to_hc32(ehci, uf->bufp & ~(u32)0);
+ itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(uf->bufp >> 32));
/* iso_frame_desc[].offset must be strictly increasing */
if (unlikely (uf->cross)) {
u64 bufp = uf->bufp + 4096;
+
itd->pg = ++pg;
- itd->hw_bufp [pg] |= cpu_to_le32 (bufp & ~(u32)0);
- itd->hw_bufp_hi [pg] |= cpu_to_le32 ((u32)(bufp >> 32));
+ itd->hw_bufp[pg] |= cpu_to_hc32(ehci, bufp & ~(u32)0);
+ itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(bufp >> 32));
}
}
@@ -1599,7 +1607,7 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
ehci->pshadow [frame].itd = itd;
itd->frame = frame;
wmb ();
- ehci->periodic [frame] = cpu_to_le32 (itd->itd_dma) | Q_TYPE_ITD;
+ ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
}
/* fit urb's itds into the selected schedule slot; activate as needed */
@@ -1644,14 +1652,14 @@ itd_link_urb (
list_move_tail (&itd->itd_list, &stream->td_list);
itd->stream = iso_stream_get (stream);
itd->urb = usb_get_urb (urb);
- itd_init (stream, itd);
+ itd_init (ehci, stream, itd);
}
uframe = next_uframe & 0x07;
frame = next_uframe >> 3;
itd->usecs [uframe] = stream->usecs;
- itd_patch (itd, iso_sched, packet, uframe);
+ itd_patch(ehci, itd, iso_sched, packet, uframe);
next_uframe += stream->interval;
stream->depth += stream->interval;
@@ -1699,7 +1707,7 @@ itd_complete (
urb_index = itd->index[uframe];
desc = &urb->iso_frame_desc [urb_index];
- t = le32_to_cpup (&itd->hw_transaction [uframe]);
+ t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
itd->hw_transaction [uframe] = 0;
stream->depth -= stream->interval;
@@ -1829,7 +1837,8 @@ done:
*/
static inline void
-sitd_sched_init (
+sitd_sched_init(
+ struct ehci_hcd *ehci,
struct ehci_iso_sched *iso_sched,
struct ehci_iso_stream *stream,
struct urb *urb
@@ -1858,7 +1867,7 @@ sitd_sched_init (
&& !(urb->transfer_flags & URB_NO_INTERRUPT))
trans |= SITD_IOC;
trans |= length << 16;
- packet->transaction = cpu_to_le32 (trans);
+ packet->transaction = cpu_to_hc32(ehci, trans);
/* might need to cross a buffer page within a td */
packet->bufp = buf;
@@ -1894,7 +1903,7 @@ sitd_urb_transaction (
if (iso_sched == NULL)
return -ENOMEM;
- sitd_sched_init (iso_sched, stream, urb);
+ sitd_sched_init(ehci, iso_sched, stream, urb);
/* allocate/init sITDs */
spin_lock_irqsave (&ehci->lock, flags);
@@ -1946,7 +1955,8 @@ sitd_urb_transaction (
/*-------------------------------------------------------------------------*/
static inline void
-sitd_patch (
+sitd_patch(
+ struct ehci_hcd *ehci,
struct ehci_iso_stream *stream,
struct ehci_sitd *sitd,
struct ehci_iso_sched *iso_sched,
@@ -1956,20 +1966,20 @@ sitd_patch (
struct ehci_iso_packet *uf = &iso_sched->packet [index];
u64 bufp = uf->bufp;
- sitd->hw_next = EHCI_LIST_END;
+ sitd->hw_next = EHCI_LIST_END(ehci);
sitd->hw_fullspeed_ep = stream->address;
sitd->hw_uframe = stream->splits;
sitd->hw_results = uf->transaction;
- sitd->hw_backpointer = EHCI_LIST_END;
+ sitd->hw_backpointer = EHCI_LIST_END(ehci);
bufp = uf->bufp;
- sitd->hw_buf [0] = cpu_to_le32 (bufp);
- sitd->hw_buf_hi [0] = cpu_to_le32 (bufp >> 32);
+ sitd->hw_buf[0] = cpu_to_hc32(ehci, bufp);
+ sitd->hw_buf_hi[0] = cpu_to_hc32(ehci, bufp >> 32);
- sitd->hw_buf [1] = cpu_to_le32 (uf->buf1);
+ sitd->hw_buf[1] = cpu_to_hc32(ehci, uf->buf1);
if (uf->cross)
bufp += 4096;
- sitd->hw_buf_hi [1] = cpu_to_le32 (bufp >> 32);
+ sitd->hw_buf_hi[1] = cpu_to_hc32(ehci, bufp >> 32);
sitd->index = index;
}
@@ -1982,7 +1992,7 @@ sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd)
ehci->pshadow [frame].sitd = sitd;
sitd->frame = frame;
wmb ();
- ehci->periodic [frame] = cpu_to_le32 (sitd->sitd_dma) | Q_TYPE_SITD;
+ ehci->periodic[frame] = cpu_to_hc32(ehci, sitd->sitd_dma | Q_TYPE_SITD);
}
/* fit urb's sitds into the selected schedule slot; activate as needed */
@@ -2010,7 +2020,7 @@ sitd_link_urb (
urb->dev->devpath, stream->bEndpointAddress & 0x0f,
(stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out",
(next_uframe >> 3) % ehci->periodic_size,
- stream->interval, le32_to_cpu (stream->splits));
+ stream->interval, hc32_to_cpu(ehci, stream->splits));
stream->start = jiffies;
}
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
@@ -2031,7 +2041,7 @@ sitd_link_urb (
sitd->stream = iso_stream_get (stream);
sitd->urb = usb_get_urb (urb);
- sitd_patch (stream, sitd, sched, packet);
+ sitd_patch(ehci, stream, sitd, sched, packet);
sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size,
sitd);
@@ -2069,7 +2079,7 @@ sitd_complete (
urb_index = sitd->index;
desc = &urb->iso_frame_desc [urb_index];
- t = le32_to_cpup (&sitd->hw_results);
+ t = hc32_to_cpup(ehci, &sitd->hw_results);
/* report transfer status */
if (t & SITD_ERRS) {
@@ -2224,7 +2234,7 @@ scan_periodic (struct ehci_hcd *ehci)
for (;;) {
union ehci_shadow q, *q_p;
- __le32 type, *hw_p;
+ __hc32 type, *hw_p;
unsigned uframes;
/* don't scan past the live uframe */
@@ -2242,7 +2252,7 @@ restart:
q_p = &ehci->pshadow [frame];
hw_p = &ehci->periodic [frame];
q.ptr = q_p->ptr;
- type = Q_NEXT_TYPE (*hw_p);
+ type = Q_NEXT_TYPE(ehci, *hw_p);
modified = 0;
while (q.ptr != NULL) {
@@ -2251,11 +2261,11 @@ restart:
int live;
live = HC_IS_RUNNING (ehci_to_hcd(ehci)->state);
- switch (type) {
+ switch (hc32_to_cpu(ehci, type)) {
case Q_TYPE_QH:
/* handle any completions */
temp.qh = qh_get (q.qh);
- type = Q_NEXT_TYPE (q.qh->hw_next);
+ type = Q_NEXT_TYPE(ehci, q.qh->hw_next);
q = q.qh->qh_next;
modified = qh_completions (ehci, temp.qh);
if (unlikely (list_empty (&temp.qh->qtd_list)))
@@ -2266,10 +2276,10 @@ restart:
/* for "save place" FSTNs, look at QH entries
* in the previous frame for completions.
*/
- if (q.fstn->hw_prev != EHCI_LIST_END) {
+ if (q.fstn->hw_prev != EHCI_LIST_END(ehci)) {
dbg ("ignoring completions from FSTNs");
}
- type = Q_NEXT_TYPE (q.fstn->hw_next);
+ type = Q_NEXT_TYPE(ehci, q.fstn->hw_next);
q = q.fstn->fstn_next;
break;
case Q_TYPE_ITD:
@@ -2277,11 +2287,12 @@ restart:
rmb ();
for (uf = live ? uframes : 8; uf < 8; uf++) {
if (0 == (q.itd->hw_transaction [uf]
- & ITD_ACTIVE))
+ & ITD_ACTIVE(ehci)))
continue;
q_p = &q.itd->itd_next;
hw_p = &q.itd->hw_next;
- type = Q_NEXT_TYPE (q.itd->hw_next);
+ type = Q_NEXT_TYPE(ehci,
+ q.itd->hw_next);
q = *q_p;
break;
}
@@ -2293,23 +2304,24 @@ restart:
*/
*q_p = q.itd->itd_next;
*hw_p = q.itd->hw_next;
- type = Q_NEXT_TYPE (q.itd->hw_next);
+ type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
wmb();
modified = itd_complete (ehci, q.itd);
q = *q_p;
break;
case Q_TYPE_SITD:
- if ((q.sitd->hw_results & SITD_ACTIVE)
+ if ((q.sitd->hw_results & SITD_ACTIVE(ehci))
&& live) {
q_p = &q.sitd->sitd_next;
hw_p = &q.sitd->hw_next;
- type = Q_NEXT_TYPE (q.sitd->hw_next);
+ type = Q_NEXT_TYPE(ehci,
+ q.sitd->hw_next);
q = *q_p;
break;
}
*q_p = q.sitd->sitd_next;
*hw_p = q.sitd->hw_next;
- type = Q_NEXT_TYPE (q.sitd->hw_next);
+ type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
wmb();
modified = sitd_complete (ehci, q.sitd);
q = *q_p;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index a9ba5d28cdc2..79ad2af5ef6a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -21,6 +21,22 @@
/* definitions used for the EHCI driver */
+/*
+ * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
+ * __leXX (normally) or __beXX (given EHCI_BIG_ENDIAN_DESC), depending on
+ * the host controller implementation.
+ *
+ * To facilitate the strongest possible byte-order checking from "sparse"
+ * and so on, we use __leXX unless that's not practical.
+ */
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
+typedef __u32 __bitwise __hc32;
+typedef __u16 __bitwise __hc16;
+#else
+#define __hc32 __le32
+#define __hc16 __le16
+#endif
+
/* statistics can be kept for for tuning/monitoring */
struct ehci_stats {
/* irq usage */
@@ -70,7 +86,7 @@ struct ehci_hcd { /* one per controller */
/* periodic schedule support */
#define DEFAULT_I_TDPS 1024 /* some HCs can do less */
unsigned periodic_size;
- __le32 *periodic; /* hw periodic table */
+ __hc32 *periodic; /* hw periodic table */
dma_addr_t periodic_dma;
unsigned i_thresh; /* uframes HC might cache */
@@ -103,6 +119,7 @@ struct ehci_hcd { /* one per controller */
unsigned no_selective_suspend:1;
unsigned has_fsl_port_bug:1; /* FreeScale */
unsigned big_endian_mmio:1;
+ unsigned big_endian_desc:1;
u8 sbrn; /* packed release number */
@@ -309,7 +326,7 @@ struct ehci_dbg_port {
/*-------------------------------------------------------------------------*/
-#define QTD_NEXT(dma) cpu_to_le32((u32)dma)
+#define QTD_NEXT(ehci, dma) cpu_to_hc32(ehci, (u32)dma)
/*
* EHCI Specification 0.95 Section 3.5
@@ -321,9 +338,9 @@ struct ehci_dbg_port {
*/
struct ehci_qtd {
/* first part defined by EHCI spec */
- __le32 hw_next; /* see EHCI 3.5.1 */
- __le32 hw_alt_next; /* see EHCI 3.5.2 */
- __le32 hw_token; /* see EHCI 3.5.3 */
+ __hc32 hw_next; /* see EHCI 3.5.1 */
+ __hc32 hw_alt_next; /* see EHCI 3.5.2 */
+ __hc32 hw_token; /* see EHCI 3.5.3 */
#define QTD_TOGGLE (1 << 31) /* data toggle */
#define QTD_LENGTH(tok) (((tok)>>16) & 0x7fff)
#define QTD_IOC (1 << 15) /* interrupt on complete */
@@ -337,8 +354,13 @@ struct ehci_qtd {
#define QTD_STS_MMF (1 << 2) /* incomplete split transaction */
#define QTD_STS_STS (1 << 1) /* split transaction state */
#define QTD_STS_PING (1 << 0) /* issue PING? */
- __le32 hw_buf [5]; /* see EHCI 3.5.4 */
- __le32 hw_buf_hi [5]; /* Appendix B */
+
+#define ACTIVE_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_ACTIVE)
+#define HALT_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_HALT)
+#define STATUS_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_STS)
+
+ __hc32 hw_buf [5]; /* see EHCI 3.5.4 */
+ __hc32 hw_buf_hi [5]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t qtd_dma; /* qtd address */
@@ -348,26 +370,33 @@ struct ehci_qtd {
} __attribute__ ((aligned (32)));
/* mask NakCnt+T in qh->hw_alt_next */
-#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+#define QTD_MASK(ehci) cpu_to_hc32 (ehci, ~0x1f)
#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
/*-------------------------------------------------------------------------*/
/* type tag from {qh,itd,sitd,fstn}->hw_next */
-#define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1))
+#define Q_NEXT_TYPE(ehci,dma) ((dma) & cpu_to_hc32(ehci, 3 << 1))
+/*
+ * Now the following defines are not converted using the
+ * __constant_cpu_to_le32() macro anymore, since we have to support
+ * "dynamic" switching between be and le support, so that the driver
+ * can be used on one system with SoC EHCI controller using big-endian
+ * descriptors as well as a normal little-endian PCI EHCI controller.
+ */
/* values for that type tag */
-#define Q_TYPE_ITD __constant_cpu_to_le32 (0 << 1)
-#define Q_TYPE_QH __constant_cpu_to_le32 (1 << 1)
-#define Q_TYPE_SITD __constant_cpu_to_le32 (2 << 1)
-#define Q_TYPE_FSTN __constant_cpu_to_le32 (3 << 1)
+#define Q_TYPE_ITD (0 << 1)
+#define Q_TYPE_QH (1 << 1)
+#define Q_TYPE_SITD (2 << 1)
+#define Q_TYPE_FSTN (3 << 1)
/* next async queue entry, or pointer to interrupt/periodic QH */
-#define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH)
+#define QH_NEXT(ehci,dma) (cpu_to_hc32(ehci, (((u32)dma)&~0x01f)|Q_TYPE_QH))
/* for periodic/async schedules and qtd lists, mark end of list */
-#define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */
+#define EHCI_LIST_END(ehci) cpu_to_hc32(ehci, 1) /* "null pointer" to hw */
/*
* Entries in periodic shadow table are pointers to one of four kinds
@@ -382,7 +411,7 @@ union ehci_shadow {
struct ehci_itd *itd; /* Q_TYPE_ITD */
struct ehci_sitd *sitd; /* Q_TYPE_SITD */
struct ehci_fstn *fstn; /* Q_TYPE_FSTN */
- __le32 *hw_next; /* (all types) */
+ __hc32 *hw_next; /* (all types) */
void *ptr;
};
@@ -398,24 +427,27 @@ union ehci_shadow {
struct ehci_qh {
/* first part defined by EHCI spec */
- __le32 hw_next; /* see EHCI 3.6.1 */
- __le32 hw_info1; /* see EHCI 3.6.2 */
+ __hc32 hw_next; /* see EHCI 3.6.1 */
+ __hc32 hw_info1; /* see EHCI 3.6.2 */
#define QH_HEAD 0x00008000
#define QH_INACTIVATE 0x00000080
- __le32 hw_info2; /* see EHCI 3.6.2 */
+
+#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE)
+
+ __hc32 hw_info2; /* see EHCI 3.6.2 */
#define QH_SMASK 0x000000ff
#define QH_CMASK 0x0000ff00
#define QH_HUBADDR 0x007f0000
#define QH_HUBPORT 0x3f800000
#define QH_MULT 0xc0000000
- __le32 hw_current; /* qtd list - see EHCI 3.6.4 */
+ __hc32 hw_current; /* qtd list - see EHCI 3.6.4 */
/* qtd overlay (hardware parts of a struct ehci_qtd) */
- __le32 hw_qtd_next;
- __le32 hw_alt_next;
- __le32 hw_token;
- __le32 hw_buf [5];
- __le32 hw_buf_hi [5];
+ __hc32 hw_qtd_next;
+ __hc32 hw_alt_next;
+ __hc32 hw_token;
+ __hc32 hw_buf [5];
+ __hc32 hw_buf_hi [5];
/* the rest is HCD-private */
dma_addr_t qh_dma; /* address of qh */
@@ -456,7 +488,7 @@ struct ehci_qh {
struct ehci_iso_packet {
/* These will be copied to iTD when scheduling */
u64 bufp; /* itd->hw_bufp{,_hi}[pg] |= */
- __le32 transaction; /* itd->hw_transaction[i] |= */
+ __hc32 transaction; /* itd->hw_transaction[i] |= */
u8 cross; /* buf crosses pages */
/* for full speed OUT splits */
u32 buf1;
@@ -478,8 +510,8 @@ struct ehci_iso_sched {
*/
struct ehci_iso_stream {
/* first two fields match QH, but info1 == 0 */
- __le32 hw_next;
- __le32 hw_info1;
+ __hc32 hw_next;
+ __hc32 hw_info1;
u32 refcount;
u8 bEndpointAddress;
@@ -494,7 +526,7 @@ struct ehci_iso_stream {
unsigned long start; /* jiffies */
unsigned long rescheduled;
int next_uframe;
- __le32 splits;
+ __hc32 splits;
/* the rest is derived from the endpoint descriptor,
* trusting urb->interval == f(epdesc->bInterval) and
@@ -508,12 +540,12 @@ struct ehci_iso_stream {
unsigned bandwidth;
/* This is used to initialize iTD's hw_bufp fields */
- __le32 buf0;
- __le32 buf1;
- __le32 buf2;
+ __hc32 buf0;
+ __hc32 buf1;
+ __hc32 buf2;
/* this is used to initialize sITD's tt info */
- __le32 address;
+ __hc32 address;
};
/*-------------------------------------------------------------------------*/
@@ -526,8 +558,8 @@ struct ehci_iso_stream {
*/
struct ehci_itd {
/* first part defined by EHCI spec */
- __le32 hw_next; /* see EHCI 3.3.1 */
- __le32 hw_transaction [8]; /* see EHCI 3.3.2 */
+ __hc32 hw_next; /* see EHCI 3.3.1 */
+ __hc32 hw_transaction [8]; /* see EHCI 3.3.2 */
#define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */
#define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */
#define EHCI_ISOC_BABBLE (1<<29) /* babble detected */
@@ -535,10 +567,10 @@ struct ehci_itd {
#define EHCI_ITD_LENGTH(tok) (((tok)>>16) & 0x0fff)
#define EHCI_ITD_IOC (1 << 15) /* interrupt on complete */
-#define ITD_ACTIVE __constant_cpu_to_le32(EHCI_ISOC_ACTIVE)
+#define ITD_ACTIVE(ehci) cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE)
- __le32 hw_bufp [7]; /* see EHCI 3.3.3 */
- __le32 hw_bufp_hi [7]; /* Appendix B */
+ __hc32 hw_bufp [7]; /* see EHCI 3.3.3 */
+ __hc32 hw_bufp_hi [7]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t itd_dma; /* for this itd */
@@ -565,11 +597,11 @@ struct ehci_itd {
*/
struct ehci_sitd {
/* first part defined by EHCI spec */
- __le32 hw_next;
+ __hc32 hw_next;
/* uses bit field macros above - see EHCI 0.95 Table 3-8 */
- __le32 hw_fullspeed_ep; /* EHCI table 3-9 */
- __le32 hw_uframe; /* EHCI table 3-10 */
- __le32 hw_results; /* EHCI table 3-11 */
+ __hc32 hw_fullspeed_ep; /* EHCI table 3-9 */
+ __hc32 hw_uframe; /* EHCI table 3-10 */
+ __hc32 hw_results; /* EHCI table 3-11 */
#define SITD_IOC (1 << 31) /* interrupt on completion */
#define SITD_PAGE (1 << 30) /* buffer 0/1 */
#define SITD_LENGTH(x) (0x3ff & ((x)>>16))
@@ -581,11 +613,11 @@ struct ehci_sitd {
#define SITD_STS_MMF (1 << 2) /* incomplete split transaction */
#define SITD_STS_STS (1 << 1) /* split transaction state */
-#define SITD_ACTIVE __constant_cpu_to_le32(SITD_STS_ACTIVE)
+#define SITD_ACTIVE(ehci) cpu_to_hc32(ehci, SITD_STS_ACTIVE)
- __le32 hw_buf [2]; /* EHCI table 3-12 */
- __le32 hw_backpointer; /* EHCI table 3-13 */
- __le32 hw_buf_hi [2]; /* Appendix B */
+ __hc32 hw_buf [2]; /* EHCI table 3-12 */
+ __hc32 hw_backpointer; /* EHCI table 3-13 */
+ __hc32 hw_buf_hi [2]; /* Appendix B */
/* the rest is HCD-private */
dma_addr_t sitd_dma;
@@ -610,8 +642,8 @@ struct ehci_sitd {
* it hits a "restore" FSTN; then it returns to finish other uframe 0/1 work.
*/
struct ehci_fstn {
- __le32 hw_next; /* any periodic q entry */
- __le32 hw_prev; /* qh or EHCI_LIST_END */
+ __hc32 hw_next; /* any periodic q entry */
+ __hc32 hw_prev; /* qh or EHCI_LIST_END */
/* the rest is HCD-private */
dma_addr_t fstn_dma;
@@ -683,8 +715,21 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
#define ehci_big_endian_mmio(e) 0
#endif
-static inline unsigned int ehci_readl (const struct ehci_hcd *ehci,
- __u32 __iomem * regs)
+/*
+ * Big-endian read/write functions are arch-specific.
+ * Other arches can be added if/when they're needed.
+ *
+ * REVISIT: arch/powerpc now has readl/writel_be, so the
+ * definition below can die once the 4xx support is
+ * finally ported over.
+ */
+#if defined(CONFIG_PPC)
+#define readl_be(addr) in_be32((__force unsigned *)addr)
+#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
+#endif
+
+static inline unsigned int ehci_readl(const struct ehci_hcd *ehci,
+ __u32 __iomem * regs)
{
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
return ehci_big_endian_mmio(ehci) ?
@@ -695,8 +740,8 @@ static inline unsigned int ehci_readl (const struct ehci_hcd *ehci,
#endif
}
-static inline void ehci_writel (const struct ehci_hcd *ehci,
- const unsigned int val, __u32 __iomem *regs)
+static inline void ehci_writel(const struct ehci_hcd *ehci,
+ const unsigned int val, __u32 __iomem *regs)
{
#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
ehci_big_endian_mmio(ehci) ?
@@ -709,6 +754,62 @@ static inline void ehci_writel (const struct ehci_hcd *ehci,
/*-------------------------------------------------------------------------*/
+/*
+ * The AMCC 440EPx not only implements its EHCI registers in big-endian
+ * format, but also its DMA data structures (descriptors).
+ *
+ * EHCI controllers accessed through PCI work normally (little-endian
+ * everywhere), so we won't bother supporting a BE-only mode for now.
+ */
+#ifdef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
+#define ehci_big_endian_desc(e) ((e)->big_endian_desc)
+
+/* cpu to ehci */
+static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x)
+{
+ return ehci_big_endian_desc(ehci)
+ ? (__force __hc32)cpu_to_be32(x)
+ : (__force __hc32)cpu_to_le32(x);
+}
+
+/* ehci to cpu */
+static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x)
+{
+ return ehci_big_endian_desc(ehci)
+ ? be32_to_cpu((__force __be32)x)
+ : le32_to_cpu((__force __le32)x);
+}
+
+static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
+{
+ return ehci_big_endian_desc(ehci)
+ ? be32_to_cpup((__force __be32 *)x)
+ : le32_to_cpup((__force __le32 *)x);
+}
+
+#else
+
+/* cpu to ehci */
+static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x)
+{
+ return cpu_to_le32(x);
+}
+
+/* ehci to cpu */
+static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x)
+{
+ return le32_to_cpu(x);
+}
+
+static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x)
+{
+ return le32_to_cpup(x);
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */