aboutsummaryrefslogtreecommitdiffstats
path: root/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'unmodified_drivers/linux-2.6/platform-pci/platform-pci.c')
-rw-r--r--unmodified_drivers/linux-2.6/platform-pci/platform-pci.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
index a1c17dd7db..f081cb1115 100644
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
@@ -257,6 +257,60 @@ int xen_reboot_init(void);
int xen_panic_handler_init(void);
int gnttab_init(void);
+#define XEN_IOPORT_BASE 0x10
+
+#define XEN_IOPORT_PLATFLAGS (XEN_IOPORT_BASE + 0) /* 1 byte access (R/W) */
+#define XEN_IOPORT_MAGIC (XEN_IOPORT_BASE + 0) /* 2 byte access (R) */
+#define XEN_IOPORT_UNPLUG (XEN_IOPORT_BASE + 0) /* 2 byte access (W) */
+#define XEN_IOPORT_DRVVER (XEN_IOPORT_BASE + 0) /* 4 byte access (W) */
+
+#define XEN_IOPORT_SYSLOG (XEN_IOPORT_BASE + 2) /* 1 byte access (W) */
+#define XEN_IOPORT_PROTOVER (XEN_IOPORT_BASE + 2) /* 1 byte access (R) */
+#define XEN_IOPORT_PRODNUM (XEN_IOPORT_BASE + 2) /* 2 byte access (W) */
+
+#define XEN_IOPORT_MAGIC_VAL 0x49d2
+#define XEN_IOPORT_LINUX_PRODNUM 0xffff /* NB: register a proper one */
+#define XEN_IOPORT_LINUX_DRVVER ((LINUX_VERSION_CODE << 8) + 0x0)
+
+static int check_platform_magic(struct device *dev, long ioaddr, long iolen)
+{
+ short magic;
+ char protocol;
+
+ if (iolen < 0x16)
+ return -ENODEV;
+
+ magic = inw(XEN_IOPORT_MAGIC);
+
+ if (magic != XEN_IOPORT_MAGIC_VAL) {
+ dev_err(dev, "invalid magic %#x", magic);
+ return -ENODEV;
+ }
+
+ protocol = inb(XEN_IOPORT_PROTOVER);
+
+ dev_info(dev, "I/O protocol version %d\n", protocol);
+
+ switch (protocol) {
+ case 1:
+ outw(XEN_IOPORT_PRODNUM, 0xbeef);
+ outl(XEN_IOPORT_DRVVER, 0xdead);
+ if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
+ dev_err(dev, "blacklisted by host\n");
+ return -ENODEV;
+ }
+ /* Fall through */
+ case 0:
+ outw(XEN_IOPORT_UNPLUG, 0xf);
+ break;
+ default:
+ dev_err(dev, "unknown qemu version\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
static int __devinit platform_pci_init(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -305,6 +359,10 @@ static int __devinit platform_pci_init(struct pci_dev *pdev,
if (ret < 0)
goto out;
+ ret = check_platform_magic(&pdev->dev, ioaddr, iolen);
+ if (ret < 0)
+ goto out;
+
if ((ret = init_xen_info()))
goto out;