[PATCH V2 6/9] scsi: ufs: fix interrupt status clears

2013-05-14 Thread Dolev Raviv
There is no need to check the version to clear
the interrupt status. And the order is changed
prior to actual handling.

Signed-off-by: Seungwon Jeon tgih@samsung.com
Tested-by: Maya Erez me...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c342a38..f4293d1 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1478,11 +1478,8 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
 
if (intr_status) {
+   ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
ufshcd_sl_intr(hba, intr_status);
-
-   /* If UFSHCI 1.0 then clear interrupt status register */
-   if (hba-ufs_version == UFSHCI_VERSION_10)
-   ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
retval = IRQ_HANDLED;
}
spin_unlock(hba-host-host_lock);
-- 
1.7.6

-- 
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 V2 7/9] scsi: ufs: rework link start-up process

2013-05-14 Thread Dolev Raviv
Link start-up requires long time with multiphase handshakes
between UFS host and device. This affects driver's probe time.
This patch let link start-up run asynchronously. Link start-up
will be executed at the end of prove separately.
Along with this change, the following is worked.

Defined completion time of uic command to avoid a permanent wait.
Added mutex to guarantee of uic command at a time.
Adapted some sequence of controller initialization after link statup
according to HCI standard.

Signed-off-by: Seungwon Jeon tgih@samsung.com
Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
Tested-by: Maya Erez me...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index f4293d1..333812f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -33,11 +33,15 @@
  * this program.
  */
 
+#include linux/async.h
+
 #include ufshcd.h
 
 #define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\
 UTP_TASK_REQ_COMPL |\
 UFSHCD_ERROR_MASK)
+/* UIC command timeout, unit: ms */
+#define UIC_CMD_TIMEOUT500
 
 enum {
UFSHCD_MAX_CHANNEL  = 0,
@@ -401,24 +405,122 @@ static inline void ufshcd_hba_capabilities(struct 
ufs_hba *hba)
 }
 
 /**
- * ufshcd_send_uic_command - Send UIC commands to unipro layers
+ * ufshcd_ready_for_uic_cmd - Check if controller is ready
+ *to accept UIC commands
  * @hba: per adapter instance
- * @uic_command: UIC command
+ * Return true on success, else false
+ */
+static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba)
+{
+   if (ufshcd_readl(hba, REG_CONTROLLER_STATUS)  UIC_COMMAND_READY)
+   return true;
+   else
+   return false;
+}
+
+/**
+ * ufshcd_dispatch_uic_cmd - Dispatch UIC commands to unipro layers
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Mutex must be held.
  */
 static inline void
-ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd)
+ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
 {
+   WARN_ON(hba-active_uic_cmd);
+
+   hba-active_uic_cmd = uic_cmd;
+
/* Write Args */
-   ufshcd_writel(hba, uic_cmnd-argument1, REG_UIC_COMMAND_ARG_1);
-   ufshcd_writel(hba, uic_cmnd-argument2, REG_UIC_COMMAND_ARG_2);
-   ufshcd_writel(hba, uic_cmnd-argument3, REG_UIC_COMMAND_ARG_3);
+   ufshcd_writel(hba, uic_cmd-argument1, REG_UIC_COMMAND_ARG_1);
+   ufshcd_writel(hba, uic_cmd-argument2, REG_UIC_COMMAND_ARG_2);
+   ufshcd_writel(hba, uic_cmd-argument3, REG_UIC_COMMAND_ARG_3);
 
/* Write UIC Cmd */
-   ufshcd_writel(hba, uic_cmnd-command  COMMAND_OPCODE_MASK,
+   ufshcd_writel(hba, uic_cmd-command  COMMAND_OPCODE_MASK,
  REG_UIC_COMMAND);
 }
 
 /**
+ * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
+ * @hba: per adapter instance
+ * @uic_command: UIC command
+ *
+ * Must be called with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+   int ret;
+   unsigned long flags;
+
+   if (wait_for_completion_timeout(uic_cmd-done,
+   msecs_to_jiffies(UIC_CMD_TIMEOUT)))
+   ret = uic_cmd-argument2  MASK_UIC_COMMAND_RESULT;
+   else
+   ret = -ETIMEDOUT;
+
+   spin_lock_irqsave(hba-host-host_lock, flags);
+   hba-active_uic_cmd = NULL;
+   spin_unlock_irqrestore(hba-host-host_lock, flags);
+
+   return ret;
+}
+
+/**
+ * __ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Identical to ufshcd_send_uic_cmd() expect mutex. Must be called
+ * with mutex held.
+ * Returns 0 only if success.
+ */
+static int
+__ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+   int ret;
+   unsigned long flags;
+
+   if (!ufshcd_ready_for_uic_cmd(hba)) {
+   dev_err(hba-dev,
+   Controller not ready to accept UIC commands\n);
+   return -EIO;
+   }
+
+   init_completion(uic_cmd-done);
+
+   spin_lock_irqsave(hba-host-host_lock, flags);
+   ufshcd_dispatch_uic_cmd(hba, uic_cmd);
+   spin_unlock_irqrestore(hba-host-host_lock, flags);
+
+   ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd);
+
+   return ret;
+}
+
+/**
+ * ufshcd_send_uic_cmd - Send UIC commands and retrieve the result
+ * @hba: per adapter instance
+ * @uic_cmd: UIC command
+ *
+ * Returns 0 only if success.
+ */
+static int
+ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
+{
+   int ret;
+
+   mutex_lock(hba-uic_cmd_mutex);
+   ret = __ufshcd_send_uic_cmd(hba, uic_cmd);
+   mutex_unlock(hba-uic_cmd_mutex);
+
+   return ret;
+}
+
+/**
  * ufshcd_map_sg - Map 

[PATCH V2 9/9] scsi: ufs: Set fDeviceInit flag to initiate device initialization

2013-05-14 Thread Dolev Raviv
Allow UFS device to complete its initialization and accept
SCSI commands by setting fDeviceInit flag. The device may take
time for this operation and hence the host should poll until
fDeviceInit flag is toggled to zero. This step is mandated by
UFS device specification for device initialization completion.

Signed-off-by: Dolev Raviv dra...@codeaurora.org
Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 086ff03..742363d 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -107,8 +107,13 @@ enum {
UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
 };
 
+/* Flag idn for Query Requests*/
+enum flag_idn {
+   QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
+};
+
 /* UTP QUERY Transaction Specific Fields OpCode */
