RE: [PATCH 1/2] scsi: ufs: Do not exit ufshcd_reset_and_restore() unless operational or dead

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

 



> 
> Callers of ufshcd_reset_and_restore() expect it to return in an operational
> state. However, the code only checks direct errors and so the ufshcd_state
> may not be UFSHCD_STATE_OPERATIONAL due to error interrupts.
> 
> Fix by checking also ufshcd_state, still allowing non-fatal errors which are left
> for the error handler to deal with.
> 
> Signed-off-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
Reviewed-by: Avri altman <avri.altman@xxxxxxx>


> ---
>  drivers/scsi/ufs/ufshcd.c | 36 +++++++++++++++++++++++-------------
>  1 file changed, 23 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index
> 9faf02cbb9ad..16492779d3a6 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -7156,31 +7156,41 @@ static int ufshcd_host_reset_and_restore(struct
> ufs_hba *hba)
>   */
>  static int ufshcd_reset_and_restore(struct ufs_hba *hba)  {
> -       u32 saved_err;
> -       u32 saved_uic_err;
> +       u32 saved_err = 0;
> +       u32 saved_uic_err = 0;
>         int err = 0;
>         unsigned long flags;
>         int retries = MAX_HOST_RESET_RETRIES;
> 
> -       /*
> -        * This is a fresh start, cache and clear saved error first,
> -        * in case new error generated during reset and restore.
> -        */
>         spin_lock_irqsave(hba->host->host_lock, flags);
> -       saved_err = hba->saved_err;
> -       saved_uic_err = hba->saved_uic_err;
> -       hba->saved_err = 0;
> -       hba->saved_uic_err = 0;
> -       spin_unlock_irqrestore(hba->host->host_lock, flags);
> -
>         do {
> +               /*
> +                * This is a fresh start, cache and clear saved error first,
> +                * in case new error generated during reset and restore.
> +                */
> +               saved_err |= hba->saved_err;
> +               saved_uic_err |= hba->saved_uic_err;
> +               hba->saved_err = 0;
> +               hba->saved_uic_err = 0;
> +               hba->force_reset = false;
> +               hba->ufshcd_state = UFSHCD_STATE_RESET;
> +               spin_unlock_irqrestore(hba->host->host_lock, flags);
> +
>                 /* Reset the attached device */
>                 ufshcd_device_reset(hba);
> 
>                 err = ufshcd_host_reset_and_restore(hba);
> +
> +               spin_lock_irqsave(hba->host->host_lock, flags);
> +               if (err)
> +                       continue;
> +               /* Do not exit unless operational or dead */
> +               if (hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL &&
> +                   hba->ufshcd_state != UFSHCD_STATE_ERROR &&
> +                   hba->ufshcd_state !=
> UFSHCD_STATE_EH_SCHEDULED_NON_FATAL)
> +                       err = -EAGAIN;
>         } while (err && --retries);
> 
> -       spin_lock_irqsave(hba->host->host_lock, flags);
>         /*
>          * Inform scsi mid-layer that we did reset and allow to handle
>          * Unit Attention properly.
> --
> 2.25.1





[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