[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1446538452-23099-10-git-send-email-baolu.lu@linux.intel.com>
Date: Tue, 3 Nov 2015 16:14:09 +0800
From: Lu Baolu <baolu.lu@...ux.intel.com>
To: Mathias Nyman <mathias.nyman@...el.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
Alan Stern <stern@...land.harvard.edu>
Cc: linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org,
Lu Baolu <baolu.lu@...ux.intel.com>
Subject: [PATCH v2 09/12] x86: early_printk: add USB3 debug port earlyprintk support
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@...ux.intel.com>
---
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 22a4b68..b65b07f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1032,6 +1032,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 eec40f5..5341a16 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-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists