// SPDX-License-Identifier: GPL-2.0
/*
 * Standalone EHCI usb debug driver
 *
 * Originally written by:
 *  Eric W. Biederman" <ebiederm@xmission.com> and
 *  Yinghai Lu <yhlu.kernel@gmail.com>
 *
 * Changes for early/late printk and HW errata:
 *  Jason Wessel <jason.wessel@windriver.com>
 *  Copyright (C) 2009 Wind River Systems, Inc.
 *
 */

#include <linux/console.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/iopoll.h>
#include <linux/pci_regs.h>
#include <linux/pci_ids.h>
#include <linux/usb/ch9.h>
#include <linux/usb/ehci_def.h>
#include <linux/delay.h>
#include <linux/serial_core.h>
#include <linux/kgdb.h>
#include <linux/kthread.h>
#include <asm/io.h>
#include <asm/pci-direct.h>
#include <asm/fixmap.h>

/* The code here is intended to talk directly to the EHCI debug port
 * and does not require that you have any kind of USB host controller
 * drivers or USB device drivers compiled into the kernel.
 *
 * If you make a change to anything in here, the following test cases
 * need to pass where a USB debug device works in the following
 * configurations.
 *
 * 1. boot args:  earlyprintk=dbgp
 *     o kernel compiled with # CONFIG_USB_EHCI_HCD is not set
 *     o kernel compiled with CONFIG_USB_EHCI_HCD=y
 * 2. boot args: earlyprintk=dbgp,keep
 *     o kernel compiled with # CONFIG_USB_EHCI_HCD is not set
 *     o kernel compiled with CONFIG_USB_EHCI_HCD=y
 * 3. boot args: earlyprintk=dbgp console=ttyUSB0
 *     o kernel has CONFIG_USB_EHCI_HCD=y and
 *       CONFIG_USB_SERIAL_DEBUG=y
 * 4. boot args: earlyprintk=vga,dbgp
 *     o kernel compiled with # CONFIG_USB_EHCI_HCD is not set
 *     o kernel compiled with CONFIG_USB_EHCI_HCD=y
 *
 * For the 4th configuration you can turn on or off the DBGP_DEBUG
 * such that you can debug the dbgp device's driver code.
 */

static int dbgp_phys_port = 1;

static struct ehci_caps __iomem *ehci_caps;
static struct ehci_regs __iomem *ehci_regs;
static struct ehci_dbg_port __iomem *ehci_debug;
static int dbgp_not_safe; /* Cannot use debug device during ehci reset */
static unsigned int dbgp_endpoint_out;
static unsigned int dbgp_endpoint_in;

struct ehci_dev {
	u32 bus;
	u32 slot;
	u32 func;
};

static struct ehci_dev ehci_dev;

#define USB_DEBUG_DEVNUM 127

#ifdef DBGP_DEBUG
#define dbgp_printk printk
static void dbgp_ehci_status(char *str)
{
	if (!ehci_debug)
		return;
	dbgp_printk("dbgp: %s\n", str);
	dbgp_printk("  Debug control: %08x", readl(&ehci_debug->control));
	dbgp_printk("  ehci cmd     : %08x", readl(&ehci_regs->command));
	dbgp_printk("  ehci conf flg: %08x\n",
		    readl(&ehci_regs->configured_flag));
	dbgp_printk("  ehci status  : %08x", readl(&ehci_regs->status));
	dbgp_printk("  ehci portsc  : %08x\n",
		    readl(&ehci_regs->port_status[dbgp_phys_port - 1]));
}
#else
static inline void dbgp_ehci_status(char *str) { }
static inline void dbgp_printk(const char *fmt, ...) { }
#endif

static inline u32 dbgp_len_update(u32 x, u32 len)
{
	return (x & ~0x0f) | (len & 0x0f);
}

#ifdef CONFIG_KGDB
static struct kgdb_io kgdbdbgp_io_ops;
#define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops)
#else
#define dbgp_kgdb_mode (0)
#endif

/* Local version of HC_LENGTH macro as ehci struct is not available here */
#define EARLY_HC_LENGTH(p)	(0x00ff & (p)) /* bits 7 : 0 */

/*
 * USB Packet IDs (PIDs)
 */

/* token */
#define USB_PID_OUT		0xe1
#define USB_PID_IN		0x69
#define USB_PID_SOF		0xa5
#define USB_PID_SETUP		0x2d
/* handshake */
#define USB_PID_ACK		0xd2
#define USB_PID_NAK		0x5a
#define USB_PID_STALL		0x1e
#define USB_PID_NYET		0x96
/* data */
#define USB_PID_DATA0		0xc3
#define USB_PID_DATA1		0x4b
#define USB_PID_DATA2		0x87
#define USB_PID_MDATA		0x0f
/* Special */
#define USB_PID_PREAMBLE	0x3c
#define USB_PID_ERR		0x3c
#define USB_PID_SPLIT		0x78
#define USB_PID_PING		0xb4
#define USB_PID_UNDEF_0		0xf0

#define USB_PID_DATA_TOGGLE	0x88
#define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)

#define PCI_CAP_ID_EHCI_DEBUG	0xa

#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_MAX_PACKET		8
#define DBGP_TIMEOUT		(250 * 1000)
#define DBGP_LOOPS		1000

static inline u32 dbgp_pid_write_update(u32 x, u32 tok)
{
	static int data0 = USB_PID_DATA1;
	data0 ^= USB_PID_DATA_TOGGLE;
	return (x & 0xffff0000) | (data0 << 8) | (tok & 0xff);
}

static inline u32 dbgp_pid_read_update(u32 x, u32 tok)
{
	return (x & 0xffff0000) | (USB_PID_DATA0 << 8) | (tok & 0xff);
}

static int dbgp_wait_until_complete(void)
{
	u32 ctrl;
	int ret;

	ret = readl_poll_timeout_atomic(&ehci_debug->control, ctrl,
				(ctrl & DBGP_DONE), 1, DBGP_TIMEOUT);
	if (ret)
		return -DBGP_TIMEOUT;

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

static inline void dbgp_mdelay(int ms)
{
	int i;

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

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

static int dbgp_wait_until_done(unsigned ctrl, int loop)
{
	u32 pids, lpid;
	int ret;

retry:
	writel(ctrl | DBGP_GO, &ehci_debug->control);
	ret = dbgp_wait_until_complete();
	pids = readl(&ehci_debug->pids);
	lpid = DBGP_PID_GET(pids);

	if (ret < 0) {
		/* A -DBGP_TIMEOUT failure here means the device has
		 * failed, perhaps because it was unplugged, in which
		 * case we do not want to hang the system so the dbgp
		 * will be marked as unsafe to use.  EHCI reset is the
		 * only way to recover if you unplug the dbgp device.
		 */
		if (ret == -DBGP_TIMEOUT && !dbgp_not_safe)
			dbgp_not_safe = 1;
		if (ret == -DBGP_ERR_BAD && --loop > 0)
			goto retry;
		return ret;
	}

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

	/* If I get a NACK reissue the transmission */
	if (lpid == USB_PID_NAK) {
		if (--loop > 0)
			goto retry;
	}

	return ret;
}

static inline void dbgp_set_data(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));
	writel(lo, &ehci_debug->data03);
	writel(hi, &ehci_debug->data47);
}

static inline void dbgp_get_data(void *buf, int size)
{
	unsigned char *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;
}

static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
			 const char *bytes, int size)
{
	int ret;
	u32 addr;
	u32 pids, ctrl;

	if (size > DBGP_MAX_PACKET)
		return -1;

	addr = DBGP_EPADDR(devnum, endpoint);

	pids = readl(&ehci_debug->pids);
	pids = dbgp_pid_write_update(pids, USB_PID_OUT);

	ctrl = readl(&ehci_debug->control);
	ctrl = dbgp_len_update(ctrl, size);
	ctrl |= DBGP_OUT;
	ctrl |= DBGP_GO;

	dbgp_set_data(bytes, size);
	writel(addr, &ehci_debug->address);
	writel(pids, &ehci_debug->pids);
	ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);

	return ret;
}

static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
			  int size, int loops)
{
	u32 pids, addr, ctrl;
	int ret;

	if (size > DBGP_MAX_PACKET)
		return -1;

	addr = DBGP_EPADDR(devnum, endpoint);

	pids = readl(&ehci_debug->pids);
	pids = dbgp_pid_read_update(pids, USB_PID_IN);

	ctrl = readl(&ehci_debug->control);
	ctrl = dbgp_len_update(ctrl, size);
	ctrl &= ~DBGP_OUT;
	ctrl |= DBGP_GO;

	writel(addr, &ehci_debug->address);
	writel(pids, &ehci_debug->pids);
	ret = dbgp_wait_until_done(ctrl, loops);
	if (ret < 0)
		return ret;

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

static int 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;

	read = (requesttype & USB_DIR_IN) != 0;
	if (size > (read ? DBGP_MAX_PACKET : 0))
		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);

	pids = DBGP_PID_SET(USB_PID_DATA0, USB_PID_SETUP);
	addr = DBGP_EPADDR(devnum, 0);

	ctrl = readl(&ehci_debug->control);
	ctrl = dbgp_len_update(ctrl, sizeof(req));
	ctrl |= DBGP_OUT;
	ctrl |= DBGP_GO;

	/* Send the setup message */
	dbgp_set_data(&req, sizeof(req));
	writel(addr, &ehci_debug->address);
	writel(pids, &ehci_debug->pids);
	ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);
	if (ret < 0)
		return ret;

	/* Read the result */
	return dbgp_bulk_read(devnum, 0, data, size, DBGP_LOOPS);
}

/* Find a PCI capability */
static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap)
{
	u8 pos;
	int bytes;

	if (!(read_pci_config_16(num, slot, func, PCI_STATUS) &
		PCI_STATUS_CAP_LIST))
		return 0;

	pos = read_pci_config_byte(num, slot, func, PCI_CAPABILITY_LIST);
	for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
		u8 id;

		pos &= ~3;
		id = read_pci_config_byte(num, slot, func, pos+PCI_CAP_LIST_ID);
		if (id == 0xff)
			break;
		if (id == cap)
			return pos;

		pos = read_pci_config_byte(num, slot, func,
						 pos+PCI_CAP_LIST_NEXT);
	}
	return 0;
}

static u32 __init __find_dbgp(u32 bus, u32 slot, u32 func)
{
	u32 class;

	class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION);
	if ((class >> 8) != PCI_CLASS_SERIAL_USB_EHCI)
		return 0;

	return find_cap(bus, slot, func, PCI_CAP_ID_EHCI_DEBUG);
}

static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc)
{
	u32 bus, slot, func;

	for (bus = 0; bus < 256; bus++) {
		for (slot = 0; slot < 32; slot++) {
			for (func = 0; func < 8; func++) {
				unsigned cap;

				cap = __find_dbgp(bus, slot, func);

				if (!cap)
					continue;
				if (ehci_num-- != 0)
					continue;
				*rbus = bus;
				*rslot = slot;
				*rfunc = func;
				return cap;
			}
		}
	}
	return 0;
}

static int dbgp_ehci_startup(void)
{
	u32 ctrl, cmd, status;
	int loop;

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

	dbgp_ehci_status("EHCI startup");
	/* Start the ehci running */
	cmd = readl(&ehci_regs->command);
	cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET);
	cmd |= CMD_RUN;
	writel(cmd, &ehci_regs->command);

	/* 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");
	return 0;
}

static int dbgp_ehci_controller_reset(void)
{
	int loop = 250 * 1000;
	u32 cmd;

	/* 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");
	return 0;
}
static int ehci_wait_for_port(int port);
/* Return 0 on success
 * Return -ENODEV for any general failure
 * Return -EIO if wait for port fails
 */
static int _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
			 * the debug device by using the packet test
			 * 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;
		} else if (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;

	return 0;
err:
	if (tries--)
		goto try_again;
	return -ENODEV;
}

static int ehci_reset_port(int port)
{
	u32 portsc;
	u32 delay_time, delay;
	int loop;

	dbgp_ehci_status("reset port");
	/* Reset the usb debug port */
	portsc = readl(&ehci_regs->port_status[port - 1]);
	portsc &= ~PORT_PE;
	portsc |= PORT_RESET;
	writel(portsc, &ehci_regs->port_status[port - 1]);

	delay = HUB_ROOT_RESET_TIME;
	for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT;
	     delay_time += delay) {
		dbgp_mdelay(delay);
		portsc = readl(&ehci_regs->port_status[port - 1]);
		if (!(portsc & PORT_RESET))
			break;
	}
	if (portsc & PORT_RESET) {
		/* force reset to complete */
		loop = 100 * 1000;
		writel(portsc & ~(PORT_RWC_BITS | PORT_RESET),
			&ehci_regs->port_status[port - 1]);
		do {
			udelay(1);
			portsc = readl(&ehci_regs->port_status[port-1]);
		} while ((portsc & PORT_RESET) && (--loop > 0));
	}

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

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

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

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

	for (reps = 0; reps < 300; reps++) {
		status = readl(&ehci_regs->status);
		if (status & STS_PCD)
			break;
		dbgp_mdelay(1);
	}
	ret = ehci_reset_port(port);
	if (ret == 0)
		return 0;
	return -ENOTCONN;
}

typedef void (*set_debug_port_t)(int port);

static void __init default_set_debug_port(int port)
{
}

static set_debug_port_t __initdata set_debug_port = default_set_debug_port;

static void __init nvidia_set_debug_port(int port)
{
	u32 dword;
	dword = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
				 0x74);
	dword &= ~(0x0f<<12);
	dword |= ((port & 0x0f)<<12);
	write_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func, 0x74,
				 dword);
	dbgp_printk("set debug port to %d\n", port);
}

static void __init detect_set_debug_port(void)
{
	u32 vendorid;

	vendorid = read_pci_config(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
		 0x00);

	if ((vendorid & 0xffff) == 0x10de) {
		dbgp_printk("using nvidia set_debug_port\n");
		set_debug_port = nvidia_set_debug_port;
	}
}

/* The code in early_ehci_bios_handoff() is derived from the usb pci
 * quirk initialization, but altered so as to use the early PCI
 * routines. */
#define EHCI_USBLEGSUP_BIOS	(1 << 16)	/* BIOS semaphore */
#define EHCI_USBLEGCTLSTS	4		/* legacy control/status */
static void __init early_ehci_bios_handoff(void)
{
	u32 hcc_params = readl(&ehci_caps->hcc_params);
	int offset = (hcc_params >> 8) & 0xff;
	u32 cap;
	int msec;

	if (!offset)
		return;

	cap = read_pci_config(ehci_dev.bus, ehci_dev.slot,
			      ehci_dev.func, offset);
	dbgp_printk("dbgp: ehci BIOS state %08x\n", cap);

	if ((cap & 0xff) == 1 && (cap & EHCI_USBLEGSUP_BIOS)) {
		dbgp_printk("dbgp: BIOS handoff\n");
		write_pci_config_byte(ehci_dev.bus, ehci_dev.slot,
				      ehci_dev.func, offset + 3, 1);
	}

	/* if boot firmware now owns EHCI, spin till it hands it over. */
	msec = 1000;
	while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) {
		mdelay(10);
		msec -= 10;
		cap = read_pci_config(ehci_dev.bus, ehci_dev.slot,
				      ehci_dev.func, offset);
	}

	if (cap & EHCI_USBLEGSUP_BIOS) {
		/* well, possibly buggy BIOS... try to shut it down,
		 * and hope nothing goes too wrong */
		dbgp_printk("dbgp: BIOS handoff failed: %08x\n", cap);
		write_pci_config_byte(ehci_dev.bus, ehci_dev.slot,
				      ehci_dev.func, offset + 2, 0);
	}

	/* just in case, always disable EHCI SMIs */
	write_pci_config_byte(ehci_dev.bus, ehci_dev.slot, ehci_dev.func,
			      offset + EHCI_USBLEGCTLSTS, 0);
}

