@ -2987,7 +2987,7 @@ int __init vty_init(const struct file_operations *console_fops)
static struct class * vtconsole_class ;
static int bind_con_driver ( const struct consw * csw , int first , int last ,
static int do_ bind_con_driver( const struct consw * csw , int first , int last ,
int deflt )
{
struct module * owner = csw - > owner ;
@ -2998,7 +2998,7 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
if ( ! try_module_get ( owner ) )
return - ENODEV ;
console_lock ( ) ;
WARN_CONSOLE_UNLOCKED ( ) ;
/* check if driver is registered */
for ( i = 0 ; i < MAX_NR_CON_DRIVER ; i + + ) {
@ -3083,11 +3083,22 @@ static int bind_con_driver(const struct consw *csw, int first, int last,
retval = 0 ;
err :
console_unlock ( ) ;
module_put ( owner ) ;
return retval ;
} ;
static int bind_con_driver ( const struct consw * csw , int first , int last ,
int deflt )
{
int ret ;
console_lock ( ) ;
ret = do_bind_con_driver ( csw , first , last , deflt ) ;
console_unlock ( ) ;
return ret ;
}
# ifdef CONFIG_VT_HW_CONSOLE_BINDING
static int con_is_graphics ( const struct consw * csw , int first , int last )
{
@ -3199,9 +3210,9 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
if ( ! con_is_bound ( csw ) )
con_driver - > flag & = ~ CON_DRIVER_FLAG_INIT ;
console_unlock ( ) ;
/* ignore return value, binding should not fail */
bind_con_driver ( defcsw , first , last , deflt ) ;
do_bind_con_driver ( defcsw , first , last , deflt ) ;
console_unlock ( ) ;
err :
module_put ( owner ) ;
return retval ;
@ -3492,28 +3503,18 @@ int con_debug_leave(void)
}
EXPORT_SYMBOL_GPL ( con_debug_leave ) ;
/**
* register_con_driver - register console driver to console layer
* @ csw : console driver
* @ first : the first console to take over , minimum value is 0
* @ last : the last console to take over , maximum value is MAX_NR_CONSOLES - 1
*
* DESCRIPTION : This function registers a console driver which can later
* bind to a range of consoles specified by @ first and @ last . It will
* also initialize the console driver by calling con_startup ( ) .
*/
int register_con_driver ( const struct consw * csw , int first , int last )
static int do_register_con_driver ( const struct consw * csw , int first , int last )
{
struct module * owner = csw - > owner ;
struct con_driver * con_driver ;
const char * desc ;
int i , retval = 0 ;
WARN_CONSOLE_UNLOCKED ( ) ;
if ( ! try_module_get ( owner ) )
return - ENODEV ;
console_lock ( ) ;
for ( i = 0 ; i < MAX_NR_CON_DRIVER ; i + + ) {
con_driver = & registered_con_driver [ i ] ;
@ -3566,10 +3567,29 @@ int register_con_driver(const struct consw *csw, int first, int last)
}
err :
console_unlock ( ) ;
module_put ( owner ) ;
return retval ;
}
/**
* register_con_driver - register console driver to console layer
* @ csw : console driver
* @ first : the first console to take over , minimum value is 0
* @ last : the last console to take over , maximum value is MAX_NR_CONSOLES - 1
*
* DESCRIPTION : This function registers a console driver which can later
* bind to a range of consoles specified by @ first and @ last . It will
* also initialize the console driver by calling con_startup ( ) .
*/
int register_con_driver ( const struct consw * csw , int first , int last )
{
int retval ;
console_lock ( ) ;
retval = do_register_con_driver ( csw , first , last ) ;
console_unlock ( ) ;
return retval ;
}
EXPORT_SYMBOL ( register_con_driver ) ;
/**
@ -3623,17 +3643,44 @@ EXPORT_SYMBOL(unregister_con_driver);
* when a driver wants to take over some existing consoles
* and become default driver for newly opened ones .
*
* take_over_console is basically a register followed by unbind
* take_over_console is basically a register followed by unbind
*/
int do_take_over_console ( const struct consw * csw , int first , int last , int deflt )
{
int err ;
err = do_register_con_driver ( csw , first , last ) ;
/*
* If we get an busy error we still want to bind the console driver
* and return success , as we may have unbound the console driver
* but not unregistered it .
*/
if ( err = = - EBUSY )
err = 0 ;
if ( ! err )
do_bind_con_driver ( csw , first , last , deflt ) ;
return err ;
}
EXPORT_SYMBOL_GPL ( do_take_over_console ) ;
/*
* If we support more console drivers , this function is used
* when a driver wants to take over some existing consoles
* and become default driver for newly opened ones .
*
* take_over_console is basically a register followed by unbind
*/
int take_over_console ( const struct consw * csw , int first , int last , int deflt )
{
int err ;
err = register_con_driver ( csw , first , last ) ;
/* if we get an busy error we still want to bind the console driver
/*
* If we get an busy error we still want to bind the console driver
* and return success , as we may have unbound the console driver
* but not unregistered it .
*/
* but not unregistered it .
*/
if ( err = = - EBUSY )
err = 0 ;
if ( ! err )