Commit ed3361ff authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] USB: ohci, hooks for big-endian registers

This is the second of the patches from Dale Farnsworth to
support OHCI implementations that use big-endian byte sex
for registers ... all register accesses changed, that's why
it's so large.  (It also includes part of an update from
his third patch, so that it compiles/runs by itself.)

This patch adds support to the OHCI code for big-endian controllers,
maintaining the existing little-endian support.  This is done using
the following transforms:

        ohci_readl(p)   --> ohci_readl(ohci, p)
	writel(v, p)    --> ohci_writel(ohci, v, p)

	cpu_to_le16(v)  --> cpu_to_hc16(ohci, v)
	cpu_to_le16p(v) --> cpu_to_hc16p(ohci, v)
	cpu_to_le32(v)  --> cpu_to_hc32(ohci, v)
	cpu_to_le32p(v) --> cpu_to_hc32p(ohci, v)

	le16_to_cpu(v) --> hc16_to_cpu(ohci, v)
	le16_to_cpup(v) --> hc16_to_cpup(ohci, v)
	le32_to_cpu(v) --> hc32_to_cpu(ohci, v)
	le32_to_cpup(v) --> hc32_to_cpup(ohci, v)

	OHCI_FRAME_NO(ohci->hcca) --> ohci_frame_no(ohci)

