diff options
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/sigio_kern.c | 10 | ||||
-rw-r--r-- | arch/um/kernel/sigio_user.c | 162 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 3 |
3 files changed, 19 insertions, 156 deletions
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c index 229988463c4c..1c1300fb1e95 100644 --- a/arch/um/kernel/sigio_kern.c +++ b/arch/um/kernel/sigio_kern.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) | 2 | * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -12,13 +12,16 @@ | |||
12 | #include "sigio.h" | 12 | #include "sigio.h" |
13 | #include "irq_user.h" | 13 | #include "irq_user.h" |
14 | #include "irq_kern.h" | 14 | #include "irq_kern.h" |
15 | #include "os.h" | ||
15 | 16 | ||
16 | /* Protected by sigio_lock() called from write_sigio_workaround */ | 17 | /* Protected by sigio_lock() called from write_sigio_workaround */ |
17 | static int sigio_irq_fd = -1; | 18 | static int sigio_irq_fd = -1; |
18 | 19 | ||
19 | static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused) | 20 | static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused) |
20 | { | 21 | { |
21 | read_sigio_fd(sigio_irq_fd); | 22 | char c; |
23 | |||
24 | os_read_file(sigio_irq_fd, &c, sizeof(c)); | ||
22 | reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); | 25 | reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); |
23 | return(IRQ_HANDLED); | 26 | return(IRQ_HANDLED); |
24 | } | 27 | } |
@@ -51,6 +54,9 @@ void sigio_unlock(void) | |||
51 | spin_unlock(&sigio_spinlock); | 54 | spin_unlock(&sigio_spinlock); |
52 | } | 55 | } |
53 | 56 | ||
57 | extern void sigio_cleanup(void); | ||
58 | __uml_exitcall(sigio_cleanup); | ||
59 | |||
54 | /* | 60 | /* |
55 | * Overrides for Emacs so that we follow Linus's tabbing style. | 61 | * Overrides for Emacs so that we follow Linus's tabbing style. |
56 | * Emacs will notice this stuff at the end of the file and automatically | 62 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index f7b18e157d35..9bef9413cb5d 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -20,127 +20,6 @@ | |||
20 | #include "sigio.h" | 20 | #include "sigio.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | 22 | ||
23 | /* Changed during early boot */ | ||
24 | int pty_output_sigio = 0; | ||
25 | int pty_close_sigio = 0; | ||
26 | |||
27 | /* Used as a flag during SIGIO testing early in boot */ | ||
28 | static volatile int got_sigio = 0; | ||
29 | |||
30 | void __init handler(int sig) | ||
31 | { | ||
32 | got_sigio = 1; | ||
33 | } | ||
34 | |||
35 | struct openpty_arg { | ||
36 | int master; | ||
37 | int slave; | ||
38 | int err; | ||
39 | }; | ||
40 | |||
41 | static void openpty_cb(void *arg) | ||
42 | { | ||
43 | struct openpty_arg *info = arg; | ||
44 | |||
45 | info->err = 0; | ||
46 | if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) | ||
47 | info->err = -errno; | ||
48 | } | ||
49 | |||
50 | void __init check_one_sigio(void (*proc)(int, int)) | ||
51 | { | ||
52 | struct sigaction old, new; | ||
53 | struct openpty_arg pty = { .master = -1, .slave = -1 }; | ||
54 | int master, slave, err; | ||
55 | |||
56 | initial_thread_cb(openpty_cb, &pty); | ||
57 | if(pty.err){ | ||
58 | printk("openpty failed, errno = %d\n", -pty.err); | ||
59 | return; | ||
60 | } | ||
61 | |||
62 | master = pty.master; | ||
63 | slave = pty.slave; | ||
64 | |||
65 | if((master == -1) || (slave == -1)){ | ||
66 | printk("openpty failed to allocate a pty\n"); | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | /* Not now, but complain so we now where we failed. */ | ||
71 | err = raw(master); | ||
72 | if (err < 0) | ||
73 | panic("check_sigio : __raw failed, errno = %d\n", -err); | ||
74 | |||
75 | err = os_sigio_async(master, slave); | ||
76 | if(err < 0) | ||
77 | panic("tty_fds : sigio_async failed, err = %d\n", -err); | ||
78 | |||
79 | if(sigaction(SIGIO, NULL, &old) < 0) | ||
80 | panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); | ||
81 | new = old; | ||
82 | new.sa_handler = handler; | ||
83 | if(sigaction(SIGIO, &new, NULL) < 0) | ||
84 | panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); | ||
85 | |||
86 | got_sigio = 0; | ||
87 | (*proc)(master, slave); | ||
88 | |||
89 | os_close_file(master); | ||
90 | os_close_file(slave); | ||
91 | |||
92 | if(sigaction(SIGIO, &old, NULL) < 0) | ||
93 | panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); | ||
94 | } | ||
95 | |||
96 | static void tty_output(int master, int slave) | ||
97 | { | ||
98 | int n; | ||
99 | char buf[512]; | ||
100 | |||
101 | printk("Checking that host ptys support output SIGIO..."); | ||
102 | |||
103 | memset(buf, 0, sizeof(buf)); | ||
104 | |||
105 | while(os_write_file(master, buf, sizeof(buf)) > 0) ; | ||
106 | if(errno != EAGAIN) | ||
107 | panic("check_sigio : write failed, errno = %d\n", errno); | ||
108 | while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; | ||
109 | |||
110 | if (got_sigio) { | ||
111 | printk("Yes\n"); | ||
112 | pty_output_sigio = 1; | ||
113 | } else if (n == -EAGAIN) { | ||
114 | printk("No, enabling workaround\n"); | ||
115 | } else { | ||
116 | panic("check_sigio : read failed, err = %d\n", n); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void tty_close(int master, int slave) | ||
121 | { | ||
122 | printk("Checking that host ptys support SIGIO on close..."); | ||
123 | |||
124 | os_close_file(slave); | ||
125 | if(got_sigio){ | ||
126 | printk("Yes\n"); | ||
127 | pty_close_sigio = 1; | ||
128 | } | ||
129 | else printk("No, enabling workaround\n"); | ||
130 | } | ||
131 | |||
132 | void __init check_sigio(void) | ||
133 | { | ||
134 | if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && | ||
135 | (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ | ||
136 | printk("No pseudo-terminals available - skipping pty SIGIO " | ||
137 | "check\n"); | ||
138 | return; | ||
139 | } | ||
140 | check_one_sigio(tty_output); | ||
141 | check_one_sigio(tty_close); | ||
142 | } | ||
143 | |||
144 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an | 23 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an |
145 | * exitcall. | 24 | * exitcall. |
146 | */ | 25 | */ |
@@ -267,10 +146,10 @@ static void update_thread(void) | |||
267 | if(write_sigio_pid != -1) | 146 | if(write_sigio_pid != -1) |
268 | os_kill_process(write_sigio_pid, 1); | 147 | os_kill_process(write_sigio_pid, 1); |
269 | write_sigio_pid = -1; | 148 | write_sigio_pid = -1; |
270 | os_close_file(sigio_private[0]); | 149 | close(sigio_private[0]); |
271 | os_close_file(sigio_private[1]); | 150 | close(sigio_private[1]); |
272 | os_close_file(write_sigio_fds[0]); | 151 | close(write_sigio_fds[0]); |
273 | os_close_file(write_sigio_fds[1]); | 152 | close(write_sigio_fds[1]); |
274 | /* Critical section end */ | 153 | /* Critical section end */ |
275 | set_signals(flags); | 154 | set_signals(flags); |
276 | } | 155 | } |
@@ -428,39 +307,18 @@ void write_sigio_workaround(void) | |||
428 | out_free: | 307 | out_free: |
429 | kfree(p); | 308 | kfree(p); |
430 | out_close2: | 309 | out_close2: |
431 | os_close_file(l_sigio_private[0]); | 310 | close(l_sigio_private[0]); |
432 | os_close_file(l_sigio_private[1]); | 311 | close(l_sigio_private[1]); |
433 | out_close1: | 312 | out_close1: |
434 | os_close_file(l_write_sigio_fds[0]); | 313 | close(l_write_sigio_fds[0]); |
435 | os_close_file(l_write_sigio_fds[1]); | 314 | close(l_write_sigio_fds[1]); |
436 | return; | 315 | return; |
437 | } | 316 | } |
438 | 317 | ||
439 | int read_sigio_fd(int fd) | 318 | void sigio_cleanup(void) |
440 | { | ||
441 | int n; | ||
442 | char c; | ||
443 | |||
444 | n = os_read_file(fd, &c, sizeof(c)); | ||
445 | if(n != sizeof(c)){ | ||
446 | if(n < 0) { | ||
447 | printk("read_sigio_fd - read failed, err = %d\n", -n); | ||
448 | return(n); | ||
449 | } | ||
450 | else { | ||
451 | printk("read_sigio_fd - short read, bytes = %d\n", n); | ||
452 | return(-EIO); | ||
453 | } | ||
454 | } | ||
455 | return(n); | ||
456 | } | ||
457 | |||
458 | static void sigio_cleanup(void) | ||
459 | { | 319 | { |
460 | if (write_sigio_pid != -1) { | 320 | if (write_sigio_pid != -1) { |
461 | os_kill_process(write_sigio_pid, 1); | 321 | os_kill_process(write_sigio_pid, 1); |
462 | write_sigio_pid = -1; | 322 | write_sigio_pid = -1; |
463 | } | 323 | } |
464 | } | 324 | } |
465 | |||
466 | __uml_exitcall(sigio_cleanup); | ||
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 0c5b9dcfbe2e..bb1c87211ac1 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -487,8 +487,7 @@ void __init setup_arch(char **cmdline_p) | |||
487 | void __init check_bugs(void) | 487 | void __init check_bugs(void) |
488 | { | 488 | { |
489 | arch_check_bugs(); | 489 | arch_check_bugs(); |
490 | check_sigio(); | 490 | os_check_bugs(); |
491 | check_devanon(); | ||
492 | } | 491 | } |
493 | 492 | ||
494 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) | 493 | void apply_alternatives(struct alt_instr *start, struct alt_instr *end) |