OSDN Git Service

printk: Move console matching logic into a separate function
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Thu, 13 Feb 2020 09:51:31 +0000 (10:51 +0100)
committerPetr Mladek <pmladek@suse.com>
Tue, 18 Feb 2020 08:33:48 +0000 (09:33 +0100)
This moves the loop that tries to match a newly registered console
with the command line or add_preferred_console list into a separate
helper, in order to be able to call it multiple times in subsequent
patches.

Link: https://lore.kernel.org/r/20200213095133.23176-2-pmladek@suse.com
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Petr Mladek <pmladek@suse.com>
kernel/printk/printk.c

index fada22d..0ebcdf5 100644 (file)
@@ -280,6 +280,7 @@ static struct console *exclusive_console;
 static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
 
 static int preferred_console = -1;
+static bool has_preferred_console;
 int console_set_on_cmdline;
 EXPORT_SYMBOL(console_set_on_cmdline);
 
@@ -2627,6 +2628,60 @@ static int __init keep_bootcon_setup(char *str)
 early_param("keep_bootcon", keep_bootcon_setup);
 
 /*
+ * This is called by register_console() to try to match
+ * the newly registered console with any of the ones selected
+ * by either the command line or add_preferred_console() and
+ * setup/enable it.
+ *
+ * Care need to be taken with consoles that are statically
+ * enabled such as netconsole
+ */
+static int try_enable_new_console(struct console *newcon)
+{
+       struct console_cmdline *c;
+       int i;
+
+       for (i = 0, c = console_cmdline;
+            i < MAX_CMDLINECONSOLES && c->name[0];
+            i++, c++) {
+               if (!newcon->match ||
+                   newcon->match(newcon, c->name, c->index, c->options) != 0) {
+                       /* default matching */
+                       BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
+                       if (strcmp(c->name, newcon->name) != 0)
+                               continue;
+                       if (newcon->index >= 0 &&
+                           newcon->index != c->index)
+                               continue;
+                       if (newcon->index < 0)
+                               newcon->index = c->index;
+
+                       if (_braille_register_console(newcon, c))
+                               return 0;
+
+                       if (newcon->setup &&
+                           newcon->setup(newcon, c->options) != 0)
+                               return -EIO;
+               }
+               newcon->flags |= CON_ENABLED;
+               if (i == preferred_console) {
+                       newcon->flags |= CON_CONSDEV;
+                       has_preferred_console = true;
+               }
+               return 0;
+       }
+
+       /*
+        * Some consoles, such as pstore and netconsole, can be enabled even
+        * without matching.
+        */
+       if (newcon->flags & CON_ENABLED)
+               return 0;
+
+       return -ENOENT;
+}
+
+/*
  * The console driver calls this routine during kernel initialization
  * to register the console printing procedure with printk() and to
  * print any messages that were printed by the kernel before the
@@ -2647,11 +2702,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
  */
 void register_console(struct console *newcon)
 {
-       int i;
        unsigned long flags;
        struct console *bcon = NULL;
-       struct console_cmdline *c;
-       static bool has_preferred;
+       int err;
 
        if (console_drivers)
                for_each_console(bcon)
@@ -2678,15 +2731,15 @@ void register_console(struct console *newcon)
        if (console_drivers && console_drivers->flags & CON_BOOT)
                bcon = console_drivers;
 
-       if (!has_preferred || bcon || !console_drivers)
-               has_preferred = preferred_console >= 0;
+       if (!has_preferred_console || bcon || !console_drivers)
+               has_preferred_console = preferred_console >= 0;
 
        /*
         *      See if we want to use this console driver. If we
         *      didn't select a console we take the first one
         *      that registers here.
         */
-       if (!has_preferred) {
+       if (!has_preferred_console) {
                if (newcon->index < 0)
                        newcon->index = 0;
                if (newcon->setup == NULL ||
@@ -2694,47 +2747,19 @@ void register_console(struct console *newcon)
                        newcon->flags |= CON_ENABLED;
                        if (newcon->device) {
                                newcon->flags |= CON_CONSDEV;
-                               has_preferred = true;
+                               has_preferred_console = true;
                        }
                }
        }
 
        /*
-        *      See if this console matches one we selected on
-        *      the command line.
+        * See if this console matches one we selected on
+        * the command line or if it was statically enabled
         */
-       for (i = 0, c = console_cmdline;
-            i < MAX_CMDLINECONSOLES && c->name[0];
-            i++, c++) {
-               if (!newcon->match ||
-                   newcon->match(newcon, c->name, c->index, c->options) != 0) {
-                       /* default matching */
-                       BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
-                       if (strcmp(c->name, newcon->name) != 0)
-                               continue;
-                       if (newcon->index >= 0 &&
-                           newcon->index != c->index)
-                               continue;
-                       if (newcon->index < 0)
-                               newcon->index = c->index;
-
-                       if (_braille_register_console(newcon, c))
-                               return;
-
-                       if (newcon->setup &&
-                           newcon->setup(newcon, c->options) != 0)
-                               break;
-               }
-
-               newcon->flags |= CON_ENABLED;
-               if (i == preferred_console) {
-                       newcon->flags |= CON_CONSDEV;
-                       has_preferred = true;
-               }
-               break;
-       }
+       err = try_enable_new_console(newcon);
 
-       if (!(newcon->flags & CON_ENABLED))
+       /* printk() messages are not printed to the Braille console. */
+       if (err || newcon->flags & CON_BRL)
                return;
 
        /*