source: trunk/packages/xen-3.1/xen-3.1/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 3.7 KB
Line 
1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License version 2
4 * as published by the Free Software Foundation; or, when distributed
5 * separately from the Linux kernel or incorporated into other
6 * software packages, subject to the following license:
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this source file (the "Software"), to deal in the Software without
10 * restriction, including without limitation the rights to use, copy, modify,
11 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27#include <linux/version.h>
28#include <linux/module.h>
29#include <linux/errno.h>
30#include <linux/signal.h>
31#include <linux/sched.h>
32#include <linux/interrupt.h>
33#include <linux/tty.h>
34#include <linux/tty_flip.h>
35#include <linux/serial.h>
36#include <linux/major.h>
37#include <linux/ptrace.h>
38#include <linux/ioport.h>
39#include <linux/mm.h>
40#include <linux/slab.h>
41
42#include <asm/hypervisor.h>
43#include <xen/evtchn.h>
44#include <xen/xencons.h>
45#include <linux/wait.h>
46#include <linux/interrupt.h>
47#include <linux/sched.h>
48#include <linux/err.h>
49#include <xen/interface/io/console.h>
50
51static int xencons_irq;
52
53static inline struct xencons_interface *xencons_interface(void)
54{
55        return mfn_to_virt(xen_start_info->console.domU.mfn);
56}
57
58static inline void notify_daemon(void)
59{
60        /* Use evtchn: this is called early, before irq is set up. */
61        notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
62}
63
64int xencons_ring_send(const char *data, unsigned len)
65{
66        int sent = 0;
67        struct xencons_interface *intf = xencons_interface();
68        XENCONS_RING_IDX cons, prod;
69
70        cons = intf->out_cons;
71        prod = intf->out_prod;
72        mb();
73        BUG_ON((prod - cons) > sizeof(intf->out));
74
75        while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
76                intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
77
78        wmb();
79        intf->out_prod = prod;
80
81        notify_daemon();
82
83        return sent;
84}
85
86static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
87{
88        struct xencons_interface *intf = xencons_interface();
89        XENCONS_RING_IDX cons, prod;
90
91        cons = intf->in_cons;
92        prod = intf->in_prod;
93        mb();
94        BUG_ON((prod - cons) > sizeof(intf->in));
95
96        while (cons != prod) {
97                xencons_rx(intf->in+MASK_XENCONS_IDX(cons,intf->in), 1, regs);
98                cons++;
99        }
100
101        mb();
102        intf->in_cons = cons;
103
104        notify_daemon();
105
106        xencons_tx();
107
108        return IRQ_HANDLED;
109}
110
111int xencons_ring_init(void)
112{
113        int irq;
114
115        if (xencons_irq)
116                unbind_from_irqhandler(xencons_irq, NULL);
117        xencons_irq = 0;
118
119        if (!is_running_on_xen() ||
120            is_initial_xendomain() ||
121            !xen_start_info->console.domU.evtchn)
122                return -ENODEV;
123
124        irq = bind_caller_port_to_irqhandler(
125                xen_start_info->console.domU.evtchn,
126                handle_input, 0, "xencons", NULL);
127        if (irq < 0) {
128                printk(KERN_ERR "XEN console request irq failed %i\n", irq);
129                return irq;
130        }
131
132        xencons_irq = irq;
133
134        /* In case we have in-flight data after save/restore... */
135        notify_daemon();
136
137        return 0;
138}
139
140void xencons_resume(void)
141{
142        (void)xencons_ring_init();
143}
Note: See TracBrowser for help on using the repository browser.