aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/early/ehci-dbgp.c17
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/ehci-hub.c4
-rw-r--r--drivers/xen/Makefile2
-rw-r--r--drivers/xen/dbgp.c48
-rw-r--r--include/linux/usb/ehci_def.h29
-rw-r--r--include/xen/interface/physdev.h16
7 files changed, 105 insertions, 15 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index 89dcf155d57e..e426ad626d74 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -491,7 +491,7 @@ static int ehci_wait_for_port(int port);
* Return -ENODEV for any general failure
* Return -EIO if wait for port fails
*/
-int dbgp_external_startup(void)
+static int _dbgp_external_startup(void)
{
int devnum;
struct usb_debug_descriptor dbgp_desc;
@@ -613,6 +613,11 @@ err:
goto try_again;
return -ENODEV;
}
+
+int dbgp_external_startup(struct usb_hcd *hcd)
+{
+ return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
+}
EXPORT_SYMBOL_GPL(dbgp_external_startup);
static int ehci_reset_port(int port)
@@ -804,7 +809,7 @@ try_next_port:
dbgp_ehci_status("ehci skip - already configured");
}
- ret = dbgp_external_startup();
+ ret = _dbgp_external_startup();
if (ret == -EIO)
goto next_debug_port;
@@ -934,7 +939,7 @@ static void early_dbgp_write(struct console *con, const char *str, u32 n)
ctrl = readl(&ehci_debug->control);
if (!(ctrl & DBGP_ENABLED)) {
dbgp_not_safe = 1;
- dbgp_external_startup();
+ _dbgp_external_startup();
} else {
cmd |= CMD_RUN;
writel(cmd, &ehci_regs->command);
@@ -974,10 +979,14 @@ struct console early_dbgp_console = {
.index = -1,
};
-int dbgp_reset_prep(void)
+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;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index b05c6865b610..6bf6c42481e8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -228,7 +228,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
/* If the EHCI debug controller is active, special care must be
* taken before and after a host controller reset */
- if (ehci->debug && !dbgp_reset_prep())
+ if (ehci->debug && !dbgp_reset_prep(ehci_to_hcd(ehci)))
ehci->debug = NULL;
command |= CMD_RESET;
@@ -251,7 +251,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
tdi_reset (ehci);
if (ehci->debug)
- dbgp_external_startup();
+ dbgp_external_startup(ehci_to_hcd(ehci));
ehci->port_c_suspend = ehci->suspended_ports =
ehci->resuming_ports = 0;
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index c7880223738a..914ce9370e70 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -353,10 +353,10 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
goto shutdown;
if (unlikely(ehci->debug)) {
- if (!dbgp_reset_prep())
+ if (!dbgp_reset_prep(hcd))
ehci->debug = NULL;
else
- dbgp_external_startup();
+ dbgp_external_startup(hcd);
}
/* Ideally and we've got a real resume here, and no port's power
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index d80bea5535a2..a4a3cab2f459 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -18,7 +18,7 @@ obj-$(CONFIG_XEN_PVHVM) += platform-pci.o
obj-$(CONFIG_XEN_TMEM) += tmem.o
obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
obj-$(CONFIG_XEN_DOM0) += pcpu.o
-obj-$(CONFIG_XEN_DOM0) += pci.o acpi.o
+obj-$(CONFIG_XEN_DOM0) += pci.o dbgp.o acpi.o
obj-$(CONFIG_XEN_MCE_LOG) += mcelog.o
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/
obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o
diff --git a/drivers/xen/dbgp.c b/drivers/xen/dbgp.c
new file mode 100644
index 000000000000..42569c77ccc8
--- /dev/null
+++ b/drivers/xen/dbgp.c
@@ -0,0 +1,48 @@
+#include <linux/pci.h>
+#include <linux/usb.h>
+#include <linux/usb/ehci_def.h>
+#include <linux/usb/hcd.h>
+#include <asm/xen/hypercall.h>
+#include <xen/interface/physdev.h>
+#include <xen/xen.h>
+
+static int xen_dbgp_op(struct usb_hcd *hcd, int op)
+{
+ const struct device *ctrlr = hcd_to_bus(hcd)->controller;
+ struct physdev_dbgp_op dbgp;
+
+ if (!xen_initial_domain())
+ return 0;
+
+ dbgp.op = op;
+
+#ifdef CONFIG_PCI
+ if (ctrlr->bus == &pci_bus_type) {
+ const struct pci_dev *pdev = to_pci_dev(ctrlr);
+
+ dbgp.u.pci.seg = pci_domain_nr(pdev->bus);
+ dbgp.u.pci.bus = pdev->bus->number;
+ dbgp.u.pci.devfn = pdev->devfn;
+ dbgp.bus = PHYSDEVOP_DBGP_BUS_PCI;
+ } else
+#endif
+ dbgp.bus = PHYSDEVOP_DBGP_BUS_UNKNOWN;
+
+ return HYPERVISOR_physdev_op(PHYSDEVOP_dbgp_op, &dbgp);
+}
+
+int xen_dbgp_reset_prep(struct usb_hcd *hcd)
+{
+ return xen_dbgp_op(hcd, PHYSDEVOP_DBGP_RESET_PREPARE);
+}
+
+int xen_dbgp_external_startup(struct usb_hcd *hcd)
+{
+ return xen_dbgp_op(hcd, PHYSDEVOP_DBGP_RESET_DONE);
+}
+
+#ifndef CONFIG_EARLY_PRINTK_DBGP
+#include <linux/export.h>
+EXPORT_SYMBOL_GPL(xen_dbgp_reset_prep);
+EXPORT_SYMBOL_GPL(xen_dbgp_external_startup);
+#endif
diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h
index de4b9ed5d5dd..9a446302b658 100644
--- a/include/linux/usb/ehci_def.h
+++ b/include/linux/usb/ehci_def.h
@@ -221,18 +221,35 @@ extern int __init early_dbgp_init(char *s);
extern struct console early_dbgp_console;
#endif /* CONFIG_EARLY_PRINTK_DBGP */
+struct usb_hcd;
+
+#ifdef CONFIG_XEN_DOM0
+extern int xen_dbgp_reset_prep(struct usb_hcd *);
+extern int xen_dbgp_external_startup(struct usb_hcd *);
+#else
+static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd)
+{
+ return 1; /* Shouldn't this be 0? */
+}
+
+static inline int xen_dbgp_external_startup(struct usb_hcd *hcd)
+{
+ return -1;
+}
+#endif
+
#ifdef CONFIG_EARLY_PRINTK_DBGP
/* Call backs from ehci host driver to ehci debug driver */
-extern int dbgp_external_startup(void);
-extern int dbgp_reset_prep(void);
+extern int dbgp_external_startup(struct usb_hcd *);
+extern int dbgp_reset_prep(struct usb_hcd *hcd);
#else
-static inline int dbgp_reset_prep(void)
+static inline int dbgp_reset_prep(struct usb_hcd *hcd)
{
- return 1;
+ return xen_dbgp_reset_prep(hcd);
}
-static inline int dbgp_external_startup(void)
+static inline int dbgp_external_startup(struct usb_hcd *hcd)
{
- return -1;
+ return xen_dbgp_external_startup(hcd);
}
#endif
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index 9ce788d8cf49..bfa1d50fe15b 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -258,6 +258,22 @@ struct physdev_pci_device {
uint8_t devfn;
};
+#define PHYSDEVOP_DBGP_RESET_PREPARE 1
+#define PHYSDEVOP_DBGP_RESET_DONE 2
+
+#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0
+#define PHYSDEVOP_DBGP_BUS_PCI 1
+
+#define PHYSDEVOP_dbgp_op 29
+struct physdev_dbgp_op {
+ /* IN */
+ uint8_t op;
+ uint8_t bus;
+ union {
+ struct physdev_pci_device pci;
+ } u;
+};
+
/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **