mbox series

[0/8] pm80xx updates.

Message ID 20201230045743.14694-1-Viswas.G@microchip.com.com
Headers show
Series pm80xx updates. | expand

Message

Viswas G Dec. 30, 2020, 4:57 a.m. UTC
From: Viswas G <Viswas.G@microchip.com>

This patch set include some bug fixes and enhancements for pm80xx driver.

Bhavesh Jashnani (1):
  pm80xx: Simultaneous poll for all FW readiness.

Vishakha Channapattan (2):
  pm80xx: Log SATA IOMB completion status on failure.
  pm80xx: Add sysfs attribute for ioc health

Viswas G (1):
  pm80xx: fix driver fatal dump failure.

akshatzen (4):
  pm80xx: No busywait in MPI init check
  pm80xx: check fatal error
  pm80xx: check main config table address
  pm80xx: fix missing tag_free in NVMD DATA req

 drivers/scsi/pm8001/pm8001_ctl.c  |  42 ++++++++
 drivers/scsi/pm8001/pm8001_hwi.c  |  15 ++-
 drivers/scsi/pm8001/pm8001_init.c |  11 ++-
 drivers/scsi/pm8001/pm8001_sas.c  |   9 ++
 drivers/scsi/pm8001/pm8001_sas.h  |   2 +
 drivers/scsi/pm8001/pm80xx_hwi.c  | 202 ++++++++++++++++++++++++--------------
 drivers/scsi/pm8001/pm80xx_hwi.h  |  17 +++-
 7 files changed, 216 insertions(+), 82 deletions(-)

Comments

Jinpu Wang Jan. 4, 2021, 6:45 a.m. UTC | #1
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote:
>

> From: akshatzen <akshatzen@google.com>

>

> We do not need to busy wait during mpi_init_check. I confirmed that

> mpi_init_check is not being invoked in an ATOMIC context. It is being

> called from pm8001_pci_resume, pm8001_pci_probe. Hence we are

> replacing the udelay which busy waits with msleep.

>

> Signed-off-by: akshatzen <akshatzen@google.com>

> Signed-off-by: Viswas G <Viswas.G@microchip.com>

> Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>

> Signed-off-by: Radha Ramachandran <radha@google.com>

Thanks akshatzen!
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

> ---

>  drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++---

>  drivers/scsi/pm8001/pm80xx_hwi.h | 4 ++--

>  2 files changed, 5 insertions(+), 5 deletions(-)

>

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c

> index 6772b0924dac..9c4b8b374ab8 100644

> --- a/drivers/scsi/pm8001/pm80xx_hwi.c

> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c

> @@ -997,7 +997,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)

>                 max_wait_count = SPC_DOORBELL_CLEAR_TIMEOUT;

>         }

>         do {

> -               udelay(1);

> +               msleep(FW_READY_INTERVAL);

>                 value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET);

>                 value &= SPCv_MSGU_CFG_TABLE_UPDATE;

>         } while ((value != 0) && (--max_wait_count));

> @@ -1010,9 +1010,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)

>                 return -EBUSY;

>         }

>         /* check the MPI-State for initialization upto 100ms*/

> -       max_wait_count = 100 * 1000;/* 100 msec */

> +       max_wait_count = 5;/* 100 msec */

