Add support for early printk by writing debug messages to the USB3 debug port. Users can use this type of early printk by specifying kernel parameter of "earlyprintk=xdbc". This gives users a chance of providing debug output. Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> --- Documentation/kernel-parameters.txt | 1 + arch/x86/kernel/early_printk.c | 5 +++++ drivers/usb/early/xhci-dbc.c | 43 +++++++++++++++++++++++++++++++++++++ include/linux/usb/xhci-dbc.h | 5 +++++ 4 files changed, 54 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f8aae63..cb879cd 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1049,6 +1049,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. earlyprintk=ttySn[,baudrate] earlyprintk=dbgp[debugController#] earlyprintk=pciserial,bus:device.function[,baudrate] + earlyprintk=xdbc[xhciController#] earlyprintk is useful when the kernel crashes before the normal console is initialized. It is not enabled by diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 21bf924..ba4c471 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -17,6 +17,7 @@ #include <asm/intel-mid.h> #include <asm/pgtable.h> #include <linux/usb/ehci_def.h> +#include <linux/usb/xhci-dbc.h> #include <linux/efi.h> #include <asm/efi.h> #include <asm/pci_x86.h> @@ -373,6 +374,10 @@ static int __init setup_early_printk(char *buf) if (!strncmp(buf, "dbgp", 4) && !early_dbgp_init(buf + 4)) early_console_register(&early_dbgp_console, keep); #endif +#ifdef CONFIG_EARLY_PRINTK_XDBC + if (!strncmp(buf, "xdbc", 4) && !early_xdbc_init(buf + 4)) + early_console_register(&early_xdbc_console, keep); +#endif #ifdef CONFIG_HVC_XEN if (!strncmp(buf, "xen", 3)) early_console_register(&xenboot_console, keep); diff --git a/drivers/usb/early/xhci-dbc.c b/drivers/usb/early/xhci-dbc.c index aaf655f..68a7139 100644 --- a/drivers/usb/early/xhci-dbc.c +++ b/drivers/usb/early/xhci-dbc.c @@ -10,6 +10,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ +#include <linux/console.h> #include <linux/pci_regs.h> #include <linux/pci_ids.h> #include <linux/bootmem.h> @@ -1332,3 +1333,45 @@ int xdbc_bulk_write(const char *bytes, int size) return ret; } + +/* + * Start a bulk-in or bulk-out transfer, wait until transfer completion + * or error. Return the count of actually transferred bytes or error. + */ +static void early_xdbc_write(struct console *con, const char *str, u32 n) +{ + int chunk, ret; + static char buf[XDBC_MAX_PACKET]; + int use_cr = 0; + + if (!xdbcp->xdbc_reg) + return; + memset(buf, 0, XDBC_MAX_PACKET); + while (n > 0) { + for (chunk = 0; chunk < XDBC_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) { + ret = xdbc_bulk_write(buf, chunk); + if (ret < 0) + break; + } + } +} + +struct console early_xdbc_console = { + .name = "earlyxdbc", + .write = early_xdbc_write, + .flags = CON_PRINTBUFFER, + .index = -1, +}; diff --git a/include/linux/usb/xhci-dbc.h b/include/linux/usb/xhci-dbc.h index 289ba58..a556eb8 100644 --- a/include/linux/usb/xhci-dbc.h +++ b/include/linux/usb/xhci-dbc.h @@ -216,4 +216,9 @@ struct xdbc_state { #define xdbc_read64(regs) xhci_read_64(NULL, (regs)) #define xdbc_write64(val, regs) xhci_write_64(NULL, (val), (regs)) +#ifdef CONFIG_EARLY_PRINTK_XDBC +extern int early_xdbc_init(char *s); +extern struct console early_xdbc_console; +#endif /* CONFIG_EARLY_PRINTK_XDBC */ + #endif /* __LINUX_XHCI_DBC_H */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html