[PATCH v1] ufs: introduce setup_hibern8 callback

2016-11-07 Thread Kiwoong Kim
Some UFS host controller may need to configure some things
around hibern8 enter/exit

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c | 10 --
 drivers/scsi/ufs/ufshcd.h | 10 ++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index fdb0502..d4a5a9c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2697,6 +2697,8 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
int ret;
struct uic_command uic_cmd = {0};
 
+   ufshcd_vops_setup_hibern8(hba, true, PRE_CHANGE);
+
uic_cmd.command = UIC_CMD_DME_HIBER_ENTER;
ret = ufshcd_uic_pwr_ctrl(hba, &uic_cmd);
 
@@ -2710,7 +2712,8 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
 */
if (ufshcd_link_recovery(hba))
ret = -ENOLINK;
-   }
+   } else
+   ufshcd_vops_setup_hibern8(hba, true, POST_CHANGE);
 
return ret;
 }
@@ -2733,13 +2736,16 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
struct uic_command uic_cmd = {0};
int ret;
 
+   ufshcd_vops_setup_hibern8(hba, false, PRE_CHANGE);
+
uic_cmd.command = UIC_CMD_DME_HIBER_EXIT;
ret = ufshcd_uic_pwr_ctrl(hba, &uic_cmd);
if (ret) {
dev_err(hba->dev, "%s: hibern8 exit failed. ret = %d\n",
__func__, ret);
ret = ufshcd_link_recovery(hba);
-   }
+   } else
+   ufshcd_vops_setup_hibern8(hba, false, POST_CHANGE);
 
return ret;
 }
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index b084d89..13504b4 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -265,6 +265,8 @@ struct ufs_pwr_mode_info {
  *  to set some things
  * @setup_task_mgmt: called before any task management request is issued
  *  to set some things
+ * @setup_hibern8: called around hibern8 enter/exit
+ * to configure some things
  * @suspend: called during host controller PM callback
  * @resume: called during host controller PM callback
  * @dbg_register_dump: used to dump controller debug information
@@ -290,6 +292,7 @@ struct ufs_hba_variant_ops {
struct ufs_pa_layer_attr *);
void(*setup_xfer_req)(struct ufs_hba *, int, bool);
void(*setup_task_mgmt)(struct ufs_hba *, int, u8);
+   void(*setup_hibern8)(struct ufs_hba *, bool, bool);
int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
void(*dbg_register_dump)(struct ufs_hba *hba);
@@ -821,6 +824,13 @@ static inline void ufshcd_vops_setup_task_mgmt(struct 
ufs_hba *hba,
return hba->vops->setup_task_mgmt(hba, tag, tm_function);
 }
 
+static inline void ufshcd_vops_setup_hibern8(struct ufs_hba *hba,
+   bool enter, bool notify)
+{
+   if (hba->vops && hba->vops->setup_hibern8)
+   return hba->vops->setup_hibern8(hba, enter, notify);
+}
+
 static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
 {
if (hba->vops && hba->vops->suspend)
-- 
2.1.4

--
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 v1] ufs: introduce setup_task_mgmt

2016-11-07 Thread Kiwoong Kim
Some UFS host controller may need to configure some things
before any task management request is issued

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c |  1 +
 drivers/scsi/ufs/ufshcd.h | 10 ++
 2 files changed, 11 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index bf78321..fdb0502 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4358,6 +4358,7 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int 
lun_id, int task_id,
task_req_upiup->input_param2 = cpu_to_be32(task_id);
 
/* send command to the controller */
+   ufshcd_vops_setup_task_mgmt(hba, free_slot, tm_function);
__set_bit(free_slot, &hba->outstanding_tasks);
 
/* Make sure descriptors are ready before ringing the task doorbell */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index f2a69c0..b084d89 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -263,6 +263,8 @@ struct ufs_pwr_mode_info {
  * to be set.
  * @setup_xfer_req: called before any transfer request is issued
  *  to set some things
+ * @setup_task_mgmt: called before any task management request is issued
+ *  to set some things
  * @suspend: called during host controller PM callback
  * @resume: called during host controller PM callback
  * @dbg_register_dump: used to dump controller debug information
@@ -287,6 +289,7 @@ struct ufs_hba_variant_ops {
struct ufs_pa_layer_attr *,
struct ufs_pa_layer_attr *);
void(*setup_xfer_req)(struct ufs_hba *, int, bool);
+   void(*setup_task_mgmt)(struct ufs_hba *, int, u8);
int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
void(*dbg_register_dump)(struct ufs_hba *hba);
@@ -811,6 +814,13 @@ static inline void ufshcd_vops_setup_xfer_req(struct 
ufs_hba *hba, int tag,
return hba->vops->setup_xfer_req(hba, tag, is_cmd_not_null);
 }
 
+static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba,
+   int tag, u8 tm_function)
+{
+   if (hba->vops && hba->vops->setup_task_mgmt)
+   return hba->vops->setup_task_mgmt(hba, tag, tm_function);
+}
+
 static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
 {
if (hba->vops && hba->vops->suspend)
-- 
2.1.4

--
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 v1] ufs: introduce UFSHCD_QUIRK_USE_OF_HCE quirk

2016-11-07 Thread Kiwoong Kim
Some host controller might not initialize itself
by setting "Host Controller Enable" to 1.
They should do this to reset UIC.
In such cases, 'DME reset' and 'DME enable' are required
for normal subsequent operations.

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c | 44 +++-
 drivers/scsi/ufs/ufshcd.h |  1 +
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 24d6ea7..c904854 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2496,6 +2496,37 @@ static inline void 
ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba)
usleep_range(min_sleep_time_us, min_sleep_time_us + 50);
 }
 
+static int ufshcd_dme_reset(struct ufs_hba *hba)
+{
+   struct uic_command uic_cmd = {0};
+   int ret;
+
+   uic_cmd.command = UIC_CMD_DME_RESET;
+   uic_cmd.argument1 = 0x1;
+
+   ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
+   if (ret)
+   dev_err(hba->dev,
+   "dme-reset: error code %d\n", ret);
+
+   return ret;
+}
+
+static int ufshcd_dme_enable(struct ufs_hba *hba)
+{
+   struct uic_command uic_cmd = {0};
+   int ret;
+
+   uic_cmd.command = UIC_CMD_DME_ENABLE;
+
+   ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
+   if (ret)
+   dev_err(hba->dev,
+   "dme-enable: error code %d\n", ret);
+
+   return ret;
+}
+
 /**
  * ufshcd_dme_set_attr - UIC command for DME_SET, DME_PEER_SET
  * @hba: per adapter instance
@@ -3101,6 +3132,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, 
bool can_sleep)
 static int ufshcd_hba_enable(struct ufs_hba *hba)
 {
int retry;
+   int ret = 0;
 
/*
 * msleep of 1 and 5 used in this function might result in msleep(20),
@@ -3117,6 +3149,9 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
 
ufshcd_vops_hce_enable_notify(hba, PRE_CHANGE);
 
+   if (hba->quirks & UFSHCD_QUIRK_USE_OF_HCE)
+   goto use_dme;
+
/* start controller initialization sequence */
ufshcd_hba_start(hba);
 
@@ -3145,12 +3180,19 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
msleep(5);
}
 
+use_dme:
/* enable UIC related interrupts */
ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
 
+   if (hba->quirks & UFSHCD_QUIRK_USE_OF_HCE) {
+   ret = ufshcd_dme_reset(hba);
+   if (!ret)
+   ret = ufshcd_dme_enable(hba);
+   }
+
ufshcd_vops_hce_enable_notify(hba, POST_CHANGE);
 
-   return 0;
+   return ret;
 }
 
 static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index c4abd76..6a96f24 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -496,6 +496,7 @@ struct ufs_hba {
#define UFSHCD_QUIRK_GET_VS_RESULT  UFS_BIT(6)
#define UFSHCD_QUIRK_BROKEN_DWORD_UTRD  UFS_BIT(7)
#define UFSHCD_QUIRK_BROKEN_REQ_LIST_CLRUFS_BIT(8)
+   #define UFSHCD_QUIRK_USE_OF_HCE UFS_BIT(9)
 
 
unsigned int quirks;/* Deviations from standard UFSHCI spec. */
-- 
2.1.4

--
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 v1] ufs: introduce UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR quirk

2016-11-07 Thread Kiwoong Kim
Some UFS host controllers may clear a transfer request slot
by setting an associated bit in UTLRCLR/UTMLRCLR to 1, not 0.
That's opposite to what UFS spec decribes.

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c | 32 
 drivers/scsi/ufs/ufshcd.h |  1 +
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 549e3e8..24d6ea7 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -392,7 +392,31 @@ static inline void ufshcd_put_tm_slot(struct ufs_hba *hba, 
int slot)
  */
 static inline void ufshcd_utrl_clear(struct ufs_hba *hba, u32 pos)
 {
-   ufshcd_writel(hba, ~(1 << pos), REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+   u32 clear;
+
+   if (hba->quirks & UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR)
+   clear = (1 << pos);
+   else
+   clear = ~(1 << pos);
+
+   ufshcd_writel(hba, clear, REG_UTP_TRANSFER_REQ_LIST_CLEAR);
+}
+
+/**
+ * ufshcd_utmrl_clear - Clear a bit in UTRMLCLR register
+ * @hba: per adapter instance
+ * @pos: position of the bit to be cleared
+ */
+static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos)
+{
+   u32 clear;
+
+   if (hba->quirks & UFSHCD_QUIRK_BROKEN_REQ_LIST_CLR)
+   clear = (1 << pos);
+   else
+   clear = ~(1 << pos);
+
+   ufshcd_writel(hba, clear, REG_UTP_TASK_REQ_LIST_CLEAR);
 }
 
 /**
@@ -1147,7 +1171,7 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct 
uic_command *uic_cmd)
  *
  * Returns 0 in case of success, non-zero value in case of failure
  */
-static int ufshcd_map_sg(struct ufshcd_lrb *lrbp)
+static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 {
struct ufshcd_sg_entry *prd_table;
struct scatterlist *sg;
@@ -1529,7 +1553,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *cmd)
 
ufshcd_comp_scsi_upiu(hba, lrbp);
 
-   err = ufshcd_map_sg(lrbp);
+   err = ufshcd_map_sg(hba, lrbp);
if (err) {
lrbp->cmd = NULL;
clear_bit_unlock(tag, &hba->lrb_in_use);
@@ -4329,7 +4353,7 @@ static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int 
tag)
goto out;
 
spin_lock_irqsave(hba->host->host_lock, flags);
-   ufshcd_writel(hba, ~(1 << tag), REG_UTP_TASK_REQ_LIST_CLEAR);
+   ufshcd_utmrl_clear(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
 
/* poll for max. 1 sec to clear door bell register by h/w */
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 565f005..c4abd76 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -495,6 +495,7 @@ struct ufs_hba {
 
#define UFSHCD_QUIRK_GET_VS_RESULT  UFS_BIT(6)
#define UFSHCD_QUIRK_BROKEN_DWORD_UTRD  UFS_BIT(7)
+   #define UFSHCD_QUIRK_BROKEN_REQ_LIST_CLRUFS_BIT(8)
 
 
unsigned int quirks;/* Deviations from standard UFSHCI spec. */
-- 
2.1.4

--
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 v1] ufs: introcude UFSHCD_QUIRK_GET_VS_RESULT quirk

2016-11-07 Thread Kiwoong Kim
Some UFS host controllers may not report a result of
UIC command completion properly.
In such cases, they should get the result from UIC directly
if their architectures support that.

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c | 27 +++
 drivers/scsi/ufs/ufshcd.h | 20 
 2 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index d4a5a9c..8e19631 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1011,7 +1011,10 @@ static inline bool ufshcd_ready_for_uic_cmd(struct 
ufs_hba *hba)
  */
 static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba)
 {
-   return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) >> 8) & 0x7;
+   if (hba->quirks & UFSHCD_QUIRK_GET_VS_RESULT)
+   return (u8)ufshcd_vops_get_vs_info(hba, VS_OP_03);
+   else
+   return (ufshcd_readl(hba, REG_CONTROLLER_STATUS) >> 8) & 0x7;
 }
 
 /**
@@ -1038,6 +1041,17 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct 
uic_command *uic_cmd)
  REG_UIC_COMMAND);
 }
 
+static inline enum vs_opcode ufshcd_get_vs_opcode(struct uic_command *uic_cmd)
+{
+   if (uic_cmd->command == UIC_CMD_DME_LINK_STARTUP)
+   return VS_OP_00;
+   else if ((uic_cmd->command == UIC_CMD_DME_HIBER_ENTER))
+   return VS_OP_01;
+   else if ((uic_cmd->command == UIC_CMD_DME_HIBER_EXIT))
+   return VS_OP_02;
+   else
+   return VS_OP_INVALID;
+}
 /**
  * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command
  * @hba: per adapter instance
@@ -1051,11 +1065,16 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct 
uic_command *uic_cmd)
 {
int ret;
unsigned long flags;
+   enum vs_opcode vs_op = ufshcd_get_vs_opcode(uic_cmd);
 
if (wait_for_completion_timeout(&uic_cmd->done,
-   msecs_to_jiffies(UIC_CMD_TIMEOUT)))
-   ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
-   else
+   msecs_to_jiffies(UIC_CMD_TIMEOUT))) {
+   if (hba->quirks & UFSHCD_QUIRK_GET_VS_RESULT &&
+   vs_op != VS_OP_INVALID)
+   ret = ufshcd_vops_get_vs_info(hba, vs_op);
+   else
+   ret = uic_cmd->argument2 & MASK_UIC_COMMAND_RESULT;
+   } else
ret = -ETIMEDOUT;
 
spin_lock_irqsave(hba->host->host_lock, flags);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 13504b4..8cf3991 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -245,6 +245,14 @@ struct ufs_pwr_mode_info {
struct ufs_pa_layer_attr info;
 };
 
+enum vs_opcode {
+   VS_OP_00 = 0x00,
+   VS_OP_01,
+   VS_OP_02,
+   VS_OP_03,
+   VS_OP_INVALID = 0xFF,
+};
+
 /**
  * struct ufs_hba_variant_ops - variant specific callbacks
  * @name: variant name
@@ -297,6 +305,7 @@ struct ufs_hba_variant_ops {
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
void(*dbg_register_dump)(struct ufs_hba *hba);
int (*phy_initialization)(struct ufs_hba *);
+   int (*get_vs_info)(struct ufs_hba *hba, enum vs_opcode);
 };
 
 /* clock gating state  */
@@ -484,6 +493,8 @@ struct ufs_hba {
 */
#define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION UFS_BIT(5)
 
+   #define UFSHCD_QUIRK_GET_VS_RESULT  UFS_BIT(6)
+
unsigned int quirks;/* Deviations from standard UFSHCI spec. */
 
/* Device deviations from standard UFS device spec. */
@@ -853,4 +864,13 @@ static inline void ufshcd_vops_dbg_register_dump(struct 
ufs_hba *hba)
hba->vops->dbg_register_dump(hba);
 }
 
+static inline int ufshcd_vops_get_vs_info(struct ufs_hba *hba,
+   enum vs_opcode op)
+{
+   if (hba->vops && hba->vops->get_vs_info)
+   return hba->vops->get_vs_info(hba, op);
+
+   return -ENOTSUPP;
+}
+
 #endif /* End of Header */
-- 
2.1.4

--
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 v1] ufs: introduce UFSHCD_QUIRK_BROKEN_DWORD_UTRD quirk

2016-11-07 Thread Kiwoong Kim
Some UFS host controllers may think
granularitys of PRDT length and offset as bytes, not double words.

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c | 24 +++-
 drivers/scsi/ufs/ufshcd.h |  2 ++
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 8e19631..549e3e8 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1161,8 +1161,13 @@ static int ufshcd_map_sg(struct ufshcd_lrb *lrbp)
return sg_segments;
 
if (sg_segments) {
-   lrbp->utr_descriptor_ptr->prd_table_length =
-   cpu_to_le16((u16) (sg_segments));
+   if (hba->quirks & UFSHCD_QUIRK_BROKEN_DWORD_UTRD)
+   lrbp->utr_descriptor_ptr->prd_table_length =
+   cpu_to_le16((u16)(sg_segments *
+   sizeof(struct ufshcd_sg_entry)));
+   else
+   lrbp->utr_descriptor_ptr->prd_table_length =
+   cpu_to_le16((u16) (sg_segments));
 
prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr;
 
@@ -2385,12 +2390,21 @@ static void ufshcd_host_memory_configure(struct ufs_hba 
*hba)

cpu_to_le32(upper_32_bits(cmd_desc_element_addr));
 
/* Response upiu and prdt offset should be in double words */
-   utrdlp[i].response_upiu_offset =
+   if (hba->quirks & UFSHCD_QUIRK_BROKEN_DWORD_UTRD) {
+   utrdlp[i].response_upiu_offset =
+   cpu_to_le16(response_offset);
+   utrdlp[i].prd_table_offset =
+   cpu_to_le16(prdt_offset);
+   utrdlp[i].response_upiu_length =
+   cpu_to_le16(ALIGNED_UPIU_SIZE);
+   } else {
+   utrdlp[i].response_upiu_offset =
cpu_to_le16((response_offset >> 2));
-   utrdlp[i].prd_table_offset =
+   utrdlp[i].prd_table_offset =
cpu_to_le16((prdt_offset >> 2));
-   utrdlp[i].response_upiu_length =
+   utrdlp[i].response_upiu_length =
cpu_to_le16(ALIGNED_UPIU_SIZE >> 2);
+   }
 
hba->lrb[i].utr_descriptor_ptr = (utrdlp + i);
hba->lrb[i].ucd_req_ptr =
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 8cf3991..565f005 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -494,6 +494,8 @@ struct ufs_hba {
#define UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION UFS_BIT(5)
 
#define UFSHCD_QUIRK_GET_VS_RESULT  UFS_BIT(6)
+   #define UFSHCD_QUIRK_BROKEN_DWORD_UTRD  UFS_BIT(7)
+
 
unsigned int quirks;/* Deviations from standard UFSHCI spec. */
 
-- 
2.1.4


--
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 v1] ufs: introduce setup_xfer_req callback

2016-11-07 Thread Kiwoong Kim
Some UFS host controller may need to configure some things
before any transfer request is issued.

Signed-off-by: Kiwoong Kim 
---
 drivers/scsi/ufs/ufshcd.c |  2 ++
 drivers/scsi/ufs/ufshcd.h | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 8cf5d8f..bf78321 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -1516,6 +1516,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, 
struct scsi_cmnd *cmd)
 
/* issue command to the controller */
spin_lock_irqsave(hba->host->host_lock, flags);
+   ufshcd_vops_setup_xfer_req(hba, tag, (lrbp->cmd ? true : false));
ufshcd_send_command(hba, tag);
 out_unlock:
spin_unlock_irqrestore(hba->host->host_lock, flags);
@@ -1727,6 +1728,7 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba,
/* Make sure descriptors are ready before ringing the doorbell */
wmb();
spin_lock_irqsave(hba->host->host_lock, flags);
+   ufshcd_vops_setup_xfer_req(hba, tag, (lrbp->cmd ? true : false));
ufshcd_send_command(hba, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
 
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index afff7f4..f2a69c0 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -261,6 +261,8 @@ struct ufs_pwr_mode_info {
  * @pwr_change_notify: called before and after a power mode change
  * is carried out to allow vendor spesific capabilities
  * to be set.
+ * @setup_xfer_req: called before any transfer request is issued
+ *  to set some things
  * @suspend: called during host controller PM callback
  * @resume: called during host controller PM callback
  * @dbg_register_dump: used to dump controller debug information
@@ -284,6 +286,7 @@ struct ufs_hba_variant_ops {
enum ufs_notify_change_status status,
struct ufs_pa_layer_attr *,
struct ufs_pa_layer_attr *);
+   void(*setup_xfer_req)(struct ufs_hba *, int, bool);
int (*suspend)(struct ufs_hba *, enum ufs_pm_op);
int (*resume)(struct ufs_hba *, enum ufs_pm_op);
void(*dbg_register_dump)(struct ufs_hba *hba);
@@ -801,6 +804,13 @@ static inline int ufshcd_vops_pwr_change_notify(struct 
ufs_hba *hba,
return -ENOTSUPP;
 }
 
+static inline void ufshcd_vops_setup_xfer_req(struct ufs_hba *hba, int tag,
+   bool is_cmd_not_null)
+{
+   if (hba->vops && hba->vops->setup_xfer_req)
+   return hba->vops->setup_xfer_req(hba, tag, is_cmd_not_null);
+}
+
 static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op)
 {
if (hba->vops && hba->vops->suspend)
-- 
2.1.4

--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Johannes Thumshirn
On Mon, Nov 07, 2016 at 08:10:25PM +0100, Christoph Hellwig wrote:
> On Mon, Nov 07, 2016 at 06:04:21PM +0100, Sebastian Andrzej Siewior wrote:
> > So we keep things as they are right now or are we getting also rid of
> > the internal list? This was tested by Johannes and Chad (claimed to do
> > testing)
> 
> IFF the patches actually are tested as-is let's get them in.  I don't
> think they are how we want the code to like in the long run, though.

I'm definitively sure I did test the bnx2fc patches. I'm not 100% sure I did
test the bnx2i patches as well (althoug I wrote "for the whole series").
Testing was IIRC booting from the FCoE LUN and the doing a series of fio tests
for about an hour.

Byte,
Johannes

-- 
Johannes Thumshirn  Storage
jthumsh...@suse.de+49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
--
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] hpsa: switch to pci_alloc_irq_vectors

2016-11-07 Thread Hannes Reinecke
Use pci_alloc_irq_vectors and drop the hand-crafted
interrupt affinity routines.

Signed-off-by: Hannes Reinecke 
Cc: Don Brace 
---
 drivers/scsi/hpsa.c | 72 +++--
 drivers/scsi/hpsa.h |  1 -
 2 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 4e82b69..104e699 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -5618,7 +5618,7 @@ static int hpsa_scsi_host_alloc(struct ctlr_info *h)
sh->sg_tablesize = h->maxsgentries;
sh->transportt = hpsa_sas_transport_template;
sh->hostdata[0] = (unsigned long) h;
-   sh->irq = h->intr[h->intr_mode];
+   sh->irq = pci_irq_vector(h->pdev, h->intr_mode);
sh->unique_id = sh->irq;
 
h->scsi_host = sh;
@@ -7667,14 +7667,9 @@ static void hpsa_disable_interrupt_mode(struct ctlr_info 
*h)
  */
 static void hpsa_interrupt_mode(struct ctlr_info *h)
 {
+   unsigned int irq_flags = PCI_IRQ_LEGACY;
 #ifdef CONFIG_PCI_MSI
-   int err, i;
-   struct msix_entry hpsa_msix_entries[MAX_REPLY_QUEUES];
-
-   for (i = 0; i < MAX_REPLY_QUEUES; i++) {
-   hpsa_msix_entries[i].vector = 0;
-   hpsa_msix_entries[i].entry = i;
-   }
+   int err;
 
/* Some boards advertise MSI but don't really support it */
if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) ||
@@ -7685,8 +7680,8 @@ static void hpsa_interrupt_mode(struct ctlr_info *h)
h->msix_vector = MAX_REPLY_QUEUES;
if (h->msix_vector > num_online_cpus())
h->msix_vector = num_online_cpus();
-   err = pci_enable_msix_range(h->pdev, hpsa_msix_entries,
-   1, h->msix_vector);
+   err = pci_alloc_irq_vectors(h->pdev, 1, h->msix_vector,
+   PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
if (err < 0) {
dev_warn(&h->pdev->dev, "MSI-X init failed %d\n", err);
h->msix_vector = 0;
@@ -7696,22 +7691,21 @@ static void hpsa_interrupt_mode(struct ctlr_info *h)
   "available\n", err);
}
h->msix_vector = err;
-   for (i = 0; i < h->msix_vector; i++)
-   h->intr[i] = hpsa_msix_entries[i].vector;
return;
}
 single_msi_mode:
