diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-02-21 06:30:42 -0500 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-03-13 19:24:31 -0400 |
commit | cf8e019b523a8caa95b56ff0ce62a4856b14395f (patch) | |
tree | 306ac28035398e3afe42c35ef5d5863254ef394c /drivers/tty/hvc | |
parent | 02e19f9c7cacfb33d7b2f5cace7972fa60f92319 (diff) |
hvc_xen: introduce HVC_XEN_FRONTEND
Introduce a new config option HVC_XEN_FRONTEND to enable/disable the
xenbus based pv console frontend.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r-- | drivers/tty/hvc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/tty/hvc/hvc_xen.c | 116 |
2 files changed, 70 insertions, 54 deletions
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig index 4222035acfb7..192e21e2239c 100644 --- a/drivers/tty/hvc/Kconfig +++ b/drivers/tty/hvc/Kconfig | |||
@@ -76,6 +76,14 @@ config HVC_XEN | |||
76 | help | 76 | help |
77 | Xen virtual console device driver | 77 | Xen virtual console device driver |
78 | 78 | ||
79 | config HVC_XEN_FRONTEND | ||
80 | bool "Xen Hypervisor Multiple Consoles support" | ||
81 | depends on HVC_XEN | ||
82 | select XEN_XENBUS_FRONTEND | ||
83 | default y | ||
84 | help | ||
85 | Xen driver for secondary virtual consoles | ||
86 | |||
79 | config HVC_UDBG | 87 | config HVC_UDBG |
80 | bool "udbg based fake hypervisor console" | 88 | bool "udbg based fake hypervisor console" |
81 | depends on PPC && EXPERIMENTAL | 89 | depends on PPC && EXPERIMENTAL |
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 26090c736bcf..83d5c88e7165 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c | |||
@@ -55,7 +55,6 @@ struct xencons_info { | |||
55 | 55 | ||
56 | static LIST_HEAD(xenconsoles); | 56 | static LIST_HEAD(xenconsoles); |
57 | static DEFINE_SPINLOCK(xencons_lock); | 57 | static DEFINE_SPINLOCK(xencons_lock); |
58 | static struct xenbus_driver xencons_driver; | ||
59 | 58 | ||
60 | /* ------------------------------------------------------------------ */ | 59 | /* ------------------------------------------------------------------ */ |
61 | 60 | ||
@@ -298,53 +297,6 @@ static int xen_initial_domain_console_init(void) | |||
298 | return 0; | 297 | return 0; |
299 | } | 298 | } |
300 | 299 | ||
301 | static int __init xen_hvc_init(void) | ||
302 | { | ||
303 | int r; | ||
304 | struct xencons_info *info; | ||
305 | const struct hv_ops *ops; | ||
306 | |||
307 | if (!xen_domain()) | ||
308 | return -ENODEV; | ||
309 | |||
310 | if (xen_initial_domain()) { | ||
311 | ops = &dom0_hvc_ops; | ||
312 | r = xen_initial_domain_console_init(); | ||
313 | if (r < 0) | ||
314 | return r; | ||
315 | info = vtermno_to_xencons(HVC_COOKIE); | ||
316 | } else { | ||
317 | ops = &domU_hvc_ops; | ||
318 | if (xen_hvm_domain()) | ||
319 | r = xen_hvm_console_init(); | ||
320 | else | ||
321 | r = xen_pv_console_init(); | ||
322 | if (r < 0) | ||
323 | return r; | ||
324 | |||
325 | info = vtermno_to_xencons(HVC_COOKIE); | ||
326 | info->irq = bind_evtchn_to_irq(info->evtchn); | ||
327 | } | ||
328 | if (info->irq < 0) | ||
329 | info->irq = 0; /* NO_IRQ */ | ||
330 | else | ||
331 | irq_set_noprobe(info->irq); | ||
332 | |||
333 | info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); | ||
334 | if (IS_ERR(info->hvc)) { | ||
335 | r = PTR_ERR(info->hvc); | ||
336 | spin_lock(&xencons_lock); | ||
337 | list_del(&info->list); | ||
338 | spin_unlock(&xencons_lock); | ||
339 | if (info->irq) | ||
340 | unbind_from_irqhandler(info->irq, NULL); | ||
341 | kfree(info); | ||
342 | return r; | ||
343 | } | ||
344 | |||
345 | return xenbus_register_frontend(&xencons_driver); | ||
346 | } | ||
347 | |||
348 | void xen_console_resume(void) | 300 | void xen_console_resume(void) |
349 | { | 301 | { |
350 | struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); | 302 | struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); |
@@ -392,6 +344,9 @@ static int xen_console_remove(struct xencons_info *info) | |||
392 | return 0; | 344 | return 0; |
393 | } | 345 | } |
394 | 346 | ||
347 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
348 | static struct xenbus_driver xencons_driver; | ||
349 | |||
395 | static int xencons_remove(struct xenbus_device *dev) | 350 | static int xencons_remove(struct xenbus_device *dev) |
396 | { | 351 | { |
397 | return xen_console_remove(dev_get_drvdata(&dev->dev)); | 352 | return xen_console_remove(dev_get_drvdata(&dev->dev)); |
@@ -543,6 +498,65 @@ static const struct xenbus_device_id xencons_ids[] = { | |||
543 | }; | 498 | }; |
544 | 499 | ||
545 | 500 | ||
501 | static DEFINE_XENBUS_DRIVER(xencons, "xenconsole", | ||
502 | .probe = xencons_probe, | ||
503 | .remove = xencons_remove, | ||
504 | .resume = xencons_resume, | ||
505 | .otherend_changed = xencons_backend_changed, | ||
506 | ); | ||
507 | #endif /* CONFIG_HVC_XEN_FRONTEND */ | ||
508 | |||
509 | static int __init xen_hvc_init(void) | ||
510 | { | ||
511 | int r; | ||
512 | struct xencons_info *info; | ||
513 | const struct hv_ops *ops; | ||
514 | |||
515 | if (!xen_domain()) | ||
516 | return -ENODEV; | ||
517 | |||
518 | if (xen_initial_domain()) { | ||
519 | ops = &dom0_hvc_ops; | ||
520 | r = xen_initial_domain_console_init(); | ||
521 | if (r < 0) | ||
522 | return r; | ||
523 | info = vtermno_to_xencons(HVC_COOKIE); | ||
524 | } else { | ||
525 | ops = &domU_hvc_ops; | ||
526 | if (xen_hvm_domain()) | ||
527 | r = xen_hvm_console_init(); | ||
528 | else | ||
529 | r = xen_pv_console_init(); | ||
530 | if (r < 0) | ||
531 | return r; | ||
532 | |||
533 | info = vtermno_to_xencons(HVC_COOKIE); | ||
534 | info->irq = bind_evtchn_to_irq(info->evtchn); | ||
535 | } | ||
536 | if (info->irq < 0) | ||
537 | info->irq = 0; /* NO_IRQ */ | ||
538 | else | ||
539 | irq_set_noprobe(info->irq); | ||
540 | |||
541 | info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); | ||
542 | if (IS_ERR(info->hvc)) { | ||
543 | r = PTR_ERR(info->hvc); | ||
544 | spin_lock(&xencons_lock); | ||
545 | list_del(&info->list); | ||
546 | spin_unlock(&xencons_lock); | ||
547 | if (info->irq) | ||
548 | unbind_from_irqhandler(info->irq, NULL); | ||
549 | kfree(info); | ||
550 | return r; | ||
551 | } | ||
552 | |||
553 | r = 0; | ||
554 | #ifdef CONFIG_HVC_XEN_FRONTEND | ||
555 | r = xenbus_register_frontend(&xencons_driver); | ||
556 | #endif | ||
557 | return r; | ||
558 | } | ||
559 | |||
546 | static void __exit xen_hvc_fini(void) | 560 | static void __exit xen_hvc_fini(void) |
547 | { | 561 | { |
548 | struct xencons_info *entry, *next; | 562 | struct xencons_info *entry, *next; |
@@ -580,12 +594,6 @@ static int xen_cons_init(void) | |||
580 | return 0; | 594 | return 0; |
581 | } | 595 | } |
582 | 596 | ||
583 | static DEFINE_XENBUS_DRIVER(xencons, "xenconsole", | ||
584 | .probe = xencons_probe, | ||
585 | .remove = xencons_remove, | ||
586 | .resume = xencons_resume, | ||
587 | .otherend_changed = xencons_backend_changed, | ||
588 | ); | ||
589 | 597 | ||
590 | module_init(xen_hvc_init); | 598 | module_init(xen_hvc_init); |
591 | module_exit(xen_hvc_fini); | 599 | module_exit(xen_hvc_fini); |