aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs/ufshcd.h
diff options
context:
space:
mode:
authorSujit Reddy Thumma <sthumma@codeaurora.org>2013-07-30 00:35:57 +0530
committerJames Bottomley <JBottomley@Parallels.com>2013-08-26 12:50:39 +0400
commit5a0b0cb9bee767ef10ff9ce2fb4141af06416288 (patch)
tree42d6f09b2c724885e2b6ada7778789548fb9ae6f /drivers/scsi/ufs/ufshcd.h
parent[SCSI] libiscsi: Add missing prints for session and connection sysfs attrs (diff)
downloadlinux-dev-5a0b0cb9bee767ef10ff9ce2fb4141af06416288.tar.xz
linux-dev-5a0b0cb9bee767ef10ff9ce2fb4141af06416288.zip
[SCSI] ufs: Add support for sending NOP OUT UPIU
As part of device initialization sequence, sending NOP OUT UPIU and waiting for NOP IN UPIU response is mandatory. This confirms that the device UFS Transport (UTP) layer is functional and the host can configure the device with further commands. Add support for sending NOP OUT UPIU to check the device connection path and test whether the UTP layer on the device side is functional during initialization. A tag is acquired from the SCSI tag map space in order to send the device management command. When the tag is acquired by internal command the scsi command is rejected with host busy flag in order to requeue the request. To avoid frequent collisions between internal commands and scsi commands the device management command tag is allocated in the opposite direction w.r.t block layer tag allocation. Signed-off-by: Sujit Reddy Thumma <sthumma@codeaurora.org> Signed-off-by: Dolev Raviv <draviv@codeaurora.org> Signed-off-by: Santosh Y <santoshsy@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/ufs/ufshcd.h')
-rw-r--r--drivers/scsi/ufs/ufshcd.h29
1 files changed, 27 insertions, 2 deletions
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 49590ee07acc..c750a90eb9da 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -68,6 +68,10 @@
#define UFSHCD "ufshcd"
#define UFSHCD_DRIVER_VERSION "0.2"
+enum dev_cmd_type {
+ DEV_CMD_TYPE_NOP = 0x0,
+};
+
/**
* struct uic_command - UIC command structure
* @command: UIC command
@@ -91,7 +95,7 @@ struct uic_command {
/**
* struct ufshcd_lrb - local reference block
* @utr_descriptor_ptr: UTRD address of the command
- * @ucd_cmd_ptr: UCD address of the command
+ * @ucd_req_ptr: UCD address of the command
* @ucd_rsp_ptr: Response UPIU address for this command
* @ucd_prdt_ptr: PRDT address of the command
* @cmd: pointer to SCSI command
@@ -101,10 +105,11 @@ struct uic_command {
* @command_type: SCSI, UFS, Query.
* @task_tag: Task tag of the command
* @lun: LUN of the command
+ * @intr_cmd: Interrupt command (doesn't participate in interrupt aggregation)
*/
struct ufshcd_lrb {
struct utp_transfer_req_desc *utr_descriptor_ptr;
- struct utp_upiu_cmd *ucd_cmd_ptr;
+ struct utp_upiu_req *ucd_req_ptr;
struct utp_upiu_rsp *ucd_rsp_ptr;
struct ufshcd_sg_entry *ucd_prdt_ptr;
@@ -116,8 +121,22 @@ struct ufshcd_lrb {
int command_type;
int task_tag;
unsigned int lun;
+ bool intr_cmd;
};
+/**
+ * struct ufs_dev_cmd - all assosiated fields with device management commands
+ * @type: device management command type - Query, NOP OUT
+ * @lock: lock to allow one command at a time
+ * @complete: internal commands completion
+ * @tag_wq: wait queue until free command slot is available
+ */
+struct ufs_dev_cmd {
+ enum dev_cmd_type type;
+ struct mutex lock;
+ struct completion *complete;
+ wait_queue_head_t tag_wq;
+};
/**
* struct ufs_hba - per adapter private structure
@@ -131,6 +150,7 @@ struct ufshcd_lrb {
* @host: Scsi_Host instance of the driver
* @dev: device handle
* @lrb: local reference block
+ * @lrb_in_use: lrb in use
* @outstanding_tasks: Bits representing outstanding task requests
* @outstanding_reqs: Bits representing outstanding transfer requests
* @capabilities: UFS Controller Capabilities
@@ -146,6 +166,7 @@ struct ufshcd_lrb {
* @intr_mask: Interrupt Mask Bits
* @feh_workq: Work queue for fatal controller error handling
* @errors: HBA errors
+ * @dev_cmd: ufs device management command information
*/
struct ufs_hba {
void __iomem *mmio_base;
@@ -164,6 +185,7 @@ struct ufs_hba {
struct device *dev;
struct ufshcd_lrb *lrb;
+ unsigned long lrb_in_use;
unsigned long outstanding_tasks;
unsigned long outstanding_reqs;
@@ -188,6 +210,9 @@ struct ufs_hba {
/* HBA Errors */
u32 errors;
+
+ /* Device management request data */
+ struct ufs_dev_cmd dev_cmd;
};
#define ufshcd_writel(hba, val, reg) \