if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) {
dev_info(&h->pdev->dev, "MSI capable controller\n");
-   if (!pci_enable_msi(h->pdev))
+   if (!pci_enable_msi(h->pdev)) {
h->msi_vector = 1;
-   else
+   irq_flags = PCI_IRQ_MSI;
+   } else
dev_warn(&h->pdev->dev, "MSI init failed\n");
}
 default_int_mode:
 #endif /* CONFIG_PCI_MSI */
/* if we get here we're going to use the default interrupt mode */
-   h->intr[h->intr_mode] = h->pdev->irq;
+   pci_alloc_irq_vectors(h->pdev, 1, 1, irq_flags);
 }
 
 static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id)
@@ -8236,17 +8230,6 @@ static int hpsa_alloc_cmd_pool(struct ctlr_info *h)
return -ENOMEM;
 }
 
-static void hpsa_irq_affinity_hints(struct ctlr_info *h)
-{
-   int i, cpu;
-
-   cpu = cpumask_first(cpu_online_mask);
-   for (i = 0; i < h->msix_vector; i++) {
-   irq_set_affinity_hint(h->intr[i], get_cpu_mask(cpu));
-   cpu = cpumask_next(cpu, cpu_online_mask);
-   }
-}
-
 /* clear affinity hints and free MSI-X, MSI, or legacy INTx vectors */
 static void hpsa_free_irqs(struct ctlr_info *h)
 {
@@ -8255,15 +8238,13 @@ static void hpsa_free_irqs(struct ctlr_info *h)
if (!h->msix_vector || h->intr_mode != PERF_MODE_INT) {
/* Single reply queue, only one irq to free */
i = h->intr_mode;
-   irq_set_affinity_hint(h->intr[i], NULL);
-   free_irq(h->intr[i], &h->q[i]);
+   free_irq(pci_irq_vector(h->pdev, i), &h->q[i]);
h->q[i] = 0;
return;
}
 
for (i = 0; i < h->msix_vector; i++) {
-   irq_set_affinity_hint(h->intr[i], NULL);
-   free_irq(h->intr[i], &h->q[i]);
+   free_irq(pci_irq_vector(h->pdev, i), &h->q[i]);
h->q[i] = 0;
}
for (; i < MAX_REPLY_QUEUES; i++)
@@ -8288,17 +8269,18 @@ static int hpsa_request_irqs(struct ctlr_info *h,
/* If performant mode and MSI-X, use multiple reply queues */
for (i = 0; i < h->msix_vector; i++) {
sprintf(h->intrname[i], "%s-msix%d", h->devname, i);
-   rc = request_irq(h->intr[i], msixhandler,
-   0, h->intrname[i],
-   &h->q[

[PATCH] aacraid: switch to pci_alloc_irq_vectors

2016-11-07 Thread Hannes Reinecke
Use pci_alloc_irq_vectors and drop the hand-crafted
interrupt affinity routines.

Signed-off-by: Hannes Reinecke 
Cc: Adaptec OEM Raid Solutions 
---
 drivers/scsi/aacraid/aacraid.h  |  1 -
 drivers/scsi/aacraid/comminit.c | 10 +++---
 drivers/scsi/aacraid/commsup.c  | 25 +
 drivers/scsi/aacraid/linit.c| 20 
 4 files changed, 12 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 969c312..f059c14 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1246,7 +1246,6 @@ struct aac_dev
u32 max_msix;   /* max. MSI-X vectors */
u32 vector_cap; /* MSI-X vector capab.*/
int msi_enabled;/* MSI/MSI-X enabled */
-   struct msix_entry   msixentry[AAC_MAX_MSIX];
struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */
u8  adapter_shutdown;
u32 handle_pci_error;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 341ea32..4f56b10 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -378,16 +378,12 @@ void aac_define_int_mode(struct aac_dev *dev)
if (msi_count > AAC_MAX_MSIX)
msi_count = AAC_MAX_MSIX;
 
-   for (i = 0; i < msi_count; i++)
-   dev->msixentry[i].entry = i;
-
if (msi_count > 1 &&
pci_find_capability(dev->pdev, PCI_CAP_ID_MSIX)) {
min_msix = 2;
-   i = pci_enable_msix_range(dev->pdev,
-   dev->msixentry,
-   min_msix,
-   msi_count);
+   i = pci_alloc_irq_vectors(dev->pdev,
+ min_msix, msi_count,
+ PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
if (i > 0) {
dev->msi_enabled = 1;
msi_count = i;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 0aeecec..9e7551f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -2043,30 +2043,22 @@ int aac_acquire_irq(struct aac_dev *dev)
int i;
int j;
int ret = 0;
-   int cpu;
 
-   cpu = cpumask_first(cpu_online_mask);
if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
for (i = 0; i < dev->max_msix; i++) {
dev->aac_msix[i].vector_no = i;
dev->aac_msix[i].dev = dev;
-   if (request_irq(dev->msixentry[i].vector,
+   if (request_irq(pci_irq_vector(dev->pdev, i),
dev->a_ops.adapter_intr,
0, "aacraid", &(dev->aac_msix[i]))) {
printk(KERN_ERR "%s%d: Failed to register IRQ 
for vector %d.\n",
dev->name, dev->id, i);
for (j = 0 ; j < i ; j++)
-   free_irq(dev->msixentry[j].vector,
+   free_irq(pci_irq_vector(dev->pdev, j),
 &(dev->aac_msix[j]));
pci_disable_msix(dev->pdev);
ret = -1;
}
-   if (irq_set_affinity_hint(dev->msixentry[i].vector,
-   get_cpu_mask(cpu))) {
-   printk(KERN_ERR "%s%d: Failed to set IRQ 
affinity for cpu %d\n",
-   dev->name, dev->id, cpu);
-   }
-   cpu = cpumask_next(cpu, cpu_online_mask);
}
} else {
dev->aac_msix[0].vector_no = 0;
@@ -2096,16 +2088,9 @@ void aac_free_irq(struct aac_dev *dev)
dev->pdev->device == PMC_DEVICE_S8 ||
dev->pdev->device == PMC_DEVICE_S9) {
if (dev->max_msix > 1) {
-   for (i = 0; i < dev->max_msix; i++) {
-   if (irq_set_affinity_hint(
-   dev->msixentry[i].vector, NULL)) {
-   printk(KERN_ERR "%s%d: Failed to reset 
IRQ affinity for cpu %d\n",
-   dev->name, dev->id, cpu);
-   }
-   cpu = cpumask_next(cpu, cpu_online_mask);
-   free_irq(dev->msixentry[i].vector,
-   &(dev->aac_msix[i]));
-   }
+   for (i = 0; i < dev->max_msix; i++)
+ 

Re: [PATCH] Avoid that SCSI device removal through sysfs triggers a deadlock

2016-11-07 Thread Greg KH
On Mon, Nov 07, 2016 at 04:32:18PM -0800, Bart Van Assche wrote:
> The SCSI core holds scan_mutex around SCSI device addition and
> removal operations. sysfs serializes attribute read and write
> operations against attribute removal through s_active. Avoid that
> grabbing scan_mutex during self-removal of a SCSI device triggers
> a deadlock by not calling __kernfs_remove() from
> kernfs_remove_by_name_ns() in case of self-removal. This patch
> avoids that self-removal triggers the following deadlock:
> 
> ===
> [ INFO: possible circular locking dependency detected ]
> 4.9.0-rc1-dbg+ #4 Not tainted
> ---
> test_02_sdev_de/12586 is trying to acquire lock:
>  (&shost->scan_mutex){+.+.+.}, at: [] 
> scsi_remove_device+0x1e/0x40
> but task is already holding lock:
>  (s_active#336){.+}, at: [] 
> kernfs_remove_self+0xde/0x140
> which lock already depends on the new lock.
> 
> the existing dependency chain (in reverse order) is:
> -> #1 (s_active#336){.+}:
> [] lock_acquire+0xe9/0x1d0
> [] __kernfs_remove+0x24a/0x310
> [] kernfs_remove_by_name_ns+0x40/0x90
> [] remove_files.isra.1+0x30/0x70
> [] sysfs_remove_group+0x3f/0x90
> [] sysfs_remove_groups+0x29/0x40
> [] device_remove_attrs+0x59/0x80
> [] device_del+0x125/0x240
> [] __scsi_remove_device+0x143/0x180
> [] scsi_forget_host+0x64/0x70
> [] scsi_remove_host+0x75/0x120
> [] 0xa035dbbb
> [] process_one_work+0x1f5/0x690
> [] worker_thread+0x49/0x490
> [] kthread+0xeb/0x110
> [] ret_from_fork+0x27/0x40
> 
> -> #0 (&shost->scan_mutex){+.+.+.}:
> [] __lock_acquire+0x10fc/0x1270
> [] lock_acquire+0xe9/0x1d0
> [] mutex_lock_nested+0x5f/0x360
> [] scsi_remove_device+0x1e/0x40
> [] sdev_store_delete+0x22/0x30
> [] dev_attr_store+0x13/0x20
> [] sysfs_kf_write+0x40/0x50
> [] kernfs_fop_write+0x137/0x1c0
> [] __vfs_write+0x23/0x140
> [] vfs_write+0xb0/0x190
> [] SyS_write+0x44/0xa0
> [] entry_SYSCALL_64_fastpath+0x18/0xad
> 
> other info that might help us debug this:
> 
>  Possible unsafe locking scenario:
>CPU0CPU1
>
>   lock(s_active#336);
>lock(&shost->scan_mutex);
>lock(s_active#336);
>   lock(&shost->scan_mutex);
> 
>  *** DEADLOCK ***
> 3 locks held by test_02_sdev_de/12586:
>  #0:  (sb_writers#4){.+.+.+}, at: [] vfs_write+0x178/0x190
>  #1:  (&of->mutex){+.+.+.}, at: [] 
> kernfs_fop_write+0x101/0x1c0
>  #2:  (s_active#336){.+}, at: [] 
> kernfs_remove_self+0xde/0x140
> 
> stack backtrace:
> CPU: 4 PID: 12586 Comm: test_02_sdev_de Not tainted 4.9.0-rc1-dbg+ #4
> Call Trace:
>  [] dump_stack+0x68/0x93
>  [] print_circular_bug+0x1be/0x210
>  [] __lock_acquire+0x10fc/0x1270
>  [] lock_acquire+0xe9/0x1d0
>  [] mutex_lock_nested+0x5f/0x360
>  [] scsi_remove_device+0x1e/0x40
>  [] sdev_store_delete+0x22/0x30
>  [] dev_attr_store+0x13/0x20
>  [] sysfs_kf_write+0x40/0x50
>  [] kernfs_fop_write+0x137/0x1c0
>  [] __vfs_write+0x23/0x140
>  [] vfs_write+0xb0/0x190
>  [] SyS_write+0x44/0xa0
>  [] entry_SYSCALL_64_fastpath+0x18/0xad
> 
> References: http://www.spinics.net/lists/linux-scsi/msg86551.html
> Signed-off-by: Bart Van Assche 
> Cc: Greg Kroah-Hartman 
> Cc: Eric Biederman 
> Cc: Hannes Reinecke 
> Cc: Johannes Thumshirn 
> Cc: Sagi Grimberg 
> Cc: 
> ---
>  fs/kernfs/dir.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
> index cf4c636..44ec536 100644
> --- a/fs/kernfs/dir.c
> +++ b/fs/kernfs/dir.c
> @@ -1410,7 +1410,7 @@ int kernfs_remove_by_name_ns(struct kernfs_node 
> *parent, const char *name,
>   mutex_lock(&kernfs_mutex);
>  
>   kn = kernfs_find_ns(parent, name, ns);
> - if (kn)
> + if (kn && !(kn->flags & KERNFS_SUICIDED))
>   __kernfs_remove(kn);

Really?  What changed recently to require this?  I thought we fixed
these issues a long time ago in kernfs :(

thanks,

greg k-h
--
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 5/6] qedi: Add support for iSCSI session management.

2016-11-07 Thread Manish Rangankar
This patch adds support for iscsi_transport LLD Login,
Logout, NOP-IN/NOP-OUT, Async, Reject PDU processing
and Firmware async event handling support.

Signed-off-by: Nilesh Javali 
Signed-off-by: Adheer Chandravanshi 
Signed-off-by: Chad Dupuis 
Signed-off-by: Saurav Kashyap 
Signed-off-by: Arun Easi 
Signed-off-by: Manish Rangankar 
---
 drivers/scsi/qedi/qedi_fw.c| 1106 +++
 drivers/scsi/qedi/qedi_gbl.h   |   67 ++
 drivers/scsi/qedi/qedi_iscsi.c | 1611 
 drivers/scsi/qedi/qedi_iscsi.h |  232 ++
 drivers/scsi/qedi/qedi_main.c  |  166 +
 5 files changed, 3182 insertions(+)
 create mode 100644 drivers/scsi/qedi/qedi_fw.c
 create mode 100644 drivers/scsi/qedi/qedi_gbl.h
 create mode 100644 drivers/scsi/qedi/qedi_iscsi.c
 create mode 100644 drivers/scsi/qedi/qedi_iscsi.h

diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
new file mode 100644
index 000..5ee62a2
--- /dev/null
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -0,0 +1,1106 @@
+/*
+ * QLogic iSCSI Offload Driver
+ * Copyright (c) 2016 Cavium Inc.
+ *
+ * This software is available under the terms of the GNU General Public License
+ * (GPL) Version 2, available from the file COPYING in the main directory of
+ * this source tree.
+ */
+
+#include 
+#include 
+#include 
+
+#include "qedi.h"
+#include "qedi_iscsi.h"
+#include "qedi_gbl.h"
+
+static int qedi_send_iscsi_tmf(struct qedi_conn *qedi_conn,
+  struct iscsi_task *mtask);
+
+void qedi_iscsi_unmap_sg_list(struct qedi_cmd *cmd)
+{
+   struct scsi_cmnd *sc = cmd->scsi_cmd;
+
+   if (cmd->io_tbl.sge_valid && sc) {
+   cmd->io_tbl.sge_valid = 0;
+   scsi_dma_unmap(sc);
+   }
+}
+
+static void qedi_process_logout_resp(struct qedi_ctx *qedi,
+union iscsi_cqe *cqe,
+struct iscsi_task *task,
+struct qedi_conn *qedi_conn)
+{
+   struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data;
+   struct iscsi_logout_rsp *resp_hdr;
+   struct iscsi_session *session = conn->session;
+   struct iscsi_logout_response_hdr *cqe_logout_response;
+   struct qedi_cmd *cmd;
+
+   cmd = (struct qedi_cmd *)task->dd_data;
+   cqe_logout_response = &cqe->cqe_common.iscsi_hdr.logout_response;
+   spin_lock(&session->back_lock);
+   resp_hdr = (struct iscsi_logout_rsp *)&qedi_conn->gen_pdu.resp_hdr;
+   memset(resp_hdr, 0, sizeof(struct iscsi_hdr));
+   resp_hdr->opcode = cqe_logout_response->opcode;
+   resp_hdr->flags = cqe_logout_response->flags;
+   resp_hdr->hlength = 0;
+
+   resp_hdr->itt = build_itt(cqe->cqe_solicited.itid, conn->session->age);
+   resp_hdr->statsn = cpu_to_be32(cqe_logout_response->stat_sn);
+   resp_hdr->exp_cmdsn = cpu_to_be32(cqe_logout_response->exp_cmd_sn);
+   resp_hdr->max_cmdsn = cpu_to_be32(cqe_logout_response->max_cmd_sn);
+
+   resp_hdr->t2wait = cpu_to_be32(cqe_logout_response->time2wait);
+   resp_hdr->t2retain = cpu_to_be32(cqe_logout_response->time2retain);
+
+   QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_TID,
+ "Freeing tid=0x%x for cid=0x%x\n",
+ cmd->task_id, qedi_conn->iscsi_conn_id);
+
+   if (likely(cmd->io_cmd_in_list)) {
+   cmd->io_cmd_in_list = false;
+   list_del_init(&cmd->io_cmd);
+   qedi_conn->active_cmd_count--;
+   } else {
+   QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
+ "Active cmd list node already deleted, tid=0x%x, 
cid=0x%x, io_cmd_node=%p\n",
+ cmd->task_id, qedi_conn->iscsi_conn_id,
+ &cmd->io_cmd);
+   }
+
+   cmd->state = RESPONSE_RECEIVED;
+   qedi_clear_task_idx(qedi, cmd->task_id);
+   __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0);
+
+   spin_unlock(&session->back_lock);
+}
+
+static void qedi_process_text_resp(struct qedi_ctx *qedi,
+  union iscsi_cqe *cqe,
+  struct iscsi_task *task,
+  struct qedi_conn *qedi_conn)
+{
+   struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data;
+   struct iscsi_session *session = conn->session;
+   struct iscsi_task_context *task_ctx;
+   struct iscsi_text_rsp *resp_hdr_ptr;
+   struct iscsi_text_response_hdr *cqe_text_response;
+   struct qedi_cmd *cmd;
+   int pld_len;
+   u32 *tmp;
+
+   cmd = (struct qedi_cmd *)task->dd_data;
+   task_ctx = qedi_get_task_mem(&qedi->tasks, cmd->task_id);
+
+   cqe_text_response = &cqe->cqe_common.iscsi_hdr.text_response;
+   spin_lock(&session->back_lock);
+   resp_hdr_ptr =  (struct iscsi_text_rsp *)&qedi_conn->gen_pdu.resp_hdr;
+   memset(resp_hdr_ptr, 0, sizeof(struct iscsi_hdr));
+   resp_hdr_ptr->opcode = cq

[PATCH v2 6/6] qedi: Add support for data path.

2016-11-07 Thread Manish Rangankar
This patch adds support for data path and TMF handling.

Signed-off-by: Nilesh Javali 
Signed-off-by: Adheer Chandravanshi 
Signed-off-by: Chad Dupuis 
Signed-off-by: Saurav Kashyap 
Signed-off-by: Arun Easi 
Signed-off-by: Manish Rangankar 
---
 drivers/scsi/qedi/qedi_fw.c| 1272 
 drivers/scsi/qedi/qedi_gbl.h   |6 +
 drivers/scsi/qedi/qedi_iscsi.c |   13 +
 drivers/scsi/qedi/qedi_main.c  |4 +
 4 files changed, 1295 insertions(+)

diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index 5ee62a2..560c3e6 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -146,6 +146,114 @@ static void qedi_process_text_resp(struct qedi_ctx *qedi,
spin_unlock(&session->back_lock);
 }
 
+static void qedi_tmf_resp_work(struct work_struct *work)
+{
+   struct qedi_cmd *qedi_cmd =
+   container_of(work, struct qedi_cmd, tmf_work);
+   struct qedi_conn *qedi_conn = qedi_cmd->conn;
+   struct qedi_ctx *qedi = qedi_conn->qedi;
+   struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data;
+   struct iscsi_session *session = conn->session;
+   struct iscsi_tm_rsp *resp_hdr_ptr;
+   struct iscsi_cls_session *cls_sess;
+   int rval = 0;
+
+   set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags);
+   resp_hdr_ptr =  (struct iscsi_tm_rsp *)qedi_cmd->tmf_resp_buf;
+   cls_sess = iscsi_conn_to_session(qedi_conn->cls_conn);
+
+   iscsi_block_session(session->cls_session);
+   rval = qedi_cleanup_all_io(qedi, qedi_conn, qedi_cmd->task, true);
+   if (rval) {
+   clear_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags);
+   qedi_clear_task_idx(qedi, qedi_cmd->task_id);
+   iscsi_unblock_session(session->cls_session);
+   return;
+   }
+
+   iscsi_unblock_session(session->cls_session);
+   qedi_clear_task_idx(qedi, qedi_cmd->task_id);
+
+   spin_lock(&session->back_lock);
+   __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0);
+   spin_unlock(&session->back_lock);
+   kfree(resp_hdr_ptr);
+   clear_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags);
+}
+
+static void qedi_process_tmf_resp(struct qedi_ctx *qedi,
+ union iscsi_cqe *cqe,
+ struct iscsi_task *task,
+ struct qedi_conn *qedi_conn)
+
+{
+   struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data;
+   struct iscsi_session *session = conn->session;
+   struct iscsi_tmf_response_hdr *cqe_tmp_response;
+   struct iscsi_tm_rsp *resp_hdr_ptr;
+   struct iscsi_tm *tmf_hdr;
+   struct qedi_cmd *qedi_cmd = NULL;
+   u32 *tmp;
+
+   cqe_tmp_response = &cqe->cqe_common.iscsi_hdr.tmf_response;
+
+   qedi_cmd = task->dd_data;
+   qedi_cmd->tmf_resp_buf = kzalloc(sizeof(*resp_hdr_ptr), GFP_KERNEL);
+   if (!qedi_cmd->tmf_resp_buf) {
+   QEDI_ERR(&qedi->dbg_ctx,
+"Failed to allocate resp buf, cid=0x%x\n",
+ qedi_conn->iscsi_conn_id);
+   return;
+   }
+
+   spin_lock(&session->back_lock);
+   resp_hdr_ptr =  (struct iscsi_tm_rsp *)qedi_cmd->tmf_resp_buf;
+   memset(resp_hdr_ptr, 0, sizeof(struct iscsi_tm_rsp));
+
+   /* Fill up the header */
+   resp_hdr_ptr->opcode = cqe_tmp_response->opcode;
+   resp_hdr_ptr->flags = cqe_tmp_response->hdr_flags;
+   resp_hdr_ptr->response = cqe_tmp_response->hdr_response;
+   resp_hdr_ptr->hlength = 0;
+
+   hton24(resp_hdr_ptr->dlength,
+  (cqe_tmp_response->hdr_second_dword &
+   ISCSI_TMF_RESPONSE_HDR_DATA_SEG_LEN_MASK));
+   tmp = (u32 *)resp_hdr_ptr->dlength;
+   resp_hdr_ptr->itt = build_itt(cqe->cqe_solicited.itid,
+ conn->session->age);
+   resp_hdr_ptr->statsn = cpu_to_be32(cqe_tmp_response->stat_sn);
+   resp_hdr_ptr->exp_cmdsn  = cpu_to_be32(cqe_tmp_response->exp_cmd_sn);
+   resp_hdr_ptr->max_cmdsn = cpu_to_be32(cqe_tmp_response->max_cmd_sn);
+
+   tmf_hdr = (struct iscsi_tm *)qedi_cmd->task->hdr;
+
+   if (likely(qedi_cmd->io_cmd_in_list)) {
+   qedi_cmd->io_cmd_in_list = false;
+   list_del_init(&qedi_cmd->io_cmd);
+   qedi_conn->active_cmd_count--;
+   }
+
+   if (((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) ==
+ ISCSI_TM_FUNC_LOGICAL_UNIT_RESET) ||
+   ((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) ==
+ ISCSI_TM_FUNC_TARGET_WARM_RESET) ||
+   ((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) ==
+ ISCSI_TM_FUNC_TARGET_COLD_RESET)) {
+   INIT_WORK(&qedi_cmd->tmf_work, qedi_tmf_resp_work);
+   queue_work(qedi->tmf_thread, &qedi_cmd->tmf_work);
+   goto unblock_sess;
+   }
+
+   qedi_clear_task_idx(qedi, qedi_cmd->task_id);

[PATCH] Avoid that SCSI device removal through sysfs triggers a deadlock

2016-11-07 Thread Bart Van Assche
The SCSI core holds scan_mutex around SCSI device addition and
removal operations. sysfs serializes attribute read and write
operations against attribute removal through s_active. Avoid that
grabbing scan_mutex during self-removal of a SCSI device triggers
a deadlock by not calling __kernfs_remove() from
kernfs_remove_by_name_ns() in case of self-removal. This patch
avoids that self-removal triggers the following deadlock:

===
[ INFO: possible circular locking dependency detected ]
4.9.0-rc1-dbg+ #4 Not tainted
---
test_02_sdev_de/12586 is trying to acquire lock:
 (&shost->scan_mutex){+.+.+.}, at: [] 
scsi_remove_device+0x1e/0x40
but task is already holding lock:
 (s_active#336){.+}, at: [] kernfs_remove_self+0xde/0x140
which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:
-> #1 (s_active#336){.+}:
[] lock_acquire+0xe9/0x1d0
[] __kernfs_remove+0x24a/0x310
[] kernfs_remove_by_name_ns+0x40/0x90
[] remove_files.isra.1+0x30/0x70
[] sysfs_remove_group+0x3f/0x90
[] sysfs_remove_groups+0x29/0x40
[] device_remove_attrs+0x59/0x80
[] device_del+0x125/0x240
[] __scsi_remove_device+0x143/0x180
[] scsi_forget_host+0x64/0x70
[] scsi_remove_host+0x75/0x120
[] 0xa035dbbb
[] process_one_work+0x1f5/0x690
[] worker_thread+0x49/0x490
[] kthread+0xeb/0x110
[] ret_from_fork+0x27/0x40

-> #0 (&shost->scan_mutex){+.+.+.}:
[] __lock_acquire+0x10fc/0x1270
[] lock_acquire+0xe9/0x1d0
[] mutex_lock_nested+0x5f/0x360
[] scsi_remove_device+0x1e/0x40
[] sdev_store_delete+0x22/0x30
[] dev_attr_store+0x13/0x20
[] sysfs_kf_write+0x40/0x50
[] kernfs_fop_write+0x137/0x1c0
[] __vfs_write+0x23/0x140
[] vfs_write+0xb0/0x190
[] SyS_write+0x44/0xa0
[] entry_SYSCALL_64_fastpath+0x18/0xad

other info that might help us debug this:

 Possible unsafe locking scenario:
   CPU0CPU1
   
  lock(s_active#336);
   lock(&shost->scan_mutex);
   lock(s_active#336);
  lock(&shost->scan_mutex);

 *** DEADLOCK ***
3 locks held by test_02_sdev_de/12586:
 #0:  (sb_writers#4){.+.+.+}, at: [] vfs_write+0x178/0x190
 #1:  (&of->mutex){+.+.+.}, at: [] 
kernfs_fop_write+0x101/0x1c0
 #2:  (s_active#336){.+}, at: [] 
kernfs_remove_self+0xde/0x140

stack backtrace:
CPU: 4 PID: 12586 Comm: test_02_sdev_de Not tainted 4.9.0-rc1-dbg+ #4
Call Trace:
 [] dump_stack+0x68/0x93
 [] print_circular_bug+0x1be/0x210
 [] __lock_acquire+0x10fc/0x1270
 [] lock_acquire+0xe9/0x1d0
 [] mutex_lock_nested+0x5f/0x360
 [] scsi_remove_device+0x1e/0x40
 [] sdev_store_delete+0x22/0x30
 [] dev_attr_store+0x13/0x20
 [] sysfs_kf_write+0x40/0x50
 [] kernfs_fop_write+0x137/0x1c0
 [] __vfs_write+0x23/0x140
 [] vfs_write+0xb0/0x190
 [] SyS_write+0x44/0xa0
 [] entry_SYSCALL_64_fastpath+0x18/0xad

References: http://www.spinics.net/lists/linux-scsi/msg86551.html
Signed-off-by: Bart Van Assche 
Cc: Greg Kroah-Hartman 
Cc: Eric Biederman 
Cc: Hannes Reinecke 
Cc: Johannes Thumshirn 
Cc: Sagi Grimberg 
Cc: 
---
 fs/kernfs/dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index cf4c636..44ec536 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -1410,7 +1410,7 @@ int kernfs_remove_by_name_ns(struct kernfs_node *parent, 
const char *name,
mutex_lock(&kernfs_mutex);
 
kn = kernfs_find_ns(parent, name, ns);
-   if (kn)
+   if (kn && !(kn->flags & KERNFS_SUICIDED))
__kernfs_remove(kn);
 
mutex_unlock(&kernfs_mutex);
-- 
2.10.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 v7 09/11] scsi: ufs: connect to RPMB subsystem

2016-11-07 Thread Christoph Hellwig
On Mon, Nov 07, 2016 at 07:27:38PM +, Winkler, Tomas wrote:
> I  value your opinion but I'm not responsible for inventing RPMB 
> and/or its  implementation storage devices (eMMC, UFC, NVMe), it's pretty 
> much done deal out there in the wild. 
> I'm just trying to provide common API above it.

And the common API must go through the SCSI midlayer.  If it can't we
won't support it, so please drop the UFS patches from the series.
--
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] Avoid that SCSI device removal through sysfs triggers a deadlock

2016-11-07 Thread James Bottomley
On Fri, 2016-11-04 at 12:17 -0600, Bart Van Assche wrote:
> On 11/04/2016 07:47 AM, James Bottomley wrote:
> > You know after
> > 
> > if (device_remove_file_self(dev, attr))
> > 
> > returns true that s_active is held and also that KERNFS_SUICIDAL is 
> > set on the node, so the non-self remove paths can simply check for 
> > this flag and return without descending into __kernfs_remove(), 
> > which would mean they never take s_active.  That means we never get 
> > the inversion.
> 
> Hello James,
> 
> The lock inversion is not triggered by the non-self remove paths but 
> by the self-remove path.

I think we should agree first what the problem is.  The inversion
occurs between the sysfs delete path and the device node delete caused
by a remove host.  When both are happening the inversion is that when

if (device_remove_file_self(dev, attr))
scsi_remove_device(to_scsi_device(dev));

Happens, after the if, the s_active lock is held then
scsi_remove_device goes on to take the scan_mutex.

Conversely in scsi_remove_host, the mutex is taken first then
scsi_forget_host iterates removing the devices, but sysfs file removal
eventually takes s_active in kernfs_drain, which is called from
kernfs_remove via kernfs_remove_by_name_ns, hence the inversion.

This is therefore a conflict between the self and non-self remove
paths.

> Anyway, can you have a look at the two attached 
> patches?

Well, they're still overly complex, but perhaps due to the
misunderstanding above?  If you look through that trigger case, you'll
see that the fix is simply to check KERNFS_SUICIDAL in
kernfs_remove_by_name_ns and not descend into __kernfs_remove() if it's
set.  I think kernfs_mutex mediates this, but probably only if it's
moved lower down in kernfs_drain.

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


[PATCH 0/2] qla2xxx: fix errors in PCI device remove with ongoing I/O

2016-11-07 Thread Mauricio Faria de Oliveira
This patchset addresses a couple of errors that might happen during
PCI device remove (e.g., PCI hotplug, PowerVM DLPAR), which prevent
the successful removal and re-addition of the adapter to the system,
and cause an oops and/or invalid DMA access (triggers an EEH event).

It allowed several cycles of PCI device add/remove with ongoing I/O,
to complete successfully without triggering oopses or EEH events.

Verified on v4.9-rc3.

Test-case:
---
# lspci
<...>
001d:70:00.0 Fibre Channel: QLogic Corp. ISP2532-based ...
001d:70:00.1 Fibre Channel: QLogic Corp. ISP2532-based ...
<...>

# for sd in $(find /sys/bus/pci/devices/001d:70:00.*/ \
   -name 'sd*' -printf "%f\n"); do \
dd if=/dev/$sd of=/dev/null iflag=nocache & done

# echo 1 | tee /sys/bus/pci/devices/001d:70:00.*/remove
(this either works or not)

# echo 1 > /sys/bus/pci/rescan

Before:
---
<...>
EEH: Frozen PHB#1d-PE#70 detected
qla2xxx [001d:70:00.1]-8042:2: PCI/Register disconnect, exiting.
<...>
EEH: Detected PCI bus error on PHB#29-PE#70
<...>
(and/or)
Unable to handle kernel paging request for data at address 0x0138
<...>
NIP [d4700a40] qla2xxx_queuecommand+0x80/0x3f0 [qla2xxx]
LR [d4700a10] qla2xxx_queuecommand+0x50/0x3f0 [qla2xxx]

(command does not return; adapter cannot be re-added)

After:
---
<...>
qla2xxx [001d:70:00.0]-801c:1: Abort command issued nexus=1:0:0 --  1 2003.
<...>
qla2xxx [001d:70:00.1]-801c:2: Abort command issued nexus=2:3:0 --  1 2003.
<...>

(command does return; adapter can be re-added correctly)


Mauricio Faria de Oliveira (2):
  qla2xxx: do not queue commands when unloading
  qla2xxx: fix invalid DMA access after command aborts in PCI device
remove

 drivers/scsi/qla2xxx/qla_os.c | 14 ++
 1 file changed, 14 insertions(+)

-- 
1.8.3.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 1/2] qla2xxx: do not queue commands when unloading

2016-11-07 Thread Mauricio Faria de Oliveira
When the driver is unloading, in qla2x00_remove_one(), there is a single
call/point in time to abort ongoing commands, qla2x00_abort_all_cmds(),
which is still several steps away from the call to scsi_remove_host().

If more commands continue to arrive and be processed during that interval,
when the driver is tearing down and releasing its structures, it might
potentially hit an oops due to invalid memory access:

Unable to handle kernel paging request for data at address 0x0138
<...>
NIP [d4700a40] qla2xxx_queuecommand+0x80/0x3f0 [qla2xxx]
LR [d4700a10] qla2xxx_queuecommand+0x50/0x3f0 [qla2xxx]

So, fail commands in qla2xxx_queuecommand() if the UNLOADING bit is set.

Signed-off-by: Mauricio Faria de Oliveira 
---
 drivers/scsi/qla2xxx/qla_os.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index ace65db..fdb135b 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -707,6 +707,11 @@ static int qla25xx_setup_mode(struct scsi_qla_host *vha)
srb_t *sp;
int rval;
 
+   if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) {
+   cmd->result = DID_NO_CONNECT << 16;
+   goto qc24_fail_command;
+   }
+
if (ha->flags.eeh_busy) {
if (ha->flags.pci_channel_io_perm_failure) {
ql_dbg(ql_dbg_aer, vha, 0x9010,
-- 
1.8.3.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] qla2xxx: fix invalid DMA access after command aborts in PCI device remove

2016-11-07 Thread Mauricio Faria de Oliveira
If a command is aborted in the kernel but not in the adapter, it might be
considered complete and its DMA memory released, but it is still alive in
the adapter, which will trigger an invalid DMA access upon its completion
(in the DMA operations to deliver the command response to the driver).

On powerpc platforms with IOMMU/EEH capabilities, the problem is observed
during PCI device removal with ongoing IO requests -- which might trigger
an EEH event very often, pointing to a 'TCE Request Page Access Error'.

In that path, which is qla2x00_remove_one(), the commands are aborted in
qla2x00_abort_all_cmds(), which does not perform an abort in the adapter
as is done in qla2xxx_eh_abort() for example.

So, this patch changes qla2x00_abort_all_cmds() to abort commands in the
adapter too, with a call to qla2xxx_eh_abort(), which already implements
all the logic to submit abort requests and handle responses.

Reported-by: Naresh Bannoth 
Signed-off-by: Mauricio Faria de Oliveira 
---
 drivers/scsi/qla2xxx/qla_os.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index fdb135b..c50dd22 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1456,6 +1456,15 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
sp = req->outstanding_cmds[cnt];
if (sp) {
+   /* Get a reference to the sp and drop the lock.
+* The reference ensures this sp->done() call
+* - and not the call in qla2xxx_eh_abort() -
+* ends the SCSI command (with result 'res').
+*/
+   sp_get(sp);
+   spin_unlock_irqrestore(&ha->hardware_lock, 
flags);
+   qla2xxx_eh_abort(GET_CMD_SP(sp));
+   spin_lock_irqsave(&ha->hardware_lock, flags);
req->outstanding_cmds[cnt] = NULL;
sp->done(vha, sp, res);
}
-- 
1.8.3.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 v7 09/11] scsi: ufs: connect to RPMB subsystem

2016-11-07 Thread Winkler, Tomas
> 
> On Mon, Nov 07, 2016 at 09:53:12PM +0200, Tomas Winkler wrote:
> > Register UFS RPMB LUN with the RPMB subsystem and provide
> > implementation for the RPMB access operations. RPMB partition is
> > accessed via a sequence of security protocol in and security protocol
> > out commands with UFS specific parameters. This multi step process is
> > abstracted into 4 basic RPMB commands.
> 
> This is a giant layering violation - the security protocol is not something 
> up to
> the LLDD but the core code.
> 
> And honestly the idea of defintining a security protocol in the UFS spec is 
> just
> as braindead.  If you care about this please take it up with T10 to get RPMB
> support into one of the core SCSI specs instead of a transport.

I  value your opinion but I'm not responsible for inventing RPMB 
and/or its  implementation storage devices (eMMC, UFC, NVMe), it's pretty much 
done deal out there in the wild. 
I'm just trying to provide common API above it.

Thanks
Tomas

--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Christoph Hellwig
On Mon, Nov 07, 2016 at 06:04:21PM +0100, Sebastian Andrzej Siewior wrote:
> So we keep things as they are right now or are we getting also rid of
> the internal list? This was tested by Johannes and Chad (claimed to do
> testing)

IFF the patches actually are tested as-is let's get them in.  I don't
think they are how we want the code to like in the long run, though.

> 
> Not sure what the last point is about.

It's about bnx2i and bnx2fc being clients of the main cnix driver,
which does the actual interrupt handling.  It seems we should actually
offloading things to a workqueue or threaded interrupts in that core
module instead of duplicating it in the clients.
--
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 v7 03/11] rpmb: add sysfs-class ABI documentation

2016-11-07 Thread Tomas Winkler
V2: resend
V3: add more verbose description
V4: resend
V5: adjust date and kernel version
V6: adjust date and kernel version
V7: adjust date and kernel version

Signed-off-by: Tomas Winkler 
---
 Documentation/ABI/testing/sysfs-class-rpmb | 20 
 MAINTAINERS|  1 +
 2 files changed, 21 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-class-rpmb

diff --git a/Documentation/ABI/testing/sysfs-class-rpmb 
b/Documentation/ABI/testing/sysfs-class-rpmb
new file mode 100644
index ..2ea6dbb91fac
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-class-rpmb
@@ -0,0 +1,20 @@
+What:  /sys/class/rpmb/
+Date:  Nov 2016
+KernelVersion:  4.10
+Contact:   Tomas Winkler 
+Description:
+   The rpmb/ class sub-directory belongs to RPMB device class.
+
+   Few storage technologies such is EMMC, UFS, and NVMe support
+   Replay Protected Memory Block (RPMB) hardware partition with
+   common protocol and frame layout.
+   Such a partition provides authenticated and replay protected 
access,
+   hence suitable as a secure storage.
+
+What:  /sys/class/rpmb/rpmbN/
+Date:  Nov 2016
+KernelVersion: 4.10
+Contact:   Tomas Winkler 
+Description:
+   The /sys/class/rpmb/rpmbN directory is created for
+   each RPMB registered device.
diff --git a/MAINTAINERS b/MAINTAINERS
index 7bae7c014af0..4c8ab6c09f3a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10290,6 +10290,7 @@ L:  linux-ker...@vger.kernel.org
 S: Supported
 F: drivers/char/rpmb/*
 F: include/linux/rpmb.h
+F: Documentation/ABI/testing/sysfs-class-rpmb
 
 RTL2830 MEDIA DRIVER
 M: Antti Palosaari 
-- 
2.7.4

--
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 v7 00/11] char:rpmb: Replay Protected Memory Block (RPMB) subsystem

2016-11-07 Thread Tomas Winkler
Few storage technologies such is EMMC, UFS, and NVMe support RPMB
hardware partition with common protocol and frame layout.
The RPMB partition cannot be accessed via standard block layer, but by a
set of specific commands: WRITE, READ, GET_WRITE_COUNTER, and
PROGRAM_KEY.
Such a partition provides authenticated and replay protected access,
hence suitable as a secure storage.

The RPMB layer aims to provide in-kernel API for Trusted Execution
Environment (TEE) devices that are capable to securely compute block
frame signature. In case a TEE device wish to store a replay protected
data, it creates an RPMB frame with requested data and computes HMAC of
the frame, then it requests the storage device via RPMB layer to store
the data.

The layer provides two APIs, for rpmb_req_cmd() for issuing one of RPMB
specific commands and rpmb_seq_cmd() for issuing of raw RPMB protocol
frames,  which is close to the functionality provided by emmc multi ioctl
interface.

A TEE driver can claim the RPMB interface, for example, via
class_interface_register ().

A storage device registers its RPMB hardware (eMMC) partition or RPMB
W-LUN (UFS) with the RPMB layer providing an implementation for
rpmb_seq_cmd() handler. The interface enables sending sequence of RPMB
standard frames.

A parallel user space API is provided via /dev/rpmbX character
device with two IOCTL commands.
Simplified one, RPMB_IOC_REQ_CMD, were read result cycles is performed
by the framework on behalf the user and second, RPMB_IOC_SEQ_CMD where
the whole RPMB sequence, including RESULT_READ is supplied by the caller.
The latter is intended for easier adjusting of the applications that
use MMC_IOC_MULTI_CMD ioctl, such as
https://android.googlesource.com/trusty/app/storage/

There is a also sample tool under tools/rpmb/ directory that exercises
these interfaces and a simulation device that implements the device part.

The code is also available from:

https://github.com/tomasbw/linux-mei.git rpmb

V7  1. Special thanks to Avri Altman  for testing emmc 
and ufs.
2. Fix char device interface.
3. Add Documentation
4. Addional small fixes described in individual patches.

Tomas Winkler (11):
  rpmb: add Replay Protected Memory Block (RPMB) subsystem
  rpmb: enable emmc specific read data fixup
  rpmb: add sysfs-class ABI documentation
  char: rpmb: add device attributes
  char: rpmb: provide a user space interface
  char: rpmb: add RPMB simulation device
  tools rpmb: add RPBM access tool
  mmc: block: register RPMB partition with the RPMB subsystem
  scsi: ufs: connect to RPMB subsystem
  scsi: ufs: retrieve rpmb rw size
  char: rpmb: Document Replay Protected Memory Block (RPMB) subsystem

 Documentation/ABI/testing/sysfs-class-rpmb |   47 ++
 Documentation/index.rst|1 +
 Documentation/ioctl/ioctl-number.txt   |1 +
 Documentation/rpmb/conf.py |5 +
 Documentation/rpmb/index.rst   |   18 +
 Documentation/rpmb/introduction.rst|  102 +++
 Documentation/rpmb/rpmb-tool.rst   |   19 +
 Documentation/rpmb/simulation-device.rst   |   19 +
 MAINTAINERS|   11 +
 drivers/char/Kconfig   |2 +
 drivers/char/Makefile  |1 +
 drivers/char/rpmb/Kconfig  |   32 +
 drivers/char/rpmb/Makefile |6 +
 drivers/char/rpmb/cdev.c   |  331 +
 drivers/char/rpmb/core.c   |  523 ++
 drivers/char/rpmb/rpmb-cdev.h  |   25 +
 drivers/char/rpmb/rpmb_sim.c   |  744 
 drivers/mmc/card/Kconfig   |1 +
 drivers/mmc/card/block.c   |  258 ++-
 drivers/scsi/ufs/Kconfig   |1 +
 drivers/scsi/ufs/ufs.h |6 +
 drivers/scsi/ufs/ufshcd.c  |  205 ++
 drivers/scsi/ufs/ufshcd.h  |2 +
 include/linux/rpmb.h   |  167 +
 include/uapi/linux/Kbuild  |1 +
 include/uapi/linux/rpmb.h  |  153 
 tools/Makefile |   14 +-
 tools/rpmb/.gitignore  |2 +
 tools/rpmb/Makefile|   34 +
 tools/rpmb/rpmb.c  | 1035 
 30 files changed, 3758 insertions(+), 8 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-class-rpmb
 create mode 100644 Documentation/rpmb/conf.py
 create mode 100644 Documentation/rpmb/index.rst
 create mode 100644 Documentation/rpmb/introduction.rst
 create mode 100644 Documentation/rpmb/rpmb-tool.rst
 create mode 100644 Documentation/rpmb/simulation-device.rst
 create mode 100644 drivers/char/rpmb/Kconfig
 create mode 100644 drivers/char/rpmb/Makefile
 create mode 100644 drivers/char/rpmb/cdev.c
 create mode 100644 drivers/char/rpmb/core.c
 create mode 100644 drivers/char/rpmb/rpmb-cdev.h
 create mo

Re: [PATCH v7 09/11] scsi: ufs: connect to RPMB subsystem

2016-11-07 Thread Christoph Hellwig
On Mon, Nov 07, 2016 at 09:53:12PM +0200, Tomas Winkler wrote:
> Register UFS RPMB LUN with the RPMB subsystem and provide
> implementation for the RPMB access operations. RPMB partition is
> accessed via a sequence of security protocol in and security protocol
> out commands with UFS specific parameters. This multi step process is
> abstracted into 4 basic RPMB commands.

This is a giant layering violation - the security protocol is not something
up to the LLDD but the core code.

And honestly the idea of defintining a security protocol in the UFS
spec is just as braindead.  If you care about this please take it up
with T10 to get RPMB support into one of the core SCSI specs instead
of a transport.
--
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 v7 01/11] rpmb: add Replay Protected Memory Block (RPMB) subsystem

2016-11-07 Thread Tomas Winkler
Few storage technologies such is EMMC, UFS, and NVMe support RPMB
hardware partition with common protocol and frame layout.
The RPMB partition cannot be accessed via standard block layer,
but by a set of specific commands: WRITE, READ, GET_WRITE_COUNTER,
and PROGRAM_KEY.
Such a partition provides authenticated and replay protected access,
hence suitable as a secure storage.

The RPMB layer aims to provide in-kernel API for Trusted Execution
Environment (TEE) devices that are capable to securely compute block
frame signature. In case a TEE device wish to store a replay protected
data, it creates an RPMB frame with requested data and computes HMAC of
the frame, then it requests the storage device via RPMB layer to store
the data.
A TEE device driver can claim the RPMB interface, for example, via
class_interface_register ().
The layer provides two APIs rpmb_cmd_req() for issuing one of RPMB
specific commands and rpmb_cmd_seq() for issuing of raw RPMB protocol
frames sequence.
The major difference between the APIs is that for rpmb_cmd_req() the
framework performs RPMB_RESULT_READ operation on behalf of a user.
The RPMB_RESULT_READ is used for retrieving result of the commands
that carry data in the write cycle and need one more step to retrieve
the result.

A storage device registers its RPMB (eMMC) partition or RPMB
W-LUN (UFS) with the RPMB layer providing an implementation for
rpmb_cmd_seq() handler. The interface enables sending sequence of RPMB
standard frames.

V2: added short workflow description in the commit message
V3: commit message fix
V4: resend
V5: add rpmb sequence interface.
V6: 1. More info in the commit message
2. Define simulation device type
V7: resend

Signed-off-by: Tomas Winkler 
Signed-off-by: Alexander Usyskin 
---
 MAINTAINERS|   7 +
 drivers/char/Kconfig   |   2 +
 drivers/char/Makefile  |   1 +
 drivers/char/rpmb/Kconfig  |   8 +
 drivers/char/rpmb/Makefile |   4 +
 drivers/char/rpmb/core.c   | 414 +
 include/linux/rpmb.h   | 232 +
 7 files changed, 668 insertions(+)
 create mode 100644 drivers/char/rpmb/Kconfig
 create mode 100644 drivers/char/rpmb/Makefile
 create mode 100644 drivers/char/rpmb/core.c
 create mode 100644 include/linux/rpmb.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3d838cf49f81..7bae7c014af0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10284,6 +10284,13 @@ F: include/net/rose.h
 F: include/uapi/linux/rose.h
 F: net/rose/
 
+RPMB SUBSYSTEM
+M: Tomas Winkler 
+L: linux-ker...@vger.kernel.org
+S: Supported
+F: drivers/char/rpmb/*
+F: include/linux/rpmb.h
+
 RTL2830 MEDIA DRIVER
 M: Antti Palosaari 
 L: linux-me...@vger.kernel.org
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index dc4f35ad19d0..220c86663b25 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -589,5 +589,7 @@ config TILE_SROM
 
 source "drivers/char/xillybus/Kconfig"
 
+source "drivers/char/rpmb/Kconfig"
+
 endmenu
 
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 6e6c244a66a0..3a0cac3ff2dc 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -60,3 +60,4 @@ js-rtc-y = rtc.o
 obj-$(CONFIG_TILE_SROM)+= tile-srom.o
 obj-$(CONFIG_XILLYBUS) += xillybus/
 obj-$(CONFIG_POWERNV_OP_PANEL) += powernv-op-panel.o
+obj-$(CONFIG_RPMB) += rpmb/
diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
new file mode 100644
index ..c5e6e909efce
--- /dev/null
+++ b/drivers/char/rpmb/Kconfig
@@ -0,0 +1,8 @@
+config RPMB
+   tristate "RPMB partition interface"
+   help
+ Unified RPMB partition interface for eMMC and UFS.
+ Provides interface for in kernel security controllers to
+ access RPMB partition.
+
+ If unsure, select N.
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
new file mode 100644
index ..812b3ed264c0
--- /dev/null
+++ b/drivers/char/rpmb/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_RPMB) += rpmb.o
+rpmb-objs += core.o
+
+ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c
new file mode 100644
index ..ff10cbb7b644
--- /dev/null
+++ b/drivers/char/rpmb/core.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2015-2016 Intel Corp. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+static DEFINE_IDA(rpmb_ida);
+
+/**
+ * rpm

[PATCH v7 02/11] rpmb: enable emmc specific read data fixup

2016-11-07 Thread Tomas Winkler
For eMMC the block count of the RPMB read operation is not indicated in
the original RPMB Data Read Request packet.
This might be different then the implementation of other protocol
standards.
This patch implements a fixup for this behavior.

V6: new in the series
V7: resend

Signed-off-by: Tomas Winkler 
---
 drivers/char/rpmb/core.c | 36 +---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c
index ff10cbb7b644..8cfbbb721538 100644
--- a/drivers/char/rpmb/core.c
+++ b/drivers/char/rpmb/core.c
@@ -117,6 +117,35 @@ static int rpmb_request_verify(struct rpmb_dev *rdev, 
struct rpmb_data *rpmbd)
 }
 
 /**
+ * rpmb_cmd_fixup - fixup rpmb command
+ *
+ * @rdev: rpmb device
+ * @cmds: rpmb command list
+ * @ncmds: number of commands
+ *
+ */
+static void rpmb_cmd_fixup(struct rpmb_dev *rdev,
+  struct rpmb_cmd *cmds, u32 ncmds)
+{
+   int i;
+
+   if (rdev->ops->type != RPMB_TYPE_EMMC)
+   return;
+
+   /* Fixup RPMB_READ_DATA specific to eMMC
+* The block count of the RPMB read operation is not indicated
+* in the original RPMB Data Read Request packet.
+* This is different then implementation for other protocol
+* standards.
+*/
+   for (i = 0; i < ncmds; i++)
+   if (cmds->frames->req_resp == cpu_to_be16(RPMB_READ_DATA)) {
+   dev_dbg(&rdev->dev, "Fixing up READ_DATA frame to 
block_count=0\n");
+   cmds->frames->block_count = 0;
+   }
+}
+
+/**
  * rpmb_cmd_seq - send RPMB command sequence
  *
  * @rdev: rpmb device
@@ -136,10 +165,11 @@ int rpmb_cmd_seq(struct rpmb_dev *rdev, struct rpmb_cmd 
*cmds, u32 ncmds)
return -EINVAL;
 
mutex_lock(&rdev->lock);
-   if (rdev->ops && rdev->ops->cmd_seq)
+   err = -EOPNOTSUPP;
+   if (rdev->ops && rdev->ops->cmd_seq) {
+   rpmb_cmd_fixup(rdev, cmds, ncmds);
err = rdev->ops->cmd_seq(rdev->dev.parent, cmds, ncmds);
-   else
-   err = -EOPNOTSUPP;
+   }
mutex_unlock(&rdev->lock);
return err;
 }
-- 
2.7.4

--
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 v7 06/11] char: rpmb: add RPMB simulation device

2016-11-07 Thread Tomas Winkler
The RPMB partition simulation device is a virtual device that
provides simulation of the RPMB protocol and use kernel memory
as storage.

Be aware it doesn't promise any real security. This driver is
suitable only for testing of the RPMB subsystem or RPMB
applications prior to RPMB key provisioning, as RPMB key
programming can be performed only once in the life time of the
storage device.

The module currently supports two configuration options via
module parameters
1. max_wr_blks: for specifying max blocks that can be written
in a single command
2. daunits:  used to set storage capacity in 128K units.

V2: remove .owner setting, it is set automatically
V3: 1. Add shutdown handler (similar to ufshcd)
2. Commit message fix
V4: Use select RPMB in Kconfg to ensure valid configuration.
V5: Revamp the code using the sequence command.
V6: 1. Be more verbose about some errors, after all this is a testing
module.
2. Fix RPMB_READ_DATA:
   a. The number of blocks for eMMC request frame should be 0
   b. Fix missing return before bailing on error
   c. Copy all the frames back
3. Fix RPMB_WRITE_DATA:
   a. Compute MAC on result packet
   b. Also address should be set in the result frame.
4. Remove platform device
5. Update the commit message
V7: Resend.

Signed-off-by: Tomas Winkler 
---
 drivers/char/rpmb/Kconfig|  17 +
 drivers/char/rpmb/Makefile   |   1 +
 drivers/char/rpmb/rpmb_sim.c | 744 +++
 3 files changed, 762 insertions(+)
 create mode 100644 drivers/char/rpmb/rpmb_sim.c

diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
index 6794be9fcc5e..533d813e9ed5 100644
--- a/drivers/char/rpmb/Kconfig
+++ b/drivers/char/rpmb/Kconfig
@@ -13,3 +13,20 @@ config RPMB_INTF_DEV
help
  Say yes here if you want to access RPMB from user space
  via character device interface /dev/rpmb%d
+
+
+config RPMB_SIM
+   tristate "RPMB partition device simulator"
+   default n
+   select RPMB
+   select CRYPTO_SHA256
+   select CRYPTO_HMAC
+   help
+ RPMB partition simulation device is a virtual device that
+ provides simulation of the RPMB protocol and use kernel memory
+ as storage.
+
+ Be aware it doesn't promise any real security. This driver is
+ suitable only for testing of the RPMB subsystem or RPMB applications
+ prior to RPMB key provisioning.
+  Most people should say N here.
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
index b5dc087b1299..81f924fd9a87 100644
--- a/drivers/char/rpmb/Makefile
+++ b/drivers/char/rpmb/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_RPMB) += rpmb.o
 rpmb-objs += core.o
 rpmb-$(CONFIG_RPMB_INTF_DEV) += cdev.o
+obj-$(CONFIG_RPMB_SIM) += rpmb_sim.o
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/rpmb_sim.c b/drivers/char/rpmb/rpmb_sim.c
new file mode 100644
index ..429a08bd67d7
--- /dev/null
+++ b/drivers/char/rpmb/rpmb_sim.c
@@ -0,0 +1,744 @@
+/**
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ * Intel Corporation.
+ * linux-...@linux.intel.com
+ * http://www.intel.com
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in
+ *the documentation and/or other materials provided with the
+ *distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *contributors may be used to endorse or promote products derived
+ *from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXP

[PATCH v7 05/11] char: rpmb: provide a user space interface

2016-11-07 Thread Tomas Winkler
The user space API is achieved via two synchronous IOCTLs.
Simplified one, RPMB_IOC_REQ_CMD, were read result cycles is performed
by the framework on behalf the user and second, RPMB_IOC_SEQ_CMD where
the whole RPMB sequence including RESULT_READ is supplied by the caller.
The latter is intended for easier adjusting of the applications that
use MMC_IOC_MULTI_CMD ioctl.

V2: use memdup_user
V3: commit message fix
V4: resend
V5: 1. Add RPMB_IOC_SEQ_CMD API.
2. Export uapi rpmb.h header
V6: 1. Remove #include .
2. Add ioctl documentation.
V7: 1. copy_from_user the value of the frame pointer.
2. Fix possible macro side-effect due to macro argument reuse.

Signed-off-by: Tomas Winkler 
---
 Documentation/ioctl/ioctl-number.txt |   1 +
 MAINTAINERS  |   1 +
 drivers/char/rpmb/Kconfig|   7 +
 drivers/char/rpmb/Makefile   |   1 +
 drivers/char/rpmb/cdev.c | 331 +++
 drivers/char/rpmb/core.c |   9 +-
 drivers/char/rpmb/rpmb-cdev.h|  25 +++
 include/linux/rpmb.h |  81 +
 include/uapi/linux/Kbuild|   1 +
 include/uapi/linux/rpmb.h| 153 
 10 files changed, 536 insertions(+), 74 deletions(-)
 create mode 100644 drivers/char/rpmb/cdev.c
 create mode 100644 drivers/char/rpmb/rpmb-cdev.h
 create mode 100644 include/uapi/linux/rpmb.h

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 81c7f2bb7daf..f645543866c7 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -321,6 +321,7 @@ Code  Seq#(hex) Include FileComments
 0xB1   00-1F   PPPoX   
 0xB3   00  linux/mmc/ioctl.h
 0xB4   00-0F   linux/gpio.h
+0xB5   00-01   linux/uapi/linux/rpmb.h 
 0xC0   00-0F   linux/usb/iowarrior.h
 0xCA   00-0F   uapi/misc/cxl.h
 0xCA   80-8F   uapi/scsi/cxlflash_ioctl.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4c8ab6c09f3a..090b6d2d31fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10289,6 +10289,7 @@ M:  Tomas Winkler 
 L: linux-ker...@vger.kernel.org
 S: Supported
 F: drivers/char/rpmb/*
+F: include/uapi/linux/rpmb.h
 F: include/linux/rpmb.h
 F: Documentation/ABI/testing/sysfs-class-rpmb
 
diff --git a/drivers/char/rpmb/Kconfig b/drivers/char/rpmb/Kconfig
index c5e6e909efce..6794be9fcc5e 100644
--- a/drivers/char/rpmb/Kconfig
+++ b/drivers/char/rpmb/Kconfig
@@ -6,3 +6,10 @@ config RPMB
  access RPMB partition.
 
  If unsure, select N.
+
+config RPMB_INTF_DEV
+   bool "RPMB character device interface /dev/rpmbN"
+   depends on RPMB
+   help
+ Say yes here if you want to access RPMB from user space
+ via character device interface /dev/rpmb%d
diff --git a/drivers/char/rpmb/Makefile b/drivers/char/rpmb/Makefile
index 812b3ed264c0..b5dc087b1299 100644
--- a/drivers/char/rpmb/Makefile
+++ b/drivers/char/rpmb/Makefile
@@ -1,4 +1,5 @@
 obj-$(CONFIG_RPMB) += rpmb.o
 rpmb-objs += core.o
+rpmb-$(CONFIG_RPMB_INTF_DEV) += cdev.o
 
 ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/char/rpmb/cdev.c b/drivers/char/rpmb/cdev.c
new file mode 100644
index ..9e3ae753a9a1
--- /dev/null
+++ b/drivers/char/rpmb/cdev.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2015-2016 Intel Corp. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "rpmb-cdev.h"
+
+static dev_t rpmb_devt;
+#define RPMB_MAX_DEVS  MINORMASK
+
+#define RPMB_DEV_OPEN0  /** single open bit (position) */
+/* from MMC_IOC_MAX_CMDS */
+#define RPMB_MAX_FRAMES 255
+
+/**
+ * rpmb_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @fp: pointer to file structure
+ *
+ * Return: 0 on success, <0 on error
+ */
+static int rpmb_open(struct inode *inode, struct file *fp)
+{
+   struct rpmb_dev *rdev;
+
+   rdev = container_of(inode->i_cdev, struct rpmb_dev, cdev);
+   if (!rdev)
+   return -ENODEV;
+
+   /* the rpmb is single open! */
+   if (test_and_set_bit(RPMB_DEV_OPEN, &rdev->status))
+   return -EBUSY;
+
+   mutex_lock(&rdev->lock);
+
+   fp->private_data = rdev;
+
+   mutex_unlock(&rdev->lock);
+
+   return nonseekable_open(inode, fp);
+}
+
+/**
+ * rpmb_open - 

[PATCH v7 04/11] char: rpmb: add device attributes

2016-11-07 Thread Tomas Winkler
Add attribute type that displays underlay storage type technology
EMMC, UFS, and attribute id, that displays underlay storage device id.
For EMMC this would be content of CID and for UFS serial number from
the device descriptor.

V2: resend
V3: set kernel version to 4.7
V4: update target date to Maj
V5: update date and kernel version
V6: 1. Add simulation device type
2. Update date and kernel version
3. Use binary attribute for id
4. use simple sprintf instead of scnprintf
5. Add more verbose documenation
V7: resend

Signed-off-by: Tomas Winkler 
---
 Documentation/ABI/testing/sysfs-class-rpmb | 27 +++
 drivers/char/rpmb/core.c   | 72 ++
 2 files changed, 99 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-class-rpmb 
b/Documentation/ABI/testing/sysfs-class-rpmb
index 2ea6dbb91fac..3c01925e29dc 100644
--- a/Documentation/ABI/testing/sysfs-class-rpmb
+++ b/Documentation/ABI/testing/sysfs-class-rpmb
@@ -18,3 +18,30 @@ Contact: Tomas Winkler 
 Description:
The /sys/class/rpmb/rpmbN directory is created for
each RPMB registered device.
+
+What:  /sys/class/rpmb/rpmbN/type
+Date:  Nov 2016
+KernelVersion: 4.10
+Contact:   Tomas Winkler 
+Description:
+   The /sys/class/rpmb/rpmbN/type file contains device
+   underlaying storage type technology: EMMC, UFS, SIM.
+
+What:  /sys/class/rpmb/rpmbN/id
+Date:  Nov 2016
+KernelVersion: 4.10
+Contact:   Tomas Winkler 
+Description:
+   The /sys/class/rpmb/rpmbN/id file contains unique device id
+   in a binary form as defined by underlying storage device.
+   In case of multiple RPMB devices a user can determine correct
+   device.
+   The content can be parsed according the storage device type.
+
+What:  /sys/class/rpmb/rpmbN/reliable_wr_cnt
+Date:  Nov 2016
+KernelVersion: 4.10
+Contact:   Tomas Winkler 
+Description:
+   The /sys/class/rpmb/rpmbN/reliable_wr_cnt file contains
+   number of blocks that can be reliable written in a single 
request.
diff --git a/drivers/char/rpmb/core.c b/drivers/char/rpmb/core.c
index 8cfbbb721538..f6b4cabb0982 100644
--- a/drivers/char/rpmb/core.c
+++ b/drivers/char/rpmb/core.c
@@ -338,6 +338,76 @@ struct rpmb_dev *rpmb_dev_find_by_device(struct device 
*parent)
 }
 EXPORT_SYMBOL_GPL(rpmb_dev_find_by_device);
 
+static ssize_t type_show(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+   struct rpmb_dev *rdev = to_rpmb_dev(dev);
+   ssize_t ret;
+
+   switch (rdev->ops->type) {
+   case RPMB_TYPE_EMMC:
+   ret = sprintf(buf, "EMMC\n");
+   break;
+   case RPMB_TYPE_UFS:
+   ret = sprintf(buf, "UFS\n");
+   break;
+   case RPMB_TYPE_SIM:
+   ret = sprintf(buf, "SIM\n");
+   break;
+   default:
+   ret = sprintf(buf, "UNKNOWN\n");
+   break;
+   }
+
+   return ret;
+}
+static DEVICE_ATTR_RO(type);
+
+static ssize_t id_read(struct file *file, struct kobject *kobj,
+  struct bin_attribute *attr, char *buf,
+  loff_t off, size_t count)
+{
+   struct device *dev = kobj_to_dev(kobj);
+   struct rpmb_dev *rdev = to_rpmb_dev(dev);
+   size_t sz = min_t(size_t, rdev->ops->dev_id_len, PAGE_SIZE);
+
+   if (!rdev->ops->dev_id)
+   return 0;
+
+   return memory_read_from_buffer(buf, count, &off, rdev->ops->dev_id, sz);
+}
+static BIN_ATTR_RO(id, 0);
+
+static ssize_t reliable_wr_cnt_show(struct device *dev,
+   struct device_attribute *attr, char *buf)
+{
+   struct rpmb_dev *rdev = to_rpmb_dev(dev);
+
+   return sprintf(buf, "%u\n", rdev->ops->reliable_wr_cnt);
+}
+static DEVICE_ATTR_RO(reliable_wr_cnt);
+
+static struct attribute *rpmb_attrs[] = {
+   &dev_attr_type.attr,
+   &dev_attr_reliable_wr_cnt.attr,
+   NULL,
+};
+
+static struct bin_attribute *rpmb_bin_attributes[] = {
+   &bin_attr_id,
+   NULL,
+};
+
+static struct attribute_group rpmb_attr_group = {
+   .attrs = rpmb_attrs,
+   .bin_attrs = rpmb_bin_attributes,
+};
+
+static const struct attribute_group *rpmb_attr_groups[] = {
+   &rpmb_attr_group,
+   NULL
+};
+
 /**
  * rpmb_dev_unregister - unregister RPMB partition from the RPMB subsystem
  *
@@ -407,6 +477,8 @@ struct rpmb_dev *rpmb_dev_register(struct device *dev,
dev_set_name(&rdev->dev, "rpmb%d", id);
rdev->dev.class = &rpmb_class;
rdev->dev.parent = dev;
+   rdev->dev.groups = rpmb_attr_groups;
+
ret = device_register(&rdev->dev);
if (ret)
goto exit;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vg

[PATCH v7 11/11] char: rpmb: Document Replay Protected Memory Block (RPMB) subsystem

2016-11-07 Thread Tomas Winkler
Add rpmb documentatin in sphinx format.

V7: new in the series

Signed-off-by: Tomas Winkler 
---
 Documentation/index.rst  |   1 +
 Documentation/rpmb/conf.py   |   5 ++
 Documentation/rpmb/index.rst |  18 ++
 Documentation/rpmb/introduction.rst  | 102 +++
 Documentation/rpmb/rpmb-tool.rst |  19 ++
 Documentation/rpmb/simulation-device.rst |  19 ++
 MAINTAINERS  |   1 +
 7 files changed, 165 insertions(+)
 create mode 100644 Documentation/rpmb/conf.py
 create mode 100644 Documentation/rpmb/index.rst
 create mode 100644 Documentation/rpmb/introduction.rst
 create mode 100644 Documentation/rpmb/rpmb-tool.rst
 create mode 100644 Documentation/rpmb/simulation-device.rst

diff --git a/Documentation/index.rst b/Documentation/index.rst
index c53d089455a4..56dd46e9359c 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -18,6 +18,7 @@ Contents:
media/index
gpu/index
80211/index
+   rpmb/index
 
 Indices and tables
 ==
diff --git a/Documentation/rpmb/conf.py b/Documentation/rpmb/conf.py
new file mode 100644
index ..20c7c275ef4a
--- /dev/null
+++ b/Documentation/rpmb/conf.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8; mode: python -*-
+
+project = "Linux 802.11 Driver Developer's Guide"
+
+tags.add("subproject")
diff --git a/Documentation/rpmb/index.rst b/Documentation/rpmb/index.rst
new file mode 100644
index ..876a2603e4b5
--- /dev/null
+++ b/Documentation/rpmb/index.rst
@@ -0,0 +1,18 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+==
+Replay Protected Memory Block (RPMB) subsystem
+==
+
+.. toctree::
+
+   introduction
+   simulation-device.rst
+   rpmb-tool.rst
+
+.. only::  subproject
+
+   Indices
+   ===
+
+   * :ref:`genindex`
diff --git a/Documentation/rpmb/introduction.rst 
b/Documentation/rpmb/introduction.rst
new file mode 100644
index ..f4ded7d18e55
--- /dev/null
+++ b/Documentation/rpmb/introduction.rst
@@ -0,0 +1,102 @@
+.. -*- coding: utf-8; mode: rst -*-
+
+=
+Introduction:
+=
+
+Few storage technologies such is EMMC, UFS, and NVMe support RPMB
+hardware partition with common protocol and frame layout.
+The RPMB partition `cannot` be accessed via standard block layer,
+but by a set of specific commands:
+
+WRITE, READ, GET_WRITE_COUNTER, and PROGRAM_KEY.
+
+The commands and the data are embedded within :c:type:`rpmb_frame 
`.
+
+An RPMB partition provides authenticated and replay protected access,
+hence it is suitable as a secure storage.
+
+In-kernel API
+-
+The RPMB layer aims to provide in-kernel API for Trusted Execution
+Environment (TEE) devices that are capable to securely compute the block
+frame signature. In case a TEE device wish to store a replay protected
+data, it creates an RPMB frame with requested data and computes HMAC of
+the frame, then it requests the storage device via RPMB layer to store
+the data.
+
+The layer provides two APIs, for :c:func:`rpmb_req_cmd()` for issuing one of 
RPMB
+specific commands and :c:func:`rpmb_seq_cmd()` for issuing of raw RPMB protocol
+frames, which is close to the functionality provided by emmc multi ioctl
+interface.
+
+.. c:function:: int rpmb_cmd_req(struct rpmb_dev *rdev, struct rpmb_data 
*data);
+
+.. c:function:: int rpmb_cmd_seq(struct rpmb_dev *rdev, struct rpmb_cmd *cmds, 
u32 ncmds);
+
+
+A TEE driver can claim the RPMB interface, for example, via
+:c:func:`class_interface_register`:
+
+.. code-block:: c
+
+struct class_interface tee_rpmb_intf = {
+.class  = &rpmb_class;
+.add_dev= rpmb_add_device;
+.remove_dev = rpmb_remove_device;
+}
+class_interface_register(&tee_rpmb_intf);
+
+
+RPMB device registeration
+
+
+A storage device registers its RPMB hardware (eMMC) partition or RPMB
+W-LUN (UFS) with the RPMB layer :c:func:`rpmb_dev_register` providing
+an implementation for :c:func:`rpmb_seq_cmd()` handler. The interface
+enables sending sequence of RPMB standard frames.
+
+.. code-block:: c
+
+struct rpmb_ops mmc_rpmb_dev_ops = {
+.cmd_seq = mmc_blk_rpmb_cmd_seq,
+.type = RPMB_TYPE_EMMC,
+...
+}
+rpmb_dev_register(disk_to_dev(part_md->disk), &mmc_rpmb_dev_ops);
+
+
+User space API
+--
+
+A parallel user space API is provided via /dev/rpmbX character
+device with two IOCTL commands.
+Simplified one, ``RPMB_IOC_REQ_CMD``, were read result cycles is performed
+by the framework on behalf the user and second, ``RPMB_IOC_SEQ_CMD`` where
+the whole RPMB sequence, including ``RESULT_READ`` is supplied by the caller.
+The latter is intended for easier adjusting of the applications that
+use ``MMC_IOC_MULTI_CMD`` ioctl, such as
+https://androi

[PATCH v7 09/11] scsi: ufs: connect to RPMB subsystem

2016-11-07 Thread Tomas Winkler
Register UFS RPMB LUN with the RPMB subsystem and provide
implementation for the RPMB access operations. RPMB partition is
accessed via a sequence of security protocol in and security protocol
out commands with UFS specific parameters. This multi step process is
abstracted into 4 basic RPMB commands.

V2: resend
V3: resend
V4: Kconfig: use select RPMB to ensure valid configuration
V5: Revamp code using new sequence command.
V6: Resend
V7: Resend

Signed-off-by: Alexander Usyskin 
Signed-off-by: Tomas Winkler 
---
 drivers/scsi/ufs/Kconfig  |   1 +
 drivers/scsi/ufs/ufshcd.c | 183 ++
 drivers/scsi/ufs/ufshcd.h |   2 +
 3 files changed, 186 insertions(+)

diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e27b4d4e6ae2..8b545a9c51dd 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -38,6 +38,7 @@ config SCSI_UFSHCD
select PM_DEVFREQ
select DEVFREQ_GOV_SIMPLE_ONDEMAND
select NLS
+   select RPMB
---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/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 05c745663c10..95bb9dc7fbfe 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -37,10 +37,13 @@
  * license terms, and distributes only under these terms.
  */
 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
+
 #include "ufshcd.h"
 #include "ufs_quirks.h"
 #include "unipro.h"
@@ -4753,6 +4756,178 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba)
 
 }
 
+#define SEC_PROTOCOL_UFS  0xEC
+#define   SEC_SPECIFIC_UFS_RPMB 0x0001
+
+#define SEC_PROTOCOL_CMD_SIZE 12
+#define SEC_PROTOCOL_RETRIES 3
+#define SEC_PROTOCOL_RETRIES_ON_RESET 10
+#define SEC_PROTOCOL_TIMEOUT msecs_to_jiffies(1000)
+
+static int
+ufshcd_rpmb_security_out(struct scsi_device *sdev,
+struct rpmb_frame *frames, u32 cnt)
+{
+   struct scsi_sense_hdr sshdr;
+   u32 trans_len = cnt * sizeof(struct rpmb_frame);
+   int reset_retries = SEC_PROTOCOL_RETRIES_ON_RESET;
+   int ret;
+   u8 cmd[SEC_PROTOCOL_CMD_SIZE];
+
+   memset(cmd, 0, SEC_PROTOCOL_CMD_SIZE);
+   cmd[0] = SECURITY_PROTOCOL_OUT;
+   cmd[1] = SEC_PROTOCOL_UFS;
+   put_unaligned_be16(SEC_SPECIFIC_UFS_RPMB, cmd + 2);
+   cmd[4] = 0;  /* inc_512 bit 7 set to 0 */
+   put_unaligned_be32(trans_len, cmd + 6);  /* transfer length */
+
+retry:
+   ret = scsi_execute_req_flags(sdev, cmd, DMA_TO_DEVICE,
+frames, trans_len, &sshdr,
+SEC_PROTOCOL_TIMEOUT, SEC_PROTOCOL_RETRIES,
+NULL, 0);
+
+   if (ret && scsi_sense_valid(&sshdr) &&
+   sshdr.sense_key == UNIT_ATTENTION &&
+   sshdr.asc == 0x29 && sshdr.ascq == 0x00)
+   /*
+* Device reset might occur several times,
+* give it one more chance
+*/
+   if (--reset_retries > 0)
+   goto retry;
+
+   if (ret)
+   dev_err(&sdev->sdev_gendev, "%s: failed with err %0x\n",
+   __func__, ret);
+
+   if (driver_byte(ret) & DRIVER_SENSE)
+   scsi_print_sense_hdr(sdev, "rpmb: security out", &sshdr);
+
+   return ret;
+}
+
+static int
+ufshcd_rpmb_security_in(struct scsi_device *sdev,
+   struct rpmb_frame *frames, u32 cnt)
+{
+   struct scsi_sense_hdr sshdr;
+   u32 alloc_len = cnt * sizeof(struct rpmb_frame);
+   int reset_retries = SEC_PROTOCOL_RETRIES_ON_RESET;
+   int ret;
+   u8 cmd[SEC_PROTOCOL_CMD_SIZE];
+
+   memset(cmd, 0, SEC_PROTOCOL_CMD_SIZE);
+   cmd[0] = SECURITY_PROTOCOL_IN;
+   cmd[1] = SEC_PROTOCOL_UFS;
+   put_unaligned_be16(SEC_SPECIFIC_UFS_RPMB, cmd + 2);
+   cmd[4] = 0; /* inc_512 bit 7 set to 0 */
+   put_unaligned_be32(alloc_len, cmd + 6); /* allocation length */
+
+retry:
+   ret = scsi_execute_req_flags(sdev, cmd, DMA_FROM_DEVICE,
+frames, alloc_len, &sshdr,
+SEC_PROTOCOL_TIMEOUT, SEC_PROTOCOL_RETRIES,
+NULL, 0);
+
+   if (ret && scsi_sense_valid(&sshdr) &&
+   sshdr.sense_key == UNIT_ATTENTION &&
+   sshdr.asc == 0x29 && sshdr.ascq == 0x00)
+   /*
+* Device reset might occur several times,
+* give it one more chance
+   */
+   if (--reset_retries > 0)
+   goto retry;
+
+   if (ret)
+   dev_err(&sdev->sdev_gendev, "%s: failed with err %0x\n",
+   __func__, ret);
+
+   if (driver_byte(ret) & DRIVER_SENSE)
+   scsi_print_sense_h

[PATCH v7 10/11] scsi: ufs: retrieve rpmb rw size

2016-11-07 Thread Tomas Winkler
Retrieve maximum number of RPMB frames that can be
in a single request.
Currently the limitations is provided only for writes
via reliable_wr_cnt API.

V7: New in the series

Signed-off-by: Tomas Winkler 
Signed-off-by: Alexander Usyskin 
---
 drivers/scsi/ufs/ufs.h|  6 ++
 drivers/scsi/ufs/ufshcd.c | 22 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 845b874e2977..84bb8d7c6b63 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -176,6 +176,12 @@ enum ufs_desc_max_size {
QUERY_DESC_RFU_MAX_SIZE = 0x00,
 };
 
+enum geometry_desc_param_offset {
+   GEOMETRY_DESC_LEN   = 0x0,
+   GEOMETRY_DESC_TYPE  = 0x1,
+   GEOMETRY_DESC_RPMB_RW_SIZE  = 0x17,
+};
+
 /* Unit descriptor parameters offsets in bytes*/
 enum unit_desc_param {
UNIT_DESC_PARAM_LEN = 0x0,
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 95bb9dc7fbfe..69f5b03f6774 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2196,6 +2196,15 @@ static inline int ufshcd_read_unit_desc_param(struct 
ufs_hba *hba,
  param_offset, param_read_buf, param_size);
 }
 
+static inline int ufshcd_read_geometry_desc_param(struct ufs_hba *hba,
+   enum geometry_desc_param_offset param_offset,
+   u8 *param_read_buf, u32 param_size)
+{
+   return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_GEOMETRY, 0,
+ param_offset, param_read_buf, param_size);
+}
+
+
 /**
  * ufshcd_memory_alloc - allocate memory for host memory space data structures
  * @hba: per adapter instance
@@ -4896,6 +4905,19 @@ static struct rpmb_ops ufshcd_rpmb_dev_ops = {
 static inline void ufshcd_rpmb_add(struct ufs_hba *hba)
 {
struct rpmb_dev *rdev;
+   u8 rw_size;
+   int ret;
+
+   ret = ufshcd_read_geometry_desc_param(hba, GEOMETRY_DESC_RPMB_RW_SIZE,
+   &rw_size, sizeof(rw_size));
+   if (ret) {
+   dev_warn(hba->dev, "%s: cannot get rpmb rw limit %d\n",
+dev_name(hba->dev), ret);
+   /* fallback to singel frame write */
+   rw_size = 1;
+   }
+
+   ufshcd_rpmb_dev_ops.reliable_wr_cnt = rw_size;
 
scsi_device_get(hba->sdev_ufs_rpmb);
rdev = rpmb_dev_register(hba->dev, &ufshcd_rpmb_dev_ops);
-- 
2.7.4

--
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 v7 08/11] mmc: block: register RPMB partition with the RPMB subsystem

2016-11-07 Thread Tomas Winkler
Register eMMC RPMB partition with the RPMB subsystem and provide
implementation for the RPMB access operations abstracting
actual multi step process.

V2: resend
V3: commit message fix
V4: Kconfig: use select RPMB to ensure valid configuration
Switch back to main area after RPMB access
V5: Revamp code using new sequence command
Support for 8K packets in e.MMC v5.1
V6: Resend.
V7: Resend.

Signed-off-by: Tomas Winkler 
Signed-off-by: Alexander Usyskin 
---
 drivers/mmc/card/Kconfig |   1 +
 drivers/mmc/card/block.c | 258 ++-
 2 files changed, 256 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/card/Kconfig b/drivers/mmc/card/Kconfig
index 5562308699bc..537d0bc82781 100644
--- a/drivers/mmc/card/Kconfig
+++ b/drivers/mmc/card/Kconfig
@@ -7,6 +7,7 @@ comment "MMC/SD/SDIO Card Drivers"
 config MMC_BLOCK
tristate "MMC block device driver"
depends on BLOCK
+   select RPMB
default y
help
  Say Y here to enable the MMC block device driver support.
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 709a872ed484..523b2d6afc1c 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -42,6 +42,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -112,6 +113,7 @@ struct mmc_blk_data {
 #define MMC_BLK_WRITE  BIT(1)
 #define MMC_BLK_DISCARDBIT(2)
 #define MMC_BLK_SECDISCARD BIT(3)
+#define MMC_BLK_RPMB   BIT(4)
 
/*
 * Only set in main mmc_blk_data associated
@@ -400,8 +402,8 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd 
__user *ic_ptr,
return 0;
 }
 
-static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status,
-  u32 retries_max)
+static int mmc_blk_rpmb_status_poll(struct mmc_card *card, u32 *status,
+   u32 retries_max)
 {
int err;
u32 retry_count = 0;
@@ -574,7 +576,7 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, 
struct mmc_blk_data *md,
 * Ensure RPMB command has completed by polling CMD13
 * "Send Status".
 */
-   err = ioctl_rpmb_card_status_poll(card, &status, 5);
+   err = mmc_blk_rpmb_status_poll(card, &status, 5);
if (err)
dev_err(mmc_dev(card->host),
"%s: Card Status=0x%08X, error %d\n",
@@ -1164,6 +1166,252 @@ int mmc_access_rpmb(struct mmc_queue *mq)
return false;
 }
 
+static int mmc_rpmb_send_cmd(struct mmc_card *card,
+unsigned int data_type, bool do_rel_wr,
+void *buf, u16 blks)
+{
+   int err;
+   u32 status;
+   struct mmc_command sbc = {
+   .opcode = MMC_SET_BLOCK_COUNT,
+   .flags  = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC,
+   };
+
+   struct mmc_command cmd = {
+   .flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC,
+   };
+
+   struct mmc_data data = {
+   .blksz = 512,
+   };
+   struct mmc_request mrq = {
+   .sbc= &sbc,
+   .cmd= &cmd,
+   .data   = &data,
+   .stop   = NULL,
+   };
+   struct scatterlist sg;
+
+   /*  set CMD23 */
+   sbc.arg = blks & 0x;
+   if (do_rel_wr)
+   sbc.arg |= MMC_CMD23_ARG_REL_WR;
+
+   /*  set CMD25/18 */
+   cmd.opcode = (data_type == MMC_DATA_WRITE) ?
+   MMC_WRITE_MULTIPLE_BLOCK : MMC_READ_MULTIPLE_BLOCK;
+
+   sg_init_one(&sg, buf, 512 * blks);
+
+   data.blocks = blks;
+   data.sg = &sg;
+   data.sg_len = 1;
+   data.flags  = data_type;
+   mmc_set_data_timeout(&data, card);
+
+   mmc_wait_for_req(card->host, &mrq);
+
+   if (cmd.error) {
+   dev_err(mmc_dev(card->host), "cmd error (%d)\n", cmd.error);
+   return cmd.error;
+   }
+
+   if (data.error) {
+   dev_err(mmc_dev(card->host), "data error (%d)\n", data.error);
+   return data.error;
+   }
+
+   err = mmc_blk_rpmb_status_poll(card, &status, 5);
+   if (err)
+   dev_err(mmc_dev(card->host), "Card Status=0x%08X, error %d\n",
+   status, err);
+   return err;
+}
+
+static int mmc_blk_rpmb_sequence(struct mmc_card *card,
+struct rpmb_cmd *cmds, u32 ncmds)
+{
+   int err, i;
+   struct rpmb_cmd *cmd;
+   unsigned int data_type;
+   bool do_rel_wr;
+
+   for (err = 0, i = 0; i < ncmds && !err; i++) {
+   cmd = &cmds[i];
+   if (cmd->flags & RPMB_F_WRITE) {
+   data_type = MMC_DATA_WRITE;
+   do_rel_wr = !!(cmd->flags & RPMB_F_REL_WRITE);
+   } else {
+   data_type = MMC_DATA_REA

[PATCH v7 07/11] tools rpmb: add RPBM access tool

2016-11-07 Thread Tomas Winkler
Add simple RPMB host testing tool. It can be used
to program key, write and read data block, and retrieve
write counter.

V2: resend
V3: fix missing objtool
V4: add verbose option
V5: 1. Adjust to the new API.
2. Exercise both request and sequence ioctls.
V6: 1. Add includes to openssl/rand.h and endian.h
2. Fix some signed, unsigned comparisons
3. Check results more thoroughly
4. use HOSTCFLAGS in compilation
5. Allocate frames dynamically.
V7: 1. Fix rpmb_alloc_frames, it has always allocated one frame instead of
requested number.
2. Use an inline function instead of macro for rw blocking wrapper

Signed-off-by: Tomas Winkler 
---
 MAINTAINERS   |1 +
 tools/Makefile|   14 +-
 tools/rpmb/.gitignore |2 +
 tools/rpmb/Makefile   |   34 ++
 tools/rpmb/rpmb.c | 1035 +
 5 files changed, 1081 insertions(+), 5 deletions(-)
 create mode 100644 tools/rpmb/.gitignore
 create mode 100644 tools/rpmb/Makefile
 create mode 100644 tools/rpmb/rpmb.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 090b6d2d31fb..d9bca5134c7f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -10292,6 +10292,7 @@ F:  drivers/char/rpmb/*
 F: include/uapi/linux/rpmb.h
 F: include/linux/rpmb.h
 F: Documentation/ABI/testing/sysfs-class-rpmb
+F: tools/rpmb/
 
 RTL2830 MEDIA DRIVER
 M: Antti Palosaari 
diff --git a/tools/Makefile b/tools/Makefile
index daa8fb3e4363..1d481b78063f 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -20,6 +20,7 @@ help:
@echo '  lguest - a minimal 32-bit x86 hypervisor'
@echo '  net- misc networking tools'
@echo '  perf   - Linux performance measurement and 
analysis tool'
+   @echo '  rpmb   - Replay protected memory block access 
tool'
@echo '  selftests  - various kernel selftests'
@echo '  spi- spi tools'
@echo '  objtool- an ELF object analysis tool'
@@ -56,7 +57,7 @@ acpi: FORCE
 cpupower: FORCE
$(call descend,power/$@)
 
-cgroup firewire hv guest spi usb virtio vm net iio gpio objtool: FORCE
+cgroup firewire hv guest rpmb spi usb virtio vm net iio gpio objtool: FORCE
$(call descend,$@)
 
 liblockdep: FORCE
@@ -86,7 +87,7 @@ freefall: FORCE
$(call descend,laptop/$@)
 
 all: acpi cgroup cpupower gpio hv firewire lguest \
-   perf selftests turbostat usb \
+   perf rpmb selftests turbostat usb \
virtio vm net x86_energy_perf_policy \
tmon freefall objtool
 
@@ -96,7 +97,7 @@ acpi_install:
 cpupower_install:
$(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install lguest_install 
perf_install usb_install virtio_install vm_install net_install objtool_install:
+cgroup_install firewire_install gpio_install hv_install lguest_install 
perf_install rpmb_install usb_install virtio_install vm_install net_install 
objtool_install:
$(call descend,$(@:_install=),install)
 
 selftests_install:
@@ -116,7 +117,7 @@ kvm_stat_install:
 
 install: acpi_install cgroup_install cpupower_install gpio_install \
hv_install firewire_install lguest_install \
-   perf_install selftests_install turbostat_install usb_install \
+   perf_install rpmb_install selftests_install turbostat_install 
usb_install \
virtio_install vm_install net_install 
x86_energy_perf_policy_install \
tmon_install freefall_install objtool_install kvm_stat_install
 
@@ -145,6 +146,9 @@ perf_clean:
$(Q)mkdir -p $(PERF_O) .
$(Q)$(MAKE) --no-print-directory -C perf O=$(PERF_O) subdir= clean
 
+rpmb_clean:
+   $(call descend,$(@:_clean=),clean)
+
 selftests_clean:
$(call descend,testing/$(@:_clean=),clean)
 
@@ -161,7 +165,7 @@ build_clean:
$(call descend,build,clean)
 
 clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean 
lguest_clean \
-   perf_clean selftests_clean turbostat_clean spi_clean usb_clean 
virtio_clean \
+   perf_clean rpmb_clean selftests_clean turbostat_clean spi_clean 
usb_clean virtio_clean \
vm_clean net_clean iio_clean x86_energy_perf_policy_clean 
tmon_clean \
freefall_clean build_clean libbpf_clean libsubcmd_clean 
liblockdep_clean \
gpio_clean objtool_clean
diff --git a/tools/rpmb/.gitignore b/tools/rpmb/.gitignore
new file mode 100644
index ..218f680548e6
--- /dev/null
+++ b/tools/rpmb/.gitignore
@@ -0,0 +1,2 @@
+*.o
+rpmb
diff --git a/tools/rpmb/Makefile b/tools/rpmb/Makefile
new file mode 100644
index ..debb5a6bc208
--- /dev/null
+++ b/tools/rpmb/Makefile
@@ -0,0 +1,34 @@
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+PKG_CONFIG = $(CROSS_COMPILE)pkg-config
+
+ifeq ($(srctree),)
+srctree := $(patsu

Re: [PATCH 1/1] iscsi: fix regression caused by session lock patch

2016-11-07 Thread Guilherme G. Piccoli
On 11/07/2016 04:15 PM, Chris Leech wrote:
> Hi,
> 
> I'm kicking this old thread because I don't think this ever got
> resolved.  I wish I had more info, but it seems to involve target
> specific behavior that hasn't come up in our test labs.

Thanks very much for reopening this thread! We have the Or's patch
reverted in multiple distros, so the issue is not likely to happen on
customer's from IBM, but upstream kernel never saw a proper fix for this.


> 
> So what can I do at this point to help resolve this?
> 
> On Sun, Nov 15, 2015 at 12:10:48PM +0200, Or Gerlitz wrote:
>> Mike, Chris
>>
>> After the locking change, adding a task to any of the connection
>> mgmtqueue, cmdqueue, or requeue lists is under the session forward lock.
>>
>> Removing tasks from any of these lists in iscsi_data_xmit is under
>> the session forward lock and **before** calling down to the transport
>> to handle the task.
>>
>> The iscsi_complete_task helper was added by Mike's commit
>> 3bbaaad95fd38ded "[SCSI] libiscsi: handle cleanup task races"
>> and is indeed typically called under the backward lock && has this section
>>
>> +   if (!list_empty(&task->running))
>> +   list_del_init(&task->running);
>>
>> which per my reading of the code never comes into play, can you comment?
>>
>> Lets address this area before we move to the others claims made on the patch.
> 
> This bit in particular is where I see a cause for concern.  If that
> list_del_init call ever races against other list operations, there's a
> potential corruption.  It's presumably there for a reason, and Mike
> explained a case where some targets have been known to send a check
> condition at unexpected times that would hit it.
> 
> I don't like having known list locking violations hanging around, based
> on an expectation that we'll never hit that path with well behaved
> targets.
> 
> If we can get a fix worked up for the list locking here, can we get any
> testing on it from the original reports at IBM?  That was very helpful
> in testing a full reversion patch.

Sure! Count on us to test any patches. I guess the first step is to
reproduce on upstream right? We haven't tested specifically this
scenario for long time. Will try to reproduce on 4.9-rc4 and update here.

Cheers,



Guilherme


> 
> - Chris Leech
> 

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


iscsi: make mutex for target scanning and unbinding per-session

2016-11-07 Thread Chris Leech
Currently the iSCSI transport class synchronises target scanning and
unbinding with a host level mutex.  For multi-session hosts (offloading
iSCSI HBAs) connecting to storage arrays that may implement one
target-per-lun, this can result in the target scan work for hundreds of
sessions being serialized behind a single mutex.  With slow enough
response times, this can cause scan requests initiated from userspace to
block on the mutex long enough to trigger 120 sec hung task warnings.

I can't see any reason not to move this to a session level mutex and let
the target scans run in parallel, speeding up connecting to a large
number of targets.  Note that as iscsi_tcp creates a virtual host for
each session, software iSCSI is effectively doing this already.

Signed-off-by: Chris Leech 
---
 drivers/scsi/scsi_transport_iscsi.c | 19 ++-
 include/scsi/scsi_transport_iscsi.h |  2 +-
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index 42bca61..83c90fa 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1568,7 +1568,6 @@ static int iscsi_setup_host(struct transport_container 
*tc, struct device *dev,
 
memset(ihost, 0, sizeof(*ihost));
atomic_set(&ihost->nr_scans, 0);
-   mutex_init(&ihost->mutex);
 
iscsi_bsg_host_add(shost, ihost);
/* ignore any bsg add error - we just can't do sgio */
@@ -1789,8 +1788,6 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
 {
struct iscsi_scan_data *scan_data = data;
struct iscsi_cls_session *session;
-   struct Scsi_Host *shost;
-   struct iscsi_cls_host *ihost;
unsigned long flags;
unsigned int id;
 
@@ -1801,10 +1798,7 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
 
ISCSI_DBG_TRANS_SESSION(session, "Scanning session\n");
 
-   shost = iscsi_session_to_shost(session);
-   ihost = shost->shost_data;
-
-   mutex_lock(&ihost->mutex);
+   mutex_lock(&session->mutex);
spin_lock_irqsave(&session->lock, flags);
if (session->state != ISCSI_SESSION_LOGGED_IN) {
spin_unlock_irqrestore(&session->lock, flags);
@@ -1823,7 +1817,7 @@ static int iscsi_user_scan_session(struct device *dev, 
void *data)
}
 
 user_scan_exit:
-   mutex_unlock(&ihost->mutex);
+   mutex_unlock(&session->mutex);
ISCSI_DBG_TRANS_SESSION(session, "Completed session scan\n");
return 0;
 }
@@ -2001,26 +1995,24 @@ static void __iscsi_unbind_session(struct work_struct 
*work)
struct iscsi_cls_session *session =
container_of(work, struct iscsi_cls_session,
 unbind_work);
-   struct Scsi_Host *shost = iscsi_session_to_shost(session);
-   struct iscsi_cls_host *ihost = shost->shost_data;
unsigned long flags;
unsigned int target_id;
 
ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n");
 
/* Prevent new scans and make sure scanning is not in progress */
-   mutex_lock(&ihost->mutex);
+   mutex_lock(&session->mutex);
spin_lock_irqsave(&session->lock, flags);
if (session->target_id == ISCSI_MAX_TARGET) {
spin_unlock_irqrestore(&session->lock, flags);
-   mutex_unlock(&ihost->mutex);
+   mutex_unlock(&session->mutex);
return;
}
 
target_id = session->target_id;
session->target_id = ISCSI_MAX_TARGET;
spin_unlock_irqrestore(&session->lock, flags);
-   mutex_unlock(&ihost->mutex);
+   mutex_unlock(&session->mutex);
 
if (session->ida_used)
ida_simple_remove(&iscsi_sess_ida, target_id);
@@ -2053,6 +2045,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct 
iscsi_transport *transport,
INIT_WORK(&session->unbind_work, __iscsi_unbind_session);
INIT_WORK(&session->scan_work, iscsi_scan_session);
spin_lock_init(&session->lock);
+   mutex_init(&session->mutex);
 
/* this is released in the dev's release function */
scsi_host_get(shost);
diff --git a/include/scsi/scsi_transport_iscsi.h 
b/include/scsi/scsi_transport_iscsi.h
index 6183d20..acf9d9d 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -238,6 +238,7 @@ struct iscsi_cls_session {
struct work_struct unblock_work;
struct work_struct scan_work;
struct work_struct unbind_work;
+   struct mutex mutex;
 
/* recovery fields */
int recovery_tmo;
@@ -272,7 +273,6 @@ struct iscsi_cls_session {
 
 struct iscsi_cls_host {
atomic_t nr_scans;
-   struct mutex mutex;
struct request_queue *bsg_q;
uint32_t port_speed;
uint32_t port_state;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
th

Re: [PATCH 1/1] iscsi: fix regression caused by session lock patch

2016-11-07 Thread Chris Leech
Hi,

I'm kicking this old thread because I don't think this ever got
resolved.  I wish I had more info, but it seems to involve target
specific behavior that hasn't come up in our test labs.

So what can I do at this point to help resolve this?

On Sun, Nov 15, 2015 at 12:10:48PM +0200, Or Gerlitz wrote:
> Mike, Chris
> 
> After the locking change, adding a task to any of the connection
> mgmtqueue, cmdqueue, or requeue lists is under the session forward lock.
> 
> Removing tasks from any of these lists in iscsi_data_xmit is under
> the session forward lock and **before** calling down to the transport
> to handle the task.
> 
> The iscsi_complete_task helper was added by Mike's commit
> 3bbaaad95fd38ded "[SCSI] libiscsi: handle cleanup task races"
> and is indeed typically called under the backward lock && has this section
> 
> +   if (!list_empty(&task->running))
> +   list_del_init(&task->running);
> 
> which per my reading of the code never comes into play, can you comment?
> 
> Lets address this area before we move to the others claims made on the patch.

This bit in particular is where I see a cause for concern.  If that
list_del_init call ever races against other list operations, there's a
potential corruption.  It's presumably there for a reason, and Mike
explained a case where some targets have been known to send a check
condition at unexpected times that would hit it.

I don't like having known list locking violations hanging around, based
on an expectation that we'll never hit that path with well behaved
targets.

If we can get a fix worked up for the list locking here, can we get any
testing on it from the original reports at IBM?  That was very helpful
in testing a full reversion patch.

- Chris Leech

--
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: CISS driver error introduced with kernel-4.9.0-0.rc2.git1.1.fc26

2016-11-07 Thread Laura Abbott

On 11/07/2016 04:44 AM, Johnny Bieren wrote:

Hello,

It appears that a check_unmap kernel failure for the CISS driver was introduced 
with kernel-4.9.0-0.rc2.git1.1.fc26.  When booting this kernel, or any newer 
kernel, I see the following:

 [3.676658] HP CISS Driver (v 3.6.26)
0m] Reached target System Initialization.
 Starting dracut initqueue hook...
 Starting Show Plymouth Boot Screen...
[3.756592] scsi host0: pata_amd
[3.772866] scsi host1: pata_amd
[3.782052] ata1: PATA max UDMA/133 cmd 0x1f0 ctl 0x3f6 bmdma 0x2000 irq 14
[3.789616] ata2: PATA max UDMA/133 cmd 0x170 ctl 0x376 bmdma 0x2008 irq 15
[3.825789] cciss :02:04.0: cciss0: <0x46> at PCI :02:04.0 IRQ 24 
using DAC
[3.836530] audit: type=1130 audit(1478270493.962:10): pid=1 uid=0 auid=4294967295 
ses=4294967295 subj=kernel msg='unit=plymouth-start comm="systemd" 
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[
  OK
] Started Show[3.839544] [ cut here ]
 Plymouth Boot S[3.839555] WARNING: CPU: 0 PID: 193 at lib/dma-debug.c:1164 
check_unmap+0x4af/0x940
creen.
[3.839559] cciss :02:04.0: DMA-API: device driver failed to check map 
error[device address=0x38f521c0] [size=36 bytes] [mapped as single]
[3.839563] Modules linked in: serio_raw cciss(+) pata_amd
[3.839566] CPU: 0 PID: 193 Comm: kworker/0:2 Not tainted 
4.9.0-0.rc2.git1.1.fc26.x86_64 #1
[3.839567] Hardware name: HP ProLiant DL385 G1, BIOS A05 03/01/2006
[3.839573] Workqueue: events work_for_cpu_fn
[3.839577]  9e9ec05938f8 8546cd23 9e9ec0593948 

[3.839579]  9e9ec0593938 850af4cb 048c0082 
8aa07ca0ea60
[3.839582]  87483a00 8aa07b878180 0282 
85c5ad66
[3.839582] Call Trace:
[3.839588]  [] dump_stack+0x86/0xc3
[3.839591]  [] __warn+0xcb/0xf0
[3.839593]  [] warn_slowpath_fmt+0x5f/0x80
[3.839595]  [] check_unmap+0x4af/0x940
[3.839597]  [] debug_dma_unmap_page+0x79/0xa0
[3.839613]  [] sendcmd_withirq_core+0x217/0x260 [cciss]
[3.839618]  [] ? wait_for_completion+0x110/0x140
[3.839623]  [] sendcmd_withirq+0x98/0xb0 [cciss]
[3.839628]  [] cciss_init_one+0x1a8f/0x1f70 [cciss]
[3.839632]  [] local_pci_probe+0x45/0xa0
[3.839634]  [] work_for_cpu_fn+0x14/0x20
[3.839637]  [] process_one_work+0x23e/0x6f0
[3.839638]  [] ? process_one_work+0x1ba/0x6f0
[3.839641]  [] worker_thread+0x1d3/0x490
[3.839642]  [] ? process_one_work+0x6f0/0x6f0
[3.839644]  [] ? process_one_work+0x6f0/0x6f0
[3.839648]  [] kthread+0x102/0x120
[3.839652]  [] ? trace_hardirqs_on_caller+0xf5/0x1b0
[3.839655]  [] ? kthread_park+0x60/0x60
[3.839658]  [] ret_from_fork+0x2a/0x40
[3.839659] ---[ end trace 1ec289ff52b16fd7 ]---
[3.839660] Mapped at:
[3.839663]
[3.839663] [] debug_dma_map_page+0x8c/0x160
[3.839668]
[3.839668] [] fill_cmd+0x1bf/0x420 [cciss]
[3.839672]
[3.839672] [] sendcmd_withirq+0x64/0xb0 [cciss]
[3.839676]
[3.839676] [] cciss_init_one+0x1a8f/0x1f70 [cciss]
[3.839679]
[3.839679] [] local_pci_probe+0x45/0xa0
[3.859535] scsi host2: cciss

This problem does not appear when booting with kernel-4.9.0-0.rc2.git0.1.fc26.  
It reproduces 100% of the time, simply try to boot 
kernel-4.9.0-0.rc2.git1.1.fc26 on a host with a CISS disk.

Thank you,
Johnny


For reference, the corresponding upstream commits for the Fedora tags are
6edc51a8d43b0bb8263fefaa8eb0cf62e8499978 and
9fe68cad6e74967b88d0c6aeca7d9cd6b6e91942 although I think those two tags
may be a misdirection because  kernel-4.9.0-0.rc2.git0.1.fc26 had
DMA_API_DEBUG turned off.

Thanks,
Laura
--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Sebastian Andrzej Siewior
On 2016-11-07 17:48:46 [+0100], Christoph Hellwig wrote:
> On Mon, Nov 07, 2016 at 05:46:29PM +0100, Sebastian Andrzej Siewior wrote:
> > sorry for the confusion in the subject. If I remember correctly you said
> > that we may not have enough room for a larger / work_struct struct and I
> > should keep the list for now.
> 
> But that was for libfc where it only has a tiny bit of private data
> i nthe skb - this is for cnix which has plenty of space, and in fact

Right. now I remember.

> probably should do the workqueue offload in the core before invoking
> the protocol drivers.

So we keep things as they are right now or are we getting also rid of
the internal list? This was tested by Johannes and Chad (claimed to do
testing) and the removal the internal list afterwards shouldn't be that
big deal. Not sure what the last point is about.

Sebastian
--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Christoph Hellwig
On Mon, Nov 07, 2016 at 05:46:29PM +0100, Sebastian Andrzej Siewior wrote:
> sorry for the confusion in the subject. If I remember correctly you said
> that we may not have enough room for a larger / work_struct struct and I
> should keep the list for now.

But that was for libfc where it only has a tiny bit of private data
i nthe skb - this is for cnix which has plenty of space, and in fact
probably should do the workqueue offload in the core before invoking
the protocol drivers.
--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Sebastian Andrzej Siewior
On 2016-11-07 17:38:48 [+0100], Christoph Hellwig wrote:
> You're right it does - between the incorrect subject and the fact
> that it still keeps the linked list of items arounds instead of fully
> using the workqueue infrastructure I was a bit confused before my
> first coffee this morning.  Same applies to patch 2.

sorry for the confusion in the subject. If I remember correctly you said
that we may not have enough room for a larger / work_struct struct and I
should keep the list for now.

Sebastian
--
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/4] qla2xxx: Add Block Multi Queue functionality.

2016-11-07 Thread Ewan D. Milne
On Fri, 2016-11-04 at 09:33 -0700, himanshu.madh...@cavium.com wrote:
> From: Michael Hernandez 
> 
> Tell the SCSI layer how many hardware queues we have based on the
> number of max queue pairs created. The number of max queue pairs
> created will depend on number of MSI X vector count or number of CPU's
> in a system.
> 
> This feature can be turned on via CONFIG_SCSI_MQ_DEFAULT or passing
> scsi_mod.use_blk_mq=Y as a parameter to the kernel
> Queue pair creation depend on module parameter "ql2xmqsupport", which
> need to be enabled to create queue pair.
> 

I don't understand this change at all.  Setting ->nr_hw_queues causes
the block layer to allocate a number of queues for that Scsi_Host
object, but it does not appear as if this code uses that functionality.
There is nothing in the patch that examines the tag to see which queue
the request came in on, in order to map it to a hardware queue.

Instead, this patch seems to be reworking the mechanism involved in
NPIV vport creation, which creates an entirely separate Scsi_Host
object.  The driver was already creating separate request queues to
the card for vports, so what does this have to do with Block-MQ?

-Ewan
 

--
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: fix spelling mistake in error message

2016-11-07 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake "operatio" to "operation"
in critical error message

Signed-off-by: Colin Ian King 
---
 drivers/scsi/dpt_i2o.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 21c8d21..d84004b 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -3350,7 +3350,7 @@ static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
if (opblk_va == NULL) {
dma_free_coherent(&pHba->pDev->dev, sizeof(u8) * (8+buflen),
resblk_va, resblk_pa);
-   printk(KERN_CRIT "%s: query operatio failed; Out of memory.\n",
+   printk(KERN_CRIT "%s: query operation failed; Out of memory.\n",
pHba->name);
return -ENOMEM;
}
-- 
2.9.3

--
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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Christoph Hellwig
On Mon, Nov 07, 2016 at 05:31:03PM +0100, Thomas Gleixner wrote:
> On Mon, 7 Nov 2016, Christoph Hellwig wrote:
> 
> > It seems like the whole damn driver should just use threaded interrupts.
> > Of course it's a giant beast and not just the iSCSI one.  But even
> > if we don't go all the way I'd much prefer workqueues.  kthread work
> > is simply the worst API ever and I'd prefer to not have it proliferate.
> 
> That's what the patch is doing. It uses INIT_WORK() and
> schedule_work[_on](). I can't find any reference to kthread work.

You're right it does - between the incorrect subject and the fact
that it still keeps the linked list of items arounds instead of fully
using the workqueue infrastructure I was a bit confused before my
first coffee this morning.  Same applies to patch 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: [PREEMPT-RT] [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Thomas Gleixner
On Mon, 7 Nov 2016, Christoph Hellwig wrote:

> It seems like the whole damn driver should just use threaded interrupts.
> Of course it's a giant beast and not just the iSCSI one.  But even
> if we don't go all the way I'd much prefer workqueues.  kthread work
> is simply the worst API ever and I'd prefer to not have it proliferate.

That's what the patch is doing. It uses INIT_WORK() and
schedule_work[_on](). I can't find any reference to kthread work.

Thanks,

tglx
--
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] target: fix spelling mistake and unwrap multi-line text

2016-11-07 Thread Colin King
From: Colin Ian King 

Trivial fix to spelling mistake "Obselete" to "Obsolete"
in error message and also turn multi-line text into one
line.

Signed-off-by: Colin Ian King 
---
 drivers/target/target_core_pr.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 47463c9..0cd38af 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -253,8 +253,7 @@ target_scsi2_reservation_reserve(struct se_cmd *cmd)
 
if ((cmd->t_task_cdb[1] & 0x01) &&
(cmd->t_task_cdb[1] & 0x02)) {
-   pr_err("LongIO and Obselete Bits set, returning"
-   " ILLEGAL_REQUEST\n");
+   pr_err("LongIO and Obsolete Bits set, returning 
ILLEGAL_REQUEST\n");
return TCM_UNSUPPORTED_SCSI_OPCODE;
}
/*
-- 
2.9.3

--
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: [REPOST PATCH 1/5] scsi: bnx2i: convert to kworker

2016-11-07 Thread Christoph Hellwig
It seems like the whole damn driver should just use threaded interrupts.
Of course it's a giant beast and not just the iSCSI one.  But even
if we don't go all the way I'd much prefer workqueues.  kthread work
is simply the worst API ever and I'd prefer to not have it proliferate.
--
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


[Bug 187231] kernel panic during hpsa MSI plus tg3 MSI

2016-11-07 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=187231

--- Comment #3 from Don  ---

(In reply to Patrick Schaaf from comment #2)
> Thanks Don for the reaction!
> 
> Right now, on the box that had that panic and the worst resetting/reset
> issues (see the other bug I linked), I'm back to 3.14.79, and want to stay
> there for another 24 to 36 hours, to see that this issue was not present
> with that kernel series.
> 
> What would your patch help with? Specifically the panic potential in case a
> logical device reset is ongoing? Or should it affect / remedy the mysterious
> (to me) "resetting logical" events in the first place?
> 
> I'm willing to test patches on that box starting Thursday, but I'd like to
> understand a bit better what we are dealing with here.

The specific issue that this patch addresses is that during a reset,
complete_scsi_command returns without having called scsi_done which causes the
OS to offline the disk (after two more occurrences). But this code path is not
often followed so the issue does not happen with all resets.

There are some other recent patches that should also be tested that have been
recently applied.

>From git format-patch:
0457-scsi-hpsa-Check-for-null-device-pointers.patch
* This checks for a NULL device that can happen if the OS
  off-lines the disk because of the afore mentioned reset issue.
0460-scsi-hpsa-Check-for-null-devices-in-ioaccel-submissi.patch
0462-scsi-hpsa-correct-call-to-hpsa_do_reset.patch
* Fine tunes resets into LOGICAL/Physical resets.

A patch I still have pending on linux-scsi
0464-hpsa-add-generate-controller-NMI-on-lockup.patch
* This patch just adds more granularity on lock-up detection.

It would be nice to know why the reset is happening in the first place.

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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 2/4] qla2xxx: Fix mailbox command timeout due to starvation

2016-11-07 Thread Ewan D. Milne
On Fri, 2016-11-04 at 09:33 -0700, himanshu.madh...@cavium.com wrote:
...
> @@ -2349,6 +2349,17 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
>   return atomic_read(&vha->loop_state) == LOOP_READY;
>  }
>  
> +static void qla2x00_destroy_mbx_wq(struct qla_hw_data *ha)
> +{
> + struct workqueue_struct *wq = ha->mbx_wq;
> +
> + if (wq) {
> + ha->mbx_wq = NULL;
> + flush_workqueue(wq);
> + destroy_workqueue(wq);
> + }
> +}
> +
>  /*
>   * PCI driver interface
>   */

There is already a function qla2x00_destroy_deferred_work() that
destroys 3 other workqueues.

...

> @@ -3059,6 +3079,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
>  
>   qla2x00_free_fw_dump(ha);
>  
> + qla2x00_destroy_mbx_wq(ha);
> +
>   pci_disable_pcie_error_reporting(pdev);
>   pci_disable_device(pdev);
>  }

This code path (pci_driver->shutdown) does not appear to destroy the
other workqueues created by the driver. ???

> @@ -5011,6 +5033,8 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
>*/
>   qla2x00_free_sysfs_attr(base_vha, false);
>  
> + qla2x00_destroy_mbx_wq(ha);
> +
>   fc_remove_host(base_vha->host);
>  
>   scsi_remove_host(base_vha->host);

See above.

-Ewan


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


[Bug 187231] kernel panic during hpsa MSI plus tg3 MSI

2016-11-07 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=187231

--- Comment #2 from Patrick Schaaf  ---
Thanks Don for the reaction!

Right now, on the box that had that panic and the worst resetting/reset issues
(see the other bug I linked), I'm back to 3.14.79, and want to stay there for
another 24 to 36 hours, to see that this issue was not present with that kernel
series.

What would your patch help with? Specifically the panic potential in case a
logical device reset is ongoing? Or should it affect / remedy the mysterious
(to me) "resetting logical" events in the first place?

I'm willing to test patches on that box starting Thursday, but I'd like to
understand a bit better what we are dealing with here.

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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


[Bug 187231] kernel panic during hpsa MSI plus tg3 MSI

2016-11-07 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=187231

Don  changed:

   What|Removed |Added

 CC||don.br...@microsemi.com

--- Comment #1 from Don  ---
Created attachment 243811
  --> https://bugzilla.kernel.org/attachment.cgi?id=243811&action=edit
Patch to correct resets

I will be uploading this patch to linux-scsi this week.

I am attaching the patch in case you would like to test this patch now.

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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


[Bug 187231] New: kernel panic during hpsa MSI plus tg3 MSI

2016-11-07 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=187231

Bug ID: 187231
   Summary: kernel panic during hpsa MSI plus tg3 MSI
   Product: IO/Storage
   Version: 2.5
Kernel Version: 4.8.6
  Hardware: All
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: SCSI
  Assignee: linux-scsi@vger.kernel.org
  Reporter: kernel...@bof.de
Regression: No

Created attachment 243801
  --> https://bugzilla.kernel.org/attachment.cgi?id=243801&action=edit
kernel 4.8.6 .config

I'm not sure whether this is a SCSI / HPSA bug or a networking / tg3 driver
bug. Both are seen in the stack dump. As the trigger seems to be HPSA I'm
reporting as a SCSI issue here...

I've been recently attempting to run mainline 4.8.x kernels, most recently
4.8.6, on our production HP DL 380 Intel servers.

On several of them there is some related issue reported in
https://bugzilla.kernel.org/show_bug.cgi?id=187221 where the HPSA driver on
some of the hosts sometimes resets the logical device. I had seen that already
with 4.4.x kernels, and again with 4.8.6.

Now, specifically with 4.8.6, on the box which has the worst of these symptoms,
I _additionally_ experienced multiple full kernel panics. The same box (with
the same hpsa reset symtoms) had been running 4.4.x kernels before without such
kernel panics. The panics then happened multiple times with about a day in
between.

On the last round I had the ILO SSH console running under screen with logging
enabled, and was able to retrieve the following panic backtrace:

[187283.903173] hpsa :03:00.0: scsi 0:1:0:0: resetting logical 
Direct-Access HP   LOGICAL VOLUME   RAID-5 SSDSmartPathCap- En- Exp=1   
[187314.331375] sd 0:1:0:0: rejecting I/O to offline device 
[187314.413441] sd 0:1:0:0: rejecting I/O to offline device 
[187314.854183] sd 0:1:0:0: rejecting I/O to offline device 
... lots of these ...
[187328.991285] sd 0:1:0:0: rejecting I/O to offline device 
[187328.991389] sd 0:1:0:0: rejecting I/O to offline device 
[187329.190166] sd 0:1:0:0: rejecting I/O to offline device 
[187329.271304]  88bd1a7e8000 88bd1a7be500 88bd7f483eb8
8143
493f
[187329.271304] Call Trace: 
[187329.271310]
[187329.271310]  [] ? tg3_poll_msix+0xc2/0x160 [tg3]  
[187329.271311]  [] do_hpsa_intr_msi+0x8f/0x1c0   
[187329.271314]  [] __handle_irq_event_percpu+0x66/0xe0   
[187329.271315]  [] handle_irq_event_percpu+0x1e/0x50 
[187329.271316]  [] handle_irq_event+0x27/0x50
[187329.271318]  [] handle_edge_irq+0x65/0x140
[187329.271320]  [] handle_irq+0x15/0x20  
[187329.271321]  [] do_IRQ+0x46/0xd0  
[187329.271324]  [] common_interrupt+0x7c/0x7c
[187329.271325]
[187329.271338] Code: 53 48 89 fb 48 83 ec 28 4c 8b a7 5c 02 00 00 4c 8b bf 40
0
2 00 00 4c 8b b7 38 02 00 00 4c 8b af 4c 02 00 00 49 8b 04 24 4c 89 e7 <48> 8b
8
0 98 00 00 00 48 89 45 c0 49 8b 87 d0 01 00 00 48 89 45 
[187329.271339] RIP  [] complete_scsi_command+0x37/0x8c0  
[187329.271339]  RSP  
[187329.271339] CR2: 0098   
[187329.271341] ---[ end trace 52898916f0da5c53 ]---
[187329.273413] Kernel panic - not syncing: Fatal exception in interrupt
[187330.308465] Shutting down cpus with NMI 
[187330.308471] Kernel Offset: disabled 
[187330.919173] Rebooting in 300 seconds..  

I'll attach my kernel .config.

As this is a production system and so far the panics only hit with our usual
(webserver and DB kvm machine) production load active, there's not much testing
or bisecting I can do, but I didn't want to drop the issue unreported, either. 

Hope this helps somebody. If there is any more info I can provide, just ask
what would be useful.

(I'm back to running 4.4.x)

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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


[Bug 187221] New: HPSA resetting logical / reset logical

2016-11-07 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=187221

Bug ID: 187221
   Summary: HPSA resetting logical / reset logical
   Product: IO/Storage
   Version: 2.5
Kernel Version: 4.4.x, 4.8.x
  Hardware: Intel
OS: Linux
  Tree: Mainline
Status: NEW
  Severity: normal
  Priority: P1
 Component: SCSI
  Assignee: linux-scsi@vger.kernel.org
  Reporter: kernel...@bof.de
Regression: No

I have about 20 HP DL 380 (some 360) servers, from Gen7 to Gen9, using the HPSA
driver with various smartarray controllers.

For a long time I've been running mainline 3.14 kernels, without any issues.
Some time ago I updated to mainline 4.4.x, up to the most recent 4.4.30.

Now I noticed, especially on one server, but in the logs on 6 of them, the
following kind of message:

2016-11-06T22:09:50.227592+01:00 HOST kernel: [68853.338610] hpsa :03:00.0:
scsi 0:1:0:0: resetting logical  Direct-Access HP   LOGICAL VOLUME  
RAID-5 SSDSmartPathCap- En- Exp=1
2016-11-06T22:10:18.713759+01:00 HOST kernel: [68881.832436] hpsa :03:00.0:
scsi 0:1:0:0: reset logical  completed successfully Direct-Access HP  
LOGICAL VOLUME   RAID-5 SSDSmartPathCap- En- Exp=1

I see such messages, _usually_ only with 1 second between resetting/reset, on
machines with the following controller+controller firmware variants:
1 P410i 5.14
1 P420i 5.42
2 P440ar 3.02
1 P440ar 3.56
1 P440ar 4.02

The one machine for which I've shown the concrete message, is a P440ar with
firmware 3.02. There, contrary to the other machines, it sometimes takes up to
20 seconds for that resetting operation, and meanwhile, all I/O stalls.

I also tested with 4.8.x kernels, and saw the same symptoms there. I'm somewhat
sure that I did not see these with 3.14 kernels. This morning I rebooted the
most problematic box to 3.14.79, so far it was silent. I'll report if that
changes.

Apart from these log lines, there is nothing strange to be found - no ILO or
IML notifications visible, no other kernel messages, no drive failures, SMART
alerts, or performance regressions...

-- 
You are receiving this mail because:
You are the assignee for the bug.
--
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


CISS driver error introduced with kernel-4.9.0-0.rc2.git1.1.fc26

2016-11-07 Thread Johnny Bieren

Hello,

It appears that a check_unmap kernel failure for the CISS driver was 
introduced with kernel-4.9.0-0.rc2.git1.1.fc26.  When booting this 
kernel, or any newer kernel, I see the following:


 [3.676658] HP CISS Driver (v 3.6.26)
0m] Reached target System Initialization.
 Starting dracut initqueue hook...
 Starting Show Plymouth Boot Screen...
[3.756592] scsi host0: pata_amd
[3.772866] scsi host1: pata_amd
[3.782052] ata1: PATA max UDMA/133 cmd 0x1f0 ctl 0x3f6 bmdma 0x2000 irq 14
[3.789616] ata2: PATA max UDMA/133 cmd 0x170 ctl 0x376 bmdma 0x2008 irq 15
[3.825789] cciss :02:04.0: cciss0: <0x46> at PCI :02:04.0 IRQ 24 
using DAC
[3.836530] audit: type=1130 audit(1478270493.962:10): pid=1 uid=0 auid=4294967295 
ses=4294967295 subj=kernel msg='unit=plymouth-start comm="systemd" 
exe="/usr/lib/systemd/systemd" hostname=? addr=? terminal=? res=success'
[
  OK
] Started Show[3.839544] [ cut here ]
 Plymouth Boot S[3.839555] WARNING: CPU: 0 PID: 193 at lib/dma-debug.c:1164 
check_unmap+0x4af/0x940
creen.
[3.839559] cciss :02:04.0: DMA-API: device driver failed to check map 
error[device address=0x38f521c0] [size=36 bytes] [mapped as single]
[3.839563] Modules linked in: serio_raw cciss(+) pata_amd
[3.839566] CPU: 0 PID: 193 Comm: kworker/0:2 Not tainted 
4.9.0-0.rc2.git1.1.fc26.x86_64 #1
[3.839567] Hardware name: HP ProLiant DL385 G1, BIOS A05 03/01/2006
[3.839573] Workqueue: events work_for_cpu_fn
[3.839577]  9e9ec05938f8 8546cd23 9e9ec0593948 

[3.839579]  9e9ec0593938 850af4cb 048c0082 
8aa07ca0ea60
[3.839582]  87483a00 8aa07b878180 0282 
85c5ad66
[3.839582] Call Trace:
[3.839588]  [] dump_stack+0x86/0xc3
[3.839591]  [] __warn+0xcb/0xf0
[3.839593]  [] warn_slowpath_fmt+0x5f/0x80
[3.839595]  [] check_unmap+0x4af/0x940
[3.839597]  [] debug_dma_unmap_page+0x79/0xa0
[3.839613]  [] sendcmd_withirq_core+0x217/0x260 [cciss]
[3.839618]  [] ? wait_for_completion+0x110/0x140
[3.839623]  [] sendcmd_withirq+0x98/0xb0 [cciss]
[3.839628]  [] cciss_init_one+0x1a8f/0x1f70 [cciss]
[3.839632]  [] local_pci_probe+0x45/0xa0
[3.839634]  [] work_for_cpu_fn+0x14/0x20
[3.839637]  [] process_one_work+0x23e/0x6f0
[3.839638]  [] ? process_one_work+0x1ba/0x6f0
[3.839641]  [] worker_thread+0x1d3/0x490
[3.839642]  [] ? process_one_work+0x6f0/0x6f0
[3.839644]  [] ? process_one_work+0x6f0/0x6f0
[3.839648]  [] kthread+0x102/0x120
[3.839652]  [] ? trace_hardirqs_on_caller+0xf5/0x1b0
[3.839655]  [] ? kthread_park+0x60/0x60
[3.839658]  [] ret_from_fork+0x2a/0x40
[3.839659] ---[ end trace 1ec289ff52b16fd7 ]---
[3.839660] Mapped at:
[3.839663]
[3.839663] [] debug_dma_map_page+0x8c/0x160
[3.839668]
[3.839668] [] fill_cmd+0x1bf/0x420 [cciss]
[3.839672]
[3.839672] [] sendcmd_withirq+0x64/0xb0 [cciss]
[3.839676]
[3.839676] [] cciss_init_one+0x1a8f/0x1f70 [cciss]
[3.839679]
[3.839679] [] local_pci_probe+0x45/0xa0
[3.859535] scsi host2: cciss

This problem does not appear when booting with 
kernel-4.9.0-0.rc2.git0.1.fc26.  It reproduces 100% of the time, simply 
try to boot kernel-4.9.0-0.rc2.git1.1.fc26 on a host with a CISS disk.


Thank you,
Johnny
--
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 07/11] hisi_sas: delete repeated configuration in free_device_v2_hw()

2016-11-07 Thread John Garry
From: Xiang Chen 

Delete repeated configuration items for hisi_sas_device() when
we free a device. These items are now only set in
hisi_sas_dev_gone().

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 7567193..3081eec 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -739,8 +739,6 @@ static void free_device_v2_hw(struct hisi_hba *hisi_hba,
qw0 &= ~(1 << ITCT_HDR_VALID_OFF);
hisi_sas_write32(hisi_hba, ENT_INT_SRC3,
 ENT_INT_SRC3_ITC_INT_MSK);
-   hisi_hba->devices[dev_id].dev_type = SAS_PHY_UNUSED;
-   hisi_hba->devices[dev_id].dev_status = 
HISI_SAS_DEV_NORMAL;
 
/* clear the itct */
hisi_sas_write32(hisi_hba, ITCT_CLR, 0);
-- 
1.9.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 01/11] hisi_sas: add v2 hw support for ECC and AXI bus fatal error

2016-11-07 Thread John Garry
From: Xiang Chen 

For ECC 1bit error, logic can recover it, so we only print
a warning.
For ECC multi-bit and AXI bus fatal error, we panic.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 425 -
 1 file changed, 420 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 0763b47..9e70e6d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -55,10 +55,44 @@
 #define HGC_DFX_CFG2   0xc0
 #define HGC_IOMB_PROC1_STATUS  0x104
 #define CFG_1US_TIMER_TRSH 0xcc
+#define HGC_LM_DFX_STATUS2 0x128
+#define HGC_LM_DFX_STATUS2_IOSTLIST_OFF0
+#define HGC_LM_DFX_STATUS2_IOSTLIST_MSK(0xfff << \
+HGC_LM_DFX_STATUS2_IOSTLIST_OFF)
+#define HGC_LM_DFX_STATUS2_ITCTLIST_OFF12
+#define HGC_LM_DFX_STATUS2_ITCTLIST_MSK(0x7ff << \
+HGC_LM_DFX_STATUS2_ITCTLIST_OFF)
+#define HGC_CQE_ECC_ADDR   0x13c
+#define HGC_CQE_ECC_1B_ADDR_OFF0
+#define HGC_CQE_ECC_1B_ADDR_MSK(0x3f < HGC_CQE_ECC_1B_ADDR_OFF)
+#define HGC_CQE_ECC_MB_ADDR_OFF8
+#define HGC_CQE_ECC_MB_ADDR_MSK (0x3f < HGC_CQE_ECC_MB_ADDR_OFF)
+#define HGC_IOST_ECC_ADDR  0x140
+#define HGC_IOST_ECC_1B_ADDR_OFF   0
+#define HGC_IOST_ECC_1B_ADDR_MSK   (0x3ff < HGC_IOST_ECC_1B_ADDR_OFF)
+#define HGC_IOST_ECC_MB_ADDR_OFF   16
+#define HGC_IOST_ECC_MB_ADDR_MSK   (0x3ff < HGC_IOST_ECC_MB_ADDR_OFF)
+#define HGC_DQE_ECC_ADDR   0x144
+#define HGC_DQE_ECC_1B_ADDR_OFF0
+#define HGC_DQE_ECC_1B_ADDR_MSK(0xfff < HGC_DQE_ECC_1B_ADDR_OFF)
+#define HGC_DQE_ECC_MB_ADDR_OFF16
+#define HGC_DQE_ECC_MB_ADDR_MSK (0xfff < HGC_DQE_ECC_MB_ADDR_OFF)
 #define HGC_INVLD_DQE_INFO 0x148
 #define HGC_INVLD_DQE_INFO_FB_CH0_OFF  9
 #define HGC_INVLD_DQE_INFO_FB_CH0_MSK  (0x1 << HGC_INVLD_DQE_INFO_FB_CH0_OFF)
 #define HGC_INVLD_DQE_INFO_FB_CH3_OFF  18
+#define HGC_ITCT_ECC_ADDR  0x150
+#define HGC_ITCT_ECC_1B_ADDR_OFF   0
+#define HGC_ITCT_ECC_1B_ADDR_MSK   (0x3ff << \
+HGC_ITCT_ECC_1B_ADDR_OFF)
+#define HGC_ITCT_ECC_MB_ADDR_OFF   16
+#define HGC_ITCT_ECC_MB_ADDR_MSK   (0x3ff << \
+HGC_ITCT_ECC_MB_ADDR_OFF)
+#define HGC_AXI_FIFO_ERR_INFO  0x154
+#define AXI_ERR_INFO_OFF   0
+#define AXI_ERR_INFO_MSK   (0xff << AXI_ERR_INFO_OFF)
+#define FIFO_ERR_INFO_OFF  8
+#define FIFO_ERR_INFO_MSK  (0xff << FIFO_ERR_INFO_OFF)
 #define INT_COAL_EN0x19c
 #define OQ_INT_COAL_TIME   0x1a0
 #define OQ_INT_COAL_CNT0x1a4
@@ -73,13 +107,41 @@
 #define ENT_INT_SRC1_D2H_FIS_CH1_MSK   (0x1 << ENT_INT_SRC1_D2H_FIS_CH1_OFF)
 #define ENT_INT_SRC2   0x1bc
 #define ENT_INT_SRC3   0x1c0
+#define ENT_INT_SRC3_WP_DEPTH_OFF  8
+#define ENT_INT_SRC3_IPTT_SLOT_NOMATCH_OFF 9
+#define ENT_INT_SRC3_RP_DEPTH_OFF  10
+#define ENT_INT_SRC3_AXI_OFF   11
+#define ENT_INT_SRC3_FIFO_OFF  12
+#define ENT_INT_SRC3_LM_OFF14
 #define ENT_INT_SRC3_ITC_INT_OFF   15
 #define ENT_INT_SRC3_ITC_INT_MSK   (0x1 << ENT_INT_SRC3_ITC_INT_OFF)
+#define ENT_INT_SRC3_ABT_OFF   16
 #define ENT_INT_SRC_MSK1   0x1c4
 #define ENT_INT_SRC_MSK2   0x1c8
 #define ENT_INT_SRC_MSK3   0x1cc
 #define ENT_INT_SRC_MSK3_ENT95_MSK_OFF 31
 #define ENT_INT_SRC_MSK3_ENT95_MSK_MSK (0x1 << ENT_INT_SRC_MSK3_ENT95_MSK_OFF)
+#define SAS_ECC_INTR   0x1e8
+#define SAS_ECC_INTR_DQE_ECC_1B_OFF0
+#define SAS_ECC_INTR_DQE_ECC_MB_OFF1
+#define SAS_ECC_INTR_IOST_ECC_1B_OFF   2
+#define SAS_ECC_INTR_IOST_ECC_MB_OFF   3
+#define SAS_ECC_INTR_ITCT_ECC_MB_OFF   4
+#define SAS_ECC_INTR_ITCT_ECC_1B_OFF   5
+#define SAS_ECC_INTR_IOSTLIST_ECC_MB_OFF   6
+#define SAS_ECC_INTR_IOSTLIST_ECC_1B_OFF   7
+#define SAS_ECC_INTR_ITCTLIST_ECC_1B_OFF   8
+#define SAS_ECC_INTR_ITCTLIST_ECC_MB_OFF   9
+#define SAS_ECC_INTR_CQE_ECC_1B_OFF10
+#define SAS_ECC_INTR_CQE_ECC_MB_OFF11
+#define SAS_ECC_INTR_NCQ_MEM0_ECC_MB_OFF   12
+#define SAS_ECC_INTR_NCQ_MEM0_ECC_1B_OFF   13
+#define SAS_ECC_INTR_NCQ_MEM1_ECC_MB_OFF   14
+#define SAS_ECC_INTR_NCQ_MEM1_ECC_1B_OFF   15
+#define SAS_ECC_INTR_NCQ_MEM2_ECC_MB_OFF   16
+#define SAS_ECC_INTR_NCQ_MEM2_ECC_1B_OFF   17
+#define SAS_ECC_INTR_NCQ_MEM3_ECC_MB_OFF   18
+#define SAS_ECC_INTR_NCQ_MEM3_ECC_1B_OFF   19
 #define SAS_ECC_INTR_MSK   0x1ec
 #define HGC_ERR_STAT_EN   

[PATCH 08/11] hisi_sas: modify some values in get_ata_protocol()

2016-11-07 Thread John Garry
From: Xiang Chen 

Modify and add some SATA commands according to SATA protocol.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index 3081eec..a5faa4d 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1750,6 +1750,7 @@ static u8 get_ata_protocol(u8 cmd, int direction)
case ATA_CMD_NCQ_NON_DATA:
return SATA_PROTOCOL_FPDMA;
 
+   case ATA_CMD_DOWNLOAD_MICRO:
case ATA_CMD_ID_ATA:
case ATA_CMD_PMP_READ:
case ATA_CMD_READ_LOG_EXT:
@@ -1761,18 +1762,27 @@ static u8 get_ata_protocol(u8 cmd, int direction)
case ATA_CMD_PIO_WRITE_EXT:
return SATA_PROTOCOL_PIO;
 
+   case ATA_CMD_DSM:
+   case ATA_CMD_DOWNLOAD_MICRO_DMA:
+   case ATA_CMD_PMP_READ_DMA:
+   case ATA_CMD_PMP_WRITE_DMA:
case ATA_CMD_READ:
case ATA_CMD_READ_EXT:
case ATA_CMD_READ_LOG_DMA_EXT:
+   case ATA_CMD_READ_STREAM_DMA_EXT:
+   case ATA_CMD_TRUSTED_RCV_DMA:
+   case ATA_CMD_TRUSTED_SND_DMA:
case ATA_CMD_WRITE:
case ATA_CMD_WRITE_EXT:
+   case ATA_CMD_WRITE_FUA_EXT:
case ATA_CMD_WRITE_QUEUED:
case ATA_CMD_WRITE_LOG_DMA_EXT:
+   case ATA_CMD_WRITE_STREAM_DMA_EXT:
return SATA_PROTOCOL_DMA;
 
-   case ATA_CMD_DOWNLOAD_MICRO:
-   case ATA_CMD_DEV_RESET:
case ATA_CMD_CHK_POWER:
+   case ATA_CMD_DEV_RESET:
+   case ATA_CMD_EDD:
case ATA_CMD_FLUSH:
case ATA_CMD_FLUSH_EXT:
case ATA_CMD_VERIFY:
-- 
1.9.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 03/11] hisi_sas: only process broadcast change in phy_bcast_v2_hw()

2016-11-07 Thread John Garry
From: Xiang Chen 

There are many BROADCAST primitives generated by the host.
We are only interested in BROADCAST (CHANGE) primitives currently,
so only process this.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index cb19e73..7567193 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -194,6 +194,9 @@
 #define SL_CONTROL_NOTIFY_EN_MSK   (0x1 << SL_CONTROL_NOTIFY_EN_OFF)
 #define SL_CONTROL_CTA_OFF 17
 #define SL_CONTROL_CTA_MSK (0x1 << SL_CONTROL_CTA_OFF)
+#define RX_PRIMS_STATUS (PORT_BASE + 0x98)
+#define RX_BCAST_CHG_OFF1
+#define RX_BCAST_CHG_MSK(0x1 << RX_BCAST_CHG_OFF)
 #define TX_ID_DWORD0   (PORT_BASE + 0x9c)
 #define TX_ID_DWORD1   (PORT_BASE + 0xa0)
 #define TX_ID_DWORD2   (PORT_BASE + 0xa4)
@@ -2044,9 +2047,12 @@ static void phy_bcast_v2_hw(int phy_no, struct hisi_hba 
*hisi_hba)
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
+   u32 bcast_status;
 
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 1);
-   sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
+   bcast_status = hisi_sas_phy_read32(hisi_hba, phy_no, RX_PRIMS_STATUS);
+   if (bcast_status & RX_BCAST_CHG_MSK)
+   sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD);
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
 CHL_INT0_SL_RX_BCST_ACK_MSK);
hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0);
-- 
1.9.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 10/11] hisi_sas: use atomic64_t for hisi_sas_device.running_req

2016-11-07 Thread John Garry
Sometimes the value of hisi_sas_device.running_req
would go negative unless we have the check for
running_req >= 0 before trying to decrement.

This is because using running_req is not thread-safe.

As such, the value for running_req may be actually incorrect,
so use atomic64_t instead.

Signed-off-by: John Garry 
Reviewed-by: Xiang Chen 
---
 drivers/scsi/hisi_sas/hisi_sas.h   | 2 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 9 +
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 4 ++--
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 ++--
 4 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index bf59fab..8b5ecc6 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -111,7 +111,7 @@ struct hisi_sas_device {
struct domain_device*sas_device;
u64 attached_phy;
u64 device_id;
-   u64 running_req;
+   atomic64_t running_req;
u8 dev_status;
 };
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 504cbcf..18e2194 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -162,8 +162,8 @@ static void hisi_sas_slot_abort(struct work_struct *work)
hisi_sas_slot_task_free(hisi_hba, task, abort_slot);
if (task->task_done)
task->task_done(task);
-   if (sas_dev && sas_dev->running_req)
-   sas_dev->running_req--;
+   if (sas_dev)
+   atomic64_dec(&sas_dev->running_req);
 }
 
 static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
@@ -303,7 +303,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct 
hisi_hba *hisi_hba,
 
hisi_hba->slot_prep = slot;
 
-   sas_dev->running_req++;
+   atomic64_inc(&sas_dev->running_req);
++(*pass);
 
return 0;
@@ -1027,7 +1027,8 @@ static int hisi_sas_query_task(struct sas_task *task)
 
hisi_hba->slot_prep = slot;
 
-   sas_dev->running_req++;
+   atomic64_inc(&sas_dev->running_req);
+
/* send abort command to our chip */
hisi_hba->hw->start_delivery(hisi_hba);
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index bbc5760..05177fc 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -1366,8 +1366,8 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba,
}
 
 out:
