/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2006 Eric Biederman (ebiederm@xmission.com)
 * Copyright (C) 2007 AMD
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
 */

#include <stddef.h>
#include <console/console.h>
#include <console/usb.h>
#include <arch/io.h>
#include <arch/early_variables.h>
#include <string.h>
#include <cbmem.h>

#include "ehci_debug.h"
#include "usb_ch9.h"
#include "ehci.h"

struct ehci_debug_info {
	void *ehci_base;
	void *ehci_debug;

	struct dbgp_pipe ep_pipe[DBGP_MAX_ENDPOINTS];
};

#if CONFIG_DEBUG_USBDEBUG
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug);
static int dbgp_enabled(void);
# define dprintk(LEVEL, args...) \
	do { if (!dbgp_enabled()) printk(LEVEL, ##args); } while (0)
#else
# define dbgp_print_data(x)	do {} while(0)
# define dprintk(LEVEL, args...)   do {} while(0)
#endif

#define DBGP_LEN_UPDATE(x, len) (((x) & ~0x0f) | ((len) & 0x0f))

#define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)

#define HUB_ROOT_RESET_TIME	50	/* times are in msec */
#define HUB_SHORT_RESET_TIME	10
#define HUB_LONG_RESET_TIME	200
#define HUB_RESET_TIMEOUT	500

#define DBGP_MICROFRAME_TIMEOUT_LOOPS	1000
#define DBGP_MICROFRAME_RETRIES		10
#define DBGP_MAX_PACKET		8

static struct ehci_debug_info glob_dbg_info CAR_GLOBAL;
static struct ehci_debug_info * glob_dbg_info_p CAR_GLOBAL;

static inline struct ehci_debug_info *dbgp_ehci_info(void)
{
	if (car_get_var(glob_dbg_info_p) == NULL)
		car_set_var(glob_dbg_info_p, &glob_dbg_info);

	return car_get_var(glob_dbg_info_p);
}

static int dbgp_wait_until_complete(struct ehci_dbg_port *ehci_debug)
{
	u32 ctrl;
	int loop = 0;

	do {
		ctrl = read32(&ehci_debug->control);
		/* Stop when the transaction is finished */
		if (ctrl & DBGP_DONE)
			break;
	} while (++loop < DBGP_MICROFRAME_TIMEOUT_LOOPS);

	if (! (ctrl & DBGP_DONE)) {
		dprintk(BIOS_ERR, "dbgp_wait_until_complete: retry timeout.\n");
		return -DBGP_ERR_SIGNAL;
	}

	/* Now that we have observed the completed transaction,
	 * clear the done bit.
	 */
	write32(&ehci_debug->control, ctrl | DBGP_DONE);
	return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);
}

static void dbgp_breath(void)
{
	/* Sleep to give the debug port a chance to breathe */
}

static int dbgp_wait_until_done(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
	unsigned ctrl, const int timeout)
{
	u32 rd_ctrl, rd_pids;
	u32 ctrl_prev = 0, pids_prev = 0;
	u8 lpid;
	int ret, host_retries;
	int loop;

	loop = 0;
device_retry:
	host_retries = 0;
	if (loop++ >= timeout)
		return -DBGP_ERR_BAD;

host_retry:
	if (host_retries++ >= DBGP_MICROFRAME_RETRIES)
		return -DBGP_ERR_BAD;
	if (loop == 1 || host_retries > 1)
		dprintk(BIOS_SPEW, "dbgp:  start (@ %3d,%d) ctrl=%08x\n",
			loop, host_retries, ctrl | DBGP_GO);
	write32(&ehci_debug->control, ctrl | DBGP_GO);
	ret = dbgp_wait_until_complete(ehci_debug);
	rd_ctrl = read32(&ehci_debug->control);
	rd_pids = read32(&ehci_debug->pids);

	if (rd_ctrl != ctrl_prev || rd_pids != pids_prev || (ret<0)) {
		ctrl_prev = rd_ctrl;
		pids_prev = rd_pids;
		dprintk(BIOS_SPEW, "dbgp: status (@ %3d,%d) ctrl=%08x pids=%08x ret=%d\n",
			loop, host_retries, rd_ctrl, rd_pids, ret);
	}

	/* Controller hardware failure. */
	if (ret == -DBGP_ERR_SIGNAL) {
		return ret;

	/* Bus failure (corrupted microframe). */
	} else if (ret == -DBGP_ERR_BAD) {
		goto host_retry;
	}

	lpid = DBGP_PID_GET(rd_pids);

	/* If I get an ACK or in-sync DATA PID, we are done. */
	if ((lpid == USB_PID_ACK) || (lpid == pipe->pid)) {
		pipe->pid ^= USB_PID_DATA_TOGGLE;
	}

	/* If the port is getting full or it has dropped data
	 * start pacing ourselves, not necessary but it's friendly.
	 */
	else if (lpid == USB_PID_NYET) {
		dbgp_breath();
		goto device_retry;
	}

	/* If I get a NACK or out-of-sync DATA PID, reissue the transmission. */
	else if ((lpid == USB_PID_NAK) || (lpid == (pipe->pid ^ USB_PID_DATA_TOGGLE))) {
		goto device_retry;
	}

	/* Abort on STALL handshake for endpoint 0.*/
	else if ((lpid == USB_PID_STALL) && (pipe->endpoint == 0x0)) {
		ret = -DBGP_ERR_BAD;
	}

	dbgp_print_data(ehci_debug);

	return ret;
}

static void dbgp_set_data(struct ehci_dbg_port *ehci_debug, const void *buf, int size)
{
	const unsigned char *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));
	write32(&ehci_debug->data03, lo);
	write32(&ehci_debug->data47, hi);
}

static void dbgp_get_data(struct ehci_dbg_port *ehci_debug, void *buf, int size)
{
	unsigned char *bytes = buf;
	u32 lo, hi;
	int i;

	lo = read32(&ehci_debug->data03);
	hi = read32(&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;
}

#if CONFIG_DEBUG_USBDEBUG
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug)
{
	u32 ctrl = read32(&ehci_debug->control);
	u32	lo = read32(&ehci_debug->data03);
	u32	hi = read32(&ehci_debug->data47);
	int len = DBGP_LEN(ctrl);
	if (len) {
		int i;
		dprintk(BIOS_SPEW, "dbgp:    buf:");
		for (i = 0; i < 4 && i < len; i++)
			dprintk(BIOS_SPEW, " %02x", (lo >> (8*i)) & 0xff);
		for (; i < 8 && i < len; i++)
			dprintk(BIOS_SPEW, " %02x", (hi >> (8*(i - 4))) & 0xff);
		dprintk(BIOS_SPEW, "\n");
	}
}
#endif

static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
	const char *bytes, int size)
{
	u32 pids, addr, ctrl;
	int ret;

	if (size > DBGP_MAX_PACKET)
		return -1;

	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
	pids = DBGP_PID_SET(pipe->pid, USB_PID_OUT);

	ctrl = read32(&ehci_debug->control);
	ctrl = DBGP_LEN_UPDATE(ctrl, size);
	ctrl |= DBGP_OUT;

	dbgp_set_data(ehci_debug, bytes, size);
	write32(&ehci_debug->address, addr);
	write32(&ehci_debug->pids, pids);

	ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);

	return ret;
}

int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	return dbgp_bulk_write(dbg_info->ehci_debug, pipe, bytes, size);
}

static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
	void *data, int size)
{
	u32 pids, addr, ctrl;
	int ret;

	if (size > DBGP_MAX_PACKET)
		return -1;

	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
	pids = DBGP_PID_SET(pipe->pid, USB_PID_IN);

	ctrl = read32(&ehci_debug->control);
	ctrl = DBGP_LEN_UPDATE(ctrl, size);
	ctrl &= ~DBGP_OUT;

	write32(&ehci_debug->address, addr);
	write32(&ehci_debug->pids, pids);
	ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);
	if (ret < 0)
		return ret;

	if (size > ret)
		size = ret;
	dbgp_get_data(ehci_debug, data, size);
	return ret;
}

int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	return dbgp_bulk_read(dbg_info->ehci_debug, pipe, data, size);
}

void dbgp_mdelay(int ms)
{
	int i;

	while (ms--) {
		for (i = 0; i < 1000; i++)
			inb(0x80);
	}
}

int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, int requesttype,
		int request, int value, int index, void *data, int size)
{
	struct ehci_debug_info *info = dbgp_ehci_info();
	struct dbgp_pipe *pipe = &info->ep_pipe[DBGP_SETUP_EP0];
	u32 pids, addr, ctrl;
	struct usb_ctrlrequest req;
	int read;
	int ret, ret2;

	read = (requesttype & USB_DIR_IN) != 0;
	if (size > DBGP_MAX_PACKET)
		return -1;

	/* Compute the control message */
	req.bRequestType = requesttype;
	req.bRequest = request;
	req.wValue = cpu_to_le16(value);
	req.wIndex = cpu_to_le16(index);
	req.wLength = cpu_to_le16(size);

	pipe->devnum = devnum;
	pipe->endpoint = 0;
	pipe->pid = USB_PID_DATA0;
	pipe->timeout = 1000;
	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
	pids = DBGP_PID_SET(pipe->pid, USB_PID_SETUP);

	ctrl = read32(&ehci_debug->control);
	ctrl = DBGP_LEN_UPDATE(ctrl, sizeof(req));
	ctrl |= DBGP_OUT;

	/* Setup stage */
	dbgp_set_data(ehci_debug, &req, sizeof(req));
	write32(&ehci_debug->address, addr);
	write32(&ehci_debug->pids, pids);
	ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, 1);
	if (ret < 0)
		return ret;

	/* Data stage (optional) */
	if (read && size)
		ret = dbgp_bulk_read(ehci_debug, pipe, data, size);
	else if (!read && size)
		ret = dbgp_bulk_write(ehci_debug, pipe, data, size);

	/* Status stage in opposite direction */
	pipe->pid = USB_PID_DATA1;
	ctrl = read32(&ehci_debug->control);
	ctrl = DBGP_LEN_UPDATE(ctrl, 0);
	if (read) {
		pids = DBGP_PID_SET(pipe->pid, USB_PID_OUT);
		ctrl |= DBGP_OUT;
	} else {
		pids = DBGP_PID_SET(pipe->pid, USB_PID_IN);
		ctrl &= ~DBGP_OUT;
	}

	write32(&ehci_debug->pids, pids);
	ret2 = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);
	if (ret2 < 0)
		return ret2;

	return ret;
}

static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
{
	u32 portsc;
	int loop;

	/* Reset the usb debug port */
	portsc = read32(&ehci_regs->port_status[port - 1]);
	portsc &= ~PORT_PE;
	portsc |= PORT_RESET;
	write32(&ehci_regs->port_status[port - 1], portsc);

	dbgp_mdelay(HUB_ROOT_RESET_TIME);

	portsc = read32(&ehci_regs->port_status[port - 1]);
	write32(&ehci_regs->port_status[port - 1],
			portsc & ~(PORT_RWC_BITS | PORT_RESET));

	loop = 100;
	do {
		dbgp_mdelay(1);
		portsc = read32(&ehci_regs->port_status[port - 1]);
	} while ((portsc & PORT_RESET) && (--loop > 0));

	/* Device went away? */
	if (!(portsc & PORT_CONNECT))
		return -1; //-ENOTCONN;

	/* bomb out completely if something weird happened */
	if ((portsc & PORT_CSC))
		return -2; //-EINVAL;

	/* If we've finished resetting, then break out of the loop */
	if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
		return 0;

	return -3; //-EBUSY;
}

static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port)
{
	u32 status;
	int ret, reps;

	for (reps = 0; reps < 3; reps++) {
		dbgp_mdelay(100);
		status = read32(&ehci_regs->status);
		if (status & STS_PCD) {
			ret = ehci_reset_port(ehci_regs, port);
			if (ret == 0)
				return 0;
		}
	}
	return -1; //-ENOTCONN;
}



