diff mbox series

[2/3] scsi: ufs: Map the correct size to the rpmb unit descriptor

Message ID 20210727123546.17228-3-avri.altman@wdc.com
State New
Headers show
Series Log correct rpmb unit descriptor size | expand

Commit Message

Avri Altman July 27, 2021, 12:35 p.m. UTC
Each lun is designated by its unit descriptor. All regular luns share
the same unit descriptor size. The rpmb unit descriptor size, however,
is different.

Log the correct size for the rpmb unit descriptor in an unused
descriptor id number.

Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/scsi/ufs/ufs.h     |  1 +
 drivers/scsi/ufs/ufs_bsg.c |  3 ++-
 drivers/scsi/ufs/ufshcd.c  | 18 +++++++++++-------
 drivers/scsi/ufs/ufshcd.h  |  2 +-
 4 files changed, 15 insertions(+), 9 deletions(-)

Comments

Daejun Park July 28, 2021, 5:06 a.m. UTC | #1
Hi Avri,

> diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h

> index 579cf6f9e7a1..d0be8d4c8091 100644

> --- a/drivers/scsi/ufs/ufs.h

> +++ b/drivers/scsi/ufs/ufs.h

> @@ -167,6 +167,7 @@ enum desc_idn {

>          QUERY_DESC_IDN_GEOMETRY                = 0x7,

>          QUERY_DESC_IDN_POWER                = 0x8,

>          QUERY_DESC_IDN_HEALTH           = 0x9,

> +        QUERY_DESC_IDN_UNIT_RPMB        = 0xA,

>          QUERY_DESC_IDN_MAX,


By adding QUERY_DESC_IDN_UNIT_RPMB, the value of QUERY_DESC_IDN_MAX is
changed to 0xB.
...

> diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c

> index 74ccfd2b80ce..eec1bc95391b 100644

> --- a/drivers/scsi/ufs/ufshcd.c

> +++ b/drivers/scsi/ufs/ufshcd.c

> @@ -3319,11 +3319,13 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba,

>   * @desc_len: mapped desc length (out)

>   */

>  void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,

> -                                  int *desc_len)

> +                                  int desc_index, int *desc_len)

>  {

>          if (desc_id >= QUERY_DESC_IDN_MAX || desc_id == QUERY_DESC_IDN_RFU_0 ||

>              desc_id == QUERY_DESC_IDN_RFU_1)

>                  *desc_len = 0;


So, if user sending desc_id as 0xA, it can not be detected as invalid descriptor.

> +        else if (desc_index == UFS_UPIU_RPMB_WLUN)

> +                *desc_len = hba->desc_size[QUERY_DESC_IDN_UNIT_RPMB];

>          else

>                  *desc_len = hba->desc_size[desc_id];

>  }


Thanks,
Daejun
Avri Altman July 28, 2021, 7:28 a.m. UTC | #2
> Hi Avri,

> 

> > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index

> > 579cf6f9e7a1..d0be8d4c8091 100644

> > --- a/drivers/scsi/ufs/ufs.h

> > +++ b/drivers/scsi/ufs/ufs.h

> > @@ -167,6 +167,7 @@ enum desc_idn {

> >          QUERY_DESC_IDN_GEOMETRY                = 0x7,

> >          QUERY_DESC_IDN_POWER                = 0x8,

> >          QUERY_DESC_IDN_HEALTH           = 0x9,

> > +        QUERY_DESC_IDN_UNIT_RPMB        = 0xA,

> >          QUERY_DESC_IDN_MAX,

> 

> By adding QUERY_DESC_IDN_UNIT_RPMB, the value of

> QUERY_DESC_IDN_MAX is changed to 0xB.

> ...

Yes

> 

> > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c

> > index 74ccfd2b80ce..eec1bc95391b 100644

> > --- a/drivers/scsi/ufs/ufshcd.c

> > +++ b/drivers/scsi/ufs/ufshcd.c

> > @@ -3319,11 +3319,13 @@ int ufshcd_query_descriptor_retry(struct ufs_hba

> *hba,

> >   * @desc_len: mapped desc length (out)

> >   */

> >  void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn

> desc_id,

> > -                                  int *desc_len)

> > +                                  int desc_index, int *desc_len)

