Commit ad8cd1db authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Petr Mladek
Browse files

printk: Move console matching logic into a separate function

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: default avatarSergey Senozhatsky <sergey.senozhatsky@gmail.com>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
parent a4fe2b4d
Loading
Loading
Loading
Loading
+65 −40
Original line number Diff line number Diff line
@@ -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);

@@ -2626,6 +2627,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
@@ -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.
	 * 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;

	/*