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.)
Please merge.
- Dave
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: Dale Farnsworth <[EMAIL PROTECTED]>
Signed-off-by: David Brownell <[EMAIL PROTECTED]>
--- 1.36/drivers/usb/host/ohci-dbg.c 2004-10-30 15:10:57 -07:00
+++ edited/drivers/usb/host/ohci-dbg.c 2004-10-31 12:15:44 -08:00
@@ -134,13 +134,13 @@
struct ohci_regs __iomem *regs = controller->regs;
u32 temp;
- temp = ohci_readl (®s->revision) & 0xff;
+ temp = ohci_readl (controller, ®s->revision) & 0xff;
ohci_dbg_sw (controller, next, size,
"OHCI %d.%d, %s legacy support registers\n",
0x03 & (temp >> 4), (temp & 0x0f),
(temp & 0x10) ? "with" : "NO");
- temp = ohci_readl (®s->control);
+ temp = ohci_readl (controller, ®s->control);
ohci_dbg_sw (controller, next, size,
"control 0x%03x%s%s%s HCFS=%s%s%s%s%s CBSR=%d\n",
temp,
@@ -155,7 +155,7 @@
temp & OHCI_CTRL_CBSR
);
- temp = ohci_readl (®s->cmdstatus);
+ temp = ohci_readl (controller, ®s->cmdstatus);
ohci_dbg_sw (controller, next, size,
"cmdstatus 0x%05x SOC=%d%s%s%s%s\n", temp,
(temp & OHCI_SOC) >> 16,
@@ -166,26 +166,33 @@
);
ohci_dump_intr_mask (controller, "intrstatus",
- ohci_readl (®s->intrstatus), next, size);
+ ohci_readl (controller, ®s->intrstatus),
+ next, size);
ohci_dump_intr_mask (controller, "intrenable",
- ohci_readl (®s->intrenable), next, size);
+ ohci_readl (controller, ®s->intrenable),
+ next, size);
// intrdisable always same as intrenable
maybe_print_eds (controller, "ed_periodcurrent",
- ohci_readl (®s->ed_periodcurrent), next, size);
+ ohci_readl (controller, ®s->ed_periodcurrent),
+ next, size);
maybe_print_eds (controller, "ed_controlhead",
- ohci_readl (®s->ed_controlhead), next, size);
+ ohci_readl (controller, ®s->ed_controlhead),
+ next, size);
maybe_print_eds (controller, "ed_controlcurrent",
- ohci_readl (®s->ed_controlcurrent), next, size);
+ ohci_readl (controller, ®s->ed_controlcurrent),
+ next, size);
maybe_print_eds (controller, "ed_bulkhead",
- ohci_readl (®s->ed_bulkhead), next, size);
+ ohci_readl (controller, ®s->ed_bulkhead),
+ next, size);
maybe_print_eds (controller, "ed_bulkcurrent",
- ohci_readl (®s->ed_bulkcurrent), next, size);
+ ohci_readl (controller, ®s->ed_bulkcurrent),
+ next, size);
maybe_print_eds (controller, "donehead",
- ohci_readl (®s->donehead), next, size);
+ ohci_readl (controller, ®s->donehead), next, size);
}
#define dbg_port_sw(hc,num,value,next,size) \
@@ -269,7 +276,7 @@
ohci_dump_status (controller, NULL, NULL);
if (controller->hcca)
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);
}
@@ -279,13 +286,13 @@
static void ohci_dump_td (const struct ohci_hcd *ohci, const char *label,
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",
label, td,
(tmp & TD_DONE) ? " (DONE)" : "",
td->urb, td->index,
- le32_to_cpup (&td->hwNextTD));
+ hc32_to_cpup (ohci, &td->hwNextTD));
if ((tmp & TD_ISO) == 0) {
const char *toggle, *pid;
u32 cbp, be;
@@ -306,8 +313,8 @@
TD_CC_GET(tmp), /* EC, */ toggle,
(tmp & TD_DI) >> 21, pid,
(tmp & TD_R) ? "R" : "");
- cbp = le32_to_cpup (&td->hwCBP);
- be = le32_to_cpup (&td->hwBE);
+ cbp = hc32_to_cpup (ohci, &td->hwCBP);
+ be = hc32_to_cpup (ohci, &td->hwBE);
ohci_dbg (ohci, " cbp %08x be %08x (len %d)\n", cbp, be,
cbp ? (be + 1 - cbp) : 0);
} else {
@@ -318,10 +325,10 @@
(tmp & TD_DI) >> 21,
tmp & 0x0000ffff);
ohci_dbg (ohci, " bp0 %08x be %08x\n",
- le32_to_cpup (&td->hwCBP) & ~0x0fff,
- le32_to_cpup (&td->hwBE));
+ hc32_to_cpup (ohci, &td->hwCBP) & ~0x0fff,
+ hc32_to_cpup (ohci, &td->hwBE));
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;
ohci_dbg (ohci, " psw [%d] = %2x, CC=%x %s=%d\n", i,
psw, cc,
@@ -336,13 +343,13 @@
ohci_dump_ed (const struct ohci_hcd *ohci, const char *label,
const struct ed *ed, int verbose)
{
- u32 tmp = le32_to_cpu (ed->hwINFO);
+ u32 tmp = hc32_to_cpu (ohci, ed->hwINFO);
char *type = "";
ohci_dbg (ohci, "%s, ed %p state 0x%x type %s; next ed %08x\n",
label,
ed, ed->state, edstring (ed->type),
- le32_to_cpup (&ed->hwNextED));
+ hc32_to_cpup (ohci, &ed->hwNextED));
switch (tmp & (ED_IN|ED_OUT)) {
case ED_OUT: type = "-OUT"; break;
case ED_IN: type = "-IN"; break;
@@ -358,12 +365,12 @@
0x000f & (tmp >> 7),
type,
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",
tmp,
(tmp & ED_C) ? data1 : data0,
(tmp & ED_H) ? " HALT" : "",
- le32_to_cpup (&ed->hwTailP),
+ hc32_to_cpup (ohci, &ed->hwTailP),
verbose ? "" : " (not listing)");
if (verbose) {
struct list_head *tmp;
@@ -416,10 +423,10 @@
/* dump a snapshot of the bulk or control schedule */
while (ed) {
- u32 info = le32_to_cpu (ed->hwINFO);
- u32 headp = le32_to_cpu (ed->hwHeadP);
- struct list_head *entry;
- struct td *td;
+ u32 info = hc32_to_cpu (ohci, ed->hwINFO);
+ u32 headp = hc32_to_cpu (ohci, ed->hwHeadP);
+ struct list_head *entry;
+ struct td *td;
temp = scnprintf (buf, size,
"ed/%p %cs dev%d ep%d%s max %d %08x%s%s %s",
@@ -440,9 +447,9 @@
u32 cbp, be;
td = list_entry (entry, struct td, td_list);
- info = le32_to_cpup (&td->hwINFO);
- cbp = le32_to_cpup (&td->hwCBP);
- be = le32_to_cpup (&td->hwBE);
+ info = hc32_to_cpup (ohci, &td->hwINFO);
+ cbp = hc32_to_cpup (ohci, &td->hwCBP);
+ be = hc32_to_cpup (ohci, &td->hwBE);
temp = scnprintf (buf, size,
"\n\ttd %p %s %d cc=%x urb %p (%08x)",
td,
@@ -542,7 +549,7 @@
/* show more info the first time around */
if (temp == seen_count) {
- u32 info = le32_to_cpu (ed->hwINFO);
+ u32 info = hc32_to_cpu (ohci, ed->hwINFO);
struct list_head *entry;
unsigned qlen = 0;
@@ -562,8 +569,9 @@
0x03ff & (info >> 16),
info,
(info & ED_SKIP) ? " K" : "",
- (ed->hwHeadP & cpu_to_le32(ED_H)) ?
- " H" : "");
+ (ed->hwHeadP &
+ cpu_to_hc32(ohci, ED_H)) ?
+ " H" : "");
size -= temp;
next += temp;
@@ -635,10 +643,10 @@
/* hcca */
if (ohci->hcca)
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 */
- rdata = ohci_readl (®s->fminterval);
+ rdata = ohci_readl (ohci, ®s->fminterval);
temp = scnprintf (next, size,
"fmintvl 0x%08x %sFSMPS=0x%04x FI=0x%04x\n",
rdata, (rdata >> 31) ? "FIT " : "",
@@ -646,20 +654,20 @@
size -= temp;
next += temp;
- rdata = ohci_readl (®s->fmremaining);
+ rdata = ohci_readl (ohci, ®s->fmremaining);
temp = scnprintf (next, size, "fmremaining 0x%08x %sFR=0x%04x\n",
rdata, (rdata >> 31) ? "FRT " : "",
rdata & 0x3fff);
size -= temp;
next += temp;
- rdata = ohci_readl (®s->periodicstart);
+ rdata = ohci_readl (ohci, ®s->periodicstart);
temp = scnprintf (next, size, "periodicstart 0x%04x\n",
rdata & 0x3fff);
size -= temp;
next += temp;
- rdata = ohci_readl (®s->lsthresh);
+ rdata = ohci_readl (ohci, ®s->lsthresh);
temp = scnprintf (next, size, "lsthresh 0x%04x\n",
rdata & 0x3fff);
size -= temp;
--- 1.40/drivers/usb/host/ohci-hub.c 2004-10-28 08:38:21 -07:00
+++ edited/drivers/usb/host/ohci-hub.c 2004-10-31 12:15:44 -08:00
@@ -58,14 +58,14 @@
spin_lock_irq (&ohci->lock);
- ohci->hc_control = ohci_readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_RESUME:
ohci_dbg (ohci, "resume/suspend?\n");
ohci->hc_control &= ~OHCI_CTRL_HCFS;
ohci->hc_control |= OHCI_USB_RESET;
- writel (ohci->hc_control, &ohci->regs->control);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
/* FALL THROUGH */
case OHCI_USB_RESET:
status = -EBUSY;
@@ -83,9 +83,9 @@
int limit;
ohci->hc_control &= ~OHCI_SCHED_ENABLES;
- writel (ohci->hc_control, &ohci->regs->control);
- ohci->hc_control = ohci_readl (&ohci->regs->control);
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+ ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrstatus);
/* sched disables take effect on the next frame,
* then the last WDH could take 6+ msec
@@ -95,15 +95,17 @@
while (limit > 0) {
udelay (250);
limit =- 250;
- if (ohci_readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
+ if (ohci_readl (ohci, &ohci->regs->intrstatus)
+ & OHCI_INTR_SF)
break;
}
dl_done_list (ohci, NULL);
mdelay (7);
}
dl_done_list (ohci, NULL);
- finish_unlinks (ohci, OHCI_FRAME_NO(ohci->hcca), NULL);
- writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+ finish_unlinks (ohci, ohci_frame_no(ohci), NULL);
+ ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
+ &ohci->regs->intrstatus);
/* maybe resume can wake root hub */
if (ohci->hcd.remote_wakeup)
@@ -114,8 +116,8 @@
/* Suspend hub */
ohci->hc_control &= ~OHCI_CTRL_HCFS;
ohci->hc_control |= OHCI_USB_SUSPEND;
- writel (ohci->hc_control, &ohci->regs->control);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
/* no resumes until devices finish suspending */
ohci->next_statechange = jiffies + msecs_to_jiffies (5);
@@ -153,7 +155,7 @@
return -EAGAIN;
spin_lock_irq (&ohci->lock);
- ohci->hc_control = ohci_readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
/* this can happen after suspend-to-disk */
ohci_dbg (ohci, "BIOS/SMM active, control %03x\n",
@@ -163,8 +165,8 @@
case OHCI_USB_SUSPEND:
ohci->hc_control &= ~(OHCI_CTRL_HCFS|OHCI_SCHED_ENABLES);
ohci->hc_control |= OHCI_USB_RESUME;
- writel (ohci->hc_control, &ohci->regs->control);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
ohci_dbg (ohci, "resume root hub\n");
break;
case OHCI_USB_RESUME:
@@ -191,19 +193,21 @@
temp = roothub_a (ohci) & RH_A_NDP;
enables = 0;
while (temp--) {
- u32 stat = ohci_readl (&ohci->regs->roothub.portstatus [temp]);
+ u32 stat = ohci_readl (ohci,
+ &ohci->regs->roothub.portstatus [temp]);
/* force global, not selective, resume */
if (!(stat & RH_PS_PSS))
continue;
- writel (RH_PS_POCI, &ohci->regs->roothub.portstatus [temp]);
+ ohci_writel (ohci, RH_PS_POCI,
+ &ohci->regs->roothub.portstatus [temp]);
}
/* Some controllers (lucent) need extra-long delays */
ohci->hcd.state = USB_STATE_RESUMING;
mdelay (20 /* usb 11.5.1.10 */ + 15);
- temp = ohci_readl (&ohci->regs->control);
+ temp = ohci_readl (ohci, &ohci->regs->control);
temp &= OHCI_CTRL_HCFS;
if (temp != OHCI_USB_RESUME) {
ohci_err (ohci, "controller won't resume\n");
@@ -211,32 +215,33 @@
}
/* disable old schedule state, reinit from scratch */
- writel (0, &ohci->regs->ed_controlhead);
- writel (0, &ohci->regs->ed_controlcurrent);
- writel (0, &ohci->regs->ed_bulkhead);
- writel (0, &ohci->regs->ed_bulkcurrent);
- writel (0, &ohci->regs->ed_periodcurrent);
- writel ((u32) ohci->hcca_dma, &ohci->regs->hcca);
+ ohci_writel (ohci, 0, &ohci->regs->ed_controlhead);
+ ohci_writel (ohci, 0, &ohci->regs->ed_controlcurrent);
+ ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead);
+ ohci_writel (ohci, 0, &ohci->regs->ed_bulkcurrent);
+ ohci_writel (ohci, 0, &ohci->regs->ed_periodcurrent);
+ ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
periodic_reinit (ohci);
/* interrupts might have been disabled */
- writel (OHCI_INTR_INIT, &ohci->regs->intrenable);
+ ohci_writel (ohci, OHCI_INTR_INIT, &ohci->regs->intrenable);
if (ohci->ed_rm_list)
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
- writel (ohci_readl (&ohci->regs->intrstatus), &ohci->regs->intrstatus);
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
+ ohci_writel (ohci, ohci_readl (ohci, &ohci->regs->intrstatus),
+ &ohci->regs->intrstatus);
/* Then re-enable operations */
- writel (OHCI_USB_OPER, &ohci->regs->control);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, OHCI_USB_OPER, &ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
msleep (3);
temp = OHCI_CONTROL_INIT | OHCI_USB_OPER;
if (ohci->hcd.can_wakeup)
temp |= OHCI_CTRL_RWC;
ohci->hc_control = temp;
- writel (temp, &ohci->regs->control);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, temp, &ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
/* TRSMRCY */
msleep (10);
@@ -251,13 +256,14 @@
temp = 0;
if (!ohci->ed_rm_list) {
if (ohci->ed_controltail) {
- writel (find_head (ohci->ed_controltail)->dma,
- &ohci->regs->ed_controlhead);
+ ohci_writel (ohci,
+ find_head (ohci->ed_controltail)->dma,
+ &ohci->regs->ed_controlhead);
enables |= OHCI_CTRL_CLE;
temp |= OHCI_CLF;
}
if (ohci->ed_bulktail) {
- writel (find_head (ohci->ed_bulktail)->dma,
+ ohci_writel (ohci, find_head (ohci->ed_bulktail)->dma,
&ohci->regs->ed_bulkhead);
enables |= OHCI_CTRL_BLE;
temp |= OHCI_BLF;
@@ -269,10 +275,10 @@
if (enables) {
ohci_dbg (ohci, "restarting schedules ... %08x\n", enables);
ohci->hc_control |= enables;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
if (temp)
- writel (temp, &ohci->regs->cmdstatus);
- (void) ohci_readl (&ohci->regs->control);
+ ohci_writel (ohci, temp, &ohci->regs->cmdstatus);
+ (void) ohci_readl (ohci, &ohci->regs->control);
}
ohci->hcd.state = USB_STATE_RUNNING;
@@ -322,8 +328,8 @@
if (ports > MAX_ROOT_PORTS) {
if (!HCD_IS_RUNNING(ohci->hcd.state))
return -ESHUTDOWN;
- ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n",
- ports, ohci_readl (&ohci->regs->roothub.a) & RH_A_NDP);
+ ohci_err (ohci, "bogus NDP=%d, rereads as NDP=%d\n", ports,
+ ohci_readl (ohci, &ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
return 0;
}
@@ -418,7 +424,7 @@
temp |= 0x0010;
else if (rh & RH_A_OCPM) /* per-port overcurrent reporting? */
temp |= 0x0008;
- desc->wHubCharacteristics = cpu_to_le16 (temp);
+ desc->wHubCharacteristics = cpu_to_hc16 (ohci, temp);
/* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */
rh = roothub_b (ohci);
@@ -444,12 +450,12 @@
port--;
/* start port reset before HNP protocol times out */
- status = ohci_readl(&ohci->regs->roothub.portstatus [port]);
+ status = ohci_readl(ohci, &ohci->regs->roothub.portstatus [port]);
if (!(status & RH_PS_CCS))
return -ENODEV;
/* khubd will finish the reset later */
- writel(RH_PS_PRS, &ohci->regs->roothub.portstatus [port]);
+ ohci_writel(ohci, RH_PS_PRS, &ohci->regs->roothub.portstatus [port]);
return 0;
}
@@ -486,7 +492,7 @@
{
u32 __iomem *portstat = &ohci->regs->roothub.portstatus [port];
u32 temp;
- u16 now = readl(&ohci->regs->fmnumber);
+ u16 now = ohci_readl(ohci, &ohci->regs->fmnumber);
u16 reset_done = now + PORT_RESET_MSEC;
/* build a "continuous enough" reset signal, with up to
@@ -496,7 +502,7 @@
do {
/* spin until any current reset finishes */
for (;;) {
- temp = ohci_readl (portstat);
+ temp = ohci_readl (ohci, portstat);
if (!(temp & RH_PS_PRS))
break;
udelay (500);
@@ -505,12 +511,12 @@
if (!(temp & RH_PS_CCS))
break;
if (temp & RH_PS_PRSC)
- writel (RH_PS_PRSC, portstat);
+ ohci_writel (ohci, RH_PS_PRSC, portstat);
/* start the next reset, sleep till it's probably done */
- writel (RH_PS_PRS, portstat);
+ ohci_writel (ohci, RH_PS_PRS, portstat);
msleep(PORT_RESET_HW_MSEC);
- now = readl(&ohci->regs->fmnumber);
+ now = ohci_readl(ohci, &ohci->regs->fmnumber);
} while (tick_before(now, reset_done));
/* caller synchronizes using PRSC */
}
@@ -532,7 +538,8 @@
case ClearHubFeature:
switch (wValue) {
case C_HUB_OVER_CURRENT:
- writel (RH_HS_OCIC, &ohci->regs->roothub.status);
+ ohci_writel (ohci, RH_HS_OCIC,
+ &ohci->regs->roothub.status);
case C_HUB_LOCAL_POWER:
break;
default:
@@ -575,8 +582,9 @@
default:
goto error;
}
- writel (temp, &ohci->regs->roothub.portstatus [wIndex]);
- // ohci_readl (&ohci->regs->roothub.portstatus [wIndex]);
+ ohci_writel (ohci, temp,
+ &ohci->regs->roothub.portstatus [wIndex]);
+ // ohci_readl (ohci, &ohci->regs->roothub.portstatus [wIndex]);
break;
case GetHubDescriptor:
ohci_hub_descriptor (ohci, (struct usb_hub_descriptor *) buf);
@@ -619,11 +627,11 @@
start_hnp(ohci);
else
#endif
- writel (RH_PS_PSS,
+ ohci_writel (ohci, RH_PS_PSS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_POWER:
- writel (RH_PS_PPS,
+ ohci_writel (ohci, RH_PS_PPS,
&ohci->regs->roothub.portstatus [wIndex]);
break;
case USB_PORT_FEAT_RESET:
--- 1.24/drivers/usb/host/ohci-mem.c 2004-10-30 15:10:57 -07:00
+++ edited/drivers/usb/host/ohci-mem.c 2004-10-31 12:15:44 -08:00
@@ -104,7 +104,7 @@
if (td) {
/* in case hc fetches it, make it look dead */
memset (td, 0, sizeof *td);
- td->hwNextTD = cpu_to_le32 (dma);
+ td->hwNextTD = cpu_to_hc32 (hc, dma);
td->td_dma = dma;
/* hashed in td_fill */
}
@@ -120,7 +120,7 @@
prev = &(*prev)->td_hash;
if (*prev)
*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);
dma_pool_free (hc->td_cache, td, td->td_dma);
}
--- 1.89/drivers/usb/host/ohci-hcd.c 2004-10-30 15:10:57 -07:00
+++ edited/drivers/usb/host/ohci-hcd.c 2004-10-31 12:15:44 -08:00
@@ -260,7 +260,7 @@
if (retval < 0)
goto fail0;
if (ed->type == PIPE_ISOCHRONOUS) {
- u16 frame = OHCI_FRAME_NO(ohci->hcca);
+ u16 frame = ohci_frame_no(ohci);
/* delay a few frames before the first TD */
frame += max_t (u16, 8, ed->interval);
@@ -403,14 +403,14 @@
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- return OHCI_FRAME_NO(ohci->hcca);
+ return ohci_frame_no(ohci);
}
static void ohci_usb_reset (struct ohci_hcd *ohci)
{
- ohci->hc_control = ohci_readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
ohci->hc_control &= OHCI_CTRL_RWC;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
}
/*-------------------------------------------------------------------------*
@@ -430,7 +430,8 @@
#ifndef IR_DISABLE
/* SMM owns the HC? not for long! */
- if (!no_handshake && ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ if (!no_handshake && ohci_readl (ohci,
+ &ohci->regs->control) & OHCI_CTRL_IR) {
ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n");
/* this timeout is arbitrary. we make it long, so systems
@@ -439,9 +440,9 @@
*/
temp = 500; /* arbitrary: five seconds */
- writel (OHCI_INTR_OC, &ohci->regs->intrenable);
- writel (OHCI_OCR, &ohci->regs->cmdstatus);
- while (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ ohci_writel (ohci, OHCI_INTR_OC, &ohci->regs->intrenable);
+ ohci_writel (ohci, OHCI_OCR, &ohci->regs->cmdstatus);
+ while (ohci_readl (ohci, &ohci->regs->control) & OHCI_CTRL_IR) {
msleep (10);
if (--temp == 0) {
ohci_err (ohci, "USB HC TakeOver failed!\n");
@@ -453,9 +454,9 @@
#endif
/* Disable HC interrupts */
- writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
// flush the writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
if (ohci->hcca)
return 0;
@@ -491,7 +492,7 @@
/* boot firmware should have set this up (5.1.1.3.1) */
if (first) {
- temp = ohci_readl (&ohci->regs->fminterval);
+ temp = ohci_readl (ohci, &ohci->regs->fminterval);
ohci->fminterval = temp & 0x3fff;
if (ohci->fminterval != FI)
ohci_dbg (ohci, "fminterval delta %d\n",
@@ -504,7 +505,7 @@
* saved if boot firmware (BIOS/SMM/...) told us it's connected
* (for OHCI integrated on mainboard, it normally is)
*/
- ohci->hc_control = ohci_readl (&ohci->regs->control);
+ ohci->hc_control = ohci_readl (ohci, &ohci->regs->control);
ohci_dbg (ohci, "resetting from state '%s', control = 0x%x\n",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
ohci->hc_control);
@@ -530,20 +531,20 @@
temp = 50 /* msec wait */;
break;
}
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
// flush the writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
msleep(temp);
if (power_switching) {
unsigned ports = roothub_a (ohci) & RH_A_NDP;
/* power down each port */
for (temp = 0; temp < ports; temp++)
- writel (RH_PS_LSDA,
+ ohci_writel (ohci, RH_PS_LSDA,
&ohci->regs->roothub.portstatus [temp]);
}
// flush those writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
/* 2msec timelimit here means no irqs/preempt */
@@ -551,9 +552,9 @@
retry:
/* HC Reset requires max 10 us delay */
- writel (OHCI_HCR, &ohci->regs->cmdstatus);
+ ohci_writel (ohci, OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */
- while ((ohci_readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
+ while ((ohci_readl (ohci, &ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
if (--temp == 0) {
spin_unlock_irq (&ohci->lock);
ohci_err (ohci, "USB HC reset timed out!\n");
@@ -572,27 +573,27 @@
* easily be a longstanding bug in chip init on Linux.
*/
if (ohci->flags & OHCI_QUIRK_INITRESET) {
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
// flush those writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
}
- writel (ohci->fminterval, &ohci->regs->fminterval);
+ ohci_writel (ohci, ohci->fminterval, &ohci->regs->fminterval);
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
- writel (0, &ohci->regs->ed_controlhead);
- writel (0, &ohci->regs->ed_bulkhead);
+ ohci_writel (ohci, 0, &ohci->regs->ed_controlhead);
+ ohci_writel (ohci, 0, &ohci->regs->ed_bulkhead);
/* a reset clears this */
- writel ((u32) ohci->hcca_dma, &ohci->regs->hcca);
+ ohci_writel (ohci, (u32) ohci->hcca_dma, &ohci->regs->hcca);
periodic_reinit (ohci);
/* some OHCI implementations are finicky about how they init.
* bogus values here mean not even enumeration could work.
*/
- if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
- || !ohci_readl (&ohci->regs->periodicstart)) {
+ if ((ohci_readl (ohci, &ohci->regs->fminterval) & 0x3fff0000) == 0
+ || !ohci_readl (ohci, &ohci->regs->periodicstart)) {
if (!(ohci->flags & OHCI_QUIRK_INITRESET)) {
ohci->flags |= OHCI_QUIRK_INITRESET;
ohci_dbg (ohci, "enabling initreset quirk\n");
@@ -600,24 +601,24 @@
}
spin_unlock_irq (&ohci->lock);
ohci_err (ohci, "init err (%08x %04x)\n",
- ohci_readl (&ohci->regs->fminterval),
- ohci_readl (&ohci->regs->periodicstart));
+ ohci_readl (ohci, &ohci->regs->fminterval),
+ ohci_readl (ohci, &ohci->regs->periodicstart));
return -EOVERFLOW;
}
/* start controller operations */
ohci->hc_control &= OHCI_CTRL_RWC;
ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
ohci->hcd.state = USB_STATE_RUNNING;
/* wake on ConnectStatusChange, matching external hubs */
- writel (RH_HS_DRWE, &ohci->regs->roothub.status);
+ ohci_writel (ohci, RH_HS_DRWE, &ohci->regs->roothub.status);
/* Choose the interrupts we care about now, others later on demand */
mask = OHCI_INTR_INIT;
- writel (mask, &ohci->regs->intrstatus);
- writel (mask, &ohci->regs->intrenable);
+ ohci_writel (ohci, mask, &ohci->regs->intrstatus);
+ ohci_writel (ohci, mask, &ohci->regs->intrenable);
/* handle root hub init quirks ... */
temp = roothub_a (ohci);
@@ -638,11 +639,12 @@
*/
temp |= RH_A_NPS;
}
- writel (temp, &ohci->regs->roothub.a);
- writel (RH_HS_LPSC, &ohci->regs->roothub.status);
- writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b);
+ ohci_writel (ohci, temp, &ohci->regs->roothub.a);
+ ohci_writel (ohci, RH_HS_LPSC, &ohci->regs->roothub.status);
+ ohci_writel (ohci, power_switching ? RH_B_PPCM : 0,
+ &ohci->regs->roothub.b);
// flush those writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
spin_unlock_irq (&ohci->lock);
@@ -665,7 +667,7 @@
if (!udev) {
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
return -ENOMEM;
}
@@ -674,7 +676,7 @@
usb_put_dev (udev);
disable (ohci);
ohci->hc_control &= ~OHCI_CTRL_HCFS;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
return -ENODEV;
}
if (ohci->power_budget)
@@ -697,17 +699,18 @@
/* we can eliminate a (slow) ohci_readl()
if _only_ WDH caused this irq */
if ((ohci->hcca->done_head != 0)
- && ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
+ && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head)
+ & 0x01)) {
ints = OHCI_INTR_WDH;
/* cardbus/... hardware gone before remove() */
- } else if ((ints = ohci_readl (®s->intrstatus)) == ~(u32)0) {
+ } else if ((ints = ohci_readl (ohci, ®s->intrstatus)) == ~(u32)0) {
disable (ohci);
ohci_dbg (ohci, "device removed!\n");
return IRQ_HANDLED;
/* interrupt for some other device? */
- } else if ((ints &= ohci_readl (®s->intrenable)) == 0) {
+ } else if ((ints &= ohci_readl (ohci, ®s->intrenable)) == 0) {
return IRQ_NONE;
}
@@ -727,12 +730,12 @@
if (ints & OHCI_INTR_WDH) {
if (HCD_IS_RUNNING(hcd->state))
- writel (OHCI_INTR_WDH, ®s->intrdisable);
+ ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrdisable);
spin_lock (&ohci->lock);
dl_done_list (ohci, ptregs);
spin_unlock (&ohci->lock);
if (HCD_IS_RUNNING(hcd->state))
- writel (OHCI_INTR_WDH, ®s->intrenable);
+ ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable);
}
/* could track INTR_SO to reduce available PCI/... bandwidth */
@@ -742,18 +745,17 @@
*/
spin_lock (&ohci->lock);
if (ohci->ed_rm_list)
- finish_unlinks (ohci, OHCI_FRAME_NO(ohci->hcca),
- ptregs);
+ finish_unlinks (ohci, ohci_frame_no(ohci), ptregs);
if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
&& HCD_IS_RUNNING(ohci->hcd.state))
- writel (OHCI_INTR_SF, ®s->intrdisable);
+ ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable);
spin_unlock (&ohci->lock);
if (HCD_IS_RUNNING(ohci->hcd.state)) {
- writel (ints, ®s->intrstatus);
- writel (OHCI_INTR_MIE, ®s->intrenable);
+ ohci_writel (ohci, ints, ®s->intrstatus);
+ ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable);
// flush those writes
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
}
return IRQ_HANDLED;
@@ -773,7 +775,7 @@
flush_scheduled_work();
ohci_usb_reset (ohci);
- writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+ ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
remove_debug_files (ohci);
ohci_mem_cleanup (ohci);
@@ -815,7 +817,7 @@
switch (ed->state) {
case ED_OPER:
ed->state = ED_UNLINK;
- ed->hwINFO |= cpu_to_le32(ED_DEQUEUE);
+ ed->hwINFO |= cpu_to_hc32(ohci, ED_DEQUEUE);
ed_deschedule (ohci, ed);
ed->ed_next = ohci->ed_rm_list;
@@ -859,7 +861,7 @@
*/
i = roothub_a (ohci) & RH_A_NDP;
while (i--)
- writel (RH_PS_PSS,
+ ohci_writel (ohci, RH_PS_PSS,
&ohci->regs->roothub.portstatus [temp]);
ohci_dbg (ohci, "restart complete\n");
ohci->hcd.state = USB_STATE_RUNNING;
--- 1.69/drivers/usb/host/ohci-q.c 2004-10-30 15:10:57 -07:00
+++ edited/drivers/usb/host/ohci-q.c 2004-10-31 12:15:44 -08:00
@@ -78,7 +78,7 @@
if (hcd_to_bus (&ohci->hcd)->bandwidth_isoc_reqs == 0
&& hcd_to_bus (&ohci->hcd)->bandwidth_int_reqs == 0) {
ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_IE);
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
}
}
@@ -131,12 +131,12 @@
unsigned i;
ohci_vdbg (ohci, "link %sed %p branch %d [%dus.], interval %d\n",
- (ed->hwINFO & cpu_to_le32 (ED_ISO)) ? "iso " : "",
+ (ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
ed, ed->branch, ed->load, ed->interval);
for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
struct ed **prev = &ohci->periodic [i];
- __le32 *prev_p = &ohci->hcca->int_table [i];
+ __hc32 *prev_p = &ohci->hcca->int_table [i];
struct ed *here = *prev;
/* sorting each branch by period (slow before fast)
@@ -156,7 +156,7 @@
ed->hwNextED = *prev_p;
wmb ();
*prev = ed;
- *prev_p = cpu_to_le32(ed->dma);
+ *prev_p = cpu_to_hc32(ohci, ed->dma);
wmb();
}
ohci->load [i] += ed->load;
@@ -193,17 +193,20 @@
case PIPE_CONTROL:
if (ohci->ed_controltail == NULL) {
WARN_ON (ohci->hc_control & OHCI_CTRL_CLE);
- writel (ed->dma, &ohci->regs->ed_controlhead);
+ ohci_writel (ohci, ed->dma,
+ &ohci->regs->ed_controlhead);
} else {
ohci->ed_controltail->ed_next = ed;
- ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma);
+ ohci->ed_controltail->hwNextED = cpu_to_hc32 (ohci,
+ ed->dma);
}
ed->ed_prev = ohci->ed_controltail;
if (!ohci->ed_controltail && !ohci->ed_rm_list) {
wmb();
ohci->hc_control |= OHCI_CTRL_CLE;
- writel (0, &ohci->regs->ed_controlcurrent);
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, 0, &ohci->regs->ed_controlcurrent);
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
}
ohci->ed_controltail = ed;
break;
@@ -211,17 +214,19 @@
case PIPE_BULK:
if (ohci->ed_bulktail == NULL) {
WARN_ON (ohci->hc_control & OHCI_CTRL_BLE);
- writel (ed->dma, &ohci->regs->ed_bulkhead);
+ ohci_writel (ohci, ed->dma, &ohci->regs->ed_bulkhead);
} else {
ohci->ed_bulktail->ed_next = ed;
- ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma);
+ ohci->ed_bulktail->hwNextED = cpu_to_hc32 (ohci,
+ ed->dma);
}
ed->ed_prev = ohci->ed_bulktail;
if (!ohci->ed_bulktail && !ohci->ed_rm_list) {
wmb();
ohci->hc_control |= OHCI_CTRL_BLE;
- writel (0, &ohci->regs->ed_bulkcurrent);
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, 0, &ohci->regs->ed_bulkcurrent);
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
}
ohci->ed_bulktail = ed;
break;
@@ -257,7 +262,7 @@
for (i = ed->branch; i < NUM_INTS; i += ed->interval) {
struct ed *temp;
struct ed **prev = &ohci->periodic [i];
- __le32 *prev_p = &ohci->hcca->int_table [i];
+ __hc32 *prev_p = &ohci->hcca->int_table [i];
while (*prev && (temp = *prev) != ed) {
prev_p = &temp->hwNextED;
@@ -272,7 +277,7 @@
hcd_to_bus (&ohci->hcd)->bandwidth_allocated -= ed->load / ed->interval;
ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n",
- (ed->hwINFO & cpu_to_le32 (ED_ISO)) ? "iso " : "",
+ (ed->hwINFO & cpu_to_hc32 (ohci, ED_ISO)) ? "iso " : "",
ed, ed->branch, ed->load, ed->interval);
}
@@ -300,7 +305,7 @@
*/
static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
{
- ed->hwINFO |= cpu_to_le32 (ED_SKIP);
+ ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
wmb ();
ed->state = ED_UNLINK;
@@ -320,10 +325,12 @@
if (ed->ed_prev == NULL) {
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_CLE;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
// a ohci_readl() later syncs CLE with the HC
} else
- writel (le32_to_cpup (&ed->hwNextED),
+ ohci_writel (ohci,
+ hc32_to_cpup (ohci, &ed->hwNextED),
&ohci->regs->ed_controlhead);
} else {
ed->ed_prev->ed_next = ed->ed_next;
@@ -344,10 +351,12 @@
if (ed->ed_prev == NULL) {
if (!ed->hwNextED) {
ohci->hc_control &= ~OHCI_CTRL_BLE;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
// a ohci_readl() later syncs BLE with the HC
} else
- writel (le32_to_cpup (&ed->hwNextED),
+ ohci_writel (ohci,
+ hc32_to_cpup (ohci, &ed->hwNextED),
&ohci->regs->ed_bulkhead);
} else {
ed->ed_prev->ed_next = ed->ed_next;
@@ -416,7 +425,7 @@
goto done;
}
ed->dummy = td;
- ed->hwTailP = cpu_to_le32 (td->td_dma);
+ ed->hwTailP = cpu_to_hc32 (ohci, td->td_dma);
ed->hwHeadP = ed->hwTailP; /* ED_C, ED_H zeroed */
ed->state = ED_IDLE;
ed->type = type;
@@ -450,7 +459,7 @@
/ 1000;
}
}
- ed->hwINFO = cpu_to_le32(info);
+ ed->hwINFO = cpu_to_hc32(ohci, info);
}
done:
@@ -468,7 +477,7 @@
*/
static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed)
{
- ed->hwINFO |= cpu_to_le32 (ED_DEQUEUE);
+ ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE);
ed_deschedule (ohci, ed);
/* rm_list is just singly linked, for simplicity */
@@ -477,17 +486,17 @@
ohci->ed_rm_list = ed;
/* enable SOF interrupt */
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrstatus);
+ ohci_writel (ohci, OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those writes, and get latest HCCA contents
- (void) ohci_readl (&ohci->regs->control);
+ (void) ohci_readl (ohci, &ohci->regs->control);
/* SF interrupt might get delayed; record the frame counter value that
* indicates when the HC isn't looking at it, so concurrent unlinks
* behave. frame_no wraps every 2^16 msec, and changes right before
* SF is triggered.
*/
- ed->tick = OHCI_FRAME_NO(ohci->hcca) + 1;
+ ed->tick = ohci_frame_no(ohci) + 1;
}
@@ -539,19 +548,19 @@
if (!len)
data = 0;
- td->hwINFO = cpu_to_le32 (info);
+ td->hwINFO = cpu_to_hc32 (ohci, info);
if (is_iso) {
- td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
- td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000);
+ td->hwCBP = cpu_to_hc32 (ohci, data & 0xFFFFF000);
+ td->hwPSW [0] = cpu_to_hc16 (ohci, (data & 0x0FFF) | 0xE000);
td->ed->last_iso = info & 0xffff;
} else {
- td->hwCBP = cpu_to_le32 (data);
+ td->hwCBP = cpu_to_hc32 (ohci, data);
}
if (data)
- td->hwBE = cpu_to_le32 (data + len - 1);
+ td->hwBE = cpu_to_hc32 (ohci, data + len - 1);
else
td->hwBE = 0;
- td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
+ td->hwNextTD = cpu_to_hc32 (ohci, td_pt->td_dma);
/* append to queue */
list_add_tail (&td->td_list, &td->ed->td_list);
@@ -592,7 +601,7 @@
if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) {
usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe),
is_out, 1);
- urb_priv->ed->hwHeadP &= ~cpu_to_le32 (ED_C);
+ urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C);
}
urb_priv->td_cnt = 0;
@@ -641,7 +650,7 @@
/* maybe kickstart bulk list */
if (urb_priv->ed->type == PIPE_BULK) {
wmb ();
- writel (OHCI_BLF, &ohci->regs->cmdstatus);
+ ohci_writel (ohci, OHCI_BLF, &ohci->regs->cmdstatus);
}
break;
@@ -663,7 +672,7 @@
td_fill (ohci, info, data, 0, urb, cnt++);
/* maybe kickstart control list */
wmb ();
- writel (OHCI_CLF, &ohci->regs->cmdstatus);
+ ohci_writel (ohci, OHCI_CLF, &ohci->regs->cmdstatus);
break;
/* ISO has no retransmit, so no toggle; and it uses special TDs.
@@ -692,7 +701,7 @@
if (periodic) {
wmb ();
ohci->hc_control |= OHCI_CTRL_PLE|OHCI_CTRL_IE;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control, &ohci->regs->control);
}
// ASSERT (urb_priv->length == cnt);
@@ -707,14 +716,14 @@
*/
static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td)
{
- u32 tdINFO = le32_to_cpup (&td->hwINFO);
+ u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO);
int cc = 0;
list_del (&td->td_list);
/* ISO ... drivers see per-TD length/status */
if (tdINFO & TD_ISO) {
- u16 tdPSW = le16_to_cpu (td->hwPSW [0]);
+ u16 tdPSW = hc16_to_cpu (ohci, td->hwPSW [0]);
int dlen = 0;
/* NOTE: assumes FC in tdINFO == 0 (and MAXPSW == 1) */
@@ -746,7 +755,7 @@
*/
} else {
int type = usb_pipetype (urb->pipe);
- u32 tdBE = le32_to_cpup (&td->hwBE);
+ u32 tdBE = hc32_to_cpup (ohci, &td->hwBE);
cc = TD_CC_GET (tdINFO);
@@ -767,7 +776,7 @@
urb->actual_length += tdBE - td->data_dma + 1;
else
urb->actual_length +=
- le32_to_cpup (&td->hwCBP)
+ hc32_to_cpup (ohci, &td->hwCBP)
- td->data_dma;
}
@@ -788,14 +797,14 @@
struct urb *urb = td->urb;
struct ed *ed = td->ed;
struct list_head *tmp = td->td_list.next;
- __le32 toggle = ed->hwHeadP & cpu_to_le32 (ED_C);
+ __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C);
/* clear ed halt; this is the td that caused it, but keep it inactive
* until its urb->complete() has a chance to clean up.
*/
- ed->hwINFO |= cpu_to_le32 (ED_SKIP);
+ ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP);
wmb ();
- ed->hwHeadP &= ~cpu_to_le32 (ED_H);
+ ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H);
/* put any later tds from this urb onto the donelist, after 'td',
* order won't matter here: no errors, and nothing was transferred.
@@ -803,7 +812,7 @@
*/
while (tmp != &ed->td_list) {
struct td *next;
- __le32 info;
+ __hc32 info;
next = list_entry (tmp, struct td, td_list);
tmp = next->td_list.next;
@@ -819,8 +828,8 @@
* and clear ED_SKIP.
*/
info = next->hwINFO;
- info |= cpu_to_le32 (TD_DONE);
- info &= ~cpu_to_le32 (TD_CC);
+ info |= cpu_to_hc32 (ohci, TD_DONE);
+ info &= ~cpu_to_hc32 (ohci, TD_CC);
next->hwINFO = info;
next->next_dl_td = rev;
@@ -848,7 +857,7 @@
urb, urb->dev->devpath,
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
- le32_to_cpu (td->hwINFO),
+ hc32_to_cpu (ohci, td->hwINFO),
cc, cc_to_error [cc]);
}
@@ -864,7 +873,7 @@
struct td *td_rev = NULL;
struct td *td = NULL;
- td_dma = le32_to_cpup (&ohci->hcca->done_head);
+ td_dma = hc32_to_cpup (ohci, &ohci->hcca->done_head);
ohci->hcca->done_head = 0;
wmb();
@@ -880,20 +889,20 @@
break;
}
- td->hwINFO |= cpu_to_le32 (TD_DONE);
- cc = TD_CC_GET (le32_to_cpup (&td->hwINFO));
+ td->hwINFO |= cpu_to_hc32 (ohci, TD_DONE);
+ cc = TD_CC_GET (hc32_to_cpup (ohci, &td->hwINFO));
/* Non-iso endpoints can halt on error; un-halt,
* and dequeue any other TDs from this urb.
* No other TD could have caused the halt.
*/
if (cc != TD_CC_NOERROR
- && (td->ed->hwHeadP & cpu_to_le32 (ED_H)))
+ && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H)))
td_rev = ed_halted (ohci, td, cc, td_rev);
td->next_dl_td = td_rev;
td_rev = td;
- td_dma = le32_to_cpup (&td->hwNextTD);
+ td_dma = hc32_to_cpup (ohci, &td->hwNextTD);
}
return td_rev;
}
@@ -910,7 +919,7 @@
for (last = &ohci->ed_rm_list, ed = *last; ed != NULL; ed = *last) {
struct list_head *entry, *tmp;
int completed, modified;
- __le32 *prev;
+ __hc32 *prev;
/* only take off EDs that the HC isn't using, accounting for
* frame counter wraps and EDs with partially retired TDs
@@ -928,7 +937,8 @@
td = list_entry (ed->td_list.next, struct td,
td_list);
- head = le32_to_cpu (ed->hwHeadP) & TD_MASK;
+ head = hc32_to_cpu (ohci, ed->hwHeadP) &
+ TD_MASK;
/* INTR_WDH may need to clean up first */
if (td->td_dma != head)
@@ -959,7 +969,7 @@
struct td *td;
struct urb *urb;
urb_priv_t *urb_priv;
- __le32 savebits;
+ __hc32 savebits;
td = list_entry (entry, struct td, td_list);
urb = td->urb;
@@ -971,7 +981,7 @@
}
/* patch pointer hc uses */
- savebits = *prev & ~cpu_to_le32 (TD_MASK);
+ savebits = *prev & ~cpu_to_hc32 (ohci, TD_MASK);
*prev = td->hwNextTD | savebits;
/* HC may have partly processed this TD */
@@ -989,10 +999,10 @@
/* ED's now officially unlinked, hc doesn't see */
ed->state = ED_IDLE;
- ed->hwHeadP &= ~cpu_to_le32(ED_H);
+ ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H);
ed->hwNextED = 0;
wmb ();
- ed->hwINFO &= ~cpu_to_le32 (ED_SKIP | ED_DEQUEUE);
+ ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE);
/* but if there's work queued, reschedule */
if (!list_empty (&ed->td_list)) {
@@ -1014,24 +1024,27 @@
command |= OHCI_CLF;
if (!(ohci->hc_control & OHCI_CTRL_CLE)) {
control |= OHCI_CTRL_CLE;
- writel (0, &ohci->regs->ed_controlcurrent);
+ ohci_writel (ohci, 0,
+ &ohci->regs->ed_controlcurrent);
}
}
if (ohci->ed_bulktail) {
command |= OHCI_BLF;
if (!(ohci->hc_control & OHCI_CTRL_BLE)) {
control |= OHCI_CTRL_BLE;
- writel (0, &ohci->regs->ed_bulkcurrent);
+ ohci_writel (ohci, 0,
+ &ohci->regs->ed_bulkcurrent);
}
}
/* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */
if (control) {
ohci->hc_control |= control;
- writel (ohci->hc_control, &ohci->regs->control);
+ ohci_writel (ohci, ohci->hc_control,
+ &ohci->regs->control);
}
if (command)
- writel (command, &ohci->regs->cmdstatus);
+ ohci_writel (ohci, command, &ohci->regs->cmdstatus);
}
}
@@ -1071,19 +1084,19 @@
start_ed_unlink (ohci, ed);
/* ... reenabling halted EDs only after fault cleanup */
- } else if ((ed->hwINFO & cpu_to_le32 (ED_SKIP | ED_DEQUEUE))
- == cpu_to_le32 (ED_SKIP)) {
+ } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE))
+ == cpu_to_hc32 (ohci, ED_SKIP)) {
td = list_entry (ed->td_list.next, struct td, td_list);
- if (!(td->hwINFO & cpu_to_le32 (TD_DONE))) {
- ed->hwINFO &= ~cpu_to_le32 (ED_SKIP);
+ if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) {
+ ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP);
/* ... hc may need waking-up */
switch (ed->type) {
case PIPE_CONTROL:
- writel (OHCI_CLF,
+ ohci_writel (ohci, OHCI_CLF,
&ohci->regs->cmdstatus);
break;
case PIPE_BULK:
- writel (OHCI_BLF,
+ ohci_writel (ohci, OHCI_BLF,
&ohci->regs->cmdstatus);
break;
}
--- 1.40/drivers/usb/host/ohci.h 2004-10-30 15:10:57 -07:00
+++ edited/drivers/usb/host/ohci.h 2004-10-31 12:15:44 -08:00
@@ -6,6 +6,14 @@
*
* This file is licenced under the GPL.
*/
+
+/*
+ * __hc32 and __hc16 are "Host Controller" types, they may be equivalent to
+ * __leXX (normally) or __beXX (given OHCI_BIG_ENDIAN), depending on the
+ * host controller implementation.
+ */
+typedef __u32 __bitwise __hc32;
+typedef __u16 __bitwise __hc16;
/*
* OHCI Endpoint Descriptor (ED) ... holds TD queue
@@ -15,8 +23,8 @@
* both EHCI and UHCI call similar structures a "QH".
*/
struct ed {
- /* first fields are hardware-specified, le32 */
- __le32 hwINFO; /* endpoint config bitmap */
+ /* first fields are hardware-specified */
+ __hc32 hwINFO; /* endpoint config bitmap */
/* info bits defined by hcd */
#define ED_DEQUEUE (1 << 27)
/* info bits defined by the hardware */
@@ -25,11 +33,11 @@
#define ED_LOWSPEED (1 << 13)
#define ED_OUT (0x01 << 11)
#define ED_IN (0x02 << 11)
- __le32 hwTailP; /* tail of TD list */
- __le32 hwHeadP; /* head of TD list (hc r/w) */
+ __hc32 hwTailP; /* tail of TD list */
+ __hc32 hwHeadP; /* head of TD list (hc r/w) */
#define ED_C (0x02) /* toggle carry */
#define ED_H (0x01) /* halted */
- __le32 hwNextED; /* next ED in list */
+ __hc32 hwNextED; /* next ED in list */
/* rest are purely for the driver's use */
dma_addr_t dma; /* addr of ED */
@@ -69,8 +77,8 @@
* and 4.3.2 (iso)
*/
struct td {
- /* first fields are hardware-specified, le32 */
- __le32 hwINFO; /* transfer info bitmask */
+ /* first fields are hardware-specified */
+ __hc32 hwINFO; /* transfer info bitmask */
/* hwINFO bits for both general and iso tds: */
#define TD_CC 0xf0000000 /* condition code */
@@ -99,13 +107,13 @@
/* (no hwINFO #defines yet for iso tds) */
- __le32 hwCBP; /* Current Buffer Pointer (or 0) */
- __le32 hwNextTD; /* Next TD Pointer */
- __le32 hwBE; /* Memory Buffer End Pointer */
+ __hc32 hwCBP; /* Current Buffer Pointer (or 0) */
+ __hc32 hwNextTD; /* Next TD Pointer */
+ __hc32 hwBE; /* Memory Buffer End Pointer */
/* PSW is only for ISO */
#define MAXPSW 1 /* hardware allows 8 */
- __le16 hwPSW [MAXPSW];
+ __hc16 hwPSW [MAXPSW];
/* rest are purely for the driver's use */
__u8 index;
@@ -170,20 +178,20 @@
*/
struct ohci_hcca {
#define NUM_INTS 32
- __le32 int_table [NUM_INTS]; /* periodic schedule */
+ __hc32 int_table [NUM_INTS]; /* periodic schedule */
/*
* OHCI defines u16 frame_no, followed by u16 zero pad.
* Since some processors can't do 16 bit bus accesses,
* portable access must be a 32 bit byteswapped access.
*/
- __le32 frame_no; /* current frame number */
-#define OHCI_FRAME_NO(hccap) ((u16)le32_to_cpup(&(hccap)->frame_no))
- __le32 done_head; /* info returned for an interrupt */
+ __hc32 frame_no; /* current frame number */
+ __hc32 done_head; /* info returned for an interrupt */
u8 reserved_for_hc [116];
u8 what [4]; /* spec only identifies 252 bytes :) */
} __attribute__ ((aligned(256)));
+#define ohci_frame_no(ohci) ((u16)hc32_to_cpup(ohci,&(ohci)->hcca->frame_no))
/*
* This is the structure of the OHCI controller's memory mapped I/O region.
@@ -192,36 +200,36 @@
*/
struct ohci_regs {
/* control and status registers (section 7.1) */
- __u32 revision;
- __u32 control;
- __u32 cmdstatus;
- __u32 intrstatus;
- __u32 intrenable;
- __u32 intrdisable;
+ __hc32 revision;
+ __hc32 control;
+ __hc32 cmdstatus;
+ __hc32 intrstatus;
+ __hc32 intrenable;
+ __hc32 intrdisable;
/* memory pointers (section 7.2) */
- __u32 hcca;
- __u32 ed_periodcurrent;
- __u32 ed_controlhead;
- __u32 ed_controlcurrent;
- __u32 ed_bulkhead;
- __u32 ed_bulkcurrent;
- __u32 donehead;
+ __hc32 hcca;
+ __hc32 ed_periodcurrent;
+ __hc32 ed_controlhead;
+ __hc32 ed_controlcurrent;
+ __hc32 ed_bulkhead;
+ __hc32 ed_bulkcurrent;
+ __hc32 donehead;
/* frame counters (section 7.3) */
- __u32 fminterval;
- __u32 fmremaining;
- __u32 fmnumber;
- __u32 periodicstart;
- __u32 lsthresh;
+ __hc32 fminterval;
+ __hc32 fmremaining;
+ __hc32 fmnumber;
+ __hc32 periodicstart;
+ __hc32 lsthresh;
/* Root hub ports (section 7.4) */
struct ohci_roothub_regs {
- __u32 a;
- __u32 b;
- __u32 status;
+ __hc32 a;
+ __hc32 b;
+ __hc32 status;
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports (RH_A_NDP) */
- __u32 portstatus [MAX_ROOT_PORTS];
+ __hc32 portstatus [MAX_ROOT_PORTS];
} roothub;
/* and optional "legacy support" registers (appendix B) at 0x0100 */
@@ -387,6 +395,7 @@
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */
+#define OHCI_BIG_ENDIAN 0x08 /* big endian HC */
// there are also chip quirks/bugs in init logic
/*
@@ -399,24 +408,6 @@
/*-------------------------------------------------------------------------*/
-static inline void disable (struct ohci_hcd *ohci)
-{
- ohci->hcd.state = USB_STATE_HALT;
-}
-
-#define FI 0x2edf /* 12000 bits per frame (-1) */
-#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
-#define LSTHRESH 0x628 /* lowspeed bit threshold */
-
-static inline void periodic_reinit (struct ohci_hcd *ohci)
-{
- u32 fi = ohci->fminterval & 0x0ffff;
-
- writel (((9 * fi) / 10) & 0x3fff, &ohci->regs->periodicstart);
-}
-
-/*-------------------------------------------------------------------------*/
-
#ifndef DEBUG
#define STUB_DEBUG_FILES
#endif /* DEBUG */
@@ -438,44 +429,162 @@
/*-------------------------------------------------------------------------*/
+/*
+ * While most USB host controllers implement their registers and
+ * in-memory communication descriptors in little-endian format,
+ * a minority (notably the IBM STB04XXX and the Motorola MPC5200
+ * processors) implement them in big endian format.
+ *
+ * This attempts to support either format at compile time without a
+ * runtime penalty, or both formats with the additional overhead
+ * of checking a flag bit.
+ */
+
+#ifdef CONFIG_USB_OHCI_BIG_ENDIAN
+
+#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN
+#define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */
+#else
+#define big_endian(ohci) 1 /* only big endian */
+#endif
+
+/*
+ * Big-endian read/write functions are arch-specific.
+ * Other arches can be added if/when they're needed.
+ */
+#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 ohci_readl (const struct ohci_hcd *ohci,
+ __hc32 __iomem * regs)
+{
+ return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs);
+}
+
+static inline void ohci_writel (const struct ohci_hcd *ohci,
+ const unsigned int val, __hc32 __iomem *regs)
+{
+ big_endian(ohci) ? writel_be (val, regs) :
+ writel (val, (__force u32 *)regs);
+}
+
+#else /* !CONFIG_USB_OHCI_BIG_ENDIAN */
+
+#define big_endian(ohci) 0 /* only little endian */
+
#ifdef CONFIG_ARCH_LH7A404
/* Marc Singer: at the time this code was written, the LH7A404
* had a problem reading the USB host registers. This
* implementation of the ohci_readl function performs the read
* twice as a work-around.
*/
-static inline unsigned int ohci_readl (void* regs)
+static inline unsigned int
+ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs)
{
- *(volatile unsigned int*) regs;
- return *(volatile unsigned int*) regs;
+ *(volatile __force unsigned int*) regs;
+ return *(volatile __force unsigned int*) regs;
}
#else
/* Standard version of ohci_readl uses standard, platform
* specific implementation. */
-static inline unsigned int ohci_readl (void __iomem * regs)
+static inline unsigned int
+ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs)
{
- return readl (regs);
+ return readl ((__force u32 *)regs);
}
#endif
+static inline void ohci_writel (const struct ohci_hcd *ohci,
+ const unsigned int val, __hc32 __iomem *regs)
+{
+ writel (val, (__force u32 *)regs);
+}
+
+#endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */
+
+/*-------------------------------------------------------------------------*/
+
+/* cpu to ohci */
+static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x)
+{
+ return big_endian(ohci) ? cpu_to_be16(x) : cpu_to_le16(x);
+}
+
+static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x)
+{
+ return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x);
+}
+
+static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x)
+{
+ return big_endian(ohci) ? cpu_to_be32(x) : cpu_to_le32(x);
+}
+
+static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x)
+{
+ return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x);
+}
+
+/* ohci to cpu */
+static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x)
+{
+ return big_endian(ohci) ? be16_to_cpu(x) : le16_to_cpu(x);
+}
+
+static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x)
+{
+ return big_endian(ohci) ? be16_to_cpup(x) : le16_to_cpup(x);
+}
+
+static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x)
+{
+ return big_endian(ohci) ? be32_to_cpu(x) : le32_to_cpu(x);
+}
+
+static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x)
+{
+ return big_endian(ohci) ? be32_to_cpup(x) : le32_to_cpup(x);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static inline void disable (struct ohci_hcd *ohci)
+{
+ ohci->hcd.state = USB_STATE_HALT;
+}
+
+#define FI 0x2edf /* 12000 bits per frame (-1) */
+#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
+#define LSTHRESH 0x628 /* lowspeed bit threshold */
+
+static inline void periodic_reinit (struct ohci_hcd *ohci)
+{
+ u32 fi = ohci->fminterval & 0x0ffff;
+
+ ohci_writel (ohci, ((9 * fi) / 10) & 0x3fff,
+ &ohci->regs->periodicstart);
+}
+
/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
* The erratum (#4) description is incorrect. AMD's workaround waits
* till some bits (mostly reserved) are clear; ok for all revs.
*/
#define read_roothub(hc, register, mask) ({ \
- u32 temp = ohci_readl (&hc->regs->roothub.register); \
+ u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \
if (temp == -1) \
disable (hc); \
else if (hc->flags & OHCI_QUIRK_AMD756) \
while (temp & mask) \
- temp = ohci_readl (&hc->regs->roothub.register); \
+ temp = ohci_readl (hc, &hc->regs->roothub.register); \
temp; })
static u32 roothub_a (struct ohci_hcd *hc)
{ return read_roothub (hc, a, 0xfc0fe000); }
static inline u32 roothub_b (struct ohci_hcd *hc)
- { return ohci_readl (&hc->regs->roothub.b); }
+ { return ohci_readl (hc, &hc->regs->roothub.b); }
static inline u32 roothub_status (struct ohci_hcd *hc)
- { return ohci_readl (&hc->regs->roothub.status); }
+ { return ohci_readl (hc, &hc->regs->roothub.status); }
static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }