26 #include <linux/types.h>
27 #include <linux/list.h>
30 #include <asm/xen/hypervisor.h>
37 #include <xen/events.h>
45 #define HVC_COOKIE 0x58656e
67 if (list_empty(&xenconsoles))
71 if (entry->
vtermno == vtermno) {
80 static inline int xenbus_devid_to_vtermno(
int devid)
88 notify_remote_via_evtchn(cons->
evtchn);
92 const char *
data,
int len)
101 BUG_ON((prod - cons) >
sizeof(intf->
out));
103 while ((sent < len) && ((prod - cons) <
sizeof(intf->
out)))
110 notify_daemon(xencons);
114 static int domU_write_console(
uint32_t vtermno,
const char *data,
int len)
117 struct xencons_info *cons = vtermno_to_xencons(vtermno);
128 int sent = __write_console(cons, data, len);
140 static int domU_read_console(
uint32_t vtermno,
char *
buf,
int len)
145 struct xencons_info *xencons = vtermno_to_xencons(vtermno);
148 intf = xencons->
intf;
153 BUG_ON((prod - cons) >
sizeof(intf->
in));
155 while (cons != prod && recv < len)
161 notify_daemon(xencons);
165 static struct hv_ops domU_hvc_ops = {
166 .get_chars = domU_read_console,
167 .put_chars = domU_write_console,
173 static int dom0_read_console(
uint32_t vtermno,
char *buf,
int len)
182 static int dom0_write_console(
uint32_t vtermno,
const char *
str,
int len)
191 static struct hv_ops dom0_hvc_ops = {
192 .get_chars = dom0_read_console,
193 .put_chars = dom0_write_console,
199 static int xen_hvm_console_init(
void)
238 spin_lock(&xencons_lock);
240 spin_unlock(&xencons_lock);
248 static int xen_pv_console_init(
void)
271 spin_lock(&xencons_lock);
273 spin_unlock(&xencons_lock);
278 static int xen_initial_domain_console_init(
void)
295 spin_lock(&xencons_lock);
297 spin_unlock(&xencons_lock);
309 static void xencons_disconnect_backend(
struct xencons_info *info)
333 static int xen_console_remove(
struct xencons_info *info)
335 xencons_disconnect_backend(info);
336 spin_lock(&xencons_lock);
338 spin_unlock(&xencons_lock);
349 #ifdef CONFIG_HVC_XEN_FRONTEND
357 static int xencons_connect_backend(
struct xenbus_device *dev,
375 irq, &domU_hvc_ops, 256);
376 if (IS_ERR(info->
hvc))
377 return PTR_ERR(info->
hvc);
440 info->
vtermno = xenbus_devid_to_vtermno(devid);
445 ret = xencons_connect_backend(dev, info);
448 spin_lock(&xencons_lock);
450 spin_unlock(&xencons_lock);
458 xencons_disconnect_backend(info);
467 xencons_disconnect_backend(info);
469 return xencons_connect_backend(dev, info);
472 static void xencons_backend_changed(
struct xenbus_device *dev,
475 switch (backend_state) {
507 .probe = xencons_probe,
508 .
remove = xencons_remove,
510 .otherend_changed = xencons_backend_changed,
514 static int __init xen_hvc_init(
void)
525 r = xen_initial_domain_console_init();
532 r = xen_hvm_console_init();
534 r = xen_pv_console_init();
544 irq_set_noprobe(info->
irq);
547 if (IS_ERR(info->
hvc)) {
548 r = PTR_ERR(info->
hvc);
549 spin_lock(&xencons_lock);
551 spin_unlock(&xencons_lock);
559 #ifdef CONFIG_HVC_XEN_FRONTEND
565 static void __exit xen_hvc_fini(
void)
569 if (list_empty(&xenconsoles))
573 xen_console_remove(entry);
577 static int xen_cons_init(
void)
591 r = xen_hvm_console_init();
593 r = xen_pv_console_init();
607 #ifdef CONFIG_EARLY_PRINTK
608 static void xenboot_write_console(
struct console *
console,
const char *
string,
611 unsigned int linelen, off = 0;
617 dom0_write_console(0,
string, len);
622 domU_write_console(0,
"(early) ", 8);
623 while (off < len &&
NULL != (pos =
strchr(
string+off,
'\n'))) {
624 linelen = pos-
string+off;
625 if (off + linelen > len)
627 domU_write_console(0,
string+off, linelen);
628 domU_write_console(0,
"\r\n", 2);
632 domU_write_console(0,
string+off, len-off);
637 .write = xenboot_write_console,
644 dom0_write_console(0, str,
strlen(str));
649 static char buf[512];