aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/um/drivers
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/chan.h50
-rw-r--r--arch/um/drivers/chan_kern.c240
-rw-r--r--arch/um/drivers/chan_user.c13
-rw-r--r--arch/um/drivers/chan_user.h53
-rw-r--r--arch/um/drivers/cow.h35
-rw-r--r--arch/um/drivers/cow_sys.h7
-rw-r--r--arch/um/drivers/cow_user.c43
-rw-r--r--arch/um/drivers/daemon.h2
-rw-r--r--arch/um/drivers/daemon_kern.c4
-rw-r--r--arch/um/drivers/daemon_user.c7
-rw-r--r--arch/um/drivers/fd.c6
-rw-r--r--arch/um/drivers/harddog_user.c3
-rw-r--r--arch/um/drivers/hostaudio_kern.c18
-rw-r--r--arch/um/drivers/line.c476
-rw-r--r--arch/um/drivers/line.h99
-rw-r--r--arch/um/drivers/mconsole.h98
-rw-r--r--arch/um/drivers/mconsole_kern.c116
-rw-r--r--arch/um/drivers/mconsole_kern.h52
-rw-r--r--arch/um/drivers/mconsole_user.c2
-rw-r--r--arch/um/drivers/mmapper_kern.c2
-rw-r--r--arch/um/drivers/net_kern.c31
-rw-r--r--arch/um/drivers/net_user.c8
-rw-r--r--arch/um/drivers/null.c2
-rw-r--r--arch/um/drivers/pcap_kern.c4
-rw-r--r--arch/um/drivers/pcap_user.c6
-rw-r--r--arch/um/drivers/pcap_user.h2
-rw-r--r--arch/um/drivers/port_kern.c28
-rw-r--r--arch/um/drivers/port_user.c6
-rw-r--r--arch/um/drivers/pty.c6
-rw-r--r--arch/um/drivers/random.c7
-rw-r--r--arch/um/drivers/slip_common.c2
-rw-r--r--arch/um/drivers/slip_kern.c2
-rw-r--r--arch/um/drivers/slip_user.c8
-rw-r--r--arch/um/drivers/slirp_kern.c6
-rw-r--r--arch/um/drivers/slirp_user.c6
-rw-r--r--arch/um/drivers/ssl.c109
-rw-r--r--arch/um/drivers/stdio_console.c106
-rw-r--r--arch/um/drivers/tty.c6
-rw-r--r--arch/um/drivers/ubd.h16
-rw-r--r--arch/um/drivers/ubd_kern.c58
-rw-r--r--arch/um/drivers/ubd_user.c9
-rw-r--r--arch/um/drivers/umcast.h2
-rw-r--r--arch/um/drivers/umcast_kern.c4
-rw-r--r--arch/um/drivers/umcast_user.c6
-rw-r--r--arch/um/drivers/vde_kern.c6
-rw-r--r--arch/um/drivers/vde_user.c6
-rw-r--r--arch/um/drivers/xterm.c6
-rw-r--r--arch/um/drivers/xterm_kern.c9
48 files changed, 872 insertions, 921 deletions
diff --git a/arch/um/drivers/chan.h b/arch/um/drivers/chan.h
deleted file mode 100644
index 02b5a76e98d..00000000000
--- a/arch/um/drivers/chan.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __CHAN_KERN_H__
7#define __CHAN_KERN_H__
8
9#include <linux/tty.h>
10#include <linux/list.h>
11#include <linux/console.h>
12#include "chan_user.h"
13#include "line.h"
14
15struct chan {
16 struct list_head list;
17 struct list_head free_list;
18 struct line *line;
19 char *dev;
20 unsigned int primary:1;
21 unsigned int input:1;
22 unsigned int output:1;
23 unsigned int opened:1;
24 unsigned int enabled:1;
25 int fd;
26 const struct chan_ops *ops;
27 void *data;
28};
29
30extern void chan_interrupt(struct line *line,
31 struct tty_struct *tty, int irq);
32extern int parse_chan_pair(char *str, struct line *line, int device,
33 const struct chan_opts *opts, char **error_out);
34extern int write_chan(struct chan *chan, const char *buf, int len,
35 int write_irq);
36extern int console_write_chan(struct chan *chan, const char *buf,
37 int len);
38extern int console_open_chan(struct line *line, struct console *co);
39extern void deactivate_chan(struct chan *chan, int irq);
40extern void reactivate_chan(struct chan *chan, int irq);
41extern void chan_enable_winch(struct chan *chan, struct tty_struct *tty);
42extern int enable_chan(struct line *line);
43extern void close_chan(struct line *line);
44extern int chan_window_size(struct line *line,
45 unsigned short *rows_out,
46 unsigned short *cols_out);
47extern int chan_config_string(struct line *line, char *str, int size,
48 char **error_out);
49
50#endif
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index e9a0abc6a32..d4191fe1ced 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -6,9 +6,8 @@
6#include <linux/slab.h> 6#include <linux/slab.h>
7#include <linux/tty.h> 7#include <linux/tty.h>
8#include <linux/tty_flip.h> 8#include <linux/tty_flip.h>
9#include "chan.h" 9#include "chan_kern.h"
10#include <os.h> 10#include "os.h"
11#include <irq_kern.h>
12 11
13#ifdef CONFIG_NOCONFIG_CHAN 12#ifdef CONFIG_NOCONFIG_CHAN
14static void *not_configged_init(char *str, int device, 13static void *not_configged_init(char *str, int device,
@@ -83,8 +82,21 @@ static const struct chan_ops not_configged_ops = {
83 82
84static void tty_receive_char(struct tty_struct *tty, char ch) 83static void tty_receive_char(struct tty_struct *tty, char ch)
85{ 84{
86 if (tty) 85 if (tty == NULL)
87 tty_insert_flip_char(tty, ch, TTY_NORMAL); 86 return;
87
88 if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
89 if (ch == STOP_CHAR(tty)) {
90 stop_tty(tty);
91 return;
92 }
93 else if (ch == START_CHAR(tty)) {
94 start_tty(tty);
95 return;
96 }
97 }
98
99 tty_insert_flip_char(tty, ch, TTY_NORMAL);
88} 100}
89 101
90static int open_one_chan(struct chan *chan) 102static int open_one_chan(struct chan *chan)
@@ -128,20 +140,18 @@ static int open_chan(struct list_head *chans)
128 return err; 140 return err;
129} 141}
130 142
131void chan_enable_winch(struct chan *chan, struct tty_struct *tty) 143void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
132{ 144{
133 if (chan && chan->primary && chan->ops->winch) 145 struct list_head *ele;
134 register_winch(chan->fd, tty); 146 struct chan *chan;
135}
136
137static void line_timer_cb(struct work_struct *work)
138{
139 struct line *line = container_of(work, struct line, task.work);
140 struct tty_struct *tty = tty_port_tty_get(&line->port);
141 147
142 if (!line->throttled) 148 list_for_each(ele, chans) {
143 chan_interrupt(line, tty, line->driver->read_irq); 149 chan = list_entry(ele, struct chan, list);
144 tty_kref_put(tty); 150 if (chan->primary && chan->output && chan->ops->winch) {
151 register_winch(chan->fd, tty);
152 return;
153 }
154 }
145} 155}
146 156
147int enable_chan(struct line *line) 157int enable_chan(struct line *line)
@@ -150,8 +160,6 @@ int enable_chan(struct line *line)
150 struct chan *chan; 160 struct chan *chan;
151 int err; 161 int err;
152 162
153 INIT_DELAYED_WORK(&line->task, line_timer_cb);
154
155 list_for_each(ele, &line->chan_list) { 163 list_for_each(ele, &line->chan_list) {
156 chan = list_entry(ele, struct chan, list); 164 chan = list_entry(ele, struct chan, list);
157 err = open_one_chan(chan); 165 err = open_one_chan(chan);
@@ -175,7 +183,7 @@ int enable_chan(struct line *line)
175 return 0; 183 return 0;
176 184
177 out_close: 185 out_close:
178 close_chan(line); 186 close_chan(&line->chan_list, 0);
179 return err; 187 return err;
180} 188}
181 189
@@ -203,9 +211,9 @@ void free_irqs(void)
203 chan = list_entry(ele, struct chan, free_list); 211 chan = list_entry(ele, struct chan, free_list);
204 212
205 if (chan->input && chan->enabled) 213 if (chan->input && chan->enabled)
206 um_free_irq(chan->line->driver->read_irq, chan); 214 free_irq(chan->line->driver->read_irq, chan);
207 if (chan->output && chan->enabled) 215 if (chan->output && chan->enabled)
208 um_free_irq(chan->line->driver->write_irq, chan); 216 free_irq(chan->line->driver->write_irq, chan);
209 chan->enabled = 0; 217 chan->enabled = 0;
210 } 218 }
211} 219}
@@ -224,9 +232,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
224 } 232 }
225 else { 233 else {
226 if (chan->input && chan->enabled) 234 if (chan->input && chan->enabled)
227 um_free_irq(chan->line->driver->read_irq, chan); 235 free_irq(chan->line->driver->read_irq, chan);
228 if (chan->output && chan->enabled) 236 if (chan->output && chan->enabled)
229 um_free_irq(chan->line->driver->write_irq, chan); 237 free_irq(chan->line->driver->write_irq, chan);
230 chan->enabled = 0; 238 chan->enabled = 0;
231 } 239 }
232 if (chan->ops->close != NULL) 240 if (chan->ops->close != NULL)
@@ -236,7 +244,7 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
236 chan->fd = -1; 244 chan->fd = -1;
237} 245}
238 246
239void close_chan(struct line *line) 247void close_chan(struct list_head *chans, int delay_free_irq)
240{ 248{
241 struct chan *chan; 249 struct chan *chan;
242 250
@@ -245,50 +253,77 @@ void close_chan(struct line *line)
245 * state. Then, the first one opened will have the original state, 253 * state. Then, the first one opened will have the original state,
246 * so it must be the last closed. 254 * so it must be the last closed.
247 */ 255 */
248 list_for_each_entry_reverse(chan, &line->chan_list, list) { 256 list_for_each_entry_reverse(chan, chans, list) {
249 close_one_chan(chan, 0); 257 close_one_chan(chan, delay_free_irq);
250 } 258 }
251} 259}
252 260
253void deactivate_chan(struct chan *chan, int irq) 261void deactivate_chan(struct list_head *chans, int irq)
254{ 262{
255 if (chan && chan->enabled) 263 struct list_head *ele;
256 deactivate_fd(chan->fd, irq); 264
265 struct chan *chan;
266 list_for_each(ele, chans) {
267 chan = list_entry(ele, struct chan, list);
268
269 if (chan->enabled && chan->input)
270 deactivate_fd(chan->fd, irq);
271 }
257} 272}
258 273
259void reactivate_chan(struct chan *chan, int irq) 274void reactivate_chan(struct list_head *chans, int irq)
260{ 275{
261 if (chan && chan->enabled) 276 struct list_head *ele;
262 reactivate_fd(chan->fd, irq); 277 struct chan *chan;
278
279 list_for_each(ele, chans) {
280 chan = list_entry(ele, struct chan, list);
281
282 if (chan->enabled && chan->input)
283 reactivate_fd(chan->fd, irq);
284 }
263} 285}
264 286
265int write_chan(struct chan *chan, const char *buf, int len, 287int write_chan(struct list_head *chans, const char *buf, int len,
266 int write_irq) 288 int write_irq)
267{ 289{
290 struct list_head *ele;
291 struct chan *chan = NULL;
268 int n, ret = 0; 292 int n, ret = 0;
269 293
270 if (len == 0 || !chan || !chan->ops->write) 294 if (len == 0)
271 return 0; 295 return 0;
272 296
273 n = chan->ops->write(chan->fd, buf, len, chan->data); 297 list_for_each(ele, chans) {
274 if (chan->primary) { 298 chan = list_entry(ele, struct chan, list);
275 ret = n; 299 if (!chan->output || (chan->ops->write == NULL))
276 if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len))) 300 continue;
277 reactivate_fd(chan->fd, write_irq); 301
302 n = chan->ops->write(chan->fd, buf, len, chan->data);
303 if (chan->primary) {
304 ret = n;
305 if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
306 reactivate_fd(chan->fd, write_irq);
307 }
278 } 308 }
279 return ret; 309 return ret;
280} 310}
281 311
282int console_write_chan(struct chan *chan, const char *buf, int len) 312int console_write_chan(struct list_head *chans, const char *buf, int len)
283{ 313{
314 struct list_head *ele;
315 struct chan *chan;
284 int n, ret = 0; 316 int n, ret = 0;
285 317
286 if (!chan || !chan->ops->console_write) 318 list_for_each(ele, chans) {
287 return 0; 319 chan = list_entry(ele, struct chan, list);
320 if (!chan->output || (chan->ops->console_write == NULL))
321 continue;
288 322
289 n = chan->ops->console_write(chan->fd, buf, len); 323 n = chan->ops->console_write(chan->fd, buf, len);
290 if (chan->primary) 324 if (chan->primary)
291 ret = n; 325 ret = n;
326 }
292 return ret; 327 return ret;
293} 328}
294 329
@@ -305,33 +340,29 @@ int console_open_chan(struct line *line, struct console *co)
305 return 0; 340 return 0;
306} 341}
307 342
308int chan_window_size(struct line *line, unsigned short *rows_out, 343int chan_window_size(struct list_head *chans, unsigned short *rows_out,
309 unsigned short *cols_out) 344 unsigned short *cols_out)
310{ 345{
346 struct list_head *ele;
311 struct chan *chan; 347 struct chan *chan;
312 348
313 chan = line->chan_in; 349 list_for_each(ele, chans) {
314 if (chan && chan->primary) { 350 chan = list_entry(ele, struct chan, list);
315 if (chan->ops->window_size == NULL) 351 if (chan->primary) {
316 return 0; 352 if (chan->ops->window_size == NULL)
317 return chan->ops->window_size(chan->fd, chan->data, 353 return 0;
318 rows_out, cols_out); 354 return chan->ops->window_size(chan->fd, chan->data,
319 } 355 rows_out, cols_out);
320 chan = line->chan_out; 356 }
321 if (chan && chan->primary) {
322 if (chan->ops->window_size == NULL)
323 return 0;
324 return chan->ops->window_size(chan->fd, chan->data,
325 rows_out, cols_out);
326 } 357 }
327 return 0; 358 return 0;
328} 359}
329 360
330static void free_one_chan(struct chan *chan) 361static void free_one_chan(struct chan *chan, int delay_free_irq)
331{ 362{
332 list_del(&chan->list); 363 list_del(&chan->list);
333 364
334 close_one_chan(chan, 0); 365 close_one_chan(chan, delay_free_irq);
335 366
336 if (chan->ops->free != NULL) 367 if (chan->ops->free != NULL)
337 (*chan->ops->free)(chan->data); 368 (*chan->ops->free)(chan->data);
@@ -341,14 +372,14 @@ static void free_one_chan(struct chan *chan)
341 kfree(chan); 372 kfree(chan);
342} 373}
343 374
344static void free_chan(struct list_head *chans) 375static void free_chan(struct list_head *chans, int delay_free_irq)
345{ 376{
346 struct list_head *ele, *next; 377 struct list_head *ele, *next;
347 struct chan *chan; 378 struct chan *chan;
348 379
349 list_for_each_safe(ele, next, chans) { 380 list_for_each_safe(ele, next, chans) {
350 chan = list_entry(ele, struct chan, list); 381 chan = list_entry(ele, struct chan, list);
351 free_one_chan(chan); 382 free_one_chan(chan, delay_free_irq);
352 } 383 }
353} 384}
354 385
@@ -398,15 +429,21 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
398 return n; 429 return n;
399} 430}
400 431
401int chan_config_string(struct line *line, char *str, int size, 432int chan_config_string(struct list_head *chans, char *str, int size,
402 char **error_out) 433 char **error_out)
403{ 434{
404 struct chan *in = line->chan_in, *out = line->chan_out; 435 struct list_head *ele;
436 struct chan *chan, *in = NULL, *out = NULL;
405 437
406 if (in && !in->primary) 438 list_for_each(ele, chans) {
407 in = NULL; 439 chan = list_entry(ele, struct chan, list);
408 if (out && !out->primary) 440 if (!chan->primary)
409 out = NULL; 441 continue;
442 if (chan->input)
443 in = chan;
444 if (chan->output)
445 out = chan;
446 }
410 447
411 return chan_pair_config_string(in, out, str, size, error_out); 448 return chan_pair_config_string(in, out, str, size, error_out);
412} 449}
@@ -510,14 +547,10 @@ int parse_chan_pair(char *str, struct line *line, int device,
510 char *in, *out; 547 char *in, *out;
511 548
512 if (!list_empty(chans)) { 549 if (!list_empty(chans)) {
513 line->chan_in = line->chan_out = NULL; 550 free_chan(chans, 0);
514 free_chan(chans);
515 INIT_LIST_HEAD(chans); 551 INIT_LIST_HEAD(chans);
516 } 552 }
517 553
518 if (!str)
519 return 0;
520
521 out = strchr(str, ','); 554 out = strchr(str, ',');
522 if (out != NULL) { 555 if (out != NULL) {
523 in = str; 556 in = str;
@@ -529,7 +562,6 @@ int parse_chan_pair(char *str, struct line *line, int device,
529 562
530 new->input = 1; 563 new->input = 1;
531 list_add(&new->list, chans); 564 list_add(&new->list, chans);
532 line->chan_in = new;
533 565
534 new = parse_chan(line, out, device, opts, error_out); 566 new = parse_chan(line, out, device, opts, error_out);
535 if (new == NULL) 567 if (new == NULL)
@@ -537,7 +569,6 @@ int parse_chan_pair(char *str, struct line *line, int device,
537 569
538 list_add(&new->list, chans); 570 list_add(&new->list, chans);
539 new->output = 1; 571 new->output = 1;
540 line->chan_out = new;
541 } 572 }
542 else { 573 else {
543 new = parse_chan(line, str, device, opts, error_out); 574 new = parse_chan(line, str, device, opts, error_out);
@@ -547,42 +578,43 @@ int parse_chan_pair(char *str, struct line *line, int device,
547 list_add(&new->list, chans); 578 list_add(&new->list, chans);
548 new->input = 1; 579 new->input = 1;
549 new->output = 1; 580 new->output = 1;
550 line->chan_in = line->chan_out = new;
551 } 581 }
552 return 0; 582 return 0;
553} 583}
554 584
555void chan_interrupt(struct line *line, struct tty_struct *tty, int irq) 585void chan_interrupt(struct list_head *chans, struct delayed_work *task,
586 struct tty_struct *tty, int irq)
556{ 587{
557 struct chan *chan = line->chan_in; 588 struct list_head *ele, *next;
589 struct chan *chan;
558 int err; 590 int err;
559 char c; 591 char c;
560 592
561 if (!chan || !chan->ops->read) 593 list_for_each_safe(ele, next, chans) {
562 goto out; 594 chan = list_entry(ele, struct chan, list);
563 595 if (!chan->input || (chan->ops->read == NULL))
564 do { 596 continue;
565 if (tty && !tty_buffer_request_room(tty, 1)) { 597 do {
566 schedule_delayed_work(&line->task, 1); 598 if (tty && !tty_buffer_request_room(tty, 1)) {
567 goto out; 599 schedule_delayed_work(task, 1);
568 } 600 goto out;
569 err = chan->ops->read(chan->fd, &c, chan->data); 601 }
570 if (err > 0) 602 err = chan->ops->read(chan->fd, &c, chan->data);
571 tty_receive_char(tty, c); 603 if (err > 0)
572 } while (err > 0); 604 tty_receive_char(tty, c);
573 605 } while (err > 0);
574 if (err == 0) 606
575 reactivate_fd(chan->fd, irq); 607 if (err == 0)
576 if (err == -EIO) { 608 reactivate_fd(chan->fd, irq);
577 if (chan->primary) { 609 if (err == -EIO) {
578 if (tty != NULL) 610 if (chan->primary) {
579 tty_hangup(tty); 611 if (tty != NULL)
580 if (line->chan_out != chan) 612 tty_hangup(tty);
581 close_one_chan(line->chan_out, 1); 613 close_chan(chans, 1);
614 return;
615 }
616 else close_one_chan(chan, 1);
582 } 617 }
583 close_one_chan(chan, 1);
584 if (chan->primary)
585 return;
586 } 618 }
587 out: 619 out:
588 if (tty) 620 if (tty)
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 9be670ad23b..cfeb3f4a44a 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -11,8 +11,10 @@
11#include <termios.h> 11#include <termios.h>
12#include <sys/ioctl.h> 12#include <sys/ioctl.h>
13#include "chan_user.h" 13#include "chan_user.h"
14#include <os.h> 14#include "kern_constants.h"
15#include <um_malloc.h> 15#include "os.h"
16#include "um_malloc.h"
17#include "user.h"
16 18
17void generic_close(int fd, void *unused) 19void generic_close(int fd, void *unused)
18{ 20{
@@ -281,12 +283,7 @@ void register_winch(int fd, struct tty_struct *tty)
281 return; 283 return;
282 284
283 pid = tcgetpgrp(fd); 285 pid = tcgetpgrp(fd);
284 if (is_skas_winch(pid, fd, tty)) { 286 if (!is_skas_winch(pid, fd, tty) && (pid == -1)) {
285 register_winch_irq(-1, fd, -1, tty, 0);
286 return;
287 }
288
289 if (pid == -1) {
290 thread = winch_tramp(fd, tty, &thread_fd, &stack); 287 thread = winch_tramp(fd, tty, &thread_fd, &stack);
291 if (thread < 0) 288 if (thread < 0)
292 return; 289 return;
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h
deleted file mode 100644
index dc693298eb8..00000000000
--- a/arch/um/drivers/chan_user.h
+++ /dev/null
@@ -1,53 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __CHAN_USER_H__
7#define __CHAN_USER_H__
8
9#include <init.h>
10
11struct chan_opts {
12 void (*const announce)(char *dev_name, int dev);
13 char *xterm_title;
14 const int raw;
15};
16
17struct chan_ops {
18 char *type;
19 void *(*init)(char *, int, const struct chan_opts *);
20 int (*open)(int, int, int, void *, char **);
21 void (*close)(int, void *);
22 int (*read)(int, char *, void *);
23 int (*write)(int, const char *, int, void *);
24 int (*console_write)(int, const char *, int);
25 int (*window_size)(int, void *, unsigned short *, unsigned short *);
26 void (*free)(void *);
27 int winch;
28};
29
30extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops,
31 tty_ops, xterm_ops;
32
33extern void generic_close(int fd, void *unused);
34extern int generic_read(int fd, char *c_out, void *unused);
35extern int generic_write(int fd, const char *buf, int n, void *unused);
36extern int generic_console_write(int fd, const char *buf, int n);
37extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
38 unsigned short *cols_out);
39extern void generic_free(void *data);
40
41struct tty_struct;
42extern void register_winch(int fd, struct tty_struct *tty);
43extern void register_winch_irq(int fd, int tty_fd, int pid,
44 struct tty_struct *tty, unsigned long stack);
45
46#define __channel_help(fn, prefix) \
47__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
48" Attach a console or serial line to a host channel. See\n" \
49" http://user-mode-linux.sourceforge.net/old/input.html for a complete\n" \
50" description of this switch.\n\n" \
51);
52
53#endif
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 6673508f342..dc36b222100 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -3,6 +3,41 @@
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5 5
6#if defined(__KERNEL__)
7
8# include <asm/byteorder.h>
9
10# if defined(__BIG_ENDIAN)
11# define ntohll(x) (x)
12# define htonll(x) (x)
13# elif defined(__LITTLE_ENDIAN)
14# define ntohll(x) be64_to_cpu(x)
15# define htonll(x) cpu_to_be64(x)
16# else
17# error "Could not determine byte order"
18# endif
19
20#else
21/* For the definition of ntohl, htonl and __BYTE_ORDER */
22#include <endian.h>
23#include <netinet/in.h>
24#if defined(__BYTE_ORDER)
25
26# if __BYTE_ORDER == __BIG_ENDIAN
27# define ntohll(x) (x)
28# define htonll(x) (x)
29# elif __BYTE_ORDER == __LITTLE_ENDIAN
30# define ntohll(x) bswap_64(x)
31# define htonll(x) bswap_64(x)
32# else
33# error "Could not determine byte order: __BYTE_ORDER uncorrectly defined"
34# endif
35
36#else /* ! defined(__BYTE_ORDER) */
37# error "Could not determine byte order: __BYTE_ORDER not defined"
38#endif
39#endif /* ! defined(__KERNEL__) */
40
6extern int init_cow_file(int fd, char *cow_file, char *backing_file, 41extern int init_cow_file(int fd, char *cow_file, char *backing_file,
7 int sectorsize, int alignment, int *bitmap_offset_out, 42 int sectorsize, int alignment, int *bitmap_offset_out,
8 unsigned long *bitmap_len_out, int *data_offset_out); 43 unsigned long *bitmap_len_out, int *data_offset_out);
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index 67cbee63e70..f5701fd2ef9 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -1,9 +1,10 @@
1#ifndef __COW_SYS_H__ 1#ifndef __COW_SYS_H__
2#define __COW_SYS_H__ 2#define __COW_SYS_H__
3 3
4#include <kern_util.h> 4#include "kern_util.h"
5#include <os.h> 5#include "os.h"
6#include <um_malloc.h> 6#include "user.h"
7#include "um_malloc.h"
7 8
8static inline void *cow_malloc(int size) 9static inline void *cow_malloc(int size)
9{ 10{
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 0ee9cc6cc4c..9cbb426c0b9 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -8,10 +8,11 @@
8 * that. 8 * that.
9 */ 9 */
10#include <unistd.h> 10#include <unistd.h>
11#include <byteswap.h>
11#include <errno.h> 12#include <errno.h>
12#include <string.h> 13#include <string.h>
13#include <arpa/inet.h> 14#include <arpa/inet.h>
14#include <endian.h> 15#include <asm/types.h>
15#include "cow.h" 16#include "cow.h"
16#include "cow_sys.h" 17#include "cow_sys.h"
17 18
@@ -213,8 +214,8 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
213 "header\n"); 214 "header\n");
214 goto out; 215 goto out;
215 } 216 }
216 header->magic = htobe32(COW_MAGIC); 217 header->magic = htonl(COW_MAGIC);
217 header->version = htobe32(COW_VERSION); 218 header->version = htonl(COW_VERSION);
218 219
219 err = -EINVAL; 220 err = -EINVAL;
220 if (strlen(backing_file) > sizeof(header->backing_file) - 1) { 221 if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
@@ -245,10 +246,10 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
245 goto out_free; 246 goto out_free;
246 } 247 }
247 248
248 header->mtime = htobe32(modtime); 249 header->mtime = htonl(modtime);
249 header->size = htobe64(*size); 250 header->size = htonll(*size);
250 header->sectorsize = htobe32(sectorsize); 251 header->sectorsize = htonl(sectorsize);
251 header->alignment = htobe32(alignment); 252 header->alignment = htonl(alignment);
252 header->cow_format = COW_BITMAP; 253 header->cow_format = COW_BITMAP;
253 254
254 err = cow_write_file(fd, header, sizeof(*header)); 255 err = cow_write_file(fd, header, sizeof(*header));
@@ -300,8 +301,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
300 magic = header->v1.magic; 301 magic = header->v1.magic;
301 if (magic == COW_MAGIC) 302 if (magic == COW_MAGIC)
302 version = header->v1.version; 303 version = header->v1.version;
303 else if (magic == be32toh(COW_MAGIC)) 304 else if (magic == ntohl(COW_MAGIC))
304 version = be32toh(header->v1.version); 305 version = ntohl(header->v1.version);
305 /* No error printed because the non-COW case comes through here */ 306 /* No error printed because the non-COW case comes through here */
306 else goto out; 307 else goto out;
307 308
@@ -326,9 +327,9 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
326 "header\n"); 327 "header\n");
327 goto out; 328 goto out;
328 } 329 }
329 *mtime_out = be32toh(header->v2.mtime); 330 *mtime_out = ntohl(header->v2.mtime);
330 *size_out = be64toh(header->v2.size); 331 *size_out = ntohll(header->v2.size);
331 *sectorsize_out = be32toh(header->v2.sectorsize); 332 *sectorsize_out = ntohl(header->v2.sectorsize);
332 *bitmap_offset_out = sizeof(header->v2); 333 *bitmap_offset_out = sizeof(header->v2);
333 *align_out = *sectorsize_out; 334 *align_out = *sectorsize_out;
334 file = header->v2.backing_file; 335 file = header->v2.backing_file;
@@ -340,10 +341,10 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
340 "header\n"); 341 "header\n");
341 goto out; 342 goto out;
342 } 343 }
343 *mtime_out = be32toh(header->v3.mtime); 344 *mtime_out = ntohl(header->v3.mtime);
344 *size_out = be64toh(header->v3.size); 345 *size_out = ntohll(header->v3.size);
345 *sectorsize_out = be32toh(header->v3.sectorsize); 346 *sectorsize_out = ntohl(header->v3.sectorsize);
346 *align_out = be32toh(header->v3.alignment); 347 *align_out = ntohl(header->v3.alignment);
347 if (*align_out == 0) { 348 if (*align_out == 0) {
348 cow_printf("read_cow_header - invalid COW header, " 349 cow_printf("read_cow_header - invalid COW header, "
349 "align == 0\n"); 350 "align == 0\n");
@@ -365,16 +366,16 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
365 * this was used until Dec2005 - 64bits are needed to represent 366 * this was used until Dec2005 - 64bits are needed to represent
366 * 2038+. I.e. we can safely do this truncating cast. 367 * 2038+. I.e. we can safely do this truncating cast.
367 * 368 *
368 * Additionally, we must use be32toh() instead of be64toh(), since 369 * Additionally, we must use ntohl() instead of ntohll(), since
369 * the program used to use the former (tested - I got mtime 370 * the program used to use the former (tested - I got mtime
370 * mismatch "0 vs whatever"). 371 * mismatch "0 vs whatever").
371 * 372 *
372 * Ever heard about bug-to-bug-compatibility ? ;-) */ 373 * Ever heard about bug-to-bug-compatibility ? ;-) */
373 *mtime_out = (time32_t) be32toh(header->v3_b.mtime); 374 *mtime_out = (time32_t) ntohl(header->v3_b.mtime);
374 375
375 *size_out = be64toh(header->v3_b.size); 376 *size_out = ntohll(header->v3_b.size);
376 *sectorsize_out = be32toh(header->v3_b.sectorsize); 377 *sectorsize_out = ntohl(header->v3_b.sectorsize);
377 *align_out = be32toh(header->v3_b.alignment); 378 *align_out = ntohl(header->v3_b.alignment);
378 if (*align_out == 0) { 379 if (*align_out == 0) {
379 cow_printf("read_cow_header - invalid COW header, " 380 cow_printf("read_cow_header - invalid COW header, "
380 "align == 0\n"); 381 "align == 0\n");
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index c2dd1951559..6e0e891f8a0 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -6,7 +6,7 @@
6#ifndef __DAEMON_H__ 6#ifndef __DAEMON_H__
7#define __DAEMON_H__ 7#define __DAEMON_H__
8 8
9#include <net_user.h> 9#include "net_user.h"
10 10
11#define SWITCH_VERSION 3 11#define SWITCH_VERSION 3
12 12
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index 7568cc2f3cd..b4a1522f215 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -6,9 +6,9 @@
6 * Licensed under the GPL. 6 * Licensed under the GPL.
7 */ 7 */
8 8
9#include <linux/init.h> 9#include "linux/init.h"
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <net_kern.h> 11#include "net_kern.h"
12#include "daemon.h" 12#include "daemon.h"
13 13
14struct daemon_init { 14struct daemon_init {
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 8813c10d017..f8e85e0bdac 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,9 +14,10 @@
14#include <sys/time.h> 14#include <sys/time.h>
15#include <sys/un.h> 15#include <sys/un.h>
16#include "daemon.h" 16#include "daemon.h"
17#include <net_user.h> 17#include "net_user.h"
18#include <os.h> 18#include "os.h"
19#include <um_malloc.h> 19#include "um_malloc.h"
20#include "user.h"
20 21
21enum request_type { REQ_NEW_CONTROL }; 22enum request_type { REQ_NEW_CONTROL };
22 23
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index a13a427b996..f5a981a1624 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,8 +9,10 @@
9#include <errno.h> 9#include <errno.h>
10#include <termios.h> 10#include <termios.h>
11#include "chan_user.h" 11#include "chan_user.h"
12#include <os.h> 12#include "kern_constants.h"
13#include <um_malloc.h> 13#include "os.h"
14#include "um_malloc.h"
15#include "user.h"
14 16
15struct fd_chan { 17struct fd_chan {
16 int fd; 18 int fd;
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index f99b32a4dbf..84dce3fc590 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,8 @@
6#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include <os.h> 9#include "os.h"
10#include "user.h"
10 11
11struct dog_data { 12struct dog_data {
12 int stdin; 13 int stdin;
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 9b90fdc4b15..f9f6a4e2059 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -3,15 +3,15 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/fs.h> 6#include "linux/fs.h"
7#include <linux/module.h> 7#include "linux/module.h"
8#include <linux/slab.h> 8#include "linux/slab.h"
9#include <linux/sound.h> 9#include "linux/sound.h"
10#include <linux/soundcard.h> 10#include "linux/soundcard.h"
11#include <linux/mutex.h> 11#include "linux/mutex.h"
12#include <asm/uaccess.h> 12#include "asm/uaccess.h"
13#include <init.h> 13#include "init.h"
14#include <os.h> 14#include "os.h"
15 15
16struct hostaudio_state { 16struct hostaudio_state {
17 int fd; 17 int fd;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 9ffc28bd4b7..364c8a15c4c 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -3,15 +3,15 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/irqreturn.h> 6#include "linux/irqreturn.h"
7#include <linux/kd.h> 7#include "linux/kd.h"
8#include <linux/sched.h> 8#include "linux/sched.h"
9#include <linux/slab.h> 9#include "linux/slab.h"
10#include "chan.h" 10#include "chan_kern.h"
11#include <irq_kern.h> 11#include "irq_kern.h"
12#include <irq_user.h> 12#include "irq_user.h"
13#include <kern_util.h> 13#include "kern_util.h"
14#include <os.h> 14#include "os.h"
15 15
16#define LINE_BUFSIZE 4096 16#define LINE_BUFSIZE 4096
17 17
@@ -19,14 +19,21 @@ static irqreturn_t line_interrupt(int irq, void *data)
19{ 19{
20 struct chan *chan = data; 20 struct chan *chan = data;
21 struct line *line = chan->line; 21 struct line *line = chan->line;
22 struct tty_struct *tty = tty_port_tty_get(&line->port);
23 22
24 if (line) 23 if (line)
25 chan_interrupt(line, tty, irq); 24 chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
26 tty_kref_put(tty);
27 return IRQ_HANDLED; 25 return IRQ_HANDLED;
28} 26}
29 27
28static void line_timer_cb(struct work_struct *work)
29{
30 struct line *line = container_of(work, struct line, task.work);
31
32 if (!line->throttled)
33 chan_interrupt(&line->chan_list, &line->task, line->tty,
34 line->driver->read_irq);
35}
36
30/* 37/*
31 * Returns the free space inside the ring buffer of this line. 38 * Returns the free space inside the ring buffer of this line.
32 * 39 *
@@ -138,7 +145,7 @@ static int flush_buffer(struct line *line)
138 /* line->buffer + LINE_BUFSIZE is the end of the buffer! */ 145 /* line->buffer + LINE_BUFSIZE is the end of the buffer! */
139 count = line->buffer + LINE_BUFSIZE - line->head; 146 count = line->buffer + LINE_BUFSIZE - line->head;
140 147
141 n = write_chan(line->chan_out, line->head, count, 148 n = write_chan(&line->chan_list, line->head, count,
142 line->driver->write_irq); 149 line->driver->write_irq);
143 if (n < 0) 150 if (n < 0)
144 return n; 151 return n;
@@ -155,7 +162,7 @@ static int flush_buffer(struct line *line)
155 } 162 }
156 163
157 count = line->tail - line->head; 164 count = line->tail - line->head;
158 n = write_chan(line->chan_out, line->head, count, 165 n = write_chan(&line->chan_list, line->head, count,
159 line->driver->write_irq); 166 line->driver->write_irq);
160 167
161 if (n < 0) 168 if (n < 0)
@@ -199,7 +206,7 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
199 if (line->head != line->tail) 206 if (line->head != line->tail)
200 ret = buffer_data(line, buf, len); 207 ret = buffer_data(line, buf, len);
201 else { 208 else {
202 n = write_chan(line->chan_out, buf, len, 209 n = write_chan(&line->chan_list, buf, len,
203 line->driver->write_irq); 210 line->driver->write_irq);
204 if (n < 0) { 211 if (n < 0) {
205 ret = n; 212 ret = n;
@@ -221,11 +228,97 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old)
221 /* nothing */ 228 /* nothing */
222} 229}
223 230
231static const struct {
232 int cmd;
233 char *level;
234 char *name;
235} tty_ioctls[] = {
236 /* don't print these, they flood the log ... */
237 { TCGETS, NULL, "TCGETS" },
238 { TCSETS, NULL, "TCSETS" },
239 { TCSETSW, NULL, "TCSETSW" },
240 { TCFLSH, NULL, "TCFLSH" },
241 { TCSBRK, NULL, "TCSBRK" },
242
243 /* general tty stuff */
244 { TCSETSF, KERN_DEBUG, "TCSETSF" },
245 { TCGETA, KERN_DEBUG, "TCGETA" },
246 { TIOCMGET, KERN_DEBUG, "TIOCMGET" },
247 { TCSBRKP, KERN_DEBUG, "TCSBRKP" },
248 { TIOCMSET, KERN_DEBUG, "TIOCMSET" },
249
250 /* linux-specific ones */
251 { TIOCLINUX, KERN_INFO, "TIOCLINUX" },
252 { KDGKBMODE, KERN_INFO, "KDGKBMODE" },
253 { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" },
254 { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" },
255};
256
257int line_ioctl(struct tty_struct *tty, unsigned int cmd,
258 unsigned long arg)
259{
260 int ret;
261 int i;
262
263 ret = 0;
264 switch(cmd) {
265#ifdef TIOCGETP
266 case TIOCGETP:
267 case TIOCSETP:
268 case TIOCSETN:
269#endif
270#ifdef TIOCGETC
271 case TIOCGETC:
272 case TIOCSETC:
273#endif
274#ifdef TIOCGLTC
275 case TIOCGLTC:
276 case TIOCSLTC:
277#endif
278 /* Note: these are out of date as we now have TCGETS2 etc but this
279 whole lot should probably go away */
280 case TCGETS:
281 case TCSETSF:
282 case TCSETSW:
283 case TCSETS:
284 case TCGETA:
285 case TCSETAF:
286 case TCSETAW:
287 case TCSETA:
288 case TCXONC:
289 case TCFLSH:
290 case TIOCOUTQ:
291 case TIOCINQ:
292 case TIOCGLCKTRMIOS:
293 case TIOCSLCKTRMIOS:
294 case TIOCPKT:
295 case TIOCGSOFTCAR:
296 case TIOCSSOFTCAR:
297 return -ENOIOCTLCMD;
298#if 0
299 case TCwhatever:
300 /* do something */
301 break;
302#endif
303 default:
304 for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
305 if (cmd == tty_ioctls[i].cmd)
306 break;
307 if (i == ARRAY_SIZE(tty_ioctls)) {
308 printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
309 __func__, tty->name, cmd);
310 }
311 ret = -ENOIOCTLCMD;
312 break;
313 }
314 return ret;
315}
316
224void line_throttle(struct tty_struct *tty) 317void line_throttle(struct tty_struct *tty)
225{ 318{
226 struct line *line = tty->driver_data; 319 struct line *line = tty->driver_data;
227 320
228 deactivate_chan(line->chan_in, line->driver->read_irq); 321 deactivate_chan(&line->chan_list, line->driver->read_irq);
229 line->throttled = 1; 322 line->throttled = 1;
230} 323}
231 324
@@ -234,7 +327,8 @@ void line_unthrottle(struct tty_struct *tty)
234 struct line *line = tty->driver_data; 327 struct line *line = tty->driver_data;
235 328
236 line->throttled = 0; 329 line->throttled = 0;
237 chan_interrupt(line, tty, line->driver->read_irq); 330 chan_interrupt(&line->chan_list, &line->task, tty,
331 line->driver->read_irq);
238 332
239 /* 333 /*
240 * Maybe there is enough stuff pending that calling the interrupt 334 * Maybe there is enough stuff pending that calling the interrupt
@@ -242,25 +336,24 @@ void line_unthrottle(struct tty_struct *tty)
242 * again and we shouldn't turn the interrupt back on. 336 * again and we shouldn't turn the interrupt back on.
243 */ 337 */
244 if (!line->throttled) 338 if (!line->throttled)
245 reactivate_chan(line->chan_in, line->driver->read_irq); 339 reactivate_chan(&line->chan_list, line->driver->read_irq);
246} 340}
247 341
248static irqreturn_t line_write_interrupt(int irq, void *data) 342static irqreturn_t line_write_interrupt(int irq, void *data)
249{ 343{
250 struct chan *chan = data; 344 struct chan *chan = data;
251 struct line *line = chan->line; 345 struct line *line = chan->line;
252 struct tty_struct *tty; 346 struct tty_struct *tty = line->tty;
253 int err; 347 int err;
254 348
255 /* 349 /*
256 * Interrupts are disabled here because genirq keep irqs disabled when 350 * Interrupts are disabled here because we registered the interrupt with
257 * calling the action handler. 351 * IRQF_DISABLED (see line_setup_irq).
258 */ 352 */
259 353
260 spin_lock(&line->lock); 354 spin_lock(&line->lock);
261 err = flush_buffer(line); 355 err = flush_buffer(line);
262 if (err == 0) { 356 if (err == 0) {
263 spin_unlock(&line->lock);
264 return IRQ_NONE; 357 return IRQ_NONE;
265 } else if (err < 0) { 358 } else if (err < 0) {
266 line->head = line->buffer; 359 line->head = line->buffer;
@@ -268,103 +361,124 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
268 } 361 }
269 spin_unlock(&line->lock); 362 spin_unlock(&line->lock);
270 363
271 tty = tty_port_tty_get(&line->port);
272 if (tty == NULL) 364 if (tty == NULL)
273 return IRQ_NONE; 365 return IRQ_NONE;
274 366
275 tty_wakeup(tty); 367 tty_wakeup(tty);
276 tty_kref_put(tty);
277
278 return IRQ_HANDLED; 368 return IRQ_HANDLED;
279} 369}
280 370
281int line_setup_irq(int fd, int input, int output, struct line *line, void *data) 371int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
282{ 372{
283 const struct line_driver *driver = line->driver; 373 const struct line_driver *driver = line->driver;
284 int err = 0; 374 int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM;
285 375
286 if (input) 376 if (input)
287 err = um_request_irq(driver->read_irq, fd, IRQ_READ, 377 err = um_request_irq(driver->read_irq, fd, IRQ_READ,
288 line_interrupt, IRQF_SHARED, 378 line_interrupt, flags,
289 driver->read_irq_name, data); 379 driver->read_irq_name, data);
290 if (err) 380 if (err)
291 return err; 381 return err;
292 if (output) 382 if (output)
293 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, 383 err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
294 line_write_interrupt, IRQF_SHARED, 384 line_write_interrupt, flags,
295 driver->write_irq_name, data); 385 driver->write_irq_name, data);
386 line->have_irq = 1;
296 return err; 387 return err;
297} 388}
298 389
299static int line_activate(struct tty_port *port, struct tty_struct *tty) 390/*
391 * Normally, a driver like this can rely mostly on the tty layer
392 * locking, particularly when it comes to the driver structure.
393 * However, in this case, mconsole requests can come in "from the
394 * side", and race with opens and closes.
395 *
396 * mconsole config requests will want to be sure the device isn't in
397 * use, and get_config, open, and close will want a stable
398 * configuration. The checking and modification of the configuration
399 * is done under a spinlock. Checking whether the device is in use is
400 * line->tty->count > 1, also under the spinlock.
401 *
402 * line->count serves to decide whether the device should be enabled or
403 * disabled on the host. If it's equal to 0, then we are doing the
404 * first open or last close. Otherwise, open and close just return.
405 */
406
407int line_open(struct line *lines, struct tty_struct *tty)
300{ 408{
301 int ret; 409 struct line *line = &lines[tty->index];
302 struct line *line = tty->driver_data; 410 int err = -ENODEV;
411
412 spin_lock(&line->count_lock);
413 if (!line->valid)
414 goto out_unlock;
415
416 err = 0;
417 if (line->count++)
418 goto out_unlock;
419
420 BUG_ON(tty->driver_data);
421 tty->driver_data = line;
422 line->tty = tty;
423
424 spin_unlock(&line->count_lock);
425 err = enable_chan(line);
426 if (err) /* line_close() will be called by our caller */
427 return err;
303 428
304 ret = enable_chan(line); 429 INIT_DELAYED_WORK(&line->task, line_timer_cb);
305 if (ret)
306 return ret;
307 430
308 if (!line->sigio) { 431 if (!line->sigio) {
309 chan_enable_winch(line->chan_out, tty); 432 chan_enable_winch(&line->chan_list, tty);
310 line->sigio = 1; 433 line->sigio = 1;
311 } 434 }
312 435
313 chan_window_size(line, &tty->winsize.ws_row, 436 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
314 &tty->winsize.ws_col); 437 &tty->winsize.ws_col);
315 438
316 return 0; 439 return 0;
440
441out_unlock:
442 spin_unlock(&line->count_lock);
443 return err;
317} 444}
318 445
319static const struct tty_port_operations line_port_ops = { 446static void unregister_winch(struct tty_struct *tty);
320 .activate = line_activate,
321};
322 447
323int line_open(struct tty_struct *tty, struct file *filp) 448void line_close(struct tty_struct *tty, struct file * filp)
324{ 449{
325 struct line *line = tty->driver_data; 450 struct line *line = tty->driver_data;
326 451
327 return tty_port_open(&line->port, tty, filp); 452 /*
328} 453 * If line_open fails (and tty->driver_data is never set),
454 * tty_open will call line_close. So just return in this case.
455 */
456 if (line == NULL)
457 return;
329 458
330int line_install(struct tty_driver *driver, struct tty_struct *tty, 459 /* We ignore the error anyway! */
331 struct line *line) 460 flush_buffer(line);
332{
333 int ret;
334 461
335 ret = tty_standard_install(driver, tty); 462 spin_lock(&line->count_lock);
336 if (ret) 463 BUG_ON(!line->valid);
337 return ret;
338 464
339 tty->driver_data = line; 465 if (--line->count)
466 goto out_unlock;
340 467
341 return 0; 468 line->tty = NULL;
342} 469 tty->driver_data = NULL;
343 470
344static void unregister_winch(struct tty_struct *tty); 471 spin_unlock(&line->count_lock);
345
346void line_cleanup(struct tty_struct *tty)
347{
348 struct line *line = tty->driver_data;
349 472
350 if (line->sigio) { 473 if (line->sigio) {
351 unregister_winch(tty); 474 unregister_winch(tty);
352 line->sigio = 0; 475 line->sigio = 0;
353 } 476 }
354}
355
356void line_close(struct tty_struct *tty, struct file * filp)
357{
358 struct line *line = tty->driver_data;
359 477
360 tty_port_close(&line->port, tty, filp); 478 return;
361}
362
363void line_hangup(struct tty_struct *tty)
364{
365 struct line *line = tty->driver_data;
366 479
367 tty_port_hangup(&line->port); 480out_unlock:
481 spin_unlock(&line->count_lock);
368} 482}
369 483
370void close_lines(struct line *lines, int nlines) 484void close_lines(struct line *lines, int nlines)
@@ -372,58 +486,34 @@ void close_lines(struct line *lines, int nlines)
372 int i; 486 int i;
373 487
374 for(i = 0; i < nlines; i++) 488 for(i = 0; i < nlines; i++)
375 close_chan(&lines[i]); 489 close_chan(&lines[i].chan_list, 0);
376} 490}
377 491
378int setup_one_line(struct line *lines, int n, char *init, 492static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
379 const struct chan_opts *opts, char **error_out) 493 char **error_out)
380{ 494{
381 struct line *line = &lines[n]; 495 struct line *line = &lines[n];
382 struct tty_driver *driver = line->driver->driver;
383 int err = -EINVAL; 496 int err = -EINVAL;
384 497
385 if (line->port.count) { 498 spin_lock(&line->count_lock);
499
500 if (line->count) {
386 *error_out = "Device is already open"; 501 *error_out = "Device is already open";
387 goto out; 502 goto out;
388 } 503 }
389 504
390 if (!strcmp(init, "none")) { 505 if (line->init_pri <= init_prio) {
391 if (line->valid) { 506 line->init_pri = init_prio;
507 if (!strcmp(init, "none"))
392 line->valid = 0; 508 line->valid = 0;
393 kfree(line->init_str); 509 else {
394 tty_unregister_device(driver, n); 510 line->init_str = init;
395 parse_chan_pair(NULL, line, n, opts, error_out); 511 line->valid = 1;
396 err = 0;
397 }
398 } else {
399 char *new = kstrdup(init, GFP_KERNEL);
400 if (!new) {
401 *error_out = "Failed to allocate memory";
402 return -ENOMEM;
403 }
404 if (line->valid) {
405 tty_unregister_device(driver, n);
406 kfree(line->init_str);
407 }
408 line->init_str = new;
409 line->valid = 1;
410 err = parse_chan_pair(new, line, n, opts, error_out);
411 if (!err) {
412 struct device *d = tty_port_register_device(&line->port,
413 driver, n, NULL);
414 if (IS_ERR(d)) {
415 *error_out = "Failed to register device";
416 err = PTR_ERR(d);
417 parse_chan_pair(NULL, line, n, opts, error_out);
418 }
419 }
420 if (err) {
421 line->init_str = NULL;
422 line->valid = 0;
423 kfree(new);
424 } 512 }
425 } 513 }
514 err = 0;
426out: 515out:
516 spin_unlock(&line->count_lock);
427 return err; 517 return err;
428} 518}
429 519
@@ -434,43 +524,54 @@ out:
434 * @error_out is an error string in the case of failure; 524 * @error_out is an error string in the case of failure;
435 */ 525 */
436 526
437int line_setup(char **conf, unsigned int num, char **def, 527int line_setup(struct line *lines, unsigned int num, char *init,
438 char *init, char *name) 528 char **error_out)
439{ 529{
440 char *error; 530 int i, n, err;
531 char *end;
441 532
442 if (*init == '=') { 533 if (*init == '=') {
443 /* 534 /*
444 * We said con=/ssl= instead of con#=, so we are configuring all 535 * We said con=/ssl= instead of con#=, so we are configuring all
445 * consoles at once. 536 * consoles at once.
446 */ 537 */
447 *def = init + 1; 538 n = -1;
448 } else { 539 }
449 char *end; 540 else {
450 unsigned n = simple_strtoul(init, &end, 0); 541 n = simple_strtoul(init, &end, 0);
451
452 if (*end != '=') { 542 if (*end != '=') {
453 error = "Couldn't parse device number"; 543 *error_out = "Couldn't parse device number";
454 goto out; 544 return -EINVAL;
455 }
456 if (n >= num) {
457 error = "Device number out of range";
458 goto out;
459 } 545 }
460 conf[n] = end + 1; 546 init = end;
461 } 547 }
462 return 0; 548 init++;
463 549
464out: 550 if (n >= (signed int) num) {
465 printk(KERN_ERR "Failed to set up %s with " 551 *error_out = "Device number out of range";
466 "configuration string \"%s\" : %s\n", name, init, error); 552 return -EINVAL;
467 return -EINVAL; 553 }
554 else if (n >= 0) {
555 err = setup_one_line(lines, n, init, INIT_ONE, error_out);
556 if (err)
557 return err;
558 }
559 else {
560 for(i = 0; i < num; i++) {
561 err = setup_one_line(lines, i, init, INIT_ALL,
562 error_out);
563 if (err)
564 return err;
565 }
566 }
567 return n == -1 ? num : n;
468} 568}
469 569
470int line_config(struct line *lines, unsigned int num, char *str, 570int line_config(struct line *lines, unsigned int num, char *str,
471 const struct chan_opts *opts, char **error_out) 571 const struct chan_opts *opts, char **error_out)
472{ 572{
473 char *end; 573 struct line *line;
574 char *new;
474 int n; 575 int n;
475 576
476 if (*str == '=') { 577 if (*str == '=') {
@@ -478,17 +579,17 @@ int line_config(struct line *lines, unsigned int num, char *str,
478 return -EINVAL; 579 return -EINVAL;
479 } 580 }
480 581
481 n = simple_strtoul(str, &end, 0); 582 new = kstrdup(str, GFP_KERNEL);
482 if (*end++ != '=') { 583 if (new == NULL) {
483 *error_out = "Couldn't parse device number"; 584 *error_out = "Failed to allocate memory";
484 return -EINVAL; 585 return -ENOMEM;
485 }
486 if (n >= num) {
487 *error_out = "Device number out of range";
488 return -EINVAL;
489 } 586 }
587 n = line_setup(lines, num, new, error_out);
588 if (n < 0)
589 return n;
490 590
491 return setup_one_line(lines, n, end, opts, error_out); 591 line = &lines[n];
592 return parse_chan_pair(line->init_str, line, n, opts, error_out);
492} 593}
493 594
494int line_get_config(char *name, struct line *lines, unsigned int num, char *str, 595int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
@@ -511,17 +612,13 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
511 612
512 line = &lines[dev]; 613 line = &lines[dev];
513 614
615 spin_lock(&line->count_lock);
514 if (!line->valid) 616 if (!line->valid)
515 CONFIG_CHUNK(str, size, n, "none", 1); 617 CONFIG_CHUNK(str, size, n, "none", 1);
516 else { 618 else if (line->tty == NULL)
517 struct tty_struct *tty = tty_port_tty_get(&line->port); 619 CONFIG_CHUNK(str, size, n, line->init_str, 1);
518 if (tty == NULL) { 620 else n = chan_config_string(&line->chan_list, str, size, error_out);
519 CONFIG_CHUNK(str, size, n, line->init_str, 1); 621 spin_unlock(&line->count_lock);
520 } else {
521 n = chan_config_string(line, str, size, error_out);
522 tty_kref_put(tty);
523 }
524 }
525 622
526 return n; 623 return n;
527} 624}
@@ -543,23 +640,25 @@ int line_id(char **str, int *start_out, int *end_out)
543 640
544int line_remove(struct line *lines, unsigned int num, int n, char **error_out) 641int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
545{ 642{
546 if (n >= num) { 643 int err;
547 *error_out = "Device number out of range"; 644 char config[sizeof("conxxxx=none\0")];
548 return -EINVAL; 645
549 } 646 sprintf(config, "%d=none", n);
550 return setup_one_line(lines, n, "none", NULL, error_out); 647 err = line_setup(lines, num, config, error_out);
648 if (err >= 0)
649 err = 0;
650 return err;
551} 651}
552 652
553int register_lines(struct line_driver *line_driver, 653struct tty_driver *register_lines(struct line_driver *line_driver,
554 const struct tty_operations *ops, 654 const struct tty_operations *ops,
555 struct line *lines, int nlines) 655 struct line *lines, int nlines)
556{ 656{
557 struct tty_driver *driver = alloc_tty_driver(nlines);
558 int err;
559 int i; 657 int i;
658 struct tty_driver *driver = alloc_tty_driver(nlines);
560 659
561 if (!driver) 660 if (!driver)
562 return -ENOMEM; 661 return NULL;
563 662
564 driver->driver_name = line_driver->name; 663 driver->driver_name = line_driver->name;
565 driver->name = line_driver->device_name; 664 driver->name = line_driver->device_name;
@@ -567,36 +666,54 @@ int register_lines(struct line_driver *line_driver,
567 driver->minor_start = line_driver->minor_start; 666 driver->minor_start = line_driver->minor_start;
568 driver->type = line_driver->type; 667 driver->type = line_driver->type;
569 driver->subtype = line_driver->subtype; 668 driver->subtype = line_driver->subtype;
570 driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; 669 driver->flags = TTY_DRIVER_REAL_RAW;
571 driver->init_termios = tty_std_termios; 670 driver->init_termios = tty_std_termios;
572
573 for (i = 0; i < nlines; i++) {
574 tty_port_init(&lines[i].port);
575 lines[i].port.ops = &line_port_ops;
576 spin_lock_init(&lines[i].lock);
577 lines[i].driver = line_driver;
578 INIT_LIST_HEAD(&lines[i].chan_list);
579 }
580 tty_set_operations(driver, ops); 671 tty_set_operations(driver, ops);
581 672
582 err = tty_register_driver(driver); 673 if (tty_register_driver(driver)) {
583 if (err) {
584 printk(KERN_ERR "register_lines : can't register %s driver\n", 674 printk(KERN_ERR "register_lines : can't register %s driver\n",
585 line_driver->name); 675 line_driver->name);
586 put_tty_driver(driver); 676 put_tty_driver(driver);
587 for (i = 0; i < nlines; i++) 677 return NULL;
588 tty_port_destroy(&lines[i].port); 678 }
589 return err; 679
680 for(i = 0; i < nlines; i++) {
681 if (!lines[i].valid)
682 tty_unregister_device(driver, i);
590 } 683 }
591 684
592 line_driver->driver = driver;
593 mconsole_register_dev(&line_driver->mc); 685 mconsole_register_dev(&line_driver->mc);
594 return 0; 686 return driver;
595} 687}
596 688
597static DEFINE_SPINLOCK(winch_handler_lock); 689static DEFINE_SPINLOCK(winch_handler_lock);
598static LIST_HEAD(winch_handlers); 690static LIST_HEAD(winch_handlers);
599 691
692void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
693{
694 struct line *line;
695 char *error;
696 int i;
697
698 for(i = 0; i < nlines; i++) {
699 line = &lines[i];
700 INIT_LIST_HEAD(&line->chan_list);
701
702 if (line->init_str == NULL)
703 continue;
704
705 line->init_str = kstrdup(line->init_str, GFP_KERNEL);
706 if (line->init_str == NULL)
707 printk(KERN_ERR "lines_init - kstrdup returned NULL\n");
708
709 if (parse_chan_pair(line->init_str, line, i, opts, &error)) {
710 printk(KERN_ERR "parse_chan_pair failed for "
711 "device %d : %s\n", i, error);
712 line->valid = 0;
713 }
714 }
715}
716
600struct winch { 717struct winch {
601 struct list_head list; 718 struct list_head list;
602 int fd; 719 int fd;
@@ -610,7 +727,7 @@ struct winch {
610static void __free_winch(struct work_struct *work) 727static void __free_winch(struct work_struct *work)
611{ 728{
612 struct winch *winch = container_of(work, struct winch, work); 729 struct winch *winch = container_of(work, struct winch, work);
613 um_free_irq(WINCH_IRQ, winch); 730 free_irq(WINCH_IRQ, winch);
614 731
615 if (winch->pid != -1) 732 if (winch->pid != -1)
616 os_kill_process(winch->pid, 1); 733 os_kill_process(winch->pid, 1);
@@ -660,7 +777,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
660 if (tty != NULL) { 777 if (tty != NULL) {
661 line = tty->driver_data; 778 line = tty->driver_data;
662 if (line != NULL) { 779 if (line != NULL) {
663 chan_window_size(line, &tty->winsize.ws_row, 780 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
664 &tty->winsize.ws_col); 781 &tty->winsize.ws_col);
665 kill_pgrp(tty->pgrp, SIGWINCH, 1); 782 kill_pgrp(tty->pgrp, SIGWINCH, 1);
666 } 783 }
@@ -690,7 +807,8 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
690 .stack = stack }); 807 .stack = stack });
691 808
692 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 809 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
693 IRQF_SHARED, "winch", winch) < 0) { 810 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
811 "winch", winch) < 0) {
694 printk(KERN_ERR "register_winch_irq - failed to register " 812 printk(KERN_ERR "register_winch_irq - failed to register "
695 "IRQ\n"); 813 "IRQ\n");
696 goto out_free; 814 goto out_free;
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
deleted file mode 100644
index 138a14526d9..00000000000
--- a/arch/um/drivers/line.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __LINE_H__
7#define __LINE_H__
8
9#include <linux/list.h>
10#include <linux/workqueue.h>
11#include <linux/tty.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/mutex.h>
15#include "chan_user.h"
16#include "mconsole_kern.h"
17
18/* There's only two modifiable fields in this - .mc.list and .driver */
19struct line_driver {
20 const char *name;
21 const char *device_name;
22 const short major;
23 const short minor_start;
24 const short type;
25 const short subtype;
26 const int read_irq;
27 const char *read_irq_name;
28 const int write_irq;
29 const char *write_irq_name;
30 struct mc_device mc;
31 struct tty_driver *driver;
32};
33
34struct line {
35 struct tty_port port;
36 int valid;
37
38 char *init_str;
39 struct list_head chan_list;
40 struct chan *chan_in, *chan_out;
41
42 /*This lock is actually, mostly, local to*/
43 spinlock_t lock;
44 int throttled;
45 /* Yes, this is a real circular buffer.
46 * XXX: And this should become a struct kfifo!
47 *
48 * buffer points to a buffer allocated on demand, of length
49 * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
50 char *buffer;
51 char *head;
52 char *tail;
53
54 int sigio;
55 struct delayed_work task;
56 const struct line_driver *driver;
57};
58
59extern void line_close(struct tty_struct *tty, struct file * filp);
60extern int line_open(struct tty_struct *tty, struct file *filp);
61extern int line_install(struct tty_driver *driver, struct tty_struct *tty,
62 struct line *line);
63extern void line_cleanup(struct tty_struct *tty);
64extern void line_hangup(struct tty_struct *tty);
65extern int line_setup(char **conf, unsigned nlines, char **def,
66 char *init, char *name);
67extern int line_write(struct tty_struct *tty, const unsigned char *buf,
68 int len);
69extern int line_put_char(struct tty_struct *tty, unsigned char ch);
70extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
71extern int line_chars_in_buffer(struct tty_struct *tty);
72extern void line_flush_buffer(struct tty_struct *tty);
73extern void line_flush_chars(struct tty_struct *tty);
74extern int line_write_room(struct tty_struct *tty);
75extern void line_throttle(struct tty_struct *tty);
76extern void line_unthrottle(struct tty_struct *tty);
77
78extern char *add_xterm_umid(char *base);
79extern int line_setup_irq(int fd, int input, int output, struct line *line,
80 void *data);
81extern void line_close_chan(struct line *line);
82extern int register_lines(struct line_driver *line_driver,
83 const struct tty_operations *driver,
84 struct line *lines, int nlines);
85extern int setup_one_line(struct line *lines, int n, char *init,
86 const struct chan_opts *opts, char **error_out);
87extern void close_lines(struct line *lines, int nlines);
88
89extern int line_config(struct line *lines, unsigned int sizeof_lines,
90 char *str, const struct chan_opts *opts,
91 char **error_out);
92extern int line_id(char **str, int *start_out, int *end_out);
93extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n,
94 char **error_out);
95extern int line_get_config(char *dev, struct line *lines,
96 unsigned int sizeof_lines, char *str,
97 int size, char **error_out);
98
99#endif
diff --git a/arch/um/drivers/mconsole.h b/arch/um/drivers/mconsole.h
deleted file mode 100644
index 8b22535c62c..00000000000
--- a/arch/um/drivers/mconsole.h
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL
5 */
6
7#ifndef __MCONSOLE_H__
8#define __MCONSOLE_H__
9
10#ifndef __KERNEL__
11#include <stdint.h>
12#define u32 uint32_t
13#endif
14
15#include <sysdep/ptrace.h>
16
17#define MCONSOLE_MAGIC (0xcafebabe)
18#define MCONSOLE_MAX_DATA (512)
19#define MCONSOLE_VERSION 2
20
21struct mconsole_request {
22 u32 magic;
23 u32 version;
24 u32 len;
25 char data[MCONSOLE_MAX_DATA];
26};
27
28struct mconsole_reply {
29 u32 err;
30 u32 more;
31 u32 len;
32 char data[MCONSOLE_MAX_DATA];
33};
34
35struct mconsole_notify {
36 u32 magic;
37 u32 version;
38 enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
39 MCONSOLE_USER_NOTIFY } type;
40 u32 len;
41 char data[MCONSOLE_MAX_DATA];
42};
43
44struct mc_request;
45
46enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
47
48struct mconsole_command
49{
50 char *command;
51 void (*handler)(struct mc_request *req);
52 enum mc_context context;
53};
54
55struct mc_request
56{
57 int len;
58 int as_interrupt;
59
60 int originating_fd;
61 unsigned int originlen;
62 unsigned char origin[128]; /* sockaddr_un */
63
64 struct mconsole_request request;
65 struct mconsole_command *cmd;
66 struct uml_pt_regs regs;
67};
68
69extern char mconsole_socket_name[];
70
71extern int mconsole_unlink_socket(void);
72extern int mconsole_reply_len(struct mc_request *req, const char *reply,
73 int len, int err, int more);
74extern int mconsole_reply(struct mc_request *req, const char *str, int err,
75 int more);
76
77extern void mconsole_version(struct mc_request *req);
78extern void mconsole_help(struct mc_request *req);
79extern void mconsole_halt(struct mc_request *req);
80extern void mconsole_reboot(struct mc_request *req);
81extern void mconsole_config(struct mc_request *req);
82extern void mconsole_remove(struct mc_request *req);
83extern void mconsole_sysrq(struct mc_request *req);
84extern void mconsole_cad(struct mc_request *req);
85extern void mconsole_stop(struct mc_request *req);
86extern void mconsole_go(struct mc_request *req);
87extern void mconsole_log(struct mc_request *req);
88extern void mconsole_proc(struct mc_request *req);
89extern void mconsole_stack(struct mc_request *req);
90
91extern int mconsole_get_request(int fd, struct mc_request *req);
92extern int mconsole_notify(char *sock_name, int type, const void *data,
93 int len);
94extern char *mconsole_notify_socket(void);
95extern void lock_notify(void);
96extern void unlock_notify(void);
97
98#endif
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 4bd82ac0210..c70e047eed7 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -21,19 +21,15 @@
21#include <linux/un.h> 21#include <linux/un.h>
22#include <linux/workqueue.h> 22#include <linux/workqueue.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/fs.h>
25#include <linux/mount.h>
26#include <linux/file.h>
27#include <asm/uaccess.h> 24#include <asm/uaccess.h>
28#include <asm/switch_to.h>
29 25
30#include <init.h> 26#include "init.h"
31#include <irq_kern.h> 27#include "irq_kern.h"
32#include <irq_user.h> 28#include "irq_user.h"
33#include <kern_util.h> 29#include "kern_util.h"
34#include "mconsole.h" 30#include "mconsole.h"
35#include "mconsole_kern.h" 31#include "mconsole_kern.h"
36#include <os.h> 32#include "os.h"
37 33
38static int do_unlink_socket(struct notifier_block *notifier, 34static int do_unlink_socket(struct notifier_block *notifier,
39 unsigned long what, void *data) 35 unsigned long what, void *data)
@@ -121,14 +117,18 @@ void mconsole_log(struct mc_request *req)
121 mconsole_reply(req, "", 0, 0); 117 mconsole_reply(req, "", 0, 0);
122} 118}
123 119
120/* This is a more convoluted version of mconsole_proc, which has some stability
121 * problems; however, we need it fixed, because it is expected that UML users
122 * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still
123 * show the real procfs content, not the ones from hppfs.*/
124#if 0
124void mconsole_proc(struct mc_request *req) 125void mconsole_proc(struct mc_request *req)
125{ 126{
126 struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt; 127 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
127 char *buf;
128 int len;
129 struct file *file; 128 struct file *file;
130 int first_chunk = 1; 129 int n;
131 char *ptr = req->request.data; 130 char *ptr = req->request.data, *buf;
131 mm_segment_t old_fs = get_fs();
132 132
133 ptr += strlen("proc"); 133 ptr += strlen("proc");
134 ptr = skip_spaces(ptr); 134 ptr = skip_spaces(ptr);
@@ -136,7 +136,6 @@ void mconsole_proc(struct mc_request *req)
136 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY); 136 file = file_open_root(mnt->mnt_root, mnt, ptr, O_RDONLY);
137 if (IS_ERR(file)) { 137 if (IS_ERR(file)) {
138 mconsole_reply(req, "Failed to open file", 1, 0); 138 mconsole_reply(req, "Failed to open file", 1, 0);
139 printk(KERN_ERR "open /proc/%s: %ld\n", ptr, PTR_ERR(file));
140 goto out; 139 goto out;
141 } 140 }
142 141
@@ -146,13 +145,62 @@ void mconsole_proc(struct mc_request *req)
146 goto out_fput; 145 goto out_fput;
147 } 146 }
148 147
149 do { 148 if (file->f_op->read) {
150 loff_t pos; 149 do {
151 mm_segment_t old_fs = get_fs(); 150 loff_t pos;
152 set_fs(KERNEL_DS); 151 set_fs(KERNEL_DS);
153 len = vfs_read(file, buf, PAGE_SIZE - 1, &pos); 152 n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
154 set_fs(old_fs); 153 file_pos_write(file, pos);
155 file->f_pos = pos; 154 set_fs(old_fs);
155 if (n >= 0) {
156 buf[n] = '\0';
157 mconsole_reply(req, buf, 0, (n > 0));
158 }
159 else {
160 mconsole_reply(req, "Read of file failed",
161 1, 0);
162 goto out_free;
163 }
164 } while (n > 0);
165 }
166 else mconsole_reply(req, "", 0, 0);
167
168 out_free:
169 kfree(buf);
170 out_fput:
171 fput(file);
172 out: ;
173}
174#endif
175
176void mconsole_proc(struct mc_request *req)
177{
178 char path[64];
179 char *buf;
180 int len;
181 int fd;
182 int first_chunk = 1;
183 char *ptr = req->request.data;
184
185 ptr += strlen("proc");
186 ptr = skip_spaces(ptr);
187 snprintf(path, sizeof(path), "/proc/%s", ptr);
188
189 fd = sys_open(path, 0, 0);
190 if (fd < 0) {
191 mconsole_reply(req, "Failed to open file", 1, 0);
192 printk(KERN_ERR "open %s: %d\n",path,fd);
193 goto out;
194 }
195
196 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
197 if (buf == NULL) {
198 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
199 goto out_close;
200 }
201
202 for (;;) {
203 len = sys_read(fd, buf, PAGE_SIZE-1);
156 if (len < 0) { 204 if (len < 0) {
157 mconsole_reply(req, "Read of file failed", 1, 0); 205 mconsole_reply(req, "Read of file failed", 1, 0);
158 goto out_free; 206 goto out_free;
@@ -162,14 +210,22 @@ void mconsole_proc(struct mc_request *req)
162 mconsole_reply(req, "\n", 0, 1); 210 mconsole_reply(req, "\n", 0, 1);
163 first_chunk = 0; 211 first_chunk = 0;
164 } 212 }
165 buf[len] = '\0'; 213 if (len == PAGE_SIZE-1) {
166 mconsole_reply(req, buf, 0, (len > 0)); 214 buf[len] = '\0';
167 } while (len > 0); 215 mconsole_reply(req, buf, 0, 1);
216 } else {
217 buf[len] = '\0';
218 mconsole_reply(req, buf, 0, 0);
219 break;
220 }
221 }
222
168 out_free: 223 out_free:
169 kfree(buf); 224 kfree(buf);
170 out_fput: 225 out_close:
171 fput(file); 226 sys_close(fd);
172 out: ; 227 out:
228 /* nothing */;
173} 229}
174 230
175#define UML_MCONSOLE_HELPTEXT \ 231#define UML_MCONSOLE_HELPTEXT \
@@ -648,7 +704,6 @@ static void stack_proc(void *arg)
648 struct task_struct *from = current, *to = arg; 704 struct task_struct *from = current, *to = arg;
649 705
650 to->thread.saved_task = from; 706 to->thread.saved_task = from;
651 rcu_user_hooks_switch(from, to);
652 switch_to(from, to, from); 707 switch_to(from, to, from);
653} 708}
654 709
@@ -718,7 +773,8 @@ static int __init mconsole_init(void)
718 register_reboot_notifier(&reboot_notifier); 773 register_reboot_notifier(&reboot_notifier);
719 774
720 err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, 775 err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
721 IRQF_SHARED, "mconsole", (void *)sock); 776 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
777 "mconsole", (void *)sock);
722 if (err) { 778 if (err) {
723 printk(KERN_ERR "Failed to get IRQ for management console\n"); 779 printk(KERN_ERR "Failed to get IRQ for management console\n");
724 goto out; 780 goto out;
diff --git a/arch/um/drivers/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h
deleted file mode 100644
index 7a0c6a1ad1d..00000000000
--- a/arch/um/drivers/mconsole_kern.h
+++ /dev/null
@@ -1,52 +0,0 @@
1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MCONSOLE_KERN_H__
7#define __MCONSOLE_KERN_H__
8
9#include <linux/list.h>
10#include "mconsole.h"
11
12struct mconsole_entry {
13 struct list_head list;
14 struct mc_request request;
15};
16
17/* All these methods are called in process context. */
18struct mc_device {
19 struct list_head list;
20 char *name;
21 int (*config)(char *, char **);
22 int (*get_config)(char *, char *, int, char **);
23 int (*id)(char **, int *, int *);
24 int (*remove)(int, char **);
25};
26
27#define CONFIG_CHUNK(str, size, current, chunk, end) \
28do { \
29 current += strlen(chunk); \
30 if(current >= size) \
31 str = NULL; \
32 if(str != NULL){ \
33 strcpy(str, chunk); \
34 str += strlen(chunk); \
35 } \
36 if(end) \
37 current++; \
38} while(0)
39
40#ifdef CONFIG_MCONSOLE
41
42extern void mconsole_register_dev(struct mc_device *new);
43
44#else
45
46static inline void mconsole_register_dev(struct mc_device *new)
47{
48}
49
50#endif
51
52#endif
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 99209826adb..f8cf4c8bede 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -10,7 +10,9 @@
10#include <sys/socket.h> 10#include <sys/socket.h>
11#include <sys/uio.h> 11#include <sys/uio.h>
12#include <sys/un.h> 12#include <sys/un.h>
13#include "kern_constants.h"
13#include "mconsole.h" 14#include "mconsole.h"
15#include "user.h"
14 16
15static struct mconsole_command commands[] = { 17static struct mconsole_command commands[] = {
16 /* 18 /*
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 62145c27616..c0ef803c7c7 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,7 +18,7 @@
18#include <linux/mm.h> 18#include <linux/mm.h>
19 19
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include <mem_user.h> 21#include "mem_user.h"
22 22
23/* These are set in mmapper_init, which is called at boot time */ 23/* These are set in mmapper_init, which is called at boot time */
24static unsigned long mmapper_size; 24static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index b1314ebf1f7..22745b47c82 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -18,12 +18,12 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <init.h> 21#include "init.h"
22#include <irq_kern.h> 22#include "irq_kern.h"
23#include <irq_user.h> 23#include "irq_user.h"
24#include "mconsole_kern.h" 24#include "mconsole_kern.h"
25#include <net_kern.h> 25#include "net_kern.h"
26#include <net_user.h> 26#include "net_user.h"
27 27
28#define DRIVER_NAME "uml-netdev" 28#define DRIVER_NAME "uml-netdev"
29 29
@@ -161,7 +161,7 @@ static int uml_net_open(struct net_device *dev)
161 } 161 }
162 162
163 err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, 163 err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
164 IRQF_SHARED, dev->name, dev); 164 IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
165 if (err != 0) { 165 if (err != 0) {
166 printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); 166 printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
167 err = -ENETUNREACH; 167 err = -ENETUNREACH;
@@ -195,7 +195,7 @@ static int uml_net_close(struct net_device *dev)
195 195
196 netif_stop_queue(dev); 196 netif_stop_queue(dev);
197 197
198 um_free_irq(dev->irq, dev); 198 free_irq(dev->irq, dev);
199 if (lp->close != NULL) 199 if (lp->close != NULL)
200 (*lp->close)(lp->fd, &lp->user); 200 (*lp->close)(lp->fd, &lp->user);
201 lp->fd = -1; 201 lp->fd = -1;
@@ -293,7 +293,7 @@ static void uml_net_user_timer_expire(unsigned long _conn)
293#endif 293#endif
294} 294}
295 295
296static int setup_etheraddr(char *str, unsigned char *addr, char *name) 296static void setup_etheraddr(char *str, unsigned char *addr, char *name)
297{ 297{
298 char *end; 298 char *end;
299 int i; 299 int i;
@@ -334,13 +334,12 @@ static int setup_etheraddr(char *str, unsigned char *addr, char *name)
334 addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], 334 addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4],
335 addr[5]); 335 addr[5]);
336 } 336 }
337 return 0; 337 return;
338 338
339random: 339random:
340 printk(KERN_INFO 340 printk(KERN_INFO
341 "Choosing a random ethernet address for device %s\n", name); 341 "Choosing a random ethernet address for device %s\n", name);
342 eth_random_addr(addr); 342 random_ether_addr(addr);
343 return 1;
344} 343}
345 344
346static DEFINE_SPINLOCK(devices_lock); 345static DEFINE_SPINLOCK(devices_lock);
@@ -369,7 +368,7 @@ static const struct net_device_ops uml_netdev_ops = {
369 .ndo_open = uml_net_open, 368 .ndo_open = uml_net_open,
370 .ndo_stop = uml_net_close, 369 .ndo_stop = uml_net_close,
371 .ndo_start_xmit = uml_net_start_xmit, 370 .ndo_start_xmit = uml_net_start_xmit,
372 .ndo_set_rx_mode = uml_net_set_multicast_list, 371 .ndo_set_multicast_list = uml_net_set_multicast_list,
373 .ndo_tx_timeout = uml_net_tx_timeout, 372 .ndo_tx_timeout = uml_net_tx_timeout,
374 .ndo_set_mac_address = eth_mac_addr, 373 .ndo_set_mac_address = eth_mac_addr,
375 .ndo_change_mtu = uml_net_change_mtu, 374 .ndo_change_mtu = uml_net_change_mtu,
@@ -392,7 +391,6 @@ static void eth_configure(int n, void *init, char *mac,
392 struct net_device *dev; 391 struct net_device *dev;
393 struct uml_net_private *lp; 392 struct uml_net_private *lp;
394 int err, size; 393 int err, size;
395 int random_mac;
396 394
397 size = transport->private_size + sizeof(struct uml_net_private); 395 size = transport->private_size + sizeof(struct uml_net_private);
398 396
@@ -419,7 +417,7 @@ static void eth_configure(int n, void *init, char *mac,
419 */ 417 */
420 snprintf(dev->name, sizeof(dev->name), "eth%d", n); 418 snprintf(dev->name, sizeof(dev->name), "eth%d", n);
421 419
422 random_mac = setup_etheraddr(mac, device->mac, dev->name); 420 setup_etheraddr(mac, device->mac, dev->name);
423 421
424 printk(KERN_INFO "Netdevice %d (%pM) : ", n, device->mac); 422 printk(KERN_INFO "Netdevice %d (%pM) : ", n, device->mac);
425 423
@@ -476,9 +474,6 @@ static void eth_configure(int n, void *init, char *mac,
476 474
477 /* don't use eth_mac_addr, it will not work here */ 475 /* don't use eth_mac_addr, it will not work here */
478 memcpy(dev->dev_addr, device->mac, ETH_ALEN); 476 memcpy(dev->dev_addr, device->mac, ETH_ALEN);
479 if (random_mac)
480 dev->addr_assign_type |= NET_ADDR_RANDOM;
481
482 dev->mtu = transport->user->mtu; 477 dev->mtu = transport->user->mtu;
483 dev->netdev_ops = &uml_netdev_ops; 478 dev->netdev_ops = &uml_netdev_ops;
484 dev->ethtool_ops = &uml_net_ethtool_ops; 479 dev->ethtool_ops = &uml_net_ethtool_ops;
@@ -835,7 +830,7 @@ static void close_devices(void)
835 spin_lock(&opened_lock); 830 spin_lock(&opened_lock);
836 list_for_each(ele, &opened) { 831 list_for_each(ele, &opened) {
837 lp = list_entry(ele, struct uml_net_private, list); 832 lp = list_entry(ele, struct uml_net_private, list);
838 um_free_irq(lp->dev->irq, lp->dev); 833 free_irq(lp->dev->irq, lp->dev);
839 if ((lp->close != NULL) && (lp->fd >= 0)) 834 if ((lp->close != NULL) && (lp->fd >= 0))
840 (*lp->close)(lp->fd, &lp->user); 835 (*lp->close)(lp->fd, &lp->user);
841 if (lp->remove != NULL) 836 if (lp->remove != NULL)
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index cd14157b556..520118888f1 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -11,9 +11,11 @@
11#include <string.h> 11#include <string.h>
12#include <sys/socket.h> 12#include <sys/socket.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <net_user.h> 14#include "net_user.h"
15#include <os.h> 15#include "kern_constants.h"
16#include <um_malloc.h> 16#include "os.h"
17#include "um_malloc.h"
18#include "user.h"
17 19
18int tap_open_common(void *dev, char *gate_addr) 20int tap_open_common(void *dev, char *gate_addr)
19{ 21{
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 10495747ce8..2b45a1446c8 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -7,7 +7,7 @@
7#include <errno.h> 7#include <errno.h>
8#include <fcntl.h> 8#include <fcntl.h>
9#include "chan_user.h" 9#include "chan_user.h"
10#include <os.h> 10#include "os.h"
11 11
12/* This address is used only as a unique identifier */ 12/* This address is used only as a unique identifier */
13static int null_chan; 13static int null_chan;
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index be0fb57bd1d..2860525f8ff 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -3,9 +3,9 @@
3 * Licensed under the GPL. 3 * Licensed under the GPL.
4 */ 4 */
5 5
6#include <linux/init.h> 6#include "linux/init.h"
7#include <linux/netdevice.h> 7#include <linux/netdevice.h>
8#include <net_kern.h> 8#include "net_kern.h"
9#include "pcap_user.h" 9#include "pcap_user.h"
10 10
11struct pcap_init { 11struct pcap_init {
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index c07b9c752c8..5f903587d69 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -7,9 +7,11 @@
7#include <pcap.h> 7#include <pcap.h>
8#include <string.h> 8#include <string.h>
9#include <asm/types.h> 9#include <asm/types.h>
10#include <net_user.h> 10#include "net_user.h"
11#include "pcap_user.h" 11#include "pcap_user.h"
12#include <um_malloc.h> 12#include "kern_constants.h"
13#include "um_malloc.h"
14#include "user.h"
13 15
14#define PCAP_FD(p) (*(int *)(p)) 16#define PCAP_FD(p) (*(int *)(p))
15 17
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
index 1ca7c764cc6..d8ba6153f91 100644
--- a/arch/um/drivers/pcap_user.h
+++ b/arch/um/drivers/pcap_user.h
@@ -3,7 +3,7 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <net_user.h> 6#include "net_user.h"
7 7
8struct pcap_data { 8struct pcap_data {
9 char *host_if; 9 char *host_if;
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 40ca5cc275e..a11573be096 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -3,16 +3,16 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/completion.h> 6#include "linux/completion.h"
7#include <linux/interrupt.h> 7#include "linux/interrupt.h"
8#include <linux/list.h> 8#include "linux/list.h"
9#include <linux/mutex.h> 9#include "linux/mutex.h"
10#include <linux/slab.h> 10#include "linux/slab.h"
11#include <linux/workqueue.h> 11#include "linux/workqueue.h"
12#include <asm/atomic.h> 12#include "asm/atomic.h"
13#include <init.h> 13#include "init.h"
14#include <irq_kern.h> 14#include "irq_kern.h"
15#include <os.h> 15#include "os.h"
16#include "port.h" 16#include "port.h"
17 17
18struct port_list { 18struct port_list {
@@ -100,7 +100,8 @@ static int port_accept(struct port_list *port)
100 .port = port }); 100 .port = port });
101 101
102 if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 102 if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
103 IRQF_SHARED, "telnetd", conn)) { 103 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
104 "telnetd", conn)) {
104 printk(KERN_ERR "port_accept : failed to get IRQ for " 105 printk(KERN_ERR "port_accept : failed to get IRQ for "
105 "telnetd\n"); 106 "telnetd\n");
106 goto out_free; 107 goto out_free;
@@ -183,7 +184,8 @@ void *port_data(int port_num)
183 } 184 }
184 185
185 if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 186 if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
186 IRQF_SHARED, "port", port)) { 187 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
188 "port", port)) {
187 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); 189 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
188 goto out_close; 190 goto out_close;
189 } 191 }
@@ -252,7 +254,7 @@ int port_wait(void *data)
252 * connection. Then we loop here throwing out failed 254 * connection. Then we loop here throwing out failed
253 * connections until a good one is found. 255 * connections until a good one is found.
254 */ 256 */
255 um_free_irq(TELNETD_IRQ, conn); 257 free_irq(TELNETD_IRQ, conn);
256 258
257 if (conn->fd >= 0) 259 if (conn->fd >= 0)
258 break; 260 break;
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 9a8e1b64c22..b49bf56a56a 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -10,9 +10,11 @@
10#include <unistd.h> 10#include <unistd.h>
11#include <netinet/in.h> 11#include <netinet/in.h>
12#include "chan_user.h" 12#include "chan_user.h"
13#include <os.h> 13#include "kern_constants.h"
14#include "os.h"
14#include "port.h" 15#include "port.h"
15#include <um_malloc.h> 16#include "um_malloc.h"
17#include "user.h"
16 18
17struct port_chan { 19struct port_chan {
18 int raw; 20 int raw;
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index f1fcc2cedb5..1113911dcb2 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -12,8 +12,10 @@
12#include <termios.h> 12#include <termios.h>
13#include <sys/stat.h> 13#include <sys/stat.h>
14#include "chan_user.h" 14#include "chan_user.h"
15#include <os.h> 15#include "kern_constants.h"
16#include <um_malloc.h> 16#include "os.h"
17#include "um_malloc.h"
18#include "user.h"
17 19
18struct pty_chan { 20struct pty_chan {
19 void (*announce)(char *dev_name, int dev); 21 void (*announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 9e3a7220582..981085a93f3 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -13,8 +13,8 @@
13#include <linux/miscdevice.h> 13#include <linux/miscdevice.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16#include <irq_kern.h> 16#include "irq_kern.h"
17#include <os.h> 17#include "os.h"
18 18
19/* 19/*
20 * core module and version information 20 * core module and version information
@@ -131,7 +131,8 @@ static int __init rng_init (void)
131 random_fd = err; 131 random_fd = err;
132 132
133 err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt, 133 err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
134 0, "random", NULL); 134 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
135 NULL);
135 if (err) 136 if (err)
136 goto err_out_cleanup_hw; 137 goto err_out_cleanup_hw;
137 138
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
index f597fa7c91d..e89cfc68fc3 100644
--- a/arch/um/drivers/slip_common.c
+++ b/arch/um/drivers/slip_common.c
@@ -1,6 +1,6 @@
1#include <string.h> 1#include <string.h>
2#include "slip_common.h" 2#include "slip_common.h"
3#include <net_user.h> 3#include "net_user.h"
4 4
5int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip) 5int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
6{ 6{
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index ed5249fc057..dd2aadc14af 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -6,7 +6,7 @@
6#include <linux/if_arp.h> 6#include <linux/if_arp.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/netdevice.h> 8#include <linux/netdevice.h>
9#include <net_kern.h> 9#include "net_kern.h"
10#include "slip.h" 10#include "slip.h"
11 11
12struct slip_init { 12struct slip_init {
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 55c290d925f..cbacfc4e63e 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -11,10 +11,12 @@
11#include <string.h> 11#include <string.h>
12#include <sys/termios.h> 12#include <sys/termios.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <net_user.h> 14#include "kern_constants.h"
15#include <os.h> 15#include "net_user.h"
16#include "os.h"
16#include "slip.h" 17#include "slip.h"
17#include <um_malloc.h> 18#include "um_malloc.h"
19#include "user.h"
18 20
19static int slip_user_init(void *data, void *dev) 21static int slip_user_init(void *data, void *dev)
20{ 22{
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 4ef11ca7cac..e376284f0fb 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -4,11 +4,11 @@
4 */ 4 */
5 5
6#include <linux/if_arp.h> 6#include <linux/if_arp.h>
7#include <linux/init.h> 7#include "linux/init.h"
8#include <linux/netdevice.h> 8#include <linux/netdevice.h>
9#include <linux/string.h> 9#include <linux/string.h>
10#include <net_kern.h> 10#include "net_kern.h"
11#include <net_user.h> 11#include "net_user.h"
12#include "slirp.h" 12#include "slirp.h"
13 13
14struct slirp_init { 14struct slirp_init {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c999d187abb..a0ada8fec72 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,9 +7,11 @@
7#include <errno.h> 7#include <errno.h>
8#include <string.h> 8#include <string.h>
9#include <sys/wait.h> 9#include <sys/wait.h>
10#include <net_user.h> 10#include "kern_constants.h"
11#include <os.h> 11#include "net_user.h"
12#include "os.h"
12#include "slirp.h" 13#include "slirp.h"
14#include "user.h"
13 15
14static int slirp_user_init(void *data, void *dev) 16static int slirp_user_init(void *data, void *dev)
15{ 17{
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 16fdd0a0f9d..f1786e64607 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -3,23 +3,31 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/fs.h> 6#include "linux/fs.h"
7#include <linux/tty.h> 7#include "linux/tty.h"
8#include <linux/tty_driver.h> 8#include "linux/tty_driver.h"
9#include <linux/major.h> 9#include "linux/major.h"
10#include <linux/mm.h> 10#include "linux/mm.h"
11#include <linux/init.h> 11#include "linux/init.h"
12#include <linux/console.h> 12#include "linux/console.h"
13#include <asm/termbits.h> 13#include "asm/termbits.h"
14#include <asm/irq.h> 14#include "asm/irq.h"
15#include "line.h"
15#include "ssl.h" 16#include "ssl.h"
16#include "chan.h" 17#include "chan_kern.h"
17#include <init.h> 18#include "kern.h"
18#include <irq_user.h> 19#include "init.h"
20#include "irq_user.h"
19#include "mconsole_kern.h" 21#include "mconsole_kern.h"
20 22
21static const int ssl_version = 1; 23static const int ssl_version = 1;
22 24
25/* Referenced only by tty_driver below - presumably it's locked correctly
26 * by the tty driver.
27 */
28
29static struct tty_driver *ssl_driver;
30
23#define NR_PORTS 64 31#define NR_PORTS 64
24 32
25static void ssl_announce(char *dev_name, int dev) 33static void ssl_announce(char *dev_name, int dev)
@@ -65,9 +73,8 @@ static struct line_driver driver = {
65/* The array is initialized by line_init, at initcall time. The 73/* The array is initialized by line_init, at initcall time. The
66 * elements are locked individually as needed. 74 * elements are locked individually as needed.
67 */ 75 */
68static char *conf[NR_PORTS]; 76static struct line serial_lines[NR_PORTS] =
69static char *def_conf = CONFIG_SSL_CHAN; 77 { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) };
70static struct line serial_lines[NR_PORTS];
71 78
72static int ssl_config(char *str, char **error_out) 79static int ssl_config(char *str, char **error_out)
73{ 80{
@@ -87,13 +94,40 @@ static int ssl_remove(int n, char **error_out)
87 error_out); 94 error_out);
88} 95}
89 96
90static int ssl_install(struct tty_driver *driver, struct tty_struct *tty) 97static int ssl_open(struct tty_struct *tty, struct file *filp)
98{
99 int err = line_open(serial_lines, tty);
100
101 if (err)
102 printk(KERN_ERR "Failed to open serial line %d, err = %d\n",
103 tty->index, err);
104
105 return err;
106}
107
108#if 0
109static void ssl_flush_buffer(struct tty_struct *tty)
110{
111 return;
112}
113
114static void ssl_stop(struct tty_struct *tty)
115{
116 printk(KERN_ERR "Someone should implement ssl_stop\n");
117}
118
119static void ssl_start(struct tty_struct *tty)
91{ 120{
92 return line_install(driver, tty, &serial_lines[tty->index]); 121 printk(KERN_ERR "Someone should implement ssl_start\n");
93} 122}
94 123
124void ssl_hangup(struct tty_struct *tty)
125{
126}
127#endif
128
95static const struct tty_operations ssl_ops = { 129static const struct tty_operations ssl_ops = {
96 .open = line_open, 130 .open = ssl_open,
97 .close = line_close, 131 .close = line_close,
98 .write = line_write, 132 .write = line_write,
99 .put_char = line_put_char, 133 .put_char = line_put_char,
@@ -102,11 +136,14 @@ static const struct tty_operations ssl_ops = {
102 .flush_buffer = line_flush_buffer, 136 .flush_buffer = line_flush_buffer,
103 .flush_chars = line_flush_chars, 137 .flush_chars = line_flush_chars,
104 .set_termios = line_set_termios, 138 .set_termios = line_set_termios,
139 .ioctl = line_ioctl,
105 .throttle = line_throttle, 140 .throttle = line_throttle,
106 .unthrottle = line_unthrottle, 141 .unthrottle = line_unthrottle,
107 .install = ssl_install, 142#if 0
108 .cleanup = line_cleanup, 143 .stop = ssl_stop,
109 .hangup = line_hangup, 144 .start = ssl_start,
145 .hangup = ssl_hangup,
146#endif
110}; 147};
111 148
112/* Changed by ssl_init and referenced by ssl_exit, which are both serialized 149/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
@@ -121,14 +158,14 @@ static void ssl_console_write(struct console *c, const char *string,
121 unsigned long flags; 158 unsigned long flags;
122 159
123 spin_lock_irqsave(&line->lock, flags); 160 spin_lock_irqsave(&line->lock, flags);
124 console_write_chan(line->chan_out, string, len); 161 console_write_chan(&line->chan_list, string, len);
125 spin_unlock_irqrestore(&line->lock, flags); 162 spin_unlock_irqrestore(&line->lock, flags);
126} 163}
127 164
128static struct tty_driver *ssl_console_device(struct console *c, int *index) 165static struct tty_driver *ssl_console_device(struct console *c, int *index)
129{ 166{
130 *index = c->index; 167 *index = c->index;
131 return driver.driver; 168 return ssl_driver;
132} 169}
133 170
134static int ssl_console_setup(struct console *co, char *options) 171static int ssl_console_setup(struct console *co, char *options)
@@ -151,30 +188,17 @@ static struct console ssl_cons = {
151static int ssl_init(void) 188static int ssl_init(void)
152{ 189{
153 char *new_title; 190 char *new_title;
154 int err;
155 int i;
156 191
157 printk(KERN_INFO "Initializing software serial port version %d\n", 192 printk(KERN_INFO "Initializing software serial port version %d\n",
158 ssl_version); 193 ssl_version);
159 194 ssl_driver = register_lines(&driver, &ssl_ops, serial_lines,
160 err = register_lines(&driver, &ssl_ops, serial_lines,
161 ARRAY_SIZE(serial_lines)); 195 ARRAY_SIZE(serial_lines));
162 if (err)
163 return err;
164 196
165 new_title = add_xterm_umid(opts.xterm_title); 197 new_title = add_xterm_umid(opts.xterm_title);
166 if (new_title != NULL) 198 if (new_title != NULL)
167 opts.xterm_title = new_title; 199 opts.xterm_title = new_title;
168 200
169 for (i = 0; i < NR_PORTS; i++) { 201 lines_init(serial_lines, ARRAY_SIZE(serial_lines), &opts);
170 char *error;
171 char *s = conf[i];
172 if (!s)
173 s = def_conf;
174 if (setup_one_line(serial_lines, i, s, &opts, &error))
175 printk(KERN_ERR "setup_one_line failed for "
176 "device %d : %s\n", i, error);
177 }
178 202
179 ssl_init_done = 1; 203 ssl_init_done = 1;
180 register_console(&ssl_cons); 204 register_console(&ssl_cons);
@@ -192,7 +216,14 @@ __uml_exitcall(ssl_exit);
192 216
193static int ssl_chan_setup(char *str) 217static int ssl_chan_setup(char *str)
194{ 218{
195 line_setup(conf, NR_PORTS, &def_conf, str, "serial line"); 219 char *error;
220 int ret;
221
222 ret = line_setup(serial_lines, ARRAY_SIZE(serial_lines), str, &error);
223 if(ret < 0)
224 printk(KERN_ERR "Failed to set up serial line with "
225 "configuration string \"%s\" : %s\n", str, error);
226
196 return 1; 227 return 1;
197} 228}
198 229
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 827777af3f6..49266f6108c 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -3,30 +3,37 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/posix_types.h> 6#include "linux/posix_types.h"
7#include <linux/tty.h> 7#include "linux/tty.h"
8#include <linux/tty_flip.h> 8#include "linux/tty_flip.h"
9#include <linux/types.h> 9#include "linux/types.h"
10#include <linux/major.h> 10#include "linux/major.h"
11#include <linux/kdev_t.h> 11#include "linux/kdev_t.h"
12#include <linux/console.h> 12#include "linux/console.h"
13#include <linux/string.h> 13#include "linux/string.h"
14#include <linux/sched.h> 14#include "linux/sched.h"
15#include <linux/list.h> 15#include "linux/list.h"
16#include <linux/init.h> 16#include "linux/init.h"
17#include <linux/interrupt.h> 17#include "linux/interrupt.h"
18#include <linux/slab.h> 18#include "linux/slab.h"
19#include <linux/hardirq.h> 19#include "linux/hardirq.h"
20#include <asm/current.h> 20#include "asm/current.h"
21#include <asm/irq.h> 21#include "asm/irq.h"
22#include "stdio_console.h" 22#include "stdio_console.h"
23#include "chan.h" 23#include "line.h"
24#include <irq_user.h> 24#include "chan_kern.h"
25#include "irq_user.h"
25#include "mconsole_kern.h" 26#include "mconsole_kern.h"
26#include <init.h> 27#include "init.h"
27 28
28#define MAX_TTYS (16) 29#define MAX_TTYS (16)
29 30
31/* Referenced only by tty_driver below - presumably it's locked correctly
32 * by the tty driver.
33 */
34
35static struct tty_driver *console_driver;
36
30static void stdio_announce(char *dev_name, int dev) 37static void stdio_announce(char *dev_name, int dev)
31{ 38{
32 printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev, 39 printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
@@ -70,9 +77,9 @@ static struct line_driver driver = {
70/* The array is initialized by line_init, at initcall time. The 77/* The array is initialized by line_init, at initcall time. The
71 * elements are locked individually as needed. 78 * elements are locked individually as needed.
72 */ 79 */
73static char *vt_conf[MAX_TTYS]; 80static struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
74static char *def_conf; 81 [ 1 ... MAX_TTYS - 1 ] =
75static struct line vts[MAX_TTYS]; 82 LINE_INIT(CONFIG_CON_CHAN, &driver) };
76 83
77static int con_config(char *str, char **error_out) 84static int con_config(char *str, char **error_out)
78{ 85{
@@ -89,17 +96,21 @@ static int con_remove(int n, char **error_out)
89 return line_remove(vts, ARRAY_SIZE(vts), n, error_out); 96 return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
90} 97}
91 98
92/* Set in an initcall, checked in an exitcall */ 99static int con_open(struct tty_struct *tty, struct file *filp)
93static int con_init_done = 0;
94
95static int con_install(struct tty_driver *driver, struct tty_struct *tty)
96{ 100{
97 return line_install(driver, tty, &vts[tty->index]); 101 int err = line_open(vts, tty);
102 if (err)
103 printk(KERN_ERR "Failed to open console %d, err = %d\n",
104 tty->index, err);
105
106 return err;
98} 107}
99 108
109/* Set in an initcall, checked in an exitcall */
110static int con_init_done = 0;
111
100static const struct tty_operations console_ops = { 112static const struct tty_operations console_ops = {
101 .open = line_open, 113 .open = con_open,
102 .install = con_install,
103 .close = line_close, 114 .close = line_close,
104 .write = line_write, 115 .write = line_write,
105 .put_char = line_put_char, 116 .put_char = line_put_char,
@@ -108,10 +119,9 @@ static const struct tty_operations console_ops = {
108 .flush_buffer = line_flush_buffer, 119 .flush_buffer = line_flush_buffer,
109 .flush_chars = line_flush_chars, 120 .flush_chars = line_flush_chars,
110 .set_termios = line_set_termios, 121 .set_termios = line_set_termios,
122 .ioctl = line_ioctl,
111 .throttle = line_throttle, 123 .throttle = line_throttle,
112 .unthrottle = line_unthrottle, 124 .unthrottle = line_unthrottle,
113 .cleanup = line_cleanup,
114 .hangup = line_hangup,
115}; 125};
116 126
117static void uml_console_write(struct console *console, const char *string, 127static void uml_console_write(struct console *console, const char *string,
@@ -121,14 +131,14 @@ static void uml_console_write(struct console *console, const char *string,
121 unsigned long flags; 131 unsigned long flags;
122 132
123 spin_lock_irqsave(&line->lock, flags); 133 spin_lock_irqsave(&line->lock, flags);
124 console_write_chan(line->chan_out, string, len); 134 console_write_chan(&line->chan_list, string, len);
125 spin_unlock_irqrestore(&line->lock, flags); 135 spin_unlock_irqrestore(&line->lock, flags);
126} 136}
127 137
128static struct tty_driver *uml_console_device(struct console *c, int *index) 138static struct tty_driver *uml_console_device(struct console *c, int *index)
129{ 139{
130 *index = c->index; 140 *index = c->index;
131 return driver.driver; 141 return console_driver;
132} 142}
133 143
134static int uml_console_setup(struct console *co, char *options) 144static int uml_console_setup(struct console *co, char *options)
@@ -151,31 +161,18 @@ static struct console stdiocons = {
151static int stdio_init(void) 161static int stdio_init(void)
152{ 162{
153 char *new_title; 163 char *new_title;
154 int err;
155 int i;
156 164
157 err = register_lines(&driver, &console_ops, vts, 165 console_driver = register_lines(&driver, &console_ops, vts,
158 ARRAY_SIZE(vts)); 166 ARRAY_SIZE(vts));
159 if (err) 167 if (console_driver == NULL)
160 return err; 168 return -1;
161
162 printk(KERN_INFO "Initialized stdio console driver\n"); 169 printk(KERN_INFO "Initialized stdio console driver\n");
163 170
164 new_title = add_xterm_umid(opts.xterm_title); 171 new_title = add_xterm_umid(opts.xterm_title);
165 if(new_title != NULL) 172 if(new_title != NULL)
166 opts.xterm_title = new_title; 173 opts.xterm_title = new_title;
167 174
168 for (i = 0; i < MAX_TTYS; i++) { 175 lines_init(vts, ARRAY_SIZE(vts), &opts);
169 char *error;
170 char *s = vt_conf[i];
171 if (!s)
172 s = def_conf;
173 if (!s)
174 s = i ? CONFIG_CON_CHAN : CONFIG_CON_ZERO_CHAN;
175 if (setup_one_line(vts, i, s, &opts, &error))
176 printk(KERN_ERR "setup_one_line failed for "
177 "device %d : %s\n", i, error);
178 }
179 176
180 con_init_done = 1; 177 con_init_done = 1;
181 register_console(&stdiocons); 178 register_console(&stdiocons);
@@ -193,7 +190,14 @@ __uml_exitcall(console_exit);
193 190
194static int console_chan_setup(char *str) 191static int console_chan_setup(char *str)
195{ 192{
196 line_setup(vt_conf, MAX_TTYS, &def_conf, str, "console"); 193 char *error;
194 int ret;
195
196 ret = line_setup(vts, ARRAY_SIZE(vts), str, &error);
197 if(ret < 0)
198 printk(KERN_ERR "Failed to set up console with "
199 "configuration string \"%s\" : %s\n", str, error);
200
197 return 1; 201 return 1;
198} 202}
199__setup("con", console_chan_setup); 203__setup("con", console_chan_setup);
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index eaa201bca5e..495858a090e 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -7,8 +7,10 @@
7#include <fcntl.h> 7#include <fcntl.h>
8#include <termios.h> 8#include <termios.h>
9#include "chan_user.h" 9#include "chan_user.h"
10#include <os.h> 10#include "kern_constants.h"
11#include <um_malloc.h> 11#include "os.h"
12#include "um_malloc.h"
13#include "user.h"
12 14
13struct tty_chan { 15struct tty_chan {
14 char *dev; 16 char *dev;
diff --git a/arch/um/drivers/ubd.h b/arch/um/drivers/ubd.h
deleted file mode 100644
index 3845051f1b1..00000000000
--- a/arch/um/drivers/ubd.h
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
4 * Licensed under the GPL
5 */
6
7#ifndef __UM_UBD_USER_H
8#define __UM_UBD_USER_H
9
10extern void ignore_sigwinch_sig(void);
11extern int start_io_thread(unsigned long sp, int *fds_out);
12extern int io_thread(void *arg);
13extern int kernel_fd;
14
15#endif
16
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 41bf72073cc..0491e40d696 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -19,26 +19,42 @@
19 19
20#define UBD_SHIFT 4 20#define UBD_SHIFT 4
21 21
22#include <linux/module.h> 22#include "linux/kernel.h"
23#include <linux/init.h> 23#include "linux/module.h"
24#include <linux/blkdev.h> 24#include "linux/blkdev.h"
25#include <linux/ata.h> 25#include "linux/ata.h"
26#include <linux/hdreg.h> 26#include "linux/hdreg.h"
27#include <linux/cdrom.h> 27#include "linux/init.h"
28#include <linux/proc_fs.h> 28#include "linux/cdrom.h"
29#include <linux/seq_file.h> 29#include "linux/proc_fs.h"
30#include <linux/ctype.h> 30#include "linux/seq_file.h"
31#include <linux/slab.h> 31#include "linux/ctype.h"
32#include <linux/vmalloc.h> 32#include "linux/capability.h"
33#include <linux/platform_device.h> 33#include "linux/mm.h"
34#include <linux/scatterlist.h> 34#include "linux/slab.h"
35#include <asm/tlbflush.h> 35#include "linux/vmalloc.h"
36#include <kern_util.h> 36#include "linux/mutex.h"
37#include "linux/blkpg.h"
38#include "linux/genhd.h"
39#include "linux/spinlock.h"
40#include "linux/platform_device.h"
41#include "linux/scatterlist.h"
42#include "asm/segment.h"
43#include "asm/uaccess.h"
44#include "asm/irq.h"
45#include "asm/types.h"
46#include "asm/tlbflush.h"
47#include "mem_user.h"
48#include "kern_util.h"
49#include "kern.h"
37#include "mconsole_kern.h" 50#include "mconsole_kern.h"
38#include <init.h> 51#include "init.h"
39#include <irq_kern.h> 52#include "irq_user.h"
40#include "ubd.h" 53#include "irq_kern.h"
41#include <os.h> 54#include "ubd_user.h"
55#include "os.h"
56#include "mem.h"
57#include "mem_kern.h"
42#include "cow.h" 58#include "cow.h"
43 59
44enum ubd_req { UBD_READ, UBD_WRITE }; 60enum ubd_req { UBD_READ, UBD_WRITE };
@@ -514,7 +530,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
514 goto out; 530 goto out;
515 } 531 }
516 532
517 fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0); 533 fd = os_open_file(ubd_dev->file, global_openflags, 0);
518 if (fd < 0) 534 if (fd < 0)
519 return fd; 535 return fd;
520 536
@@ -1101,7 +1117,7 @@ static int __init ubd_driver_init(void){
1101 return 0; 1117 return 0;
1102 } 1118 }
1103 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 1119 err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
1104 0, "ubd", ubd_devs); 1120 IRQF_DISABLED, "ubd", ubd_devs);
1105 if(err != 0) 1121 if(err != 0)
1106 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); 1122 printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
1107 return 0; 1123 return 0;
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index a703e45d8aa..b591bb9c41d 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -15,12 +15,15 @@
15#include <sys/socket.h> 15#include <sys/socket.h>
16#include <sys/mman.h> 16#include <sys/mman.h>
17#include <sys/param.h> 17#include <sys/param.h>
18#include "asm/types.h"
19#include "user.h"
20#include "ubd_user.h"
21#include "os.h"
22#include "cow.h"
23
18#include <endian.h> 24#include <endian.h>
19#include <byteswap.h> 25#include <byteswap.h>
20 26
21#include "ubd.h"
22#include <os.h>
23
24void ignore_sigwinch_sig(void) 27void ignore_sigwinch_sig(void)
25{ 28{
26 signal(SIGWINCH, SIG_IGN); 29 signal(SIGWINCH, SIG_IGN);
diff --git a/arch/um/drivers/umcast.h b/arch/um/drivers/umcast.h
index c190c644091..6f8c0fe890f 100644
--- a/arch/um/drivers/umcast.h
+++ b/arch/um/drivers/umcast.h
@@ -6,7 +6,7 @@
6#ifndef __DRIVERS_UMCAST_H 6#ifndef __DRIVERS_UMCAST_H
7#define __DRIVERS_UMCAST_H 7#define __DRIVERS_UMCAST_H
8 8
9#include <net_user.h> 9#include "net_user.h"
10 10
11struct umcast_data { 11struct umcast_data {
12 char *addr; 12 char *addr;
diff --git a/arch/um/drivers/umcast_kern.c b/arch/um/drivers/umcast_kern.c
index f5ba6e37791..42dab11d2ec 100644
--- a/arch/um/drivers/umcast_kern.c
+++ b/arch/um/drivers/umcast_kern.c
@@ -11,10 +11,10 @@
11 * Licensed under the GPL. 11 * Licensed under the GPL.
12 */ 12 */
13 13
14#include <linux/init.h> 14#include "linux/init.h"
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16#include "umcast.h" 16#include "umcast.h"
17#include <net_kern.h> 17#include "net_kern.h"
18 18
19struct umcast_init { 19struct umcast_init {
20 char *addr; 20 char *addr;
diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c
index 6074184bb51..59c56fd6f52 100644
--- a/arch/um/drivers/umcast_user.c
+++ b/arch/um/drivers/umcast_user.c
@@ -15,9 +15,11 @@
15#include <unistd.h> 15#include <unistd.h>
16#include <errno.h> 16#include <errno.h>
17#include <netinet/in.h> 17#include <netinet/in.h>
18#include "kern_constants.h"
18#include "umcast.h" 19#include "umcast.h"
19#include <net_user.h> 20#include "net_user.h"
20#include <um_malloc.h> 21#include "um_malloc.h"
22#include "user.h"
21 23
22static struct sockaddr_in *new_addr(char *addr, unsigned short port) 24static struct sockaddr_in *new_addr(char *addr, unsigned short port)
23{ 25{
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
index 6a365fadc7c..1b852bffdeb 100644
--- a/arch/um/drivers/vde_kern.c
+++ b/arch/um/drivers/vde_kern.c
@@ -7,10 +7,10 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/init.h> 10#include "linux/init.h"
11#include <linux/netdevice.h> 11#include <linux/netdevice.h>
12#include <net_kern.h> 12#include "net_kern.h"
13#include <net_user.h> 13#include "net_user.h"
14#include "vde.h" 14#include "vde.h"
15 15
16static void vde_init(struct net_device *dev, void *data) 16static void vde_init(struct net_device *dev, void *data)
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
index 64cb630d115..c5c43253e6c 100644
--- a/arch/um/drivers/vde_user.c
+++ b/arch/um/drivers/vde_user.c
@@ -6,8 +6,10 @@
6#include <stddef.h> 6#include <stddef.h>
7#include <errno.h> 7#include <errno.h>
8#include <libvdeplug.h> 8#include <libvdeplug.h>
9#include <net_user.h> 9#include "kern_constants.h"
10#include <um_malloc.h> 10#include "net_user.h"
11#include "um_malloc.h"
12#include "user.h"
11#include "vde.h" 13#include "vde.h"
12 14
13static int vde_user_init(void *data, void *dev) 15static int vde_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 20e30be4479..2e1de572860 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -11,8 +11,10 @@
11#include <string.h> 11#include <string.h>
12#include <termios.h> 12#include <termios.h>
13#include "chan_user.h" 13#include "chan_user.h"
14#include <os.h> 14#include "kern_constants.h"
15#include <um_malloc.h> 15#include "os.h"
16#include "um_malloc.h"
17#include "user.h"
16#include "xterm.h" 18#include "xterm.h"
17 19
18struct xterm_chan { 20struct xterm_chan {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index e8f9957bfbf..b646bccef37 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,8 +7,8 @@
7#include <linux/completion.h> 7#include <linux/completion.h>
8#include <linux/irqreturn.h> 8#include <linux/irqreturn.h>
9#include <asm/irq.h> 9#include <asm/irq.h>
10#include <irq_kern.h> 10#include "irq_kern.h"
11#include <os.h> 11#include "os.h"
12 12
13struct xterm_wait { 13struct xterm_wait {
14 struct completion ready; 14 struct completion ready;
@@ -50,7 +50,8 @@ int xterm_fd(int socket, int *pid_out)
50 init_completion(&data->ready); 50 init_completion(&data->ready);
51 51
52 err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, 52 err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
53 IRQF_SHARED, "xterm", data); 53 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
54 "xterm", data);
54 if (err) { 55 if (err) {
55 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " 56 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
56 "err = %d\n", err); 57 "err = %d\n", err);
@@ -64,7 +65,7 @@ int xterm_fd(int socket, int *pid_out)
64 * isn't set) this will hang... */ 65 * isn't set) this will hang... */
65 wait_for_completion(&data->ready); 66 wait_for_completion(&data->ready);
66 67
67 um_free_irq(XTERM_IRQ, data); 68 free_irq(XTERM_IRQ, data);
68 69
69 ret = data->new_fd; 70 ret = data->new_fd;
70 *pid_out = data->pid; 71 *pid_out = data->pid;