linux/drivers/usb/early/ehci-dbgp.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Standalone EHCI usb debug driver
 *
 * Originally written by:
 *  Eric W. Biederman" <[email protected]> and
 *  Yinghai Lu <[email protected]>
 *
 * Changes for early/late printk and HW errata:
 *  Jason Wessel <[email protected]>
 *  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 =;

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 {};

static struct ehci_dev ehci_dev;

#define USB_DEBUG_DEVNUM

#ifdef DBGP_DEBUG
#define dbgp_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)
{}

#ifdef CONFIG_KGDB
static struct kgdb_io kgdbdbgp_io_ops;
#define dbgp_kgdb_mode
#else
#define dbgp_kgdb_mode
#endif

/* Local version of HC_LENGTH macro as ehci struct is not available here */
#define EARLY_HC_LENGTH(p)

/*
 * USB Packet IDs (PIDs)
 */

/* token */
#define USB_PID_OUT
#define USB_PID_IN
#define USB_PID_SOF
#define USB_PID_SETUP
/* handshake */
#define USB_PID_ACK
#define USB_PID_NAK
#define USB_PID_STALL
#define USB_PID_NYET
/* data */
#define USB_PID_DATA0
#define USB_PID_DATA1
#define USB_PID_DATA2
#define USB_PID_MDATA
/* Special */
#define USB_PID_PREAMBLE
#define USB_PID_ERR
#define USB_PID_SPLIT
#define USB_PID_PING
#define USB_PID_UNDEF_0

#define USB_PID_DATA_TOGGLE
#define DBGP_CLAIM

#define PCI_CAP_ID_EHCI_DEBUG

#define HUB_ROOT_RESET_TIME
#define HUB_SHORT_RESET_TIME
#define HUB_LONG_RESET_TIME
#define HUB_RESET_TIMEOUT

#define DBGP_MAX_PACKET
#define DBGP_TIMEOUT
#define DBGP_LOOPS

static inline u32 dbgp_pid_write_update(u32 x, u32 tok)
{}

static inline u32 dbgp_pid_read_update(u32 x, u32 tok)
{}

static int dbgp_wait_until_complete(void)
{}

static inline void dbgp_mdelay(int ms)
{}

static void dbgp_breath(void)
{}

static int dbgp_wait_until_done(unsigned ctrl, int loop)
{}

static inline void dbgp_set_data(const void *buf, int size)
{}

static inline void dbgp_get_data(void *buf, int size)
{}

static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
			 const char *bytes, int size)
{}

static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
			  int size, int loops)
{}

static int dbgp_control_msg(unsigned devnum, int requesttype,
	int request, int value, int index, void *data, int size)
{}

/* Find a PCI capability */
static u32 __init find_cap(u32 num, u32 slot, u32 func, int cap)
{}

static u32 __init __find_dbgp(u32 bus, u32 slot, u32 func)
{}

static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc)
{}

static int dbgp_ehci_startup(void)
{}

static int dbgp_ehci_controller_reset(void)
{}
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)
{}

static int ehci_reset_port(int port)
{}

static int ehci_wait_for_port(int port)
{}

set_debug_port_t;

static void __init default_set_debug_port(int port)
{}

static set_debug_port_t __initdata set_debug_port =;

static void __init nvidia_set_debug_port(int port)
{}

static void __init detect_set_debug_port(void)
{}

/* 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
#define EHCI_USBLEGCTLSTS
static void __init early_ehci_bios_handoff(void)
{}

static int __init ehci_setup(void)
{}

int __init early_dbgp_init(char *s)
{}

static void early_dbgp_write(struct console *con, const char *str, u32 n)
{}

struct console early_dbgp_console =;

#if IS_ENABLED(CONFIG_USB)
int dbgp_reset_prep(struct usb_hcd *hcd)
{}
EXPORT_SYMBOL_GPL();

int dbgp_external_startup(struct usb_hcd *hcd)
{}
EXPORT_SYMBOL_GPL();
#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 =;

static int kgdbdbgp_read_char(void)
{}

static void kgdbdbgp_write_char(u8 chr)
{}

static struct kgdb_io kgdbdbgp_io_ops =;

static int kgdbdbgp_wait_time;

static int __init kgdbdbgp_parse_config(char *str)
{}
early_param();

static int kgdbdbgp_reader_thread(void *ptr)
{}

static int __init kgdbdbgp_start_thread(void)
{}
device_initcall(kgdbdbgp_start_thread);
#endif /* CONFIG_KGDB */