diff options
| -rw-r--r-- | drivers/tty/vt/vt.c | 14 | ||||
| -rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 67 | ||||
| -rw-r--r-- | include/linux/vt_kern.h | 2 |
3 files changed, 56 insertions, 27 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index fbd447b390f7..740202d8a5c4 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
| @@ -779,7 +779,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
| 779 | con_set_default_unimap(vc); | 779 | con_set_default_unimap(vc); |
| 780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); | 780 | vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); |
| 781 | if (!vc->vc_screenbuf) { | 781 | if (!vc->vc_screenbuf) { |
| 782 | tty_port_destroy(&vc->port); | ||
| 783 | kfree(vc); | 782 | kfree(vc); |
| 784 | vc_cons[currcons].d = NULL; | 783 | vc_cons[currcons].d = NULL; |
| 785 | return -ENOMEM; | 784 | return -ENOMEM; |
| @@ -986,26 +985,25 @@ static int vt_resize(struct tty_struct *tty, struct winsize *ws) | |||
| 986 | return ret; | 985 | return ret; |
| 987 | } | 986 | } |
| 988 | 987 | ||
| 989 | void vc_deallocate(unsigned int currcons) | 988 | struct vc_data *vc_deallocate(unsigned int currcons) |
| 990 | { | 989 | { |
| 990 | struct vc_data *vc = NULL; | ||
| 991 | |||
| 991 | WARN_CONSOLE_UNLOCKED(); | 992 | WARN_CONSOLE_UNLOCKED(); |
| 992 | 993 | ||
| 993 | if (vc_cons_allocated(currcons)) { | 994 | if (vc_cons_allocated(currcons)) { |
| 994 | struct vc_data *vc = vc_cons[currcons].d; | 995 | struct vt_notifier_param param; |
| 995 | struct vt_notifier_param param = { .vc = vc }; | ||
| 996 | 996 | ||
| 997 | param.vc = vc = vc_cons[currcons].d; | ||
| 997 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); | 998 | atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); |
| 998 | vcs_remove_sysfs(currcons); | 999 | vcs_remove_sysfs(currcons); |
| 999 | vc->vc_sw->con_deinit(vc); | 1000 | vc->vc_sw->con_deinit(vc); |
| 1000 | put_pid(vc->vt_pid); | 1001 | put_pid(vc->vt_pid); |
| 1001 | module_put(vc->vc_sw->owner); | 1002 | module_put(vc->vc_sw->owner); |
| 1002 | kfree(vc->vc_screenbuf); | 1003 | kfree(vc->vc_screenbuf); |
| 1003 | if (currcons >= MIN_NR_CONSOLES) { | ||
| 1004 | tty_port_destroy(&vc->port); | ||
| 1005 | kfree(vc); | ||
| 1006 | } | ||
| 1007 | vc_cons[currcons].d = NULL; | 1004 | vc_cons[currcons].d = NULL; |
| 1008 | } | 1005 | } |
| 1006 | return vc; | ||
| 1009 | } | 1007 | } |
| 1010 | 1008 | ||
| 1011 | /* | 1009 | /* |
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 98ff1735eafc..fc2c06c66e89 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c | |||
| @@ -283,6 +283,51 @@ do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_ | |||
| 283 | return 0; | 283 | return 0; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | /* deallocate a single console, if possible (leave 0) */ | ||
| 287 | static int vt_disallocate(unsigned int vc_num) | ||
| 288 | { | ||
| 289 | struct vc_data *vc = NULL; | ||
| 290 | int ret = 0; | ||
| 291 | |||
| 292 | if (!vc_num) | ||
| 293 | return 0; | ||
| 294 | |||
| 295 | console_lock(); | ||
| 296 | if (VT_BUSY(vc_num)) | ||
| 297 | ret = -EBUSY; | ||
| 298 | else | ||
| 299 | vc = vc_deallocate(vc_num); | ||
| 300 | console_unlock(); | ||
| 301 | |||
| 302 | if (vc && vc_num >= MIN_NR_CONSOLES) { | ||
| 303 | tty_port_destroy(&vc->port); | ||
| 304 | kfree(vc); | ||
| 305 | } | ||
| 306 | |||
| 307 | return ret; | ||
| 308 | } | ||
| 309 | |||
| 310 | /* deallocate all unused consoles, but leave 0 */ | ||
| 311 | static void vt_disallocate_all(void) | ||
| 312 | { | ||
| 313 | struct vc_data *vc[MAX_NR_CONSOLES]; | ||
| 314 | int i; | ||
| 315 | |||
| 316 | console_lock(); | ||
| 317 | for (i = 1; i < MAX_NR_CONSOLES; i++) | ||
| 318 | if (!VT_BUSY(i)) | ||
| 319 | vc[i] = vc_deallocate(i); | ||
| 320 | else | ||
| 321 | vc[i] = NULL; | ||
| 322 | console_unlock(); | ||
| 323 | |||
| 324 | for (i = 1; i < MAX_NR_CONSOLES; i++) { | ||
| 325 | if (vc[i] && i >= MIN_NR_CONSOLES) { | ||
| 326 | tty_port_destroy(&vc[i]->port); | ||
| 327 | kfree(vc[i]); | ||
| 328 | } | ||
| 329 | } | ||
| 330 | } | ||
| 286 | 331 | ||
| 287 | 332 | ||
| 288 | /* | 333 | /* |
| @@ -769,24 +814,10 @@ int vt_ioctl(struct tty_struct *tty, | |||
| 769 | ret = -ENXIO; | 814 | ret = -ENXIO; |
| 770 | break; | 815 | break; |
| 771 | } | 816 | } |
| 772 | if (arg == 0) { | 817 | if (arg == 0) |
| 773 | /* deallocate all unused consoles, but leave 0 */ | 818 | vt_disallocate_all(); |
| 774 | console_lock(); | 819 | else |
| 775 | for (i=1; i<MAX_NR_CONSOLES; i++) | 820 | ret = vt_disallocate(--arg); |
| 776 | if (! VT_BUSY(i)) | ||
| 777 | vc_deallocate(i); | ||
| 778 | console_unlock(); | ||
| 779 | } else { | ||
| 780 | /* deallocate a single console, if possible */ | ||
| 781 | arg--; | ||
| 782 | if (VT_BUSY(arg)) | ||
| 783 | ret = -EBUSY; | ||
| 784 | else if (arg) { /* leave 0 */ | ||
| 785 | console_lock(); | ||
| 786 | vc_deallocate(arg); | ||
| 787 | console_unlock(); | ||
| 788 | } | ||
| 789 | } | ||
| 790 | break; | 821 | break; |
| 791 | 822 | ||
| 792 | case VT_RESIZE: | 823 | case VT_RESIZE: |
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index e8d65718560b..0d33fca48774 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
| @@ -36,7 +36,7 @@ extern int fg_console, last_console, want_console; | |||
| 36 | int vc_allocate(unsigned int console); | 36 | int vc_allocate(unsigned int console); |
| 37 | int vc_cons_allocated(unsigned int console); | 37 | int vc_cons_allocated(unsigned int console); |
| 38 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); | 38 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); |
| 39 | void vc_deallocate(unsigned int console); | 39 | struct vc_data *vc_deallocate(unsigned int console); |
| 40 | void reset_palette(struct vc_data *vc); | 40 | void reset_palette(struct vc_data *vc); |
| 41 | void do_blank_screen(int entering_gfx); | 41 | void do_blank_screen(int entering_gfx); |
| 42 | void do_unblank_screen(int leaving_gfx); | 42 | void do_unblank_screen(int leaving_gfx); |
