[PATCH 1/8] scsi: ufs: add support for query requests
From: Dolev Raviv dra...@codeaurora.org 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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com 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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN= 0xFD, + QUERY_RESULT_INVALID_OPCODE = 0xFE, + QUERY_RESULT_GENERAL_FAILURE= 0xFF,
[PATCH V2 1/9] scsi: ufs: add support for query requests
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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com 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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN= 0xFD, + QUERY_RESULT_INVALID_OPCODE = 0xFE, + QUERY_RESULT_GENERAL_FAILURE= 0xFF, +}; + /* UTP Transfer Request Command Type
Re: [SCSI] ufs: add support for query requests
On Tue, 2013-05-07 at 17:25 +0300, Dan Carpenter wrote: Hello Dolev Raviv, This is a semi-automatic email about new static checker warnings. The patch 3aee47c623a3: [SCSI] ufs: add support for query requests from May 2, 2013, leads to the following Smatch complaint: drivers/scsi/ufs/ufshcd.c:723 ufshcd_query_request() error: we previously assumed 'hba' could be null (see line 722) drivers/scsi/ufs/ufshcd.c 721 722 if (!hba || !query || !response) { New check. 723 dev_err(hba-dev, New dereference. 724 %s: NULL pointer hba = %p, query = %p response = %p\n, 725 __func__, hba, query, response); We don't actually have any callers of this function either, so nothing ever exercises the code. Given that we're not supposed to put stuff in the tree without a use case anyway, I can just remove it and then it can be resubmitted when the function has a user. This is fine, this patch introduce the infrastructure and the api. I could upload the api as part of the fDeviceInit patch that was sent before. James -- 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 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- 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
re: [SCSI] ufs: add support for query requests
Hello Dolev Raviv, This is a semi-automatic email about new static checker warnings. The patch 3aee47c623a3: [SCSI] ufs: add support for query requests from May 2, 2013, leads to the following Smatch complaint: drivers/scsi/ufs/ufshcd.c:723 ufshcd_query_request() error: we previously assumed 'hba' could be null (see line 722) drivers/scsi/ufs/ufshcd.c 721 722 if (!hba || !query || !response) { New check. 723 dev_err(hba-dev, New dereference. 724 %s: NULL pointer hba = %p, query = %p response = %p\n, 725 __func__, hba, query, response); regards, dan carpenter -- 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
Re: [SCSI] ufs: add support for query requests
On Tue, 2013-05-07 at 17:25 +0300, Dan Carpenter wrote: Hello Dolev Raviv, This is a semi-automatic email about new static checker warnings. The patch 3aee47c623a3: [SCSI] ufs: add support for query requests from May 2, 2013, leads to the following Smatch complaint: drivers/scsi/ufs/ufshcd.c:723 ufshcd_query_request() error: we previously assumed 'hba' could be null (see line 722) drivers/scsi/ufs/ufshcd.c 721 722if (!hba || !query || !response) { New check. 723dev_err(hba-dev, New dereference. 724%s: NULL pointer hba = %p, query = %p response = %p\n, 725__func__, hba, query, response); We don't actually have any callers of this function either, so nothing ever exercises the code. Given that we're not supposed to put stuff in the tree without a use case anyway, I can just remove it and then it can be resubmitted when the function has a user. James -- 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
Re: [PATCH 3/3] scsi: ufs: add support for query requests
Tested-by: Maya Erez me...@codeaurora.org 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 I don't think you want to force this on in every configuration since it's only appropriate to non server/desktop. I stripped this hunk. Hi James, Please apply the patch without the particular change or you can apply the latest patch sent by Dolev - http://marc.info/?l=linux-scsim=136774922024179w=1. Thanks, 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 -- Maya Erez QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- 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 V5] scsi: ufs: add support for query requests
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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com changes for v5: - Removed Kconfig change introduced by mistake - Removed redundant NULL pointer checks 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/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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, +
Re: [PATCH 3/3] scsi: ufs: add support for query requests
Hi James, I've noticed you haven't merged this patch. To avoid further problems I resent a V5 to this patch removing the Kconfig change. Dolev On Thu, 2013-05-02 at 17:25 +0530, Santosh Y wrote: From: Dolev Raviv dra...@codeaurora.org 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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com 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 I don't think you want to force this on in every configuration since it's only appropriate to non server/desktop. I stripped this hunk. James -- 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 -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- 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
Re: [PATCH 3/3] scsi: ufs: add support for query requests
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 I don't think you want to force this on in every configuration since it's only appropriate to non server/desktop. I stripped this hunk. Hi James, Please apply the patch without the particular change or you can apply the latest patch sent by Dolev - http://marc.info/?l=linux-scsim=136774922024179w=1. Thanks, 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
Re: [PATCH 3/3] scsi: ufs: add support for query requests
On Thu, 2013-05-02 at 17:25 +0530, Santosh Y wrote: From: Dolev Raviv dra...@codeaurora.org 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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com 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 I don't think you want to force this on in every configuration since it's only appropriate to non server/desktop. I stripped this hunk. James -- 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
Re: [PATCH V4] scsi: ufs: add support for query requests
+ +/** + * 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 3/3] scsi: ufs: add support for query requests
From: Dolev Raviv dra...@codeaurora.org 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 dra...@codeaurora.org Signed-off-by: Santosh Y santos...@gmail.com 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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE
[PATCH V4] scsi: ufs: add support for query requests
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 dra...@codeaurora.org --- 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 linux/mutex.h +#include linux/types.h + #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 {
[PATCH V3] scsi: ufs: add support for query requests
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 dra...@codeaurora.org --- 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/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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN=
[PATCH V3] scsi: ufs: add support for query requests
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 dra...@codeaurora.org --- 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/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 linux/mutex.h +#include linux/types.h + #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, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN= 0xFD, +
Re: [PATCH V2] scsi: ufs: add support for query requests
+ * 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; + + if (!lrbp) { + dev_err(hba-dev, %s: lrbp can not be NULL\n, __func__); + ret = -EINVAL; + } else if (!lrbp-ucd_req_ptr) { + dev_err(hba-dev, %s: ucd_req_ptr can not be NULL\n, + __func__); + ret = -EINVAL; + } else if (!lrbp-utr_descriptor_ptr) { + dev_err(hba-dev, %s: utr_descriptor_ptr can not be NULL\n, + __func__); + ret = -EINVAL; + } + if (!ret) + goto exit; + ufshcd_compose_upiu() is not being called from anywhere else other than ufshcd_queuecommand(), *lrbp* is being used before calling ufshcd_compose_upiu(). So, if lrbp is NULL, it will give a problem in ufshcd_queuecommand() itself and lrbp-ucd_req_ptr, lrbp-utr_descriptor_ptr are being configured in ufshcd_memory_config(). Also if lrbp can be NULL then why not hba? So, the right thing would be to remove these checks. switch (ocs) { case OCS_SUCCESS: - /* check if the returned transfer response is valid */ - result = ufshcd_is_valid_req_rsp(lrbp-ucd_rsp_ptr); + expected_rsp_code = ufshcd_is_query_req(lrbp) ? + UPIU_TRANSACTION_QUERY_RSP : UPIU_TRANSACTION_RESPONSE; + result = ufshcd_is_valid_req_rsp(lrbp-ucd_rsp_ptr, + expected_rsp_code); + if (result) { dev_err(hba-dev, Invalid response = %x\n, result); break; } - /* -* get the response UPIU result to extract -* the SCSI command status -*/ - result = ufshcd_get_rsp_upiu_result(lrbp-ucd_rsp_ptr); + if (ufshcd_is_query_req(lrbp)) { + /* +* Return result = ok, since SCSI layer wouldn't +* know how to handle errors from query requests. +* The result is saved with the response so that +* the ufs_core layer will handle it. +*/ + result |= DID_OK 16; + ufshcd_copy_query_response(hba, lrbp); + } else { + /* +* get the response UPIU result to extract +* the SCSI command status +*/ + result = ufshcd_get_rsp_upiu_result(lrbp-ucd_rsp_ptr); - /* -* get the result based on SCSI status response -* to notify the SCSI midlayer of the command status -*/ - scsi_status = result MASK_SCSI_STATUS; - result = ufshcd_scsi_cmd_status(lrbp, scsi_status); + /* +* get the result based on SCSI status response +* to notify the SCSI midlayer of the command status +*/ + scsi_status = result MASK_SCSI_STATUS; + result = ufshcd_scsi_cmd_status(lrbp, scsi_status); + } break; The following would be better, static int ufshcd_get_req_rsp(struct utp_upiu_rsp *ucd_rsp_ptr) { return (be32_to_cpu(ucd_rsp_ptr-header.dword_0) 24); } switch (ocs) { case OCS_SUCCESS: /* check if the returned transfer response is valid */ result = ufshcd_get_req_rsp(lrbp-ucd_rsp_ptr); switch (result) { case UPIU_TRANSACTION_RESPONSE: /* perform required steps */ break; case UPIU_TRANSACTION_QUERY_RSP: /* perform required steps */ break; case /* reject upiu */: you can add a check for Reject UPIU also if you want. /* return error */ break; default: /* return error */ } ... } -- ~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
Re: [PATCH V2] scsi: ufs: add support for query requests
Hi All, A minor bug was spotted, as shown blow. The fix will be submitted with the next version. +static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + u32 upiu_flags; + int ret = 0; + + if (!lrbp) { + dev_err(hba-dev, %s: lrbp can not be NULL\n, __func__); + ret = -EINVAL; + } else if (!lrbp-ucd_req_ptr) { + dev_err(hba-dev, %s: ucd_req_ptr can not be NULL\n, + __func__); + ret = -EINVAL; + } else if (!lrbp-utr_descriptor_ptr) { + dev_err(hba-dev, %s: utr_descriptor_ptr can not be NULL\n, + __func__); + ret = -EINVAL; + } + if (!ret) + goto exit; should be: if (ret) Thanks, Dolev -- QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- 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
Re: scsi: ufs: add support for query requests
Santosh, thank you very much for your comments. Most where adopted, others where replied inline. Please note the comment on removing ufs_coe.c file. I will appreciated your opinion on that. linux-...@vger.kernel.org is for UFS filesystem. The API for submitting a query request is ufs_query_request() in ufs_core.c. This function is responsible for: This can be part of ufshcd.c which is actually the core file, no need to create a new core file for the function. You are right and I moved it for now. But, I think that a good design that will allow easy extension and feature development, will be to separate the hci and features from the rest. + +#define UFS_QUERY_RESERVED_SCSI_CMD_SIZE 10 + Move this to ufs.h, The name seems too big, it can be changed to UFS_QUERY_CMD_SIZE. + if (!hba || !query || !response) { + pr_err(%s: NULL pointer hba = %p, query = %p response = %p, + __func__, hba, query, response); + return -EINVAL; + } The function will be called withing the driver, So, no need for these checks. The caller will/must pass the correct parameters. I disagree. Why not play it safe? Anyone can make this function accessible for IOCTLs or EXPORT it in future. In case they forget (most do), let's not leave holes. + /* + * A SCSI command structure is composed from opcode at the + * begining and 0 at the end. + */ + memset(cmd, 0, UFS_QUERY_RESERVED_SCSI_CMD_SIZE); + cmd[0] = UFS_QUERY_RESERVED_SCSI_CMD; Remove memset. Anyway only the first byte is being checked in ufshcd_is_query_req(); + * ufshcd_is_valid_query_rsp - checks if controller TR response is valid + * @ucd_rsp_ptr: pointer to response UPIU + * + * This function checks the response UPIU for valid transaction type in + * response field + * Returns 0 on success, non-zero on failure + */ +static inline int +ufshcd_is_valid_query_rsp(struct utp_upiu_rsp *ucd_rsp_ptr) Combine this with ufshcd_is_valid_req_rsp(), accordingly handle it in ufshcd_transfer_rsp_status(). +static inline void ufshcd_copy_query_response(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + struct ufs_query_res *query_res = hba-query.response; + u8 *descp = (u8 *)lrbp-ucd_rsp_ptr + GENERAL_UPIU_REQUEST_SIZE; This can be done inside the following if condition i.e. if (hba-query.descriptor != NULL). and change the condition to if (!hba-query.descriptor). + /* Get the descriptor */ + if (hba-query.descriptor != NULL lrbp-ucd_rsp_ptr-qr.opcode == + UPIU_QUERY_OPCODE_READ_DESC) { +static int ufshcd_compose_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct utp_upiu_req *ucd_req_ptr; Remove ucd_req_ptr, it is not doing anything. + if (!lrbp || !lrbp-cmd || !lrbp-ucd_req_ptr || + !lrbp-utr_descriptor_ptr) { + if (!lrbp) + pr_err(%s: lrbp can not be NULL, __func__); + if (!lrbp-cmd) + pr_err(%s: lrbp-cmd can not be NULL, __func__); +if (!lrbp-ucd_req_ptr) + pr_err(%s: ucd_req_ptr can not be NULL, __func__); + if (!lrbp-utr_descriptor_ptr) + pr_err(%s: utr_descriptor_ptr can not be NULL, + __func__); + ret = -EINVAL; + goto exit; + } I rather play it safe and not remove it. I rewrote it to make it cleaner. These are redundant, remove them. + if (ufshcd_is_query_req(lrbp)) + lrbp-command_type = UTP_CMD_TYPE_DEV_MANAGE; + else + lrbp-command_type = UTP_CMD_TYPE_SCSI; /* form UPIU before issuing the command */ - ufshcd_compose_upiu(lrbp); + ufshcd_compose_upiu(hba, lrbp); err = ufshcd_map_sg(lrbp); if (err) goto out; Why call ufshcd_map_sg() and scsi_dma_unmap() in ufshcd_transfer_req_compl() for requests of type UTP_CMD_TYPE_DEV_MANAGE? We are doing this since there is no harm calling it when the buffer is null, as well as this flow is responsible for setting the length parameter in the transfer request descriptor. Bottom line there is no need to split the original flow. ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) + if (ufshcd_is_query_req(lrbp)) + result = ufshcd_is_valid_query_rsp(lrbp-ucd_rsp_ptr); + else + result = ufshcd_is_valid_req_rsp(lrbp-ucd_rsp_ptr); + As already mentioned you can combine these. +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS = 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN = 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN = 0xFD, + QUERY_RESULT_INVALID_OPCODE = 0xFE, + QUERY_RESULT_GENERAL_FAILURE = 0xFF, +}; Move this to ufs.h. -- ~Santosh -- Dolev -- QUALCOMM ISRAEL, on behalf of
[PATCH V2] scsi: ufs: add support for query requests
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 dra...@codeaurora.org --- 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/ufs.h b/drivers/scsi/ufs/ufs.h index 139bc06..5d2208a 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -36,10 +36,20 @@ #ifndef _UFS_H #define _UFS_H +#include linux/mutex.h +#include linux/types.h + #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 */ @@ -90,6 +100,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 +119,21 @@ enum { UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8, }; +/* Query response result code */ +enum { + QUERY_RESULT_SUCCESS= 0x00, + QUERY_RESULT_NOT_READABLE = 0xF6, + QUERY_RESULT_NOT_WRITEABLE = 0xF7, + QUERY_RESULT_ALREADY_WRITTEN= 0xF8, + QUERY_RESULT_INVALID_LENGTH = 0xF9, + QUERY_RESULT_INVALID_VALUE = 0xFA, + QUERY_RESULT_INVALID_SELECTOR = 0xFB, + QUERY_RESULT_INVALID_INDEX = 0xFC, + QUERY_RESULT_INVALID_IDN= 0xFD, + QUERY_RESULT_INVALID_OPCODE = 0xFE, + QUERY_RESULT_GENERAL_FAILURE= 0xFF, +}; + /* UTP Transfer Request Command Type (CT) */ enum { UPIU_COMMAND_SET_TYPE_SCSI = 0x0, @@ -110,10 +141,17 @@ enum { UPIU_COMMAND_SET_TYPE_QUERY = 0x2, }; +/* UTP Transfer Request Command
Re: scsi: ufs: add support for query requests
This can be done inside the following if condition i.e. if (hba-query.descriptor != NULL). and change the condition to if (!hba-query.descriptor). I meant to write if (hba-query.descriptor)...:-) -- ~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] scsi: ufs: add support for query requests
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 ufs_core.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 dra...@codeaurora.org diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 1e5bd48..1ca46ca 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -1,4 +1,5 @@ # UFSHCD makefile obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o +obj-$(CONFIG_SCSI_UFSHCD) += ufs_core.o obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 139bc06..6b75014 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -36,10 +36,19 @@ #ifndef _UFS_H #define _UFS_H +#include linux/mutex.h +#include linux/types.h + #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 UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\ - ((byte3 24) | (byte2 16) |\ + cpu_to_be32((byte3 24) | (byte2 16) |\ (byte1 8) | (byte0)) /* @@ -62,7 +71,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 */ @@ -90,6 +99,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, @@ -110,10 +125,17 @@ enum { UPIU_COMMAND_SET_TYPE_QUERY = 0x2, }; +/* UTP Transfer Request Command Offset */ +#define UPIU_COMMAND_TYPE_OFFSET 28 + +/* Offset of the response code in the UPIU header */ +#define UPIU_RSP_CODE_OFFSET 8 + enum { MASK_SCSI_STATUS= 0xFF, MASK_TASK_RESPONSE = 0xFF00, MASK_RSP_UPIU_RESULT= 0x, + MASK_QUERY_DATA_SEG_LEN = 0x, }; /* Task management service response */ @@ -138,26 +160,59 @@ struct utp_upiu_header { /** * struct utp_upiu_cmd - Command UPIU structure - * @header: UPIU header structure DW-0 to DW-2 * @data_transfer_len: Data Transfer Length DW-3 * @cdb: Command Descriptor Block CDB