There's no runtime penalty except for systems configured to handle
both byteorders at the same time.
Signed-off-by: default avatarDale Farnsworth <dale@farnsworth.org>
Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent c13db862
...@@ -134,13 +134,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) ...@@ -134,13 +134,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
struct ohci_regs __iomem *regs = controller->regs; struct ohci_regs __iomem *regs = controller->regs;
u32 temp; u32 temp;
temp = ohci_readl (&regs->revision) & 0xff; temp = ohci_readl (controller, &regs->revision) & 0xff;
ohci_dbg_sw (controller, next, size, ohci_dbg_sw (controller, next, size,
"OHCI %d.%d, %s legacy support registers\n", "OHCI %d.%d, %s legacy support registers\n",
0x03 & (temp >> 4), (temp & 0x0f), 0x03 & (temp >> 4), (temp & 0x0f),
(temp & 0x10) ? "with" : "NO"); (temp & 0x10) ? "with" : "NO");
temp = ohci_readl (&regs->control); temp = ohci_readl (controller, &regs->control);
ohci_dbg_sw (controller, next, size, ohci_dbg_sw (controller, next, size,
"control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n", "control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
temp, temp,
...@@ -155,7 +155,7 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) ...@@ -155,7 +155,7 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
temp & OHCI_CTRL_CBSR temp & OHCI_CTRL_CBSR
); );
temp = ohci_readl (&regs->cmdstatus); temp = ohci_readl (controller, &regs->cmdstatus);
ohci_dbg_sw (controller, next, size, ohci_dbg_sw (controller, next, size,
"cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp, "cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
(temp & OHCI_SOC) >> 16, (temp & OHCI_SOC) >> 16,
...@@ -166,26 +166,33 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) ...@@ -166,26 +166,33 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size)
); );
ohci_dump_intr_mask (controller, "intrstatus", ohci_dump_intr_mask (controller, "intrstatus",
ohci_readl (&regs->intrstatus), next, size); ohci_readl (controller, &regs->intrstatus),
next, size);
ohci_dump_intr_mask (controller, "intrenable", ohci_dump_intr_mask (controller, "intrenable",
ohci_readl (&regs->intrenable), next, size); ohci_readl (controller, &regs->intrenable),
next, size);
// intrdisable always same as intrenable // intrdisable always same as intrenable
maybe_print_eds (controller, "ed_periodcurrent", maybe_print_eds (controller, "ed_periodcurrent",
ohci_readl (&regs->ed_periodcurrent), next, size); ohci_readl (controller, &regs->ed_periodcurrent),
next, size);
maybe_print_eds (controller, "ed_controlhead", maybe_print_eds (controller, "ed_controlhead",
ohci_readl (&regs->ed_controlhead), next, size); ohci_readl (controller, &regs->ed_controlhead),
next, size);
maybe_print_eds (controller, "ed_controlcurrent", maybe_print_eds (controller, "ed_controlcurrent",
ohci_readl (&regs->ed_controlcurrent), next, size); ohci_readl (controller, &regs->ed_controlcurrent),
next, size);
maybe_print_eds (controller, "ed_bulkhead", maybe_print_eds (controller, "ed_bulkhead",
ohci_readl (&regs->ed_bulkhead), next, size); ohci_readl (controller, &regs->ed_bulkhead),
next, size);
maybe_print_eds (controller, "ed_bulkcurrent", maybe_print_eds (controller, "ed_bulkcurrent",
ohci_readl (&regs->ed_bulkcurrent), next, size); ohci_readl (controller, &regs->ed_bulkcurrent),
next, size);
maybe_print_eds (controller, "donehead", maybe_print_eds (controller, "donehead",
ohci_readl (&regs->donehead), next, size); ohci_readl (controller, &regs->donehead), next, size);
} }
#define dbg_port_sw(hc,num,value,next,size) \ #define dbg_port_sw(hc,num,value,next,size) \
...@@ -269,7 +276,7 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose) ...@@ -269,7 +276,7 @@ static void ohci_dump (struct ohci_hcd *controller, int verbose)
ohci_dump_status (controller, NULL, NULL); ohci_dump_status (controller, NULL, NULL);
if (controller->hcca) if (controller->hcca)
ohci_dbg (controller, ohci_dbg (controller,
"hcca frame #%04x\n", OHCI_FRAME_NO(controller->hcca)); "hcca frame #%04x\n", ohci_frame_no(controller));
ohci_dump_roothub (controller, 1, NULL, NULL); ohci_dump_roothub (controller, 1, NULL, NULL);
} }
...@@ -279,13 +286,13 @@ static const char data1 [] = "DATA1"; ...@@ -279,13 +286,13 @@ static const char data1 [] = "DATA1";
static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label, static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
const struct td *td) const struct td *td)
{ {
u32 tmp = le32_to_cpup (&td->hwINFO); u32 tmp = hc32_to_cpup (ohci, &td->hwINFO);
ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n", ohci_dbg (ohci, "%s td %p%s; urb %p index %d; hw next td %08x\n",
label, td, label, td,
(tmp & TD_DONE) ? " (DONE)" : "", (tmp & TD_DONE) ? " (DONE)" : "",
td->urb, td->index, td->urb, td->index,
le32_to_cpup (&td->hwNextTD)); hc32_to_cpup (ohci, &td->hwNextTD));
if ((tmp & TD_ISO) == 0) { if ((tmp & TD_ISO) == 0) {
const char *toggle, *pid; const char *toggle, *pid;
u32 cbp, be; u32 cbp, be;
...@@ -306,8 +313,8 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label, ...@@ -306,8 +313,8 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
TD_CC_GET(tmp), /* EC, */ toggle, TD_CC_GET(tmp), /* EC, */ toggle,
(tmp & TD_DI) >> 21, pid, (tmp & TD_DI) >> 21, pid,
(tmp & TD_R) ? "R" : ""); (tmp & TD_R) ? "R" : "");
cbp = le32_to_cpup (&td->hwCBP); cbp = hc32_to_cpup (ohci, &td->hwCBP);
be = le32_to_cpup (&td->hwBE); be = hc32_to_cpup (ohci, &td->hwBE);
ohci_dbg (ohci, " cbp %08x be %08x (len %d)\n", cbp, be, ohci_dbg (ohci, " cbp %08x be %08x (len %d)\n", cbp, be,
cbp ? (be + 1 - cbp) : 0); cbp ? (be + 1 - cbp) : 0);
} else { } else {
...@@ -318,10 +325,10 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label, ...@@ -318,10 +325,10 @@ static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
(tmp & TD_DI) >> 21, (tmp & TD_DI) >> 21,
tmp & 0x0000ffff); tmp & 0x0000ffff);
ohci_dbg (ohci, " bp0 %08x be %08x\n", ohci_dbg (ohci, " bp0 %08x be %08x\n",
le32_to_cpup (&td->hwCBP) & ~0x0fff, hc32_to_cpup (ohci, &td->hwCBP) & ~0x0fff,
le32_to_cpup (&td->hwBE)); hc32_to_cpup (ohci, &td->hwBE));
for (i = 0; i < MAXPSW; i++) { for (i = 0; i < MAXPSW; i++) {
u16 psw = le16_to_cpup (&td->hwPSW [i]); u16 psw = hc16_to_cpup (ohci, &td->hwPSW [i]);
int cc = (psw >> 12) & 0x0f; int cc = (psw >> 12) & 0x0f;
ohci_dbg (ohci, " psw [%d] = %2x, CC=%x %s=%d\n", i, ohci_dbg (ohci, " psw [%d] = %2x, CC=%x %s=%d\n", i,
psw, cc, psw, cc,
...@@ -336,13 +343,13 @@ static void __attribute__((unused)) ...@@ -336,13 +343,13 @@ static void __attribute__((unused))
ohci_dump_ed (const struct ohci_hcd *ohci, const char *label, ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,
const struct ed *ed, int verbose) const struct ed *ed, int verbose)
{ {
u32 tmp = le32_to_cpu (ed->hwINFO); u32 tmp = hc32_to_cpu (ohci, ed->hwINFO);
char *type = ""; char *type = "";
ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n", ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n",
label, label,
ed, ed->state, edstring (ed->type), ed, ed->state, edstring (ed->type),
le32_to_cpup (&ed->hwNextED)); hc32_to_cpup (ohci, &ed->hwNextED));
switch (tmp & (ED_IN|ED_OUT)) { switch (tmp & (ED_IN|ED_OUT)) {
case ED_OUT: type = "-OUT"; break; case ED_OUT: type = "-OUT"; break;
case ED_IN: type = "-IN"; break; case ED_IN: type = "-IN"; break;
...@@ -358,12 +365,12 @@ ohci_dump_ed (const struct ohci_hcd *ohci, const char *label, ...@@ -358,12 +365,12 @@ ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,
0x000f & (tmp >> 7), 0x000f & (tmp >> 7),
type, type,
0x007f & tmp); 0x007f & tmp);
tmp = le32_to_cpup (&ed->hwHeadP); tmp = hc32_to_cpup (ohci, &ed->hwHeadP);
ohci_dbg (ohci, " tds: head %08x %s%s tail %08x%s\n", ohci_dbg (ohci, " tds: head %08x %s%s tail %08x%s\n",
tmp, tmp,
(tmp & ED_C) ? data1 : data0, (tmp & ED_C) ? data1 : data0,
(tmp & ED_H) ? " HALT" : "", (tmp & ED_H) ? " HALT" : "",
le32_to_cpup (&ed->hwTailP), hc32_to_cpup (ohci, &ed->hwTailP),
verbose ? "" : " (not listing)"); verbose ? "" : " (not listing)");
if (verbose) { if (verbose) {
struct list_head *tmp; struct list_head *tmp;
...@@ -409,10 +416,10 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) ...@@ -409,10 +416,10 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
/* dump a snapshot of the bulk or control schedule */ /* dump a snapshot of the bulk or control schedule */
while (ed) { while (ed) {
u32 info = le32_to_cpu (ed->hwINFO); u32 info = hc32_to_cpu (ohci, ed->hwINFO);
u32 headp = le32_to_cpu (ed->hwHeadP); u32 headp = hc32_to_cpu (ohci, ed->hwHeadP);
struct list_head *entry; struct list_head *entry;
struct td *td; struct td *td;
temp = scnprintf (buf, size, temp = scnprintf (buf, size,
"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s", "ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
...@@ -433,9 +440,9 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) ...@@ -433,9 +440,9 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
u32 cbp, be; u32 cbp, be;
td = list_entry (entry, struct td, td_list); td = list_entry (entry, struct td, td_list);
info = le32_to_cpup (&td->hwINFO); info = hc32_to_cpup (ohci, &td->hwINFO);
cbp = le32_to_cpup (&td->hwCBP); cbp = hc32_to_cpup (ohci, &td->hwCBP);
be = le32_to_cpup (&td->hwBE); be = hc32_to_cpup (ohci, &td->hwBE);
temp = scnprintf (buf, size, temp = scnprintf (buf, size,
"\n\ttd %p %s %d cc=%x urb %p (%08x)", "\n\ttd %p %s %d cc=%x urb %p (%08x)",
td, td,
...@@ -535,7 +542,7 @@ show_periodic (struct class_device *class_dev, char *buf) ...@@ -535,7 +542,7 @@ show_periodic (struct class_device *class_dev, char *buf)
/* show more info the first time around */ /* show more info the first time around */
if (temp == seen_count) { if (temp == seen_count) {
u32 info = le32_to_cpu (ed->hwINFO); u32 info = hc32_to_cpu (ohci, ed->hwINFO);
struct list_head *entry; struct list_head *entry;
unsigned qlen = 0; unsigned qlen = 0;
...@@ -555,8 +562,9 @@ show_periodic (struct class_device *class_dev, char *buf) ...@@ -555,8 +562,9 @@ show_periodic (struct class_device *class_dev, char *buf)
0x03ff & (info >> 16), 0x03ff & (info >> 16),
info, info,
(info & ED_SKIP) ? " K" : "", (info & ED_SKIP) ? " K" : "",
(ed->hwHeadP & cpu_to_le32(ED_H)) ? (ed->hwHeadP &
" H" : ""); cpu_to_hc32(ohci, ED_H)) ?
" H" : "");
size -= temp; size -= temp;
next += temp; next += temp;
...@@ -628,10 +636,10 @@ show_registers (struct class_device *class_dev, char *buf) ...@@ -628,10 +636,10 @@ show_registers (struct class_device *class_dev, char *buf)
/* hcca */ /* hcca */
if (ohci->hcca) if (ohci->hcca)
ohci_dbg_sw (ohci, &next, &size, ohci_dbg_sw (ohci, &next, &size,
"hcca frame 0x%04x\n", OHCI_FRAME_NO(ohci->hcca)); "hcca frame 0x%04x\n", ohci_frame_no(ohci));
/* other registers mostly affect frame timings */ /* other registers mostly affect frame timings */
rdata = ohci_readl (&regs->fminterval); rdata = ohci_readl (ohci, &regs->fminterval);
temp = scnprintf (next, size, temp = scnprintf (next, size,
"fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n", "fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
rdata, (rdata >> 31) ? "FIT " : "", rdata, (rdata >> 31) ? "FIT " : "",
...@@ -639,20 +647,20 @@ show_registers (struct class_device *class_dev, char *buf) ...@@ -639,20 +647,20 @@ show_registers (struct class_device *class_dev, char *buf)
size -= temp; size -= temp;
next += temp; next += temp;
rdata = ohci_readl (&regs->fmremaining); rdata = ohci_readl (ohci, &regs->fmremaining);
temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n", temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
rdata, (rdata >> 31) ? "FRT " : "", rdata, (rdata >> 31) ? "FRT " : "",
rdata & 0x3fff); rdata & 0x3fff);
size -= temp; size -= temp;
next += temp; next += temp;
rdata = ohci_readl (&regs->periodicstart); rdata = ohci_readl (ohci, &regs->periodicstart);
temp = scnprintf (next, size, "periodicstart 0x%04x\n", temp = scnprintf (next, size, "periodicstart 0x%04x\n",
rdata & 0x3fff); rdata & 0x3fff);
size -= temp; size -= temp;
next += temp; next += temp;
rdata = ohci_readl (&regs->lsthresh); rdata = ohci_readl (ohci, &regs->lsthresh);
temp = scnprintf (next, size, "lsthresh 0x%04x\n", temp = scnprintf (next, size, "lsthresh 0x%04x\n",
rdata & 0x3fff); rdata & 0x3fff);
size -= temp; size -= temp;
......
This diff is collapsed.
This diff is collapsed.
...@@ -99,7 +99,7 @@ td_alloc (struct ohci_hcd *hc, int mem_flags) ...@@ -99,7 +99,7 @@ td_alloc (struct ohci_hcd *hc, int mem_flags)
if (td) { if (td) {
/* in case hc fetches it, make it look dead */ /* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td); memset (td, 0, sizeof *td);
td->hwNextTD = cpu_to_le32 (dma); td->hwNextTD = cpu_to_hc32 (hc, dma);
td->td_dma = dma; td->td_dma = dma;
/* hashed in td_fill */ /* hashed in td_fill */
} }
...@@ -115,7 +115,7 @@ td_free (struct ohci_hcd *hc, struct td *td) ...@@ -115,7 +115,7 @@ td_free (struct ohci_hcd *hc, struct td *td)
prev = &(*prev)->td_hash; prev = &(*prev)->td_hash;
if (*prev) if (*prev)
*prev = td->td_hash; *prev = td->td_hash;
else if ((td->hwINFO & cpu_to_le32(TD_DONE)) != 0) else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
ohci_dbg (hc, "no hash for td %p\n", td); ohci_dbg (hc, "no hash for td %p\n", td);
dma_pool_free (hc->td_cache, td, td->td_dma); dma_pool_free (hc->td_cache, td, td->td_dma);
} }
......
This diff is collapsed.
This diff is collapsed.
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