# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1264235183 0
# Node ID 15efdfc465934aa822dbff9d8037412db41d2605
# Parent 7d65247d5f067ac745a73f62696408ad2589fecf
pv-on-hvm: Only unplug emulated devices if requested via module parameter.
dev_unplug=[all,][ide-disks,][aux-ide-disks,][nics]
ide-disks: Unplug all emulated IDE disks (but not CD-ROMs)
aux-ide-disks: As above, but doesn't touch primary IDE master
nics: Unplug all emulated NICs
all: ide-disks and nics
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 66 +++++++++++----
1 files changed, 52 insertions(+), 14 deletions(-)
diff -r 7d65247d5f06 -r 15efdfc46593
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sat Jan 23
08:23:24 2010 +0000
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sat Jan 23
08:26:23 2010 +0000
@@ -62,6 +62,13 @@ MODULE_DESCRIPTION("Xen platform PCI dev
MODULE_DESCRIPTION("Xen platform PCI device");
MODULE_LICENSE("GPL");
+/* NB. [aux-]ide-disks options do not unplug IDE CD-ROM drives. */
+/* NB. aux-ide-disks is equiv to ide-disks except ignores primary master. */
+static char *dev_unplug;
+module_param(dev_unplug, charp, 0644);
+MODULE_PARM_DESC(dev_unplug, "Emulated devices to unplug: "
+ "[all,][ide-disks,][aux-ide-disks,][nics]\n");
+
struct pci_dev *xen_platform_pdev;
static unsigned long shared_info_frame;
@@ -272,19 +279,43 @@ int gnttab_init(void);
#define XEN_IOPORT_LINUX_PRODNUM 0xffff /* NB: register a proper one */
#define XEN_IOPORT_LINUX_DRVVER ((LINUX_VERSION_CODE << 8) + 0x0)
+#define UNPLUG_ALL_IDE_DISKS 1
+#define UNPLUG_ALL_NICS 2
+#define UNPLUG_AUX_IDE_DISKS 4
+#define UNPLUG_ALL 7
+
static int check_platform_magic(struct device *dev, long ioaddr, long iolen)
{
- short magic;
- char protocol;
-
- if (iolen < 0x16)
- return -ENODEV;
+ short magic, unplug = 0;
+ char protocol, *p, *q, *err;
+
+ for (p = dev_unplug; p; p = q) {
+ q = strchr(dev_unplug, ',');
+ if (q)
+ *q++ = '\0';
+ if (!strcmp(p, "all"))
+ unplug |= UNPLUG_ALL;
+ else if (!strcmp(p, "ide-disks"))
+ unplug |= UNPLUG_ALL_IDE_DISKS;
+ else if (!strcmp(p, "aux-ide-disks"))
+ unplug |= UNPLUG_AUX_IDE_DISKS;
+ else if (!strcmp(p, "nics"))
+ unplug |= UNPLUG_ALL_NICS;
+ else
+ dev_warn(dev, "unrecognised option '%s' "
+ "in module parameter 'dev_unplug'\n", p);
+ }
+
+ if (iolen < 0x16) {
+ err = "backend too old";
+ goto no_dev;
+ }
magic = inw(XEN_IOPORT_MAGIC);
if (magic != XEN_IOPORT_MAGIC_VAL) {
- dev_err(dev, "invalid magic %#x", magic);
- return -ENODEV;
+ err = "unrecognised magic value";
+ goto no_dev;
}
protocol = inb(XEN_IOPORT_PROTOVER);
@@ -293,8 +324,8 @@ static int check_platform_magic(struct d
switch (protocol) {
case 1:
- outw(XEN_IOPORT_PRODNUM, 0xbeef);
- outl(XEN_IOPORT_DRVVER, 0xdead);
+ outw(XEN_IOPORT_PRODNUM, XEN_IOPORT_LINUX_PRODNUM);
+ outl(XEN_IOPORT_DRVVER, XEN_IOPORT_LINUX_DRVVER);
if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
dev_err(dev, "blacklisted by host\n");
return -ENODEV;
@@ -304,11 +335,18 @@ static int check_platform_magic(struct d
outw(XEN_IOPORT_UNPLUG, 0xf);
break;
default:
- dev_err(dev, "unknown qemu version\n");
- return -ENODEV;
- }
-
- return 0;
+ err = "unknown I/O protocol version";
+ goto no_dev;
+ }
+
+ return 0;
+
+ no_dev:
+ dev_warn(dev, "failed backend handshake: %s\n", err);
+ if (!unplug)
+ return 0;
+ dev_err(dev, "failed to execute specified dev_unplug options!\n");
+ return -ENODEV;
}
static int __devinit platform_pci_init(struct pci_dev *pdev,
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|