>         do {

> -               udelay(1);

> +               msleep(FW_READY_INTERVAL);

>                 gst_len_mpistate =

>                         pm8001_mr32(pm8001_ha->general_stat_tbl_addr,

>                                         GST_GSTLEN_MPIS_OFFSET);

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h

> index ec48bc276de6..2b6b52551968 100644

> --- a/drivers/scsi/pm8001/pm80xx_hwi.h

> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h

> @@ -220,8 +220,8 @@

>  #define SAS_DOPNRJT_RTRY_TMO            128

>  #define SAS_COPNRJT_RTRY_TMO            128

>

> -#define SPCV_DOORBELL_CLEAR_TIMEOUT    (30 * 1000 * 1000) /* 30 sec */

> -#define SPC_DOORBELL_CLEAR_TIMEOUT     (15 * 1000 * 1000) /* 15 sec */

> +#define SPCV_DOORBELL_CLEAR_TIMEOUT    (30 * 50) /* 30 sec */

> +#define SPC_DOORBELL_CLEAR_TIMEOUT     (15 * 50) /* 15 sec */

>

>  /*

>    Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second.

> --

> 2.16.3

>
Jinpu Wang Jan. 5, 2021, 1:19 p.m. UTC | #2
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote:
>

> From: akshatzen <akshatzen@google.com>

>

> When controller runs into fatal error, commands which expect

> response get stuck due to no response. If the controller is

> in fatal error state, abort request issued to the controller

> gets hung too. Hence we should fail it without trying.

>

> Signed-off-by: akshatzen <akshatzen@google.com>

> Signed-off-by: Viswas G <Viswas.G@microchip.com>

> Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>

> Signed-off-by: Radha Ramachandran <radha@google.com>

Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

Thx
> ---

>  drivers/scsi/pm8001/pm8001_hwi.c |  1 +

>  drivers/scsi/pm8001/pm8001_sas.c |  9 +++++++++

>  drivers/scsi/pm8001/pm8001_sas.h |  2 ++

>  drivers/scsi/pm8001/pm80xx_hwi.c | 36 ++++++++++++++++++++++++++++++++++++

>  drivers/scsi/pm8001/pm80xx_hwi.h | 13 +++++++++++++

>  5 files changed, 61 insertions(+)

>

> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c

> index c8d4d87c5473..f147193d67bd 100644

> --- a/drivers/scsi/pm8001/pm8001_hwi.c

> +++ b/drivers/scsi/pm8001/pm8001_hwi.c

> @@ -4998,4 +4998,5 @@ const struct pm8001_dispatch pm8001_8001_dispatch = {

>         .fw_flash_update_req    = pm8001_chip_fw_flash_update_req,

>         .set_dev_state_req      = pm8001_chip_set_dev_state_req,

>         .sas_re_init_req        = pm8001_chip_sas_re_initialization,

> +       .fatal_errors           = pm80xx_fatal_errors,

>  };

> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c

> index d1e9dba2ef19..f8d142f9b9ad 100644

> --- a/drivers/scsi/pm8001/pm8001_sas.c

> +++ b/drivers/scsi/pm8001/pm8001_sas.c

> @@ -1183,12 +1183,21 @@ int pm8001_abort_task(struct sas_task *task)

>         int rc = TMF_RESP_FUNC_FAILED, ret;

>         u32 phy_id;

>         struct sas_task_slow slow_task;

> +

>         if (unlikely(!task || !task->lldd_task || !task->dev))

>                 return TMF_RESP_FUNC_FAILED;

> +

>         dev = task->dev;

>         pm8001_dev = dev->lldd_dev;

>         pm8001_ha = pm8001_find_ha_by_dev(dev);

>         phy_id = pm8001_dev->attached_phy;

> +

> +       if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) {

> +               // If the controller is seeing fatal errors

> +               // abort task will not get a response from the controller

> +               return TMF_RESP_FUNC_FAILED;

> +       }

> +

>         ret = pm8001_find_tag(task, &tag);

>         if (ret == 0) {

>                 pm8001_info(pm8001_ha, "no tag for task:%p\n", task);

> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h

> index f2c8cbad3853..039ed91e9841 100644

> --- a/drivers/scsi/pm8001/pm8001_sas.h

> +++ b/drivers/scsi/pm8001/pm8001_sas.h

> @@ -215,6 +215,7 @@ struct pm8001_dispatch {

>         int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,

>                 u32 state);

>         int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);

> +       int (*fatal_errors)(struct pm8001_hba_info *pm8001_ha);

>  };

>

>  struct pm8001_chip_info {

> @@ -725,6 +726,7 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,

>  ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,

>                 struct device_attribute *attr, char *buf);

>  ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);

> +int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha);

>  /* ctl shared API */

>  extern struct device_attribute *pm8001_host_attrs[];

>

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c

> index 9c4b8b374ab8..86a3d483749c 100644

> --- a/drivers/scsi/pm8001/pm80xx_hwi.c

> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c

> @@ -1525,6 +1525,41 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha)

>         return 0;

>  }

>

> +/**

> + * pm80xx_fatal_errors - returns non zero *ONLY* when fatal errors

> + * @pm8001_ha: our hba card information

> + *

> + * Fatal errors are recoverable only after a host reboot.

> + */