> >  {

> >          if (desc_id >= QUERY_DESC_IDN_MAX || desc_id ==

> QUERY_DESC_IDN_RFU_0 ||

> >              desc_id == QUERY_DESC_IDN_RFU_1)

> >                  *desc_len = 0;

> 

> So, if user sending desc_id as 0xA, it can not be detected as invalid descriptor.

Which user?
Oh, you mean if someone uses the ufs-bsg with some upiu-based query app, like ufs-utils?
Well, those apps are for developers and field engineers, expected to know what they are doing...

Alternatively, maybe its better to just remove the unit descriptor sysfs entries for wlun altogether?
They really meant nothing and shouldn't be there in the first place.
What do you think?

Thanks,
Avri 
> 

> > +        else if (desc_index == UFS_UPIU_RPMB_WLUN)

> > +                *desc_len = hba->desc_size[QUERY_DESC_IDN_UNIT_RPMB];

> >          else

> >                  *desc_len = hba->desc_size[desc_id];  }

> 

> Thanks,

> Daejun
Daejun Park July 28, 2021, 7:51 a.m. UTC | #3
Hi,

> > Hi Avri,

> > 

> > > diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index

> > > 579cf6f9e7a1..d0be8d4c8091 100644

> > > --- a/drivers/scsi/ufs/ufs.h

> > > +++ b/drivers/scsi/ufs/ufs.h

> > > @@ -167,6 +167,7 @@ enum desc_idn {

> > >          QUERY_DESC_IDN_GEOMETRY                = 0x7,

> > >          QUERY_DESC_IDN_POWER                = 0x8,

> > >          QUERY_DESC_IDN_HEALTH           = 0x9,

> > > +        QUERY_DESC_IDN_UNIT_RPMB        = 0xA,

> > >          QUERY_DESC_IDN_MAX,

> > 

> > By adding QUERY_DESC_IDN_UNIT_RPMB, the value of

> > QUERY_DESC_IDN_MAX is changed to 0xB.

> > ...

> Yes

>  

> > 

> > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c

> > > index 74ccfd2b80ce..eec1bc95391b 100644

> > > --- a/drivers/scsi/ufs/ufshcd.c

> > > +++ b/drivers/scsi/ufs/ufshcd.c

> > > @@ -3319,11 +3319,13 @@ int ufshcd_query_descriptor_retry(struct ufs_hba

> > *hba,

> > >   * @desc_len: mapped desc length (out)

> > >   */

> > >  void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn

> > desc_id,

> > > -                                  int *desc_len)

> > > +                                  int desc_index, int *desc_len)

> > >  {

> > >          if (desc_id >= QUERY_DESC_IDN_MAX || desc_id ==

> > QUERY_DESC_IDN_RFU_0 ||

> > >              desc_id == QUERY_DESC_IDN_RFU_1)

> > >                  *desc_len = 0;

> > 

> > So, if user sending desc_id as 0xA, it can not be detected as invalid descriptor.

> Which user?

> Oh, you mean if someone uses the ufs-bsg with some upiu-based query app, like ufs-utils?

> Well, those apps are for developers and field engineers, expected to know what they are doing...


Yes, but checking QUERY_DESC_IDN_MAX can be useless because of adding entry in enum desc_idn.
 
> Alternatively, maybe its better to just remove the unit descriptor sysfs entries for wlun altogether?

> They really meant nothing and shouldn't be there in the first place.

> What do you think?


Although if they were removed, ufs-bsg can access unit descriptors of wlun.
But it can be OK because developers are expected to access unit descriptors of wlun correctly.
So, I think it can be a solution.

> Thanks,

> Avri 

> > 

> > > +        else if (desc_index == UFS_UPIU_RPMB_WLUN)

> > > +                *desc_len = hba->desc_size[QUERY_DESC_IDN_UNIT_RPMB];

> > >          else

> > >                  *desc_len = hba->desc_size[desc_id];  }

