diff mbox series

[v4,4/4] scsi: ufs: add compatibility with 3.1 UFS unit descriptor length

Message ID 20200529164054.27552-5-huobean@gmail.com (mailing list archive)
State Superseded
Headers show
Series scsi: ufs: cleanup ufs initialization | expand

Commit Message

Bean Huo May 29, 2020, 4:40 p.m. UTC
From: Bean Huo <beanhuo@micron.com>

For UFS 3.1, the normal unit descriptor is 10 bytes larger
than the RPMB unit, however, both descriptors share the same
desc_idn, to cover both unit descriptors with one length, we
choose the normal unit descriptor length by desc_index.

Signed-off-by: Bean Huo <beanhuo@micron.com>
---
 drivers/scsi/ufs/ufs.h    |  1 +
 drivers/scsi/ufs/ufshcd.c | 11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

Comments

Avri Altman May 30, 2020, 6:56 a.m. UTC | #1
> 
> From: Bean Huo <beanhuo@micron.com>
> 
> For UFS 3.1, the normal unit descriptor is 10 bytes larger
> than the RPMB unit, however, both descriptors share the same
> desc_idn, to cover both unit descriptors with one length, we
> choose the normal unit descriptor length by desc_index.
This is not what your code is doing.
For RPMB - desc size will not be 0x2d but remain 256.

Your strategy is still correct IMO - if you assign the larger size,
The device will not reply with error, but with the proper buffer.

You can also rely that reading the rpmb unit descriptor will not happen before
Reading regular luns, because this is happening in the first slave_alloc.
 
Hence, I think you can drop the extra if, and just add the comment.

Thanks,
Avri 

