aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c134
1 files changed, 97 insertions, 37 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b3915b7ad3e..e41288a0003 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3016,7 +3016,7 @@ int __init vty_init(const struct file_operations *console_fops)
3016 3016
3017static struct class *vtconsole_class; 3017static struct class *vtconsole_class;
3018 3018
3019static int bind_con_driver(const struct consw *csw, int first, int last, 3019static int do_bind_con_driver(const struct consw *csw, int first, int last,
3020 int deflt) 3020 int deflt)
3021{ 3021{
3022 struct module *owner = csw->owner; 3022 struct module *owner = csw->owner;
@@ -3027,7 +3027,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
3027 if (!try_module_get(owner)) 3027 if (!try_module_get(owner))
3028 return -ENODEV; 3028 return -ENODEV;
3029 3029
3030 console_lock(); 3030 WARN_CONSOLE_UNLOCKED();
3031 3031
3032 /* check if driver is registered */ 3032 /* check if driver is registered */
3033 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3033 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3112,11 +3112,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
3112 3112
3113 retval = 0; 3113 retval = 0;
3114err: 3114err:
3115 console_unlock();
3116 module_put(owner); 3115 module_put(owner);
3117 return retval; 3116 return retval;
3118}; 3117};
3119 3118
3119
3120static int bind_con_driver(const struct consw *csw, int first, int last,
3121 int deflt)
3122{
3123 int ret;
3124
3125 console_lock();
3126 ret = do_bind_con_driver(csw, first, last, deflt);
3127 console_unlock();
3128 return ret;
3129}
3130
3120#ifdef CONFIG_VT_HW_CONSOLE_BINDING 3131#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3121static int con_is_graphics(const struct consw *csw, int first, int last) 3132static int con_is_graphics(const struct consw *csw, int first, int last)
3122{ 3133{
@@ -3153,6 +3164,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
3153 */ 3164 */
3154int unbind_con_driver(const struct consw *csw, int first, int last, int deflt) 3165int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3155{ 3166{
3167 int retval;
3168
3169 console_lock();
3170 retval = do_unbind_con_driver(csw, first, last, deflt);
3171 console_unlock();
3172 return retval;
3173}
3174EXPORT_SYMBOL(unbind_con_driver);
3175
3176/* unlocked version of unbind_con_driver() */
3177int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3178{
3156 struct module *owner = csw->owner; 3179 struct module *owner = csw->owner;
3157 const struct consw *defcsw = NULL; 3180 const struct consw *defcsw = NULL;
3158 struct con_driver *con_driver = NULL, *con_back = NULL; 3181 struct con_driver *con_driver = NULL, *con_back = NULL;
@@ -3161,7 +3184,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3161 if (!try_module_get(owner)) 3184 if (!try_module_get(owner))
3162 return -ENODEV; 3185 return -ENODEV;
3163 3186
3164 console_lock(); 3187 WARN_CONSOLE_UNLOCKED();
3165 3188
3166 /* check if driver is registered and if it is unbindable */ 3189 /* check if driver is registered and if it is unbindable */
3167 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3190 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
@@ -3174,10 +3197,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3174 } 3197 }
3175 } 3198 }
3176 3199
3177 if (retval) { 3200 if (retval)
3178 console_unlock();
3179 goto err; 3201 goto err;
3180 }
3181 3202
3182 retval = -ENODEV; 3203 retval = -ENODEV;
3183 3204
@@ -3193,15 +3214,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3193 } 3214 }
3194 } 3215 }
3195 3216
3196 if (retval) { 3217 if (retval)
3197 console_unlock();
3198 goto err; 3218 goto err;
3199 }
3200 3219
3201 if (!con_is_bound(csw)) { 3220 if (!con_is_bound(csw))
3202 console_unlock();
3203 goto err; 3221 goto err;
3204 }
3205 3222
3206 first = max(first, con_driver->first); 3223 first = max(first, con_driver->first);
3207 last = min(last, con_driver->last); 3224 last = min(last, con_driver->last);
@@ -3228,15 +3245,14 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3228 if (!con_is_bound(csw)) 3245 if (!con_is_bound(csw))
3229 con_driver->flag &= ~CON_DRIVER_FLAG_INIT; 3246 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3230 3247
3231 console_unlock();
3232 /* ignore return value, binding should not fail */ 3248 /* ignore return value, binding should not fail */
3233 bind_con_driver(defcsw, first, last, deflt); 3249 do_bind_con_driver(defcsw, first, last, deflt);
3234err: 3250err:
3235 module_put(owner); 3251 module_put(owner);
3236 return retval; 3252 return retval;
3237 3253
3238} 3254}
3239EXPORT_SYMBOL(unbind_con_driver); 3255EXPORT_SYMBOL_GPL(do_unbind_con_driver);
3240 3256
3241static int vt_bind(struct con_driver *con) 3257static int vt_bind(struct con_driver *con)
3242{ 3258{
@@ -3508,28 +3524,18 @@ int con_debug_leave(void)
3508} 3524}
3509EXPORT_SYMBOL_GPL(con_debug_leave); 3525EXPORT_SYMBOL_GPL(con_debug_leave);
3510 3526
3511/** 3527static int do_register_con_driver(const struct consw *csw, int first, int last)
3512 * register_con_driver - register console driver to console layer
3513 * @csw: console driver
3514 * @first: the first console to take over, minimum value is 0
3515 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3516 *
3517 * DESCRIPTION: This function registers a console driver which can later
3518 * bind to a range of consoles specified by @first and @last. It will
3519 * also initialize the console driver by calling con_startup().
3520 */
3521int register_con_driver(const struct consw *csw, int first, int last)
3522{ 3528{
3523 struct module *owner = csw->owner; 3529 struct module *owner = csw->owner;
3524 struct con_driver *con_driver; 3530 struct con_driver *con_driver;
3525 const char *desc; 3531 const char *desc;
3526 int i, retval = 0; 3532 int i, retval = 0;
3527 3533
3534 WARN_CONSOLE_UNLOCKED();
3535
3528 if (!try_module_get(owner)) 3536 if (!try_module_get(owner))
3529 return -ENODEV; 3537 return -ENODEV;
3530 3538
3531 console_lock();
3532
3533 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3539 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3534 con_driver = &registered_con_driver[i]; 3540 con_driver = &registered_con_driver[i];
3535 3541
@@ -3582,10 +3588,29 @@ int register_con_driver(const struct consw *csw, int first, int last)
3582 } 3588 }
3583 3589
3584err: 3590err:
3585 console_unlock();
3586 module_put(owner); 3591 module_put(owner);
3587 return retval; 3592 return retval;
3588} 3593}
3594
3595/**
3596 * register_con_driver - register console driver to console layer
3597 * @csw: console driver
3598 * @first: the first console to take over, minimum value is 0
3599 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3600 *
3601 * DESCRIPTION: This function registers a console driver which can later
3602 * bind to a range of consoles specified by @first and @last. It will
3603 * also initialize the console driver by calling con_startup().
3604 */
3605int register_con_driver(const struct consw *csw, int first, int last)
3606{
3607 int retval;
3608
3609 console_lock();
3610 retval = do_register_con_driver(csw, first, last);
3611 console_unlock();
3612 return retval;
3613}
3589EXPORT_SYMBOL(register_con_driver); 3614EXPORT_SYMBOL(register_con_driver);
3590 3615
3591/** 3616/**
@@ -3601,9 +3626,18 @@ EXPORT_SYMBOL(register_con_driver);
3601 */ 3626 */
3602int unregister_con_driver(const struct consw *csw) 3627int unregister_con_driver(const struct consw *csw)
3603{ 3628{
3604 int i, retval = -ENODEV; 3629 int retval;
3605 3630
3606 console_lock(); 3631 console_lock();
3632 retval = do_unregister_con_driver(csw);
3633 console_unlock();
3634 return retval;
3635}
3636EXPORT_SYMBOL(unregister_con_driver);
3637
3638int do_unregister_con_driver(const struct consw *csw)
3639{
3640 int i, retval = -ENODEV;
3607 3641
3608 /* cannot unregister a bound driver */ 3642 /* cannot unregister a bound driver */
3609 if (con_is_bound(csw)) 3643 if (con_is_bound(csw))
@@ -3629,27 +3663,53 @@ int unregister_con_driver(const struct consw *csw)
3629 } 3663 }
3630 } 3664 }
3631err: 3665err:
3632 console_unlock();
3633 return retval; 3666 return retval;
3634} 3667}
3635EXPORT_SYMBOL(unregister_con_driver); 3668EXPORT_SYMBOL_GPL(do_unregister_con_driver);
3636 3669
3637/* 3670/*
3638 * If we support more console drivers, this function is used 3671 * If we support more console drivers, this function is used
3639 * when a driver wants to take over some existing consoles 3672 * when a driver wants to take over some existing consoles
3640 * and become default driver for newly opened ones. 3673 * and become default driver for newly opened ones.
3641 * 3674 *
3642 * take_over_console is basically a register followed by unbind 3675 * take_over_console is basically a register followed by unbind
3676 */
3677int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
3678{
3679 int err;
3680
3681 err = do_register_con_driver(csw, first, last);
3682 /*
3683 * If we get an busy error we still want to bind the console driver
3684 * and return success, as we may have unbound the console driver
3685 * but not unregistered it.
3686 */
3687 if (err == -EBUSY)
3688 err = 0;
3689 if (!err)
3690 do_bind_con_driver(csw, first, last, deflt);
3691
3692 return err;
3693}
3694EXPORT_SYMBOL_GPL(do_take_over_console);
3695
3696/*
3697 * If we support more console drivers, this function is used
3698 * when a driver wants to take over some existing consoles
3699 * and become default driver for newly opened ones.
3700 *
3701 * take_over_console is basically a register followed by unbind
3643 */ 3702 */
3644int take_over_console(const struct consw *csw, int first, int last, int deflt) 3703int take_over_console(const struct consw *csw, int first, int last, int deflt)
3645{ 3704{
3646 int err; 3705 int err;
3647 3706
3648 err = register_con_driver(csw, first, last); 3707 err = register_con_driver(csw, first, last);
3649 /* if we get an busy error we still want to bind the console driver 3708 /*
3709 * If we get an busy error we still want to bind the console driver
3650 * and return success, as we may have unbound the console driver 3710 * and return success, as we may have unbound the console driver
3651  * but not unregistered it. 3711 * but not unregistered it.
3652 */ 3712 */
3653 if (err == -EBUSY) 3713 if (err == -EBUSY)
3654 err = 0; 3714 err = 0;
3655 if (!err) 3715 if (!err)