-   if (sas_dev && sas_dev->running_req)
-   sas_dev->running_req--;
+   if (sas_dev)
+   atomic64_dec(&sas_dev->running_req);
 
hisi_sas_slot_task_free(hisi_hba, task, slot);
sts = ts->stat;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index cda3baf..e88113a 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -1728,8 +1728,8 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
}
 
 out:
-   if (sas_dev && sas_dev->running_req)
-   sas_dev->running_req--;
+   if (sas_dev)
+   atomic64_dec(&sas_dev->running_req);
 
hisi_sas_slot_task_free(hisi_hba, task, slot);
sts = ts->stat;
-- 
1.9.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 04/11] hisi_sas: fix port form bug in hisi_sas_port_notify_formed()

2016-11-07 Thread John Garry
From: Xiang Chen 

When we form a wideport, we should use hardware PHY port_id instead
of sas_phy->id.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 9f5ccc5..486aa92 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -537,7 +537,7 @@ static void hisi_sas_port_notify_formed(struct asd_sas_phy 
*sas_phy)
struct hisi_hba *hisi_hba = sas_ha->lldd_ha;
struct hisi_sas_phy *phy = sas_phy->lldd_phy;
struct asd_sas_port *sas_port = sas_phy->port;
-   struct hisi_sas_port *port = &hisi_hba->port[sas_phy->id];
+   struct hisi_sas_port *port = &hisi_hba->port[phy->port_id];
unsigned long flags;
 
if (!sas_port)
-- 
1.9.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 00/11] hisi_sas: some fixes, improvements, and new features

2016-11-07 Thread John Garry
This patchset introduces some misc bug fixes, improvements,
and new features to the HiSilicon SAS driver.

The new features include:
- ECC and AXI bus fatal error handling for v2 hw
- PHY (min and max) linkrate setting

John Garry (1):
  hisi_sas: use atomic64_t for hisi_sas_device.running_req

Xiang Chen (10):
  hisi_sas: add v2 hw support for ECC and AXI bus fatal error
  hisi_sas: alloc queue id of slot according to device id
  hisi_sas: only process broadcast change in phy_bcast_v2_hw()
  hisi_sas: fix port form bug in hisi_sas_port_notify_formed()
  hisi_sas: replace WARN_ON() with dev_warn() for internal abort
  hisi_sas: modify return value of hisi_sas_query_task()
  hisi_sas: delete repeated configuration in free_device_v2_hw()
  hisi_sas: modify some values in get_ata_protocol()
  hisi_sas: check SATA FIS when directly attaching SATA device
  hisi_sas: add PHY set linkrate support for v1 and v2 hw

 drivers/scsi/hisi_sas/hisi_sas.h   |   9 +-
 drivers/scsi/hisi_sas/hisi_sas_main.c  |  37 ++-
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c |  79 +++--
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 539 +++--
 4 files changed, 599 insertions(+), 65 deletions(-)

