diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/os-Linux/irq.c | 27 | ||||
-rw-r--r-- | arch/um/os-Linux/sigio.c | 241 |
2 files changed, 150 insertions, 118 deletions
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index a26e0662aa12..430866ca1ce4 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c | |||
@@ -1,22 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <unistd.h> | ||
8 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <poll.h> | ||
9 | #include <signal.h> | 9 | #include <signal.h> |
10 | #include <string.h> | 10 | #include <string.h> |
11 | #include <sys/poll.h> | ||
12 | #include <sys/types.h> | ||
13 | #include <sys/time.h> | ||
14 | #include "user.h" | ||
15 | #include "process.h" | ||
16 | #include "sigio.h" | ||
17 | #include "irq_user.h" | 11 | #include "irq_user.h" |
12 | #include "kern_constants.h" | ||
18 | #include "os.h" | 13 | #include "os.h" |
14 | #include "process.h" | ||
19 | #include "um_malloc.h" | 15 | #include "um_malloc.h" |
16 | #include "user.h" | ||
20 | 17 | ||
21 | /* | 18 | /* |
22 | * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd | 19 | * Locked by irq_lock in arch/um/kernel/irq.c. Changed by os_create_pollfd |
@@ -35,7 +32,7 @@ int os_waiting_for_events(struct irq_fd *active_fds) | |||
35 | if (n < 0) { | 32 | if (n < 0) { |
36 | err = -errno; | 33 | err = -errno; |
37 | if (errno != EINTR) | 34 | if (errno != EINTR) |
38 | printk("sigio_handler: os_waiting_for_events:" | 35 | printk(UM_KERN_ERR "os_waiting_for_events:" |
39 | " poll returned %d, errno = %d\n", n, errno); | 36 | " poll returned %d, errno = %d\n", n, errno); |
40 | return err; | 37 | return err; |
41 | } | 38 | } |
@@ -94,24 +91,26 @@ void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | |||
94 | struct irq_fd *old_fd = *prev; | 91 | struct irq_fd *old_fd = *prev; |
95 | if ((pollfds[i].fd != -1) && | 92 | if ((pollfds[i].fd != -1) && |
96 | (pollfds[i].fd != (*prev)->fd)) { | 93 | (pollfds[i].fd != (*prev)->fd)) { |
97 | printk("os_free_irq_by_cb - mismatch between " | 94 | printk(UM_KERN_ERR "os_free_irq_by_cb - " |
98 | "active_fds and pollfds, fd %d vs %d\n", | 95 | "mismatch between active_fds and " |
96 | "pollfds, fd %d vs %d\n", | ||
99 | (*prev)->fd, pollfds[i].fd); | 97 | (*prev)->fd, pollfds[i].fd); |
100 | goto out; | 98 | goto out; |
101 | } | 99 | } |
102 | 100 | ||
103 | pollfds_num--; | 101 | pollfds_num--; |
104 | 102 | ||
105 | /* This moves the *whole* array after pollfds[i] | 103 | /* |
104 | * This moves the *whole* array after pollfds[i] | ||
106 | * (though it doesn't spot as such)! | 105 | * (though it doesn't spot as such)! |
107 | */ | 106 | */ |
108 | memmove(&pollfds[i], &pollfds[i + 1], | 107 | memmove(&pollfds[i], &pollfds[i + 1], |
109 | (pollfds_num - i) * sizeof(pollfds[0])); | 108 | (pollfds_num - i) * sizeof(pollfds[0])); |
110 | if(*last_irq_ptr2 == &old_fd->next) | 109 | if (*last_irq_ptr2 == &old_fd->next) |
111 | *last_irq_ptr2 = prev; | 110 | *last_irq_ptr2 = prev; |
112 | 111 | ||
113 | *prev = (*prev)->next; | 112 | *prev = (*prev)->next; |
114 | if(old_fd->type == IRQ_WRITE) | 113 | if (old_fd->type == IRQ_WRITE) |
115 | ignore_sigio_fd(old_fd->fd); | 114 | ignore_sigio_fd(old_fd->fd); |
116 | kfree(old_fd); | 115 | kfree(old_fd); |
117 | continue; | 116 | continue; |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 6443809cfdfb..abf47a7c4abd 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -1,33 +1,33 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <unistd.h> | 6 | #include <unistd.h> |
7 | #include <stdlib.h> | 7 | #include <errno.h> |
8 | #include <termios.h> | 8 | #include <fcntl.h> |
9 | #include <poll.h> | ||
9 | #include <pty.h> | 10 | #include <pty.h> |
11 | #include <sched.h> | ||
10 | #include <signal.h> | 12 | #include <signal.h> |
11 | #include <fcntl.h> | ||
12 | #include <errno.h> | ||
13 | #include <string.h> | 13 | #include <string.h> |
14 | #include <sched.h> | 14 | #include "kern_constants.h" |
15 | #include <sys/socket.h> | ||
16 | #include <sys/poll.h> | ||
17 | #include "init.h" | ||
18 | #include "user.h" | ||
19 | #include "kern_util.h" | 15 | #include "kern_util.h" |
20 | #include "sigio.h" | 16 | #include "init.h" |
21 | #include "os.h" | 17 | #include "os.h" |
18 | #include "sigio.h" | ||
22 | #include "um_malloc.h" | 19 | #include "um_malloc.h" |
20 | #include "user.h" | ||
23 | 21 | ||
24 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an | 22 | /* |
23 | * Protected by sigio_lock(), also used by sigio_cleanup, which is an | ||
25 | * exitcall. | 24 | * exitcall. |
26 | */ | 25 | */ |
27 | static int write_sigio_pid = -1; | 26 | static int write_sigio_pid = -1; |
28 | static unsigned long write_sigio_stack; | 27 | static unsigned long write_sigio_stack; |
29 | 28 | ||
30 | /* These arrays are initialized before the sigio thread is started, and | 29 | /* |
30 | * These arrays are initialized before the sigio thread is started, and | ||
31 | * the descriptors closed after it is killed. So, it can't see them change. | 31 | * the descriptors closed after it is killed. So, it can't see them change. |
32 | * On the UML side, they are changed under the sigio_lock. | 32 | * On the UML side, they are changed under the sigio_lock. |
33 | */ | 33 | */ |
@@ -42,7 +42,8 @@ struct pollfds { | |||
42 | int used; | 42 | int used; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | /* Protected by sigio_lock(). Used by the sigio thread, but the UML thread | 45 | /* |
46 | * Protected by sigio_lock(). Used by the sigio thread, but the UML thread | ||
46 | * synchronizes with it. | 47 | * synchronizes with it. |
47 | */ | 48 | */ |
48 | static struct pollfds current_poll; | 49 | static struct pollfds current_poll; |
@@ -56,23 +57,26 @@ static int write_sigio_thread(void *unused) | |||
56 | int i, n, respond_fd; | 57 | int i, n, respond_fd; |
57 | char c; | 58 | char c; |
58 | 59 | ||
59 | signal(SIGWINCH, SIG_IGN); | 60 | signal(SIGWINCH, SIG_IGN); |
60 | fds = ¤t_poll; | 61 | fds = ¤t_poll; |
61 | while(1){ | 62 | while (1) { |
62 | n = poll(fds->poll, fds->used, -1); | 63 | n = poll(fds->poll, fds->used, -1); |
63 | if(n < 0){ | 64 | if (n < 0) { |
64 | if(errno == EINTR) continue; | 65 | if (errno == EINTR) |
65 | printk("write_sigio_thread : poll returned %d, " | 66 | continue; |
66 | "errno = %d\n", n, errno); | 67 | printk(UM_KERN_ERR "write_sigio_thread : poll returned " |
68 | "%d, errno = %d\n", n, errno); | ||
67 | } | 69 | } |
68 | for(i = 0; i < fds->used; i++){ | 70 | for (i = 0; i < fds->used; i++) { |
69 | p = &fds->poll[i]; | 71 | p = &fds->poll[i]; |
70 | if(p->revents == 0) continue; | 72 | if (p->revents == 0) |
71 | if(p->fd == sigio_private[1]){ | 73 | continue; |
74 | if (p->fd == sigio_private[1]) { | ||
72 | CATCH_EINTR(n = read(sigio_private[1], &c, | 75 | CATCH_EINTR(n = read(sigio_private[1], &c, |
73 | sizeof(c))); | 76 | sizeof(c))); |
74 | if(n != sizeof(c)) | 77 | if (n != sizeof(c)) |
75 | printk("write_sigio_thread : " | 78 | printk(UM_KERN_ERR |
79 | "write_sigio_thread : " | ||
76 | "read on socket failed, " | 80 | "read on socket failed, " |
77 | "err = %d\n", errno); | 81 | "err = %d\n", errno); |
78 | tmp = current_poll; | 82 | tmp = current_poll; |
@@ -88,9 +92,10 @@ static int write_sigio_thread(void *unused) | |||
88 | } | 92 | } |
89 | 93 | ||
90 | CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); | 94 | CATCH_EINTR(n = write(respond_fd, &c, sizeof(c))); |
91 | if(n != sizeof(c)) | 95 | if (n != sizeof(c)) |
92 | printk("write_sigio_thread : write on socket " | 96 | printk(UM_KERN_ERR "write_sigio_thread : " |
93 | "failed, err = %d\n", errno); | 97 | "write on socket failed, err = %d\n", |
98 | errno); | ||
94 | } | 99 | } |
95 | } | 100 | } |
96 | 101 | ||
@@ -101,12 +106,13 @@ static int need_poll(struct pollfds *polls, int n) | |||
101 | { | 106 | { |
102 | struct pollfd *new; | 107 | struct pollfd *new; |
103 | 108 | ||
104 | if(n <= polls->size) | 109 | if (n <= polls->size) |
105 | return 0; | 110 | return 0; |
106 | 111 | ||
107 | new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); | 112 | new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC); |
108 | if(new == NULL){ | 113 | if (new == NULL) { |
109 | printk("need_poll : failed to allocate new pollfds\n"); | 114 | printk(UM_KERN_ERR "need_poll : failed to allocate new " |
115 | "pollfds\n"); | ||
110 | return -ENOMEM; | 116 | return -ENOMEM; |
111 | } | 117 | } |
112 | 118 | ||
@@ -118,7 +124,8 @@ static int need_poll(struct pollfds *polls, int n) | |||
118 | return 0; | 124 | return 0; |
119 | } | 125 | } |
120 | 126 | ||
121 | /* Must be called with sigio_lock held, because it's needed by the marked | 127 | /* |
128 | * Must be called with sigio_lock held, because it's needed by the marked | ||
122 | * critical section. | 129 | * critical section. |
123 | */ | 130 | */ |
124 | static void update_thread(void) | 131 | static void update_thread(void) |
@@ -128,15 +135,17 @@ static void update_thread(void) | |||
128 | char c; | 135 | char c; |
129 | 136 | ||
130 | flags = set_signals(0); | 137 | flags = set_signals(0); |
131 | n = write(sigio_private[0], &c, sizeof(c)); | 138 | CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c))); |
132 | if(n != sizeof(c)){ | 139 | if (n != sizeof(c)) { |
133 | printk("update_thread : write failed, err = %d\n", errno); | 140 | printk(UM_KERN_ERR "update_thread : write failed, err = %d\n", |
141 | errno); | ||
134 | goto fail; | 142 | goto fail; |
135 | } | 143 | } |
136 | 144 | ||
137 | CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); | 145 | CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c))); |
138 | if(n != sizeof(c)){ | 146 | if (n != sizeof(c)) { |
139 | printk("update_thread : read failed, err = %d\n", errno); | 147 | printk(UM_KERN_ERR "update_thread : read failed, err = %d\n", |
148 | errno); | ||
140 | goto fail; | 149 | goto fail; |
141 | } | 150 | } |
142 | 151 | ||
@@ -163,23 +172,23 @@ int add_sigio_fd(int fd) | |||
163 | int err = 0, i, n; | 172 | int err = 0, i, n; |
164 | 173 | ||
165 | sigio_lock(); | 174 | sigio_lock(); |
166 | for(i = 0; i < all_sigio_fds.used; i++){ | 175 | for (i = 0; i < all_sigio_fds.used; i++) { |
167 | if(all_sigio_fds.poll[i].fd == fd) | 176 | if (all_sigio_fds.poll[i].fd == fd) |
168 | break; | 177 | break; |
169 | } | 178 | } |
170 | if(i == all_sigio_fds.used) | 179 | if (i == all_sigio_fds.used) |
171 | goto out; | 180 | goto out; |
172 | 181 | ||
173 | p = &all_sigio_fds.poll[i]; | 182 | p = &all_sigio_fds.poll[i]; |
174 | 183 | ||
175 | for(i = 0; i < current_poll.used; i++){ | 184 | for (i = 0; i < current_poll.used; i++) { |
176 | if(current_poll.poll[i].fd == fd) | 185 | if (current_poll.poll[i].fd == fd) |
177 | goto out; | 186 | goto out; |
178 | } | 187 | } |
179 | 188 | ||
180 | n = current_poll.used; | 189 | n = current_poll.used; |
181 | err = need_poll(&next_poll, n + 1); | 190 | err = need_poll(&next_poll, n + 1); |
182 | if(err) | 191 | if (err) |
183 | goto out; | 192 | goto out; |
184 | 193 | ||
185 | memcpy(next_poll.poll, current_poll.poll, | 194 | memcpy(next_poll.poll, current_poll.poll, |
@@ -197,27 +206,29 @@ int ignore_sigio_fd(int fd) | |||
197 | struct pollfd *p; | 206 | struct pollfd *p; |
198 | int err = 0, i, n = 0; | 207 | int err = 0, i, n = 0; |
199 | 208 | ||
200 | /* This is called from exitcalls elsewhere in UML - if | 209 | /* |
210 | * This is called from exitcalls elsewhere in UML - if | ||
201 | * sigio_cleanup has already run, then update_thread will hang | 211 | * sigio_cleanup has already run, then update_thread will hang |
202 | * or fail because the thread is no longer running. | 212 | * or fail because the thread is no longer running. |
203 | */ | 213 | */ |
204 | if(write_sigio_pid == -1) | 214 | if (write_sigio_pid == -1) |
205 | return -EIO; | 215 | return -EIO; |
206 | 216 | ||
207 | sigio_lock(); | 217 | sigio_lock(); |
208 | for(i = 0; i < current_poll.used; i++){ | 218 | for (i = 0; i < current_poll.used; i++) { |
209 | if(current_poll.poll[i].fd == fd) break; | 219 | if (current_poll.poll[i].fd == fd) |
220 | break; | ||
210 | } | 221 | } |
211 | if(i == current_poll.used) | 222 | if (i == current_poll.used) |
212 | goto out; | 223 | goto out; |
213 | 224 | ||
214 | err = need_poll(&next_poll, current_poll.used - 1); | 225 | err = need_poll(&next_poll, current_poll.used - 1); |
215 | if(err) | 226 | if (err) |
216 | goto out; | 227 | goto out; |
217 | 228 | ||
218 | for(i = 0; i < current_poll.used; i++){ | 229 | for (i = 0; i < current_poll.used; i++) { |
219 | p = ¤t_poll.poll[i]; | 230 | p = ¤t_poll.poll[i]; |
220 | if(p->fd != fd) | 231 | if (p->fd != fd) |
221 | next_poll.poll[n++] = *p; | 232 | next_poll.poll[n++] = *p; |
222 | } | 233 | } |
223 | next_poll.used = current_poll.used - 1; | 234 | next_poll.used = current_poll.used - 1; |
@@ -234,7 +245,8 @@ static struct pollfd *setup_initial_poll(int fd) | |||
234 | 245 | ||
235 | p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); | 246 | p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL); |
236 | if (p == NULL) { | 247 | if (p == NULL) { |
237 | printk("setup_initial_poll : failed to allocate poll\n"); | 248 | printk(UM_KERN_ERR "setup_initial_poll : failed to allocate " |
249 | "poll\n"); | ||
238 | return NULL; | 250 | return NULL; |
239 | } | 251 | } |
240 | *p = ((struct pollfd) { .fd = fd, | 252 | *p = ((struct pollfd) { .fd = fd, |
@@ -260,27 +272,29 @@ static void write_sigio_workaround(void) | |||
260 | return; | 272 | return; |
261 | 273 | ||
262 | err = os_pipe(l_write_sigio_fds, 1, 1); | 274 | err = os_pipe(l_write_sigio_fds, 1, 1); |
263 | if(err < 0){ | 275 | if (err < 0) { |
264 | printk("write_sigio_workaround - os_pipe 1 failed, " | 276 | printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 1 failed, " |
265 | "err = %d\n", -err); | 277 | "err = %d\n", -err); |
266 | return; | 278 | return; |
267 | } | 279 | } |
268 | err = os_pipe(l_sigio_private, 1, 1); | 280 | err = os_pipe(l_sigio_private, 1, 1); |
269 | if(err < 0){ | 281 | if (err < 0) { |
270 | printk("write_sigio_workaround - os_pipe 2 failed, " | 282 | printk(UM_KERN_ERR "write_sigio_workaround - os_pipe 2 failed, " |
271 | "err = %d\n", -err); | 283 | "err = %d\n", -err); |
272 | goto out_close1; | 284 | goto out_close1; |
273 | } | 285 | } |
274 | 286 | ||
275 | p = setup_initial_poll(l_sigio_private[1]); | 287 | p = setup_initial_poll(l_sigio_private[1]); |
276 | if(!p) | 288 | if (!p) |
277 | goto out_close2; | 289 | goto out_close2; |
278 | 290 | ||
279 | sigio_lock(); | 291 | sigio_lock(); |
280 | 292 | ||
281 | /* Did we race? Don't try to optimize this, please, it's not so likely | 293 | /* |
282 | * to happen, and no more than once at the boot. */ | 294 | * Did we race? Don't try to optimize this, please, it's not so likely |
283 | if(write_sigio_pid != -1) | 295 | * to happen, and no more than once at the boot. |
296 | */ | ||
297 | if (write_sigio_pid != -1) | ||
284 | goto out_free; | 298 | goto out_free; |
285 | 299 | ||
286 | current_poll = ((struct pollfds) { .poll = p, | 300 | current_poll = ((struct pollfds) { .poll = p, |
@@ -332,19 +346,19 @@ void maybe_sigio_broken(int fd, int read) | |||
332 | { | 346 | { |
333 | int err; | 347 | int err; |
334 | 348 | ||
335 | if(!isatty(fd)) | 349 | if (!isatty(fd)) |
336 | return; | 350 | return; |
337 | 351 | ||
338 | if((read || pty_output_sigio) && (!read || pty_close_sigio)) | 352 | if ((read || pty_output_sigio) && (!read || pty_close_sigio)) |
339 | return; | 353 | return; |
340 | 354 | ||
341 | write_sigio_workaround(); | 355 | write_sigio_workaround(); |
342 | 356 | ||
343 | sigio_lock(); | 357 | sigio_lock(); |
344 | err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); | 358 | err = need_poll(&all_sigio_fds, all_sigio_fds.used + 1); |
345 | if(err){ | 359 | if (err) { |
346 | printk("maybe_sigio_broken - failed to add pollfd for " | 360 | printk(UM_KERN_ERR "maybe_sigio_broken - failed to add pollfd " |
347 | "descriptor %d\n", fd); | 361 | "for descriptor %d\n", fd); |
348 | goto out; | 362 | goto out; |
349 | } | 363 | } |
350 | 364 | ||
@@ -387,7 +401,7 @@ static void openpty_cb(void *arg) | |||
387 | struct openpty_arg *info = arg; | 401 | struct openpty_arg *info = arg; |
388 | 402 | ||
389 | info->err = 0; | 403 | info->err = 0; |
390 | if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) | 404 | if (openpty(&info->master, &info->slave, NULL, NULL, NULL)) |
391 | info->err = -errno; | 405 | info->err = -errno; |
392 | } | 406 | } |
393 | 407 | ||
@@ -396,14 +410,14 @@ static int async_pty(int master, int slave) | |||
396 | int flags; | 410 | int flags; |
397 | 411 | ||
398 | flags = fcntl(master, F_GETFL); | 412 | flags = fcntl(master, F_GETFL); |
399 | if(flags < 0) | 413 | if (flags < 0) |
400 | return -errno; | 414 | return -errno; |
401 | 415 | ||
402 | if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || | 416 | if ((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || |
403 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) | 417 | (fcntl(master, F_SETOWN, os_getpid()) < 0)) |
404 | return -errno; | 418 | return -errno; |
405 | 419 | ||
406 | if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) | 420 | if ((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)) |
407 | return -errno; | 421 | return -errno; |
408 | 422 | ||
409 | return 0; | 423 | return 0; |
@@ -416,34 +430,49 @@ static void __init check_one_sigio(void (*proc)(int, int)) | |||
416 | int master, slave, err; | 430 | int master, slave, err; |
417 | 431 | ||
418 | initial_thread_cb(openpty_cb, &pty); | 432 | initial_thread_cb(openpty_cb, &pty); |
419 | if(pty.err){ | 433 | if (pty.err) { |
420 | printk("openpty failed, errno = %d\n", -pty.err); | 434 | printk(UM_KERN_ERR "check_one_sigio failed, errno = %d\n", |
435 | -pty.err); | ||
421 | return; | 436 | return; |
422 | } | 437 | } |
423 | 438 | ||
424 | master = pty.master; | 439 | master = pty.master; |
425 | slave = pty.slave; | 440 | slave = pty.slave; |
426 | 441 | ||
427 | if((master == -1) || (slave == -1)){ | 442 | if ((master == -1) || (slave == -1)) { |
428 | printk("openpty failed to allocate a pty\n"); | 443 | printk(UM_KERN_ERR "check_one_sigio failed to allocate a " |
444 | "pty\n"); | ||
429 | return; | 445 | return; |
430 | } | 446 | } |
431 | 447 | ||
432 | /* Not now, but complain so we now where we failed. */ | 448 | /* Not now, but complain so we now where we failed. */ |
433 | err = raw(master); | 449 | err = raw(master); |
434 | if (err < 0) | 450 | if (err < 0) { |
435 | panic("check_sigio : __raw failed, errno = %d\n", -err); | 451 | printk(UM_KERN_ERR "check_one_sigio : raw failed, errno = %d\n", |
452 | -err); | ||
453 | return; | ||
454 | } | ||
436 | 455 | ||
437 | err = async_pty(master, slave); | 456 | err = async_pty(master, slave); |
438 | if(err < 0) | 457 | if (err < 0) { |
439 | panic("tty_fds : sigio_async failed, err = %d\n", -err); | 458 | printk(UM_KERN_ERR "check_one_sigio : sigio_async failed, " |
459 | "err = %d\n", -err); | ||
460 | return; | ||
461 | } | ||
462 | |||
463 | if (sigaction(SIGIO, NULL, &old) < 0) { | ||
464 | printk(UM_KERN_ERR "check_one_sigio : sigaction 1 failed, " | ||
465 | "errno = %d\n", errno); | ||
466 | return; | ||
467 | } | ||
440 | 468 | ||
441 | if(sigaction(SIGIO, NULL, &old) < 0) | ||
442 | panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); | ||
443 | new = old; | 469 | new = old; |
444 | new.sa_handler = handler; | 470 | new.sa_handler = handler; |
445 | if(sigaction(SIGIO, &new, NULL) < 0) | 471 | if (sigaction(SIGIO, &new, NULL) < 0) { |
446 | panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); | 472 | printk(UM_KERN_ERR "check_one_sigio : sigaction 2 failed, " |
473 | "errno = %d\n", errno); | ||
474 | return; | ||
475 | } | ||
447 | 476 | ||
448 | got_sigio = 0; | 477 | got_sigio = 0; |
449 | (*proc)(master, slave); | 478 | (*proc)(master, slave); |
@@ -451,8 +480,9 @@ static void __init check_one_sigio(void (*proc)(int, int)) | |||
451 | close(master); | 480 | close(master); |
452 | close(slave); | 481 | close(slave); |
453 | 482 | ||
454 | if(sigaction(SIGIO, &old, NULL) < 0) | 483 | if (sigaction(SIGIO, &old, NULL) < 0) |
455 | panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); | 484 | printk(UM_KERN_ERR "check_one_sigio : sigaction 3 failed, " |
485 | "errno = %d\n", errno); | ||
456 | } | 486 | } |
457 | 487 | ||
458 | static void tty_output(int master, int slave) | 488 | static void tty_output(int master, int slave) |
@@ -460,42 +490,45 @@ static void tty_output(int master, int slave) | |||
460 | int n; | 490 | int n; |
461 | char buf[512]; | 491 | char buf[512]; |
462 | 492 | ||
463 | printk("Checking that host ptys support output SIGIO..."); | 493 | printk(UM_KERN_INFO "Checking that host ptys support output SIGIO..."); |
464 | 494 | ||
465 | memset(buf, 0, sizeof(buf)); | 495 | memset(buf, 0, sizeof(buf)); |
466 | 496 | ||
467 | while(write(master, buf, sizeof(buf)) > 0) ; | 497 | while (write(master, buf, sizeof(buf)) > 0) ; |
468 | if(errno != EAGAIN) | 498 | if (errno != EAGAIN) |
469 | panic("tty_output : write failed, errno = %d\n", errno); | 499 | printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n", |
470 | while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; | 500 | errno); |
501 | while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) | ||
502 | ; | ||
471 | 503 | ||
472 | if(got_sigio){ | 504 | if (got_sigio) { |
473 | printk("Yes\n"); | 505 | printk(UM_KERN_CONT "Yes\n"); |
474 | pty_output_sigio = 1; | 506 | pty_output_sigio = 1; |
475 | } | 507 | } else if (n == -EAGAIN) |
476 | else if(n == -EAGAIN) | 508 | printk(UM_KERN_CONT "No, enabling workaround\n"); |
477 | printk("No, enabling workaround\n"); | 509 | else |
478 | else panic("tty_output : read failed, err = %d\n", n); | 510 | printk(UM_KERN_CONT "tty_output : read failed, err = %d\n", n); |
479 | } | 511 | } |
480 | 512 | ||
481 | static void tty_close(int master, int slave) | 513 | static void tty_close(int master, int slave) |
482 | { | 514 | { |
483 | printk("Checking that host ptys support SIGIO on close..."); | 515 | printk(UM_KERN_INFO "Checking that host ptys support SIGIO on " |
516 | "close..."); | ||
484 | 517 | ||
485 | close(slave); | 518 | close(slave); |
486 | if(got_sigio){ | 519 | if (got_sigio) { |
487 | printk("Yes\n"); | 520 | printk(UM_KERN_CONT "Yes\n"); |
488 | pty_close_sigio = 1; | 521 | pty_close_sigio = 1; |
489 | } | 522 | } else |
490 | else printk("No, enabling workaround\n"); | 523 | printk(UM_KERN_CONT "No, enabling workaround\n"); |
491 | } | 524 | } |
492 | 525 | ||
493 | void __init check_sigio(void) | 526 | void __init check_sigio(void) |
494 | { | 527 | { |
495 | if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && | 528 | if ((access("/dev/ptmx", R_OK) < 0) && |
496 | (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ | 529 | (access("/dev/ptyp0", R_OK) < 0)) { |
497 | printk("No pseudo-terminals available - skipping pty SIGIO " | 530 | printk(UM_KERN_WARNING "No pseudo-terminals available - " |
498 | "check\n"); | 531 | "skipping pty SIGIO check\n"); |
499 | return; | 532 | return; |
500 | } | 533 | } |
501 | check_one_sigio(tty_output); | 534 | check_one_sigio(tty_output); |