Skip to content

Commit 6a0af9f

Browse files
committed
Merge branch 'for-5.7-preferred-console' into for-linus
2 parents e8cc2b9 + 33225d7 commit 6a0af9f

File tree

3 files changed

+80
-45
lines changed

3 files changed

+80
-45
lines changed

include/linux/console.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static inline int con_debug_leave(void)
135135
*/
136136

137137
#define CON_PRINTBUFFER (1)
138-
#define CON_CONSDEV (2) /* Last on the command line */
138+
#define CON_CONSDEV (2) /* Preferred console, /dev/console */
139139
#define CON_ENABLED (4)
140140
#define CON_BOOT (8)
141141
#define CON_ANYTIME (16) /* Safe to call when cpu is offline */

kernel/printk/console_cmdline.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ struct console_cmdline
66
{
77
char name[16]; /* Name of the driver */
88
int index; /* Minor dev. to use */
9+
bool user_specified; /* Specified by command line vs. platform */
910
char *options; /* Options for the driver */
1011
#ifdef CONFIG_A11Y_BRAILLE_CONSOLE
1112
char *brl_options; /* Options for braille driver */

kernel/printk/printk.c

Lines changed: 78 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ static struct console *exclusive_console;
280280
static struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES];
281281

282282
static int preferred_console = -1;
283+
static bool has_preferred_console;
283284
int console_set_on_cmdline;
284285
EXPORT_SYMBOL(console_set_on_cmdline);
285286

@@ -2115,7 +2116,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
21152116
#endif
21162117

21172118
static int __add_preferred_console(char *name, int idx, char *options,
2118-
char *brl_options)
2119+
char *brl_options, bool user_specified)
21192120
{
21202121
struct console_cmdline *c;
21212122
int i;
@@ -2130,6 +2131,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
21302131
if (strcmp(c->name, name) == 0 && c->index == idx) {
21312132
if (!brl_options)
21322133
preferred_console = i;
2134+
if (user_specified)
2135+
c->user_specified = true;
21332136
return 0;
21342137
}
21352138
}
@@ -2139,6 +2142,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
21392142
preferred_console = i;
21402143
strlcpy(c->name, name, sizeof(c->name));
21412144
c->options = options;
2145+
c->user_specified = user_specified;
21422146
braille_set_options(c, brl_options);
21432147

21442148
c->index = idx;
@@ -2193,7 +2197,7 @@ static int __init console_setup(char *str)
21932197
idx = simple_strtoul(s, NULL, 10);
21942198
*s = 0;
21952199

2196-
__add_preferred_console(buf, idx, options, brl_options);
2200+
__add_preferred_console(buf, idx, options, brl_options, true);
21972201
console_set_on_cmdline = 1;
21982202
return 1;
21992203
}
@@ -2214,7 +2218,7 @@ __setup("console=", console_setup);
22142218
*/
22152219
int add_preferred_console(char *name, int idx, char *options)
22162220
{
2217-
return __add_preferred_console(name, idx, options, NULL);
2221+
return __add_preferred_console(name, idx, options, NULL, false);
22182222
}
22192223

22202224
bool console_suspend_enabled = true;
@@ -2626,6 +2630,63 @@ static int __init keep_bootcon_setup(char *str)
26262630

26272631
early_param("keep_bootcon", keep_bootcon_setup);
26282632

2633+
/*
2634+
* This is called by register_console() to try to match
2635+
* the newly registered console with any of the ones selected
2636+
* by either the command line or add_preferred_console() and
2637+
* setup/enable it.
2638+
*
2639+
* Care need to be taken with consoles that are statically
2640+
* enabled such as netconsole
2641+
*/
2642+
static int try_enable_new_console(struct console *newcon, bool user_specified)
2643+
{
2644+
struct console_cmdline *c;
2645+
int i;
2646+
2647+
for (i = 0, c = console_cmdline;
2648+
i < MAX_CMDLINECONSOLES && c->name[0];
2649+
i++, c++) {
2650+
if (c->user_specified != user_specified)
2651+
continue;
2652+
if (!newcon->match ||
2653+
newcon->match(newcon, c->name, c->index, c->options) != 0) {
2654+
/* default matching */
2655+
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
2656+
if (strcmp(c->name, newcon->name) != 0)
2657+
continue;
2658+
if (newcon->index >= 0 &&
2659+
newcon->index != c->index)
2660+
continue;
2661+
if (newcon->index < 0)
2662+
newcon->index = c->index;
2663+
2664+
if (_braille_register_console(newcon, c))
2665+
return 0;
2666+
2667+
if (newcon->setup &&
2668+
newcon->setup(newcon, c->options) != 0)
2669+
return -EIO;
2670+
}
2671+
newcon->flags |= CON_ENABLED;
2672+
if (i == preferred_console) {
2673+
newcon->flags |= CON_CONSDEV;
2674+
has_preferred_console = true;
2675+
}
2676+
return 0;
2677+
}
2678+
2679+
/*
2680+
* Some consoles, such as pstore and netconsole, can be enabled even
2681+
* without matching. Accept the pre-enabled consoles only when match()
2682+
* and setup() had a change to be called.
2683+
*/
2684+
if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
2685+
return 0;
2686+
2687+
return -ENOENT;
2688+
}
2689+
26292690
/*
26302691
* The console driver calls this routine during kernel initialization
26312692
* to register the console printing procedure with printk() and to
@@ -2647,11 +2708,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
26472708
*/
26482709
void register_console(struct console *newcon)
26492710
{
2650-
int i;
26512711
unsigned long flags;
26522712
struct console *bcon = NULL;
2653-
struct console_cmdline *c;
2654-
static bool has_preferred;
2713+
int err;
26552714

26562715
if (console_drivers)
26572716
for_each_console(bcon)
@@ -2678,63 +2737,36 @@ void register_console(struct console *newcon)
26782737
if (console_drivers && console_drivers->flags & CON_BOOT)
26792738
bcon = console_drivers;
26802739

2681-
if (!has_preferred || bcon || !console_drivers)
2682-
has_preferred = preferred_console >= 0;
2740+
if (!has_preferred_console || bcon || !console_drivers)
2741+
has_preferred_console = preferred_console >= 0;
26832742

26842743
/*
26852744
* See if we want to use this console driver. If we
26862745
* didn't select a console we take the first one
26872746
* that registers here.
26882747
*/
2689-
if (!has_preferred) {
2748+
if (!has_preferred_console) {
26902749
if (newcon->index < 0)
26912750
newcon->index = 0;
26922751
if (newcon->setup == NULL ||
26932752
newcon->setup(newcon, NULL) == 0) {
26942753
newcon->flags |= CON_ENABLED;
26952754
if (newcon->device) {
26962755
newcon->flags |= CON_CONSDEV;
2697-
has_preferred = true;
2756+
has_preferred_console = true;
26982757
}
26992758
}
27002759
}
27012760

2702-
/*
2703-
* See if this console matches one we selected on
2704-
* the command line.
2705-
*/
2706-
for (i = 0, c = console_cmdline;
2707-
i < MAX_CMDLINECONSOLES && c->name[0];
2708-
i++, c++) {
2709-
if (!newcon->match ||
2710-
newcon->match(newcon, c->name, c->index, c->options) != 0) {
2711-
/* default matching */
2712-
BUILD_BUG_ON(sizeof(c->name) != sizeof(newcon->name));
2713-
if (strcmp(c->name, newcon->name) != 0)
2714-
continue;
2715-
if (newcon->index >= 0 &&
2716-
newcon->index != c->index)
2717-
continue;
2718-
if (newcon->index < 0)
2719-
newcon->index = c->index;
2720-
2721-
if (_braille_register_console(newcon, c))
2722-
return;
2723-
2724-
if (newcon->setup &&
2725-
newcon->setup(newcon, c->options) != 0)
2726-
break;
2727-
}
2761+
/* See if this console matches one we selected on the command line */
2762+
err = try_enable_new_console(newcon, true);
27282763

2729-
newcon->flags |= CON_ENABLED;
2730-
if (i == preferred_console) {
2731-
newcon->flags |= CON_CONSDEV;
2732-
has_preferred = true;
2733-
}
2734-
break;
2735-
}
2764+
/* If not, try to match against the platform default(s) */
2765+
if (err == -ENOENT)
2766+
err = try_enable_new_console(newcon, false);
27362767

2737-
if (!(newcon->flags & CON_ENABLED))
2768+
/* printk() messages are not printed to the Braille console. */
2769+
if (err || newcon->flags & CON_BRL)
27382770
return;
27392771

27402772
/*
@@ -2756,6 +2788,8 @@ void register_console(struct console *newcon)
27562788
console_drivers = newcon;
27572789
if (newcon->next)
27582790
newcon->next->flags &= ~CON_CONSDEV;
2791+
/* Ensure this flag is always set for the head of the list */
2792+
newcon->flags |= CON_CONSDEV;
27592793
} else {
27602794
newcon->next = console_drivers->next;
27612795
console_drivers->next = newcon;

0 commit comments

Comments
 (0)