> 
> Signed-off-by: Bean Huo <beanhuo@micron.com>
> ---
>  drivers/scsi/ufs/ufs.h    |  1 +
>  drivers/scsi/ufs/ufshcd.c | 11 ++++++++---
>  2 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
> index 6548ef102eb9..332ae09e6238 100644
> --- a/drivers/scsi/ufs/ufs.h
> +++ b/drivers/scsi/ufs/ufs.h
> @@ -63,6 +63,7 @@
>  #define UFS_UPIU_MAX_UNIT_NUM_ID       0x7F
>  #define UFS_MAX_LUNS           (SCSI_W_LUN_BASE +
> UFS_UPIU_MAX_UNIT_NUM_ID)
>  #define UFS_UPIU_WLUN_ID       (1 << 7)
> +#define UFS_RPMB_UNIT          0xC4
> 
>  /* WriteBooster buffer is available only for the logical unit from 0 to 7 */
>  #define UFS_UPIU_MAX_WB_LUN_ID 8
> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
> index 951e52babf65..3cdc585d0095 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -3070,11 +3070,16 @@ void ufshcd_map_desc_id_to_length(struct
> ufs_hba *hba, enum desc_idn desc_id,
>  EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
> 
>  static void ufshcd_update_desc_length(struct ufs_hba *hba,
> -                                     enum desc_idn desc_id,
> +                                     enum desc_idn desc_id, int desc_index,
>                                       unsigned char desc_len)
>  {
>         if (hba->desc_size[desc_id] == QUERY_DESC_MAX_SIZE &&
> -           desc_id != QUERY_DESC_IDN_STRING)
> +           desc_id != QUERY_DESC_IDN_STRING && desc_index !=
> UFS_RPMB_UNIT)
> +               /* For UFS 3.1, the normal unit descriptor is 10 bytes larger
> +                * than the RPMB unit, however, both descriptors share the same
> +                * desc_idn, to cover both unit descriptors with one length, we
> +                * choose the normal unit descriptor length by desc_index.
> +                */
>                 hba->desc_size[desc_id] = desc_len;
>  }
> 
> @@ -3141,7 +3146,7 @@ int ufshcd_read_desc_param(struct ufs_hba *hba,
>                 goto out;
>         }
> 
> -       ufshcd_update_desc_length(hba, desc_id,
> +       ufshcd_update_desc_length(hba, desc_id, desc_index,
>                                   desc_buf[QUERY_DESC_LENGTH_OFFSET]);
> 
>         /* Check wherher we will not copy more data, than available */
> --
> 2.17.1
Bean Huo May 30, 2020, 6:33 p.m. UTC | #2
Avri,


On Sat, 2020-05-30 at 06:56 +0000, Avri Altman wrote:
>  
> > 
> > From: Bean Huo <beanhuo@micron.com>
> > 
> > For UFS 3.1, the normal unit descriptor is 10 bytes larger
> > than the RPMB unit, however, both descriptors share the same
> > desc_idn, to cover both unit descriptors with one length, we
> > choose the normal unit descriptor length by desc_index.
> 
> This is not what your code is doing.
> For RPMB - desc size will not be 0x2d but remain 256.

sorry, I'm afraid I didn't quite get your point here.
would you go over it again in detail please?


> 
> Your strategy is still correct IMO - if you assign the larger size,
> The device will not reply with error, but with the proper buffer.
> 
> You can also rely that reading the rpmb unit descriptor will not
> happen before
> Reading regular luns, because this is happening in the first
> slave_alloc.
>  

On my side, I saw the Well-know LU descriptor is read before
regulaer/normal LU descritptor. see ufshcd_add_lus();

I did further debug to verify my patch, and the unit descriptor read
sequence:

1. read RPMB descriptor: desc_id 2, desc_index 0xc4
2. read LU 0 descriptor: desc_id 2, desc_index 0
3. read LU 0 descriptor: desc_id 2, desc_index 1
4. read LU 0 descriptor: desc_id 2, desc_index 2
5. read LU 0 descriptor: desc_id 2, desc_index 4
....

> Hence, I think you can drop the extra if, and just add the comment.
> 

so, this 'if' is still needed. otherwise, LU descriptor length will be
initialized as 0x23(RPMB descriptor length).

if I am wrong, please correct me.
thanks,

Bean
Avri Altman May 30, 2020, 7:43 p.m. UTC | #3
> Avri,
> 
> 
> On Sat, 2020-05-30 at 06:56 +0000, Avri Altman wrote:
> >
> > >
> > > From: Bean Huo <beanhuo@micron.com>
> > >
> > > For UFS 3.1, the normal unit descriptor is 10 bytes larger
> > > than the RPMB unit, however, both descriptors share the same
> > > desc_idn, to cover both unit descriptors with one length, we
> > > choose the normal unit descriptor length by desc_index.
> >
> > This is not what your code is doing.
> > For RPMB - desc size will not be 0x2d but remain 256.
> 
> sorry, I'm afraid I didn't quite get your point here.
> would you go over it again in detail please?
> 
> 
> >
> > Your strategy is still correct IMO - if you assign the larger size,
> > The device will not reply with error, but with the proper buffer.
> >
> > You can also rely that reading the rpmb unit descriptor will not
> > happen before
> > Reading regular luns, because this is happening in the first
> > slave_alloc.
> >
> 
> On my side, I saw the Well-know LU descriptor is read before
> regulaer/normal LU descritptor. see ufshcd_add_lus();
> 
> I did further debug to verify my patch, and the unit descriptor read
> sequence:
> 
> 1. read RPMB descriptor: desc_id 2, desc_index 0xc4
> 2. read LU 0 descriptor: desc_id 2, desc_index 0
> 3. read LU 0 descriptor: desc_id 2, desc_index 1
> 4. read LU 0 descriptor: desc_id 2, desc_index 2
> 5. read LU 0 descriptor: desc_id 2, desc_index 4
> ....
> 
> > Hence, I think you can drop the extra if, and just add the comment.
> >
> 
> so, this 'if' is still needed. otherwise, LU descriptor length will be
> initialized as 0x23(RPMB descriptor length).
> 
Ahha, ok.  I see your point now,
Fair enough.

Reviewed-by: Avri Altman <avri.altman@wdc.com>
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 6548ef102eb9..332ae09e6238 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -63,6 +63,7 @@ 
 #define UFS_UPIU_MAX_UNIT_NUM_ID	0x7F
 #define UFS_MAX_LUNS		(SCSI_W_LUN_BASE + UFS_UPIU_MAX_UNIT_NUM_ID)
 #define UFS_UPIU_WLUN_ID	(1 << 7)
+#define UFS_RPMB_UNIT		0xC4
 
 /* WriteBooster buffer is available only for the logical unit from 0 to 7 */
 #define UFS_UPIU_MAX_WB_LUN_ID	8
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 951e52babf65..3cdc585d0095 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3070,11 +3070,16 @@  void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
 EXPORT_SYMBOL(ufshcd_map_desc_id_to_length);
 
 static void ufshcd_update_desc_length(struct ufs_hba *hba,
-				      enum desc_idn desc_id,
+				      enum desc_idn desc_id, int desc_index,
 				      unsigned char desc_len)
 {
 	if (hba->desc_size[desc_id] == QUERY_DESC_MAX_SIZE &&
-	    desc_id != QUERY_DESC_IDN_STRING)
+	    desc_id != QUERY_DESC_IDN_STRING && desc_index != UFS_RPMB_UNIT)
+		/* For UFS 3.1, the normal unit descriptor is 10 bytes larger
+		 * than the RPMB unit, however, both descriptors share the same
+		 * desc_idn, to cover both unit descriptors with one length, we
+		 * choose the normal unit descriptor length by desc_index.
+		 */
 		hba->desc_size[desc_id] = desc_len;
 }
 
@@ -3141,7 +3146,7 @@  int ufshcd_read_desc_param(struct ufs_hba *hba,
 		goto out;
 	}
 
-	ufshcd_update_desc_length(hba, desc_id,
+	ufshcd_update_desc_length(hba, desc_id, desc_index,
 				  desc_buf[QUERY_DESC_LENGTH_OFFSET]);
 
 	/* Check wherher we will not copy more data, than available */