aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
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, ...)