@@ -2429,28 +2429,34 @@ static void set_user_specified(struct console_cmdline *c, bool user_specified)
2429
2429
console_set_on_cmdline = 1 ;
2430
2430
}
2431
2431
2432
- static int __add_preferred_console (const char * name , const short idx , char * options ,
2432
+ static int __add_preferred_console (const char * name , const short idx ,
2433
+ const char * devname , char * options ,
2433
2434
char * brl_options , bool user_specified )
2434
2435
{
2435
2436
struct console_cmdline * c ;
2436
2437
int i ;
2437
2438
2439
+ if (!name && !devname )
2440
+ return - EINVAL ;
2441
+
2438
2442
/*
2439
2443
* We use a signed short index for struct console for device drivers to
2440
2444
* indicate a not yet assigned index or port. However, a negative index
2441
- * value is not valid for preferred console.
2445
+ * value is not valid when the console name and index are defined on
2446
+ * the command line.
2442
2447
*/
2443
- if (idx < 0 )
2448
+ if (name && idx < 0 )
2444
2449
return - EINVAL ;
2445
2450
2446
2451
/*
2447
2452
* See if this tty is not yet registered, and
2448
2453
* if we have a slot free.
2449
2454
*/
2450
2455
for (i = 0 , c = console_cmdline ;
2451
- i < MAX_CMDLINECONSOLES && c -> name [0 ];
2456
+ i < MAX_CMDLINECONSOLES && ( c -> name [0 ] || c -> devname [ 0 ]) ;
2452
2457
i ++ , c ++ ) {
2453
- if (strcmp (c -> name , name ) == 0 && c -> index == idx ) {
2458
+ if ((name && strcmp (c -> name , name ) == 0 && c -> index == idx ) ||
2459
+ (devname && strcmp (c -> devname , devname ) == 0 )) {
2454
2460
if (!brl_options )
2455
2461
preferred_console = i ;
2456
2462
set_user_specified (c , user_specified );
@@ -2461,7 +2467,10 @@ static int __add_preferred_console(const char *name, const short idx, char *opti
2461
2467
return - E2BIG ;
2462
2468
if (!brl_options )
2463
2469
preferred_console = i ;
2464
- strscpy (c -> name , name , sizeof (c -> name ));
2470
+ if (name )
2471
+ strscpy (c -> name , name );
2472
+ if (devname )
2473
+ strscpy (c -> devname , devname );
2465
2474
c -> options = options ;
2466
2475
set_user_specified (c , user_specified );
2467
2476
braille_set_options (c , brl_options );
@@ -2486,8 +2495,13 @@ __setup("console_msg_format=", console_msg_format_setup);
2486
2495
*/
2487
2496
static int __init console_setup (char * str )
2488
2497
{
2489
- char buf [sizeof (console_cmdline [0 ].name ) + 4 ]; /* 4 for "ttyS" */
2490
- char * s , * options , * brl_options = NULL ;
2498
+ static_assert (sizeof (console_cmdline [0 ].devname ) >= sizeof (console_cmdline [0 ].name ) + 4 );
2499
+ char buf [sizeof (console_cmdline [0 ].devname )];
2500
+ char * brl_options = NULL ;
2501
+ char * ttyname = NULL ;
2502
+ char * devname = NULL ;
2503
+ char * options ;
2504
+ char * s ;
2491
2505
int idx ;
2492
2506
2493
2507
/*
@@ -2496,17 +2510,23 @@ static int __init console_setup(char *str)
2496
2510
* for exactly this purpose.
2497
2511
*/
2498
2512
if (str [0 ] == 0 || strcmp (str , "null" ) == 0 ) {
2499
- __add_preferred_console ("ttynull" , 0 , NULL , NULL , true);
2513
+ __add_preferred_console ("ttynull" , 0 , NULL , NULL , NULL , true);
2500
2514
return 1 ;
2501
2515
}
2502
2516
2503
2517
if (_braille_console_setup (& str , & brl_options ))
2504
2518
return 1 ;
2505
2519
2520
+ /* For a DEVNAME:0.0 style console the character device is unknown early */
2521
+ if (strchr (str , ':' ))
2522
+ devname = buf ;
2523
+ else
2524
+ ttyname = buf ;
2525
+
2506
2526
/*
2507
2527
* Decode str into name, index, options.
2508
2528
*/
2509
- if (isdigit (str [0 ]))
2529
+ if (ttyname && isdigit (str [0 ]))
2510
2530
scnprintf (buf , sizeof (buf ), "ttyS%s" , str );
2511
2531
else
2512
2532
strscpy (buf , str );
@@ -2523,12 +2543,18 @@ static int __init console_setup(char *str)
2523
2543
#endif
2524
2544
2525
2545
for (s = buf ; * s ; s ++ )
2526
- if (isdigit (* s ) || * s == ',' )
2546
+ if (( ttyname && isdigit (* s ) ) || * s == ',' )
2527
2547
break ;
2528
- idx = simple_strtoul (s , NULL , 10 );
2548
+
2549
+ /* @idx will get defined when devname matches. */
2550
+ if (devname )
2551
+ idx = -1 ;
2552
+ else
2553
+ idx = simple_strtoul (s , NULL , 10 );
2554
+
2529
2555
* s = 0 ;
2530
2556
2531
- __add_preferred_console (buf , idx , options , brl_options , true);
2557
+ __add_preferred_console (ttyname , idx , devname , options , brl_options , true);
2532
2558
return 1 ;
2533
2559
}
2534
2560
__setup ("console=" , console_setup );
@@ -2548,7 +2574,51 @@ __setup("console=", console_setup);
2548
2574
*/
2549
2575
int add_preferred_console (const char * name , const short idx , char * options )
2550
2576
{
2551
- return __add_preferred_console (name , idx , options , NULL , false);
2577
+ return __add_preferred_console (name , idx , NULL , options , NULL , false);
2578
+ }
2579
+
2580
+ /**
2581
+ * match_devname_and_update_preferred_console - Update a preferred console
2582
+ * when matching devname is found.
2583
+ * @devname: DEVNAME:0.0 style device name
2584
+ * @name: Name of the corresponding console driver, e.g. "ttyS"
2585
+ * @idx: Console index, e.g. port number.
2586
+ *
2587
+ * The function checks whether a device with the given @devname is
2588
+ * preferred via the console=DEVNAME:0.0 command line option.
2589
+ * It fills the missing console driver name and console index
2590
+ * so that a later register_console() call could find (match)
2591
+ * and enable this device.
2592
+ *
2593
+ * It might be used when a driver subsystem initializes particular
2594
+ * devices with already known DEVNAME:0.0 style names. And it
2595
+ * could predict which console driver name and index this device
2596
+ * would later get associated with.
2597
+ *
2598
+ * Return: 0 on success, negative error code on failure.
2599
+ */
2600
+ int match_devname_and_update_preferred_console (const char * devname ,
2601
+ const char * name ,
2602
+ const short idx )
2603
+ {
2604
+ struct console_cmdline * c = console_cmdline ;
2605
+ int i ;
2606
+
2607
+ if (!devname || !strlen (devname ) || !name || !strlen (name ) || idx < 0 )
2608
+ return - EINVAL ;
2609
+
2610
+ for (i = 0 ; i < MAX_CMDLINECONSOLES && (c -> name [0 ] || c -> devname [0 ]);
2611
+ i ++ , c ++ ) {
2612
+ if (!strcmp (devname , c -> devname )) {
2613
+ pr_info ("associate the preferred console \"%s\" with \"%s%d\"\n" ,
2614
+ devname , name , idx );
2615
+ strscpy (c -> name , name );
2616
+ c -> index = idx ;
2617
+ return 0 ;
2618
+ }
2619
+ }
2620
+
2621
+ return - ENOENT ;
2552
2622
}
2553
2623
2554
2624
bool console_suspend_enabled = true;
@@ -3318,8 +3388,11 @@ static int try_enable_preferred_console(struct console *newcon,
3318
3388
int i , err ;
3319
3389
3320
3390
for (i = 0 , c = console_cmdline ;
3321
- i < MAX_CMDLINECONSOLES && c -> name [0 ];
3391
+ i < MAX_CMDLINECONSOLES && ( c -> name [0 ] || c -> devname [ 0 ]) ;
3322
3392
i ++ , c ++ ) {
3393
+ /* Console not yet initialized? */
3394
+ if (!c -> name [0 ])
3395
+ continue ;
3323
3396
if (c -> user_specified != user_specified )
3324
3397
continue ;
3325
3398
if (!newcon -> match ||
0 commit comments