-- 
1.9.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 09/11] hisi_sas: check SATA FIS when directly attaching SATA device

2016-11-07 Thread John Garry
From: Xiang Chen 

Check ERR bit of status to decide whether there is something wrong with
initial register-D2H FIS. If error exists, PHY reset the channel to
restart OOB.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index a5faa4d..cda3baf 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -2537,6 +2537,16 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
goto end;
}
 
+   /* check ERR bit of Status Register */
+   if (fis->status & ATA_ERR) {
+   dev_warn(dev, "sata int: phy%d FIS status: 0x%x\n", phy_no,
+   fis->status);
+   disable_phy_v2_hw(hisi_hba, phy_no);
+   enable_phy_v2_hw(hisi_hba, phy_no);
+   res = IRQ_NONE;
+   goto end;
+   }
+
if (unlikely(phy_no == 8)) {
u32 port_state = hisi_sas_read32(hisi_hba, PORT_STATE);
 
-- 
1.9.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 11/11] hisi_sas: add PHY set linkrate support for v1 and v2 hw

2016-11-07 Thread John Garry
From: Xiang Chen 

Add the function to set PHY min and max linkrate through
sysfs interface.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas.h   |  3 +++
 drivers/scsi/hisi_sas/hisi_sas_main.c  | 12 +++--
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 45 ++
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 45 ++
 4 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 8b5ecc6..c0cd505 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -168,6 +168,9 @@ struct hisi_sas_hw {
void (*phy_enable)(struct hisi_hba *hisi_hba, int phy_no);
void (*phy_disable)(struct hisi_hba *hisi_hba, int phy_no);
void (*phy_hard_reset)(struct hisi_hba *hisi_hba, int phy_no);
+   void (*phy_set_linkrate)(struct hisi_hba *hisi_hba, int phy_no,
+   struct sas_phy_linkrates *linkrates);
+   enum sas_linkrate (*phy_get_max_linkrate)(void);
void (*free_device)(struct hisi_hba *hisi_hba,
struct hisi_sas_device *dev);
int (*get_wideport_bitmap)(struct hisi_hba *hisi_hba, int port_id);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 18e2194..6d6f150 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -369,9 +369,14 @@ static void hisi_sas_bytes_dmaed(struct hisi_hba 
*hisi_hba, int phy_no)
struct sas_phy *sphy = sas_phy->phy;
 
sphy->negotiated_linkrate = sas_phy->linkrate;
-   sphy->minimum_linkrate = phy->minimum_linkrate;
sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS;
-   sphy->maximum_linkrate = phy->maximum_linkrate;
+   sphy->maximum_linkrate_hw =
+   hisi_hba->hw->phy_get_max_linkrate();
+   if (sphy->minimum_linkrate == SAS_LINK_RATE_UNKNOWN)
+   sphy->minimum_linkrate = phy->minimum_linkrate;
+
+   if (sphy->maximum_linkrate == SAS_LINK_RATE_UNKNOWN)
+   sphy->maximum_linkrate = phy->maximum_linkrate;
}
 
