|
@@ -3134,6 +3134,18 @@ static int con_is_graphics(const struct consw *csw, int first, int last)
|
|
|
* or 0 on success.
|
|
|
*/
|
|
|
int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
+{
|
|
|
+ int retval;
|
|
|
+
|
|
|
+ console_lock();
|
|
|
+ retval = do_unbind_con_driver(csw, first, last, deflt);
|
|
|
+ console_unlock();
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(unbind_con_driver);
|
|
|
+
|
|
|
+/* unlocked version of unbind_con_driver() */
|
|
|
+int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
{
|
|
|
struct module *owner = csw->owner;
|
|
|
const struct consw *defcsw = NULL;
|
|
@@ -3143,7 +3155,7 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
if (!try_module_get(owner))
|
|
|
return -ENODEV;
|
|
|
|
|
|
- console_lock();
|
|
|
+ WARN_CONSOLE_UNLOCKED();
|
|
|
|
|
|
/* check if driver is registered and if it is unbindable */
|
|
|
for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
|
|
@@ -3156,10 +3168,8 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (retval) {
|
|
|
- console_unlock();
|
|
|
+ if (retval)
|
|
|
goto err;
|
|
|
- }
|
|
|
|
|
|
retval = -ENODEV;
|
|
|
|
|
@@ -3175,15 +3185,11 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (retval) {
|
|
|
- console_unlock();
|
|
|
+ if (retval)
|
|
|
goto err;
|
|
|
- }
|
|
|
|
|
|
- if (!con_is_bound(csw)) {
|
|
|
- console_unlock();
|
|
|
+ if (!con_is_bound(csw))
|
|
|
goto err;
|
|
|
- }
|
|
|
|
|
|
first = max(first, con_driver->first);
|
|
|
last = min(last, con_driver->last);
|
|
@@ -3212,13 +3218,12 @@ int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
|
|
|
|
|
|
/* ignore return value, binding should not fail */
|
|
|
do_bind_con_driver(defcsw, first, last, deflt);
|
|
|
- console_unlock();
|
|
|
err:
|
|
|
module_put(owner);
|
|
|
return retval;
|
|
|
|
|
|
}
|
|
|
-EXPORT_SYMBOL(unbind_con_driver);
|
|
|
+EXPORT_SYMBOL_GPL(do_unbind_con_driver);
|
|
|
|
|
|
static int vt_bind(struct con_driver *con)
|
|
|
{
|
|
@@ -3605,9 +3610,18 @@ EXPORT_SYMBOL(register_con_driver);
|
|
|
*/
|
|
|
int unregister_con_driver(const struct consw *csw)
|
|
|
{
|
|
|
- int i, retval = -ENODEV;
|
|
|
+ int retval;
|
|
|
|
|
|
console_lock();
|
|
|
+ retval = do_unregister_con_driver(csw);
|
|
|
+ console_unlock();
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(unregister_con_driver);
|
|
|
+
|
|
|
+int do_unregister_con_driver(const struct consw *csw)
|
|
|
+{
|
|
|
+ int i, retval = -ENODEV;
|
|
|
|
|
|
/* cannot unregister a bound driver */
|
|
|
if (con_is_bound(csw))
|
|
@@ -3633,10 +3647,9 @@ int unregister_con_driver(const struct consw *csw)
|
|
|
}
|
|
|
}
|
|
|
err:
|
|
|
- console_unlock();
|
|
|
return retval;
|
|
|
}
|
|
|
-EXPORT_SYMBOL(unregister_con_driver);
|
|
|
+EXPORT_SYMBOL_GPL(do_unregister_con_driver);
|
|
|
|
|
|
/*
|
|
|
* If we support more console drivers, this function is used
|