Blame view

arch/x86/xen/platform-pci-unplug.c 4.37 KB
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  /******************************************************************************
   * platform-pci-unplug.c
   *
   * Xen platform PCI device driver
   * Copyright (c) 2010, Citrix
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms and conditions of the GNU General Public License,
   * version 2, as published by the Free Software Foundation.
   *
   * This program is distributed in the hope it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   * more details.
   *
   * You should have received a copy of the GNU General Public License along with
   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   * Place - Suite 330, Boston, MA 02111-1307 USA.
   *
   */
  
  #include <linux/init.h>
  #include <linux/io.h>
  #include <linux/module.h>
  
  #include <xen/platform_pci.h>
  
  #define XEN_PLATFORM_ERR_MAGIC -1
  #define XEN_PLATFORM_ERR_PROTOCOL -2
  #define XEN_PLATFORM_ERR_BLACKLIST -3
  
  /* store the value of xen_emul_unplug after the unplug is done */
  int xen_platform_pci_unplug;
  EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
ca65f9fc0   Stefano Stabellini   Introduce CONFIG_...
35
  #ifdef CONFIG_XEN_PVHVM
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
36
  static int xen_emul_unplug;
3c52b7bf6   Raghavendra D Prabhu   xen:pvhvm: Modpos...
37
  static int check_platform_magic(void)
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
  {
  	short magic;
  	char protocol;
  
  	magic = inw(XEN_IOPORT_MAGIC);
  	if (magic != XEN_IOPORT_MAGIC_VAL) {
  		printk(KERN_ERR "Xen Platform PCI: unrecognised magic value
  ");
  		return XEN_PLATFORM_ERR_MAGIC;
  	}
  
  	protocol = inb(XEN_IOPORT_PROTOVER);
  
  	printk(KERN_DEBUG "Xen Platform PCI: I/O protocol version %d
  ",
  			protocol);
  
  	switch (protocol) {
  	case 1:
  		outw(XEN_IOPORT_LINUX_PRODNUM, XEN_IOPORT_PRODNUM);
  		outl(XEN_IOPORT_LINUX_DRVVER, XEN_IOPORT_DRVVER);
  		if (inw(XEN_IOPORT_MAGIC) != XEN_IOPORT_MAGIC_VAL) {
  			printk(KERN_ERR "Xen Platform: blacklisted by host
  ");
  			return XEN_PLATFORM_ERR_BLACKLIST;
  		}
  		break;
  	default:
  		printk(KERN_WARNING "Xen Platform PCI: unknown I/O protocol version");
  		return XEN_PLATFORM_ERR_PROTOCOL;
  	}
  
  	return 0;
  }
512b109ec   Stefano Stabellini   xen: unplug the e...
72
  void xen_unplug_emulated_devices(void)
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
73
74
  {
  	int r;
c93a4dfb3   Ian Campbell   xen: pvhvm: allow...
75
76
77
  	/* user explicitly requested no unplug */
  	if (xen_emul_unplug & XEN_UNPLUG_NEVER)
  		return;
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
78
79
80
  	/* check the version of the xen platform PCI device */
  	r = check_platform_magic();
  	/* If the version matches enable the Xen platform PCI driver.
1dc7ce99b   Ian Campbell   xen: pvhvm: renam...
81
82
83
  	 * Also enable the Xen platform PCI driver if the host does
  	 * not support the unplug protocol (XEN_PLATFORM_ERR_MAGIC)
  	 * but the user told us that unplugging is unnecessary. */
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
84
  	if (r && !(r == XEN_PLATFORM_ERR_MAGIC &&
1dc7ce99b   Ian Campbell   xen: pvhvm: renam...
85
  			(xen_emul_unplug & XEN_UNPLUG_UNNECESSARY)))
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  		return;
  	/* Set the default value of xen_emul_unplug depending on whether or
  	 * not the Xen PV frontends and the Xen platform PCI driver have
  	 * been compiled for this kernel (modules or built-in are both OK). */
  	if (!xen_emul_unplug) {
  		if (xen_must_unplug_nics()) {
  			printk(KERN_INFO "Netfront and the Xen platform PCI driver have "
  					"been compiled for this kernel: unplug emulated NICs.
  ");
  			xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
  		}
  		if (xen_must_unplug_disks()) {
  			printk(KERN_INFO "Blkfront and the Xen platform PCI driver have "
  					"been compiled for this kernel: unplug emulated disks.
  "
  					"You might have to change the root device
  "
  					"from /dev/hd[a-d] to /dev/xvd[a-d]
  "
  					"in your root= kernel command line option
  ");
  			xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
  		}
  	}
  	/* Now unplug the emulated devices */
1dc7ce99b   Ian Campbell   xen: pvhvm: renam...
111
  	if (!(xen_emul_unplug & XEN_UNPLUG_UNNECESSARY))
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  		outw(xen_emul_unplug, XEN_IOPORT_UNPLUG);
  	xen_platform_pci_unplug = xen_emul_unplug;
  }
  
  static int __init parse_xen_emul_unplug(char *arg)
  {
  	char *p, *q;
  	int l;
  
  	for (p = arg; p; p = q) {
  		q = strchr(p, ',');
  		if (q) {
  			l = q - p;
  			q++;
  		} else {
  			l = strlen(p);
  		}
  		if (!strncmp(p, "all", l))
  			xen_emul_unplug |= XEN_UNPLUG_ALL;
  		else if (!strncmp(p, "ide-disks", l))
  			xen_emul_unplug |= XEN_UNPLUG_ALL_IDE_DISKS;
  		else if (!strncmp(p, "aux-ide-disks", l))
  			xen_emul_unplug |= XEN_UNPLUG_AUX_IDE_DISKS;
  		else if (!strncmp(p, "nics", l))
  			xen_emul_unplug |= XEN_UNPLUG_ALL_NICS;
1dc7ce99b   Ian Campbell   xen: pvhvm: renam...
137
138
  		else if (!strncmp(p, "unnecessary", l))
  			xen_emul_unplug |= XEN_UNPLUG_UNNECESSARY;
c93a4dfb3   Ian Campbell   xen: pvhvm: allow...
139
140
  		else if (!strncmp(p, "never", l))
  			xen_emul_unplug |= XEN_UNPLUG_NEVER;
c1c5413ad   Stefano Stabellini   x86: Unplug emula...
141
142
143
144
145
146
147
148
  		else
  			printk(KERN_WARNING "unrecognised option '%s' "
  				 "in parameter 'xen_emul_unplug'
  ", p);
  	}
  	return 0;
  }
  early_param("xen_emul_unplug", parse_xen_emul_unplug);
ca65f9fc0   Stefano Stabellini   Introduce CONFIG_...
149
  #endif