if (phy->phy_type & PORT_TYPE_SAS) {
@@ -645,6 +650,9 @@ static int hisi_sas_control_phy(struct asd_sas_phy 
*sas_phy, enum phy_func func,
break;
 
case PHY_FUNC_SET_LINK_RATE:
+   hisi_hba->hw->phy_set_linkrate(hisi_hba, phy_no, funcdata);
+   break;
+
case PHY_FUNC_RELEASE_SPINUP_HOLD:
default:
return -EOPNOTSUPP;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index 05177fc..8a1be0b 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -843,6 +843,49 @@ static void sl_notify_v1_hw(struct hisi_hba *hisi_hba, int 
phy_no)
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
 }
 
+static enum sas_linkrate phy_get_max_linkrate_v1_hw(void)
+{
+   return SAS_LINK_RATE_6_0_GBPS;
+}
+
+static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no,
+   struct sas_phy_linkrates *r)
+{
+   u32 prog_phy_link_rate =
+   hisi_sas_phy_read32(hisi_hba, phy_no, PROG_PHY_LINK_RATE);
+   struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+   struct asd_sas_phy *sas_phy = &phy->sas_phy;
+   int i;
+   enum sas_linkrate min, max;
+   u32 rate_mask = 0;
+
+   if (r->maximum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+   max = sas_phy->phy->maximum_linkrate;
+   min = r->minimum_linkrate;
+   } else if (r->minimum_linkrate == SAS_LINK_RATE_UNKNOWN) {
+   max = r->maximum_linkrate;
+   min = sas_phy->phy->minimum_linkrate;
+   } else
+   return;
+
+   sas_phy->phy->maximum_linkrate = max;
+   sas_phy->phy->minimum_linkrate = min;
+
+   min -= SAS_LINK_RATE_1_5_GBPS;
+   max -= SAS_LINK_RATE_1_5_GBPS;
+
+   for (i = 0; i <= max; i++)
+   rate_mask |= 1 << (i * 2);
+
+   prog_phy_link_rate &= ~0xff;
+   prog_phy_link_rate |= rate_mask;
+
+   hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE,
+   prog_phy_link_rate);
+
+   phy_hard_reset_v1_hw(hisi_hba, phy_no);
+}
+
 static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id)
 {
int i, bitmap = 0;
@@ -1818,6 +1861,8 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba)
.phy_enable = enable_phy_v1_hw,
.phy_disable = disable_phy_v1_hw,
.phy_hard_reset = phy_hard_reset_v1_hw,
+   .phy_set_linkrate = phy_set_linkrate_v1_hw,
+   .phy_get_max_linkrate = phy_get_max_linkrate_v1_hw,
.get_wideport_bitmap = get_wideport_bitmap_v1_hw,
.max_command_entries = 

