From 53494dcc73fb0baaabe4337993ece450bb2291e1 Mon Sep 17 00:00:00 2001 From: fengsheng Date: Wed, 29 May 2019 20:15:26 +0800 Subject: [PATCH] sysctl: Miscarriage of Justice sas ras to usb ras. driver inclusion category: feature bugzilla: NA CVE: NA 1 fix bug:Miscarriage of Justice sas ras to usb ras. 2 read reg 0x20107E238 to judge cs or es. Signed-off-by: fengsheng Reviewed-by: linsiwei a Reviewed-by: Yang Yingliang Signed-off-by: Yang Yingliang --- drivers/soc/hisilicon/sysctl/sysctl_drv.c | 92 ++-- drivers/soc/hisilicon/sysctl/sysctl_drv.h | 16 +- .../soc/hisilicon/sysctl/sysctl_local_ras.c | 397 ++++++++++-------- .../soc/hisilicon/sysctl/sysctl_local_ras.h | 15 +- 4 files changed, 296 insertions(+), 224 deletions(-) diff --git a/drivers/soc/hisilicon/sysctl/sysctl_drv.c b/drivers/soc/hisilicon/sysctl/sysctl_drv.c index b2cce6d5b6e8..3d9d26cbc4ab 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_drv.c +++ b/drivers/soc/hisilicon/sysctl/sysctl_drv.c @@ -50,6 +50,10 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define DEBUG +#define SYSCTL_DRIVER_VERSION "1.7.8.0" +/* debug?a1? */ +unsigned int g_sysctrl_debug; + /* sysctrl reg base address */ struct his_hllc_priv { void __iomem *hllc_base[CHIP_ID_NUM_MAX][HLLC_NUM_MAX]; @@ -62,7 +66,7 @@ struct his_hllc_priv { struct his_hllc_priv hip_hllc_priv; -static void his_sysctrl_reg_rd(void __iomem *addr, u32 reg, unsigned int *val) +static void his_sysctrl_reg_rd(const void __iomem *addr, u32 reg, unsigned int *val) { *val = readl(addr + reg); } @@ -72,6 +76,16 @@ static void his_sysctrl_reg_wr(void __iomem *addr, u32 reg, unsigned int val) writel(val, addr + reg); } +int hisi_sysctl_print_debug(u32 print_debug_en) +{ + if (print_debug_en) + g_sysctrl_debug = 0x1; + else + g_sysctrl_debug = 0x0; + + return 0; +} + int his_hllc_init(void) { u32 hllc_num; @@ -81,46 +95,52 @@ int his_hllc_init(void) u32 chip_ver; u64 chip_module_base; void __iomem *chip_ver_addr; - void __iomem *chip_ver_base; - chip_ver_base = ioremap(0xd7d00000, (u64)0x10000); - chip_ver_addr = chip_ver_base + 0x8; + pr_info("[INFO] %s start.\n", __func__); + + chip_ver_addr = ioremap(0x20107E238, (u64)4); + if (!chip_ver_addr) { + pr_err("[ERROR] %s chip_ver_base is error.\n", __func__); + return ERR_FAILED; + } chip_ver = readl(chip_ver_addr); - if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_ES) { + chip_ver = chip_ver>>28; + if (chip_ver == CHIP_VERSION_ES) { + pr_info("[sysctl hllc] chip is es\n"); chip_module_base = HLLC_CHIP_MODULE_ES; - } else if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_CS) { - chip_module_base = HLLC_CHIP_MODULE_CS; } else { - pr_err("%s: chip_ver[%u] is ERR.\n", __func__, chip_ver); - if (chip_ver_base) - iounmap((void *)chip_ver_base); - return ERR_FAILED; + chip_module_base = HLLC_CHIP_MODULE_CS; + pr_info("[sysctl hllc] chip is cs\n"); } + pr_info("[sysctl hllc] chip ver=%x\n", chip_ver); for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) { for (hllc_num = 0; hllc_num < HLLC_NUM_MAX; hllc_num++) { addr = (u64)chip_id * chip_module_base + HLLC0_REG_BASE + (u64)hllc_num * 0x10000; hip_hllc_priv.hllc_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000); - debug_sysctrl_print("hllc_base:%p\n", + debug_sysctrl_print("[DBG] hllc_base: %p.\n", hip_hllc_priv.hllc_base[chip_id][hllc_num]); addr = (u64)chip_id * chip_module_base + PCS0_REG_BASE + (u64)hllc_num * 0x10000; hip_hllc_priv.pcs_base[chip_id][hllc_num] = ioremap(addr, (u64)0x10000); - debug_sysctrl_print("hllc_base:%p\n", - hip_hllc_priv.hllc_base[chip_id][hllc_num]); + debug_sysctrl_print("[DBG] pcs_base: %p.\n", + hip_hllc_priv.pcs_base[chip_id][hllc_num]); } addr = (u64)chip_id * chip_module_base + PA_REG_BASE; hip_hllc_priv.pa_base[chip_id] = ioremap(addr, (u64)0x10000); + debug_sysctrl_print("[DBG] pa_base: %p.\n", + hip_hllc_priv.pa_base[chip_id]); + addr = (u64)chip_id * chip_module_base + PM_REG_BASE; hip_hllc_priv.pm_base[chip_id] = ioremap(addr, (u64)0x10000); - debug_sysctrl_print("pa_base:%p\n", - hip_hllc_priv.pa_base[chip_id]); + debug_sysctrl_print("[DBG] pm_base: %p.\n", + hip_hllc_priv.pm_base[chip_id]); for (ddrc_num = 0; ddrc_num < DDRC_CH_NUM_MAX; ddrc_num++) { addr = (u64)chip_id * chip_module_base + DDRC0_TB_REG_BASE + (u64)ddrc_num * 0x10000; @@ -128,15 +148,15 @@ int his_hllc_init(void) addr = (u64)chip_id * chip_module_base + DDRC0_TA_REG_BASE + (u64)ddrc_num * 0x10000; hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num] = ioremap(addr, (u64)0x10000); - debug_sysctrl_print("ddrc_tb_base:%p\n", + debug_sysctrl_print("[DBG] ddrc_tb_base: %p.\n", hip_hllc_priv.ddrc_tb_base[chip_id][ddrc_num]); - debug_sysctrl_print("ddrc_ta_base:%p\n", + debug_sysctrl_print("[DBG] ddrc_ta_base: %p.\n", hip_hllc_priv.ddrc_ta_base[chip_id][ddrc_num]); } } - iounmap((void *)chip_ver_base); + iounmap((void *)chip_ver_addr); return ERR_OK; } @@ -926,9 +946,8 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu static void __iomem *base; if (CHIP_ID_NUM_MAX <= chip_id - || 0x4 < data_len - || 0x0 == data_len) { - pr_err("[sysctl pmbus]write chip_id range[0x0-0x3] or data_len range[0x1-0x4] is err!\n"); + || 0x4 < data_len) { + pr_err("[sysctl pmbus]write chip_id range[0x0-0x3] or data_len range[0x0-0x4] is err!\n"); return ERR_PARAM; } @@ -937,15 +956,16 @@ int sysctl_pmbus_write(u8 chip_id, u8 addr, u32 slave_addr, u32 data_len, u32 bu his_sysctrl_reg_wr(base, I2C_INTR_RAW_OFFSET, 0x3ffff); his_sysctrl_reg_wr(base, 0x0810, (2 << 8) | slave_addr); - his_sysctrl_reg_wr(base, 0x0810, addr); - - for (i = 0; i < data_len - 1; i++) { - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0xff & (buf >> (i*8))); - } + if (data_len != 0) { + his_sysctrl_reg_wr(base, 0x0810, addr); - i++; + for (i = 0; i < data_len - 1; i++) + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, 0xff & (buf >> (i*8))); - his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (4 << 8) | (0xff & (buf >> (i*8)))); + his_sysctrl_reg_wr(base, I2C_DATA_CMD_OFFSET, (4 << 8) | (0xff & (buf >> (i*8)))); + } else { + his_sysctrl_reg_wr(base, 0x0810, (4 << 8) | addr); + } /*poll untill send done*/ for (;;) { @@ -1234,7 +1254,7 @@ int hip_sysctrl_probe(void) ret = his_hllc_init(); if (ret != ERR_OK) { - pr_err("sysctrl init fail, ret:[0x%x]\n", ret); + pr_err("[ERROR] his_hllc_init fail, ret:[0x%x].\n", ret); return ret; } @@ -1248,7 +1268,7 @@ int hip_sysctrl_remove(void) ret = his_hllc_deinit(); if (ret != ERR_OK) { - pr_err("sysctrl deinit fail, ret:[0x%x]\n", ret); + pr_err("[ERROR] his hllc deinit fail, ret:[0x%x].\n", ret); return ret; } @@ -1263,7 +1283,7 @@ static int __init his_sysctrl_init(void) (void)hip_sysctl_local_ras_init(); - pr_info("insmod sysctrl success\n"); + pr_info("[INFO] insmod sysctrl success.\n"); return ret; } @@ -1274,7 +1294,7 @@ static void __exit his_sysctrl_exit(void) (void)hip_sysctl_local_ras_exit(); - pr_info("rmmod sysctrl success\n"); + pr_info("[INFO] rmmod sysctrl success.\n"); return; } @@ -1292,11 +1312,15 @@ EXPORT_SYMBOL(hip_sysctrl_remove); EXPORT_SYMBOL(sysctl_cpu_voltage_read); EXPORT_SYMBOL(hi_vrd_info_get); EXPORT_SYMBOL(sysctl_cpu_voltage_adjust); +EXPORT_SYMBOL(sysctl_pmbus_write); +EXPORT_SYMBOL(sysctl_pmbus_read); +EXPORT_SYMBOL(InitPmbus); +EXPORT_SYMBOL(DeInitPmbus); module_init(his_sysctrl_init); module_exit(his_sysctrl_exit); MODULE_DESCRIPTION("sysctrl for hisillicon platform"); -MODULE_VERSION("1.02"); +MODULE_VERSION(SYSCTL_DRIVER_VERSION); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:hip-sysctl"); diff --git a/drivers/soc/hisilicon/sysctl/sysctl_drv.h b/drivers/soc/hisilicon/sysctl/sysctl_drv.h index 5892f34ca804..8e2de6474054 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_drv.h +++ b/drivers/soc/hisilicon/sysctl/sysctl_drv.h @@ -76,9 +76,7 @@ #define HLLC_INTLV_MODE_3P1 0x5 #define HLLC_INTLV_MODE_3P2 0x6 -#define CHIP_VERSION_MASK (0xff) -#define CHIP_VERSION_ES (0x20) -#define CHIP_VERSION_CS (0x21) +#define CHIP_VERSION_ES (0x1) #define HLLC_CHIP_MODULE_ES (0x400000000000) #define HLLC_CHIP_MODULE_CS (0x200000000000) #define HLLC_NUM_MAX (0x3) @@ -152,13 +150,13 @@ #define STATUS_RPT_OFFSET 0x0AA4 #define STATUS_ERR_RPT_OFFSET 0x0AA8 -#define SYSCTL_DEBUG_LEVEL 0 +extern unsigned int g_sysctrl_debug; -#if (SYSCTL_DEBUG_LEVEL == 0) -#define debug_sysctrl_print(fmt...) -#else -#define debug_sysctrl_print(fmt...) printk(fmt) -#endif +#define debug_sysctrl_print(fmt...) \ +do { \ + if (g_sysctrl_debug) \ + printk(fmt); \ +} while (0) typedef struct { unsigned char hllc_enable; diff --git a/drivers/soc/hisilicon/sysctl/sysctl_local_ras.c b/drivers/soc/hisilicon/sysctl/sysctl_local_ras.c index 8a71c42b46fe..b1cbfad96a69 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_local_ras.c +++ b/drivers/soc/hisilicon/sysctl/sysctl_local_ras.c @@ -41,7 +41,7 @@ static LIST_HEAD(hisi_ghes_list); static DEFINE_MUTEX(hisi_ghes_mutex); -#define GHES_ESTATUS_MAX_SIZE 65536 +#define HISI_GHES_ESTATUS_MAX_SIZE 65536 /* Platform Memory */ #define CPER_SEC_PLATFORM_sysctl_LOCAL_RAS \ @@ -69,37 +69,39 @@ static int sysctl_lpc_init(void) u32 chip_ver; u64 chip_module_base; void __iomem *chip_ver_addr; - void __iomem *chip_ver_base; - chip_ver_base = ioremap(0xd7d00000, (u64)0x10000); - if (!chip_ver_base) { - pr_err("%s: chip_ver_base is error.\n", __func__); + pr_info("[INFO] %s start.\n", __func__); + + chip_ver_addr = ioremap(0x20107E238, (u64)4); + if (!chip_ver_addr) { + pr_err("[ERROR] %s chip_ver_base is error.\n", __func__); return ERR_FAILED; } - chip_ver_addr = chip_ver_base + 0x8; chip_ver = readl(chip_ver_addr); - if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_ES) { + chip_ver = chip_ver>>28; + if (chip_ver == CHIP_VERSION_ES) { + pr_info("[sysctl lpc] chip is es\n"); chip_module_base = HLLC_CHIP_MODULE_ES; - } else if ((chip_ver & CHIP_VERSION_MASK) == CHIP_VERSION_CS) { - chip_module_base = HLLC_CHIP_MODULE_CS; } else { - pr_err("%s: chip_ver[%u] is ERR.\n", __func__, chip_ver); - iounmap((void *)chip_ver_base); - return ERR_FAILED; + chip_module_base = HLLC_CHIP_MODULE_CS; + pr_info("[sysctl lpc] chip is cs\n"); } + pr_info("[sysctl lpc] chip ver=%x\n", chip_ver); for (chip_id = 0; chip_id < CHIP_ID_NUM_MAX; chip_id++) { addr = (u64)chip_id * chip_module_base + SUBCTRL_REG_BASE; sysctl_subctrl_lpc_priv[chip_id] = ioremap(addr, (u64)0x10000); - debug_sysctrl_print("subctl lpc_reset addr:%p\n", sysctl_subctrl_lpc_priv[chip_id]); + debug_sysctrl_print("[DBG] subctl lpc reset addr of chip[%d]: %p.\n", + chip_id, sysctl_subctrl_lpc_priv[chip_id]); lpc_addr = (u64)chip_id * chip_module_base + LPC_REG_BASE; sysctl_lpc_priv[chip_id] = ioremap(lpc_addr, (u64)0x10000); - debug_sysctrl_print("lpc mem access ctrl addr:%p\n", sysctl_lpc_priv[chip_id]); + debug_sysctrl_print("[DBG] lpc mem access ctrl addr of chip[%d]: %p.\n", + chip_id, sysctl_lpc_priv[chip_id]); } - iounmap((void *)chip_ver_base); + iounmap((void *)chip_ver_addr); return ERR_OK; } @@ -143,6 +145,9 @@ static int sysctl_lpc_mem_access_open(u8 chip_id) { void __iomem *addr; + if (!sysctl_lpc_priv[chip_id]) + return ERR_PARAM; + addr = sysctl_lpc_priv[chip_id] + LPC_MEM_ACCESS_OFFSET; writel(0x0, addr); @@ -167,40 +172,55 @@ static int sysctl_correlation_reg_report(const struct sysctl_local_ras_cper *ras { switch (ras_cper->module_id) { case MODULE_LPC_ERR: - pr_err("SYSCTL RAS lpc correlation_reg info"); + pr_info("[INFO] SYSCTL RAS lpc correlation_reg info:\n"); break; - - case MODULE_USB2_ERR: - pr_err("SYSCTL RAS usb2 correlation_reg info"); + case MODULE_USB_ERR: + if (ras_cper->sub_mod_id == MODULE_USB0_ERR) { + pr_info("[INFO] SYSCTL RAS usb0 correlation_reg info:\n"); + } else if (ras_cper->sub_mod_id == MODULE_USB1_ERR) { + pr_info("[INFO] SYSCTL RAS usb1 correlation_reg info:\n"); + } else if (ras_cper->sub_mod_id == MODULE_USB2_ERR) { + pr_info("[INFO] SYSCTL RAS usb2 correlation_reg info:\n"); + } else { + pr_err("[ERROR] SYSCTL RAS usb sub_module_id[0x%x] is error.\n", + ras_cper->sub_mod_id); + return -1; + } break; - - case MODULE_USB3_ERR: - pr_err("SYSCTL RAS usb3 correlation_reg info"); + case MODULE_SAS_ERR: + if (ras_cper->sub_mod_id == MODULE_SAS0_ERR) { + pr_info("[INFO] SYSCTL RAS sas0 correlation_reg info:\n"); + } else if (ras_cper->sub_mod_id == MODULE_SAS1_ERR) { + pr_info("[INFO] SYSCTL RAS sas1 correlation_reg info:\n"); + } else { + pr_err("[ERROR] SYSCTL RAS sas sub_module_id[0x%x] is error.\n", + ras_cper->sub_mod_id); + return -1; + } break; - default: - pr_err("SYSCTL RAS module_id[0x%x] correlation_reg info", + pr_err("[ERROR] SYSCTL RAS module_id[0x%x] is error.\n", ras_cper->module_id); return -1; } - pr_err("SYSCTL RAS socket_id %x", + pr_info("[INFO] SYSCTL RAS socket_id: %x.\n", ras_cper->socket_id); - pr_err("SYSCTL RAS nimbus_id %x", + pr_info("[INFO] SYSCTL RAS nimbus_id: %x.\n", ras_cper->nimbus_id); - pr_err("SYSCTL RAS err_misc0 %x", + pr_info("[INFO] SYSCTL RAS err_misc0: %x.\n", ras_cper->err_misc0); - pr_err("SYSCTL RAS err_misc1 %x", + pr_info("[INFO] SYSCTL RAS err_misc1: %x.\n", ras_cper->err_misc1); - pr_err("SYSCTL RAS err_misc2 %x", + pr_info("[INFO] SYSCTL RAS err_misc2: %x.\n", ras_cper->err_misc2); - pr_err("SYSCTL RAS err_misc3 %x", + pr_info("[INFO] SYSCTL RAS err_misc3: %x.\n", ras_cper->err_misc3); - pr_err("SYSCTL RAS err_misc4 %x", + pr_info("[INFO] SYSCTL RAS err_misc4: %x.\n", ras_cper->err_misc4); - pr_err("SYSCTL RAS err_addrl %x", + pr_info("[INFO] SYSCTL RAS err_addrl: %x.\n", ras_cper->err_addrl); - pr_err("SYSCTL RAS err_addrh %x", + pr_info("[INFO] SYSCTL RAS err_addrh: %x.\n", ras_cper->err_addrh); return 0; @@ -215,33 +235,51 @@ static int sysctl_do_recovery(const struct sysctl_local_ras_cper *ras_cper) sysctl_lpc_irq_cnt++; sysctl_lpc_reset(ras_cper->socket_id); - pr_err("SYSCTL RAS lpc of chip[%d] reset", ras_cper->socket_id); - pr_err("SYSCTL RAS sysctl_lpc_irq_cnt[%d]", sysctl_lpc_irq_cnt); + pr_info("[INFO] SYSCTL RAS lpc of chip[%d] reset.\n", ras_cper->socket_id); + pr_info("[INFO] SYSCTL RAS sysctl_lpc_irq_cnt[%d].\n", sysctl_lpc_irq_cnt); udelay((unsigned long)20); if (sysctl_lpc_irq_cnt <= LPC_IRQ_CNT_MAX) { sysctl_lpc_unreset(ras_cper->socket_id); - pr_err("SYSCTL RAS lpc of chip[%d] unreset", + pr_info("[INFO] SYSCTL RAS lpc of chip[%d] unreset.\n", ras_cper->socket_id); sysctl_lpc_mem_access_open(ras_cper->socket_id); - pr_err("SYSCTL RAS lpc of chip[%d] mem access open", + pr_info("[INFO] SYSCTL RAS lpc of chip[%d] mem access open.\n", ras_cper->socket_id); } else { - pr_err("SYSCTL RAS lpc of chip[%d] unreset 3 times, which won't unreset", - ras_cper->socket_id); + pr_err("[ERROR] SYSCTL RAS lpc of chip[%d] unreset %d times, won't unreset.\n", + ras_cper->socket_id, LPC_IRQ_CNT_MAX); } break; - case MODULE_USB2_ERR: - pr_err("SYSCTL RAS usb2 err %d", ret); + case MODULE_USB_ERR: + if (ras_cper->sub_mod_id == MODULE_USB0_ERR) { + pr_info("[INFO] SYSCTL RAS usb0 error.\n"); + } else if (ras_cper->sub_mod_id == MODULE_USB1_ERR) { + pr_info("[INFO] SYSCTL RAS usb1 error.\n"); + } else if (ras_cper->sub_mod_id == MODULE_USB2_ERR) { + pr_info("[INFO] SYSCTL RAS usb2 error.\n"); + } else { + pr_err("[ERROR] SYSCTL RAS usb sub_module_id[0x%x] is error.\n", + ras_cper->sub_mod_id); + return ret; + } break; - case MODULE_USB3_ERR: - pr_err("SYSCTL RAS usb3 err %d", ret); + case MODULE_SAS_ERR: + if (ras_cper->sub_mod_id == MODULE_SAS0_ERR) { + pr_info("[INFO] SYSCTL RAS sas0 error.\n"); + } else if (ras_cper->sub_mod_id == MODULE_SAS1_ERR) { + pr_info("[INFO] SYSCTL RAS sas1 error.\n"); + } else { + pr_err("[ERROR] SYSCTL RAS sas sub_module_id[0x%x] is error.\n", + ras_cper->sub_mod_id); + return ret; + } break; default: - pr_err("SYSCTL RAS err module_id[0x%x] not process in sysctl\n", + pr_err("[ERROR] SYSCTL RAS module_id[0x%x] is error, has not match process in sysctl.\n", ras_cper->module_id); - return 0; + return ret; } (void)sysctl_correlation_reg_report(ras_cper); @@ -259,248 +297,250 @@ static int sysctl_hest_hisi_parse_ghes_count(struct acpi_hest_header *hest_hdr, return 0; } -static struct ghes *sysctl_ghes_new(struct acpi_hest_generic *generic) +static struct ghes *sysctl_ghes_new(struct acpi_hest_generic *sysctl_generic) { - struct ghes *ghes; - size_t error_block_length; - int rc = 0; + struct ghes *sysctl_ghes; + size_t err_block_length = 0; + int ret = 0; - ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); - if (!ghes) + sysctl_ghes = kzalloc(sizeof(*sysctl_ghes), GFP_KERNEL); + if (!sysctl_ghes) return ERR_PTR((long)-ENOMEM); - ghes->generic = generic; - if (is_hest_type_generic_v2(ghes)) { - rc = map_gen_v2(ghes); - if (rc) + sysctl_ghes->generic = sysctl_generic; + if (is_hest_type_generic_v2(sysctl_ghes)) { + ret = map_gen_v2(sysctl_ghes); + if (ret) goto err_free; } - rc = apei_map_generic_address(&generic->error_status_address); - if (rc) + ret = apei_map_generic_address(&sysctl_generic->error_status_address); + if (ret) goto err_unmap_read_ack_addr; - error_block_length = generic->error_block_length; - if (error_block_length > GHES_ESTATUS_MAX_SIZE) { + err_block_length = sysctl_generic->error_block_length; + if (err_block_length > HISI_GHES_ESTATUS_MAX_SIZE) { pr_err("SYSCTL RAS Error status block length is too long: %u for " "generic hardware error source: %d.\n", - (u32)error_block_length, generic->header.source_id); - error_block_length = GHES_ESTATUS_MAX_SIZE; + (u32)err_block_length, sysctl_generic->header.source_id); + err_block_length = HISI_GHES_ESTATUS_MAX_SIZE; } - ghes->estatus = (struct acpi_hest_generic_status *)kmalloc(error_block_length, GFP_KERNEL); - if (!ghes->estatus) { - rc = -ENOMEM; + sysctl_ghes->estatus = (struct acpi_hest_generic_status *)kmalloc(err_block_length, GFP_KERNEL); + if (!sysctl_ghes->estatus) { + ret = -ENOMEM; goto err_unmap_status_addr; } - return ghes; + return sysctl_ghes; err_unmap_status_addr: - apei_unmap_generic_address(&generic->error_status_address); + apei_unmap_generic_address(&sysctl_generic->error_status_address); err_unmap_read_ack_addr: - if (is_hest_type_generic_v2(ghes)) - unmap_gen_v2(ghes); + if (is_hest_type_generic_v2(sysctl_ghes)) + unmap_gen_v2(sysctl_ghes); err_free: - kfree(ghes); - return ERR_PTR((long)rc); + kfree(sysctl_ghes); + return ERR_PTR((long)ret); } static int sysctl_hest_hisi_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) { - struct acpi_hest_generic *generic; - struct ghes *ghes; + struct acpi_hest_generic *sysctl_generic; + struct ghes *sysctl_ghes; (void)data; - generic = container_of(hest_hdr, struct acpi_hest_generic, header); - if (!generic->enabled) + sysctl_generic = container_of(hest_hdr, struct acpi_hest_generic, header); + if (!sysctl_generic->enabled) return 0; - debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes source id = %x\n", + debug_sysctrl_print("[DBG] SYSCTL RAS ghes source id: %x.\n", hest_hdr->source_id); - debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes error_block_length = %x\n", - generic->error_block_length); - debug_sysctrl_print("SYSCTL RAS HISILICON Error : ghes notify type = %x\n", - generic->notify.type); - - ghes = sysctl_ghes_new(generic); - if (!ghes) + debug_sysctrl_print("[DBG] SYSCTL RAS ghes error_block_length: %x.\n", + sysctl_generic->error_block_length); + debug_sysctrl_print("[DBG] SYSCTL RAS ghes notify type: %x.\n", + sysctl_generic->notify.type); + + sysctl_ghes = sysctl_ghes_new(sysctl_generic); + if (!sysctl_ghes) { + pr_err("[ERROR] SYSCTL RAS sysctl_ghes is null.\n"); return -ENOMEM; + } mutex_lock(&hisi_ghes_mutex); - list_add_rcu(&ghes->list, &hisi_ghes_list); + list_add_rcu(&sysctl_ghes->list, &hisi_ghes_list); mutex_unlock(&hisi_ghes_mutex); return 0; } -static int sysctl_ghes_read_estatus(struct ghes *ghes, int silent) +static int sysctl_ghes_read_estatus(struct ghes *sysctl_ghes, int silent) { - struct acpi_hest_generic *g = ghes->generic; + struct acpi_hest_generic *g = sysctl_ghes->generic; phys_addr_t buf_paddr; - u32 error_block_length; + u32 err_block_length = 0; u32 len; - int rc = 0; + int ret = 0; - rc = apei_read(&buf_paddr, &g->error_status_address); - if (rc) { + ret = apei_read(&buf_paddr, &g->error_status_address); + if (ret) { if (!silent && printk_ratelimit()) { - pr_err("SYSCTL RAS Failed to read error status block address for hardware error source: %d.\n", - g->header.source_id); + pr_err("[ERROR] SYSCTL RAS apei_read fail, source_id: %d.\n", + g->header.source_id); } - pr_err("SYSCTL RAS apei_read rc: %d.\n", rc); + pr_err("[ERROR] SYSCTL RAS apei_read fail, ret: %d.\n", ret); return -EIO; } if (!buf_paddr) { - pr_err("SYSCTL RAS buf_paddr is null.\n"); + pr_err("[ERROR] SYSCTL RAS buf_paddr is null.\n"); return -ENOENT; } - error_block_length = g->error_block_length; - if (error_block_length > GHES_ESTATUS_MAX_SIZE) { - pr_err("SYSCTL RAS error_block_length: %u, source_id: %d.\n", - error_block_length, g->header.source_id); - error_block_length = GHES_ESTATUS_MAX_SIZE; + err_block_length = g->error_block_length; + if (err_block_length > HISI_GHES_ESTATUS_MAX_SIZE) { + pr_info("[INFO] SYSCTL RAS error_block_length: %u, source_id: %d.\n", + err_block_length, g->header.source_id); + err_block_length = HISI_GHES_ESTATUS_MAX_SIZE; } - ghes->estatus = ioremap_wc(buf_paddr, error_block_length); + sysctl_ghes->estatus = ioremap_wc(buf_paddr, err_block_length); - if (!ghes->estatus) { - pr_err("SYSCTL RAS ghes->estatus is null.\n"); - goto err_release_estatus; + if (!sysctl_ghes->estatus) { + pr_err("[ERROR] SYSCTL RAS sysctl_ghes->estatus is null.\n"); + goto error_release_estatus; } - if (!ghes->estatus->block_status) { - pr_err("SYSCTL RAS ghes->estatus->block_status is 0.\n"); - iounmap(ghes->estatus); + if (!sysctl_ghes->estatus->block_status) { + pr_err("[ERROR] SYSCTL RAS sysctl_ghes->estatus->block_status is 0.\n"); + iounmap(sysctl_ghes->estatus); return -ENOENT; } - ghes->buffer_paddr = buf_paddr; - ghes->flags |= GHES_TO_CLEAR; + sysctl_ghes->buffer_paddr = buf_paddr; + sysctl_ghes->flags |= GHES_TO_CLEAR; - rc = -EIO; - len = cper_estatus_len(ghes->estatus); - if (len < sizeof(*ghes->estatus)) { - pr_err("SYSCTL RAS len[%d] less than sizeof(*ghes->estatus)[%ld].\n", - len, sizeof(*ghes->estatus)); - goto err_read_block; + ret = -EIO; + len = cper_estatus_len(sysctl_ghes->estatus); + if (len < sizeof(*sysctl_ghes->estatus)) { + pr_err("[ERROR] SYSCTL RAS len[%d] less than sizeof(*ghes->estatus)[%ld].\n", + len, sizeof(*sysctl_ghes->estatus)); + goto error_read_block; } - if (len > ghes->generic->error_block_length) { - pr_err("SYSCTL RAS len[%d] more than error_block_length[%d].\n", - len, ghes->generic->error_block_length); - goto err_read_block; + if (len > sysctl_ghes->generic->error_block_length) { + pr_err("[ERROR] SYSCTL RAS len[%d] more than error_block_length[%d].\n", + len, sysctl_ghes->generic->error_block_length); + goto error_read_block; } - if (cper_estatus_check_header(ghes->estatus)) { - pr_err("SYSCTL RAS cper_estatus_check_header fail.\n"); - goto err_read_block; + if (cper_estatus_check_header(sysctl_ghes->estatus)) { + pr_err("[ERROR] SYSCTL RAS cper_estatus_check_header fail.\n"); + goto error_read_block; } - pr_err("SYSCTL RAS HISILICON Error : ghes source id is %d\n", + pr_info("[INFO] SYSCTL RAS HISILICON Error : ghes source id is %d.\n", g->header.source_id); - pr_err("SYSCTL RAS HISILICON Error : error status addr is 0x%llx\n", + pr_info("[INFO] SYSCTL RAS HISILICON Error : error status addr is 0x%llx.\n", buf_paddr); - pr_err("SYSCTL RAS HISILICON Error : data_length = %d.\n", - ghes->estatus->data_length); - pr_err("SYSCTL RAS HISILICON Error : severity = %d.\n", - ghes->estatus->error_severity); - - if (cper_estatus_check(ghes->estatus)) { - pr_err("SYSCTL RAS cper_estatus_check fail.\n"); - goto err_read_block; + pr_info("[INFO] SYSCTL RAS HISILICON Error : data_length is %d.\n", + sysctl_ghes->estatus->data_length); + pr_info("[INFO] SYSCTL RAS HISILICON Error : severity is %d.\n", + sysctl_ghes->estatus->error_severity); + + if (cper_estatus_check(sysctl_ghes->estatus)) { + pr_err("[ERROR] SYSCTL RAS cper_estatus_check fail.\n"); + goto error_read_block; } - rc = 0; - return rc; + ret = 0; + return ret; -err_read_block: - pr_err("SYSCTL RAS ghes error status block read error\n"); - iounmap(ghes->estatus); +error_read_block: + pr_err("[ERROR] SYSCTL RAS info of ghes error status block is error.\n"); + iounmap(sysctl_ghes->estatus); - pr_err("SYSCTL RAS Failed to read error status block!\n"); -err_release_estatus: - pr_err("error ioremap, release memory\n"); - return rc; + pr_err("[ERROR] SYSCTL RAS read error status block fail.\n"); +error_release_estatus: + pr_err("[ERROR] ioremap_wc fail, release_estatus.\n"); + return ret; } -void sysctl_ghes_clear_estatus(struct ghes *ghes) +void sysctl_ghes_clear_estatus(struct ghes *sysctl_ghes) { - ghes->estatus->block_status = 0; - if (!(ghes->flags & GHES_TO_CLEAR)) + sysctl_ghes->estatus->block_status = 0; + if (!(sysctl_ghes->flags & GHES_TO_CLEAR)) return; - ghes->flags &= ~GHES_TO_CLEAR; + sysctl_ghes->flags &= ~GHES_TO_CLEAR; } -static void sysctl_ghes_do_proc(struct ghes *ghes, - struct acpi_hest_generic_status *estatus) +static void sysctl_ghes_do_proc(struct ghes *sysctl_ghes, + struct acpi_hest_generic_status *sysct_estatus) { struct acpi_hest_generic_data *gdata = NULL; guid_t *sec_type; struct sysctl_local_ras_cper *ras_cper; struct cper_sec_proc_arm *arm_ras_cper; - (void)ghes; + (void)sysctl_ghes; - apei_estatus_for_each_section(estatus, gdata) { + apei_estatus_for_each_section(sysct_estatus, gdata) { sec_type = (guid_t *)gdata->section_type; if (guid_equal(sec_type, &CPER_SEC_PLATFORM_sysctl_LOCAL_RAS)) { ras_cper = acpi_hest_get_payload(gdata); (void)sysctl_do_recovery(ras_cper); - } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { arm_ras_cper = acpi_hest_get_payload(gdata); if (arm_ras_cper->err_info_num != 1) { - pr_err("SYSCTL RAS ERR: err_info_num[0x%x] is err.\n", + pr_err("[ERROR] SYSCTL RAS err_info_num[0x%x] is error.\n", arm_ras_cper->err_info_num); return; } } - cper_estatus_print("SYSCTL RAS HISILICON Error : ", - ghes->estatus); + cper_estatus_print("[INFO] SYSCTL RAS HISILICON Error : ", + sysctl_ghes->estatus); } return; } -static int sysctl_ghes_proc(struct ghes *ghes) +static int sysctl_ghes_proc(struct ghes *sysctl_ghes) { - int rc = 0; + int ret = 0; - rc = sysctl_ghes_read_estatus(ghes, 0); - if (rc) - return rc; + ret = sysctl_ghes_read_estatus(sysctl_ghes, 0); + if (ret) + return ret; - sysctl_ghes_do_proc(ghes, ghes->estatus); + sysctl_ghes_do_proc(sysctl_ghes, sysctl_ghes->estatus); - if (ghes->estatus) - iounmap(ghes->estatus); + if (sysctl_ghes->estatus) + iounmap(sysctl_ghes->estatus); - return rc; + return ret; } static int sysctl_hisi_error_handler(struct work_struct *work) { int ret = 0; - struct ghes *ghes; + struct ghes *sysctl_ghes; (void)work; - pr_err("SYSCTL RAS HISILICON Error : handler start.\n"); + pr_info("[INFO] SYSCTL RAS %s start.\n", __func__); + rcu_read_lock(); - list_for_each_entry_rcu(ghes, &hisi_ghes_list, list) { - if (!sysctl_ghes_proc(ghes)) + list_for_each_entry_rcu(sysctl_ghes, &hisi_ghes_list, list) { + if (!sysctl_ghes_proc(sysctl_ghes)) ret = NOTIFY_OK; } rcu_read_unlock(); - pr_err("SYSCTL RAS ghes_proc %d", ret); - pr_err("SYSCTL RAS HISILICON Error : handler end.\n"); + pr_info("[INFO] SYSCTL RAS sysctl_ghes_proc ret: %d.\n", ret); + pr_info("[INFO] SYSCTL RAS %s end.\n", __func__); return ret; @@ -509,30 +549,29 @@ static int sysctl_hisi_error_handler(struct work_struct *work) /*acpi hisi hest init*/ static void sysctl_acpi_hisi_hest_init(void) { - int rc; + int ret; unsigned int ghes_count = 0; - debug_sysctrl_print("SYSCTL RAS sysctl_acpi_hisi_hest_init start\n"); + debug_sysctrl_print("[DBG] SYSCTL RAS %s start.\n", __func__); if (hest_disable) { - pr_err("SYSCTL RAS Table parsing disabled.\n"); + pr_err("[ERROR] SYSCTL RAS Table parsing disabled.\n"); return; } - rc = apei_hest_parse(sysctl_hest_hisi_parse_ghes_count, &ghes_count); - if (rc) { - pr_err("SYSCTL RAS hest_hisi_parse_ghes_count faile.\n"); + ret = apei_hest_parse(sysctl_hest_hisi_parse_ghes_count, &ghes_count); + if (ret) { + pr_err("[ERROR] SYSCTL RAS hest_hisi_parse_ghes_count fail.\n"); return; } + debug_sysctrl_print("[DBG] SYSCTL RAS Get ghes count: %d.\n", ghes_count); - debug_sysctrl_print("SYSCTL RAS Get ghes count = %d\n", ghes_count); - - rc = apei_hest_parse(sysctl_hest_hisi_parse_ghes, &ghes_count); - if (rc) { - pr_err("SYSCTL RAS hest_hisi_parse_ghes faile.\n"); + ret = apei_hest_parse(sysctl_hest_hisi_parse_ghes, &ghes_count); + if (ret) { + pr_err("[ERROR] SYSCTL RAS hest_hisi_parse_ghes fail.\n"); return; } - debug_sysctrl_print("SYSCTL RAS sysctl_acpi_hisi_hest_init end\n"); + debug_sysctrl_print("[DBG] SYSCTL RAS sysctl_acpi_hisi_hest_init end.\n"); return; } @@ -575,5 +614,5 @@ void hip_sysctl_local_ras_exit(void) unregister_acpi_hed_notifier(&sysctl_ghes_hisi_notifier_hed); - pr_err(KERN_INFO "Goodbye test.\n"); + pr_info("[INFO] hip sysctl local ras exit.\n"); } diff --git a/drivers/soc/hisilicon/sysctl/sysctl_local_ras.h b/drivers/soc/hisilicon/sysctl/sysctl_local_ras.h index 969625721b30..cb2c06d98dff 100644 --- a/drivers/soc/hisilicon/sysctl/sysctl_local_ras.h +++ b/drivers/soc/hisilicon/sysctl/sysctl_local_ras.h @@ -21,8 +21,19 @@ enum sysctl_bios_err { MODULE_LPC_ERR = 9, - MODULE_USB2_ERR = 14, - MODULE_USB3_ERR = 15, + MODULE_SAS_ERR = 15, + MODULE_USB_ERR = 17, +}; + +enum sysctl_sub_usb_err { + MODULE_USB0_ERR = 0, + MODULE_USB1_ERR, + MODULE_USB2_ERR, +}; + +enum sysctl_sub_sas_err { + MODULE_SAS0_ERR = 0, + MODULE_SAS1_ERR, }; struct sysctl_validation_bits { -- GitLab