@@ -280,6 +280,7 @@ static struct console *exclusive_console;
280
280
static struct console_cmdline console_cmdline [MAX_CMDLINECONSOLES ];
281
281
282
282
static int preferred_console = -1 ;
283
+ static bool has_preferred_console ;
283
284
int console_set_on_cmdline ;
284
285
EXPORT_SYMBOL (console_set_on_cmdline );
285
286
@@ -2115,7 +2116,7 @@ asmlinkage __visible void early_printk(const char *fmt, ...)
2115
2116
#endif
2116
2117
2117
2118
static int __add_preferred_console (char * name , int idx , char * options ,
2118
- char * brl_options )
2119
+ char * brl_options , bool user_specified )
2119
2120
{
2120
2121
struct console_cmdline * c ;
2121
2122
int i ;
@@ -2130,6 +2131,8 @@ static int __add_preferred_console(char *name, int idx, char *options,
2130
2131
if (strcmp (c -> name , name ) == 0 && c -> index == idx ) {
2131
2132
if (!brl_options )
2132
2133
preferred_console = i ;
2134
+ if (user_specified )
2135
+ c -> user_specified = true;
2133
2136
return 0 ;
2134
2137
}
2135
2138
}
@@ -2139,6 +2142,7 @@ static int __add_preferred_console(char *name, int idx, char *options,
2139
2142
preferred_console = i ;
2140
2143
strlcpy (c -> name , name , sizeof (c -> name ));
2141
2144
c -> options = options ;
2145
+ c -> user_specified = user_specified ;
2142
2146
braille_set_options (c , brl_options );
2143
2147
2144
2148
c -> index = idx ;
@@ -2193,7 +2197,7 @@ static int __init console_setup(char *str)
2193
2197
idx = simple_strtoul (s , NULL , 10 );
2194
2198
* s = 0 ;
2195
2199
2196
- __add_preferred_console (buf , idx , options , brl_options );
2200
+ __add_preferred_console (buf , idx , options , brl_options , true );
2197
2201
console_set_on_cmdline = 1 ;
2198
2202
return 1 ;
2199
2203
}
@@ -2214,7 +2218,7 @@ __setup("console=", console_setup);
2214
2218
*/
2215
2219
int add_preferred_console (char * name , int idx , char * options )
2216
2220
{
2217
- return __add_preferred_console (name , idx , options , NULL );
2221
+ return __add_preferred_console (name , idx , options , NULL , false );
2218
2222
}
2219
2223
2220
2224
bool console_suspend_enabled = true;
@@ -2626,6 +2630,63 @@ static int __init keep_bootcon_setup(char *str)
2626
2630
2627
2631
early_param ("keep_bootcon" , keep_bootcon_setup );
2628
2632
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
+
2629
2690
/*
2630
2691
* The console driver calls this routine during kernel initialization
2631
2692
* to register the console printing procedure with printk() and to
@@ -2647,11 +2708,9 @@ early_param("keep_bootcon", keep_bootcon_setup);
2647
2708
*/
2648
2709
void register_console (struct console * newcon )
2649
2710
{
2650
- int i ;
2651
2711
unsigned long flags ;
2652
2712
struct console * bcon = NULL ;
2653
- struct console_cmdline * c ;
2654
- static bool has_preferred ;
2713
+ int err ;
2655
2714
2656
2715
if (console_drivers )
2657
2716
for_each_console (bcon )
@@ -2678,63 +2737,36 @@ void register_console(struct console *newcon)
2678
2737
if (console_drivers && console_drivers -> flags & CON_BOOT )
2679
2738
bcon = console_drivers ;
2680
2739
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 ;
2683
2742
2684
2743
/*
2685
2744
* See if we want to use this console driver. If we
2686
2745
* didn't select a console we take the first one
2687
2746
* that registers here.
2688
2747
*/
2689
- if (!has_preferred ) {
2748
+ if (!has_preferred_console ) {
2690
2749
if (newcon -> index < 0 )
2691
2750
newcon -> index = 0 ;
2692
2751
if (newcon -> setup == NULL ||
2693
2752
newcon -> setup (newcon , NULL ) == 0 ) {
2694
2753
newcon -> flags |= CON_ENABLED ;
2695
2754
if (newcon -> device ) {
2696
2755
newcon -> flags |= CON_CONSDEV ;
2697
- has_preferred = true;
2756
+ has_preferred_console = true;
2698
2757
}
2699
2758
}
2700
2759
}
2701
2760
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);
2728
2763
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);
2736
2767
2737
- if (!(newcon -> flags & CON_ENABLED ))
2768
+ /* printk() messages are not printed to the Braille console. */
2769
+ if (err || newcon -> flags & CON_BRL )
2738
2770
return ;
2739
2771
2740
2772
/*
@@ -2756,6 +2788,8 @@ void register_console(struct console *newcon)
2756
2788
console_drivers = newcon ;
2757
2789
if (newcon -> next )
2758
2790
newcon -> next -> flags &= ~CON_CONSDEV ;
2791
+ /* Ensure this flag is always set for the head of the list */
2792
+ newcon -> flags |= CON_CONSDEV ;
2759
2793
} else {
2760
2794
newcon -> next = console_drivers -> next ;
2761
2795
console_drivers -> next = newcon ;
0 commit comments