Skip to content

Commit c7ee6c8

Browse files
Salomon Dushimirimanamartinkpetersen
authored andcommitted
scsi: pm80xx: Add controller SCSI host fatal error uevents
Add pm80xx_fatal_error_uevent_emit() which is called when the pm80xx driver encouters a fatal error. The uevent has the following additional custom key/value pair sets: - DRIVER: driver name, pm80xx in this case - HBA_NUM: the scsi host id of the device - EVENT_TYPE: to indicate a fatal error - REPORTED_BY: either driver or firmware The uevent is anchored to the kernel object that represents the SCSI controller, which includes other useful core variables, such as, ACTION, DEVPATH, SUBSYSTEM, and more. The fatal_error_uevent_emit() function is called when the controller fatal error state changes. Since this doesn't happen often for a specific SCSI host, there is no worries of a uevent storm. Signed-off-by: Salomon Dushimirimana <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 94bb407 commit c7ee6c8

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

drivers/scsi/pm8001/pm8001_sas.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,14 @@ struct forensic_data {
170170
#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80
171171
#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD 0x28) */
172172

173+
/**
174+
* enum fatal_error_reporter: Indicates the originator of the fatal error
175+
*/
176+
enum fatal_error_reporter {
177+
REPORTER_DRIVER,
178+
REPORTER_FIRMWARE,
179+
};
180+
173181
struct pm8001_dispatch {
174182
char *name;
175183
int (*chip_init)(struct pm8001_hba_info *pm8001_ha);
@@ -715,6 +723,8 @@ ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
715723
struct device_attribute *attr, char *buf);
716724
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
717725
int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha);
726+
void pm80xx_fatal_error_uevent_emit(struct pm8001_hba_info *pm8001_ha,
727+
enum fatal_error_reporter error_reporter);
718728
void pm8001_free_dev(struct pm8001_device *pm8001_dev);
719729
/* ctl shared API */
720730
extern const struct attribute_group *pm8001_host_groups[];

drivers/scsi/pm8001/pm80xx_hwi.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,52 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)
15511551
return 0;
15521552
}
15531553

1554+
/**
1555+
* pm80xx_fatal_error_uevent_emit - emits a single fatal error uevent
1556+
* @pm8001_ha: our hba card information
1557+
* @error_reporter: reporter of fatal error
1558+
*/
1559+
void pm80xx_fatal_error_uevent_emit(struct pm8001_hba_info *pm8001_ha,
1560+
enum fatal_error_reporter error_reporter)
1561+
{
1562+
struct kobj_uevent_env *env;
1563+
1564+
pm8001_dbg(pm8001_ha, FAIL, "emitting fatal error uevent");
1565+
1566+
env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
1567+
if (!env)
1568+
return;
1569+
1570+
if (add_uevent_var(env, "DRIVER=%s", DRV_NAME))
1571+
goto exit;
1572+
1573+
if (add_uevent_var(env, "HBA_NUM=%u", pm8001_ha->id))
1574+
goto exit;
1575+
1576+
if (add_uevent_var(env, "EVENT_TYPE=FATAL_ERROR"))
1577+
goto exit;
1578+
1579+
switch (error_reporter) {
1580+
case REPORTER_DRIVER:
1581+
if (add_uevent_var(env, "REPORTED_BY=DRIVER"))
1582+
goto exit;
1583+
break;
1584+
case REPORTER_FIRMWARE:
1585+
if (add_uevent_var(env, "REPORTED_BY=FIRMWARE"))
1586+
goto exit;
1587+
break;
1588+
default:
1589+
if (add_uevent_var(env, "REPORTED_BY=OTHER"))
1590+
goto exit;
1591+
break;
1592+
}
1593+
1594+
kobject_uevent_env(&pm8001_ha->shost->shost_dev.kobj, KOBJ_CHANGE, env->envp);
1595+
1596+
exit:
1597+
kfree(env);
1598+
}
1599+
15541600
/**
15551601
* pm80xx_fatal_errors - returns non-zero *ONLY* when fatal errors
15561602
* @pm8001_ha: our hba card information
@@ -1580,6 +1626,7 @@ pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)
15801626
"Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n",
15811627
scratch_pad1, scratch_pad2, scratch_pad3,
15821628
scratch_pad_rsvd0, scratch_pad_rsvd1);
1629+
pm80xx_fatal_error_uevent_emit(pm8001_ha, REPORTER_DRIVER);
15831630
ret = 1;
15841631
}
15851632

@@ -4039,6 +4086,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec)
40394086
pm8001_dbg(pm8001_ha, FAIL,
40404087
"Firmware Fatal error! Regval:0x%x\n",
40414088
regval);
4089+
pm80xx_fatal_error_uevent_emit(pm8001_ha, REPORTER_FIRMWARE);
40424090
pm8001_handle_event(pm8001_ha, NULL, IO_FATAL_ERROR);
40434091
print_scratchpad_registers(pm8001_ha);
40444092
return ret;

0 commit comments

Comments
 (0)