-enum {
+enum query_opcode {
UPIU_QUERY_OPCODE_NOP   = 0x0,
UPIU_QUERY_OPCODE_READ_DESC = 0x1,
UPIU_QUERY_OPCODE_WRITE_DESC= 0x2,
@@ -208,6 +213,9 @@ struct utp_upiu_query {
u32 reserved[2];
 };
 
+/* Expose the flag value from utp_upiu_query.value */
+#define MASK_QUERY_UPIU_FLAG_LOC 0xFF
+
 /**
  * struct utp_upiu_req - general upiu request structure
  * @header:UPIU header structure DW-0 to DW-2
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 2db550b..e9dba33 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -50,6 +50,15 @@
 /* Reserved tag for internal commands */
 #define INTERNAL_CMD_TAG   0
 
+/* Query request standart retries */
+#define QUERY_REQ_RETRIES 10
+/* Query request standart timeout  in seconds */
+#define QUERY_REQ_TIMEOUT 5
+/* Send Query Requst with default parameters */
+#define send_query_request(ARG1, ARG2, ARG3, ARG4) \
+   ufshcd_query_request(ARG1, ARG2, ARG3, ARG4,\
+   QUERY_REQ_TIMEOUT, QUERY_REQ_RETRIES)
+
 enum {
UFSHCD_MAX_CHANNEL  = 0,
UFSHCD_MAX_ID   = 1,
@@ -862,6 +871,164 @@ out:
 }
 
 /**
+ *  ufshcd_query_request() - Entry point for issuing query request to a
+ *  ufs device.
+ *  @hba: ufs driver context
+ *  @query: params for query request
+ *  @descriptor: buffer for sending/receiving descriptor
+ *  @response: pointer to a buffer that will contain the response code and
+ *   response upiu
+ *  @timeout: time limit for the command in seconds
+ *  @retries: number of times to try executing the command
+ *
+ *  The query request is submitted to the same request queue as the rest of
+ *  the scsi commands passed to the UFS controller. In order to use this
+ *  queue, we need to receive a tag, same as all other commands. The tags
+ *  are issued from the block layer. To simulate a request from the block
+ *  layer, we use the same interface as the SCSI layer does when it issues
+ *  commands not generated by users. To distinguish a query request from
+ *  the SCSI commands, we use a vendor specific unused SCSI command
+ *  op-code. This op-code is not part of the SCSI command subset used in
+ *  UFS. In such way it is easy to check the command in the driver and
+ *  handle it appropriately.
+ *
+ *  All necessary fields for issuing a query and receiving its response are
+ *  stored in the UFS hba struct. We can use this method since we know
+ *  there is only one active query request at all times.
+ *
+ *  The request that will pass to the device is stored in query argument
+ *  passed to this function, while the response argument (which is output
+ *  field) will hold the query response from the device along with the
+ *  response code.
+ */
+int ufshcd_query_request(struct ufs_hba *hba,
+   struct ufs_query_req *query,
+   u8 *descriptor,
+   struct ufs_query_res *response,
+   int timeout,
+   int retries)
+{
+   struct scsi_device *sdev;
+   u8 cmd[UFS_QUERY_CMD_SIZE] = {0};
+   int result;
+   bool sdev_lookup = true;
+
+   BUG_ON(!hba);
+   if (!query || !response) {
+   dev_err(hba-dev,
+   %s: NULL pointer hba = %p, query = %p response = %p\n,
+   __func__, hba, query, response);
+   return -EINVAL;
+   }
+
+   /*
+* A SCSI command structure is composed from opcode at the
+* begining and 0 at the end.
+*/
+   cmd[0] = UFS_QUERY_RESERVED_SCSI_CMD;
+
+   /* extracting the SCSI Device */
+   sdev = scsi_device_lookup(hba-host, 0, 0, 0);
+   if (!sdev) {
+   /**
+* There are some Query Requests that are sent during device
+* initialization, this happens before the scsi device was
+* initialized. If there is no scsi device, we generate a
+* temporary device to allow the Query Request flow.
+*/
+   sdev_lookup = false;
+   sdev = 

[PATCH V2 8/9] scsi: ufs: Add support for sending NOP OUT UPIU

2013-05-14 Thread Dolev Raviv
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.

Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com
Tested-by: Dolev Raviv dra...@codeaurora.org

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 333812f..2db550b 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -43,6 +43,13 @@
 /* UIC command timeout, unit: ms */
 #define UIC_CMD_TIMEOUT500
 
+/* NOP OUT retries waiting for NOP IN response */
+#define NOP_OUT_RETRIES10
+/* Timeout after 30 msecs if NOP OUT hangs without response */
+#define NOP_OUT_TIMEOUT30 /* msecs */
+/* Reserved tag for internal commands */
+#define INTERNAL_CMD_TAG   0
+
 enum {
UFSHCD_MAX_CHANNEL  = 0,
UFSHCD_MAX_ID   = 1,
@@ -71,6 +78,39 @@ enum {
INT_AGGR_CONFIG,
 };
 
+/*
+ * ufshcd_wait_for_register - wait for register value to change
+ * @hba - per-adapter interface
+ * @reg - mmio register offset
+ * @mask - mask to apply to read register value
+ * @val - wait condition
+ * @interval_us - polling interval in microsecs
+ * @timeout_ms - timeout in millisecs
+ *
+ * Returns final register value after iteration
+ */
+static u32 ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
+   u32 val, unsigned long interval_us, unsigned long timeout_ms)
+{
+   u32 tmp;
+   ktime_t start;
+   unsigned long diff;
+
+   tmp = ufshcd_readl(hba, reg);
+
+   start = ktime_get();
+   while ((tmp  mask) == val) {
+   /* wakeup within 50us of expiry */
+   usleep_range(interval_us, interval_us + 50);
+   tmp = ufshcd_readl(hba, reg);
+   diff = ktime_to_ms(ktime_sub(ktime_get(), start));
+   if (diff  timeout_ms)
+   break;
+   }
+
+   return tmp;
+}
+
 /**
  * ufshcd_get_intr_mask - Get the interrupt bit mask
  * @hba - Pointer to adapter instance
@@ -612,7 +652,7 @@ static void ufshcd_prepare_req_desc(struct ufshcd_lrb 
*lrbp, u32 *upiu_flags)
 {
struct utp_transfer_req_desc *req_desc = lrbp-utr_descriptor_ptr;
enum dma_data_direction cmd_dir =
-   lrbp-cmd-sc_data_direction;
+   lrbp-cmd ? lrbp-cmd-sc_data_direction : DMA_NONE;
u32 data_direction;
u32 dword_0;
 
@@ -629,6 +669,8 @@ static void ufshcd_prepare_req_desc(struct ufshcd_lrb 
*lrbp, u32 *upiu_flags)
 
dword_0 = data_direction | (lrbp-command_type
 UPIU_COMMAND_TYPE_OFFSET);
+   if (lrbp-intr_cmd)
+   dword_0 |= UTP_REQ_DESC_INT_CMD;
 
/* Transfer request descriptor header fields */
req_desc-header.dword_0 = cpu_to_le32(dword_0);
@@ -717,6 +759,18 @@ static void ufshcd_prepare_utp_query_req_upiu(struct 
ufs_hba *hba,
 
 }
 
+static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp)
+{
+   struct utp_upiu_req *ucd_req_ptr = lrbp-ucd_req_ptr;
+
+   memset(ucd_req_ptr, 0, sizeof(struct utp_upiu_req));
+
+   /* command descriptor fields */
+   ucd_req_ptr-header.dword_0 =
+   UPIU_HEADER_DWORD(
+   UPIU_TRANSACTION_NOP_OUT, 0, 0, lrbp-task_tag);
+}
+
 /**
  * ufshcd_compose_upiu - form UFS Protocol Information Unit(UPIU)
  * @hba - UFS hba
@@ -731,11 +785,13 @@ static int ufshcd_compose_upiu(struct ufs_hba *hba, 
struct ufshcd_lrb *lrbp)
case UTP_CMD_TYPE_SCSI:
case UTP_CMD_TYPE_DEV_MANAGE:
ufshcd_prepare_req_desc(lrbp, upiu_flags);
-   if (lrbp-command_type == UTP_CMD_TYPE_SCSI)
+   if (lrbp-cmd  lrbp-command_type == UTP_CMD_TYPE_SCSI)
ufshcd_prepare_utp_scsi_cmd_upiu(lrbp, upiu_flags);
-   else
+   else if (lrbp-cmd  ufshcd_is_query_req(lrbp))
ufshcd_prepare_utp_query_req_upiu(hba, lrbp,
upiu_flags);
+   else if (!lrbp-cmd)
+   ufshcd_prepare_utp_nop_upiu(lrbp);
break;
case UTP_CMD_TYPE_UFS:
/* For UFS native command implementation */
@@ -784,6 +840,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *cmd)
lrbp-sense_buffer = cmd-sense_buffer;
lrbp-task_tag = tag;
lrbp-lun = cmd-device-lun;
+   lrbp-intr_cmd = false;
 
if (ufshcd_is_query_req(lrbp))
lrbp-command_type = UTP_CMD_TYPE_DEV_MANAGE;
@@ -972,6 +1029,104 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba)
return 

[PATCH V2 1/9] scsi: ufs: add support for query requests

2013-05-14 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 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 

[PATCH V2 4/9] scsi: ufs: wrap the i/o access operations

2013-05-14 Thread Dolev Raviv
Simplify operations with hiding mmio_base.

Signed-off-by: Seungwon Jeon tgih@samsung.com
Tested-by: Maya Erez me...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 7ce40a5..3946b9d 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -71,7 +71,7 @@ enum {
  */
 static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba)
 {
-   return readl(hba-mmio_base + REG_UFS_VERSION);
+   return ufshcd_readl(hba, REG_UFS_VERSION);
 }
 
 /**
@@ -130,8 +130,7 @@ static inline int ufshcd_get_tm_free_slot(struct ufs_hba 
*hba)
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-   writel(~(1  pos),
-   (hba-mmio_base + REG_UTP_TRANSFER_REQ_LIST_CLEAR));
+   ufshcd_writel(hba, ~(1  pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
 }
 
 /**
@@ -165,7 +164,7 @@ static inline int ufshcd_get_lists_status(u32 reg)
  */
 static inline int ufshcd_get_uic_cmd_result(struct ufs_hba *hba)
 {
-   return readl(hba-mmio_base + REG_UIC_COMMAND_ARG_2) 
+   return ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2) 
   MASK_UIC_COMMAND_RESULT;
 }
 
@@ -238,18 +237,15 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option)
 {
switch (option) {
case INT_AGGR_RESET:
-   writel((INT_AGGR_ENABLE |
-   INT_AGGR_COUNTER_AND_TIMER_RESET),
-   (hba-mmio_base +
-REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+   ufshcd_writel(hba, INT_AGGR_ENABLE |
+ INT_AGGR_COUNTER_AND_TIMER_RESET,
+ REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
break;
case INT_AGGR_CONFIG:
-   writel((INT_AGGR_ENABLE |
-   INT_AGGR_PARAM_WRITE |
-   INT_AGGR_COUNTER_THRESHOLD_VALUE |
-   INT_AGGR_TIMEOUT_VALUE),
-   (hba-mmio_base +
-REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL));
+   ufshcd_writel(hba, INT_AGGR_ENABLE | INT_AGGR_PARAM_WRITE |
+ INT_AGGR_COUNTER_THRESHOLD_VALUE |
+ INT_AGGR_TIMEOUT_VALUE,
+ REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL);
break;
}
 }
@@ -262,12 +258,10 @@ ufshcd_config_int_aggr(struct ufs_hba *hba, int option)
  */
 static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
 {
-   writel(UTP_TASK_REQ_LIST_RUN_STOP_BIT,
-  (hba-mmio_base +
-   REG_UTP_TASK_REQ_LIST_RUN_STOP));
-   writel(UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
-  (hba-mmio_base +
-   REG_UTP_TRANSFER_REQ_LIST_RUN_STOP));
+   ufshcd_writel(hba, UTP_TASK_REQ_LIST_RUN_STOP_BIT,
+ REG_UTP_TASK_REQ_LIST_RUN_STOP);
+   ufshcd_writel(hba, UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT,
+ REG_UTP_TRANSFER_REQ_LIST_RUN_STOP);
 }
 
 /**
@@ -276,7 +270,7 @@ static void ufshcd_enable_run_stop_reg(struct ufs_hba *hba)
  */
 static inline void ufshcd_hba_start(struct ufs_hba *hba)
 {
-   writel(CONTROLLER_ENABLE , (hba-mmio_base + REG_CONTROLLER_ENABLE));
+   ufshcd_writel(hba, CONTROLLER_ENABLE, REG_CONTROLLER_ENABLE);
 }
 
 /**
@@ -287,7 +281,7 @@ static inline void ufshcd_hba_start(struct ufs_hba *hba)
  */
 static inline int ufshcd_is_hba_active(struct ufs_hba *hba)
 {
-   return (readl(hba-mmio_base + REG_CONTROLLER_ENABLE)  0x1) ? 0 : 1;
+   return (ufshcd_readl(hba, REG_CONTROLLER_ENABLE)  0x1) ? 0 : 1;
 }
 
 /**
@@ -299,8 +293,7 @@ static inline
 void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag)
 {
__set_bit(task_tag, hba-outstanding_reqs);
-   writel((1  task_tag),
-  (hba-mmio_base + REG_UTP_TRANSFER_REQ_DOOR_BELL));
+   ufshcd_writel(hba, 1  task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL);
 }
 
 /**
@@ -381,8 +374,7 @@ void ufshcd_copy_query_response(struct ufs_hba *hba, struct 
ufshcd_lrb *lrbp)
  */
 static inline void ufshcd_hba_capabilities(struct ufs_hba *hba)
 {
-   hba-capabilities =
-   readl(hba-mmio_base + REG_CONTROLLER_CAPABILITIES);
+   hba-capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES);
 
/* nutrs and nutmrs are 0 based values */
hba-nutrs = (hba-capabilities  MASK_TRANSFER_REQUESTS_SLOTS) + 1;
@@ -399,16 +391,13 @@ static inline void
 ufshcd_send_uic_command(struct ufs_hba *hba, struct uic_command *uic_cmnd)
 {
/* Write Args */
-   writel(uic_cmnd-argument1,
- (hba-mmio_base + REG_UIC_COMMAND_ARG_1));
-   writel(uic_cmnd-argument2,
- (hba-mmio_base + REG_UIC_COMMAND_ARG_2));
-   writel(uic_cmnd-argument3,
- (hba-mmio_base + REG_UIC_COMMAND_ARG_3));
+   ufshcd_writel(hba, uic_cmnd-argument1, REG_UIC_COMMAND_ARG_1);
+   ufshcd_writel(hba, uic_cmnd-argument2, 

[PATCH V2 5/9] scsi: ufs: amend interrupt configuration

2013-05-14 Thread Dolev Raviv
It makes interrupt setting more flexible especially
for disabling. And wrong bit mask is fixed for ver 1.0.
[17:16] is added for mask.

Signed-off-by: Seungwon Jeon tgih@samsung.com
Tested-by: Maya Erez me...@codeaurora.org
Acked-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 3946b9d..c342a38 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -35,6 +35,10 @@
 
 #include ufshcd.h
 
+#define UFSHCD_ENABLE_INTRS(UTP_TRANSFER_REQ_COMPL |\
+UTP_TASK_REQ_COMPL |\
+UFSHCD_ERROR_MASK)
+
 enum {
UFSHCD_MAX_CHANNEL  = 0,
UFSHCD_MAX_ID   = 1,
@@ -64,6 +68,20 @@ enum {
 };
 
 /**
+ * ufshcd_get_intr_mask - Get the interrupt bit mask
+ * @hba - Pointer to adapter instance
+ *
+ * Returns interrupt bit mask per version
+ */
+static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba)
+{
+   if (hba-ufs_version == UFSHCI_VERSION_10)
+   return INTERRUPT_MASK_ALL_VER_10;
+   else
+   return INTERRUPT_MASK_ALL_VER_11;
+}
+
+/**
  * ufshcd_get_ufs_version - Get the UFS version supported by the HBA
  * @hba - Pointer to adapter instance
  *
@@ -441,25 +459,45 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp)
 }
 
 /**
- * ufshcd_int_config - enable/disable interrupts
+ * ufshcd_enable_intr - enable interrupts
  * @hba: per adapter instance
- * @option: interrupt option
+ * @intrs: interrupt bits
  */
-static void ufshcd_int_config(struct ufs_hba *hba, u32 option)
+static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs)
 {
-   switch (option) {
-   case UFSHCD_INT_ENABLE:
-   ufshcd_writel(hba, hba-int_enable_mask, REG_INTERRUPT_ENABLE);
-   break;
-   case UFSHCD_INT_DISABLE:
-   if (hba-ufs_version == UFSHCI_VERSION_10)
-   ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_10,
- REG_INTERRUPT_ENABLE);
-   else
-   ufshcd_writel(hba, INTERRUPT_DISABLE_MASK_11,
- REG_INTERRUPT_ENABLE);
-   break;
+   u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+   if (hba-ufs_version == UFSHCI_VERSION_10) {
+   u32 rw;
+   rw = set  INTERRUPT_MASK_RW_VER_10;
+   set = rw | ((set ^ intrs)  intrs);
+   } else {
+   set |= intrs;
+   }
+
+   ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
+}
+
+/**
+ * ufshcd_disable_intr - disable interrupts
+ * @hba: per adapter instance
+ * @intrs: interrupt bits
+ */
+static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs)
+{
+   u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+   if (hba-ufs_version == UFSHCI_VERSION_10) {
+   u32 rw;
+   rw = (set  INTERRUPT_MASK_RW_VER_10) 
+   ~(intrs  INTERRUPT_MASK_RW_VER_10);
+   set = rw | ((set  intrs)  ~INTERRUPT_MASK_RW_VER_10);
+
+   } else {
+   set = ~intrs;
}
+
+   ufshcd_writel(hba, set, REG_INTERRUPT_ENABLE);
 }
 
 /**
@@ -842,8 +880,7 @@ static int ufshcd_dme_link_startup(struct ufs_hba *hba)
uic_cmd-argument3 = 0;
 
/* enable UIC related interrupts */
-   hba-int_enable_mask |= UIC_COMMAND_COMPL;
-   ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+   ufshcd_enable_intr(hba, UIC_COMMAND_COMPL);
 
/* sending UIC commands to controller */
ufshcd_send_uic_command(hba, uic_cmd);
@@ -890,13 +927,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba)
}
 
/* Enable required interrupts */
-   hba-int_enable_mask |= (UTP_TRANSFER_REQ_COMPL |
-UIC_ERROR |
-UTP_TASK_REQ_COMPL |
-DEVICE_FATAL_ERROR |
-CONTROLLER_FATAL_ERROR |
-SYSTEM_BUS_FATAL_ERROR);
-   ufshcd_int_config(hba, UFSHCD_INT_ENABLE);
+   ufshcd_enable_intr(hba, UFSHCD_ENABLE_INTRS);
 
/* Configure interrupt aggregation */
ufshcd_config_int_aggr(hba, INT_AGGR_CONFIG);
@@ -1724,7 +1755,7 @@ static void ufshcd_hba_free(struct ufs_hba *hba)
 void ufshcd_remove(struct ufs_hba *hba)
 {
/* disable interrupts */
-   ufshcd_int_config(hba, UFSHCD_INT_DISABLE);
+   ufshcd_disable_intr(hba, hba-intr_mask);
 
ufshcd_hba_stop(hba);
ufshcd_hba_free(hba);
@@ -1782,6 +1813,9 @@ int ufshcd_init(struct device *dev, struct ufs_hba 
**hba_handle,
/* Get UFS version supported by the controller */
hba-ufs_version = ufshcd_get_ufs_version(hba);
 
+   /* Get Interrupt bit mask per version */
+   hba-intr_mask = ufshcd_get_intr_mask(hba);
+
/* Allocate memory for host memory space */
err = ufshcd_memory_alloc(hba);
if (err) {

[PATCH V2 3/9] scsi: ufs: Fix the response UPIU length setting

2013-05-14 Thread Dolev Raviv
The response UPIU length should be in DWORD and not in bytes.

Signed-off-by: Maya Erez me...@codeaurora.org
Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
Tested-by: Dolev Raviv dra...@codeaurora.org

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 4ddc8be..7ce40a5 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -807,7 +807,7 @@ static void ufshcd_host_memory_configure(struct ufs_hba 
*hba)
utrdlp[i].prd_table_offset =
cpu_to_le16((prdt_offset  2));
utrdlp[i].response_upiu_length =
-   cpu_to_le16(ALIGNED_UPIU_SIZE);
+   cpu_to_le16(ALIGNED_UPIU_SIZE  2);
 
hba-lrb[i].utr_descriptor_ptr = (utrdlp + i);
hba-lrb[i].ucd_req_ptr =
-- 
1.7.6

-- 
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 V2 0/9] ufs patch siries

2013-05-14 Thread Dolev Raviv
This patch series clusters the latest version of all the UFS patches in the
SCSI mailing list. It gives a stable functional base line for the UFS driver.

It includes the following versions:
 [PATCH V5] scsi: ufs: add support for query requests
 [PATCH 1/2] Documentation: devicetree: Add DT bindings for UFS host
 controller
 [PATCH 2/2] scsi: ufs: Fix the response UPIU length setting
 [PATCH v4 1/6] scsi: ufs: wrap the i/o access operations
 [PATCH v4 2/6] scsi: ufs: amend interrupt configuration
 [PATCH v4 3/6] scsi: ufs: fix interrupt status clears
 [PATCH v4 4/6] scsi: ufs: rework link start-up process
 [PATCH V5 1/1] scsi: ufs: Add support for sending NOP OUT UPIU
 [PATCH V4] scsi: ufs: Set fDeviceInit flag to initiate device
 initialization

But does not include:
 [PATCH v4 5/6] scsi: ufs: add dme configuration primit
 [PATCH v4 6/6] scsi: ufs: add dme control primitives

-- 
V2:
- Add query requst support patch which was ommited from the merge window

Dolev Raviv (9):
  scsi: ufs: add support for query requests
  Documentation: devicetree: Add DT bindings for UFS host controller
  scsi: ufs: Fix the response UPIU length setting
  scsi: ufs: wrap the i/o access operations
  scsi: ufs: amend interrupt configuration
  scsi: ufs: fix interrupt status clears
  scsi: ufs: rework link start-up process
  scsi: ufs: Add support for sending NOP OUT UPIU
  scsi: ufs: Set fDeviceInit flag to initiate device initialization

 .../devicetree/bindings/ufs/ufshcd-pltfrm.txt  |   16 +
 drivers/scsi/ufs/ufs.h |  132 ++-
 drivers/scsi/ufs/ufshcd.c  | 1172 +++-
 drivers/scsi/ufs/ufshcd.h  |   47 +-
 drivers/scsi/ufs/ufshci.h  |7 +-
 5 files changed, 1101 insertions(+), 273 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt

-- 
1.7.6

-- 
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 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds()

2013-05-14 Thread Gu Zheng
From 18072c1c3506a7e37ee485307a2c343efe5af4d0 Mon Sep 17 00:00:00 2001
From: Gu Zheng guz.f...@cn.fujitsu.com
Date: Mon, 13 May 2013 15:45:24 +0900
Subject: [PATCH 1/2] Kernel/time: Introduce a new timestamp function 
local_time_seconds()

Introduce a new timestamp function local_time_seconds() to hide the conversion 
of system time in UTC to local time seconds.

Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com
---
 include/linux/time.h |1 +
 kernel/time.c|   11 +++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/time.h b/include/linux/time.h
index 22d81b3..1aec534 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -271,4 +271,5 @@ static __always_inline void timespec_add_ns(struct timespec 
*a, u64 ns)
a-tv_nsec = ns;
 }
 
+extern u32 local_time_seconds(void);
 #endif
diff --git a/kernel/time.c b/kernel/time.c
index d3617db..715377d 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -712,3 +712,14 @@ struct timespec timespec_add_safe(const struct timespec 
lhs,
 
return res;
 }
+
+/*
+ * Convert system time in UTC to local time seconds.
+ */
+u32 local_time_seconds(void)
+{
+   struct timeval utc;
+   do_gettimeofday(utc);
+   return (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
+}
+EXPORT_SYMBOL(local_time_seconds);
-- 
1.7.1

--
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 2/2] driver/scsi: Use local_time_seconds() to simplify the get local timestamp operation

2013-05-14 Thread Gu Zheng
From 1abbcf9fa5ce6c9a0b005a445c53b9412b42fa83 Mon Sep 17 00:00:00 2001
From: Gu Zheng guz.f...@cn.fujitsu.com
Date: Mon, 13 May 2013 14:58:49 +0900
Subject: [PATCH 2/2] driver/scsi: Use local_time_seconds() to simplify the get 
local timestamp operation


Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com
---
 drivers/scsi/3w-9xxx.c |   14 ++
 drivers/scsi/3w-sas.c  |   14 ++
 2 files changed, 4 insertions(+), 24 deletions(-)

diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 5e1e12c..44b3ea8 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -374,8 +374,6 @@ out:
 /* This function will queue an event */
 static void twa_aen_queue_event(TW_Device_Extension *tw_dev, 
TW_Command_Apache_Header *header)
 {
-   u32 local_time;
-   struct timeval time;
TW_Event *event;
unsigned short aen;
char host[16];
@@ -398,9 +396,7 @@ static void twa_aen_queue_event(TW_Device_Extension 
*tw_dev, TW_Command_Apache_H
memset(event, 0, sizeof(TW_Event));
 
event-severity = TW_SEV_OUT(header-status_block.severity__reserved);
-   do_gettimeofday(time);
-   local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
-   event-time_stamp_sec = local_time;
+   event-time_stamp_sec = local_time_seconds();
event-aen_code = aen;
event-retrieved = TW_AEN_NOT_RETRIEVED;
event-sequence_id = tw_dev-error_sequence_id;
@@ -479,11 +475,9 @@ out:
 static void twa_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 {
u32 schedulertime;
-   struct timeval utc;
TW_Command_Full *full_command_packet;
TW_Command *command_packet;
TW_Param_Apache *param;
-   u32 local_time;
 
/* Fill out the command packet */
full_command_packet = tw_dev-command_packet_virt[request_id];
@@ -503,11 +497,7 @@ static void twa_aen_sync_time(TW_Device_Extension *tw_dev, 
int request_id)
param-parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
param-parameter_size_bytes = cpu_to_le16(4);
 
-   /* Convert system time in UTC to local time seconds since last 
-   Sunday 12:00AM */
-   do_gettimeofday(utc);
-   local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
-   schedulertime = local_time - (3 * 86400);
+   schedulertime = local_time_seconds() - (3 * 86400);
schedulertime = cpu_to_le32(schedulertime % 604800);
 
memcpy(param-data, schedulertime, sizeof(u32));
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index c845bdb..69f1d8a 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -236,8 +236,6 @@ out:
 /* This function will queue an event */
 static void twl_aen_queue_event(TW_Device_Extension *tw_dev, 
TW_Command_Apache_Header *header)
 {
-   u32 local_time;
-   struct timeval time;
TW_Event *event;
unsigned short aen;
char host[16];
@@ -256,9 +254,7 @@ static void twl_aen_queue_event(TW_Device_Extension 
*tw_dev, TW_Command_Apache_H
memset(event, 0, sizeof(TW_Event));
 
event-severity = TW_SEV_OUT(header-status_block.severity__reserved);
-   do_gettimeofday(time);
-   local_time = (u32)(time.tv_sec - (sys_tz.tz_minuteswest * 60));
-   event-time_stamp_sec = local_time;
+   event-time_stamp_sec = local_time_seconds();
event-aen_code = aen;
event-retrieved = TW_AEN_NOT_RETRIEVED;
event-sequence_id = tw_dev-error_sequence_id;
@@ -444,11 +440,9 @@ out:
 static void twl_aen_sync_time(TW_Device_Extension *tw_dev, int request_id)
 {
u32 schedulertime;
-   struct timeval utc;
TW_Command_Full *full_command_packet;
TW_Command *command_packet;
TW_Param_Apache *param;
-   u32 local_time;
 
/* Fill out the command packet */
full_command_packet = tw_dev-command_packet_virt[request_id];
@@ -468,11 +462,7 @@ static void twl_aen_sync_time(TW_Device_Extension *tw_dev, 
int request_id)
param-parameter_id = cpu_to_le16(0x3); /* SchedulerTime */
param-parameter_size_bytes = cpu_to_le16(4);
 
-   /* Convert system time in UTC to local time seconds since last 
-   Sunday 12:00AM */
-   do_gettimeofday(utc);
-   local_time = (u32)(utc.tv_sec - (sys_tz.tz_minuteswest * 60));
-   schedulertime = local_time - (3 * 86400);
+   schedulertime = local_time_seconds() - (3 * 86400);
schedulertime = cpu_to_le32(schedulertime % 604800);
 
memcpy(param-data, schedulertime, sizeof(u32));
-- 
1.7.1

--
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 V1 0/8] ufs patch siries

2013-05-14 Thread Dolev Raviv
Yes, apparently I have, and I missed this mail as well until it was
brought to my attention earlier.

I apologise for re sending the patch series with mistakes, I withdraw it
and let Santosh send it as he see fit.

 On Monday, May 13, 2013, Dolev Raviv wrote:
 This patch series clusters the latest version of all the UFS patches in
 the
 SCSI mailing list. It gives a stable functional base line for the UFS
 driver.

 It includes the following versions:
  [PATCH 1/2] Documentation: devicetree: Add DT bindings for UFS host
  controller
  [PATCH 2/2] scsi: ufs: Fix the response UPIU length setting
  [PATCH v4 1/6] scsi: ufs: wrap the i/o access operations
  [PATCH v4 2/6] scsi: ufs: amend interrupt configuration
  [PATCH v4 3/6] scsi: ufs: fix interrupt status clears
  [PATCH v4 4/6] scsi: ufs: rework link start-up process
  [PATCH V5 1/1] scsi: ufs: Add support for sending NOP OUT UPIU
  [PATCH V4] scsi: ufs: Set fDeviceInit flag to initiate device
  initialization

 But does not include:
  [PATCH v4 5/6] scsi: ufs: add dme configuration primit
  [PATCH v4 6/6] scsi: ufs: add dme control primitives


 Dolev Raviv (8):
   Documentation: devicetree: Add DT bindings for UFS host controller
   scsi: ufs: Fix the response UPIU length setting
   scsi: ufs: wrap the i/o access operations
   scsi: ufs: amend interrupt configuration
   scsi: ufs: fix interrupt status clears
   scsi: ufs: rework link start-up process
   scsi: ufs: Add support for sending NOP OUT UPIU
   scsi: ufs: Set fDeviceInit flag to initiate device initialization

 It seems that you missed my first comment on previous mailing.

 RE: [PATCH V1 3/8] scsi: ufs: wrap the i/o access operations
 Could you check the e-mail?

 If you intended to sort the patches instead of Santosh,
 you should have identify the author per patch e-mail expect 8/8 which is
 from you.
 'From: Author name Author e-mail' is expected in the head of e-mail.
 I feel that maintainer has this role, though.

 And there is need to check the base of tree for ufshcd.
 ' scsi: ufs: add support for query requests' is not merged finally.
 I think we can talk with Santosh for those.

 Thanks,
 Seungwon Jeon

 --
 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 v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead

2013-05-14 Thread Gu Zheng
On 05/14/2013 01:23 AM, Yinghai Lu wrote:

 On Mon, May 13, 2013 at 9:08 AM, Jiang Liu liu...@gmail.com wrote:
 From: Gu Zheng guz.f...@cn.fujitsu.com
 diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
 index 4f0bc0a..bc075a3 100644
 --- a/drivers/pci/probe.c
 +++ b/drivers/pci/probe.c
 @@ -1131,6 +1131,7 @@ static void pci_release_dev(struct device *dev)
 struct pci_dev *pci_dev;

 pci_dev = to_pci_dev(dev);
 +   pci_bus_put(pci_dev-bus);
 pci_release_capabilities(pci_dev);
 pci_release_of_node(pci_dev);
 kfree(pci_dev);
 @@ -1269,11 +1270,10 @@ static struct pci_dev *pci_scan_device(struct 
 pci_bus *bus, int devfn)
 if (!pci_bus_read_dev_vendor_id(bus, devfn, l, 60*1000))
 return NULL;

 -   dev = alloc_pci_dev();
 +   dev = pci_alloc_dev(bus);
 if (!dev)
 return NULL;

 -   dev-bus = bus;
 dev-devfn = devfn;
 dev-vendor = l  0x;
 dev-device = (l  16)  0x;
 
 in pci_setup_device() fail path, it release the ref to that bus.

Yes, you're right, we need to release the bus' ref if pci_setup_device() failed.
Thanks for your correction.:)

Best regards,
Gu

 
 Yinghai
 


From 7add6d9e70919b95be2debde2f58fc31d26c75bf Mon Sep 17 00:00:00 2001
From: Gu Zheng guz.f...@cn.fujitsu.com
Date: Tue, 14 May 2013 16:11:07 +0800
Subject: [PATCH v3] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) 
instead

v3:
  Follow Yinghai's correction to release the bus' ref
  in pci_setup_device() fail path.

v2:
  Follow Bjorn's correction to move pci_bus_put() to
  pci_release_dev() instead.

Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com
---
 arch/powerpc/kernel/pci_of_scan.c |3 +--
 arch/sparc/kernel/pci.c   |3 +--
 drivers/char/agp/alpha-agp.c  |2 +-
 drivers/char/agp/parisc-agp.c |2 +-
 drivers/pci/iov.c |8 +---
 drivers/pci/probe.c   |5 +++--
 drivers/scsi/megaraid.c   |2 +-
 7 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/kernel/pci_of_scan.c 
b/arch/powerpc/kernel/pci_of_scan.c
index 2a67e9b..24d01c4 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -128,7 +128,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
const char *type;
struct pci_slot *slot;
 
-   dev = alloc_pci_dev();
+   dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
type = of_get_property(node, device_type, NULL);
@@ -137,7 +137,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
 
pr_debug(create device, devfn: %x, type: %s\n, devfn, type);
 
-   dev-bus = bus;
dev-dev.of_node = of_node_get(node);
dev-dev.parent = bus-bridge;
dev-dev.bus = pci_bus_type;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index baf4366..e5871fb 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -254,7 +254,7 @@ static struct pci_dev *of_create_pci_dev(struct 
pci_pbm_info *pbm,
const char *type;
u32 class;
 
-   dev = alloc_pci_dev();
+   dev = pci_alloc_dev(bus);
if (!dev)
return NULL;
 
@@ -281,7 +281,6 @@ static struct pci_dev *of_create_pci_dev(struct 
pci_pbm_info *pbm,
printk(create device, devfn: %x, type: %s\n,
   devfn, type);
 
-   dev-bus = bus;
dev-sysdata = node;
dev-dev.parent = bus-bridge;
dev-dev.bus = pci_bus_type;
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
index dd84af4..199b8e9 100644
--- a/drivers/char/agp/alpha-agp.c
+++ b/drivers/char/agp/alpha-agp.c
@@ -174,7 +174,7 @@ alpha_core_agp_setup(void)
/*
 * Build a fake pci_dev struct
 */
-   pdev = alloc_pci_dev();
+   pdev = pci_alloc_dev(NULL);
if (!pdev)
return -ENOMEM;
pdev-vendor = 0x;
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 94821ab..bf5d247 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -333,7 +333,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem 
*lba_hpa)
struct agp_bridge_data *bridge;
int error = 0;
 
-   fake_bridge_dev = alloc_pci_dev();
+   fake_bridge_dev = pci_alloc_dev(NULL);
if (!fake_bridge_dev) {
error = -ENOMEM;
goto fail;
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index c93071d..2652ca0 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -75,18 +75,20 @@ static int virtfn_add(struct pci_dev *dev, int id, int 
reset)
struct pci_dev *virtfn;
struct resource *res;
struct pci_sriov *iov = dev-sriov;
+   struct pci_bus *bus;
 
-   virtfn = alloc_pci_dev();
+   virtfn = pci_alloc_dev(NULL);
if (!virtfn)
return 

Re: [PATCH v2, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead

2013-05-14 Thread Liu Jiang

On 05/14/2013 04:26 PM, Gu Zheng wrote:

On 05/14/2013 01:23 AM, Yinghai Lu wrote:


On Mon, May 13, 2013 at 9:08 AM, Jiang Liu liu...@gmail.com wrote:

From: Gu Zheng guz.f...@cn.fujitsu.com
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 4f0bc0a..bc075a3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1131,6 +1131,7 @@ static void pci_release_dev(struct device *dev)
 struct pci_dev *pci_dev;

 pci_dev = to_pci_dev(dev);
+   pci_bus_put(pci_dev-bus);
 pci_release_capabilities(pci_dev);
 pci_release_of_node(pci_dev);
 kfree(pci_dev);
@@ -1269,11 +1270,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus 
*bus, int devfn)
 if (!pci_bus_read_dev_vendor_id(bus, devfn, l, 60*1000))
 return NULL;

-   dev = alloc_pci_dev();
+   dev = pci_alloc_dev(bus);
 if (!dev)
 return NULL;

-   dev-bus = bus;
 dev-devfn = devfn;
 dev-vendor = l  0x;
 dev-device = (l  16)  0x;

in pci_setup_device() fail path, it release the ref to that bus.

Yes, you're right, we need to release the bus' ref if pci_setup_device() failed.

Hi Zheng,
I suggest to use pci_release_dev() instead because it also needs to 
release OF related resources.

I will update it in next version.

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bc075a3..2ac6338 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct 
pci_bus *bus

pci_set_of_node(dev);

if (pci_setup_device(dev)) {
-   kfree(dev);
+   pci_release_dev(dev-dev);
return NULL;
}



hanks for your correction.:)

Best regards,
Gu


Yinghai





--
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, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead

2013-05-14 Thread Yinghai Lu
On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote:
 On 05/14/2013 04:26 PM, Gu Zheng wrote:
 I suggest to use pci_release_dev() instead because it also needs to
 release OF related resources.
 I will update it in next version.

 diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
 index bc075a3..2ac6338 100644
 --- a/drivers/pci/probe.c
 +++ b/drivers/pci/probe.c
 @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus
 *bus
 pci_set_of_node(dev);

 if (pci_setup_device(dev)) {
 -   kfree(dev);
 +   pci_release_dev(dev-dev);
 return NULL;

no, should move pci_set_of_node calling into pci_setup_device.

Yinghai
--
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 1/2] Kernel/time: Introduce a new timestamp function local_time_seconds()

2013-05-14 Thread John Stultz

On 05/14/2013 12:45 AM, Gu Zheng wrote:

 From 18072c1c3506a7e37ee485307a2c343efe5af4d0 Mon Sep 17 00:00:00 2001
From: Gu Zheng guz.f...@cn.fujitsu.com
Date: Mon, 13 May 2013 15:45:24 +0900
Subject: [PATCH 1/2] Kernel/time: Introduce a new timestamp function 
local_time_seconds()

Introduce a new timestamp function local_time_seconds() to hide the conversion 
of system time in UTC to local time seconds.


So, why is this useful/needed?

thanks
-john

--
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 0/3] UFSHCD updates

2013-05-14 Thread Santosh Y
Hi James,

Please merge the following patches to scsi tree.

Thanks,
Santosh

Geert Uytterhoeven (1):
  SCSI_UFSHCD should depend on SCSI_DMA

Sachin Kamat (1):
  ufs: Remove redundant platform_set_drvdata()

Sujit Reddy Thumma (1):
  Documentation: devicetree: Add DT bindings for UFS host controller

 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt | 16 
 drivers/scsi/ufs/Kconfig|  2 +-
 drivers/scsi/ufs/ufshcd-pltfrm.c|  1 -
 3 files changed, 17 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt

-- 
1.8.1.2

--
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 1/3] ufs: Remove redundant platform_set_drvdata()

2013-05-14 Thread Santosh Y
From: Sachin Kamat sachin.ka...@linaro.org

Commit 0998d06310 (device-core: Ensure drvdata = NULL when no
driver is bound) removes the need to set driver data field to
NULL.

Signed-off-by: Sachin Kamat sachin.ka...@linaro.org
Signed-off-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 03319ac..3db2ee1 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -184,7 +184,6 @@ static int ufshcd_pltfrm_remove(struct platform_device 
*pdev)
mem_size = resource_size(mem_res);
release_mem_region(mem_res-start, mem_size);
}
-   platform_set_drvdata(pdev, NULL);
return 0;
 }
 
-- 
1.8.1.2

--
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 2/3] SCSI_UFSHCD should depend on SCSI_DMA

