RE: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-06 Thread Avri Altman
Ok thanks.
Will test and those as the first 2 patches in the series.

Thanks a lot,
Avri

> -Original Message-
> From: Christoph Hellwig 
> Sent: Wednesday, September 05, 2018 8:15 PM
> To: Avri Altman 
> Cc: Christoph Hellwig ; Johannes Thumshirn
> ; Hannes Reinecke ; Bart Van Assche
> ; James E.J. Bottomley
> ; Martin K. Petersen
> ; linux-scsi@vger.kernel.org; Stanislav Nijnikov
> ; Avi Shchislowski
> ; Alex Lemberg ;
> Subhash Jadavani ; Vinayak Holikatti
> 
> Subject: Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request
> 
> On Wed, Sep 05, 2018 at 07:08:50PM +0200, Christoph Hellwig wrote:
> > On Wed, Sep 05, 2018 at 03:53:41PM +, Avri Altman wrote:
> > > But on the other hand, task management request and response UPIUs
> > > are honorable members of the ufs spec (JEDEC 220C paragraphs 10.7.6 &
> 10.7.7).
> > > and indeed they lives in ufs.h, where they should.
> >
> > There is no other use anywhere.  Remember that there is no need to
> > have C data structure match what is in the spec, in fact doing so
> > often leads to worse code, which is why we often avoid it.
> >
> > I'll send out a little series (untested) to show how I'd like to see
> > this task menagement code look like.
> 
> Ok, the wifi at the meeting I'm at right now doesn't allow sending
> mail, so here are the patches as an attachment.


Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-05 Thread Christoph Hellwig
On Wed, Sep 05, 2018 at 07:08:50PM +0200, Christoph Hellwig wrote:
> On Wed, Sep 05, 2018 at 03:53:41PM +, Avri Altman wrote:
> > But on the other hand, task management request and response UPIUs
> > are honorable members of the ufs spec (JEDEC 220C paragraphs 10.7.6 & 
> > 10.7.7).
> > and indeed they lives in ufs.h, where they should.
> 
> There is no other use anywhere.  Remember that there is no need to
> have C data structure match what is in the spec, in fact doing so
> often leads to worse code, which is why we often avoid it.
> 
> I'll send out a little series (untested) to show how I'd like to see
> this task menagement code look like.

Ok, the wifi at the meeting I'm at right now doesn't allow sending
mail, so here are the patches as an attachment.
>From 895b2ef4ada52a9c233853c63777faab32a47221 Mon Sep 17 00:00:00 2001
From: Christoph Hellwig 
Date: Wed, 5 Sep 2018 06:31:16 -0700
Subject: scsi: ufs: cleanup struct utp_task_req_desc

Remove the pointless task_req_upiu and task_rsp_upiu indirections,
which are __le32 arrays always cast to given structures and just add
the members directly.  Also clean up variables names in use in the
callers a bit to make the code more readable.

Signed-off-by: Christoph Hellwig 
---
 drivers/scsi/ufs/ufs.h| 30 -
 drivers/scsi/ufs/ufshcd.c | 68 ---
 drivers/scsi/ufs/ufshci.h | 25 +++---
 3 files changed, 34 insertions(+), 89 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 14e5bf7af0bb..16230df242f9 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -519,36 +519,6 @@ struct utp_upiu_rsp {
 	};
 };
 
-/**
- * struct utp_upiu_task_req - Task request UPIU structure
- * @header - UPIU header structure DW0 to DW-2
- * @input_param1: Input parameter 1 DW-3
- * @input_param2: Input parameter 2 DW-4
- * @input_param3: Input parameter 3 DW-5
- * @reserved: Reserved double words DW-6 to DW-7
- */
-struct utp_upiu_task_req {
-	struct utp_upiu_header header;
-	__be32 input_param1;
-	__be32 input_param2;
-	__be32 input_param3;
-	__be32 reserved[2];
-};
-
-/**
- * struct utp_upiu_task_rsp - Task Management Response UPIU structure
- * @header: UPIU header structure DW0-DW-2
- * @output_param1: Ouput parameter 1 DW3
- * @output_param2: Output parameter 2 DW4
- * @reserved: Reserved double words DW-5 to DW-7
- */
-struct utp_upiu_task_rsp {
-	struct utp_upiu_header header;
-	__be32 output_param1;
-	__be32 output_param2;
-	__be32 reserved[3];
-};
-
 /**
  * struct ufs_query_req - parameters for building a query request
  * @query_func: UPIU header query function
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9d5d2ca7fc4f..178bbf7ed19e 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -326,14 +326,11 @@ static void ufshcd_add_query_upiu_trace(struct ufs_hba *hba, unsigned int tag,
 static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
 		const char *str)
 {
-	struct utp_task_req_desc *descp;
-	struct utp_upiu_task_req *task_req;
 	int off = (int)tag - hba->nutrs;
+	struct utp_task_req_desc *descp = >utmrdl_base_addr[off];
 
-	descp = >utmrdl_base_addr[off];
-	task_req = (struct utp_upiu_task_req *)descp->task_req_upiu;
-	trace_ufshcd_upiu(dev_name(hba->dev), str, _req->header,
-			_req->input_param1);
+	trace_ufshcd_upiu(dev_name(hba->dev), str, >req_header,
+			>input_param1);
 }
 
 static void ufshcd_add_command_trace(struct ufs_hba *hba,
@@ -475,22 +472,13 @@ void ufshcd_print_trs(struct ufs_hba *hba, unsigned long bitmap, bool pr_prdt)
 
 static void ufshcd_print_tmrs(struct ufs_hba *hba, unsigned long bitmap)
 {
-	struct utp_task_req_desc *tmrdp;
 	int tag;
 
 	for_each_set_bit(tag, , hba->nutmrs) {
-		tmrdp = >utmrdl_base_addr[tag];
+		struct utp_task_req_desc *tmrdp = >utmrdl_base_addr[tag];
+
 		dev_err(hba->dev, "TM[%d] - Task Management Header\n", tag);
-		ufshcd_hex_dump("TM TRD: ", >header,
-sizeof(struct request_desc_header));
-		dev_err(hba->dev, "TM[%d] - Task Management Request UPIU\n",
-tag);
-		ufshcd_hex_dump("TM REQ: ", tmrdp->task_req_upiu,
-sizeof(struct utp_upiu_req));
-		dev_err(hba->dev, "TM[%d] - Task Management Response UPIU\n",
-tag);
-		ufshcd_hex_dump("TM RSP: ", tmrdp->task_rsp_upiu,
-sizeof(struct utp_task_req_desc));
+		ufshcd_hex_dump("", tmrdp, sizeof(*tmrdp));
 	}
 }
 
@@ -4610,31 +4598,22 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev)
  */
 static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index, u8 *resp)
 {
-	struct utp_task_req_desc *task_req_descp;
-	struct utp_upiu_task_rsp *task_rsp_upiup;
+	struct utp_task_req_desc *treq = hba->utmrdl_base_addr + index;
 	unsigned long flags;
 	int ocs_value;
-	int task_result;
 
 	spin_lock_irqsave(hba->host->host_lock, flags);
 
 	/* Clear completed tasks from outstanding_tasks */
 	__clear_bit(index, >outstanding_tasks);
 
-	task_req_descp = hba->utmrdl_base_addr;
-	ocs_value 

Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-05 Thread Christoph Hellwig
On Wed, Sep 05, 2018 at 03:53:41PM +, Avri Altman wrote:
> But on the other hand, task management request and response UPIUs
> are honorable members of the ufs spec (JEDEC 220C paragraphs 10.7.6 & 10.7.7).
> and indeed they lives in ufs.h, where they should.

There is no other use anywhere.  Remember that there is no need to
have C data structure match what is in the spec, in fact doing so
often leads to worse code, which is why we often avoid it.

I'll send out a little series (untested) to show how I'd like to see
this task menagement code look like.


RE: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-05 Thread Avri Altman


> On Wed, Sep 05, 2018 at 07:30:03AM +, Avri Altman wrote:
> > Looking into the UFSHCI spec (JESD223C March 2016) paragraph 6.2,
> > It doesn't specify any inner structure of the task management
> > request or response, just a bunch of 8 DW each.
> > I guess this is why it is defined as a __le32 array.
> >
> > So the host controller is not aware of the inner structure of this
> > Sequence, and probably shouldn't. Making it aware of that,
> > e.g. by moving utp_upiu_task_req and utp_upiu_task_rsp
> > from ufs.h to ufshci.h will break this abstraction.
> 
> Well, then just kill struct utp_upiu_task_req entirely and use
> the dwords form the spec.
But on the other hand, task management request and response UPIUs
are honorable members of the ufs spec (JEDEC 220C paragraphs 10.7.6 & 10.7.7).
and indeed they lives in ufs.h, where they should.
So just removing it, replacing it with an opaque array is pointless.

Trying to understand why this is happening for task management requests,
But not for device management requests, I came to realized that you were 
originally right
Saying: " I think someone needs to untangle how the data structures are used in 
this part of the code."

Unlike utrd-typed requests (scsi & device management), that have their memory 
space
properly configured (utrdl_base_addr in ufshcd_host_memory_configure()),
task management requests - utmrd-typed requests (utmrdl_base_addr) do not get 
similar attention.

Will fix that in a separate patch prior to this one.

Thanks,
Avri


Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-05 Thread Christoph Hellwig
On Wed, Sep 05, 2018 at 07:30:03AM +, Avri Altman wrote:
> Looking into the UFSHCI spec (JESD223C March 2016) paragraph 6.2,
> It doesn't specify any inner structure of the task management
> request or response, just a bunch of 8 DW each.
> I guess this is why it is defined as a __le32 array.
> 
> So the host controller is not aware of the inner structure of this
> Sequence, and probably shouldn't. Making it aware of that,
> e.g. by moving utp_upiu_task_req and utp_upiu_task_rsp 
> from ufs.h to ufshci.h will break this abstraction.

Well, then just kill struct utp_upiu_task_req entirely and use
the dwords form the spec.


RE: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-05 Thread Avri Altman



> -Original Message-
> From: linux-scsi-ow...@vger.kernel.org 
> On Behalf Of Christoph Hellwig
> Sent: Tuesday, September 04, 2018 10:12 PM
> To: Avri Altman 
> Cc: Christoph Hellwig ; Johannes Thumshirn
> ; Hannes Reinecke ; Bart Van Assche
> ; James E.J. Bottomley
> ; Martin K. Petersen
> ; linux-scsi@vger.kernel.org; Stanislav Nijnikov
> ; Avi Shchislowski
> ; Alex Lemberg ;
> Subhash Jadavani ; Vinayak Holikatti
> 
> Subject: Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request
> 
> In general this looks good, but a question below:
> 
> > index ed37914..d18832a 100644
> > --- a/drivers/scsi/ufs/ufshcd.c
> > +++ b/drivers/scsi/ufs/ufshcd.c
> > @@ -5598,6 +5598,32 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba
> *hba, int tag)
> > return err;
> >  }
> >
> > +static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
> > +  int lun_id, int task_id, u8 tm_function,
> > +  int task_tag)
> > +{
> > +   struct utp_upiu_task_req *task_req_upiup;
> > +
> > +   /* Configure task request descriptor */
> > +   task_req_descp->header.dword_0 =
> cpu_to_le32(UTP_REQ_DESC_INT_CMD);
> > +   task_req_descp->header.dword_2 =
> > +   cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
> > +
> > +   task_req_upiup =
> > +   (struct utp_upiu_task_req *)task_req_descp->task_req_upiu;
> 
> 
> Why is task_req_upiu a __le32 array instead of using the proper
> structure?
Looking into the UFSHCI spec (JESD223C March 2016) paragraph 6.2,
It doesn't specify any inner structure of the task management
request or response, just a bunch of 8 DW each.
I guess this is why it is defined as a __le32 array.

So the host controller is not aware of the inner structure of this
Sequence, and probably shouldn't. Making it aware of that,
e.g. by moving utp_upiu_task_req and utp_upiu_task_rsp 
from ufs.h to ufshci.h will break this abstraction.

> 
> Doing that would nicely clean up the code:
> 
> static void ufshcd_fill_tm_req(struct utp_task_req_desc *treq,
>  int lun_id, int task_id, u8 tm_function,
>  int task_tag)
> {
>   /* Configure task request descriptor */
>   treq->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
>   treq->header.dword_2 =
> cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
> 
>   treq->task_req_upiup->header.dword_0 =
>   UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0,
> lun_id,
> task_tag);
>   treq->task_req_upiup->header.dword_1 =
>   UPIU_HEADER_DWORD(0, tm_function, 0, 0);
>   treq->task_req_upiup->input_param1 = cpu_to_be32(lun_id);
>   treq->task_req_upiup->input_param2 = cpu_to_be32(task_id);
> }


