Re: [PATCH V4] scsi: ufs: add support for query requests

2013-05-02 Thread Santosh Y
> +
> +/**
> + * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU)
> + * @hba - UFS hba
> + * @lrb - pointer to local reference block
> + */
> +static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
> +{
> +   u32 upiu_flags;
> +   int ret = 0;
> +
> +   switch (lrbp->command_type) {
> +   case UTP_CMD_TYPE_SCSI:
> case UTP_CMD_TYPE_DEV_MANAGE:
> -   /* For query function implementation */
> +   ufshcd_prepare_req_desc(lrbp, &upiu_flags);
> +   if (lrbp->cmd && lrbp->command_type == UTP_CMD_TYPE_SCSI)

Sorry, probably missed it in the initial review. Here no need to check
for 'lrbp->cmd'.

> +   ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
> +   else if (lrbp->cmd)

no need to check here also

> +   ufshcd_prepare_utp_query_req_upiu(hba, lrbp,
> +   upiu_flags);
> +   else {
> +   dev_err(hba->dev, "%s: Invalid UPIU request\n",
> +   __func__);
> +   ret = -EINVAL;
> +   }

remove this else part, this condition will never be true.

> break;
> case UTP_CMD_TYPE_UFS:
> /* For UFS native command implementation */
> +   dev_err(hba->dev, "%s: UFS native command are not 
> supported\n",
> +   __func__);
> +   ret = -ENOTSUPP;
> +   break;
> +   default:
> +   ret = -ENOTSUPP;
> +   dev_err(hba->dev, "%s: unknown command type: 0x%x\n",
> +   __func__, lrbp->command_type);
> break;
> } /* end of switch */
> +
> +   return ret;
>  }
>


-- 
~Santosh
--
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


[PATCH V4] scsi: ufs: add support for query requests

2013-05-01 Thread Dolev Raviv
Add support for sending UFS query requests through tagged command
queuing. This design allows queuing query requests in any open slot
along with other SCSI commands. In this way there is no need to
save a slot in the requests queue and decrease its size.

A query request is posing to a SCSI command to use native flow. But
unlike normal SCSI command flow, the data and response fields are
filled in UFS host data structure instead of passing as arguments
while queuing into SCSI mlqueue (mid-layer SCSI queue, the requests
from this queue are submitted to the device queue). As per specification
only one query request is allowed to be processed by device. Hence a
mutex lock for protecting data and response fields (hba->query.request and
hba->query.response) needs to be held while query request is in
progress.

The API for submitting a query request is ufs_query_request() in
ufshcd.c. This function is responsible for:
1. Obtaining the SCSI device from the host
2. Keeping the query mutex to prevent multiple queries
3. Storing the required data for sending a query request in ufs_hba
4. Queuing a SCSI vendor specific command to trigger a query request
   in the UFS driver.

The callers of ufs_query_request() are expected to fill the query
command data fields and are to provide an allocated response field
for the driver to fill response fields after request completion.

The request and response upiu is extended in a union to enable using the
same data structure, both for command upiu and query request upiu.

The query request flow is separated from the scsi command flow in:
1. Preparing the request
2. Validating response (error) codes
3. Copying data (only used for descriptor read/write query requests)
4. Copying response/sense

Data error can't be handled in the scsi command native flow. Hence,
we pass the code as without a change back to the submitting layer.

UPIU (UFS Protocol Information Unit) size is increased to 512 bytes
from 128. The UPIU header and the transaction specific fields (SCSI
command or Query Request OSF - Op-code Specific Fields) are 32 bytes
together, the rest is used to transfer extra request data (such as
descriptor in query requests). In order to accommodate the largest
descriptor in the UFS spec (256 bytes) we need to increase the UPIU
size.

Signed-off-by: Dolev Raviv 
---
changes for v4:
- Removed un-necessary inline modifiers
- Fixed return values to SCSI layer on completion
changes for v3:
- Reworked validating response UPIU
- Removed redundant NULL pointer checks
changes for v2:
- Moved ufs_query_request to ufshcd.c and removed ufs_core.c
- Addressed Santosh's comments



diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 35faf24..82417d6 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -35,6 +35,7 @@
 config SCSI_UFSHCD
tristate "Universal Flash Storage Controller Driver Core"
depends on SCSI
+   default y
---help---
This selects the support for UFS devices in Linux, say Y and make
  sure that you know the name of your UFS host adapter (the card
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 139bc06..086ff03 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -36,10 +36,20 @@
 #ifndef _UFS_H
 #define _UFS_H
 
+#include 
+#include 
+
 #define MAX_CDB_SIZE   16
+#define GENERAL_UPIU_REQUEST_SIZE 32
+#define UPIU_HEADER_DATA_SEGMENT_MAX_SIZE  ((ALIGNED_UPIU_SIZE) - \
+   (GENERAL_UPIU_REQUEST_SIZE))
+#define QUERY_OSF_SIZE ((GENERAL_UPIU_REQUEST_SIZE) - \
+   (sizeof(struct utp_upiu_header)))
+#define UFS_QUERY_RESERVED_SCSI_CMD 0xCC
+#define UFS_QUERY_CMD_SIZE 10
 
 #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\
-   ((byte3 << 24) | (byte2 << 16) |\
+   cpu_to_be32((byte3 << 24) | (byte2 << 16) |\
 (byte1 << 8) | (byte0))
 
 /*
@@ -62,7 +72,7 @@ enum {
UPIU_TRANSACTION_COMMAND= 0x01,
UPIU_TRANSACTION_DATA_OUT   = 0x02,
UPIU_TRANSACTION_TASK_REQ   = 0x04,
-   UPIU_TRANSACTION_QUERY_REQ  = 0x26,
+   UPIU_TRANSACTION_QUERY_REQ  = 0x16,
 };
 
 /* UTP UPIU Transaction Codes Target to Initiator */
@@ -73,6 +83,7 @@ enum {
UPIU_TRANSACTION_TASK_RSP   = 0x24,
UPIU_TRANSACTION_READY_XFER = 0x31,
UPIU_TRANSACTION_QUERY_RSP  = 0x36,
+   UPIU_TRANSACTION_REJECT_UPIU= 0x3F,
 };
 
 /* UPIU Read/Write flags */
@@ -90,6 +101,12 @@ enum {
UPIU_TASK_ATTR_ACA  = 0x03,
 };
 
+/* UPIU Query request function */
+enum {
+   UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01,
+   UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
+};
+
 /* UTP QUERY Transaction Specific Fields OpCode */
 enum {
UPIU_QUERY_OPCODE_NOP   = 0x0,
@@ -103,6 +120,21 @@ enum {
UPIU_QUERY_OPCODE_TOGGLE_FLAG   = 0x8,
 };
 
+