aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-28 20:11:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-28 20:11:17 -0400
commit18cb657ca1bafe635f368346a1676fb04c512edf (patch)
treeb0eb6a4ceddf98e7bf820be7ff24bf131ff56b0c /drivers/char
parent2301b65b86df8b80e6779ce9885ad62a5c4adc38 (diff)
parente28c31a96b1570f17731b18e8efabb7308d0c22c (diff)
Merge branch 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
and branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm * 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm: xen: register xen pci notifier xen: initialize cpu masks for pv guests in xen_smp_init xen: add a missing #include to arch/x86/pci/xen.c xen: mask the MTRR feature from the cpuid xen: make hvc_xen console work for dom0. xen: add the direct mapping area for ISA bus access xen: Initialize xenbus for dom0. xen: use vcpu_ops to setup cpu masks xen: map a dummy page for local apic and ioapic in xen_set_fixmap xen: remap MSIs into pirqs when running as initial domain xen: remap GSIs as pirqs when running as initial domain xen: introduce XEN_DOM0 as a silent option xen: map MSIs into pirqs xen: support GSI -> pirq remapping in PV on HVM guests xen: add xen hvm acpi_register_gsi variant acpi: use indirect call to register gsi in different modes xen: implement xen_hvm_register_pirq xen: get the maximum number of pirqs from xen xen: support pirq != irq * 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: (27 commits) X86/PCI: Remove the dependency on isapnp_disable. xen: Update Makefile with CONFIG_BLOCK dependency for biomerge.c MAINTAINERS: Add myself to the Xen Hypervisor Interface and remove Chris Wright. x86: xen: Sanitse irq handling (part two) swiotlb-xen: On x86-32 builts, select SWIOTLB instead of depending on it. MAINTAINERS: Add myself for Xen PCI and Xen SWIOTLB maintainer. xen/pci: Request ACS when Xen-SWIOTLB is activated. xen-pcifront: Xen PCI frontend driver. xenbus: prevent warnings on unhandled enumeration values xenbus: Xen paravirtualised PCI hotplug support. xen/x86/PCI: Add support for the Xen PCI subsystem x86: Introduce x86_msi_ops msi: Introduce default_[teardown|setup]_msi_irqs with fallback. x86/PCI: Export pci_walk_bus function. x86/PCI: make sure _PAGE_IOMAP it set on pci mappings x86/PCI: Clean up pci_cache_line_size xen: fix shared irq device passthrough xen: Provide a variant of xen_poll_irq with timeout. xen: Find an unbound irq number in reverse order (high to low). xen: statically initialize cpu_evtchn_mask_p ... Fix up trivial conflicts in drivers/pci/Makefile
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/hvc_xen.c98
1 files changed, 65 insertions, 33 deletions
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index 6b8e6d18a8e6..3740e327f180 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -79,7 +79,7 @@ static int __write_console(const char *data, int len)
79 return sent; 79 return sent;
80} 80}
81 81
82static int write_console(uint32_t vtermno, const char *data, int len) 82static int domU_write_console(uint32_t vtermno, const char *data, int len)
83{ 83{
84 int ret = len; 84 int ret = len;
85 85
@@ -102,7 +102,7 @@ static int write_console(uint32_t vtermno, const char *data, int len)
102 return ret; 102 return ret;
103} 103}
104 104
105static int read_console(uint32_t vtermno, char *buf, int len) 105static int domU_read_console(uint32_t vtermno, char *buf, int len)
106{ 106{
107 struct xencons_interface *intf = xencons_interface(); 107 struct xencons_interface *intf = xencons_interface();
108 XENCONS_RING_IDX cons, prod; 108 XENCONS_RING_IDX cons, prod;
@@ -123,28 +123,62 @@ static int read_console(uint32_t vtermno, char *buf, int len)
123 return recv; 123 return recv;
124} 124}
125 125
126static const struct hv_ops hvc_ops = { 126static struct hv_ops domU_hvc_ops = {
127 .get_chars = read_console, 127 .get_chars = domU_read_console,
128 .put_chars = write_console, 128 .put_chars = domU_write_console,
129 .notifier_add = notifier_add_irq, 129 .notifier_add = notifier_add_irq,
130 .notifier_del = notifier_del_irq, 130 .notifier_del = notifier_del_irq,
131 .notifier_hangup = notifier_hangup_irq, 131 .notifier_hangup = notifier_hangup_irq,
132}; 132};
133 133
134static int __init xen_init(void) 134static int dom0_read_console(uint32_t vtermno, char *buf, int len)
135{
136 return HYPERVISOR_console_io(CONSOLEIO_read, len, buf);
137}
138
139/*
140 * Either for a dom0 to write to the system console, or a domU with a
141 * debug version of Xen
142 */
143static int dom0_write_console(uint32_t vtermno, const char *str, int len)
144{
145 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
146 if (rc < 0)
147 return 0;
148
149 return len;
150}
151
152static struct hv_ops dom0_hvc_ops = {
153 .get_chars = dom0_read_console,
154 .put_chars = dom0_write_console,
155 .notifier_add = notifier_add_irq,
156 .notifier_del = notifier_del_irq,
157 .notifier_hangup = notifier_hangup_irq,
158};
159
160static int __init xen_hvc_init(void)
135{ 161{
136 struct hvc_struct *hp; 162 struct hvc_struct *hp;
163 struct hv_ops *ops;
137 164
138 if (!xen_pv_domain() || 165 if (!xen_pv_domain())
139 xen_initial_domain() ||
140 !xen_start_info->console.domU.evtchn)
141 return -ENODEV; 166 return -ENODEV;
142 167
143 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); 168 if (xen_initial_domain()) {
169 ops = &dom0_hvc_ops;
170 xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
171 } else {
172 if (!xen_start_info->console.domU.evtchn)
173 return -ENODEV;
174
175 ops = &domU_hvc_ops;
176 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
177 }
144 if (xencons_irq < 0) 178 if (xencons_irq < 0)
145 xencons_irq = 0; /* NO_IRQ */ 179 xencons_irq = 0; /* NO_IRQ */
146 180
147 hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); 181 hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
148 if (IS_ERR(hp)) 182 if (IS_ERR(hp))
149 return PTR_ERR(hp); 183 return PTR_ERR(hp);
150 184
@@ -161,7 +195,7 @@ void xen_console_resume(void)
161 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); 195 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
162} 196}
163 197
164static void __exit xen_fini(void) 198static void __exit xen_hvc_fini(void)
165{ 199{
166 if (hvc) 200 if (hvc)
167 hvc_remove(hvc); 201 hvc_remove(hvc);
@@ -169,29 +203,24 @@ static void __exit xen_fini(void)
169 203
170static int xen_cons_init(void) 204static int xen_cons_init(void)
171{ 205{
206 struct hv_ops *ops;
207
172 if (!xen_pv_domain()) 208 if (!xen_pv_domain())
173 return 0; 209 return 0;
174 210
175 hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); 211 if (xen_initial_domain())
212 ops = &dom0_hvc_ops;
213 else
214 ops = &domU_hvc_ops;
215
216 hvc_instantiate(HVC_COOKIE, 0, ops);
176 return 0; 217 return 0;
177} 218}
178 219
179module_init(xen_init); 220module_init(xen_hvc_init);
180module_exit(xen_fini); 221module_exit(xen_hvc_fini);
181console_initcall(xen_cons_init); 222console_initcall(xen_cons_init);
182 223
183static void raw_console_write(const char *str, int len)
184{
185 while(len > 0) {
186 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
187 if (rc <= 0)
188 break;
189
190 str += rc;
191 len -= rc;
192 }
193}
194
195#ifdef CONFIG_EARLY_PRINTK 224#ifdef CONFIG_EARLY_PRINTK
196static void xenboot_write_console(struct console *console, const char *string, 225static void xenboot_write_console(struct console *console, const char *string,
197 unsigned len) 226 unsigned len)
@@ -199,19 +228,22 @@ static void xenboot_write_console(struct console *console, const char *string,
199 unsigned int linelen, off = 0; 228 unsigned int linelen, off = 0;
200 const char *pos; 229 const char *pos;
201 230
202 raw_console_write(string, len); 231 dom0_write_console(0, string, len);
232
233 if (xen_initial_domain())
234 return;
203 235
204 write_console(0, "(early) ", 8); 236 domU_write_console(0, "(early) ", 8);
205 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 237 while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
206 linelen = pos-string+off; 238 linelen = pos-string+off;
207 if (off + linelen > len) 239 if (off + linelen > len)
208 break; 240 break;
209 write_console(0, string+off, linelen); 241 domU_write_console(0, string+off, linelen);
210 write_console(0, "\r\n", 2); 242 domU_write_console(0, "\r\n", 2);
211 off += linelen + 1; 243 off += linelen + 1;
212 } 244 }
213 if (off < len) 245 if (off < len)
214 write_console(0, string+off, len-off); 246 domU_write_console(0, string+off, len-off);
215} 247}
216 248
217struct console xenboot_console = { 249struct console xenboot_console = {
@@ -223,7 +255,7 @@ struct console xenboot_console = {
223 255
224void xen_raw_console_write(const char *str) 256void xen_raw_console_write(const char *str)
225{ 257{
226 raw_console_write(str, strlen(str)); 258 dom0_write_console(0, str, strlen(str));
227} 259}
228 260
229void xen_raw_printk(const char *fmt, ...) 261void xen_raw_printk(const char *fmt, ...)