> From: Bean Huo <beanhuo@xxxxxxxxxx> > > For the Micron UFS, L2P entry need to be swapped in HPB READ command > before sending HPB READ command to the UFS device. Add this quirk > UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ to fix this > inconsistency. > > Fixes: 2fff76f87542 ("scsi: ufs: ufshpb: Prepare HPB read for cached sub- > region") Not really needed - the patch is fine. > Signed-off-by: Bean Huo <beanhuo@xxxxxxxxxx> Reviewed-by: Avri Altman <avri.altman@xxxxxxx> > --- > drivers/scsi/ufs/ufs_quirks.h | 6 ++++++ > drivers/scsi/ufs/ufshcd.c | 3 ++- > drivers/scsi/ufs/ufshpb.c | 15 ++++++++++----- > 3 files changed, 18 insertions(+), 6 deletions(-) > > diff --git a/drivers/scsi/ufs/ufs_quirks.h b/drivers/scsi/ufs/ufs_quirks.h > index 07f559ac5883..35ec9ea79869 100644 > --- a/drivers/scsi/ufs/ufs_quirks.h > +++ b/drivers/scsi/ufs/ufs_quirks.h > @@ -116,4 +116,10 @@ struct ufs_dev_fix { > */ > #define UFS_DEVICE_QUIRK_DELAY_AFTER_LPM (1 << 11) > > +/* > + * Some UFS devices require L2P entry should be swapped before being sent to > the > + * UFS device for HPB READ command. > + */ > +#define UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ (1 << 12) > + > #endif /* UFS_QUIRKS_H_ */ > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index 47a5085f16a9..c3a14d3b0030 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -199,7 +199,8 @@ ufs_get_desired_pm_lvl_for_dev_link_state(enum > ufs_dev_pwr_mode dev_state, > static struct ufs_dev_fix ufs_fixups[] = { > /* UFS cards deviations table */ > UFS_FIX(UFS_VENDOR_MICRON, UFS_ANY_MODEL, > - UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM), > + UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | > + UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ), > UFS_FIX(UFS_VENDOR_SAMSUNG, UFS_ANY_MODEL, > UFS_DEVICE_QUIRK_DELAY_BEFORE_LPM | > UFS_DEVICE_QUIRK_HOST_PA_TACTIVATE | > diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c > index 54e8e019bdbe..d0eb14be47a3 100644 > --- a/drivers/scsi/ufs/ufshpb.c > +++ b/drivers/scsi/ufs/ufshpb.c > @@ -323,15 +323,19 @@ ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, > unsigned long lpn, int *rgn_idx, > } > > static void > -ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, > - u32 lpn, __be64 ppn, u8 transfer_len, int read_id) > +ufshpb_set_hpb_read_to_upiu(struct ufs_hba *hba, struct ufshpb_lu *hpb, > + struct ufshcd_lrb *lrbp, u32 lpn, __be64 ppn, > + u8 transfer_len, int read_id) > { > unsigned char *cdb = lrbp->cmd->cmnd; > - > + __be64 ppn_tmp = ppn; > cdb[0] = UFSHPB_READ; > > + if (hba->dev_quirks & > UFS_DEVICE_QUIRK_SWAP_L2P_ENTRY_FOR_HPB_READ) > + ppn_tmp = swab64(ppn); > + > /* ppn value is stored as big-endian in the host memory */ > - memcpy(&cdb[6], &ppn, sizeof(__be64)); > + memcpy(&cdb[6], &ppn_tmp, sizeof(__be64)); > cdb[14] = transfer_len; > cdb[15] = read_id; > > @@ -689,7 +693,8 @@ int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb > *lrbp) > } > } > > - ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len, read_id); > + ufshpb_set_hpb_read_to_upiu(hba, hpb, lrbp, lpn, ppn, transfer_len, > + read_id); > > hpb->stats.hit_cnt++; > return 0; > -- > 2.25.1