Re: [PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-04 Thread Christoph Hellwig
In general this looks good, but a question below:

> index ed37914..d18832a 100644
> --- a/drivers/scsi/ufs/ufshcd.c
> +++ b/drivers/scsi/ufs/ufshcd.c
> @@ -5598,6 +5598,32 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, 
> int tag)
>   return err;
>  }
>  
> +static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
> +int lun_id, int task_id, u8 tm_function,
> +int task_tag)
> +{
> + struct utp_upiu_task_req *task_req_upiup;
> +
> + /* Configure task request descriptor */
> + task_req_descp->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
> + task_req_descp->header.dword_2 =
> + cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
> +
> + task_req_upiup =
> + (struct utp_upiu_task_req *)task_req_descp->task_req_upiu;


Why is task_req_upiu a __le32 array instead of using the proper
structure?

Doing that would nicely clean up the code:

static void ufshcd_fill_tm_req(struct utp_task_req_desc *treq,
   int lun_id, int task_id, u8 tm_function,
   int task_tag)
{
/* Configure task request descriptor */
treq->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
treq->header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);

treq->task_req_upiup->header.dword_0 =
UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0, lun_id,
  task_tag);
treq->task_req_upiup->header.dword_1 =
UPIU_HEADER_DWORD(0, tm_function, 0, 0);
treq->task_req_upiup->input_param1 = cpu_to_be32(lun_id);
treq->task_req_upiup->input_param2 = cpu_to_be32(task_id);
}


[PATCH v3 3/7] scsi: ufs: Add fill task management request

2018-09-03 Thread Avri Altman
Do that in preparation to re-use ufshcd_issue_tm_cmd code.

Signed-off-by: Avri Altman 
---
 drivers/scsi/ufs/ufshcd.c | 50 +++
 1 file changed, 29 insertions(+), 21 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index ed37914..d18832a 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5598,6 +5598,32 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int 
tag)
return err;
 }
 
+static void ufshcd_fill_tm_req(struct utp_task_req_desc *task_req_descp,
+  int lun_id, int task_id, u8 tm_function,
+  int task_tag)
+{
+   struct utp_upiu_task_req *task_req_upiup;
+
+   /* Configure task request descriptor */
+   task_req_descp->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
+   task_req_descp->header.dword_2 =
+   cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
+
+   task_req_upiup =
+   (struct utp_upiu_task_req *)task_req_descp->task_req_upiu;
+   task_req_upiup->header.dword_0 =
+   UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0, lun_id,
+ task_tag);
+   task_req_upiup->header.dword_1 = UPIU_HEADER_DWORD(0, tm_function, 0,
+  0);
+   /*
+* The host shall provide the same value for LUN field in the basic
+* header and for Input Parameter.
+*/
+   task_req_upiup->input_param1 = cpu_to_be32(lun_id);
+   task_req_upiup->input_param2 = cpu_to_be32(task_id);
+}
+
 /**
  * ufshcd_issue_tm_cmd - issues task management commands to controller
  * @hba: per adapter instance
@@ -5612,7 +5638,6 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int 
lun_id, int task_id,
u8 tm_function, u8 *tm_response)
 {
struct utp_task_req_desc *task_req_descp;
-   struct utp_upiu_task_req *task_req_upiup;
struct Scsi_Host *host;
unsigned long flags;
int free_slot;
@@ -5632,27 +5657,10 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int 
lun_id, int task_id,
spin_lock_irqsave(host->host_lock, flags);
task_req_descp = hba->utmrdl_base_addr;
task_req_descp += free_slot;
-
-   /* Configure task request descriptor */
-   task_req_descp->header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
-   task_req_descp->header.dword_2 =
-   cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
-
-   /* Configure task request UPIU */
-   task_req_upiup =
-   (struct utp_upiu_task_req *) task_req_descp->task_req_upiu;
task_tag = hba->nutrs + free_slot;
-   task_req_upiup->header.dword_0 =
-   UPIU_HEADER_DWORD(UPIU_TRANSACTION_TASK_REQ, 0,
- lun_id, task_tag);
-   task_req_upiup->header.dword_1 =
-   UPIU_HEADER_DWORD(0, tm_function, 0, 0);
-   /*
-* The host shall provide the same value for LUN field in the basic
-* header and for Input Parameter.
-*/
-   task_req_upiup->input_param1 = cpu_to_be32(lun_id);
-   task_req_upiup->input_param2 = cpu_to_be32(task_id);
+
+   ufshcd_fill_tm_req(task_req_descp, lun_id, task_id, tm_function,
+  task_tag);
 
ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function);
 
-- 
1.9.1