[PATCH 06/11] hisi_sas: modify return value of hisi_sas_query_task()

2016-11-07 Thread John Garry
From: Xiang Chen 

sas_scsi_find_task() only deals with return value
TMF_RESP_FUNC_FAILED/TMF_RESP_FUNC_SUCC/TMF_RESP_FUNC_COMPLETE of
query task. So for LLDD errors just return TMF_RESP_FUNC_FAILED.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 9133238..504cbcf 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -961,6 +961,9 @@ static int hisi_sas_query_task(struct sas_task *task)
case TMF_RESP_FUNC_FAILED:
case TMF_RESP_FUNC_COMPLETE:
break;
+   default:
+   rc = TMF_RESP_FUNC_FAILED;
+   break;
}
}
return rc;
-- 
1.9.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 05/11] hisi_sas: replace WARN_ON() with dev_warn() for internal abort

2016-11-07 Thread John Garry
From: Xiang Chen 

Replace WARN_ON() with dev_warn() print when internal abort fails.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 486aa92..9133238 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -764,7 +764,8 @@ static int hisi_sas_exec_internal_tmf_task(struct 
domain_device *device,
task = NULL;
}
 ex_err:
-   WARN_ON(retry == TASK_RETRY);
+   if (retry == TASK_RETRY)
+   dev_warn(dev, "abort tmf: executing internal task failed!\n");
sas_free_task(task);
return res;
 }