static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_info *info)
{
	struct ehci_caps *ehci_caps;
	struct ehci_regs *ehci_regs;

	u32 cmd, ctrl, status, portsc, hcs_params;
	u32 debug_port, new_debug_port = 0, n_ports;
	int ret, i;
	int loop;
	int port_map_tried;
	int playtimes = 3;

	/* Keep all endpoints disabled before any printk() call. */
	memset(info, 0, sizeof (*info));
	info->ehci_base = (void *)ehci_bar;
	info->ehci_debug = (void *)(ehci_bar + offset);

	dprintk(BIOS_INFO, "ehci_bar: 0x%x debug_offset 0x%x\n", ehci_bar, offset);

	ehci_caps  = (struct ehci_caps *)ehci_bar;
	ehci_regs  = (struct ehci_regs *)(ehci_bar +
			HC_LENGTH(read32(&ehci_caps->hc_capbase)));

	struct ehci_dbg_port *ehci_debug = info->ehci_debug;

	if (CONFIG_USBDEBUG_DEFAULT_PORT > 0)
		ehci_debug_select_port(CONFIG_USBDEBUG_DEFAULT_PORT);
	else
		ehci_debug_select_port(1);

try_next_time:
	port_map_tried = 0;

try_next_port:
	hcs_params = read32(&ehci_caps->hcs_params);
	debug_port = HCS_DEBUG_PORT(hcs_params);
	n_ports    = HCS_N_PORTS(hcs_params);

	dprintk(BIOS_INFO, "debug_port: %d\n", debug_port);
	dprintk(BIOS_INFO, "n_ports:    %d\n", n_ports);

        for (i = 1; i <= n_ports; i++) {
                portsc = read32(&ehci_regs->port_status[i-1]);
                dprintk(BIOS_INFO, "PORTSC #%d: %08x\n", i, portsc);
        }

	if(port_map_tried && (new_debug_port != debug_port)) {
		if(--playtimes) {
			ehci_debug_select_port(debug_port);
			goto try_next_time;
		}
		return -1;
	}

	/* Wait until the controller is halted */
	status = read32(&ehci_regs->status);
	if (!(status & STS_HALT)) {
		cmd = read32(&ehci_regs->command);
		cmd &= ~CMD_RUN;
		write32(&ehci_regs->command, cmd);
		loop = 100;
		do {
			dbgp_mdelay(10);
			status = read32(&ehci_regs->status);
		} while (!(status & STS_HALT) && (--loop > 0));
		if (status & STS_HALT)
			dprintk(BIOS_INFO, "EHCI controller halted successfully.\n");
		else
			dprintk(BIOS_INFO, "EHCI controller is not halted. Reset may fail.\n");
	}

	loop = 100;
	/* Reset the EHCI controller */
	cmd = read32(&ehci_regs->command);
	cmd |= CMD_RESET;
	write32(&ehci_regs->command, cmd);
	do {
		dbgp_mdelay(10);
		cmd = read32(&ehci_regs->command);
	} while ((cmd & CMD_RESET) && (--loop > 0));

	if(!loop) {
		dprintk(BIOS_INFO, "Could not reset EHCI controller.\n");
		// on some systems it works without succeeding here.
		// return -2;
	} else {
		dprintk(BIOS_INFO, "EHCI controller reset successfully.\n");
	}

	/* Claim ownership, but do not enable yet */
	ctrl = read32(&ehci_debug->control);
	ctrl |= DBGP_OWNER;
	ctrl &= ~(DBGP_ENABLED | DBGP_INUSE);
	write32(&ehci_debug->control, ctrl);

	/* Start EHCI controller */
	cmd = read32(&ehci_regs->command);
	cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET);
	cmd |= CMD_RUN;
	write32(&ehci_regs->command, cmd);

	/* Ensure everything is routed to the EHCI */
	write32(&ehci_regs->configured_flag, FLAG_CF);

	/* Wait until the controller is no longer halted */
	loop = 10;
	do {
		dbgp_mdelay(10);
		status = read32(&ehci_regs->status);
	} while ((status & STS_HALT) && (--loop > 0));

	if(!loop) {
		dprintk(BIOS_INFO, "EHCI could not be started.\n");
		return -3;
	}
	dprintk(BIOS_INFO, "EHCI started.\n");

	/* Wait for a device to show up in the debug port */
	ret = ehci_wait_for_port(ehci_regs, debug_port);
	if (ret < 0) {
		dprintk(BIOS_INFO, "No device found in debug port %d\n", debug_port);
		goto next_debug_port;
	}
	dprintk(BIOS_INFO, "EHCI done waiting for port.\n");


	/* Enable the debug port */
	ctrl = read32(&ehci_debug->control);
	ctrl |= DBGP_CLAIM;
	write32(&ehci_debug->control, ctrl);
	ctrl = read32(&ehci_debug->control);
	if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) {
		dprintk(BIOS_INFO, "No device in EHCI debug port.\n");
		write32(&ehci_debug->control, ctrl & ~DBGP_CLAIM);
		ret = -4;
		goto err;
	}
	dprintk(BIOS_INFO, "EHCI debug port enabled.\n");

#if 0
	/* Completely transfer the debug device to the debug controller */
	portsc = read32(&ehci_regs->port_status[debug_port - 1]);
	portsc &= ~PORT_PE;
	write32(&ehci_regs->port_status[debug_port - 1], portsc);
#endif

	dbgp_mdelay(100);

	ret = dbgp_probe_gadget(info->ehci_debug, &info->ep_pipe[0]);
	if (ret < 0) {
		dprintk(BIOS_INFO, "Could not probe gadget on debug port.\n");
		ret = -6;
		goto err;
	}

	return 0;
err:
	/* Things didn't work so remove my claim */
	ctrl = read32(&ehci_debug->control);
	ctrl &= ~(DBGP_CLAIM | DBGP_OUT);
	write32(&ehci_debug->control, ctrl);
	//return ret;

next_debug_port:
#if CONFIG_USBDEBUG_DEFAULT_PORT==0
	port_map_tried |= (1 << (debug_port - 1));
	new_debug_port = ((debug_port-1 + 1) % n_ports) + 1;
	if (port_map_tried != ((1 << n_ports) - 1)) {
		ehci_debug_select_port(new_debug_port);
		goto try_next_port;
	}
	if (--playtimes) {
		ehci_debug_select_port(new_debug_port);
		goto try_next_time;
	}
#else
	if (0)
		goto try_next_port;
	if (--playtimes)
		goto try_next_time;
#endif

	return -10;
}

#if CONFIG_DEBUG_USBDEBUG
static int dbgp_enabled(void)
{
	struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
	return (globals->status & DBGP_EP_ENABLED);
}
#endif

int dbgp_try_get(struct dbgp_pipe *pipe)
{
	struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
	if (!dbgp_ep_is_active(pipe) || (globals->status & DBGP_EP_BUSY))
		return 0;
	globals->status |= DBGP_EP_BUSY;
	pipe->status |= DBGP_EP_BUSY;
	return 1;
}

void dbgp_put(struct dbgp_pipe *pipe)
{
	struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
	globals->status &= ~DBGP_EP_BUSY;
	pipe->status &= ~DBGP_EP_BUSY;
}

#if !defined(__PRE_RAM__) && !defined(__SMM__)
void usbdebug_re_enable(unsigned ehci_base)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	unsigned diff;
	int i;

	diff = (unsigned)dbg_info->ehci_base - ehci_base;
	dbg_info->ehci_debug -= diff;
	dbg_info->ehci_base = (void*)ehci_base;

	for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
		if (dbg_info->ep_pipe[i].status & DBGP_EP_VALID)
			dbg_info->ep_pipe[i].status |= DBGP_EP_ENABLED;
}

void usbdebug_disable(void)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	int i;
	for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
		dbg_info->ep_pipe[i].status &= ~DBGP_EP_ENABLED;
}

#endif

#if !defined(__PRE_RAM__) && !defined(__SMM__)
static int get_usbdebug_from_cbmem(struct ehci_debug_info *info)
{
	struct ehci_debug_info *dbg_info_cbmem;

	dbg_info_cbmem = cbmem_find(CBMEM_ID_EHCI_DEBUG);
	if (dbg_info_cbmem == NULL)
		return -1;

	memcpy(info, dbg_info_cbmem, sizeof (*info));
	printk(BIOS_DEBUG, "EHCI debug port found in CBMEM.\n");

	return 0;
}

#elif defined(__PRE_RAM__)
static void migrate_ehci_debug(void)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	struct ehci_debug_info *dbg_info_cbmem;

	dbg_info_cbmem = cbmem_add(CBMEM_ID_EHCI_DEBUG, sizeof(*dbg_info));
	if (dbg_info_cbmem == NULL)
		return;

	memcpy(dbg_info_cbmem, dbg_info, sizeof(*dbg_info));
	car_set_var(glob_dbg_info_p, dbg_info_cbmem);
}
CAR_MIGRATE(migrate_ehci_debug);
#endif

int dbgp_ep_is_active(struct dbgp_pipe *pipe)
{
	return (pipe->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);
}

struct dbgp_pipe *dbgp_console_output(void)
{
	return &dbgp_ehci_info()->ep_pipe[DBGP_CONSOLE_EPOUT];
}

struct dbgp_pipe *dbgp_console_input(void)
{
	return &dbgp_ehci_info()->ep_pipe[DBGP_CONSOLE_EPIN];
}

int usbdebug_init(void)
{
	struct ehci_debug_info *dbg_info = dbgp_ehci_info();
	unsigned int ehci_base, dbg_offset;

#if !defined(__PRE_RAM__) && !defined(__SMM__)
	if (!get_usbdebug_from_cbmem(dbg_info))
		return 0;
#endif
	if (ehci_debug_hw_enable(&ehci_base, &dbg_offset))
		return -1;
	return usbdebug_init_(ehci_base, dbg_offset, dbg_info);
}
