in host/u132-hcd.c [1586:1764]
static int u132_run(struct u132 *u132)
{
int retval;
u32 control;
u32 status;
u32 fminterval;
u32 periodicstart;
u32 cmdstatus;
u32 roothub_a;
int mask = OHCI_INTR_INIT;
int first = u132->hc_fminterval == 0;
int sleep_time = 0;
int reset_timeout = 30; /* ... allow extra time */
u132_disable(u132);
if (first) {
u32 temp;
retval = u132_read_pcimem(u132, fminterval, &temp);
if (retval)
return retval;
u132->hc_fminterval = temp & 0x3fff;
u132->hc_fminterval |= FSMP(u132->hc_fminterval) << 16;
}
retval = u132_read_pcimem(u132, control, &u132->hc_control);
if (retval)
return retval;
dev_info(&u132->platform_dev->dev, "resetting from state '%s', control "
"= %08X\n", hcfs2string(u132->hc_control & OHCI_CTRL_HCFS),
u132->hc_control);
switch (u132->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
sleep_time = 0;
break;
case OHCI_USB_SUSPEND:
case OHCI_USB_RESUME:
u132->hc_control &= OHCI_CTRL_RWC;
u132->hc_control |= OHCI_USB_RESUME;
sleep_time = 10;
break;
default:
u132->hc_control &= OHCI_CTRL_RWC;
u132->hc_control |= OHCI_USB_RESET;
sleep_time = 50;
break;
}
retval = u132_write_pcimem(u132, control, u132->hc_control);
if (retval)
return retval;
retval = u132_read_pcimem(u132, control, &control);
if (retval)
return retval;
msleep(sleep_time);
retval = u132_read_pcimem(u132, roothub.a, &roothub_a);
if (retval)
return retval;
if (!(roothub_a & RH_A_NPS)) {
int temp; /* power down each port */
for (temp = 0; temp < u132->num_ports; temp++) {
retval = u132_write_pcimem(u132,
roothub.portstatus[temp], RH_PS_LSDA);
if (retval)
return retval;
}
}
retval = u132_read_pcimem(u132, control, &control);
if (retval)
return retval;
retry:
retval = u132_read_pcimem(u132, cmdstatus, &status);
if (retval)
return retval;
retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR);
if (retval)
return retval;
extra: {
retval = u132_read_pcimem(u132, cmdstatus, &status);
if (retval)
return retval;
if (0 != (status & OHCI_HCR)) {
if (--reset_timeout == 0) {
dev_err(&u132->platform_dev->dev, "USB HC reset"
" timed out!\n");
return -ENODEV;
} else {
msleep(5);
goto extra;
}
}
}
if (u132->flags & OHCI_QUIRK_INITRESET) {
retval = u132_write_pcimem(u132, control, u132->hc_control);
if (retval)
return retval;
retval = u132_read_pcimem(u132, control, &control);
if (retval)
return retval;
}
retval = u132_write_pcimem(u132, ed_controlhead, 0x00000000);
if (retval)
return retval;
retval = u132_write_pcimem(u132, ed_bulkhead, 0x11000000);
if (retval)
return retval;
retval = u132_write_pcimem(u132, hcca, 0x00000000);
if (retval)
return retval;
retval = u132_periodic_reinit(u132);
if (retval)
return retval;
retval = u132_read_pcimem(u132, fminterval, &fminterval);
if (retval)
return retval;
retval = u132_read_pcimem(u132, periodicstart, &periodicstart);
if (retval)
return retval;
if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) {
if (!(u132->flags & OHCI_QUIRK_INITRESET)) {
u132->flags |= OHCI_QUIRK_INITRESET;
goto retry;
} else
dev_err(&u132->platform_dev->dev, "init err(%08x %04x)"
"\n", fminterval, periodicstart);
} /* start controller operations */
u132->hc_control &= OHCI_CTRL_RWC;
u132->hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER;
retval = u132_write_pcimem(u132, control, u132->hc_control);
if (retval)
return retval;
retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF);
if (retval)
return retval;
retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus);
if (retval)
return retval;
retval = u132_read_pcimem(u132, control, &control);
if (retval)
return retval;
u132_to_hcd(u132)->state = HC_STATE_RUNNING;
retval = u132_write_pcimem(u132, roothub.status, RH_HS_DRWE);
if (retval)
return retval;
retval = u132_write_pcimem(u132, intrstatus, mask);
if (retval)
return retval;
retval = u132_write_pcimem(u132, intrdisable,
OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO |
OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH |
OHCI_INTR_SO);
if (retval)
return retval; /* handle root hub init quirks ... */
retval = u132_read_pcimem(u132, roothub.a, &roothub_a);
if (retval)
return retval;
roothub_a &= ~(RH_A_PSM | RH_A_OCPM);
if (u132->flags & OHCI_QUIRK_SUPERIO) {
roothub_a |= RH_A_NOCP;
roothub_a &= ~(RH_A_POTPGT | RH_A_NPS);
retval = u132_write_pcimem(u132, roothub.a, roothub_a);
if (retval)
return retval;
} else if ((u132->flags & OHCI_QUIRK_AMD756) || distrust_firmware) {
roothub_a |= RH_A_NPS;
retval = u132_write_pcimem(u132, roothub.a, roothub_a);
if (retval)
return retval;
}
retval = u132_write_pcimem(u132, roothub.status, RH_HS_LPSC);
if (retval)
return retval;
retval = u132_write_pcimem(u132, roothub.b,
(roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM);
if (retval)
return retval;
retval = u132_read_pcimem(u132, control, &control);
if (retval)
return retval;
mdelay((roothub_a >> 23) & 0x1fe);
u132_to_hcd(u132)->state = HC_STATE_RUNNING;
return 0;
}