mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
drivers/char: Panic when the requested UART fails to initialise
uart_init() cannot tell its caller that the UART the user asked for did not come up: every failure path only printks. Arm and RISC-V carry on into console_init_preirq() and boot without a console, rather than refusing to boot as they do elsewhere when a user request cannot be met. Return an error from dt_uart_init() and panic in start_xen(). An explicit request Xen cannot satisfy should stop the boot rather than silently degrade it, which is what start_xen() already does for the rest of the boot configuration. Only a path given on the command line counts as a request we have to satisfy. Falling back to /chosen/stdout-path or acpi_uart_init() therefore never fails. SPCR is firmware provided, the analogue of stdout-path, and there is no ACPI equivalent of dtuart= to make an explicit request with. While here, decide whether the SPCR table was found from the returned acpi_status rather than from the table pointer, which was only NULL because the caller initialised it - acpi_get_table() writes it solely on success. Signed-off-by: Michal Orzel <michal.orzel@amd.com> Reviewed-by: Ayan Kumar Halder <ayan.kumar.halder@amd.com>
This commit is contained in:
1 parent
12b136a965
commit
20ee984e1d
4 files changed
+44
-25
No files matched your search
@@ -377,7 +377,10 @@ void asmlinkage __init noreturn start_xen(unsigned long fdt_paddr)
|
|||||||
|
|
||||||
gic_preinit();
|
gic_preinit();
|
||||||
|
|
||||||
uart_init();
|
rc = uart_init();
|
||||||
|
if ( rc )
|
||||||
|
panic("Failed to initialize the requested UART (%d)\n", rc);
|
||||||
|
|
||||||
console_init_preirq();
|
console_init_preirq();
|
||||||
console_init_ring();
|
console_init_ring();
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ void __init noreturn start_xen(unsigned long bootcpu_id,
|
|||||||
{
|
{
|
||||||
const char *cmdline;
|
const char *cmdline;
|
||||||
size_t fdt_size;
|
size_t fdt_size;
|
||||||
|
int rc;
|
||||||
|
|
||||||
remove_identity_mapping();
|
remove_identity_mapping();
|
||||||
|
|
||||||
@@ -149,7 +150,10 @@ void __init noreturn start_xen(unsigned long bootcpu_id,
|
|||||||
|
|
||||||
intc_preinit();
|
intc_preinit();
|
||||||
|
|
||||||
uart_init();
|
rc = uart_init();
|
||||||
|
if ( rc )
|
||||||
|
panic("Failed to initialize the requested UART (%d)\n", rc);
|
||||||
|
|
||||||
console_init_preirq();
|
console_init_preirq();
|
||||||
|
|
||||||
intc_init();
|
intc_init();
|
||||||
|
|||||||
@@ -30,15 +30,17 @@
|
|||||||
static char __initdata opt_dtuart[256] = "";
|
static char __initdata opt_dtuart[256] = "";
|
||||||
string_param("dtuart", opt_dtuart);
|
string_param("dtuart", opt_dtuart);
|
||||||
|
|
||||||
static void __init dt_uart_init(void)
|
static int __init dt_uart_init(void)
|
||||||
{
|
{
|
||||||
struct dt_device_node *dev;
|
struct dt_device_node *dev;
|
||||||
int ret;
|
int ret;
|
||||||
const char *devpath = opt_dtuart;
|
const char *devpath = opt_dtuart;
|
||||||
const char *options;
|
const char *options;
|
||||||
char *split;
|
char *split;
|
||||||
|
/* Set on the command line, as opposed to inherited from /chosen */
|
||||||
|
bool explicit_request = strcmp(opt_dtuart, "") != 0;
|
||||||
|
|
||||||
if ( !strcmp(opt_dtuart, "") )
|
if ( !explicit_request )
|
||||||
{
|
{
|
||||||
const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
|
const struct dt_device_node *chosen = dt_find_node_by_path("/chosen");
|
||||||
|
|
||||||
@@ -62,7 +64,12 @@ static void __init dt_uart_init(void)
|
|||||||
if ( !strcmp(opt_dtuart, "") )
|
if ( !strcmp(opt_dtuart, "") )
|
||||||
{
|
{
|
||||||
printk("No dtuart path configured\n");
|
printk("No dtuart path configured\n");
|
||||||
return;
|
|
||||||
|
/*
|
||||||
|
* console=dtuart is the compiled-in default, so an absent dtuart= is
|
||||||
|
* not a failed user request.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
split = strchr(opt_dtuart, ':');
|
split = strchr(opt_dtuart, ':');
|
||||||
@@ -83,48 +90,49 @@ static void __init dt_uart_init(void)
|
|||||||
if ( !dev )
|
if ( !dev )
|
||||||
{
|
{
|
||||||
printk("Unable to find device \"%s\"\n", devpath);
|
printk("Unable to find device \"%s\"\n", devpath);
|
||||||
return;
|
return explicit_request ? -ENODEV : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = device_init(dev, DEVICE_SERIAL, options);
|
ret = device_init(dev, DEVICE_SERIAL, options);
|
||||||
|
|
||||||
if ( ret )
|
if ( ret )
|
||||||
printk("Unable to initialize dtuart: %d\n", ret);
|
printk("Unable to initialize dtuart: %d\n", ret);
|
||||||
|
|
||||||
|
return explicit_request ? ret : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ACPI
|
#ifdef CONFIG_ACPI
|
||||||
static void __init acpi_uart_init(void)
|
static int __init acpi_uart_init(void)
|
||||||
{
|
{
|
||||||
struct acpi_table_spcr *spcr = NULL;
|
struct acpi_table_spcr *spcr;
|
||||||
|
acpi_status status;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
acpi_get_table(ACPI_SIG_SPCR, 0, (struct acpi_table_header **)&spcr);
|
/* SPCR is firmware provided, so nothing here is a failed user request */
|
||||||
|
status = acpi_get_table(ACPI_SIG_SPCR, 0,
|
||||||
|
(struct acpi_table_header **)&spcr);
|
||||||
|
|
||||||
if ( spcr == NULL )
|
if ( ACPI_FAILURE(status) )
|
||||||
{
|
{
|
||||||
printk("Unable to get spcr table\n");
|
printk("Unable to get spcr table\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ret = acpi_device_init(DEVICE_SERIAL, NULL, spcr->interface_type);
|
|
||||||
|
|
||||||
if ( ret )
|
ret = acpi_device_init(DEVICE_SERIAL, NULL, spcr->interface_type);
|
||||||
printk("Unable to initialize acpi uart: %d\n", ret);
|
if ( ret )
|
||||||
}
|
printk("Unable to initialize acpi uart: %d\n", ret);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void __init acpi_uart_init(void) { }
|
static int __init acpi_uart_init(void) { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void __init uart_init(void)
|
int __init uart_init(void)
|
||||||
{
|
{
|
||||||
if ( !console_has("dtuart") )
|
if ( !console_has("dtuart") )
|
||||||
return; /* Not for us */
|
return 0; /* Not for us */
|
||||||
|
|
||||||
if ( acpi_disabled )
|
return acpi_disabled ? dt_uart_init() : acpi_uart_init();
|
||||||
dt_uart_init();
|
|
||||||
else
|
|
||||||
acpi_uart_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -170,7 +170,11 @@ void xhci_dbc_uart_init(void);
|
|||||||
static void inline xhci_dbc_uart_init(void) {}
|
static void inline xhci_dbc_uart_init(void) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void uart_init(void);
|
/*
|
||||||
|
* Returns 0 unless a UART explicitly requested via dtuart= failed to
|
||||||
|
* initialise.
|
||||||
|
*/
|
||||||
|
int uart_init(void);
|
||||||
|
|
||||||
struct physdev_dbgp_op;
|
struct physdev_dbgp_op;
|
||||||
int dbgp_op(const struct physdev_dbgp_op *op);
|
int dbgp_op(const struct physdev_dbgp_op *op);
|
||||||
|
|||||||