lkml.org 
[lkml]   [2021]   [Mar]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 06/10] scsi: ufshpb: Add hpb dev reset response
    Date
    The spec does not define what is the host's recommended response when
    the device send hpb dev reset response (oper 0x2).

    We will update all active hpb regions: mark them and do that on the next
    read.

    Signed-off-by: Avri Altman <avri.altman@wdc.com>
    ---
    drivers/scsi/ufs/ufshpb.c | 32 +++++++++++++++++++++++++++++++-
    drivers/scsi/ufs/ufshpb.h | 1 +
    2 files changed, 32 insertions(+), 1 deletion(-)

    diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c
    index 1f0344eaa546..6e580111293f 100644
    --- a/drivers/scsi/ufs/ufshpb.c
    +++ b/drivers/scsi/ufs/ufshpb.c
    @@ -640,7 +640,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
    if (rgn->reads == ACTIVATION_THRESHOLD)
    activate = true;
    spin_unlock(&rgn->rgn_lock);
    - if (activate) {
    + if (activate ||
    + test_and_clear_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags)) {
    spin_lock_irqsave(&hpb->rsp_list_lock, flags);
    ufshpb_update_active_info(hpb, rgn_idx, srgn_idx);
    spin_unlock_irqrestore(&hpb->rsp_list_lock, flags);
    @@ -1402,6 +1403,20 @@ static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb,
    queue_work(ufshpb_wq, &hpb->map_work);
    }

    +static void ufshpb_dev_reset_handler(struct ufshpb_lu *hpb)
    +{
    + struct victim_select_info *lru_info = &hpb->lru_info;
    + struct ufshpb_region *rgn;
    + unsigned long flags;
    +
    + spin_lock_irqsave(&hpb->rgn_state_lock, flags);
    +
    + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn)
    + set_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags);
    +
    + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags);
    +}
    +
    /*
    * This function will parse recommended active subregion information in sense
    * data field of response UPIU with SAM_STAT_GOOD state.
    @@ -1476,6 +1491,18 @@ void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
    case HPB_RSP_DEV_RESET:
    dev_warn(&hpb->sdev_ufs_lu->sdev_dev,
    "UFS device lost HPB information during PM.\n");
    +
    + if (hpb->is_hcm) {
    + struct scsi_device *sdev;
    +
    + __shost_for_each_device(sdev, hba->host) {
    + struct ufshpb_lu *h = sdev->hostdata;
    +
    + if (h)
    + ufshpb_dev_reset_handler(h);
    + }
    + }
    +
    break;
    default:
    dev_notice(&hpb->sdev_ufs_lu->sdev_dev,
    @@ -1795,6 +1822,8 @@ static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb)
    } else {
    rgn->rgn_state = HPB_RGN_INACTIVE;
    }
    +
    + rgn->rgn_flags = 0;
    }

    return 0;
    @@ -2122,6 +2151,7 @@ static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb)
    {
    if (hpb->is_hcm)
    cancel_work_sync(&hpb->ufshpb_normalization_work);
    +
    cancel_work_sync(&hpb->map_work);
    }

    diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h
    index 7afc98e61c0a..24aa116c42c6 100644
    --- a/drivers/scsi/ufs/ufshpb.h
    +++ b/drivers/scsi/ufs/ufshpb.h
    @@ -123,6 +123,7 @@ struct ufshpb_region {
    struct list_head list_lru_rgn;
    unsigned long rgn_flags;
    #define RGN_FLAG_DIRTY 0
    +#define RGN_FLAG_UPDATE 1

    /* region reads - for host mode */
    spinlock_t rgn_lock;
    --
    2.25.1
    \
     
     \ /
      Last update: 2021-03-22 09:14    [W:3.750 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site