diff options
Diffstat (limited to 'arch/um/drivers')
-rw-r--r-- | arch/um/drivers/chan_kern.c | 3 | ||||
-rw-r--r-- | arch/um/drivers/cow_user.c | 6 | ||||
-rw-r--r-- | arch/um/drivers/harddog_user.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 64 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 12 | ||||
-rw-r--r-- | arch/um/drivers/net_user.c | 5 | ||||
-rw-r--r-- | arch/um/drivers/slip_user.c | 3 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 31 | ||||
-rw-r--r-- | arch/um/drivers/xterm.c | 1 |
9 files changed, 92 insertions, 35 deletions
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 25e1965df7c..d4191fe1ced 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -543,11 +543,10 @@ int parse_chan_pair(char *str, struct line *line, int device, | |||
543 | const struct chan_opts *opts, char **error_out) | 543 | const struct chan_opts *opts, char **error_out) |
544 | { | 544 | { |
545 | struct list_head *chans = &line->chan_list; | 545 | struct list_head *chans = &line->chan_list; |
546 | struct chan *new, *chan; | 546 | struct chan *new; |
547 | char *in, *out; | 547 | char *in, *out; |
548 | 548 | ||
549 | if (!list_empty(chans)) { | 549 | if (!list_empty(chans)) { |
550 | chan = list_entry(chans->next, struct chan, list); | ||
551 | free_chan(chans, 0); | 550 | free_chan(chans, 0); |
552 | INIT_LIST_HEAD(chans); | 551 | INIT_LIST_HEAD(chans); |
553 | } | 552 | } |
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 93f227a25ba..9cbb426c0b9 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
@@ -186,7 +186,11 @@ static int absolutize(char *to, int size, char *from) | |||
186 | strcat(to, "/"); | 186 | strcat(to, "/"); |
187 | strcat(to, from); | 187 | strcat(to, from); |
188 | } | 188 | } |
189 | chdir(save_cwd); | 189 | if (chdir(save_cwd)) { |
190 | cow_printf("absolutize : Can't cd to '%s' - " | ||
191 | "errno = %d\n", save_cwd, errno); | ||
192 | return -1; | ||
193 | } | ||
190 | return 0; | 194 | return 0; |
191 | } | 195 | } |
192 | 196 | ||
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c index b56f8e0196a..84dce3fc590 100644 --- a/arch/um/drivers/harddog_user.c +++ b/arch/um/drivers/harddog_user.c | |||
@@ -32,7 +32,7 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) | |||
32 | { | 32 | { |
33 | struct dog_data data; | 33 | struct dog_data data; |
34 | int in_fds[2], out_fds[2], pid, n, err; | 34 | int in_fds[2], out_fds[2], pid, n, err; |
35 | char pid_buf[sizeof("nnnnn\0")], c; | 35 | char pid_buf[sizeof("nnnnnnn\0")], c; |
36 | char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; | 36 | char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; |
37 | char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, | 37 | char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, |
38 | NULL }; | 38 | NULL }; |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 35dd0b86401..364c8a15c4c 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -176,10 +176,9 @@ void line_flush_buffer(struct tty_struct *tty) | |||
176 | { | 176 | { |
177 | struct line *line = tty->driver_data; | 177 | struct line *line = tty->driver_data; |
178 | unsigned long flags; | 178 | unsigned long flags; |
179 | int err; | ||
180 | 179 | ||
181 | spin_lock_irqsave(&line->lock, flags); | 180 | spin_lock_irqsave(&line->lock, flags); |
182 | err = flush_buffer(line); | 181 | flush_buffer(line); |
183 | spin_unlock_irqrestore(&line->lock, flags); | 182 | spin_unlock_irqrestore(&line->lock, flags); |
184 | } | 183 | } |
185 | 184 | ||
@@ -400,8 +399,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data) | |||
400 | * is done under a spinlock. Checking whether the device is in use is | 399 | * is done under a spinlock. Checking whether the device is in use is |
401 | * line->tty->count > 1, also under the spinlock. | 400 | * line->tty->count > 1, also under the spinlock. |
402 | * | 401 | * |
403 | * tty->count serves to decide whether the device should be enabled or | 402 | * line->count serves to decide whether the device should be enabled or |
404 | * disabled on the host. If it's equal to 1, then we are doing the | 403 | * disabled on the host. If it's equal to 0, then we are doing the |
405 | * first open or last close. Otherwise, open and close just return. | 404 | * first open or last close. Otherwise, open and close just return. |
406 | */ | 405 | */ |
407 | 406 | ||
@@ -415,16 +414,16 @@ int line_open(struct line *lines, struct tty_struct *tty) | |||
415 | goto out_unlock; | 414 | goto out_unlock; |
416 | 415 | ||
417 | err = 0; | 416 | err = 0; |
418 | if (tty->count > 1) | 417 | if (line->count++) |
419 | goto out_unlock; | 418 | goto out_unlock; |
420 | 419 | ||
421 | spin_unlock(&line->count_lock); | 420 | BUG_ON(tty->driver_data); |
422 | |||
423 | tty->driver_data = line; | 421 | tty->driver_data = line; |
424 | line->tty = tty; | 422 | line->tty = tty; |
425 | 423 | ||
424 | spin_unlock(&line->count_lock); | ||
426 | err = enable_chan(line); | 425 | err = enable_chan(line); |
427 | if (err) | 426 | if (err) /* line_close() will be called by our caller */ |
428 | return err; | 427 | return err; |
429 | 428 | ||
430 | INIT_DELAYED_WORK(&line->task, line_timer_cb); | 429 | INIT_DELAYED_WORK(&line->task, line_timer_cb); |
@@ -437,7 +436,7 @@ int line_open(struct line *lines, struct tty_struct *tty) | |||
437 | chan_window_size(&line->chan_list, &tty->winsize.ws_row, | 436 | chan_window_size(&line->chan_list, &tty->winsize.ws_row, |
438 | &tty->winsize.ws_col); | 437 | &tty->winsize.ws_col); |
439 | 438 | ||
440 | return err; | 439 | return 0; |
441 | 440 | ||
442 | out_unlock: | 441 | out_unlock: |
443 | spin_unlock(&line->count_lock); | 442 | spin_unlock(&line->count_lock); |
@@ -461,17 +460,16 @@ void line_close(struct tty_struct *tty, struct file * filp) | |||
461 | flush_buffer(line); | 460 | flush_buffer(line); |
462 | 461 | ||
463 | spin_lock(&line->count_lock); | 462 | spin_lock(&line->count_lock); |
464 | if (!line->valid) | 463 | BUG_ON(!line->valid); |
465 | goto out_unlock; | ||
466 | 464 | ||
467 | if (tty->count > 1) | 465 | if (--line->count) |
468 | goto out_unlock; | 466 | goto out_unlock; |
469 | 467 | ||
470 | spin_unlock(&line->count_lock); | ||
471 | |||
472 | line->tty = NULL; | 468 | line->tty = NULL; |
473 | tty->driver_data = NULL; | 469 | tty->driver_data = NULL; |
474 | 470 | ||
471 | spin_unlock(&line->count_lock); | ||
472 | |||
475 | if (line->sigio) { | 473 | if (line->sigio) { |
476 | unregister_winch(tty); | 474 | unregister_winch(tty); |
477 | line->sigio = 0; | 475 | line->sigio = 0; |
@@ -499,7 +497,7 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio, | |||
499 | 497 | ||
500 | spin_lock(&line->count_lock); | 498 | spin_lock(&line->count_lock); |
501 | 499 | ||
502 | if (line->tty != NULL) { | 500 | if (line->count) { |
503 | *error_out = "Device is already open"; | 501 | *error_out = "Device is already open"; |
504 | goto out; | 502 | goto out; |
505 | } | 503 | } |
@@ -723,41 +721,53 @@ struct winch { | |||
723 | int pid; | 721 | int pid; |
724 | struct tty_struct *tty; | 722 | struct tty_struct *tty; |
725 | unsigned long stack; | 723 | unsigned long stack; |
724 | struct work_struct work; | ||
726 | }; | 725 | }; |
727 | 726 | ||
728 | static void free_winch(struct winch *winch, int free_irq_ok) | 727 | static void __free_winch(struct work_struct *work) |
729 | { | 728 | { |
730 | if (free_irq_ok) | 729 | struct winch *winch = container_of(work, struct winch, work); |
731 | free_irq(WINCH_IRQ, winch); | 730 | free_irq(WINCH_IRQ, winch); |
732 | |||
733 | list_del(&winch->list); | ||
734 | 731 | ||
735 | if (winch->pid != -1) | 732 | if (winch->pid != -1) |
736 | os_kill_process(winch->pid, 1); | 733 | os_kill_process(winch->pid, 1); |
737 | if (winch->fd != -1) | ||
738 | os_close_file(winch->fd); | ||
739 | if (winch->stack != 0) | 734 | if (winch->stack != 0) |
740 | free_stack(winch->stack, 0); | 735 | free_stack(winch->stack, 0); |
741 | kfree(winch); | 736 | kfree(winch); |
742 | } | 737 | } |
743 | 738 | ||
739 | static void free_winch(struct winch *winch) | ||
740 | { | ||
741 | int fd = winch->fd; | ||
742 | winch->fd = -1; | ||
743 | if (fd != -1) | ||
744 | os_close_file(fd); | ||
745 | list_del(&winch->list); | ||
746 | __free_winch(&winch->work); | ||
747 | } | ||
748 | |||
744 | static irqreturn_t winch_interrupt(int irq, void *data) | 749 | static irqreturn_t winch_interrupt(int irq, void *data) |
745 | { | 750 | { |
746 | struct winch *winch = data; | 751 | struct winch *winch = data; |
747 | struct tty_struct *tty; | 752 | struct tty_struct *tty; |
748 | struct line *line; | 753 | struct line *line; |
754 | int fd = winch->fd; | ||
749 | int err; | 755 | int err; |
750 | char c; | 756 | char c; |
751 | 757 | ||
752 | if (winch->fd != -1) { | 758 | if (fd != -1) { |
753 | err = generic_read(winch->fd, &c, NULL); | 759 | err = generic_read(fd, &c, NULL); |
754 | if (err < 0) { | 760 | if (err < 0) { |
755 | if (err != -EAGAIN) { | 761 | if (err != -EAGAIN) { |
762 | winch->fd = -1; | ||
763 | list_del(&winch->list); | ||
764 | os_close_file(fd); | ||
756 | printk(KERN_ERR "winch_interrupt : " | 765 | printk(KERN_ERR "winch_interrupt : " |
757 | "read failed, errno = %d\n", -err); | 766 | "read failed, errno = %d\n", -err); |
758 | printk(KERN_ERR "fd %d is losing SIGWINCH " | 767 | printk(KERN_ERR "fd %d is losing SIGWINCH " |
759 | "support\n", winch->tty_fd); | 768 | "support\n", winch->tty_fd); |
760 | free_winch(winch, 0); | 769 | INIT_WORK(&winch->work, __free_winch); |
770 | schedule_work(&winch->work); | ||
761 | return IRQ_HANDLED; | 771 | return IRQ_HANDLED; |
762 | } | 772 | } |
763 | goto out; | 773 | goto out; |
@@ -829,7 +839,7 @@ static void unregister_winch(struct tty_struct *tty) | |||
829 | list_for_each_safe(ele, next, &winch_handlers) { | 839 | list_for_each_safe(ele, next, &winch_handlers) { |
830 | winch = list_entry(ele, struct winch, list); | 840 | winch = list_entry(ele, struct winch, list); |
831 | if (winch->tty == tty) { | 841 | if (winch->tty == tty) { |
832 | free_winch(winch, 1); | 842 | free_winch(winch); |
833 | break; | 843 | break; |
834 | } | 844 | } |
835 | } | 845 | } |
@@ -845,7 +855,7 @@ static void winch_cleanup(void) | |||
845 | 855 | ||
846 | list_for_each_safe(ele, next, &winch_handlers) { | 856 | list_for_each_safe(ele, next, &winch_handlers) { |
847 | winch = list_entry(ele, struct winch, list); | 857 | winch = list_entry(ele, struct winch, list); |
848 | free_winch(winch, 1); | 858 | free_winch(winch); |
849 | } | 859 | } |
850 | 860 | ||
851 | spin_unlock(&winch_handler_lock); | 861 | spin_unlock(&winch_handler_lock); |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 47d0c37897d..22745b47c82 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
@@ -262,6 +262,15 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) | |||
262 | return 0; | 262 | return 0; |
263 | } | 263 | } |
264 | 264 | ||
265 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
266 | static void uml_net_poll_controller(struct net_device *dev) | ||
267 | { | ||
268 | disable_irq(dev->irq); | ||
269 | uml_net_interrupt(dev->irq, dev); | ||
270 | enable_irq(dev->irq); | ||
271 | } | ||
272 | #endif | ||
273 | |||
265 | static void uml_net_get_drvinfo(struct net_device *dev, | 274 | static void uml_net_get_drvinfo(struct net_device *dev, |
266 | struct ethtool_drvinfo *info) | 275 | struct ethtool_drvinfo *info) |
267 | { | 276 | { |
@@ -364,6 +373,9 @@ static const struct net_device_ops uml_netdev_ops = { | |||
364 | .ndo_set_mac_address = eth_mac_addr, | 373 | .ndo_set_mac_address = eth_mac_addr, |
365 | .ndo_change_mtu = uml_net_change_mtu, | 374 | .ndo_change_mtu = uml_net_change_mtu, |
366 | .ndo_validate_addr = eth_validate_addr, | 375 | .ndo_validate_addr = eth_validate_addr, |
376 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
377 | .ndo_poll_controller = uml_net_poll_controller, | ||
378 | #endif | ||
367 | }; | 379 | }; |
368 | 380 | ||
369 | /* | 381 | /* |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 9415dd9e63e..520118888f1 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -228,7 +228,10 @@ static void change(char *dev, char *what, unsigned char *addr, | |||
228 | "buffer\n"); | 228 | "buffer\n"); |
229 | 229 | ||
230 | pid = change_tramp(argv, output, output_len); | 230 | pid = change_tramp(argv, output, output_len); |
231 | if (pid < 0) return; | 231 | if (pid < 0) { |
232 | kfree(output); | ||
233 | return; | ||
234 | } | ||
232 | 235 | ||
233 | if (output != NULL) { | 236 | if (output != NULL) { |
234 | printk("%s", output); | 237 | printk("%s", output); |
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index a1c2d2c98a9..cbacfc4e63e 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c | |||
@@ -102,7 +102,7 @@ static int slip_tramp(char **argv, int fd) | |||
102 | "buffer\n"); | 102 | "buffer\n"); |
103 | os_kill_process(pid, 1); | 103 | os_kill_process(pid, 1); |
104 | err = -ENOMEM; | 104 | err = -ENOMEM; |
105 | goto out_free; | 105 | goto out_close; |
106 | } | 106 | } |
107 | 107 | ||
108 | close(fds[1]); | 108 | close(fds[1]); |
@@ -112,7 +112,6 @@ static int slip_tramp(char **argv, int fd) | |||
112 | err = helper_wait(pid); | 112 | err = helper_wait(pid); |
113 | close(fds[0]); | 113 | close(fds[0]); |
114 | 114 | ||
115 | out_free: | ||
116 | kfree(output); | 115 | kfree(output); |
117 | return err; | 116 | return err; |
118 | 117 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 620f5b70957..0491e40d696 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -513,8 +513,37 @@ __uml_exitcall(kill_io_thread); | |||
513 | static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) | 513 | static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) |
514 | { | 514 | { |
515 | char *file; | 515 | char *file; |
516 | int fd; | ||
517 | int err; | ||
518 | |||
519 | __u32 version; | ||
520 | __u32 align; | ||
521 | char *backing_file; | ||
522 | time_t mtime; | ||
523 | unsigned long long size; | ||
524 | int sector_size; | ||
525 | int bitmap_offset; | ||
526 | |||
527 | if (ubd_dev->file && ubd_dev->cow.file) { | ||
528 | file = ubd_dev->cow.file; | ||
529 | |||
530 | goto out; | ||
531 | } | ||
516 | 532 | ||
517 | file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; | 533 | fd = os_open_file(ubd_dev->file, global_openflags, 0); |
534 | if (fd < 0) | ||
535 | return fd; | ||
536 | |||
537 | err = read_cow_header(file_reader, &fd, &version, &backing_file, \ | ||
538 | &mtime, &size, §or_size, &align, &bitmap_offset); | ||
539 | os_close_file(fd); | ||
540 | |||
541 | if(err == -EINVAL) | ||
542 | file = ubd_dev->file; | ||
543 | else | ||
544 | file = backing_file; | ||
545 | |||
546 | out: | ||
518 | return os_file_size(file, size_out); | 547 | return os_file_size(file, size_out); |
519 | } | 548 | } |
520 | 549 | ||
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c index 8ac7146c237..2e1de572860 100644 --- a/arch/um/drivers/xterm.c +++ b/arch/um/drivers/xterm.c | |||
@@ -123,6 +123,7 @@ static int xterm_open(int input, int output, int primary, void *d, | |||
123 | err = -errno; | 123 | err = -errno; |
124 | printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", | 124 | printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n", |
125 | errno); | 125 | errno); |
126 | close(fd); | ||
126 | return err; | 127 | return err; |
127 | } | 128 | } |
128 | close(fd); | 129 | close(fd); |