/* If I get a NACK reissue the transmission */ if (lpid == USB_PID_NAK) { if (--loop > 0) goto retry;
}
return ret;
}
staticinlinevoid dbgp_set_data(constvoid *buf, int size)
{ constunsignedchar *bytes = buf;
u32 lo, hi; int i;
lo = hi = 0; for (i = 0; i < 4 && i < size; i++)
lo |= bytes[i] << (8*i); for (; i < 8 && i < size; i++)
hi |= bytes[i] << (8*(i - 4));
writel(lo, &ehci_debug->data03);
writel(hi, &ehci_debug->data47);
}
staticinlinevoid dbgp_get_data(void *buf, int size)
{ unsignedchar *bytes = buf;
u32 lo, hi; int i;
lo = readl(&ehci_debug->data03);
hi = readl(&ehci_debug->data47); for (i = 0; i < 4 && i < size; i++)
bytes[i] = (lo >> (8*i)) & 0xff; for (; i < 8 && i < size; i++)
bytes[i] = (hi >> (8*(i - 4))) & 0xff;
}
staticint dbgp_bulk_write(unsigned devnum, unsigned endpoint, constchar *bytes, int size)
{ int ret;
u32 addr;
u32 pids, ctrl;
staticint dbgp_control_msg(unsigned devnum, int requesttype, int request, int value, int index, void *data, int size)
{
u32 pids, addr, ctrl; struct usb_ctrlrequest req; int read; int ret;
/* Ensure everything is routed to the EHCI */
writel(FLAG_CF, &ehci_regs->configured_flag);
/* Wait until the controller is no longer halted */
loop = 1000; do {
status = readl(&ehci_regs->status); if (!(status & STS_HALT)) break;
udelay(1);
} while (--loop > 0);
if (!loop) {
dbgp_printk("ehci can not be started\n"); return -ENODEV;
}
dbgp_printk("ehci started\n"); return0;
}
/* Reset the EHCI controller */
cmd = readl(&ehci_regs->command);
cmd |= CMD_RESET;
writel(cmd, &ehci_regs->command); do {
cmd = readl(&ehci_regs->command);
} while ((cmd & CMD_RESET) && (--loop > 0));
if (!loop) {
dbgp_printk("can not reset ehci\n"); return -1;
}
dbgp_ehci_status("ehci reset done"); return0;
} staticint ehci_wait_for_port(int port); /* Return 0 on success *Return-ENODEVforanygeneralfailure *Return-EIOifwaitforportfails
*/ staticint _dbgp_external_startup(void)
{ int devnum; struct usb_debug_descriptor dbgp_desc; int ret;
u32 ctrl, portsc, cmd; int dbg_port = dbgp_phys_port; int tries = 3; int reset_port_tries = 1; int try_hard_once = 1;
try_port_reset_again:
ret = dbgp_ehci_startup(); if (ret) return ret;
/* Wait for a device to show up in the debug port */
ret = ehci_wait_for_port(dbg_port); if (ret < 0) {
portsc = readl(&ehci_regs->port_status[dbg_port - 1]); if (!(portsc & PORT_CONNECT) && try_hard_once) { /* Last ditch effort to try to force enable *thedebugdevicebyusingthepackettest
* ehci command to try and wake it up. */
try_hard_once = 0;
cmd = readl(&ehci_regs->command);
cmd &= ~CMD_RUN;
writel(cmd, &ehci_regs->command);
portsc = readl(&ehci_regs->port_status[dbg_port - 1]);
portsc |= PORT_TEST_PKT;
writel(portsc, &ehci_regs->port_status[dbg_port - 1]);
dbgp_ehci_status("Trying to force debug port online");
mdelay(50);
dbgp_ehci_controller_reset(); goto try_port_reset_again;
} elseif (reset_port_tries--) { goto try_port_reset_again;
}
dbgp_printk("No device found in debug port\n"); return -EIO;
}
dbgp_ehci_status("wait for port done");
/* Enable the debug port */
ctrl = readl(&ehci_debug->control);
ctrl |= DBGP_CLAIM;
writel(ctrl, &ehci_debug->control);
ctrl = readl(&ehci_debug->control); if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) {
dbgp_printk("No device in debug port\n");
writel(ctrl & ~DBGP_CLAIM, &ehci_debug->control); return -ENODEV;
}
dbgp_ehci_status("debug ported enabled");
/* Completely transfer the debug device to the debug controller */
portsc = readl(&ehci_regs->port_status[dbg_port - 1]);
portsc &= ~PORT_PE;
writel(portsc, &ehci_regs->port_status[dbg_port - 1]);
dbgp_mdelay(100);
try_again: /* Find the debug device and make it device number 127 */ for (devnum = 0; devnum <= 127; devnum++) {
ret = dbgp_control_msg(devnum,
USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,
&dbgp_desc, sizeof(dbgp_desc)); if (ret > 0) break;
} if (devnum > 127) {
dbgp_printk("Could not find attached debug device\n"); goto err;
}
dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint;
/* Move the device to 127 if it isn't already there */ if (devnum != USB_DEBUG_DEVNUM) {
ret = dbgp_control_msg(devnum,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0); if (ret < 0) {
dbgp_printk("Could not move attached device to %d\n",
USB_DEBUG_DEVNUM); goto err;
}
dbgp_printk("debug device renamed to 127\n");
}
/* Enable the debug interface */
ret = dbgp_control_msg(USB_DEBUG_DEVNUM,
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0); if (ret < 0) {
dbgp_printk(" Could not enable the debug device\n"); goto err;
}
dbgp_printk("debug interface enabled\n"); /* Perform a small write to get the even/odd data state in sync
*/
ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, dbgp_endpoint_out, " ", 1); if (ret < 0) {
dbgp_printk("dbgp_bulk_write failed: %d\n", ret); goto err;
}
dbgp_printk("small write done\n");
dbgp_not_safe = 0;
return0;
err: if (tries--) goto try_again; return -ENODEV;
}
for (i = 1; i <= n_ports; i++) {
portsc = readl(&ehci_regs->port_status[i-1]);
dbgp_printk("portstatus%d: %08x\n", i, portsc);
}
if (port_map_tried && (new_debug_port != debug_port)) { if (--playtimes) {
set_debug_port(new_debug_port); goto try_next_time;
} return -1;
}
/* Only reset the controller if it is not already in the
* configured state */ if (!(readl(&ehci_regs->configured_flag) & FLAG_CF)) { if (dbgp_ehci_controller_reset() != 0) return -1;
} else {
dbgp_ehci_status("ehci skip - already configured");
}
ret = _dbgp_external_startup(); if (ret == -EIO) goto next_debug_port;
if (ret < 0) { /* Things didn't work so remove my claim */
ctrl = readl(&ehci_debug->control);
ctrl &= ~(DBGP_CLAIM | DBGP_OUT);
writel(ctrl, &ehci_debug->control); return -1;
} return0;
/* double check if the mem space is enabled */
byte = read_pci_config_byte(bus, slot, func, 0x04); if (!(byte & 0x2)) {
byte |= 0x02;
write_pci_config_byte(bus, slot, func, 0x04, byte);
dbgp_printk("mmio for ehci enabled\n");
}
#if IS_ENABLED(CONFIG_USB) int dbgp_reset_prep(struct usb_hcd *hcd)
{ int ret = xen_dbgp_reset_prep(hcd);
u32 ctrl;
if (ret) return ret;
dbgp_not_safe = 1; if (!ehci_debug) return0;
if ((early_dbgp_console.index != -1 &&
!(early_dbgp_console.flags & CON_BOOT)) ||
dbgp_kgdb_mode) return1; /* This means the console is not initialized, or should get *shutdownsoastoallowforreuseoftheusbdevice,which
* means it is time to shutdown the usb debug port. */
ctrl = readl(&ehci_debug->control); if (ctrl & DBGP_ENABLED) {
ctrl &= ~(DBGP_CLAIM);
writel(ctrl, &ehci_debug->control);
} return0;
}
EXPORT_SYMBOL_GPL(dbgp_reset_prep);
int dbgp_external_startup(struct usb_hcd *hcd)
{ return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
}
EXPORT_SYMBOL_GPL(dbgp_external_startup); #endif/* USB */
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.