2013-05-14 Thread Santosh Y
From: Geert Uytterhoeven ge...@linux-m68k.org

If NO_DMA=y:

drivers/built-in.o: In function `ufshcd_transfer_req_compl':
drivers/scsi/ufs/ufshcd.c:1182: undefined reference to `scsi_dma_unmap'
drivers/built-in.o: In function `ufshcd_map_sg':
drivers/scsi/ufs/ufshcd.c:377: undefined reference to `scsi_dma_map'
drivers/built-in.o: In function `ufshcd_do_reset':
drivers/scsi/ufs/ufshcd.c:912: undefined reference to `scsi_dma_unmap'
drivers/built-in.o: In function `ufshcd_memory_alloc':
drivers/scsi/ufs/ufshcd.c:565: undefined reference to `dma_alloc_coherent'
drivers/built-in.o: In function `ufshcd_free_hba_memory':
drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent'
drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent'
drivers/scsi/ufs/ufshcd.c:199: undefined reference to `dma_free_coherent'
drivers/scsi/ufs/ufshcd.c:185: undefined reference to `dma_free_coherent'
drivers/scsi/ufs/ufshcd.c:192: undefined reference to `dma_free_coherent'
drivers/built-in.o:drivers/scsi/ufs/ufshcd.c:199: more undefined references to 
`dma_free_coherent' follow
drivers/built-in.o: In function `ufshcd_abort':
drivers/scsi/ufs/ufshcd.c:1498: undefined reference to `scsi_dma_unmap'
drivers/built-in.o: In function `ufshcd_device_reset':
drivers/scsi/ufs/ufshcd.c:1436: undefined reference to `scsi_dma_unmap'

Signed-off-by: Geert Uytterhoeven ge...@linux-m68k.org
Cc: Vinayak Holikatti vinholika...@gmail.com
Cc: James E.J. Bottomley jbottom...@parallels.com
Cc: linux-scsi@vger.kernel.org
Signed-off-by: Santosh Y santos...@gmail.com

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index 35faf24..f07f901 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -34,7 +34,7 @@
 
 config SCSI_UFSHCD
tristate Universal Flash Storage Controller Driver Core
-   depends on SCSI
+   depends on SCSI  SCSI_DMA
---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
-- 
1.8.1.2

--
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, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead

2013-05-14 Thread Liu Jiang

On Tue 14 May 2013 11:10:33 PM CST, Yinghai Lu wrote:

On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote:

On 05/14/2013 04:26 PM, Gu Zheng wrote:
 I suggest to use pci_release_dev() instead because it also needs to
release OF related resources.
I will update it in next version.

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bc075a3..2ac6338 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus
*bus
 pci_set_of_node(dev);

 if (pci_setup_device(dev)) {
-   kfree(dev);
+   pci_release_dev(dev-dev);
 return NULL;


no, should move pci_set_of_node calling into pci_setup_device.

Yinghai


I'm not sure whether we should call pci_set_of_node() for SR-IOV 
devices too,

any suggestions here?
--
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 2/9] Documentation: devicetree: Add DT bindings for UFS host controller

2013-05-14 Thread Olof Johansson
On Tue, May 14, 2013 at 12:08 AM, Dolev Raviv dra...@codeaurora.org wrote:
 Compatible list is used in commit 03b1781 but is not documented.
 Add necessary device tree bindings to describe on-chip UFS host
 controllers.

 Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org

 diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt 
 b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
 new file mode 100644
 index 000..20468b2
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
 @@ -0,0 +1,16 @@
 +* Universal Flash Storage (UFS) Host Controller
 +
 +UFSHC nodes are defined to describe on-chip UFS host controllers.
 +Each UFS controller instance should have its own node.
 +
 +Required properties:
 +- compatible: compatible list, contains jedec,ufs-1.1
 +- interrupts: interrupt mapping for UFS host controller IRQ
 +- reg   : registers mapping
 +
 +Example:
 +   ufshc@0xfc598000 {
 +   compatible = jedec,ufs-1.1;

Hmm.

Does jedec really specify the programming interface of this type of
device, register layout and meaning? It seems to be more about the
command set and electrical/connectivity specifications, no?


-Olof
--
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, part 1 3/9] PCI: Convert alloc_pci_dev(void) to pci_alloc_dev(bus) instead

2013-05-14 Thread Yinghai Lu
On Tue, May 14, 2013 at 9:57 AM, Liu Jiang liu...@gmail.com wrote:
 On Tue 14 May 2013 11:10:33 PM CST, Yinghai Lu wrote:

 On Tue, May 14, 2013 at 7:59 AM, Liu Jiang liu...@gmail.com wrote:

 On 05/14/2013 04:26 PM, Gu Zheng wrote:
  I suggest to use pci_release_dev() instead because it also needs to
 release OF related resources.
 I will update it in next version.

 diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
 index bc075a3..2ac6338 100644
 --- a/drivers/pci/probe.c
 +++ b/drivers/pci/probe.c
 @@ -1281,7 +1281,7 @@ static struct pci_dev *pci_scan_device(struct
 pci_bus
 *bus
  pci_set_of_node(dev);

  if (pci_setup_device(dev)) {
 -   kfree(dev);
 +   pci_release_dev(dev-dev);
  return NULL;


 no, should move pci_set_of_node calling into pci_setup_device.

 Yinghai


 I'm not sure whether we should call pci_set_of_node() for SR-IOV devices
 too,
 any suggestions here?

or just move down pci_set_of_node after pci_setup_device?

anyway that is another bug.

Yinghai
--
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 testing/USB devices are amazing

2013-05-14 Thread Martin K. Petersen
 Ronnie == ronnie sahlberg ronniesahlb...@gmail.com writes:

Ronnie,

Ronnie I have added tests for the block limits VPD as
Ronnie SCSI.Inquiry.InquiryBlockLimits.  It checks that the pagelength
Ronnie is valid. 3C if SBC3 is claimed and 0C if prior to SBC3.

Well, there are devices out there that claim SPC3/SBC2 compliance but do
support some of the newer features from SPC4/SBC3.

In this case I'd rely on the supported VPD page list. And if the BL VPD
is present and the device reports SPC3/SBC2 I'd print a warning.


Ronnie It then validates that the UNMAP counts are sane.  Sane being
Ronnie that if LBPU==0 then these must be 0, and if LBPU==1 then these
Ronnie must be 1, must be than 2**LBPPBE and either 0x or
Ronnie 1M. (1M is arbitrary for crazy large number of blocks)

That's a good start, anyway.


Ronnie The other fields I had a hard time to come up with good sanity
Ronnie tests for. Any suggestions ?  Do you have examples of things
Ronnie that vendors get wrong here ?

Maximum Write Same Length vs. support for WS10 and WS16.

Another interesting Write Same test: I have several devices that support
WS16 but which only support a 2-byte block count in WS16. I.e. you get
the larger LBA but not a bigger block count with WS16.

There's also the Logical Block Provisioning VPD page. You could verify
that UNMAP is supported when LBPU=1. Repeat for LBPWS and LBPWS10.

You could verify that the device actually returns zeroes when LBPRZ=1.


Ronnie I will add tests for when protection information is enabled in
Ronnie the future, I will need to find time to add it to tgt first.

I have a fairly extensive set of PI tests in my test suite. But that
gets pretty involved. We can deal with those later.


Ronnie Very nice document.  Section 1.3 could update
Ronnie though. READCAPACITY16 is only mandatory in SBC-2 IF the device
Ronnie supports protection information, but optional if it does not.
Ronnie In SBC-3 it is always mandatory though. Thin provisioning and
Ronnie different logical/physical block sizes were only added to this
Ronnie command in SBC-3 not SBC-2.

I describe what we actually do, not what's spec compliant :)

This is our current heuristic for READ CAPACITY(16):

static int sd_try_rc16_first(struct scsi_device *sdp)
{
if (sdp-host-max_cmd_len  16)
return 0;
if (sdp-scsi_level  SCSI_SPC_2)
return 1;
if (scsi_device_protection(sdp))
return 1;
return 0;
}


Ronnie I have thus updated my READCAPACITY16 tests so that IF SBC-3 is
Ronnie claimed, or if IQN-PROTECT is set then the device must support
Ronnie this opcode or the test will fail.  Otherwise, if it is not
Ronnie SBC-3 and if PROTECT is clear, then the test will be skipped but
Ronnie not fail if the opcode is missing.

*nod*

-- 
Martin K. Petersen  Oracle Linux Engineering
--
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