diff options
Diffstat (limited to 'drivers/tty/vt/vt_ioctl.c')
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 67 |
1 files changed, 49 insertions, 18 deletions
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: |