FROMLIST: scsi: ufs: Add hpb dev reset response

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.

Bug: 183467926
Bug: 170940265
Bug: 183454255

Link: https://lore.kernel.org/lkml/20210607061401.58884-8-avri.altman@wdc.com/
Signed-off-by: Avri Altman <avri.altman@wdc.com>
Change-Id: Ibe87969a4130b4e77f5d163771648679bc5ac7e8
This commit is contained in:
Avri Altman
2020-06-03 18:01:07 +03:00
committed by Todd Kjos
parent dbf4aa202c
commit 992cbc0e10
2 changed files with 32 additions and 1 deletions

View File

@@ -196,7 +196,8 @@ next_srgn:
}
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);
@@ -1411,6 +1412,21 @@ out:
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.
@@ -1485,6 +1501,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,
@@ -1811,6 +1839,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;

View File

@@ -127,6 +127,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;