-- 
1.9.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 02/11] hisi_sas: alloc queue id of slot according to device id

2016-11-07 Thread John Garry
From: Xiang Chen 

Currently slots are allocated from queues in a round-robin fashion.
This causes a problem for internal commands in device mode. For this
mode, we should ensure that the internal abort command is the last
command seen in the host for that device. We can only ensure this when
we place the internal abort command after the preceding commands for
device that in the same queue, as there is no order in which the host
will select a queue to execute the next command.

This queue restriction makes supporting scsi mq more tricky in
the future, but should not be a blocker.

Note: Even though v1 hw does not support internal abort, the
  allocation method is chosen to be the same for consistency.

Signed-off-by: Xiang Chen 
Signed-off-by: John Garry 
---
 drivers/scsi/hisi_sas/hisi_sas.h   |  4 ++--
 drivers/scsi/hisi_sas/hisi_sas_main.c  |  8 
 drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 30 --
 drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 29 -
 4 files changed, 30 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index 64046c5..bf59fab 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -150,7 +150,8 @@ struct hisi_sas_hw {
struct domain_device *device);
struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
-   int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s);
+   int (*get_free_slot)(struct hisi_hba *hisi_hba, u32 dev_id,
+   int *q, int *s);
void (*start_delivery)(struct hisi_hba *hisi_hba);
int (*prep_ssp)(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot, int is_tmf,
@@ -207,7 +208,6 @@ struct hisi_hba {
struct hisi_sas_port port[HISI_SAS_MAX_PHYS];
 
int queue_count;
-   int queue;
struct hisi_sas_slot*slot_prep;
 
struct dma_pool *sge_page_pool;
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c 
b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 9afc697..9f5ccc5 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -232,8 +232,8 @@ static int hisi_sas_task_prep(struct sas_task *task, struct 
hisi_hba *hisi_hba,
rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
if (rc)
goto err_out;
-   rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue,
-&dlvry_queue_slot);
+   rc = hisi_hba->hw->get_free_slot(hisi_hba, sas_dev->device_id,
+   &dlvry_queue, &dlvry_queue_slot);
if (rc)
goto err_out_tag;
 
@@ -987,8 +987,8 @@ static int hisi_sas_query_task(struct sas_task *task)
rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
if (rc)
goto err_out;
-   rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue,
-&dlvry_queue_slot);
+   rc = hisi_hba->hw->get_free_slot(hisi_hba, sas_dev->device_id,
+   &dlvry_queue, &dlvry_queue_slot);
if (rc)
goto err_out_tag;
 
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
index c0ac49d..bbc5760 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
@@ -862,29 +862,23 @@ static int get_wideport_bitmap_v1_hw(struct hisi_hba 
*hisi_hba, int port_id)
  * The callpath to this function and upto writing the write
  * queue pointer should be safe from interruption.
  */
-static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, int *q, int *s)
+static int get_free_slot_v1_hw(struct hisi_hba *hisi_hba, u32 dev_id,
+   int *q, int *s)
 {
struct device *dev = &hisi_hba->pdev->dev;
struct hisi_sas_dq *dq;
u32 r, w;
-   int queue = hisi_hba->queue;
-
-   while (1) {
-   dq = &hisi_hba->dq[queue];
-   w = dq->wr_point;
-   r = hisi_sas_read32_relaxed(hisi_hba,
-   DLVRY_Q_0_RD_PTR + (queue * 0x14));
-   if (r == (w+1) % HISI_SAS_QUEUE_SLOTS) {
-   queue = (queue + 1) % hisi_hba->queue_count;
-   if (queue == hisi_hba->queue) {
-   dev_warn(dev, "could not find free slot\n");
-   return -EAGAIN;
-   }
-   continue;
-   }
-   break;
+   int queue = dev_id % hisi_hba->queue_count;
+
+   dq = &hisi_hba->dq[queue];
+   w = dq->wr_point;
+   r = hisi_sas_read32_relaxed(hisi_hba,
+   DLVRY_Q_0_RD_PTR + (queue * 0x14));
+   if (