static int __init ehci_setup(void)
{
	u32 ctrl, portsc, hcs_params;
	u32 debug_port, new_debug_port = 0, n_ports;
	int ret, i;
	int port_map_tried;
	int playtimes = 3;

	early_ehci_bios_handoff();

try_next_time:
	port_map_tried = 0;

try_next_port:

	hcs_params = readl(&ehci_caps->hcs_params);
	debug_port = HCS_DEBUG_PORT(hcs_params);
	dbgp_phys_port = debug_port;
	n_ports    = HCS_N_PORTS(hcs_params);

	dbgp_printk("debug_port: %d\n", debug_port);
	dbgp_printk("n_ports:    %d\n", n_ports);
	dbgp_ehci_status("");

	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;
	}
	return 0;

next_debug_port:
	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)) {
		set_debug_port(new_debug_port);
		goto try_next_port;
	}
	if (--playtimes) {
		set_debug_port(new_debug_port);
		goto try_next_time;
	}

	return -1;
}

int __init early_dbgp_init(char *s)
{
	u32 debug_port, bar, offset;
	u32 bus, slot, func, cap;
	void __iomem *ehci_bar;
	u32 dbgp_num;
	u32 bar_val;
	char *e;
	int ret;
	u8 byte;

	if (!early_pci_allowed())
		return -1;

	dbgp_num = 0;
	if (*s)
		dbgp_num = simple_strtoul(s, &e, 10);
	dbgp_printk("dbgp_num: %d\n", dbgp_num);

	cap = find_dbgp(dbgp_num, &bus, &slot, &func);
	if (!cap)
		return -1;

	dbgp_printk("Found EHCI debug port on %02x:%02x.%1x\n", bus, slot,
			 func);

	debug_port = read_pci_config(bus, slot, func, cap);
	bar = (debug_port >> 29) & 0x7;
	bar = (bar * 4) + 0xc;
	offset = (debug_port >> 16) & 0xfff;
	dbgp_printk("bar: %02x offset: %03x\n", bar, offset);
	if (bar != PCI_BASE_ADDRESS_0) {
		dbgp_printk("only debug ports on bar 1 handled.\n");

		return -1;
	}

	bar_val = read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
	dbgp_printk("bar_val: %02x offset: %03x\n", bar_val, offset);
	if (bar_val & ~PCI_BASE_ADDRESS_MEM_MASK) {
		dbgp_printk("only simple 32bit mmio bars supported\n");

		return -1;
	}

	/* 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");
	}

	/*
	 * FIXME I don't have the bar size so just guess PAGE_SIZE is more
	 * than enough.  1K is the biggest I have seen.
	 */
	set_fixmap_nocache(FIX_DBGP_BASE, bar_val & PAGE_MASK);
	ehci_bar = (void __iomem *)__fix_to_virt(FIX_DBGP_BASE);
	ehci_bar += bar_val & ~PAGE_MASK;
	dbgp_printk("ehci_bar: %p\n", ehci_bar);

	ehci_caps  = ehci_bar;
	ehci_regs  = ehci_bar + EARLY_HC_LENGTH(readl(&ehci_caps->hc_capbase));
	ehci_debug = ehci_bar + offset;
	ehci_dev.bus = bus;
	ehci_dev.slot = slot;
	ehci_dev.func = func;

	detect_set_debug_port();

	ret = ehci_setup();
	if (ret < 0) {
		dbgp_printk("ehci_setup failed\n");
		ehci_debug = NULL;

		return -1;
	}
	dbgp_ehci_status("early_init_complete");

	return 0;
}

static void early_dbgp_write(struct console *con, const char *str, u32 n)
{
	int chunk;
	char buf[DBGP_MAX_PACKET];
	int use_cr = 0;
	u32 cmd, ctrl;
	int reset_run = 0;

	if (!ehci_debug || dbgp_not_safe)
		return;

	cmd = readl(&ehci_regs->command);
	if (unlikely(!(cmd & CMD_RUN))) {
		/* If the ehci controller is not in the run state do extended
		 * checks to see if the acpi or some other initialization also
		 * reset the ehci debug port */
		ctrl = readl(&ehci_debug->control);
		if (!(ctrl & DBGP_ENABLED)) {
			dbgp_not_safe = 1;
			_dbgp_external_startup();
		} else {
			cmd |= CMD_RUN;
			writel(cmd, &ehci_regs->command);
			reset_run = 1;
		}
	}
	while (n > 0) {
		for (chunk = 0; chunk < DBGP_MAX_PACKET && n > 0;
		     str++, chunk++, n--) {
			if (!use_cr && *str == '\n') {
				use_cr = 1;
				buf[chunk] = '\r';
				str--;
				n++;
				continue;
			}
			if (use_cr)
				use_cr = 0;
			buf[chunk] = *str;
		}
		if (chunk > 0) {
			dbgp_bulk_write(USB_DEBUG_DEVNUM,
					dbgp_endpoint_out, buf, chunk);
		}
	}
	if (unlikely(reset_run)) {
		cmd = readl(&ehci_regs->command);
		cmd &= ~CMD_RUN;
		writel(cmd, &ehci_regs->command);
	}
}

struct console early_dbgp_console = {
	.name =		"earlydbg",
	.write =	early_dbgp_write,
	.flags =	CON_PRINTBUFFER,
	.index =	-1,
};

#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)
		return 0;

	if ((early_dbgp_console.index != -1 &&
	     !(early_dbgp_console.flags & CON_BOOT)) ||
	    dbgp_kgdb_mode)
		return 1;
	/* This means the console is not initialized, or should get
	 * shutdown so as to allow for reuse of the usb device, 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);
	}
	return 0;
}
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 */

#ifdef CONFIG_KGDB

static char kgdbdbgp_buf[DBGP_MAX_PACKET];
static int kgdbdbgp_buf_sz;
static int kgdbdbgp_buf_idx;
static int kgdbdbgp_loop_cnt = DBGP_LOOPS;

static int kgdbdbgp_read_char(void)
{
	int ret;

	if (kgdbdbgp_buf_idx < kgdbdbgp_buf_sz) {
		char ch = kgdbdbgp_buf[kgdbdbgp_buf_idx++];
		return ch;
	}

	ret = dbgp_bulk_read(USB_DEBUG_DEVNUM, dbgp_endpoint_in,
			     &kgdbdbgp_buf, DBGP_MAX_PACKET,
			     kgdbdbgp_loop_cnt);
	if (ret <= 0)
		return NO_POLL_CHAR;
	kgdbdbgp_buf_sz = ret;
	kgdbdbgp_buf_idx = 1;
	return kgdbdbgp_buf[0];
}

static void kgdbdbgp_write_char(u8 chr)
{
	early_dbgp_write(NULL, &chr, 1);
}

static struct kgdb_io kgdbdbgp_io_ops = {
	.name = "kgdbdbgp",
	.read_char = kgdbdbgp_read_char,
	.write_char = kgdbdbgp_write_char,
};

static int kgdbdbgp_wait_time;

static int __init kgdbdbgp_parse_config(char *str)
{
	char *ptr;

	if (!ehci_debug) {
		if (early_dbgp_init(str))
			return -1;
	}
	ptr = strchr(str, ',');
	if (ptr) {
		ptr++;
		kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10);
	}
	kgdb_register_io_module(&kgdbdbgp_io_ops);
	if (early_dbgp_console.index != -1)
		kgdbdbgp_io_ops.cons = &early_dbgp_console;

	return 0;
}
early_param("kgdbdbgp", kgdbdbgp_parse_config);

static int kgdbdbgp_reader_thread(void *ptr)
{
	int ret;

	while (readl(&ehci_debug->control) & DBGP_ENABLED) {
		kgdbdbgp_loop_cnt = 1;
		ret = kgdbdbgp_read_char();
		kgdbdbgp_loop_cnt = DBGP_LOOPS;
		if (ret != NO_POLL_CHAR) {
			if (ret == 0x3 || ret == '$') {
				if (ret == '$')
					kgdbdbgp_buf_idx--;
				kgdb_breakpoint();
			}
			continue;
		}
		schedule_timeout_interruptible(kgdbdbgp_wait_time * HZ);
	}
	return 0;
}

static int __init kgdbdbgp_start_thread(void)
{
	if (dbgp_kgdb_mode && kgdbdbgp_wait_time)
		kthread_run(kgdbdbgp_reader_thread, NULL, "%s", "dbgp");

	return 0;
}
device_initcall(kgdbdbgp_start_thread);
#endif /* CONFIG_KGDB */
