aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2012-09-18 07:23:02 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-09-18 12:20:48 -0400
commit9fa5780beea1274d498a224822397100022da7d4 (patch)
tree9dbc2d31f3af70502843bbebe8017828abd63136
parentee42f6c9fc62d1d4d45b0d75e5f947e6645d8c30 (diff)
USB EHCI/Xen: propagate controller reset information to hypervisor
Just like for the in-tree early console debug port driver, the hypervisor - when using a debug port based console - also needs to be told about controller resets, so it can suppress using and then re-initialize the debug port accordingly. Other than the in-tree driver, the hypervisor driver actually cares about doing this only for the device where the debug is port actually in use, i.e. it needs to be told the coordinates of the device being reset (quite obviously, leveraging the addition done for that would likely benefit the in-tree driver too). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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);
491 * Return -ENODEV for any general failure 491 * Return -ENODEV for any general failure
492 * Return -EIO if wait for port fails 492 * Return -EIO if wait for port fails
493 */ 493 */
494int dbgp_external_startup(void) 494static int _dbgp_external_startup(void)
495{ 495{
496 int devnum; 496 int devnum;
497 struct usb_debug_descriptor dbgp_desc; 497 struct usb_debug_descriptor dbgp_desc;
@@ -613,6 +613,11 @@ err:
613 goto try_again; 613 goto try_again;
614 return -ENODEV; 614 return -ENODEV;
615} 615}
616
617int dbgp_external_startup(struct usb_hcd *hcd)
618{
619 return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
620}
616EXPORT_SYMBOL_GPL(dbgp_external_startup); 621EXPORT_SYMBOL_GPL(dbgp_external_startup);
617 622
618static int ehci_reset_port(int port) 623static int ehci_reset_port(int port)
@@ -804,7 +809,7 @@ try_next_port:
804 dbgp_ehci_status("ehci skip - already configured"); 809 dbgp_ehci_status("ehci skip - already configured");
805 } 810 }
806 811
807 ret = dbgp_external_startup(); 812 ret = _dbgp_external_startup();
808 if (ret == -EIO) 813 if (ret == -EIO)
809 goto next_debug_port; 814 goto next_debug_port;
810 815
@@ -934,7 +939,7 @@ static void early_dbgp_write(struct console *con, const char *str, u32 n)
934 ctrl = readl(&ehci_debug->control); 939 ctrl = readl(&ehci_debug->control);
935 if (!(ctrl & DBGP_ENABLED)) { 940 if (!(ctrl & DBGP_ENABLED)) {
936 dbgp_not_safe = 1; 941 dbgp_not_safe = 1;
937 dbgp_external_startup(); 942 _dbgp_external_startup();
938 } else { 943 } else {
939 cmd |= CMD_RUN; 944 cmd |= CMD_RUN;
940 writel(cmd, &ehci_regs->command); 945 writel(cmd, &ehci_regs->command);
@@ -974,10 +979,14 @@ struct console early_dbgp_console = {
974 .index = -1, 979 .index = -1,
975}; 980};
976 981
977int dbgp_reset_prep(void) 982int dbgp_reset_prep(struct usb_hcd *hcd)
978{ 983{
984 int ret = xen_dbgp_reset_prep(hcd);
979 u32 ctrl; 985 u32 ctrl;
980 986
987 if (ret)
988 return ret;
989
981 dbgp_not_safe = 1; 990 dbgp_not_safe = 1;
982 if (!ehci_debug) 991 if (!ehci_debug)
983 return 0; 992 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)
228 228
229 /* If the EHCI debug controller is active, special care must be 229 /* If the EHCI debug controller is active, special care must be
230 * taken before and after a host controller reset */ 230 * taken before and after a host controller reset */
231 if (ehci->debug && !dbgp_reset_prep()) 231 if (ehci->debug && !dbgp_reset_prep(ehci_to_hcd(ehci)))
232 ehci->debug = NULL; 232 ehci->debug = NULL;
233 233
234 command |= CMD_RESET; 234 command |= CMD_RESET;
@@ -251,7 +251,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
251 tdi_reset (ehci); 251 tdi_reset (ehci);
252 252
253 if (ehci->debug) 253 if (ehci->debug)
254 dbgp_external_startup(); 254 dbgp_external_startup(ehci_to_hcd(ehci));
255 255
256 ehci->port_c_suspend = ehci->suspended_ports = 256 ehci->port_c_suspend = ehci->suspended_ports =
257 ehci->resuming_ports = 0; 257 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)
353 goto shutdown; 353 goto shutdown;
354 354
355 if (unlikely(ehci->debug)) { 355 if (unlikely(ehci->debug)) {
356 if (!dbgp_reset_prep()) 356 if (!dbgp_reset_prep(hcd))
357 ehci->debug = NULL; 357 ehci->debug = NULL;
358 else 358 else
359 dbgp_external_startup(); 359 dbgp_external_startup(hcd);
360 } 360 }
361 361
362 /* Ideally and we've got a real resume here, and no port's power 362 /* 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
18obj-$(CONFIG_XEN_TMEM) += tmem.o 18obj-$(CONFIG_XEN_TMEM) += tmem.o
19obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o 19obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
20obj-$(CONFIG_XEN_DOM0) += pcpu.o 20obj-$(CONFIG_XEN_DOM0) += pcpu.o
21obj-$(CONFIG_XEN_DOM0) += pci.o acpi.o 21obj-$(CONFIG_XEN_DOM0) += pci.o dbgp.o acpi.o
22obj-$(CONFIG_XEN_MCE_LOG) += mcelog.o 22obj-$(CONFIG_XEN_MCE_LOG) += mcelog.o
23obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/ 23obj-$(CONFIG_XEN_PCIDEV_BACKEND) += xen-pciback/
24obj-$(CONFIG_XEN_PRIVCMD) += xen-privcmd.o 24obj-$(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 @@
1#include <linux/pci.h>
2#include <linux/usb.h>
3#include <linux/usb/ehci_def.h>
4#include <linux/usb/hcd.h>
5#include <asm/xen/hypercall.h>
6#include <xen/interface/physdev.h>
7#include <xen/xen.h>
8
9static int xen_dbgp_op(struct usb_hcd *hcd, int op)
10{
11 const struct device *ctrlr = hcd_to_bus(hcd)->controller;
12 struct physdev_dbgp_op dbgp;
13
14 if (!xen_initial_domain())
15 return 0;
16
17 dbgp.op = op;
18
19#ifdef CONFIG_PCI
20 if (ctrlr->bus == &pci_bus_type) {
21 const struct pci_dev *pdev = to_pci_dev(ctrlr);
22
23 dbgp.u.pci.seg = pci_domain_nr(pdev->bus);
24 dbgp.u.pci.bus = pdev->bus->number;
25 dbgp.u.pci.devfn = pdev->devfn;
26 dbgp.bus = PHYSDEVOP_DBGP_BUS_PCI;
27 } else
28#endif
29 dbgp.bus = PHYSDEVOP_DBGP_BUS_UNKNOWN;
30
31 return HYPERVISOR_physdev_op(PHYSDEVOP_dbgp_op, &dbgp);
32}
33
34int xen_dbgp_reset_prep(struct usb_hcd *hcd)
35{
36 return xen_dbgp_op(hcd, PHYSDEVOP_DBGP_RESET_PREPARE);
37}
38
39int xen_dbgp_external_startup(struct usb_hcd *hcd)
40{
41 return xen_dbgp_op(hcd, PHYSDEVOP_DBGP_RESET_DONE);
42}
43
44#ifndef CONFIG_EARLY_PRINTK_DBGP
45#include <linux/export.h>
46EXPORT_SYMBOL_GPL(xen_dbgp_reset_prep);
47EXPORT_SYMBOL_GPL(xen_dbgp_external_startup);
48#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);
221extern struct console early_dbgp_console; 221extern struct console early_dbgp_console;
222#endif /* CONFIG_EARLY_PRINTK_DBGP */ 222#endif /* CONFIG_EARLY_PRINTK_DBGP */
223 223
224struct usb_hcd;
225
226#ifdef CONFIG_XEN_DOM0
227extern int xen_dbgp_reset_prep(struct usb_hcd *);
228extern int xen_dbgp_external_startup(struct usb_hcd *);
229#else
230static inline int xen_dbgp_reset_prep(struct usb_hcd *hcd)
231{
232 return 1; /* Shouldn't this be 0? */
233}
234
235static inline int xen_dbgp_external_startup(struct usb_hcd *hcd)
236{
237 return -1;
238}
239#endif
240
224#ifdef CONFIG_EARLY_PRINTK_DBGP 241#ifdef CONFIG_EARLY_PRINTK_DBGP
225/* Call backs from ehci host driver to ehci debug driver */ 242/* Call backs from ehci host driver to ehci debug driver */
226extern int dbgp_external_startup(void); 243extern int dbgp_external_startup(struct usb_hcd *);
227extern int dbgp_reset_prep(void); 244extern int dbgp_reset_prep(struct usb_hcd *hcd);
228#else 245#else
229static inline int dbgp_reset_prep(void) 246static inline int dbgp_reset_prep(struct usb_hcd *hcd)
230{ 247{
231 return 1; 248 return xen_dbgp_reset_prep(hcd);
232} 249}
233static inline int dbgp_external_startup(void) 250static inline int dbgp_external_startup(struct usb_hcd *hcd)
234{ 251{
235 return -1; 252 return xen_dbgp_external_startup(hcd);
236} 253}
237#endif 254#endif
238 255
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 {
258 uint8_t devfn; 258 uint8_t devfn;
259}; 259};
260 260
261#define PHYSDEVOP_DBGP_RESET_PREPARE 1
262#define PHYSDEVOP_DBGP_RESET_DONE 2
263
264#define PHYSDEVOP_DBGP_BUS_UNKNOWN 0
265#define PHYSDEVOP_DBGP_BUS_PCI 1
266
267#define PHYSDEVOP_dbgp_op 29
268struct physdev_dbgp_op {
269 /* IN */
270 uint8_t op;
271 uint8_t bus;
272 union {
273 struct physdev_pci_device pci;
274 } u;
275};
276
261/* 277/*
262 * Notify that some PIRQ-bound event channels have been unmasked. 278 * Notify that some PIRQ-bound event channels have been unmasked.
263 * ** This command is obsolete since interface version 0x00030202 and is ** 279 * ** This command is obsolete since interface version 0x00030202 and is **