> +int

> +pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)

> +{

> +       int ret = 0;

> +       u32 scratch_pad_rsvd0 = pm8001_cr32(pm8001_ha, 0,

> +                                       MSGU_HOST_SCRATCH_PAD_6);

> +       u32 scratch_pad_rsvd1 = pm8001_cr32(pm8001_ha, 0,

> +                                       MSGU_HOST_SCRATCH_PAD_7);

> +       u32 scratch_pad1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);

> +       u32 scratch_pad2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);

> +       u32 scratch_pad3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);

> +

> +       if (pm8001_ha->chip_id != chip_8006 &&

> +                       pm8001_ha->chip_id != chip_8074 &&

> +                       pm8001_ha->chip_id != chip_8076) {

> +               return 0;

> +       }

> +

> +       if (MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(scratch_pad1)) {

> +               pm8001_dbg(pm8001_ha, FAIL,

> +                       "Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n",

> +                               scratch_pad1, scratch_pad2, scratch_pad3,

> +                               scratch_pad_rsvd0, scratch_pad_rsvd1);

> +               ret = 1;

> +       }

> +

> +       return ret;

> +}

> +

>  /**

>   * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all

>   * the FW register status to the originated status.

> @@ -4959,4 +4994,5 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {

>         .set_nvmd_req           = pm8001_chip_set_nvmd_req,

>         .fw_flash_update_req    = pm8001_chip_fw_flash_update_req,

>         .set_dev_state_req      = pm8001_chip_set_dev_state_req,

> +       .fatal_errors           = pm80xx_fatal_errors,

>  };

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h

> index 2b6b52551968..2c8e85cfdbc4 100644

> --- a/drivers/scsi/pm8001/pm80xx_hwi.h

> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h

> @@ -1368,6 +1368,19 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;

>  #define MSGU_HOST_SCRATCH_PAD_6                        0x6C

>  #define MSGU_HOST_SCRATCH_PAD_7                        0x70

>

> +#define MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ((x & 0x3) == 0x2)

> +#define MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) (((x >> 2) & 0x3) == 0x2)

> +#define MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ((((x >> 4) & 0x7) == 0x7) || \

> +                                               (((x >> 4) & 0x7) == 0x4))

> +#define MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) (((x >> 10) & 0x3) == 0x2)

> +#define MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x) (((x >> 12) & 0x3) == 0x2)

> +#define MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(x)  \

> +                       (MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ||      \

> +                        MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) ||       \

> +                        MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ||   \

> +                        MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) ||      \

> +                        MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x))

> +

>  /* bit definition for ODMR register */

>  #define ODMR_MASK_ALL                  0xFFFFFFFF/* mask all

>                                         interrupt vector */

> --

> 2.16.3

>
Jinpu Wang Jan. 5, 2021, 1:24 p.m. UTC | #3
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote:
>

> From: akshatzen <akshatzen@google.com>

>

> Tag is not free'd in NVMD get/set data request failure scenario,

> which would have caused tag leak each time the request fails.

>

> Signed-off-by: akshatzen <akshatzen@google.com>

> Signed-off-by: Viswas G <Viswas.G@microchip.com>

> Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>

> Signed-off-by: Radha Ramachandran <radha@google.com>

Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

Thx
> ---

>  drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++++++++----

>  1 file changed, 10 insertions(+), 4 deletions(-)

>

> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c

> index f147193d67bd..9cd6a654f8b2 100644

> --- a/drivers/scsi/pm8001/pm8001_hwi.c

> +++ b/drivers/scsi/pm8001/pm8001_hwi.c

> @@ -3038,8 +3038,8 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)

>         complete(pm8001_ha->nvmd_completion);

>         pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n");

>         if ((dlen_status & NVMD_STAT) != 0) {

> -               pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error!\n");

> -               return;

> +               pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n",

> +                               dlen_status);

>         }

>         ccb->task = NULL;

>         ccb->ccb_tag = 0xFFFFFFFF;

> @@ -3062,11 +3062,17 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)

>

>         pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n");

>         if ((dlen_status & NVMD_STAT) != 0) {

> -               pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error!\n");

> +               pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error %x\n",

> +                               dlen_status);

>                 complete(pm8001_ha->nvmd_completion);

> +               /* We should free tag during failure also, the tag is not being

> +                * free'd by requesting path anywhere.

> +                */

> +               ccb->task = NULL;

> +               ccb->ccb_tag = 0xFFFFFFFF;

> +               pm8001_tag_free(pm8001_ha, tag);

>                 return;

>         }

> -

>         if (ir_tds_bn_dps_das_nvm & IPMode) {

>                 /* indirect mode - IR bit set */

>                 pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n");

> --

> 2.16.3

>
Jinpu Wang Jan. 5, 2021, 1:25 p.m. UTC | #4
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote:
>

> From: Viswas G <Viswas.G@microchip.com>

>

> The fatal dump function pm80xx_get_fatal_dump() has two issues that

> result in the fatal dump not being completed successfully.

>

> 1. When trying collect fatal_logs from the application it is getting

> failed, because we are not shifting MEMBASE-II register properly.

> Once we read 64K region of data we have to shift the MEMBASE-II register

> and read the next chunk of data, then only we would be able to get

> complete data.

>

> 2. If timeout occurs our application will get stuck because we are not

> handling this case. In this patch it resolves all these issues.

>

> Signed-off-by: Viswas G <Viswas.G@microchip.com>

> Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>

> Signed-off-by: Ashokkumar N <Ashokkumar.N@microchip.com>

Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

Thx
> ---

>  drivers/scsi/pm8001/pm80xx_hwi.c | 14 +++++++++-----

>  1 file changed, 9 insertions(+), 5 deletions(-)

>

> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c

> index 7d0eada11d3c..407c0cf6ab5f 100644

> --- a/drivers/scsi/pm8001/pm80xx_hwi.c

> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c

> @@ -349,10 +349,15 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,

>                                 sprintf(

>                                 pm8001_ha->forensic_info.data_buf.direct_data,

>                                 "%08x ", 0xFFFFFFFF);

> -                               pm8001_cw32(pm8001_ha, 0,

> +                               return((char *)pm8001_ha->forensic_info.data_buf.direct_data -

> +                                               (char *)buf);

> +                       }

> +       /* reset fatal_forensic_shift_offset back to zero and reset MEMBASE 2 register to zero */

> +                       pm8001_ha->fatal_forensic_shift_offset = 0; /* location in 64k region */

> +                       pm8001_cw32(pm8001_ha, 0,

>                                         MEMBASE_II_SHIFT_REGISTER,

>                                         pm8001_ha->fatal_forensic_shift_offset);

> -                       }

> +               }

>                         /* Read the next block of the debug data.*/

>                         length_to_read = pm8001_mr32(fatal_table_address,

>                         MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -

> @@ -373,13 +378,12 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,

>                                                                 = 0;

>                                 pm8001_ha->forensic_info.data_buf.read_len = 0;

>                         }

> -               }

>         }

>         offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data

>                         - (char *)buf);

>         pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset);

> -       return (char *)pm8001_ha->forensic_info.data_buf.direct_data -

> -               (char *)buf;

> +       return ((char *)pm8001_ha->forensic_info.data_buf.direct_data -

> +               (char *)buf);

>  }

>

>  /* pm80xx_get_non_fatal_dump - dump the nonfatal data from the dma

> --

> 2.16.3

>
Jinpu Wang Jan. 5, 2021, 1:35 p.m. UTC | #5
On Wed, Dec 30, 2020 at 5:48 AM Viswas G <Viswas.G@microchip.com.com> wrote:
>

> From: Vishakha Channapattan <vishakhavc@google.com>

>

> A new sysfs variable 'health' is being introduced that tells if the

> controller is alive by indicating controller ticks. If on subsequent

> run we see the ticks changing that indicates that controller is not

> dead.

>

> Tested: Using 'health' sysfs variable we can see ticks incrementing

> mvae14:~# cat  /sys/class/scsi_host/host*/health

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x00000169 IOPTCNT=0x0000016a IOP1TCNT=0x0000016a

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x0000014d IOPTCNT=0x0000014d IOP1TCNT=0x0000014d

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x00000149 IOPTCNT=0x00000149 IOP1TCNT=0x00000149

> mvae14:~#

> mvae14:~#

> mvae14:~#

> mvae14:~# cat  /sys/class/scsi_host/host*/health

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x0000016c IOPTCNT=0x0000016c IOP1TCNT=0x0000016c

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x0000014f IOPTCNT=0x0000014f IOP1TCNT=0x0000014f

> MPI-S= MPI is successfully initialized   HMI_ERR=0

> MSGUTCNT = 0x0000014b IOPTCNT=0x0000014b IOP1TCNT=0x0000014b

>

> Signed-off-by: Vishakha Channapattan <vishakhavc@google.com>

> Signed-off-by: Viswas G <Viswas.G@microchip.com>

> Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com>

> Signed-off-by: Ashokkumar N <Ashokkumar.N@microchip.com>

> Signed-off-by: Radha Ramachandran <radha@google.com>

Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

Thx
> ---

>  drivers/scsi/pm8001/pm8001_ctl.c | 42 ++++++++++++++++++++++++++++++++++++++++

>  1 file changed, 42 insertions(+)

>

> diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c

> index 12035baf0997..f46f341132fb 100644

> --- a/drivers/scsi/pm8001/pm8001_ctl.c

> +++ b/drivers/scsi/pm8001/pm8001_ctl.c

> @@ -41,6 +41,7 @@

>  #include <linux/slab.h>

>  #include "pm8001_sas.h"

>  #include "pm8001_ctl.h"

> +#include "pm8001_chips.h"

>

>  /* scsi host attributes */

>

> @@ -886,6 +887,46 @@ static ssize_t pm8001_show_update_fw(struct device *cdev,

>

>  static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP,

>         pm8001_show_update_fw, pm8001_store_update_fw);

> +

> +/**

> + * pm8001_ctl_health_show - controller health check

> + * @cdev: pointer to embedded class device

> + * @buf: the buffer returned

> + *

> + * A sysfs 'read-only' shost attribute.

> + */

> +

> +char mpiStateText[][80] = {

> +       "MPI is not initialized",

> +       "MPI is successfully initialized",

> +       "MPI termination is in progress",

> +       "MPI initialization failed with error in [31:16]"

> +};

> +

> +static ssize_t ctl_health_show(struct device *cdev,

> +               struct device_attribute *attr, char *buf)

> +{

> +       struct Scsi_Host *shost = class_to_shost(cdev);

> +       struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);

> +       struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;

> +       unsigned int mpiDW0 = 0;

> +       unsigned int raaeCnt = 0;

> +       unsigned int iop0Cnt = 0;

> +       unsigned int iop1Cnt = 0;

> +       int c;

> +

> +       pm8001_dbg(pm8001_ha, IOCTL, "%s\n", __func__);

> +       mpiDW0 = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 0);

> +       raaeCnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 12);

> +       iop0Cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 16);

> +       iop1Cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 20);

> +       c = sprintf(buf, "MPI-S=%s\t HMI_ERR=%x\nMSGUTCNT=0x%08x IOPTCNT=0x%08x IOP1TCNT=0x%08x\n",

> +                       mpiStateText[mpiDW0 & 0x0003], ((mpiDW0 & 0xff00) >> 16),

> +                       raaeCnt, iop0Cnt, iop1Cnt);

> +       return c;

> +}

> +static DEVICE_ATTR_RO(ctl_health);

> +

>  struct device_attribute *pm8001_host_attrs[] = {

>         &dev_attr_interface_rev,

>         &dev_attr_controller_fatal_error,

> @@ -909,6 +950,7 @@ struct device_attribute *pm8001_host_attrs[] = {

>         &dev_attr_ob_log,

>         &dev_attr_ila_version,

>         &dev_attr_inc_fw_ver,

> +       &dev_attr_ctl_health,

>         NULL,

>  };

>

> --

> 2.16.3

>
Martin K. Petersen Jan. 8, 2021, 3:21 a.m. UTC | #6
Hi Viswas!

> From: Viswas G <Viswas.G@microchip.com>


This series was submitted as <Viswas.G@microchip.com.com>. I was going
to fix it up but various tooling gets confused and we end up with weird
lore links.

Please fix your email address and resubmit.

Thanks!

-- 
Martin K. Petersen	Oracle Linux Engineering