> > 

> > Thanks,

> > Daejun

>  

>  

>
diff mbox series

Patch

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 579cf6f9e7a1..d0be8d4c8091 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -167,6 +167,7 @@  enum desc_idn {
 	QUERY_DESC_IDN_GEOMETRY		= 0x7,
 	QUERY_DESC_IDN_POWER		= 0x8,
 	QUERY_DESC_IDN_HEALTH           = 0x9,
+	QUERY_DESC_IDN_UNIT_RPMB	= 0xA,
 	QUERY_DESC_IDN_MAX,
 };
 
diff --git a/drivers/scsi/ufs/ufs_bsg.c b/drivers/scsi/ufs/ufs_bsg.c
index 39bf204c6ec3..fcb46c882f1c 100644
--- a/drivers/scsi/ufs/ufs_bsg.c
+++ b/drivers/scsi/ufs/ufs_bsg.c
@@ -11,11 +11,12 @@  static int ufs_bsg_get_query_desc_size(struct ufs_hba *hba, int *desc_len,
 {
 	int desc_size = be16_to_cpu(qr->length);
 	int desc_id = qr->idn;
+	int desc_index = qr->index;
 
 	if (desc_size <= 0)
 		return -EINVAL;
 
-	ufshcd_map_desc_id_to_length(hba, desc_id, desc_len);
+	ufshcd_map_desc_id_to_length(hba, desc_id, desc_index, desc_len);
 	if (!*desc_len)
 		return -EINVAL;
 
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 74ccfd2b80ce..eec1bc95391b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3319,11 +3319,13 @@  int ufshcd_query_descriptor_retry(struct ufs_hba *hba,
  * @desc_len: mapped desc length (out)
  */
 void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
-				  int *desc_len)
+				  int desc_index, int *desc_len)
 {
 	if (desc_id >= QUERY_DESC_IDN_MAX || desc_id == QUERY_DESC_IDN_RFU_0 ||
 	    desc_id == QUERY_DESC_IDN_RFU_1)
 		*desc_len = 0;
+	else if (desc_index == UFS_UPIU_RPMB_WLUN)
+		*desc_len = hba->desc_size[QUERY_DESC_IDN_UNIT_RPMB];
 	else
 		*desc_len = hba->desc_size[desc_id];
 }
@@ -3334,14 +3336,16 @@  static void ufshcd_update_desc_length(struct ufs_hba *hba,
 				      unsigned char desc_len)
 {
 	if (hba->desc_size[desc_id] == QUERY_DESC_MAX_SIZE &&
-	    desc_id != QUERY_DESC_IDN_STRING &&
-	    desc_index != UFS_UPIU_RPMB_WLUN)
+	    desc_id != QUERY_DESC_IDN_STRING) {
+		if (desc_index == UFS_UPIU_RPMB_WLUN)
 		/* 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.
+		 * desc_idn, but differ by the descriptor index
 		 */
-		hba->desc_size[desc_id] = desc_len;
+			hba->desc_size[QUERY_DESC_IDN_UNIT_RPMB] = desc_len;
+		else
+			hba->desc_size[desc_id] = desc_len;
+	}
 }
 
 /**
@@ -3372,7 +3376,7 @@  int ufshcd_read_desc_param(struct ufs_hba *hba,
 		return -EINVAL;
 
 	/* Get the length of descriptor */
-	ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
+	ufshcd_map_desc_id_to_length(hba, desc_id, desc_index, &buff_len);
 	if (!buff_len) {
 		dev_err(hba->dev, "%s: Failed to get desc length\n", __func__);
 		return -EINVAL;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 971cfabc4a1e..c77bef77ec87 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -1105,7 +1105,7 @@  int ufshcd_hold(struct ufs_hba *hba, bool async);
 void ufshcd_release(struct ufs_hba *hba);
 
 void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id,
-				  int *desc_length);
+				  int desc_index, int *desc_length);
 
 u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba);