Re: [PATCH 5/7] pm80xx: Completing pending IO after fatal error

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 24, 2021 at 4:48 PM Viswas G <Viswas.G@xxxxxxxxxxxxx> wrote:
>
> From: Ruksar Devadi <Ruksar.devadi@xxxxxxxxxxxxx>
>
> When controller runs into fatal error, IOs get stuck with no response,
> handler event is defined to complete the pending IOs
> (SAS task and internal task) and also perform the cleanup for the
> drives.
>
> Signed-off-by: Ruksar Devadi <Ruksar.devadi@xxxxxxxxxxxxx>
> Signed-off-by: Viswas G <Viswas.G@xxxxxxxxxxxxx>
> Signed-off-by: Ashokkumar N <Ashokkumar.N@xxxxxxxxxxxxx>
Looks ok to me, thx!
Acked-by: Jack Wang <jinpu.wang@xxxxxxxxxxxxxxx>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.c | 66 ++++++++++++++++++++++++++++++++++++----
>  drivers/scsi/pm8001/pm8001_hwi.h |  1 +
>  drivers/scsi/pm8001/pm8001_sas.c |  2 +-
>  drivers/scsi/pm8001/pm8001_sas.h |  1 +
>  drivers/scsi/pm8001/pm80xx_hwi.c |  1 +
>  drivers/scsi/pm8001/pm80xx_hwi.h |  1 +
>  6 files changed, 65 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 49bf2f70a470..4e0ce044ac69 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -1499,12 +1499,14 @@ void pm8001_work_fn(struct work_struct *work)
>          * was cancelled. This nullification happens when the device
>          * goes away.
>          */
> -       pm8001_dev = pw->data; /* Most stash device structure */
> -       if ((pm8001_dev == NULL)
> -        || ((pw->handler != IO_XFER_ERROR_BREAK)
> -         && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) {
> -               kfree(pw);
> -               return;
> +       if (pw->handler != IO_FATAL_ERROR) {
> +               pm8001_dev = pw->data; /* Most stash device structure */
> +               if ((pm8001_dev == NULL)
> +                || ((pw->handler != IO_XFER_ERROR_BREAK)
> +                        && (pm8001_dev->dev_type == SAS_PHY_UNUSED))) {
> +                       kfree(pw);
> +                       return;
> +               }
>         }
>
>         switch (pw->handler) {
> @@ -1668,6 +1670,58 @@ void pm8001_work_fn(struct work_struct *work)
>                 dev = pm8001_dev->sas_device;
>                 pm8001_I_T_nexus_reset(dev);
>                 break;
> +       case IO_FATAL_ERROR:
> +       {
> +               struct pm8001_hba_info *pm8001_ha = pw->pm8001_ha;
> +               struct pm8001_ccb_info *ccb;
> +               struct task_status_struct *ts;
> +               struct sas_task *task;
> +               int i;
> +               u32 tag, device_id;
> +
> +               for (i = 0; ccb = NULL, i < PM8001_MAX_CCB; i++) {
> +                       ccb = &pm8001_ha->ccb_info[i];
> +                       task = ccb->task;
> +                       ts = &task->task_status;
> +                       tag = ccb->ccb_tag;
> +                       /* check if tag is NULL */
> +                       if (!tag) {
> +                               pm8001_dbg(pm8001_ha, FAIL,
> +                                       "tag Null\n");
> +                               continue;
> +                       }
> +                       if (task != NULL) {
> +                               dev = task->dev;
> +                               if (!dev) {
> +                                       pm8001_dbg(pm8001_ha, FAIL,
> +                                               "dev is NULL\n");
> +                                       continue;
> +                               }
> +                               /*complete sas task and update to top layer */
> +                               pm8001_ccb_task_free(pm8001_ha, task, ccb, tag);
> +                               ts->resp = SAS_TASK_COMPLETE;
> +                               task->task_done(task);
> +                       } else if (tag != 0xFFFFFFFF) {
> +                               /* complete the internal commands/non-sas task */
> +                               pm8001_dev = ccb->device;
> +                               if (pm8001_dev->dcompletion) {
> +                                       complete(pm8001_dev->dcompletion);
> +                                       pm8001_dev->dcompletion = NULL;
> +                               }
> +                               complete(pm8001_ha->nvmd_completion);
> +                               pm8001_tag_free(pm8001_ha, tag);
> +                       }
> +               }
> +               /* Deregsiter all the device ids  */
> +               for (i = 0; i < PM8001_MAX_DEVICES; i++) {
> +                       pm8001_dev = &pm8001_ha->devices[i];
> +                       device_id = pm8001_dev->device_id;
> +                       if (device_id) {
> +                               PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id);
> +                               pm8001_free_dev(pm8001_dev);
> +                       }
> +               }
> +       }       break;
>         }
>         kfree(pw);
>  }
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
> index 6d91e2446542..d1f3aa93325b 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.h
> +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> @@ -805,6 +805,7 @@ struct set_dev_state_resp {
>  #define IO_ABORT_IN_PROGRESS                           0x40
>  #define IO_ABORT_DELAYED                               0x41
>  #define IO_INVALID_LENGTH                              0x42
> +#define IO_FATAL_ERROR                                 0x51
>
>  /* WARNING: This error code must always be the last number.
>   * If you add error code, modify this code also
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index a98d4496ff8b..edec599ac641 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -590,7 +590,7 @@ struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
>         return NULL;
>  }
>
> -static void pm8001_free_dev(struct pm8001_device *pm8001_dev)
> +void pm8001_free_dev(struct pm8001_device *pm8001_dev)
>  {
>         u32 id = pm8001_dev->id;
>         memset(pm8001_dev, 0, sizeof(*pm8001_dev));
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 039ed91e9841..36cd37c8c29a 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -727,6 +727,7 @@ 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);
> +void pm8001_free_dev(struct pm8001_device *pm8001_dev);
>  /* 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 84315560e8e1..1aa3a499c85a 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -4126,6 +4126,7 @@ static int process_oq(struct pm8001_hba_info *pm8001_ha, u8 vec)
>                         pm8001_dbg(pm8001_ha, FAIL,
>                                    "Firmware Fatal error! Regval:0x%x\n",
>                                    regval);
> +                       pm8001_handle_event(pm8001_ha, NULL, IO_FATAL_ERROR);
>                         print_scratchpad_registers(pm8001_ha);
>                         return ret;
>                 }
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index 2c8e85cfdbc4..c7e5d93bea92 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -1272,6 +1272,7 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
>  #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_OPEN_COLLIDE   0x47
>  #define IO_OPEN_CNX_ERROR_IT_NEXUS_LOSS_PATHWAY_BLOCKED        0x48
>  #define IO_DS_INVALID                                  0x49
> +#define IO_FATAL_ERROR                                 0x51
>  /* WARNING: the value is not contiguous from here */
>  #define IO_XFER_ERR_LAST_PIO_DATAIN_CRC_ERR    0x52
>  #define IO_XFER_DMA_ACTIVATE_TIMEOUT           0x53
> --
> 2.16.3
>



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux