RE: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-19 Thread Seungwon Jeon
On Thu, July 18, 2013, Sujit Reddy Thumma wrote:
   I'm not sure that BKOPS with runtime-pm associates.
   Do you think it's helpful for power management?
   How about hibernation scheme for runtime-pm?
   I'm testing and I can introduce soon.
  
  Well, I am thinking on following approach when we introduce
  power management.
  
  ufshcd_runtime_suspend() {
if (bkops_status = NON_CRITICAL) { /* 0x1 */
ufshcd_enable_auto_bkops();
hibernate(); /* only the link and the device
should be able to cary out bkops */
} else {
hibernate(); /* Link and the device for more savings */
}
  }
  
  Let me know if this is okay.
  I still consider whether BKOPS is proper behavior with runtime-pm or not.
 
 The BKOPS is something that host allows the card to carry out
 when the host knows it is idle and not expecting back to back requests.
 Runtime PM idle is the only way to know whether the device is
 idle (unless we want to reinvent the wheel to detect the idleness of
 host and trigger bkops). There was a discussion on this in MMC mailing
 list as well, and folks have agreed to move idle time bkops to runtime
 PM (http://thread.gmane.org/gmane.linux.kernel.mmc/19444/)
It looks like different.
eMMC cannot execute BKOPS itself unlike UFS.
That's the way eMMC's host should trigger the BKOPS manually.

 
  How about this scenario? It seems more simple.
  If we concern a response latency of transfer requests, BKOPS can be 
disabled by default.
  And then BKOPS can be enabled whenever device requests in some exception.
  If you have any idea, let me know.
 
 Exceptions are raised only when the device is in critical need for
 bkops. Also the spec. recommends, host should ensure that the device
 doesn't go into such states.
 
 With your suggestion, when we disable bkops, the exception is raised and
 we enable bkops after which there is no way to disable it again?
Yes, it's difficult to find proper time. 
Maybe, BKOPS can be disabled when request comes up.

Thanks,
Seungwon Jeon
 
 --
 Regards,
 Sujit
 --
 To unsubscribe from this list: send the line unsubscribe linux-scsi in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-19 Thread Sujit Reddy Thumma



I'm not sure that BKOPS with runtime-pm associates.
Do you think it's helpful for power management?
How about hibernation scheme for runtime-pm?
I'm testing and I can introduce soon.


Well, I am thinking on following approach when we introduce
power management.

ufshcd_runtime_suspend() {
if (bkops_status = NON_CRITICAL) { /* 0x1 */
ufshcd_enable_auto_bkops();
hibernate(); /* only the link and the device
should be able to cary out bkops */
} else {
hibernate(); /* Link and the device for more savings */
}
}

Let me know if this is okay.

I still consider whether BKOPS is proper behavior with runtime-pm or not.


The BKOPS is something that host allows the card to carry out
when the host knows it is idle and not expecting back to back requests.
Runtime PM idle is the only way to know whether the device is
idle (unless we want to reinvent the wheel to detect the idleness of
host and trigger bkops). There was a discussion on this in MMC mailing
list as well, and folks have agreed to move idle time bkops to runtime
PM (http://thread.gmane.org/gmane.linux.kernel.mmc/19444/)

It looks like different.
eMMC cannot execute BKOPS itself unlike UFS.
That's the way eMMC's host should trigger the BKOPS manually.



I guess it is not much of a difference for UFS as far as we concern
only about idle time bkops. In UFS one can still disallow the device to
not carry out BKOPS and hence the case where UFS device also cannot
execute BKOPS itself and a idle timer is needed to allow BKOPS
sporadically so that device doesn't go into URGENT_BKOPS state.




How about this scenario? It seems more simple.

  If we concern a response latency of transfer requests, BKOPS can be 
disabled by default.

And then BKOPS can be enabled whenever device requests in some exception.
If you have any idea, let me know.


Exceptions are raised only when the device is in critical need for
bkops. Also the spec. recommends, host should ensure that the device
doesn't go into such states.

With your suggestion, when we disable bkops, the exception is raised and
we enable bkops after which there is no way to disable it again?

Yes, it's difficult to find proper time.
Maybe, BKOPS can be disabled when request comes up.


In cases where there are back-to-back heavy data write requests then it
is not proper to enable/disable BKOPS as soon as the new request comes
up. It may happen that the card will then move from PERFORMANCE_IMPACT
state to CRITICAL and ultimately start failing the requests. The point
is that we should never get into state where we need URGENT_BKOPS.

--
Regards,
Sujit
--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-17 Thread Seungwon Jeon
On Thu, July 11, 2013, Sujit Reddy Thumma wrote:
 On 7/10/2013 7:01 PM, Seungwon Jeon wrote:
  I'm not sure that BKOPS with runtime-pm associates.
  Do you think it's helpful for power management?
  How about hibernation scheme for runtime-pm?
  I'm testing and I can introduce soon.
 
 Well, I am thinking on following approach when we introduce
 power management.
 
 ufshcd_runtime_suspend() {
   if (bkops_status = NON_CRITICAL) { /* 0x1 */
   ufshcd_enable_auto_bkops();
   hibernate(); /* only the link and the device
   should be able to cary out bkops */
   } else {
   hibernate(); /* Link and the device for more savings */
   }
 }
 
 Let me know if this is okay.
I still consider whether BKOPS is proper behavior with runtime-pm or not.
How about this scenario? It seems more simple.
If we concern a response latency of transfer requests, BKOPS can be disabled by 
default.
And then BKOPS can be enabled whenever device requests in some exception.
If you have any idea, let me know.

Thanks,
Seungwon Jeon

--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-17 Thread Sujit Reddy Thumma



 I'm not sure that BKOPS with runtime-pm associates.
 Do you think it's helpful for power management?
 How about hibernation scheme for runtime-pm?
 I'm testing and I can introduce soon.


Well, I am thinking on following approach when we introduce
power management.

ufshcd_runtime_suspend() {
if (bkops_status = NON_CRITICAL) { /* 0x1 */
ufshcd_enable_auto_bkops();
hibernate(); /* only the link and the device
should be able to cary out bkops */
} else {
hibernate(); /* Link and the device for more savings */
}
}

Let me know if this is okay.

I still consider whether BKOPS is proper behavior with runtime-pm or not.


The BKOPS is something that host allows the card to carry out
when the host knows it is idle and not expecting back to back requests.
Runtime PM idle is the only way to know whether the device is
idle (unless we want to reinvent the wheel to detect the idleness of
host and trigger bkops). There was a discussion on this in MMC mailing
list as well, and folks have agreed to move idle time bkops to runtime
PM (http://thread.gmane.org/gmane.linux.kernel.mmc/19444/)


How about this scenario? It seems more simple.
If we concern a response latency of transfer requests, BKOPS can be disabled by 
default.
And then BKOPS can be enabled whenever device requests in some exception.
If you have any idea, let me know.


Exceptions are raised only when the device is in critical need for
bkops. Also the spec. recommends, host should ensure that the device
doesn't go into such states.

With your suggestion, when we disable bkops, the exception is raised and 
we enable bkops after which there is no way to disable it again?


--
Regards,
Sujit
--
To unsubscribe from this list: send the line unsubscribe linux-arm-msm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-11 Thread Sujit Reddy Thumma

On 7/10/2013 7:01 PM, Seungwon Jeon wrote:

I'm not sure that BKOPS with runtime-pm associates.
Do you think it's helpful for power management?
How about hibernation scheme for runtime-pm?
I'm testing and I can introduce soon.


Well, I am thinking on following approach when we introduce
power management.

ufshcd_runtime_suspend() {
if (bkops_status = NON_CRITICAL) { /* 0x1 */
ufshcd_enable_auto_bkops();
hibernate(); /* only the link and the device
should be able to cary out bkops */
} else {
hibernate(); /* Link and the device for more savings */
}
}

Let me know if this is okay.



On Tue, July 09, 2013, Sujit Reddy Thumma wrote:

Background operations in the UFS device can be disabled by
the host to reduce the response latency of transfer requests.
Add support for enabling/disabling the background operations
during runtime suspend/resume of the device.

If the device is in critical need of BKOPS it will raise an
URGENT_BKOPS exception which should be handled by the host to
make sure the device performs as expected.

During bootup, the BKOPS is enabled in the device by default.
The disable of BKOPS is supported only when the driver supports
runtime suspend/resume operations as the runtime PM framework
provides a way to determine the device idleness and hence BKOPS
can be managed effectively. During runtime resume the BKOPS is
disabled to reduce latency and during runtime suspend the BKOPS
is enabled to allow device to carry out idle time BKOPS.

In some cases where the BKOPS is disabled during runtime resume
and due to continuous data transfers the runtime suspend is not
triggered, the BKOPS is enabled when the device raises a level-2
exception (outstanding operations - performance impact).

Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
---
  drivers/scsi/ufs/ufs.h|   25 -
  drivers/scsi/ufs/ufshcd.c |  338 +
  drivers/scsi/ufs/ufshcd.h |   10 ++
  3 files changed, 372 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index db5bde4..549a652 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -107,7 +107,29 @@ enum {

  /* Flag idn for Query Requests*/
  enum flag_idn {
-   QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
+   QUERY_FLAG_IDN_FDEVICEINIT  = 0x01,
+   QUERY_FLAG_IDN_BKOPS_EN = 0x04,
+};
+
+/* Attribute idn for Query requests */
+enum attr_idn {
+   QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
+   QUERY_ATTR_IDN_EE_CONTROL   = 0x0D,
+   QUERY_ATTR_IDN_EE_STATUS= 0x0E,
+};
+
+/* Exception event mask values */
+enum {
+   MASK_EE_STATUS  = 0x,
+   MASK_EE_URGENT_BKOPS= (1  2),
+};
+
+/* Background operation status */
+enum {
+   BKOPS_STATUS_NO_OP   = 0x0,
+   BKOPS_STATUS_NON_CRITICAL= 0x1,
+   BKOPS_STATUS_PERF_IMPACT = 0x2,
+   BKOPS_STATUS_CRITICAL= 0x3,
  };

  /* UTP QUERY Transaction Specific Fields OpCode */
@@ -156,6 +178,7 @@ enum {
MASK_TASK_RESPONSE  = 0xFF00,
MASK_RSP_UPIU_RESULT= 0x,
MASK_QUERY_DATA_SEG_LEN = 0x,
+   MASK_RSP_EXCEPTION_EVENT = 0x1,
  };

  /* Task management service response */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 96ccb28..a25de66 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -268,6 +268,21 @@ ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp 
*ucd_rsp_ptr)
  }

  /**
+ * ufshcd_is_exception_event - Check if the device raised an exception event
+ * @ucd_rsp_ptr: pointer to response UPIU
+ *
+ * The function checks if the device raised an exception event indicated in
+ * the Device Information field of response UPIU.
+ *
+ * Returns true if exception is raised, false otherwise.
+ */
+static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr)
+{
+   return be32_to_cpu(ucd_rsp_ptr-header.dword_2) 
+   MASK_RSP_EXCEPTION_EVENT ? true : false;
+}
+
+/**
   * ufshcd_config_int_aggr - Configure interrupt aggregation values.
   *Currently there is no use case where we want to configure
   *interrupt aggregation dynamically. So to configure interrupt
@@ -1174,6 +1189,86 @@ out_no_mem:
  }

  /**
+ * ufshcd_query_attr - Helper function for composing attribute requests
+ * hba: per-adapter instance
+ * opcode: attribute opcode
+ * idn: attribute idn to access
+ * index: index field
+ * selector: selector field
+ * attr_val: the attribute value after the query request completes
+ *
+ * Returns 0 for success, non-zero in case of failure
+*/
+int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
+   enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
+{
+   struct ufs_query_req *query;
+   struct ufs_query_res *response;
+   int 

RE: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-10 Thread Seungwon Jeon
I'm not sure that BKOPS with runtime-pm associates.
Do you think it's helpful for power management?
How about hibernation scheme for runtime-pm?
I'm testing and I can introduce soon.

On Tue, July 09, 2013, Sujit Reddy Thumma wrote:
 Background operations in the UFS device can be disabled by
 the host to reduce the response latency of transfer requests.
 Add support for enabling/disabling the background operations
 during runtime suspend/resume of the device.
 
 If the device is in critical need of BKOPS it will raise an
 URGENT_BKOPS exception which should be handled by the host to
 make sure the device performs as expected.
 
 During bootup, the BKOPS is enabled in the device by default.
 The disable of BKOPS is supported only when the driver supports
 runtime suspend/resume operations as the runtime PM framework
 provides a way to determine the device idleness and hence BKOPS
 can be managed effectively. During runtime resume the BKOPS is
 disabled to reduce latency and during runtime suspend the BKOPS
 is enabled to allow device to carry out idle time BKOPS.
 
 In some cases where the BKOPS is disabled during runtime resume
 and due to continuous data transfers the runtime suspend is not
 triggered, the BKOPS is enabled when the device raises a level-2
 exception (outstanding operations - performance impact).
 
 Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
 ---
  drivers/scsi/ufs/ufs.h|   25 -
  drivers/scsi/ufs/ufshcd.c |  338 
 +
  drivers/scsi/ufs/ufshcd.h |   10 ++
  3 files changed, 372 insertions(+), 1 deletions(-)
 
 diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
 index db5bde4..549a652 100644
 --- a/drivers/scsi/ufs/ufs.h
 +++ b/drivers/scsi/ufs/ufs.h
 @@ -107,7 +107,29 @@ enum {
 
  /* Flag idn for Query Requests*/
  enum flag_idn {
 - QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
 + QUERY_FLAG_IDN_FDEVICEINIT  = 0x01,
 + QUERY_FLAG_IDN_BKOPS_EN = 0x04,
 +};
 +
 +/* Attribute idn for Query requests */
 +enum attr_idn {
 + QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
 + QUERY_ATTR_IDN_EE_CONTROL   = 0x0D,
 + QUERY_ATTR_IDN_EE_STATUS= 0x0E,
 +};
 +
 +/* Exception event mask values */
 +enum {
 + MASK_EE_STATUS  = 0x,
 + MASK_EE_URGENT_BKOPS= (1  2),
 +};
 +
 +/* Background operation status */
 +enum {
 + BKOPS_STATUS_NO_OP   = 0x0,
 + BKOPS_STATUS_NON_CRITICAL= 0x1,
 + BKOPS_STATUS_PERF_IMPACT = 0x2,
 + BKOPS_STATUS_CRITICAL= 0x3,
  };
 
  /* UTP QUERY Transaction Specific Fields OpCode */
 @@ -156,6 +178,7 @@ enum {
   MASK_TASK_RESPONSE  = 0xFF00,
   MASK_RSP_UPIU_RESULT= 0x,
   MASK_QUERY_DATA_SEG_LEN = 0x,
 + MASK_RSP_EXCEPTION_EVENT = 0x1,
  };
 
  /* Task management service response */
 diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
 index 96ccb28..a25de66 100644
 --- a/drivers/scsi/ufs/ufshcd.c
 +++ b/drivers/scsi/ufs/ufshcd.c
 @@ -268,6 +268,21 @@ ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp 
 *ucd_rsp_ptr)
  }
 
  /**
 + * ufshcd_is_exception_event - Check if the device raised an exception event
 + * @ucd_rsp_ptr: pointer to response UPIU
 + *
 + * The function checks if the device raised an exception event indicated in
 + * the Device Information field of response UPIU.
 + *
 + * Returns true if exception is raised, false otherwise.
 + */
 +static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp 
 *ucd_rsp_ptr)
 +{
 + return be32_to_cpu(ucd_rsp_ptr-header.dword_2) 
 + MASK_RSP_EXCEPTION_EVENT ? true : false;
 +}
 +
 +/**
   * ufshcd_config_int_aggr - Configure interrupt aggregation values.
   *   Currently there is no use case where we want to configure
   *   interrupt aggregation dynamically. So to configure interrupt
 @@ -1174,6 +1189,86 @@ out_no_mem:
  }
 
  /**
 + * ufshcd_query_attr - Helper function for composing attribute requests
 + * hba: per-adapter instance
 + * opcode: attribute opcode
 + * idn: attribute idn to access
 + * index: index field
 + * selector: selector field
 + * attr_val: the attribute value after the query request completes
 + *
 + * Returns 0 for success, non-zero in case of failure
 +*/
 +int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
 + enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
 +{
 + struct ufs_query_req *query;
 + struct ufs_query_res *response;
 + int err = -ENOMEM;
 +
 + if (!attr_val) {
 + dev_err(hba-dev, %s: attribute value required for write 
 request\n,
It's trivial, but message is only focused on write.
attr_val is also needed in case read request.

Thanks,
Seungwon Jeon

 + __func__);
 + err = -EINVAL;
 + goto out;
 + }
 +
 + query = kzalloc(sizeof(struct ufs_query_req), GFP_KERNEL);
 + if (!query) {
 +  

[PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-09 Thread Sujit Reddy Thumma
Background operations in the UFS device can be disabled by
the host to reduce the response latency of transfer requests.
Add support for enabling/disabling the background operations
during runtime suspend/resume of the device.

If the device is in critical need of BKOPS it will raise an
URGENT_BKOPS exception which should be handled by the host to
make sure the device performs as expected.

During bootup, the BKOPS is enabled in the device by default.
The disable of BKOPS is supported only when the driver supports
runtime suspend/resume operations as the runtime PM framework
provides a way to determine the device idleness and hence BKOPS
can be managed effectively. During runtime resume the BKOPS is
disabled to reduce latency and during runtime suspend the BKOPS
is enabled to allow device to carry out idle time BKOPS.

In some cases where the BKOPS is disabled during runtime resume
and due to continuous data transfers the runtime suspend is not
triggered, the BKOPS is enabled when the device raises a level-2
exception (outstanding operations - performance impact).

Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
---
 drivers/scsi/ufs/ufs.h|   25 -
 drivers/scsi/ufs/ufshcd.c |  338 +
 drivers/scsi/ufs/ufshcd.h |   10 ++
 3 files changed, 372 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index db5bde4..549a652 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -107,7 +107,29 @@ enum {
 
 /* Flag idn for Query Requests*/
 enum flag_idn {
-   QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
+   QUERY_FLAG_IDN_FDEVICEINIT  = 0x01,
+   QUERY_FLAG_IDN_BKOPS_EN = 0x04,
+};
+
+/* Attribute idn for Query requests */
+enum attr_idn {
+   QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
+   QUERY_ATTR_IDN_EE_CONTROL   = 0x0D,
+   QUERY_ATTR_IDN_EE_STATUS= 0x0E,
+};
+
+/* Exception event mask values */
+enum {
+   MASK_EE_STATUS  = 0x,
+   MASK_EE_URGENT_BKOPS= (1  2),
+};
+
+/* Background operation status */
+enum {
+   BKOPS_STATUS_NO_OP   = 0x0,
+   BKOPS_STATUS_NON_CRITICAL= 0x1,
+   BKOPS_STATUS_PERF_IMPACT = 0x2,
+   BKOPS_STATUS_CRITICAL= 0x3,
 };
 
 /* UTP QUERY Transaction Specific Fields OpCode */
@@ -156,6 +178,7 @@ enum {
MASK_TASK_RESPONSE  = 0xFF00,
MASK_RSP_UPIU_RESULT= 0x,
MASK_QUERY_DATA_SEG_LEN = 0x,
+   MASK_RSP_EXCEPTION_EVENT = 0x1,
 };
 
 /* Task management service response */
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 96ccb28..a25de66 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -268,6 +268,21 @@ ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp 
*ucd_rsp_ptr)
 }
 
 /**
+ * ufshcd_is_exception_event - Check if the device raised an exception event
+ * @ucd_rsp_ptr: pointer to response UPIU
+ *
+ * The function checks if the device raised an exception event indicated in
+ * the Device Information field of response UPIU.
+ *
+ * Returns true if exception is raised, false otherwise.
+ */
+static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp *ucd_rsp_ptr)
+{
+   return be32_to_cpu(ucd_rsp_ptr-header.dword_2) 
+   MASK_RSP_EXCEPTION_EVENT ? true : false;
+}
+
+/**
  * ufshcd_config_int_aggr - Configure interrupt aggregation values.
  * Currently there is no use case where we want to configure
  * interrupt aggregation dynamically. So to configure interrupt
@@ -1174,6 +1189,86 @@ out_no_mem:
 }
 
 /**
+ * ufshcd_query_attr - Helper function for composing attribute requests
+ * hba: per-adapter instance
+ * opcode: attribute opcode
+ * idn: attribute idn to access
+ * index: index field
+ * selector: selector field
+ * attr_val: the attribute value after the query request completes
+ *
+ * Returns 0 for success, non-zero in case of failure
+*/
+int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
+   enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
+{
+   struct ufs_query_req *query;
+   struct ufs_query_res *response;
+   int err = -ENOMEM;
+
+   if (!attr_val) {
+   dev_err(hba-dev, %s: attribute value required for write 
request\n,
+   __func__);
+   err = -EINVAL;
+   goto out;
+   }
+
+   query = kzalloc(sizeof(struct ufs_query_req), GFP_KERNEL);
+   if (!query) {
+   dev_err(hba-dev,
+   %s: Failed allocating ufs_query_req instance\n,
+   __func__);
+   goto out;
+   }
+
+   response = kzalloc(sizeof(struct ufs_query_res), GFP_KERNEL);
+   if (!response) {
+   dev_err(hba-dev,
+   %s: Failed allocating ufs_query_res instance\n,
+   __func__);
+  

Re: [PATCH V3 1/2] scsi: ufs: Add support for host assisted background operations

2013-07-09 Thread merez
Tested-by: Maya Erez me...@codeaurora.org

 Background operations in the UFS device can be disabled by
 the host to reduce the response latency of transfer requests.
 Add support for enabling/disabling the background operations
 during runtime suspend/resume of the device.

 If the device is in critical need of BKOPS it will raise an
 URGENT_BKOPS exception which should be handled by the host to
 make sure the device performs as expected.

 During bootup, the BKOPS is enabled in the device by default.
 The disable of BKOPS is supported only when the driver supports
 runtime suspend/resume operations as the runtime PM framework
 provides a way to determine the device idleness and hence BKOPS
 can be managed effectively. During runtime resume the BKOPS is
 disabled to reduce latency and during runtime suspend the BKOPS
 is enabled to allow device to carry out idle time BKOPS.

 In some cases where the BKOPS is disabled during runtime resume
 and due to continuous data transfers the runtime suspend is not
 triggered, the BKOPS is enabled when the device raises a level-2
 exception (outstanding operations - performance impact).

 Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
 ---
  drivers/scsi/ufs/ufs.h|   25 -
  drivers/scsi/ufs/ufshcd.c |  338
 +
  drivers/scsi/ufs/ufshcd.h |   10 ++
  3 files changed, 372 insertions(+), 1 deletions(-)

 diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
 index db5bde4..549a652 100644
 --- a/drivers/scsi/ufs/ufs.h
 +++ b/drivers/scsi/ufs/ufs.h
 @@ -107,7 +107,29 @@ enum {

  /* Flag idn for Query Requests*/
  enum flag_idn {
 - QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
 + QUERY_FLAG_IDN_FDEVICEINIT  = 0x01,
 + QUERY_FLAG_IDN_BKOPS_EN = 0x04,
 +};
 +
 +/* Attribute idn for Query requests */
 +enum attr_idn {
 + QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
 + QUERY_ATTR_IDN_EE_CONTROL   = 0x0D,
 + QUERY_ATTR_IDN_EE_STATUS= 0x0E,
 +};
 +
 +/* Exception event mask values */
 +enum {
 + MASK_EE_STATUS  = 0x,
 + MASK_EE_URGENT_BKOPS= (1  2),
 +};
 +
 +/* Background operation status */
 +enum {
 + BKOPS_STATUS_NO_OP   = 0x0,
 + BKOPS_STATUS_NON_CRITICAL= 0x1,
 + BKOPS_STATUS_PERF_IMPACT = 0x2,
 + BKOPS_STATUS_CRITICAL= 0x3,
  };

  /* UTP QUERY Transaction Specific Fields OpCode */
 @@ -156,6 +178,7 @@ enum {
   MASK_TASK_RESPONSE  = 0xFF00,
   MASK_RSP_UPIU_RESULT= 0x,
   MASK_QUERY_DATA_SEG_LEN = 0x,
 + MASK_RSP_EXCEPTION_EVENT = 0x1,
  };

  /* Task management service response */
 diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
 index 96ccb28..a25de66 100644
 --- a/drivers/scsi/ufs/ufshcd.c
 +++ b/drivers/scsi/ufs/ufshcd.c
 @@ -268,6 +268,21 @@ ufshcd_get_rsp_upiu_result(struct utp_upiu_rsp
 *ucd_rsp_ptr)
  }

  /**
 + * ufshcd_is_exception_event - Check if the device raised an exception
 event
 + * @ucd_rsp_ptr: pointer to response UPIU
 + *
 + * The function checks if the device raised an exception event indicated
 in
 + * the Device Information field of response UPIU.
 + *
 + * Returns true if exception is raised, false otherwise.
 + */
 +static inline bool ufshcd_is_exception_event(struct utp_upiu_rsp
 *ucd_rsp_ptr)
 +{
 + return be32_to_cpu(ucd_rsp_ptr-header.dword_2) 
 + MASK_RSP_EXCEPTION_EVENT ? true : false;
 +}
 +
 +/**
   * ufshcd_config_int_aggr - Configure interrupt aggregation values.
   *   Currently there is no use case where we want to configure
   *   interrupt aggregation dynamically. So to configure interrupt
 @@ -1174,6 +1189,86 @@ out_no_mem:
  }

  /**
 + * ufshcd_query_attr - Helper function for composing attribute requests
 + * hba: per-adapter instance
 + * opcode: attribute opcode
 + * idn: attribute idn to access
 + * index: index field
 + * selector: selector field
 + * attr_val: the attribute value after the query request completes
 + *
 + * Returns 0 for success, non-zero in case of failure
 +*/
 +int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode,
 + enum attr_idn idn, u8 index, u8 selector, u32 *attr_val)
 +{
 + struct ufs_query_req *query;
 + struct ufs_query_res *response;
 + int err = -ENOMEM;
 +
 + if (!attr_val) {
 + dev_err(hba-dev, %s: attribute value required for write 
 request\n,
 + __func__);
 + err = -EINVAL;
 + goto out;
 + }
 +
 + query = kzalloc(sizeof(struct ufs_query_req), GFP_KERNEL);
 + if (!query) {
 + dev_err(hba-dev,
 + %s: Failed allocating ufs_query_req instance\n,
 + __func__);
 + goto out;
 + }
 +
 + response = kzalloc(sizeof(struct ufs_query_res), GFP_KERNEL);
 + if (!response) {
 + dev_err(hba-dev,
 + %s: