[PATCH 12/15] be2iscsi: Fix IOPOLL implementation

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

OS not responding when running 2 port traffic on 72 CPUs system.

be2iscsi IRQs gets affined to CPU0 when irqbalancer is disabled.
be_iopoll processing completions in BLOCK_IOPOLL_SOFTIRQ hogged CPU0.

1. Use budget to exit the polling loop. beiscsi_process_cq didn't honour it.
2. Rearming of EQ is done only after iopoll completes.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c  |2 +-
 drivers/scsi/be2iscsi/be_iscsi.c |2 +-
 drivers/scsi/be2iscsi/be_main.c  |   91 +-
 drivers/scsi/be2iscsi/be_main.h  |5 +-
 4 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index eced82b..3dbf6af 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -543,7 +543,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
}
 
if (num)
-   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1, 0);
+   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c89a025..3545721 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1298,7 +1298,7 @@ static void beiscsi_flush_cq(struct beiscsi_hba *phba)
for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = _context->be_eq[i];
blk_iopoll_disable(_eq->iopoll);
-   beiscsi_process_cq(pbe_eq);
+   beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
blk_iopoll_enable(_eq->iopoll);
}
 }
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index a665e6a..9a86044 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -895,32 +895,21 @@ static irqreturn_t be_isr_mcc(int irq, void *dev_id)
 static irqreturn_t be_isr_msix(int irq, void *dev_id)
 {
struct beiscsi_hba *phba;
-   struct be_eq_entry *eqe = NULL;
struct be_queue_info *eq;
-   struct be_queue_info *cq;
-   unsigned int num_eq_processed;
struct be_eq_obj *pbe_eq;
 
pbe_eq = dev_id;
eq = _eq->q;
-   cq = pbe_eq->cq;
-   eqe = queue_tail_node(eq);
 
phba = pbe_eq->phba;
-   num_eq_processed = 0;
-   while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-   & EQE_VALID_MASK) {
-   if (!blk_iopoll_sched_prep(_eq->iopoll))
-   blk_iopoll_sched(_eq->iopoll);
-
-   AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-   queue_tail_inc(eq);
-   eqe = queue_tail_node(eq);
-   num_eq_processed++;
-   }
-
-   if (num_eq_processed)
-   hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
+   /* disable interrupt till iopoll completes */
+   hwi_ring_eq_db(phba, eq->id, 1, 0, 0, 1);
+   if (!blk_iopoll_sched_prep(_eq->iopoll))
+   blk_iopoll_sched(_eq->iopoll);
+   else
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO,
+   "BM_%d: received event while polling eq %d cq %d\n",
+   eq->id, pbe_eq->cq->id);
 
return IRQ_HANDLED;
 }
@@ -998,6 +987,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
struct pci_dev *pcidev = phba->pcidev;
@@ -1072,7 +1062,7 @@ free_msix_irqs:
 
 void hwi_ring_cq_db(struct beiscsi_hba *phba,
   unsigned int id, unsigned int num_processed,
-  unsigned char rearm, unsigned char event)
+  unsigned char rearm)
 {
u32 val = 0;
 
@@ -2044,7 +2034,7 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
 
if (num_processed >= 32) {
hwi_ring_cq_db(phba, mcc_cq->id,
-   num_processed, 0, 0);
+   num_processed, 0);
num_processed = 0;
}
if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
@@ -2062,24 +2052,25 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
}
 
if (num_processed > 0)
-   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
+   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1);
 
 }
 
 /**
  * beiscsi_process_cq()- Process the Completion Queue
  * @pbe_eq: Event Q on which the Completion has come
+ * @budget: Max number of events to processed
  *
  * return
  * Number of Completion Entries processed.
  **/
-unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
+unsigned int 

RE: [PATCH 6/9] be2iscsi: Fix IOPOLL implementation

2015-12-14 Thread Jitendra Bhivare
The problem statement indicates affinity issue but IOPOLL implementation
had issues too.
1. IOPOLL budget passed in the callback is not being honored. This was the
root cause where
the driver kept polling in softirq.
2. The interrupts kept coming even when IOPOLL is scheduled. So we needed
to fix EQ rearming.

I think, choosing CPU affinity internally by driver is not right thing to
do. For setting IRQ affinity
you need to have holistic view of the system and better done by external
entity which has heuristics
of all the varied workloads on the system.

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de]
Sent: Monday, December 14, 2015 8:54 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Subject: Re: [PATCH 6/9] be2iscsi: Fix IOPOLL implementation

On 12/14/2015 07:11 AM, Jitendra Bhivare wrote:
> From: Jitendra <jitendra.bhiv...@avagotech.com>
>
> OS not responding when running 2 port traffic on 72 CPUs system.
>
> be2iscsi IRQs gets affined to CPU0 when irqbalancer is disabled.
> be_iopoll processing completions in BLOCK_IOPOLL_SOFTIRQ hogged CPU0.
>
> 1. Use budget to exit the polling loop in beiscsi_process_cq.
> 2. Rearming of EQ is done only after iopoll completes.
>
> Signed-off-by: Jitendra <jitendra.bhiv...@avagotech.com>
> ---
>   drivers/scsi/be2iscsi/be_cmds.c  |2 +-
>   drivers/scsi/be2iscsi/be_iscsi.c |2 +-
>   drivers/scsi/be2iscsi/be_main.c  |   91
+-
>   drivers/scsi/be2iscsi/be_main.h  |5 +-
>   4 files changed, 56 insertions(+), 44 deletions(-)
>
Hmm. Not sure if I agree with this.
Doesn't the be2iscsi driver set the cpu affinity internally?
If not, wouldn't that be the better solution?

Cheers,

Hannes
--
Dr. Hannes ReineckezSeries & Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284
(AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 1/9] be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx

2015-12-14 Thread Jitendra Bhivare
be_mbox_db_ready_wait was changed to remove wait_event_timeout done under
spinlock held for port initialization FW commands.
The timeout change and unrecoverable error check inside the wait loop were
needed to be addressed too.
Though spinlock was replaced with mutex in patch 2/9.

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de]
Sent: Monday, December 14, 2015 8:34 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Subject: Re: [PATCH 1/9] be2iscsi: Fix soft lockup in mgmt_get_all_if_id
path using bmbx

On 12/14/2015 07:10 AM, Jitendra Bhivare wrote:
> From: Jitendra <jitendra.bhiv...@avagotech.com>
>
> We are taking mbox_lock spinlock which disables pre-emption before we
> poll for mbox completion. Waiting there with spinlock held in excess
> of 20s will cause soft lockup.
>
> Actual fix is to change mbox_lock to mutex.
Really? I didn't find that in the patch ...

> The changes are done in phases. This is the first part.
> 1. Changed mgmt_get_all_if_id to use MCC instead of BMBX.
> 2. Changed be_mbox_db_ready_wait to busy wait for 12s max and removed
> wait_event_timeout. Added error handling code for IO reads.
> OPCODE_COMMON_QUERY_FIRMWARE_CONFIG mbox command takes 8s time when
> unreachable boot targets are configured.
>
Why did you modify be_mbox_db_ready_wait(), seeing that you're not using
the mailbox interface anymore after this change?

Cheers,

Hannes
--
Dr. Hannes ReineckezSeries & Storage
h...@suse.de   +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284
(AG Nürnberg)
--
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/15] be2iscsi: Fix return value for MCC completion

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Change return value of completed MCC EBUSY to EINVAL.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 9bb5905..eced82b 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -323,7 +323,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
if (resp_hdr->response_length)
return 0;
}
-   return -EBUSY;
+   return -EINVAL;
}
return 0;
 }
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/15] be2iscsi: Add FW config validation

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

System crash in I+T card personality

Fix to add validation for ULP in initiator mode, physical port number,
and supported queue, icd, cid counts.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_main.c |2 +-
 drivers/scsi/be2iscsi/be_main.h |2 +
 drivers/scsi/be2iscsi/be_mgmt.c |  188 +--
 3 files changed, 123 insertions(+), 69 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 8967e05..a665e6a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5670,6 +5670,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto free_port;
}
mgmt_get_port_name(>ctrl, phba);
+   beiscsi_get_params(phba);
 
if (enable_msix)
find_num_cpus(phba);
@@ -5687,7 +5688,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
}
 
phba->shost->max_id = phba->params.cxns_per_ctrl;
-   beiscsi_get_params(phba);
phba->shost->can_queue = phba->params.ios_per_ctrl;
ret = beiscsi_init_port(phba);
if (ret < 0) {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c09082a..f89861b 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -397,7 +397,9 @@ struct beiscsi_hba {
 * group together since they are used most frequently
 * for cid to cri conversion
 */
+#define BEISCSI_PHYS_PORT_MAX  4
unsigned int phys_port;
+   /* valid values of phys_port id are 0, 1, 2, 3 */
unsigned int eqid_count;
unsigned int cqid_count;
unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index ad7aa75..15f7ad7 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -373,90 +373,142 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
 {
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_fw_cfg *req = embedded_payload(wrb);
-   int status = 0;
+   struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
+   uint32_t cid_count, icd_count;
+   int status = -EINVAL;
+   uint8_t ulp_num = 0;
 
mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
+   be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
 
-   be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-
-   be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
+   be_cmd_hdr_prepare(_cfg->hdr, CMD_SUBSYSTEM_COMMON,
   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
   EMBED_MBX_MAX_PAYLOAD_SIZE);
-   status = be_mbox_notify(ctrl);
-   if (!status) {
-   uint8_t ulp_num = 0;
-   struct be_fw_cfg *pfw_cfg;
-   pfw_cfg = req;
 
-   if (!is_chip_be2_be3r(phba)) {
-   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
-   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (be_mbox_notify(ctrl)) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : Failed in mgmt_get_fw_config\n");
+   goto fail_init;
+   }
 
-   beiscsi_log(phba, KERN_INFO,
-   BEISCSI_LOG_INIT,
-   "BG_%d : EQ_Count : %d CQ_Count : %d\n",
-   phba->fw_config.eqid_count,
+   /* FW response formats depend on port id */
+   phba->fw_config.phys_port = pfw_cfg->phys_port;
+   if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid physical port id %d\n",
+   phba->fw_config.phys_port);
+   goto fail_init;
+   }
+
+   /* populate and check FW config against min and max values */
+   if (!is_chip_be2_be3r(phba)) {
+   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
+   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (phba->fw_config.eqid_count == 0 ||
+   phba->fw_config.eqid_count > 2048) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid EQ count %d\n",
+   phba->fw_config.eqid_count);
+   goto fail_init;
+   }
+   if (phba->fw_config.cqid_count == 0 ||
+   phba->fw_config.cqid_count > 4096) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid CQ 

[PATCH 08/15] be2iscsi: Fix VLAN support for IPv6 network

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Configuring VLAN parameters through IPv6 interface was not supported in driver.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_iscsi.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 188d83f..c89a025 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -466,6 +466,10 @@ beiscsi_set_ipv6(struct Scsi_Host *shost,
ret = mgmt_set_ip(phba, iface_param, NULL,
  ISCSI_BOOTPROTO_STATIC);
break;
+   case ISCSI_NET_PARAM_VLAN_ENABLED:
+   case ISCSI_NET_PARAM_VLAN_TAG:
+   ret = beiscsi_set_vlan_tag(shost, iface_param);
+   break;
default:
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Param %d not supported\n",
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/15] be2iscsi: Fix to handle misconfigured optics events

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Log messages for misconfigured transceivers reported by FW.

Register async events that driver handles using MCC_CREATE_EXT ioctl.
Errors messages for faulted/uncertified/unqualified optics are logged.
Added IOCTL to get port_name to be displayed in error message.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |  164 --
 drivers/scsi/be2iscsi/be_cmds.h |   47 ++--
 drivers/scsi/be2iscsi/be_main.c |   19 +
 drivers/scsi/be2iscsi/be_main.h |   10 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |   42 ++
 drivers/scsi/be2iscsi/be_mgmt.h |2 +
 6 files changed, 199 insertions(+), 85 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index e4cc98f..9bb5905 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
spin_unlock(>mcc_lock);
 }
 
-bool is_link_state_evt(u32 trailer)
-{
-   return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_LINK_STATE);
-}
-
-static bool is_iscsi_evt(u32 trailer)
-{
-   return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_ISCSI;
-}
-
-static int iscsi_evt_type(u32 trailer)
-{
-   return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
-ASYNC_TRAILER_EVENT_TYPE_MASK;
-}
-
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
if (compl->flags != 0) {
@@ -422,7 +402,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
@@ -450,6 +430,100 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
}
 }
 
+static char *beiscsi_port_misconf_event_msg[] = {
+   "Physical Link is functional.",
+   "Optics faulted/incorrectly installed/not installed - Reseat optics, if 
issue not resolved, replace.",
+   "Optics of two types installed - Remove one optic or install matching 
pair of optics.",
+   "Incompatible optics - Replace with compatible optics for card to 
function.",
+   "Unqualified optics - Replace with Avago optics for Warranty and 
Technical Support.",
+   "Uncertified optics - Replace with Avago Certified optics to enable 
link operation."
+};
+
+static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
+ struct be_mcc_compl *compl)
+{
+   struct be_async_event_sli *async_sli;
+   u8 evt_type, state, old_state, le;
+   char *sev = KERN_WARNING;
+   char *msg = NULL;
+
+   evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
+   evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+   /* processing only MISCONFIGURED physical port event */
+   if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
+   return;
+
+   async_sli = (struct be_async_event_sli *)compl;
+   state = async_sli->event_data1 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+   le = async_sli->event_data2 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+
+   old_state = phba->optic_state;
+   phba->optic_state = state;
+
+   if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
+   /* fw is reporting a state we don't know, log and return */
+   __beiscsi_log(phba, KERN_ERR,
+   "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
+   phba->port_name, async_sli->event_data1);
+   return;
+   }
+
+   if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
+   /* log link effect for unqualified-4, uncertified-5 optics */
+   if (state > 3)
+   msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
+   " Link is non-operational." :
+   " Link is operational.";
+   /* 1 - info */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
+   sev = KERN_INFO;
+   /* 2 - error */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2)
+   sev = KERN_ERR;
+   }
+
+   if (old_state != phba->optic_state)
+   __beiscsi_log(phba, sev, "BC_%d : Port %c: %s%s\n",
+ phba->port_name,
+ beiscsi_port_misconf_event_msg[state],
+ !msg ? "" : msg);
+}
+
+void 

[PATCH 05/15] be2iscsi: Set mbox timeout to 30s

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

FW recommended timeout for all mbox command is 30s.
Use msleep instead mdelay to relinquish CPU when polling for
mbox completion.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 6f58063..1e70053 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -587,7 +587,8 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
+   /* wait 30s for generic non-flash MBOX operation */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT3
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
@@ -612,7 +613,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 
if (time_after(jiffies, timeout))
break;
-   mdelay(1);
+   msleep(20);
} while (!ready);
 
beiscsi_log(phba, KERN_ERR,
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/15] be2iscsi: Fix to synchronize tag allocation using spin_lock

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

alloc_mcc_tag/free_mcc_tag is now done under mcc_lock spin_lock

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 21c806f..6f58063 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -118,6 +118,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
unsigned int tag = 0;
 
+   spin_lock(>ctrl.mcc_lock);
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
@@ -130,6 +131,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
else
phba->ctrl.mcc_alloc_index++;
}
+   spin_unlock(>ctrl.mcc_lock);
return tag;
 }
 
@@ -254,7 +256,7 @@ release_mcc_tag:
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 {
-   spin_lock(>mbox_lock);
+   spin_lock(>mcc_lock);
tag = tag & 0x00FF;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
@@ -262,7 +264,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
-   spin_unlock(>mbox_lock);
+   spin_unlock(>mcc_lock);
 }
 
 bool is_link_state_evt(u32 trailer)
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/15] be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

We are taking mbox_lock spinlock which disables pre-emption before we poll
for mbox completion. Waiting there with spinlock held in excess of 20s will
cause soft lockup.

Actual fix is to change mbox_lock to mutex.
The changes are done in phases. This is the first part.
1. Changed mgmt_get_all_if_id to use MCC where after posting lock is released.
2. Changed be_mbox_db_ready_wait to busy wait for 12s max and removed
wait_event_timeout. Added error handling code for IO reads.
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG mbox command takes 8s time when unreachable
boot targets configured.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |   60 +++
 drivers/scsi/be2iscsi/be_mgmt.c |   32 ++--
 2 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 2778089..cd50e3c 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -587,47 +587,42 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT4000/* 4sec */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
-   bool read_flag = false;
-   int ret = 0, i;
u32 ready;
-   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);
 
-   if (beiscsi_error(phba))
-   return -EIO;
+   /*
+* This BMBX busy wait path is used during init only.
+* For the commands executed during init, 5s should suffice.
+*/
+   timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
+   do {
+   if (beiscsi_error(phba))
+   return -EIO;
 
-   timeout = jiffies + (HZ * 110);
+   ready = ioread32(db);
+   if (ready == 0x)
+   return -EIO;
 
-   do {
-   for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
-   ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
-   if (ready) {
-   read_flag = true;
-   break;
-   }
-   mdelay(1);
-   }
+   ready &= MPU_MAILBOX_DB_RDY_MASK;
+   if (ready)
+   return 0;
 
-   if (!read_flag) {
-   wait_event_timeout(rdybit_check_q,
- (read_flag != true),
-  HZ * 5);
-   }
-   } while ((time_before(jiffies, timeout)) && !read_flag);
+   if (time_after(jiffies, timeout))
+   break;
+   mdelay(1);
+   } while (!ready);
 
-   if (!read_flag) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : FW Timed Out\n");
-   phba->fw_timeout = true;
-   beiscsi_ue_detect(phba);
-   ret = -EBUSY;
-   }
+   beiscsi_log(phba, KERN_ERR,
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : FW Timed Out\n");
 
-   return ret;
+   phba->fw_timeout = true;
+   beiscsi_ue_detect(phba);
+
+   return -EBUSY;
 }
 
 /*
@@ -674,6 +669,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
if (status)
return status;
 
+   /* RDY is set; small delay before CQE read. */
+   udelay(1);
+
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, >compl);
be_mcc_compl_use(compl);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index aea3e6b..7b54b23 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -809,27 +809,39 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
 {
struct be_ctrl_info *ctrl = >ctrl;
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
-   struct be_cmd_get_all_if_id_req *pbe_allid = req;
+   struct be_mcc_wrb *wrb;
+   struct be_cmd_get_all_if_id_req *req;
+   struct be_cmd_get_all_if_id_req *pbe_allid;
+   unsigned int tag;
int status = 0;
 
-   memset(wrb, 0, sizeof(*wrb));
-
spin_lock(>mbox_lock);
+   tag = alloc_mcc_tag(phba);
+   if (!tag) {
+   spin_unlock(>mbox_lock);
+   return -ENOMEM;
+   }
+
+   wrb = wrb_from_mccq(phba);
+  

[PATCH 06/15] be2iscsi: Added return value check for mgmt_get_all_if_id

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Use of mutex_lock_interruptible can return -EINTR, handle and log
the error.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_iscsi.c |7 ---
 drivers/scsi/be2iscsi/be_mgmt.c  |   10 ++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index b7087ba..188d83f 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -367,13 +367,14 @@ beiscsi_set_vlan_tag(struct Scsi_Host *shost,
  struct iscsi_iface_param_info *iface_param)
 {
struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   int ret = 0;
+   int ret;
 
/* Get the Interface Handle */
-   if (mgmt_get_all_if_id(phba)) {
+   ret = mgmt_get_all_if_id(phba);
+   if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Getting Interface Handle Failed\n");
-   return -EIO;
+   return ret;
}
 
switch (iface_param->param) {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index a41013e..a8a1670 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1018,8 +1018,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
uint32_t ip_type;
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
BE2_IPV6 : BE2_IPV4 ;
@@ -1188,8 +1189,9 @@ int mgmt_get_if_info(struct beiscsi_hba *phba, int 
ip_type,
uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
do {
rc = mgmt_alloc_cmd_data(phba, _cmd,
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/15] be2iscsi: Fix mbox synchronization replacing spinlock with mutex

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

This is second part of actual fix for soft lockup.

All mbox cmds issued using BMBX and MCC are synchronized using mutex
mbox_lock instead of spin_lock. Used mutex_lock_interruptible where
ever possible.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be.h  |2 +-
 drivers/scsi/be2iscsi/be_cmds.c |   73 ++-
 drivers/scsi/be2iscsi/be_main.c |2 +-
 drivers/scsi/be2iscsi/be_mgmt.c |  105 --
 4 files changed, 94 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 77f992e..cf19bce 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -124,7 +124,7 @@ struct be_ctrl_info {
struct pci_dev *pdev;
 
/* Mbox used for cmd request/response */
-   spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
+   struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
 * is stored for freeing purpose */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cd50e3c..6fabded 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -164,9 +164,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
/* Set MBX Tag state to Active */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -178,9 +178,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (rc <= 0) {
struct be_dma_mem *tag_mem;
/* Set MBX Tag state to timeout */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Store resource addr to be freed later */
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
@@ -199,9 +199,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else {
rc = 0;
/* Set MBX Tag state to completed */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
}
 
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
@@ -390,9 +390,9 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
tag_mem->va, tag_mem->dma);
 
/* Change tag state */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Free MCC Tag */
free_mcc_tag(ctrl, tag);
@@ -831,7 +831,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem = >dma_mem;
int status;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -858,7 +858,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
eq->id = le16_to_cpu(resp->eq_id);
eq->created = true;
}
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -879,7 +879,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -898,7 +898,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BC_%d : be_cmd_fw_initialize Failed\n");
 
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -919,7 +919,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -939,7 +939,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BC_%d : be_cmd_fw_uninit Failed\n");
 
-   

[PATCH 03/15] be2iscsi: Fix to use atomic operations for tag_state

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Replace lock based tag_state manipulations with atomic operations.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be.h  |2 +-
 drivers/scsi/be2iscsi/be_cmds.c |   26 --
 2 files changed, 13 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index cf19bce..419b53f 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -113,7 +113,7 @@ struct beiscsi_mcc_tag_state {
 #define MCC_TAG_STATE_COMPLETED 0x00
 #define MCC_TAG_STATE_RUNNING   0x01
 #define MCC_TAG_STATE_TIMEOUT   0x02
-   uint8_t tag_state;
+   atomic_t tag_state;
struct be_dma_mem tag_mem_state;
 };
 
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 6fabded..21c806f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -164,9 +164,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
/* Set MBX Tag state to Active */
-   mutex_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   mutex_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_RUNNING);
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -178,9 +177,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (rc <= 0) {
struct be_dma_mem *tag_mem;
/* Set MBX Tag state to timeout */
-   mutex_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   mutex_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_TIMEOUT);
 
/* Store resource addr to be freed later */
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
@@ -199,9 +197,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else {
rc = 0;
/* Set MBX Tag state to completed */
-   mutex_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   mutex_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_COMPLETED);
}
 
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
@@ -373,9 +370,11 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
ctrl->mcc_numtag[tag] |= (extd_status & 0x00FF) << 8;
ctrl->mcc_numtag[tag] |= (compl_status & 0x00FF);
 
-   if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_RUNNING) {
+   if (atomic_read(>ptag_state[tag].tag_state) ==
+   MCC_TAG_STATE_RUNNING) {
wake_up_interruptible(>mcc_wait[tag]);
-   } else if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_TIMEOUT) {
+   } else if (atomic_read(>ptag_state[tag].tag_state) ==
+   MCC_TAG_STATE_TIMEOUT) {
struct be_dma_mem *tag_mem;
tag_mem = >ptag_state[tag].tag_mem_state;
 
@@ -390,9 +389,8 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
tag_mem->va, tag_mem->dma);
 
/* Change tag state */
-   mutex_lock(>ctrl.mbox_lock);
-   ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   mutex_unlock(>ctrl.mbox_lock);
+   atomic_set(>ptag_state[tag].tag_state,
+   MCC_TAG_STATE_COMPLETED);
 
/* Free MCC Tag */
free_mcc_tag(ctrl, tag);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/15] be2iscsi: Fix to remove shutdown entry point

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Null pointer dereference in shutdown path after taking dump.

Shutdown path is not needed as FW comes up clean every time during probe
after issuing FUNCTION reset MBOX command.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |   17 +++--
 drivers/scsi/be2iscsi/be_cmds.h |2 +-
 drivers/scsi/be2iscsi/be_main.c |   24 
 drivers/scsi/be2iscsi/be_main.h |3 +--
 4 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1e70053..e4cc98f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -414,22 +414,11 @@ static struct be_mcc_compl *be_mcc_compl_get(struct 
beiscsi_hba *phba)
 }
 
 /**
- * be2iscsi_fail_session(): Closing session with appropriate error
+ * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
- *
- * Depending on adapter state appropriate error flag is passed.
  **/
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
 {
-   struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-   struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   uint32_t iscsi_err_flag;
-
-   if (phba->state & BE_ADAPTER_STATE_SHUTDOWN)
-   iscsi_err_flag = ISCSI_ERR_INVALID_HOST;
-   else
-   iscsi_err_flag = ISCSI_ERR_CONN_FAILED;
-
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
@@ -447,7 +436,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
evt->physical_port);
 
iscsi_host_for_each_session(phba->shost,
-   be2iscsi_fail_session);
+   beiscsi_fail_session);
} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 4bfca35..5d165ee 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -1367,5 +1367,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int 
payload_len,
 void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
u8 subsystem, u8 opcode, int cmd_len);
 
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session);
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session);
 #endif /* !BEISCSI_CMDS_H */
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 61ce86b..2f3e118 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5315,7 +5315,6 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
 
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
-
struct beiscsi_hba *phba = NULL;
 
phba = pci_get_drvdata(pcidev);
@@ -5325,9 +5324,9 @@ static void beiscsi_remove(struct pci_dev *pcidev)
}
 
beiscsi_destroy_def_ifaces(phba);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
iscsi_boot_destroy_kset(phba->boot_kset);
iscsi_host_remove(phba->shost);
+   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
pci_disable_pcie_error_reporting(pcidev);
@@ -5336,23 +5335,6 @@ static void beiscsi_remove(struct pci_dev *pcidev)
pci_disable_device(pcidev);
 }
 
-static void beiscsi_shutdown(struct pci_dev *pcidev)
-{
-
-   struct beiscsi_hba *phba = NULL;
-
-   phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
-   if (!phba) {
-   dev_err(>dev, "beiscsi_shutdown called with no phba\n");
-   return;
-   }
-
-   phba->state = BE_ADAPTER_STATE_SHUTDOWN;
-   iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
-   pci_disable_device(pcidev);
-}
-
 static void beiscsi_msix_enable(struct beiscsi_hba *phba)
 {
int i, status;
@@ -5673,6 +5655,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto hba_free;
}
 
+   /*
+* FUNCTION_RESET should clean up any stale info in FW for this fn
+*/
ret = beiscsi_cmd_reset_function(phba);
if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5861,7 +5846,6 @@ static struct pci_driver beiscsi_pci_driver = {
.name = DRV_NAME,
.probe = beiscsi_dev_probe,
.remove = beiscsi_remove,
-   .shutdown = beiscsi_shutdown,
.id_table = beiscsi_pci_id_table,
.err_handler = _eeh_handlers
 };
diff --git a/drivers/scsi/be2iscsi/be_main.h 

[PATCH 00/15] be2iscsi: driver update 11.0.0.0

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

This patch is generated against for-next branch.

Jitendra (15):
  be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx
  be2iscsi: Fix mbox synchronization replacing spinlock with mutex
  be2iscsi: Fix to use atomic operations for tag_state
  be2iscsi: Fix to synchronize tag allocation using spin_lock
  be2iscsi: Set mbox timeout to 30s
  be2iscsi: Added return value check for mgmt_get_all_if_id
  be2iscsi: Fix to remove shutdown entry point
  be2iscsi: Fix VLAN support for IPv6 network
  be2iscsi: Fix to handle misconfigured optics events
  be2iscsi: Add FW config validation
  be2iscsi: Fix return value for MCC completion
  be2iscsi: Fix IOPOLL implementation
  be2iscsi: Fix to process 25G link speed info from FW
  be2iscsi: Fix WRB leak in login/logout path
  be2iscsi: Update the driver version

 drivers/scsi/be2iscsi/be.h  |4 +-
 drivers/scsi/be2iscsi/be_cmds.c |  368 ++---
 drivers/scsi/be2iscsi/be_cmds.h |  114 ++-
 drivers/scsi/be2iscsi/be_iscsi.c|   54 ++---
 drivers/scsi/be2iscsi/be_main.c |  210 ++-
 drivers/scsi/be2iscsi/be_main.h |   23 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |  387 +--
 drivers/scsi/be2iscsi/be_mgmt.h |2 +
 drivers/scsi/scsi_transport_iscsi.c |2 +
 include/scsi/iscsi_if.h |2 +
 10 files changed, 648 insertions(+), 518 deletions(-)

--
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 13/15] be2iscsi: Fix to process 25G link speed info from FW

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Async link event provides port_speed info. Use the same to report in
ISCSI_HOST_PARAM_PORT_SPEED query. Removed link status query IOCTL used
to do the same.

25G and 40G are defined in kernel enum iscsi_port_speed.

Fixed get_nic_conf structure definition. Removed rsvd[23] field in
be_cmd_get_nic_conf_resp.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |   47 -
 drivers/scsi/be2iscsi/be_cmds.h |   65 ++
 drivers/scsi/be2iscsi/be_iscsi.c|   41 +
 drivers/scsi/be2iscsi/be_main.h |1 +
 drivers/scsi/be2iscsi/be_mgmt.c |   28 ---
 drivers/scsi/scsi_transport_iscsi.c |2 +
 include/scsi/iscsi_if.h |2 +
 7 files changed, 57 insertions(+), 129 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 3dbf6af..498eba2 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -402,31 +402,31 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
-   struct be_async_event_link_state *evt)
+static void beiscsi_process_async_link(struct beiscsi_hba *phba,
+  struct be_mcc_compl *compl)
 {
-   if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
-   phba->state = BE_ADAPTER_LINK_DOWN;
+   struct be_async_event_link_state *evt;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link Down on Port %d\n",
-   evt->physical_port);
+   evt = (struct be_async_event_link_state *)compl;
 
-   iscsi_host_for_each_session(phba->shost,
-   beiscsi_fail_session);
-   } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
+   phba->port_speed = evt->port_speed;
+   /**
+* Check logical link status in ASYNC event.
+* This has been newly introduced in SKH-R Firmware 10.0.338.45.
+**/
+   if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
-
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link UP on Port %d\n",
-   evt->physical_port);
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Up on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   } else {
+   phba->state = BE_ADAPTER_LINK_DOWN;
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Down on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   iscsi_host_for_each_session(phba->shost,
+   beiscsi_fail_session);
}
 }
 
@@ -503,8 +503,7 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
switch (evt_code) {
case ASYNC_EVENT_CODE_LINK_STATE:
-   beiscsi_async_link_state_process(phba,
-   (struct be_async_event_link_state *)compl);
+   beiscsi_process_async_link(phba, compl);
break;
case ASYNC_EVENT_CODE_ISCSI:
phba->state |= BE_ADAPTER_CHECK_BOOT;
@@ -520,8 +519,8 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
}
 
beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : ASYNC Event: status 0x%08x flags 0x%08x\n",
-   compl->status, compl->flags);
+   "BC_%d : ASYNC Event %x: status 0x%08x flags 0x%08x\n",
+   evt_code, compl->status, compl->flags);
 }
 
 int beiscsi_process_mcc(struct beiscsi_hba *phba)
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 6411f7b..3b9bc2e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -142,7 +142,6 @@ struct be_async_event_trailer {
 enum {
ASYNC_EVENT_LINK_DOWN = 0x0,
ASYNC_EVENT_LINK_UP = 0x1,
-   ASYNC_EVENT_LOGICAL = 0x2
 };
 
 /**
@@ -152,13 +151,26 @@ enum {
 struct 

[PATCH 14/15] be2iscsi: Fix WRB leak in login/logout path

2015-12-15 Thread Jitendra Bhivare
From: Jitendra 

Login/Logout loop was hanging after few hours. /var/log/message showed
that alloc_wrb_handle() function was not able to allocate any new WRB.

Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not send nopout
Sep 11 11:25:22 Jhelum10 kernel: scsi host10: BM_4989 : Alloc of WRB_HANDLE
Failedfor the CID : 384
Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not allocate pdu for
mgmt task.

Driver allocates WRB to pass login negotiated parameters information to FW
in beiscsi_offload_connection(). This allocated WRB was not freed so there
was WRB_Leak happening.

Put WRB used for posting the login-negotiated parameters back in pool.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_main.c |   72 ++
 1 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 9a86044..d8cdb4e 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1184,6 +1184,22 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index++;
 }
 
+static inline struct wrb_handle *
+beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  unsigned int wrbs_per_cxn)
+{
+   struct wrb_handle *pwrb_handle;
+
+   pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
+   pwrb_context->wrb_handles_available--;
+   if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
+   pwrb_context->alloc_index = 0;
+   else
+   pwrb_context->alloc_index++;
+
+   return pwrb_handle;
+}
+
 /**
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
@@ -1193,30 +1209,30 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
  * This happens under session_lock until submission to chip
  */
 struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-struct hwi_wrb_context **pcontext)
+   struct hwi_wrb_context **pcontext)
 {
struct hwi_wrb_context *pwrb_context;
struct hwi_controller *phwi_ctrlr;
-   struct wrb_handle *pwrb_handle;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = _ctrlr->wrb_context[cri_index];
-   if (pwrb_context->wrb_handles_available >= 2) {
-   pwrb_handle = pwrb_context->pwrb_handle_base[
-   pwrb_context->alloc_index];
-   pwrb_context->wrb_handles_available--;
-   if (pwrb_context->alloc_index ==
-   (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->alloc_index = 0;
-   else
-   pwrb_context->alloc_index++;
+   /* return the context address */
+   *pcontext = pwrb_context;
+   return beiscsi_get_wrb_handle(pwrb_context, phba->params.wrbs_per_cxn);
+}
 
-   /* Return the context address */
-   *pcontext = pwrb_context;
-   } else
-   pwrb_handle = NULL;
-   return pwrb_handle;
+static inline void
+beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  struct wrb_handle *pwrb_handle,
+  unsigned int wrbs_per_cxn)
+{
+   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
+   pwrb_context->wrb_handles_available++;
+   if (pwrb_context->free_index == (wrbs_per_cxn - 1))
+   pwrb_context->free_index = 0;
+   else
+   pwrb_context->free_index++;
 }
 
 /**
@@ -1231,13 +1247,9 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
struct wrb_handle *pwrb_handle)
 {
-   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
-   pwrb_context->wrb_handles_available++;
-   if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->free_index = 0;
-   else
-   pwrb_context->free_index++;
-
+   beiscsi_put_wrb_handle(pwrb_context,
+  pwrb_handle,
+  phba->params.wrbs_per_cxn);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
"BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
@@ -4715,6 +4727,20 @@ beiscsi_offload_connection(struct beiscsi_conn 
*beiscsi_conn,
doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
iowrite32(doorbell, phba->db_va +
  beiscsi_conn->doorbell_offset);
+
+   /*
+* There is no completion for CONTEXT_UPDATE. The completion of next
+* WRB posted guarantees FW's processing and DMA'ing 

RE: [PATCH 5/9] be2iscsi: Fix to handle misconfigured optics events

2015-12-15 Thread Jitendra Bhivare
> So please add defines for the individual messages and use a key-value
map to lookup the messages.
FW events are in sequence 0...5 so key is implied and value is being
stored in array of strings.
BEISCSI_PORT_MISCONF_EVENT_MAX (replaced with ARRAY_SIZE) is just to
verify the event number.
Not so sure what you are suggesting.

port_name IOCTL is needed to display the error message.

Will split FW config validation.

Thanks,

JB

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de]
Sent: Monday, December 14, 2015 8:49 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Subject: Re: [PATCH 5/9] be2iscsi: Fix to handle misconfigured optics
events

On 12/14/2015 07:11 AM, Jitendra Bhivare wrote:
> From: Jitendra <jitendra.bhiv...@avagotech.com>
>
> Log messages for misconfigured transceivers reported by FW.
>
> Register async events that driver handles using MCC_CREATE_EXT ioctl.
> Errors messages for faulted/uncertified/unqualified optics are logged.
> Added FW config validation.
>
> Signed-off-by: Jitendra <jitendra.bhiv...@avagotech.com>
> ---
>   drivers/scsi/be2iscsi/be_cmds.c |  169 ++---
>   drivers/scsi/be2iscsi/be_cmds.h |   47 +++-
>   drivers/scsi/be2iscsi/be_main.c |   22 +---
>   drivers/scsi/be2iscsi/be_main.h |   12 ++-
>   drivers/scsi/be2iscsi/be_mgmt.c |  230
+++
>   drivers/scsi/be2iscsi/be_mgmt.h |2 +
>   6 files changed, 327 insertions(+), 155 deletions(-)
>
> diff --git a/drivers/scsi/be2iscsi/be_cmds.c
> b/drivers/scsi/be2iscsi/be_cmds.c index e4cc98f..58a9fda 100644
> --- a/drivers/scsi/be2iscsi/be_cmds.c
> +++ b/drivers/scsi/be2iscsi/be_cmds.c
> @@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl,
unsigned int tag)
>   spin_unlock(>mcc_lock);
>   }
>
> -bool is_link_state_evt(u32 trailer)
> -{
> - return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
> -   ASYNC_TRAILER_EVENT_CODE_MASK) ==
> -   ASYNC_EVENT_CODE_LINK_STATE);
> -}
> -
> -static bool is_iscsi_evt(u32 trailer) -{
> - return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
> -   ASYNC_TRAILER_EVENT_CODE_MASK) ==
> -   ASYNC_EVENT_CODE_ISCSI;
> -}
> -
> -static int iscsi_evt_type(u32 trailer) -{
> - return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
> -  ASYNC_TRAILER_EVENT_TYPE_MASK;
> -}
> -
>   static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
>   {
>   if (compl->flags != 0) {
> @@ -343,7 +323,7 @@ static int be_mcc_compl_process(struct be_ctrl_info
*ctrl,
>   if (resp_hdr->response_length)
>   return 0;
>   }
> - return -EBUSY;
> + return -EINVAL;
>   }
>   return 0;
>   }
How is this related to the above description?
Shouldn't it be moved to a different patch?

> @@ -422,7 +402,7 @@ void beiscsi_fail_session(struct iscsi_cls_session
*cls_session)
>   iscsi_session_failure(cls_session->dd_data,
ISCSI_ERR_CONN_FAILED);
>   }
>
> -void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
> +static void beiscsi_async_link_state_process(struct beiscsi_hba
> +*phba,
>   struct be_async_event_link_state *evt)
>   {
>   if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) || @@ -450,6
> +430,103 @@ void beiscsi_async_link_state_process(struct beiscsi_hba
*phba,
>   }
>   }
>
> +static char *beiscsi_port_misconf_event_msg[] = {
> + "Physical Link is functional.",
> + "Optics faulted/incorrectly installed/not installed - Reseat
optics, if issue not resolved, replace.",
> + "Optics of two types installed - Remove one optic or install
matching pair of optics.",
> + "Incompatible optics - Replace with compatible optics for card to
function.",
> + "Unqualified optics - Replace with Avago optics for Warranty and
Technical Support.",
> + "Uncertified optics - Replace with Avago Certified optics to
enable link operation."
> +};
> +#define BEISCSI_PORT_MISCONF_EVENT_MAX \
> + (sizeof(beiscsi_port_misconf_event_msg) / \
> +  sizeof(beiscsi_port_misconf_event_msg[0]))
> +
Please don't. The above list is tied with event numbers from firmware, and
by no means arbitrary.
So please add defines for the individual messages and use a key-value map
to lookup the messages.

> +static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
> +   struct be_mcc_compl *compl) {
> + struct be_async_event_sli *async_sli;
> + u8 evt_type, state, old_state, le;
> + cha

[PATCH 5/9] be2iscsi: Fix to handle misconfigured optics events

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Log messages for misconfigured transceivers reported by FW.

Register async events that driver handles using MCC_CREATE_EXT ioctl.
Errors messages for faulted/uncertified/unqualified optics are logged.
Added FW config validation.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |  169 ++---
 drivers/scsi/be2iscsi/be_cmds.h |   47 +++-
 drivers/scsi/be2iscsi/be_main.c |   22 +---
 drivers/scsi/be2iscsi/be_main.h |   12 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |  230 +++
 drivers/scsi/be2iscsi/be_mgmt.h |2 +
 6 files changed, 327 insertions(+), 155 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index e4cc98f..58a9fda 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
spin_unlock(>mcc_lock);
 }
 
-bool is_link_state_evt(u32 trailer)
-{
-   return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_LINK_STATE);
-}
-
-static bool is_iscsi_evt(u32 trailer)
-{
-   return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_ISCSI;
-}
-
-static int iscsi_evt_type(u32 trailer)
-{
-   return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
-ASYNC_TRAILER_EVENT_TYPE_MASK;
-}
-
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
if (compl->flags != 0) {
@@ -343,7 +323,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
if (resp_hdr->response_length)
return 0;
}
-   return -EBUSY;
+   return -EINVAL;
}
return 0;
 }
@@ -422,7 +402,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
@@ -450,6 +430,103 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
}
 }
 
+static char *beiscsi_port_misconf_event_msg[] = {
+   "Physical Link is functional.",
+   "Optics faulted/incorrectly installed/not installed - Reseat optics, if 
issue not resolved, replace.",
+   "Optics of two types installed - Remove one optic or install matching 
pair of optics.",
+   "Incompatible optics - Replace with compatible optics for card to 
function.",
+   "Unqualified optics - Replace with Avago optics for Warranty and 
Technical Support.",
+   "Uncertified optics - Replace with Avago Certified optics to enable 
link operation."
+};
+#define BEISCSI_PORT_MISCONF_EVENT_MAX \
+   (sizeof(beiscsi_port_misconf_event_msg) / \
+sizeof(beiscsi_port_misconf_event_msg[0]))
+
+static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
+ struct be_mcc_compl *compl)
+{
+   struct be_async_event_sli *async_sli;
+   u8 evt_type, state, old_state, le;
+   char *sev = KERN_WARNING;
+   char *msg = NULL;
+
+   evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
+   evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+   /* processing only MISCONFIGURED physical port event */
+   if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
+   return;
+
+   async_sli = (struct be_async_event_sli *)compl;
+   state = async_sli->event_data1 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+   le = async_sli->event_data2 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+
+   old_state = phba->optic_state;
+   phba->optic_state = state;
+
+   if (state >= BEISCSI_PORT_MISCONF_EVENT_MAX) {
+   /* fw is reporting a state we don't know, log and return */
+   __beiscsi_log(phba, KERN_ERR,
+   "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
+   phba->port_name, async_sli->event_data1);
+   return;
+   }
+
+   if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
+   /* log link effect for unqualified-4, uncertified-5 optics */
+   if (state > 3)
+   msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
+   " Link is non-operational." :
+   " Link is operational.";
+   /* 1 - info */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
+   sev = KERN_INFO;
+   /* 2 - error */
+ 

[PATCH 3/9] be2iscsi: Fix to remove shutdown entry point

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Null pointer dereference in shutdown path after taking dump.

Shutdown path is not needed as FW comes up clean every time during probe
after issuing FUNCTION reset MBOX command.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |   17 +++--
 drivers/scsi/be2iscsi/be_cmds.h |2 +-
 drivers/scsi/be2iscsi/be_main.c |   24 
 drivers/scsi/be2iscsi/be_main.h |3 +--
 4 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1e70053..e4cc98f 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -414,22 +414,11 @@ static struct be_mcc_compl *be_mcc_compl_get(struct 
beiscsi_hba *phba)
 }
 
 /**
- * be2iscsi_fail_session(): Closing session with appropriate error
+ * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
- *
- * Depending on adapter state appropriate error flag is passed.
  **/
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
 {
-   struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-   struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   uint32_t iscsi_err_flag;
-
-   if (phba->state & BE_ADAPTER_STATE_SHUTDOWN)
-   iscsi_err_flag = ISCSI_ERR_INVALID_HOST;
-   else
-   iscsi_err_flag = ISCSI_ERR_CONN_FAILED;
-
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
@@ -447,7 +436,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
evt->physical_port);
 
iscsi_host_for_each_session(phba->shost,
-   be2iscsi_fail_session);
+   beiscsi_fail_session);
} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 4bfca35..5d165ee 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -1367,5 +1367,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int 
payload_len,
 void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
u8 subsystem, u8 opcode, int cmd_len);
 
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session);
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session);
 #endif /* !BEISCSI_CMDS_H */
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 61ce86b..2f3e118 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5315,7 +5315,6 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
 
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
-
struct beiscsi_hba *phba = NULL;
 
phba = pci_get_drvdata(pcidev);
@@ -5325,9 +5324,9 @@ static void beiscsi_remove(struct pci_dev *pcidev)
}
 
beiscsi_destroy_def_ifaces(phba);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
iscsi_boot_destroy_kset(phba->boot_kset);
iscsi_host_remove(phba->shost);
+   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
pci_disable_pcie_error_reporting(pcidev);
@@ -5336,23 +5335,6 @@ static void beiscsi_remove(struct pci_dev *pcidev)
pci_disable_device(pcidev);
 }
 
-static void beiscsi_shutdown(struct pci_dev *pcidev)
-{
-
-   struct beiscsi_hba *phba = NULL;
-
-   phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
-   if (!phba) {
-   dev_err(>dev, "beiscsi_shutdown called with no phba\n");
-   return;
-   }
-
-   phba->state = BE_ADAPTER_STATE_SHUTDOWN;
-   iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
-   pci_disable_device(pcidev);
-}
-
 static void beiscsi_msix_enable(struct beiscsi_hba *phba)
 {
int i, status;
@@ -5673,6 +5655,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto hba_free;
}
 
+   /*
+* FUNCTION_RESET should clean up any stale info in FW for this fn
+*/
ret = beiscsi_cmd_reset_function(phba);
if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5861,7 +5846,6 @@ static struct pci_driver beiscsi_pci_driver = {
.name = DRV_NAME,
.probe = beiscsi_dev_probe,
.remove = beiscsi_remove,
-   .shutdown = beiscsi_shutdown,
.id_table = beiscsi_pci_id_table,
.err_handler = _eeh_handlers
 };
diff --git a/drivers/scsi/be2iscsi/be_main.h 

[PATCH 7/9] be2iscsi: Fix to process 25G link speed info from FW

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Async link event provides port_speed info. Use the same to report in
ISCSI_HOST_PARAM_PORT_SPEED query. Removed link status query IOCTL used
to do the same.

25G and 40G are defined in kernel enum iscsi_port_speed.

Fixed get_nic_conf structure definition. Removed rsvd[23] field in
be_cmd_get_nic_conf_resp.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c |   52 +---
 drivers/scsi/be2iscsi/be_cmds.h |   65 ++
 drivers/scsi/be2iscsi/be_iscsi.c|   49 +++---
 drivers/scsi/be2iscsi/be_main.h |1 +
 drivers/scsi/be2iscsi/be_mgmt.c |   28 ---
 drivers/scsi/scsi_transport_iscsi.c |2 +
 include/scsi/iscsi_if.h |2 +
 7 files changed, 62 insertions(+), 137 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 37d1008..498eba2 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -402,31 +402,31 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
-   struct be_async_event_link_state *evt)
+static void beiscsi_process_async_link(struct beiscsi_hba *phba,
+  struct be_mcc_compl *compl)
 {
-   if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
-   phba->state = BE_ADAPTER_LINK_DOWN;
+   struct be_async_event_link_state *evt;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link Down on Port %d\n",
-   evt->physical_port);
+   evt = (struct be_async_event_link_state *)compl;
 
-   iscsi_host_for_each_session(phba->shost,
-   beiscsi_fail_session);
-   } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
+   phba->port_speed = evt->port_speed;
+   /**
+* Check logical link status in ASYNC event.
+* This has been newly introduced in SKH-R Firmware 10.0.338.45.
+**/
+   if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
-
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link UP on Port %d\n",
-   evt->physical_port);
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Up on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   } else {
+   phba->state = BE_ADAPTER_LINK_DOWN;
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Down on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   iscsi_host_for_each_session(phba->shost,
+   beiscsi_fail_session);
}
 }
 
@@ -438,9 +438,6 @@ static char *beiscsi_port_misconf_event_msg[] = {
"Unqualified optics - Replace with Avago optics for Warranty and 
Technical Support.",
"Uncertified optics - Replace with Avago Certified optics to enable 
link operation."
 };
-#define BEISCSI_PORT_MISCONF_EVENT_MAX \
-   (sizeof(beiscsi_port_misconf_event_msg) / \
-sizeof(beiscsi_port_misconf_event_msg[0]))
 
 static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
  struct be_mcc_compl *compl)
@@ -466,7 +463,7 @@ static void beiscsi_process_async_sli(struct beiscsi_hba 
*phba,
old_state = phba->optic_state;
phba->optic_state = state;
 
-   if (state >= BEISCSI_PORT_MISCONF_EVENT_MAX) {
+   if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
/* fw is reporting a state we don't know, log and return */
__beiscsi_log(phba, KERN_ERR,
"BC_%d : Port %c: Unrecognized optic state 0x%x\n",
@@ -506,8 +503,7 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
switch (evt_code) {
case ASYNC_EVENT_CODE_LINK_STATE:
-   beiscsi_async_link_state_process(phba,
-   (struct be_async_event_link_state *)compl);
+   

[PATCH 2/9] be2iscsi: Fix mbox synchronization replacing spinlock with mutex

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

This is second part of actual fix for soft lockup.
All mbox cmds issued using BMBX and MCC are synchronized using mbox_lock.
alloc_mcc_tag/free_mcc_tag is done under mcc_lock and tag_state is
accessed using atomic operations.

Mailbox command time out is now set to 30s as per FW requirement.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be.h   |4 +-
 drivers/scsi/be2iscsi/be_cmds.c  |   94 ---
 drivers/scsi/be2iscsi/be_iscsi.c |7 +-
 drivers/scsi/be2iscsi/be_main.c  |2 +-
 drivers/scsi/be2iscsi/be_mgmt.c  |  115 --
 5 files changed, 116 insertions(+), 106 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 77f992e..419b53f 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -113,7 +113,7 @@ struct beiscsi_mcc_tag_state {
 #define MCC_TAG_STATE_COMPLETED 0x00
 #define MCC_TAG_STATE_RUNNING   0x01
 #define MCC_TAG_STATE_TIMEOUT   0x02
-   uint8_t tag_state;
+   atomic_t tag_state;
struct be_dma_mem tag_mem_state;
 };
 
@@ -124,7 +124,7 @@ struct be_ctrl_info {
struct pci_dev *pdev;
 
/* Mbox used for cmd request/response */
-   spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
+   struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
 * is stored for freeing purpose */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cd50e3c..1e70053 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -118,6 +118,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
unsigned int tag = 0;
 
+   spin_lock(>ctrl.mcc_lock);
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
@@ -130,6 +131,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
else
phba->ctrl.mcc_alloc_index++;
}
+   spin_unlock(>ctrl.mcc_lock);
return tag;
 }
 
@@ -164,9 +166,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
/* Set MBX Tag state to Active */
-   spin_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   spin_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_RUNNING);
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -178,9 +179,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (rc <= 0) {
struct be_dma_mem *tag_mem;
/* Set MBX Tag state to timeout */
-   spin_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   spin_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_TIMEOUT);
 
/* Store resource addr to be freed later */
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
@@ -199,9 +199,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else {
rc = 0;
/* Set MBX Tag state to completed */
-   spin_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   atomic_set(>ctrl.ptag_state[tag].tag_state,
+   MCC_TAG_STATE_COMPLETED);
}
 
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
@@ -257,7 +256,7 @@ release_mcc_tag:
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 {
-   spin_lock(>mbox_lock);
+   spin_lock(>mcc_lock);
tag = tag & 0x00FF;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
@@ -265,7 +264,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
-   spin_unlock(>mbox_lock);
+   spin_unlock(>mcc_lock);
 }
 
 bool is_link_state_evt(u32 trailer)
@@ -373,9 +372,11 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
ctrl->mcc_numtag[tag] |= (extd_status & 0x00FF) << 8;
ctrl->mcc_numtag[tag] |= (compl_status & 0x00FF);
 
-   if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_RUNNING) {
+   if (atomic_read(>ptag_state[tag].tag_state) ==
+   MCC_TAG_STATE_RUNNING) {
wake_up_interruptible(>mcc_wait[tag]);
-   } else if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_TIMEOUT) {

[PATCH 0/9] be2iscsi driver update to 11.0.0.0

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

This patch is generated against for-next branch.

Jitendra (9):
  be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx
  be2iscsi: Fix mbox synchronization replacing spinlock with mutex
  be2iscsi: Fix to remove shutdown entry point
  be2iscsi: Fix VLAN support for IPv6 network
  be2iscsi: Fix to handle misconfigured optics events
  be2iscsi: Fix IOPOLL implementation
  be2iscsi: Fix to process 25G link speed info from FW
  be2iscsi: Fix WRB leak in login/logout path
  be2iscsi: Update the driver version

 drivers/scsi/be2iscsi/be.h  |4 +-
 drivers/scsi/be2iscsi/be_cmds.c |  368 ++---
 drivers/scsi/be2iscsi/be_cmds.h |  114 ++-
 drivers/scsi/be2iscsi/be_iscsi.c|   62 ++
 drivers/scsi/be2iscsi/be_main.c |  211 ++-
 drivers/scsi/be2iscsi/be_main.h |   23 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |  387 +--
 drivers/scsi/be2iscsi/be_mgmt.h |2 +
 drivers/scsi/scsi_transport_iscsi.c |2 +
 include/scsi/iscsi_if.h |2 +
 10 files changed, 653 insertions(+), 522 deletions(-)

--
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 4/9] be2iscsi: Fix VLAN support for IPv6 network

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Added VLAN operations in set IPv6 address for interface.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_iscsi.c |4 
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 188d83f..c89a025 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -466,6 +466,10 @@ beiscsi_set_ipv6(struct Scsi_Host *shost,
ret = mgmt_set_ip(phba, iface_param, NULL,
  ISCSI_BOOTPROTO_STATIC);
break;
+   case ISCSI_NET_PARAM_VLAN_ENABLED:
+   case ISCSI_NET_PARAM_VLAN_TAG:
+   ret = beiscsi_set_vlan_tag(shost, iface_param);
+   break;
default:
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Param %d not supported\n",
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 8/9] be2iscsi: Fix WRB leak in login/logout path

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Login/Logout loop was hanging after few hours. /var/log/message showed
that alloc_wrb_handle() function was not able to allocate any new WRB.

Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not send nopout
Sep 11 11:25:22 Jhelum10 kernel: scsi host10: BM_4989 : Alloc of WRB_HANDLE
Failedfor the CID : 384
Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not allocate pdu
for mgmt task.

Driver allocates WRB to pass login negotiated parameters information to FW
in beiscsi_offload_connection(). This allocated WRB was not freed so there
was WRB_Leak happening.

Put WRB used for posting the login-negotiated parameters back in pool.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_main.c |   72 ++
 1 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 799fe7a..9c65163 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1184,6 +1184,22 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index++;
 }
 
+static inline struct wrb_handle *
+beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  unsigned int wrbs_per_cxn)
+{
+   struct wrb_handle *pwrb_handle;
+
+   pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
+   pwrb_context->wrb_handles_available--;
+   if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
+   pwrb_context->alloc_index = 0;
+   else
+   pwrb_context->alloc_index++;
+
+   return pwrb_handle;
+}
+
 /**
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
@@ -1193,30 +1209,30 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
  * This happens under session_lock until submission to chip
  */
 struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-struct hwi_wrb_context **pcontext)
+   struct hwi_wrb_context **pcontext)
 {
struct hwi_wrb_context *pwrb_context;
struct hwi_controller *phwi_ctrlr;
-   struct wrb_handle *pwrb_handle;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = _ctrlr->wrb_context[cri_index];
-   if (pwrb_context->wrb_handles_available >= 2) {
-   pwrb_handle = pwrb_context->pwrb_handle_base[
-   pwrb_context->alloc_index];
-   pwrb_context->wrb_handles_available--;
-   if (pwrb_context->alloc_index ==
-   (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->alloc_index = 0;
-   else
-   pwrb_context->alloc_index++;
+   /* return the context address */
+   *pcontext = pwrb_context;
+   return beiscsi_get_wrb_handle(pwrb_context, phba->params.wrbs_per_cxn);
+}
 
-   /* Return the context address */
-   *pcontext = pwrb_context;
-   } else
-   pwrb_handle = NULL;
-   return pwrb_handle;
+static inline void
+beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  struct wrb_handle *pwrb_handle,
+  unsigned int wrbs_per_cxn)
+{
+   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
+   pwrb_context->wrb_handles_available++;
+   if (pwrb_context->free_index == (wrbs_per_cxn - 1))
+   pwrb_context->free_index = 0;
+   else
+   pwrb_context->free_index++;
 }
 
 /**
@@ -1231,13 +1247,9 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
struct wrb_handle *pwrb_handle)
 {
-   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
-   pwrb_context->wrb_handles_available++;
-   if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->free_index = 0;
-   else
-   pwrb_context->free_index++;
-
+   beiscsi_put_wrb_handle(pwrb_context,
+  pwrb_handle,
+  phba->params.wrbs_per_cxn);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
"BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
@@ -4715,6 +4727,20 @@ beiscsi_offload_connection(struct beiscsi_conn 
*beiscsi_conn,
doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
iowrite32(doorbell, phba->db_va +
  beiscsi_conn->doorbell_offset);
+
+   /*
+* There is no completion for CONTEXT_UPDATE. The completion of next
+* WRB posted guarantees FW's processing and DMA'ing 

[PATCH 6/9] be2iscsi: Fix IOPOLL implementation

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

OS not responding when running 2 port traffic on 72 CPUs system.

be2iscsi IRQs gets affined to CPU0 when irqbalancer is disabled.
be_iopoll processing completions in BLOCK_IOPOLL_SOFTIRQ hogged CPU0.

1. Use budget to exit the polling loop in beiscsi_process_cq.
2. Rearming of EQ is done only after iopoll completes.

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_cmds.c  |2 +-
 drivers/scsi/be2iscsi/be_iscsi.c |2 +-
 drivers/scsi/be2iscsi/be_main.c  |   91 +-
 drivers/scsi/be2iscsi/be_main.h  |5 +-
 4 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 58a9fda..37d1008 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -546,7 +546,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
}
 
if (num)
-   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1, 0);
+   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c89a025..3545721 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1298,7 +1298,7 @@ static void beiscsi_flush_cq(struct beiscsi_hba *phba)
for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = _context->be_eq[i];
blk_iopoll_disable(_eq->iopoll);
-   beiscsi_process_cq(pbe_eq);
+   beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
blk_iopoll_enable(_eq->iopoll);
}
 }
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index d036706..799fe7a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -895,32 +895,21 @@ static irqreturn_t be_isr_mcc(int irq, void *dev_id)
 static irqreturn_t be_isr_msix(int irq, void *dev_id)
 {
struct beiscsi_hba *phba;
-   struct be_eq_entry *eqe = NULL;
struct be_queue_info *eq;
-   struct be_queue_info *cq;
-   unsigned int num_eq_processed;
struct be_eq_obj *pbe_eq;
 
pbe_eq = dev_id;
eq = _eq->q;
-   cq = pbe_eq->cq;
-   eqe = queue_tail_node(eq);
 
phba = pbe_eq->phba;
-   num_eq_processed = 0;
-   while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-   & EQE_VALID_MASK) {
-   if (!blk_iopoll_sched_prep(_eq->iopoll))
-   blk_iopoll_sched(_eq->iopoll);
-
-   AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-   queue_tail_inc(eq);
-   eqe = queue_tail_node(eq);
-   num_eq_processed++;
-   }
-
-   if (num_eq_processed)
-   hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
+   /* disable interrupt till iopoll completes */
+   hwi_ring_eq_db(phba, eq->id, 1, 0, 0, 1);
+   if (!blk_iopoll_sched_prep(_eq->iopoll))
+   blk_iopoll_sched(_eq->iopoll);
+   else
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO,
+   "BM_%d: received event while polling eq %d cq %d\n",
+   eq->id, pbe_eq->cq->id);
 
return IRQ_HANDLED;
 }
@@ -998,6 +987,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
struct pci_dev *pcidev = phba->pcidev;
@@ -1072,7 +1062,7 @@ free_msix_irqs:
 
 void hwi_ring_cq_db(struct beiscsi_hba *phba,
   unsigned int id, unsigned int num_processed,
-  unsigned char rearm, unsigned char event)
+  unsigned char rearm)
 {
u32 val = 0;
 
@@ -2044,7 +2034,7 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
 
if (num_processed >= 32) {
hwi_ring_cq_db(phba, mcc_cq->id,
-   num_processed, 0, 0);
+   num_processed, 0);
num_processed = 0;
}
if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
@@ -2062,24 +2052,25 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
}
 
if (num_processed > 0)
-   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
+   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1);
 
 }
 
 /**
  * beiscsi_process_cq()- Process the Completion Queue
  * @pbe_eq: Event Q on which the Completion has come
+ * @budget: Max number of events to processed
  *
  * return
  * Number of Completion Entries processed.
  **/
-unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
+unsigned int 

[PATCH 9/9] be2iscsi: Update the driver version

2015-12-13 Thread Jitendra Bhivare
From: Jitendra 

Driver version: 11.0.0.0

Signed-off-by: Jitendra 
---
 drivers/scsi/be2iscsi/be_main.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 41c708c..16a6fd0 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -36,7 +36,7 @@
 #include 
 
 #define DRV_NAME   "be2iscsi"
-#define BUILD_STR  "10.6.0.1"
+#define BUILD_STR  "11.0.0.0"
 #define BE_NAME"Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC   BE_NAME " " "Driver"
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 10/15] be2iscsi: Add FW config validation

2015-12-20 Thread Jitendra Bhivare
It stands for Dual ULP Aware. Will add a comment explaining that.

Thanks,

JB

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de]
Sent: Friday, December 18, 2015 2:34 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Subject: Re: [PATCH 10/15] be2iscsi: Add FW config validation

On 12/15/2015 04:55 PM, Jitendra Bhivare wrote:
> From: Jitendra <jitendra.bhiv...@avagotech.com>
>
> System crash in I+T card personality
>
> Fix to add validation for ULP in initiator mode, physical port number,
> and supported queue, icd, cid counts.
>
> Signed-off-by: Jitendra <jitendra.bhiv...@avagotech.com>
> ---
>   drivers/scsi/be2iscsi/be_main.c |2 +-
>   drivers/scsi/be2iscsi/be_main.h |2 +
>   drivers/scsi/be2iscsi/be_mgmt.c |  188
+--
>   3 files changed, 123 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/scsi/be2iscsi/be_main.c
> b/drivers/scsi/be2iscsi/be_main.c index 8967e05..a665e6a 100644
> --- a/drivers/scsi/be2iscsi/be_main.c
> +++ b/drivers/scsi/be2iscsi/be_main.c
> @@ -5670,6 +5670,7 @@ static int beiscsi_dev_probe(struct pci_dev
*pcidev,
>   goto free_port;
>   }
>   mgmt_get_port_name(>ctrl, phba);
> + beiscsi_get_params(phba);
>
>   if (enable_msix)
>   find_num_cpus(phba);
> @@ -5687,7 +5688,6 @@ static int beiscsi_dev_probe(struct pci_dev
*pcidev,
>   }
>
>   phba->shost->max_id = phba->params.cxns_per_ctrl;
> - beiscsi_get_params(phba);
>   phba->shost->can_queue = phba->params.ios_per_ctrl;
>   ret = beiscsi_init_port(phba);
>   if (ret < 0) {
> diff --git a/drivers/scsi/be2iscsi/be_main.h
> b/drivers/scsi/be2iscsi/be_main.h index c09082a..f89861b 100644
> --- a/drivers/scsi/be2iscsi/be_main.h
> +++ b/drivers/scsi/be2iscsi/be_main.h
> @@ -397,7 +397,9 @@ struct beiscsi_hba {
>* group together since they are used most frequently
>* for cid to cri conversion
>*/
> +#define BEISCSI_PHYS_PORT_MAX4
>   unsigned int phys_port;
> + /* valid values of phys_port id are 0, 1, 2, 3 */
>   unsigned int eqid_count;
>   unsigned int cqid_count;
>   unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
> diff --git a/drivers/scsi/be2iscsi/be_mgmt.c
> b/drivers/scsi/be2iscsi/be_mgmt.c index ad7aa75..15f7ad7 100644
> --- a/drivers/scsi/be2iscsi/be_mgmt.c
> +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> @@ -373,90 +373,142 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
>   struct beiscsi_hba *phba)
>   {
>   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
> - struct be_fw_cfg *req = embedded_payload(wrb);
> - int status = 0;
> + struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
> + uint32_t cid_count, icd_count;
> + int status = -EINVAL;
> + uint8_t ulp_num = 0;
>
>   mutex_lock(>mbox_lock);
>   memset(wrb, 0, sizeof(*wrb));
> + be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
>
> - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> -
> - be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
> + be_cmd_hdr_prepare(_cfg->hdr, CMD_SUBSYSTEM_COMMON,
>  OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
>  EMBED_MBX_MAX_PAYLOAD_SIZE);
> - status = be_mbox_notify(ctrl);
> - if (!status) {
> - uint8_t ulp_num = 0;
> - struct be_fw_cfg *pfw_cfg;
> - pfw_cfg = req;
>
> - if (!is_chip_be2_be3r(phba)) {
> - phba->fw_config.eqid_count = pfw_cfg->eqid_count;
> - phba->fw_config.cqid_count = pfw_cfg->cqid_count;
> + if (be_mbox_notify(ctrl)) {
> + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
> + "BG_%d : Failed in mgmt_get_fw_config\n");
> + goto fail_init;
> + }
>
> - beiscsi_log(phba, KERN_INFO,
> - BEISCSI_LOG_INIT,
> - "BG_%d : EQ_Count : %d CQ_Count :
%d\n",
> - phba->fw_config.eqid_count,
> + /* FW response formats depend on port id */
> + phba->fw_config.phys_port = pfw_cfg->phys_port;
> + if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
> + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
> + "BG_%d : invalid physical port id %d\n",
> + phba->fw_config.phys_port);
> + goto fail_init;
> + }

RE: [PATCH 10/15] be2iscsi: Add FW config validation

2015-12-20 Thread Jitendra Bhivare
Yes, the faults are not being used, it just adds to the confusion, we just
intend to get the link state change - UP or DOWN.

-Original Message-
From: Hannes Reinecke [mailto:h...@suse.de]
Sent: Friday, December 18, 2015 2:34 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Subject: Re: [PATCH 10/15] be2iscsi: Add FW config validation

On 12/15/2015 04:55 PM, Jitendra Bhivare wrote:
> From: Jitendra <jitendra.bhiv...@avagotech.com>
>
> System crash in I+T card personality
>
> Fix to add validation for ULP in initiator mode, physical port number,
> and supported queue, icd, cid counts.
>
> Signed-off-by: Jitendra <jitendra.bhiv...@avagotech.com>
> ---
>   drivers/scsi/be2iscsi/be_main.c |2 +-
>   drivers/scsi/be2iscsi/be_main.h |2 +
>   drivers/scsi/be2iscsi/be_mgmt.c |  188
+--
>   3 files changed, 123 insertions(+), 69 deletions(-)
>
> diff --git a/drivers/scsi/be2iscsi/be_main.c
> b/drivers/scsi/be2iscsi/be_main.c index 8967e05..a665e6a 100644
> --- a/drivers/scsi/be2iscsi/be_main.c
> +++ b/drivers/scsi/be2iscsi/be_main.c
> @@ -5670,6 +5670,7 @@ static int beiscsi_dev_probe(struct pci_dev
*pcidev,
>   goto free_port;
>   }
>   mgmt_get_port_name(>ctrl, phba);
> + beiscsi_get_params(phba);
>
>   if (enable_msix)
>   find_num_cpus(phba);
> @@ -5687,7 +5688,6 @@ static int beiscsi_dev_probe(struct pci_dev
*pcidev,
>   }
>
>   phba->shost->max_id = phba->params.cxns_per_ctrl;
> - beiscsi_get_params(phba);
>   phba->shost->can_queue = phba->params.ios_per_ctrl;
>   ret = beiscsi_init_port(phba);
>   if (ret < 0) {
> diff --git a/drivers/scsi/be2iscsi/be_main.h
> b/drivers/scsi/be2iscsi/be_main.h index c09082a..f89861b 100644
> --- a/drivers/scsi/be2iscsi/be_main.h
> +++ b/drivers/scsi/be2iscsi/be_main.h
> @@ -397,7 +397,9 @@ struct beiscsi_hba {
>* group together since they are used most frequently
>* for cid to cri conversion
>*/
> +#define BEISCSI_PHYS_PORT_MAX4
>   unsigned int phys_port;
> + /* valid values of phys_port id are 0, 1, 2, 3 */
>   unsigned int eqid_count;
>   unsigned int cqid_count;
>   unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
> diff --git a/drivers/scsi/be2iscsi/be_mgmt.c
> b/drivers/scsi/be2iscsi/be_mgmt.c index ad7aa75..15f7ad7 100644
> --- a/drivers/scsi/be2iscsi/be_mgmt.c
> +++ b/drivers/scsi/be2iscsi/be_mgmt.c
> @@ -373,90 +373,142 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
>   struct beiscsi_hba *phba)
>   {
>   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
> - struct be_fw_cfg *req = embedded_payload(wrb);
> - int status = 0;
> + struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
> + uint32_t cid_count, icd_count;
> + int status = -EINVAL;
> + uint8_t ulp_num = 0;
>
>   mutex_lock(>mbox_lock);
>   memset(wrb, 0, sizeof(*wrb));
> + be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
>
> - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
> -
> - be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
> + be_cmd_hdr_prepare(_cfg->hdr, CMD_SUBSYSTEM_COMMON,
>  OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
>  EMBED_MBX_MAX_PAYLOAD_SIZE);
> - status = be_mbox_notify(ctrl);
> - if (!status) {
> - uint8_t ulp_num = 0;
> - struct be_fw_cfg *pfw_cfg;
> - pfw_cfg = req;
>
> - if (!is_chip_be2_be3r(phba)) {
> - phba->fw_config.eqid_count = pfw_cfg->eqid_count;
> - phba->fw_config.cqid_count = pfw_cfg->cqid_count;
> + if (be_mbox_notify(ctrl)) {
> + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
> + "BG_%d : Failed in mgmt_get_fw_config\n");
> + goto fail_init;
> + }
>
> - beiscsi_log(phba, KERN_INFO,
> - BEISCSI_LOG_INIT,
> - "BG_%d : EQ_Count : %d CQ_Count :
%d\n",
> - phba->fw_config.eqid_count,
> + /* FW response formats depend on port id */
> + phba->fw_config.phys_port = pfw_cfg->phys_port;
> + if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
> + beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
> + "BG_%d : invalid physical port id %d\n",
> + phba->fw_config.phys_

RE: [PATCH 03/15] be2iscsi: Fix to use atomic operations for tag_state

2015-12-20 Thread Jitendra Bhivare
Yep, there is a need for barrier when setting MCC_TAG_STATE_TIMEOUT.
I am sorry, was under the assumption that lock prefix would be used for
that atomic operation as well.

Thanks,

JB

-Original Message-
From: Mike Christie [mailto:micha...@cs.wisc.edu]
Sent: Sunday, December 20, 2015 3:44 PM
To: Jitendra Bhivare; linux-scsi@vger.kernel.org
Subject: Re: [PATCH 03/15] be2iscsi: Fix to use atomic operations for
tag_state

On 12/20/15 3:01 AM, Mike Christie wrote:
> On 12/20/2015 01:44 AM, Mike Christie wrote:
>
>>> diff --git a/drivers/scsi/be2iscsi/be_cmds.c
>>> b/drivers/scsi/be2iscsi/be_cmds.c index 6fabded..21c806f 100644
>>> --- a/drivers/scsi/be2iscsi/be_cmds.c
>>> +++ b/drivers/scsi/be2iscsi/be_cmds.c
>>> @@ -164,9 +164,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
>>> }
>>>
>>> /* Set MBX Tag state to Active */
>>> -   mutex_lock(>ctrl.mbox_lock);
>>> -   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
>>> -   mutex_unlock(>ctrl.mbox_lock);
>>> +   atomic_set(>ctrl.ptag_state[tag].tag_state,
>>> +   MCC_TAG_STATE_RUNNING);
>>>
>
>
> Is it possible for be_mcc_compl_process_isr to run before we have set
> the state to MCC_TAG_STATE_RUNNING, so the
> wait_event_interruptible_timeout call timesout?
>
>
>>> /* wait for the mccq completion */
>>> rc = wait_event_interruptible_timeout( @@ -178,9 +177,8 @@ int
>>> beiscsi_mccq_compl(struct beiscsi_hba *phba,
>>> if (rc <= 0) {
>>> struct be_dma_mem *tag_mem;
>>> /* Set MBX Tag state to timeout */
>>> -   mutex_lock(>ctrl.mbox_lock);
>>> -   phba->ctrl.ptag_state[tag].tag_state =
MCC_TAG_STATE_TIMEOUT;
>>> -   mutex_unlock(>ctrl.mbox_lock);
>>> +   atomic_set(>ctrl.ptag_state[tag].tag_state,
>>> +   MCC_TAG_STATE_TIMEOUT);
>>>
>>> /* Store resource addr to be freed later */
>>> tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
>>> @@ -199,9 +197,8 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
>>> } else {
>>> rc = 0;
>>> /* Set MBX Tag state to completed */
>>> -   mutex_lock(>ctrl.mbox_lock);
>>> -   phba->ctrl.ptag_state[tag].tag_state =
MCC_TAG_STATE_COMPLETED;
>>> -   mutex_unlock(>ctrl.mbox_lock);
>>> +   atomic_set(>ctrl.ptag_state[tag].tag_state,
>>> +   MCC_TAG_STATE_COMPLETED);
>>> }
>>>
>>> mcc_tag_response = phba->ctrl.mcc_numtag[tag]; @@ -373,9 +370,11
>>> @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
>>> ctrl->mcc_numtag[tag] |= (extd_status & 0x00FF) << 8;
>>> ctrl->mcc_numtag[tag] |= (compl_status & 0x00FF);
>>>
>>> -   if (ctrl->ptag_state[tag].tag_state == MCC_TAG_STATE_RUNNING) {
>>> +   if (atomic_read(>ptag_state[tag].tag_state) ==
>>> +   MCC_TAG_STATE_RUNNING) {
>>> wake_up_interruptible(>mcc_wait[tag]);
>>> -   } else if (ctrl->ptag_state[tag].tag_state ==
MCC_TAG_STATE_TIMEOUT) {
>>> +   } else if (atomic_read(>ptag_state[tag].tag_state) ==
>>> +   MCC_TAG_STATE_TIMEOUT) {
>>> struct be_dma_mem *tag_mem;
>>> tag_mem = >ptag_state[tag].tag_mem_state;
>>>
>>> @@ -390,9 +389,8 @@ int be_mcc_compl_process_isr(struct be_ctrl_info
*ctrl,
>>> tag_mem->va, tag_mem->dma);
>>>
>>> /* Change tag state */
>>> -   mutex_lock(>ctrl.mbox_lock);
>>> -   ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
>>> -   mutex_unlock(>ctrl.mbox_lock);
>>> +   atomic_set(>ptag_state[tag].tag_state,
>>> +   MCC_TAG_STATE_COMPLETED);
>>>
>>> /* Free MCC Tag */
>>> free_mcc_tag(ctrl, tag);
>>>
>>
>> I think if you only need to get and set a u8 then you can just use a
>> u8 since the operation will be atomic. No need for a atomic_t.
>
> I think you can ignore this. I think you would need some barriers in
> there too and it might be more complicated for no gain.
>

Ughhh. Sorry.

The atomic_ops.txt doc says atomic_read/atomic_set use still needs
barriers, so I guess they do not do anything for you and a u8 is ok.

The memory-barrier.txt doc says wake_up/wait calls have barriers if the
wake_up path is hit, so you are ok there.

However, besides the timeout issue in the previous mail, can
beiscsi_mccq_compl set the tag_mem_state to MCC_TAG_STATE_TIMEOUT and
be_mcc_compl_process_isr does not see the tag_mem values updated?
--
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 11/17] be2iscsi: Fix return value for MCC completion

2015-12-22 Thread Jitendra Bhivare
Change return value of completed MCC EBUSY to EINVAL.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 533060e..dbe62c0 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -323,7 +323,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
if (resp_hdr->response_length)
return 0;
}
-   return -EBUSY;
+   return -EINVAL;
}
return 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 v2 10/17] be2iscsi: Add FW config validation

2015-12-22 Thread Jitendra Bhivare
System crash in I+T card personality

Fix to add validation for ULP in initiator mode, physical port number,
and supported queue, icd, cid counts.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.c |   2 +-
 drivers/scsi/be2iscsi/be_main.h |   2 +
 drivers/scsi/be2iscsi/be_mgmt.c | 188 ++--
 3 files changed, 125 insertions(+), 67 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 8967e05..a665e6a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5670,6 +5670,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto free_port;
}
mgmt_get_port_name(>ctrl, phba);
+   beiscsi_get_params(phba);
 
if (enable_msix)
find_num_cpus(phba);
@@ -5687,7 +5688,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
}
 
phba->shost->max_id = phba->params.cxns_per_ctrl;
-   beiscsi_get_params(phba);
phba->shost->can_queue = phba->params.ios_per_ctrl;
ret = beiscsi_init_port(phba);
if (ret < 0) {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c09082a..f89861b 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -397,7 +397,9 @@ struct beiscsi_hba {
 * group together since they are used most frequently
 * for cid to cri conversion
 */
+#define BEISCSI_PHYS_PORT_MAX  4
unsigned int phys_port;
+   /* valid values of phys_port id are 0, 1, 2, 3 */
unsigned int eqid_count;
unsigned int cqid_count;
unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 10a8364..60140e2 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -373,90 +373,146 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
 {
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_fw_cfg *req = embedded_payload(wrb);
-   int status = 0;
+   struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
+   uint32_t cid_count, icd_count;
+   int status = -EINVAL;
+   uint8_t ulp_num = 0;
 
mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
+   be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
 
-   be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-
-   be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
+   be_cmd_hdr_prepare(_cfg->hdr, CMD_SUBSYSTEM_COMMON,
   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
   EMBED_MBX_MAX_PAYLOAD_SIZE);
-   status = be_mbox_notify(ctrl);
-   if (!status) {
-   uint8_t ulp_num = 0;
-   struct be_fw_cfg *pfw_cfg;
-   pfw_cfg = req;
 
-   if (!is_chip_be2_be3r(phba)) {
-   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
-   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (be_mbox_notify(ctrl)) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : Failed in mgmt_get_fw_config\n");
+   goto fail_init;
+   }
 
-   beiscsi_log(phba, KERN_INFO,
-   BEISCSI_LOG_INIT,
-   "BG_%d : EQ_Count : %d CQ_Count : %d\n",
-   phba->fw_config.eqid_count,
+   /* FW response formats depend on port id */
+   phba->fw_config.phys_port = pfw_cfg->phys_port;
+   if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid physical port id %d\n",
+   phba->fw_config.phys_port);
+   goto fail_init;
+   }
+
+   /* populate and check FW config against min and max values */
+   if (!is_chip_be2_be3r(phba)) {
+   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
+   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (phba->fw_config.eqid_count == 0 ||
+   phba->fw_config.eqid_count > 2048) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid EQ count %d\n",
+   phba->fw_config.eqid_count);
+   goto fail_init;
+   }
+   if (phba->fw_config.cqid_count == 0 ||
+   phba->fw_config.cqid_count >

[PATCH v2 04/17] be2iscsi: Fix to synchronize tag allocation using spin_lock

2015-12-22 Thread Jitendra Bhivare
alloc_mcc_tag/free_mcc_tag is now done under mcc_lock spin_lock

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1913e9e..db03149 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -121,6 +121,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
unsigned int tag = 0;
 
+   spin_lock(>ctrl.mcc_lock);
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
@@ -134,6 +135,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
else
phba->ctrl.mcc_alloc_index++;
}
+   spin_unlock(>ctrl.mcc_lock);
return tag;
 }
 
@@ -254,7 +256,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 {
-   spin_lock(>mbox_lock);
+   spin_lock(>mcc_lock);
tag = tag & 0x00FF;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
@@ -262,7 +264,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
-   spin_unlock(>mbox_lock);
+   spin_unlock(>mcc_lock);
 }
 
 bool is_link_state_evt(u32 trailer)
-- 
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 v2 09/17] be2iscsi: Fix to handle misconfigured optics events

2015-12-22 Thread Jitendra Bhivare
Log messages for misconfigured transceivers reported by FW.

Register async events that driver handles using MCC_CREATE_EXT ioctl.
Errors messages for faulted/uncertified/unqualified optics are logged.
Added IOCTL to get port_name to be displayed in error message.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 164 +---
 drivers/scsi/be2iscsi/be_cmds.h |  47 ++--
 drivers/scsi/be2iscsi/be_main.c |  19 +
 drivers/scsi/be2iscsi/be_main.h |  10 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |  42 ++
 drivers/scsi/be2iscsi/be_mgmt.h |   2 +
 6 files changed, 199 insertions(+), 85 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 66a1fc3..533060e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
spin_unlock(>mcc_lock);
 }
 
-bool is_link_state_evt(u32 trailer)
-{
-   return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_LINK_STATE);
-}
-
-static bool is_iscsi_evt(u32 trailer)
-{
-   return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_ISCSI;
-}
-
-static int iscsi_evt_type(u32 trailer)
-{
-   return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
-ASYNC_TRAILER_EVENT_TYPE_MASK;
-}
-
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
if (compl->flags != 0) {
@@ -425,7 +405,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
@@ -453,6 +433,100 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
}
 }
 
+static char *beiscsi_port_misconf_event_msg[] = {
+   "Physical Link is functional.",
+   "Optics faulted/incorrectly installed/not installed - Reseat optics, if 
issue not resolved, replace.",
+   "Optics of two types installed - Remove one optic or install matching 
pair of optics.",
+   "Incompatible optics - Replace with compatible optics for card to 
function.",
+   "Unqualified optics - Replace with Avago optics for Warranty and 
Technical Support.",
+   "Uncertified optics - Replace with Avago Certified optics to enable 
link operation."
+};
+
+static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
+ struct be_mcc_compl *compl)
+{
+   struct be_async_event_sli *async_sli;
+   u8 evt_type, state, old_state, le;
+   char *sev = KERN_WARNING;
+   char *msg = NULL;
+
+   evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
+   evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+   /* processing only MISCONFIGURED physical port event */
+   if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
+   return;
+
+   async_sli = (struct be_async_event_sli *)compl;
+   state = async_sli->event_data1 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+   le = async_sli->event_data2 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+
+   old_state = phba->optic_state;
+   phba->optic_state = state;
+
+   if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
+   /* fw is reporting a state we don't know, log and return */
+   __beiscsi_log(phba, KERN_ERR,
+   "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
+   phba->port_name, async_sli->event_data1);
+   return;
+   }
+
+   if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
+   /* log link effect for unqualified-4, uncertified-5 optics */
+   if (state > 3)
+   msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
+   " Link is non-operational." :
+   " Link is operational.";
+   /* 1 - info */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
+   sev = KERN_INFO;
+   /* 2 - error */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2)
+   sev = KERN_ERR;
+   }
+
+   if (old_state != phba->optic_state)
+   __beiscsi_log(ph

[PATCH v2 14/17] be2iscsi: Fix to process 25G link speed info from FW

2015-12-22 Thread Jitendra Bhivare
Async link event provides port_speed info. Cache the port_speed info
and use the same to report in ISCSI_HOST_PARAM_PORT_SPEED query.

Removed link status query IOCTL used to do the same.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  |  1 +
 drivers/scsi/be2iscsi/be_cmds.h  | 35 ++-
 drivers/scsi/be2iscsi/be_iscsi.c | 39 +--
 drivers/scsi/be2iscsi/be_main.h  |  1 +
 drivers/scsi/be2iscsi/be_mgmt.c  | 28 
 5 files changed, 21 insertions(+), 83 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 14a1c71..ce82f4d 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -408,6 +408,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
 static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
+   phba->port_speed = evt->port_speed;
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 724974e..a194066 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -153,12 +153,21 @@ struct be_async_event_link_state {
u8 physical_port;
u8 port_link_status;
u8 port_duplex;
+/* BE2ISCSI_LINK_SPEED_ZERO0x00 - no link */
+#define BE2ISCSI_LINK_SPEED_10MBPS 0x01
+#define BE2ISCSI_LINK_SPEED_100MBPS0x02
+#define BE2ISCSI_LINK_SPEED_1GBPS  0x03
+#define BE2ISCSI_LINK_SPEED_10GBPS 0x04
+#define BE2ISCSI_LINK_SPEED_25GBPS 0x06
+#define BE2ISCSI_LINK_SPEED_40GBPS 0x07
u8 port_speed;
 #define BEISCSI_PHY_LINK_FAULT_NONE0x00
 #define BEISCSI_PHY_LINK_FAULT_LOCAL   0x01
 #define BEISCSI_PHY_LINK_FAULT_REMOTE  0x02
u8 port_fault;
-   u8 rsvd0[7];
+   u8 event_reason;
+   u16 qos_link_speed;
+   u32 event_tag;
struct be_async_event_trailer trailer;
 } __packed;
 
@@ -711,29 +720,6 @@ struct be_cmd_hba_name {
u8 initiator_alias[BEISCSI_ALIAS_LEN];
 } __packed;
 
-struct be_cmd_ntwk_link_status_req {
-   struct be_cmd_req_hdr hdr;
-   u32 rsvd0;
-} __packed;
-
-/*** Port Speed Values ***/
-#define BE2ISCSI_LINK_SPEED_ZERO   0x00
-#define BE2ISCSI_LINK_SPEED_10MBPS 0x01
-#define BE2ISCSI_LINK_SPEED_100MBPS0x02
-#define BE2ISCSI_LINK_SPEED_1GBPS  0x03
-#define BE2ISCSI_LINK_SPEED_10GBPS 0x04
-struct be_cmd_ntwk_link_status_resp {
-   struct be_cmd_resp_hdr hdr;
-   u8 phys_port;
-   u8 mac_duplex;
-   u8 mac_speed;
-   u8 mac_fault;
-   u8 mgmt_mac_duplex;
-   u8 mgmt_mac_speed;
-   u16 qos_link_speed;
-   u32 logical_link_speed;
-} __packed;
-
 int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
  struct be_queue_info *eq, int eq_delay);
 
@@ -752,7 +738,6 @@ int be_poll_mcc(struct be_ctrl_info *ctrl);
 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
  struct beiscsi_hba *phba);
 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
-unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
 
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 3545721..a3bc5e4 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -766,34 +766,13 @@ static void beiscsi_get_port_state(struct Scsi_Host 
*shost)
  * beiscsi_get_port_speed  - Get the Port Speed from Adapter
  * @shost : pointer to scsi_host structure
  *
- * returns Success/Failure
  */
-static int beiscsi_get_port_speed(struct Scsi_Host *shost)
+static void beiscsi_get_port_speed(struct Scsi_Host *shost)
 {
-   int rc;
-   unsigned int tag;
-   struct be_mcc_wrb *wrb;
-   struct be_cmd_ntwk_link_status_resp *resp;
struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct iscsi_cls_host *ihost = shost->shost_data;
 
-   tag = be_cmd_get_port_speed(phba);
-   if (!tag) {
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
-   "BS_%d : Getting Port Speed Failed\n");
-
-return -EBUSY;
-   }
-   rc = beiscsi_mccq_compl(phba, tag, , NULL);
-   if (rc) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BS_%d : Port Speed MBX Failed\n");
-   return rc;
-   }
-   resp = embedded_payload(wrb);
-
-   switch (resp->mac_speed) {
+   switch (phba->port_speed) {
case

[PATCH v2 17/17] be2iscsi: Update the driver version

2015-12-22 Thread Jitendra Bhivare
Driver version: 11.0.0.0

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 41c708c..16a6fd0 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -36,7 +36,7 @@
 #include 
 
 #define DRV_NAME   "be2iscsi"
-#define BUILD_STR  "10.6.0.1"
+#define BUILD_STR  "11.0.0.0"
 #define BE_NAME"Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC   BE_NAME " " "Driver"
-- 
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 v2 13/17] scsi_transport_iscsi: Add 25G and 40G speed definition

2015-12-22 Thread Jitendra Bhivare
iscsi_port_speed and iscsi_port_speed_names have new entries for
25Gbps and 40Gbps link speeds.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/scsi_transport_iscsi.c | 2 ++
 include/scsi/iscsi_if.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index e4b3d8f..4414816 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -4308,6 +4308,8 @@ static const struct {
{ISCSI_PORT_SPEED_100MBPS,  "100 Mbps" },
{ISCSI_PORT_SPEED_1GBPS,"1 Gbps" },
{ISCSI_PORT_SPEED_10GBPS,   "10 Gbps" },
+   {ISCSI_PORT_SPEED_25GBPS,   "25 Gbps" },
+   {ISCSI_PORT_SPEED_40GBPS,   "40 Gbps" },
 };
 
 char *iscsi_get_port_speed_name(struct Scsi_Host *shost)
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 95ed942..d66c070 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -724,6 +724,8 @@ enum iscsi_port_speed {
ISCSI_PORT_SPEED_100MBPS= 0x4,
ISCSI_PORT_SPEED_1GBPS  = 0x8,
ISCSI_PORT_SPEED_10GBPS = 0x10,
+   ISCSI_PORT_SPEED_25GBPS = 0x20,
+   ISCSI_PORT_SPEED_40GBPS = 0x40,
 };
 
 /* iSCSI 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 v2 08/17] be2iscsi: Fix VLAN support for IPv6 network

2015-12-22 Thread Jitendra Bhivare
Configuring VLAN parameters through IPv6 interface was not supported in driver.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_iscsi.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 188d83f..c89a025 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -466,6 +466,10 @@ beiscsi_set_ipv6(struct Scsi_Host *shost,
ret = mgmt_set_ip(phba, iface_param, NULL,
  ISCSI_BOOTPROTO_STATIC);
break;
+   case ISCSI_NET_PARAM_VLAN_ENABLED:
+   case ISCSI_NET_PARAM_VLAN_TAG:
+   ret = beiscsi_set_vlan_tag(shost, iface_param);
+   break;
default:
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Param %d not supported\n",
-- 
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 v2 12/17] be2iscsi: Fix IOPOLL implementation

2015-12-22 Thread Jitendra Bhivare
OS not responding when running 2 port traffic on 72 CPUs system.

be2iscsi IRQs gets affined to CPU0 when irqbalancer is disabled.
be_iopoll processing completions in BLOCK_IOPOLL_SOFTIRQ hogged CPU0.

1. Use budget to exit the polling loop. beiscsi_process_cq didn't honour it.
2. Rearming of EQ is done only after iopoll completes.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  |  2 +-
 drivers/scsi/be2iscsi/be_iscsi.c |  2 +-
 drivers/scsi/be2iscsi/be_main.c  | 91 ++--
 drivers/scsi/be2iscsi/be_main.h  |  5 ++-
 4 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index dbe62c0..14a1c71 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -546,7 +546,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
}
 
if (num)
-   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1, 0);
+   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c89a025..3545721 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1298,7 +1298,7 @@ static void beiscsi_flush_cq(struct beiscsi_hba *phba)
for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = _context->be_eq[i];
blk_iopoll_disable(_eq->iopoll);
-   beiscsi_process_cq(pbe_eq);
+   beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
blk_iopoll_enable(_eq->iopoll);
}
 }
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index a665e6a..9a86044 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -895,32 +895,21 @@ static irqreturn_t be_isr_mcc(int irq, void *dev_id)
 static irqreturn_t be_isr_msix(int irq, void *dev_id)
 {
struct beiscsi_hba *phba;
-   struct be_eq_entry *eqe = NULL;
struct be_queue_info *eq;
-   struct be_queue_info *cq;
-   unsigned int num_eq_processed;
struct be_eq_obj *pbe_eq;
 
pbe_eq = dev_id;
eq = _eq->q;
-   cq = pbe_eq->cq;
-   eqe = queue_tail_node(eq);
 
phba = pbe_eq->phba;
-   num_eq_processed = 0;
-   while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-   & EQE_VALID_MASK) {
-   if (!blk_iopoll_sched_prep(_eq->iopoll))
-   blk_iopoll_sched(_eq->iopoll);
-
-   AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-   queue_tail_inc(eq);
-   eqe = queue_tail_node(eq);
-   num_eq_processed++;
-   }
-
-   if (num_eq_processed)
-   hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
+   /* disable interrupt till iopoll completes */
+   hwi_ring_eq_db(phba, eq->id, 1, 0, 0, 1);
+   if (!blk_iopoll_sched_prep(_eq->iopoll))
+   blk_iopoll_sched(_eq->iopoll);
+   else
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO,
+   "BM_%d: received event while polling eq %d cq %d\n",
+   eq->id, pbe_eq->cq->id);
 
return IRQ_HANDLED;
 }
@@ -998,6 +987,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
struct pci_dev *pcidev = phba->pcidev;
@@ -1072,7 +1062,7 @@ free_msix_irqs:
 
 void hwi_ring_cq_db(struct beiscsi_hba *phba,
   unsigned int id, unsigned int num_processed,
-  unsigned char rearm, unsigned char event)
+  unsigned char rearm)
 {
u32 val = 0;
 
@@ -2044,7 +2034,7 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
 
if (num_processed >= 32) {
hwi_ring_cq_db(phba, mcc_cq->id,
-   num_processed, 0, 0);
+   num_processed, 0);
num_processed = 0;
}
if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
@@ -2062,24 +2052,25 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
}
 
if (num_processed > 0)
-   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
+   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1);
 
 }
 
 /**
  * beiscsi_process_cq()- Process the Completion Queue
  * @pbe_eq: Event Q on which the Completion has come
+ * @budget: Max number of events to processed
  *
  * return
  * Numb

[PATCH v2 07/17] be2iscsi: Fix to remove shutdown entry point

2015-12-22 Thread Jitendra Bhivare
Null pointer dereference in shutdown path after taking dump.

Shutdown path is not needed as FW comes up clean every time during probe
after issuing FUNCTION reset MBOX command.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 17 +++--
 drivers/scsi/be2iscsi/be_cmds.h |  2 +-
 drivers/scsi/be2iscsi/be_main.c | 24 
 drivers/scsi/be2iscsi/be_main.h |  3 +--
 4 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f93ab6d..66a1fc3 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -417,22 +417,11 @@ static struct be_mcc_compl *be_mcc_compl_get(struct 
beiscsi_hba *phba)
 }
 
 /**
- * be2iscsi_fail_session(): Closing session with appropriate error
+ * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
- *
- * Depending on adapter state appropriate error flag is passed.
  **/
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
 {
-   struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-   struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   uint32_t iscsi_err_flag;
-
-   if (phba->state & BE_ADAPTER_STATE_SHUTDOWN)
-   iscsi_err_flag = ISCSI_ERR_INVALID_HOST;
-   else
-   iscsi_err_flag = ISCSI_ERR_CONN_FAILED;
-
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
@@ -450,7 +439,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
evt->physical_port);
 
iscsi_host_for_each_session(phba->shost,
-   be2iscsi_fail_session);
+   beiscsi_fail_session);
} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 1883d32..f988164 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -1367,5 +1367,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int 
payload_len,
 void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
u8 subsystem, u8 opcode, int cmd_len);
 
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session);
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session);
 #endif /* !BEISCSI_CMDS_H */
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 61ce86b..2f3e118 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5315,7 +5315,6 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
 
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
-
struct beiscsi_hba *phba = NULL;
 
phba = pci_get_drvdata(pcidev);
@@ -5325,9 +5324,9 @@ static void beiscsi_remove(struct pci_dev *pcidev)
}
 
beiscsi_destroy_def_ifaces(phba);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
iscsi_boot_destroy_kset(phba->boot_kset);
iscsi_host_remove(phba->shost);
+   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
pci_disable_pcie_error_reporting(pcidev);
@@ -5336,23 +5335,6 @@ static void beiscsi_remove(struct pci_dev *pcidev)
pci_disable_device(pcidev);
 }
 
-static void beiscsi_shutdown(struct pci_dev *pcidev)
-{
-
-   struct beiscsi_hba *phba = NULL;
-
-   phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
-   if (!phba) {
-   dev_err(>dev, "beiscsi_shutdown called with no phba\n");
-   return;
-   }
-
-   phba->state = BE_ADAPTER_STATE_SHUTDOWN;
-   iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
-   pci_disable_device(pcidev);
-}
-
 static void beiscsi_msix_enable(struct beiscsi_hba *phba)
 {
int i, status;
@@ -5673,6 +5655,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto hba_free;
}
 
+   /*
+* FUNCTION_RESET should clean up any stale info in FW for this fn
+*/
ret = beiscsi_cmd_reset_function(phba);
if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5861,7 +5846,6 @@ static struct pci_driver beiscsi_pci_driver = {
.name = DRV_NAME,
.probe = beiscsi_dev_probe,
.remove = beiscsi_remove,
-   .shutdown = beiscsi_shutdown,
.id_table = beiscsi_pci_id_table,
.err_han

[PATCH v2 02/17] be2iscsi: Fix mbox synchronization replacing spinlock with mutex

2015-12-22 Thread Jitendra Bhivare
This is second part of actual fix for soft lockup.

All mbox cmds issued using BMBX and MCC are synchronized using mutex
mbox_lock instead of spin_lock. Used mutex_lock_interruptible where
ever possible.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  |   2 +-
 drivers/scsi/be2iscsi/be_cmds.c |  73 ++--
 drivers/scsi/be2iscsi/be_main.c |   2 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 105 +---
 4 files changed, 94 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 77f992e..cf19bce 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -124,7 +124,7 @@ struct be_ctrl_info {
struct pci_dev *pdev;
 
/* Mbox used for cmd request/response */
-   spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
+   struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
 * is stored for freeing purpose */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cd50e3c..6fabded 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -164,9 +164,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
/* Set MBX Tag state to Active */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -178,9 +178,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (rc <= 0) {
struct be_dma_mem *tag_mem;
/* Set MBX Tag state to timeout */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Store resource addr to be freed later */
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
@@ -199,9 +199,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else {
rc = 0;
/* Set MBX Tag state to completed */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
}
 
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
@@ -390,9 +390,9 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
tag_mem->va, tag_mem->dma);
 
/* Change tag state */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Free MCC Tag */
free_mcc_tag(ctrl, tag);
@@ -831,7 +831,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem = >dma_mem;
int status;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -858,7 +858,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
eq->id = le16_to_cpu(resp->eq_id);
eq->created = true;
}
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -879,7 +879,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -898,7 +898,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BC_%d : be_cmd_fw_initialize Failed\n");
 
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -919,7 +919,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -939,7 +939,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,

[PATCH v2 00/17] be2iscsi: driver update 11.0.0.0

2015-12-22 Thread Jitendra Bhivare
This patch is generated against for-next branch.

Jitendra Bhivare (17):
  be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx
  be2iscsi: Fix mbox synchronization replacing spinlock with mutex
  be2iscsi: Fix to synchronize tag allocation using spin_lock
  be2iscsi: Set mbox timeout to 30s
  be2iscsi: Added return value check for mgmt_get_all_if_id
  be2iscsi: Fix to remove shutdown entry point
  be2iscsi: Fix VLAN support for IPv6 network
  be2iscsi: Fix to handle misconfigured optics events
  be2iscsi: Fix return value for MCC completion
  be2iscsi: Fix IOPOLL implementation
  be2iscsi: Fix WRB leak in login/logout path
  be2iscsi: Update the driver version

  be2iscsi: Fix to use atomic bit operations for tag_state
  be2iscsi: Add FW config validation
  scsi_transport_iscsi: Add 25G and 40G speed definition
  be2iscsi: Fix to process 25G link speed info from FW
  be2iscsi: Fix async link event processing

 drivers/scsi/be2iscsi/be.h  |   9 +-
 drivers/scsi/be2iscsi/be_cmds.c | 453 +++-
 drivers/scsi/be2iscsi/be_cmds.h | 118 +-
 drivers/scsi/be2iscsi/be_iscsi.c|  54 ++---
 drivers/scsi/be2iscsi/be_main.c | 210 +
 drivers/scsi/be2iscsi/be_main.h |  23 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 425 -
 drivers/scsi/be2iscsi/be_mgmt.h |   2 +
 drivers/scsi/scsi_transport_iscsi.c |   2 +
 include/scsi/iscsi_if.h |   2 +
 10 files changed, 720 insertions(+), 578 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 v2 01/17] be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx

2015-12-22 Thread Jitendra Bhivare
We are taking mbox_lock spinlock which disables pre-emption before we poll
for mbox completion. Waiting there with spinlock held in excess of 20s will
cause soft lockup.

Actual fix is to change mbox_lock to mutex.
The changes are done in phases. This is the first part.
1. Changed mgmt_get_all_if_id to use MCC where after posting lock is released.
2. Changed be_mbox_db_ready_wait to busy wait for 12s max and removed
wait_event_timeout. Added error handling code for IO reads.
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG mbox command takes 8s time when unreachable
boot targets configured.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 60 -
 drivers/scsi/be2iscsi/be_mgmt.c | 32 +++---
 2 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 2778089..cd50e3c 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -587,47 +587,42 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT4000/* 4sec */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
-   bool read_flag = false;
-   int ret = 0, i;
u32 ready;
-   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);
 
-   if (beiscsi_error(phba))
-   return -EIO;
+   /*
+* This BMBX busy wait path is used during init only.
+* For the commands executed during init, 5s should suffice.
+*/
+   timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
+   do {
+   if (beiscsi_error(phba))
+   return -EIO;
 
-   timeout = jiffies + (HZ * 110);
+   ready = ioread32(db);
+   if (ready == 0x)
+   return -EIO;
 
-   do {
-   for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
-   ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
-   if (ready) {
-   read_flag = true;
-   break;
-   }
-   mdelay(1);
-   }
+   ready &= MPU_MAILBOX_DB_RDY_MASK;
+   if (ready)
+   return 0;
 
-   if (!read_flag) {
-   wait_event_timeout(rdybit_check_q,
- (read_flag != true),
-  HZ * 5);
-   }
-   } while ((time_before(jiffies, timeout)) && !read_flag);
+   if (time_after(jiffies, timeout))
+   break;
+   mdelay(1);
+   } while (!ready);
 
-   if (!read_flag) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : FW Timed Out\n");
-   phba->fw_timeout = true;
-   beiscsi_ue_detect(phba);
-   ret = -EBUSY;
-   }
+   beiscsi_log(phba, KERN_ERR,
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : FW Timed Out\n");
 
-   return ret;
+   phba->fw_timeout = true;
+   beiscsi_ue_detect(phba);
+
+   return -EBUSY;
 }
 
 /*
@@ -674,6 +669,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
if (status)
return status;
 
+   /* RDY is set; small delay before CQE read. */
+   udelay(1);
+
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, >compl);
be_mcc_compl_use(compl);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index aea3e6b..7b54b23 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -809,27 +809,39 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
 {
struct be_ctrl_info *ctrl = >ctrl;
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
-   struct be_cmd_get_all_if_id_req *pbe_allid = req;
+   struct be_mcc_wrb *wrb;
+   struct be_cmd_get_all_if_id_req *req;
+   struct be_cmd_get_all_if_id_req *pbe_allid;
+   unsigned int tag;
int status = 0;
 
-   memset(wrb, 0, sizeof(*wrb));
-
spin_lock(>mbox_lock);
+   tag = alloc_mcc_tag(phba);
+   if (!tag) {
+   spin_unlock(>mbox_lock)

[PATCH v2 06/17] be2iscsi: Added return value check for mgmt_get_all_if_id

2015-12-22 Thread Jitendra Bhivare
Use of mutex_lock_interruptible can return -EINTR, handle and log
the error.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_iscsi.c |  7 ---
 drivers/scsi/be2iscsi/be_mgmt.c  | 10 ++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index b7087ba..188d83f 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -367,13 +367,14 @@ beiscsi_set_vlan_tag(struct Scsi_Host *shost,
  struct iscsi_iface_param_info *iface_param)
 {
struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   int ret = 0;
+   int ret;
 
/* Get the Interface Handle */
-   if (mgmt_get_all_if_id(phba)) {
+   ret = mgmt_get_all_if_id(phba);
+   if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Getting Interface Handle Failed\n");
-   return -EIO;
+   return ret;
}
 
switch (iface_param->param) {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 6ef5285..9268a70 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1024,8 +1024,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
uint32_t ip_type;
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
BE2_IPV6 : BE2_IPV4 ;
@@ -1194,8 +1195,9 @@ int mgmt_get_if_info(struct beiscsi_hba *phba, int 
ip_type,
uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
do {
rc = mgmt_alloc_cmd_data(phba, _cmd,
-- 
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 v2 15/17] be2iscsi: Fix async link event processing

2015-12-22 Thread Jitendra Bhivare
Use only port_link_status only to determine link state change.
Only bit 0 is used to get the state.
Remove code for processing port_fault.

Fixed get_nic_conf structure definition. Removed rsvd[23] field in
be_cmd_get_nic_conf_resp.

Moved defintions of struct field values below the field.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  | 48 +++-
 drivers/scsi/be2iscsi/be_cmds.h  | 32 +--
 drivers/scsi/be2iscsi/be_iscsi.c |  2 +-
 3 files changed, 34 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index ce82f4d..34c33d4 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -405,32 +405,31 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
-   struct be_async_event_link_state *evt)
+static void beiscsi_process_async_link(struct beiscsi_hba *phba,
+  struct be_mcc_compl *compl)
 {
-   phba->port_speed = evt->port_speed;
-   if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
-   phba->state = BE_ADAPTER_LINK_DOWN;
+   struct be_async_event_link_state *evt;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link Down on Port %d\n",
-   evt->physical_port);
+   evt = (struct be_async_event_link_state *)compl;
 
-   iscsi_host_for_each_session(phba->shost,
-   beiscsi_fail_session);
-   } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
+   phba->port_speed = evt->port_speed;
+   /**
+* Check logical link status in ASYNC event.
+* This has been newly introduced in SKH-R Firmware 10.0.338.45.
+**/
+   if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
-
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link UP on Port %d\n",
-   evt->physical_port);
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Up on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   } else {
+   phba->state = BE_ADAPTER_LINK_DOWN;
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Down on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   iscsi_host_for_each_session(phba->shost,
+   beiscsi_fail_session);
}
 }
 
@@ -507,8 +506,7 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
switch (evt_code) {
case ASYNC_EVENT_CODE_LINK_STATE:
-   beiscsi_async_link_state_process(phba,
-   (struct be_async_event_link_state *)compl);
+   beiscsi_process_async_link(phba, compl);
break;
case ASYNC_EVENT_CODE_ISCSI:
phba->state |= BE_ADAPTER_CHECK_BOOT;
@@ -524,8 +522,8 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
}
 
beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : ASYNC Event: status 0x%08x flags 0x%08x\n",
-   compl->status, compl->flags);
+   "BC_%d : ASYNC Event %x: status 0x%08x flags 0x%08x\n",
+   evt_code, compl->status, compl->flags);
 }
 
 int beiscsi_process_mcc(struct beiscsi_hba *phba)
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index a194066..7caf585 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -142,7 +142,6 @@ struct be_async_event_trailer {
 enum {
ASYNC_EVENT_LINK_DOWN = 0x0,
ASYNC_EVENT_LINK_UP = 0x1,
-   ASYNC_EVENT_LOGICAL = 0x2
 };
 
 /**
@@ -152,7 +151,15 @@ enum {
 struct be_async_event_link_state {
u8 physical_port;
u8 port_link

[PATCH v2 05/17] be2iscsi: Set mbox timeout to 30s

2015-12-22 Thread Jitendra Bhivare
FW recommended timeout for all mbox command is 30s.
Use msleep instead mdelay to relinquish CPU when polling for
mbox completion.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index db03149..f93ab6d 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -590,7 +590,8 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba, unsigned 
int tag)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
+   /* wait 30s for generic non-flash MBOX operation */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT3
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
@@ -615,7 +616,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 
if (time_after(jiffies, timeout))
break;
-   mdelay(1);
+   msleep(20);
} while (!ready);
 
beiscsi_log(phba, KERN_ERR,
-- 
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 v2 16/17] be2iscsi: Fix WRB leak in login/logout path

2015-12-22 Thread Jitendra Bhivare
Login/Logout loop was hanging after few hours. /var/log/message showed
that alloc_wrb_handle() function was not able to allocate any new WRB.

Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not send nopout
Sep 11 11:25:22 Jhelum10 kernel: scsi host10: BM_4989 : Alloc of WRB_HANDLE
Failedfor the CID : 384
Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not allocate pdu for
mgmt task.

Driver allocates WRB to pass login negotiated parameters information to FW
in beiscsi_offload_connection(). This allocated WRB was not freed so there
was WRB_Leak happening.

Put WRB used for posting the login-negotiated parameters back in pool.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_main.c | 72 -
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 9a86044..d8cdb4e 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1184,6 +1184,22 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index++;
 }
 
+static inline struct wrb_handle *
+beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  unsigned int wrbs_per_cxn)
+{
+   struct wrb_handle *pwrb_handle;
+
+   pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
+   pwrb_context->wrb_handles_available--;
+   if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
+   pwrb_context->alloc_index = 0;
+   else
+   pwrb_context->alloc_index++;
+
+   return pwrb_handle;
+}
+
 /**
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
@@ -1193,30 +1209,30 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
  * This happens under session_lock until submission to chip
  */
 struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-struct hwi_wrb_context **pcontext)
+   struct hwi_wrb_context **pcontext)
 {
struct hwi_wrb_context *pwrb_context;
struct hwi_controller *phwi_ctrlr;
-   struct wrb_handle *pwrb_handle;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = _ctrlr->wrb_context[cri_index];
-   if (pwrb_context->wrb_handles_available >= 2) {
-   pwrb_handle = pwrb_context->pwrb_handle_base[
-   pwrb_context->alloc_index];
-   pwrb_context->wrb_handles_available--;
-   if (pwrb_context->alloc_index ==
-   (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->alloc_index = 0;
-   else
-   pwrb_context->alloc_index++;
+   /* return the context address */
+   *pcontext = pwrb_context;
+   return beiscsi_get_wrb_handle(pwrb_context, phba->params.wrbs_per_cxn);
+}
 
-   /* Return the context address */
-   *pcontext = pwrb_context;
-   } else
-   pwrb_handle = NULL;
-   return pwrb_handle;
+static inline void
+beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  struct wrb_handle *pwrb_handle,
+  unsigned int wrbs_per_cxn)
+{
+   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
+   pwrb_context->wrb_handles_available++;
+   if (pwrb_context->free_index == (wrbs_per_cxn - 1))
+   pwrb_context->free_index = 0;
+   else
+   pwrb_context->free_index++;
 }
 
 /**
@@ -1231,13 +1247,9 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
struct wrb_handle *pwrb_handle)
 {
-   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
-   pwrb_context->wrb_handles_available++;
-   if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->free_index = 0;
-   else
-   pwrb_context->free_index++;
-
+   beiscsi_put_wrb_handle(pwrb_context,
+  pwrb_handle,
+  phba->params.wrbs_per_cxn);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
"BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
@@ -4715,6 +4727,20 @@ beiscsi_offload_connection(struct beiscsi_conn 
*beiscsi_conn,
doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
iowrite32(doorbell, phba->db_va +
  beiscsi_conn->doorbell_offset);
+
+  

[PATCH v3 11/17] be2iscsi: Fix return value for MCC completion

2015-12-23 Thread Jitendra Bhivare
Change return value of completed MCC EBUSY to EINVAL.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index d69fb0a..1e6a1b6 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -323,7 +323,7 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
if (resp_hdr->response_length)
return 0;
}
-   return -EBUSY;
+   return -EINVAL;
}
return 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 v3 07/17] be2iscsi: Fix to remove shutdown entry point

2015-12-23 Thread Jitendra Bhivare
Null pointer dereference in shutdown path after taking dump.

Shutdown path is not needed as FW comes up clean every time during probe
after issuing FUNCTION reset MBOX command.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 17 +++--
 drivers/scsi/be2iscsi/be_cmds.h |  2 +-
 drivers/scsi/be2iscsi/be_main.c | 24 
 drivers/scsi/be2iscsi/be_main.h |  3 +--
 4 files changed, 9 insertions(+), 37 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 034b868..705215e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -417,22 +417,11 @@ static struct be_mcc_compl *be_mcc_compl_get(struct 
beiscsi_hba *phba)
 }
 
 /**
- * be2iscsi_fail_session(): Closing session with appropriate error
+ * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
- *
- * Depending on adapter state appropriate error flag is passed.
  **/
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session)
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
 {
-   struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
-   struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   uint32_t iscsi_err_flag;
-
-   if (phba->state & BE_ADAPTER_STATE_SHUTDOWN)
-   iscsi_err_flag = ISCSI_ERR_INVALID_HOST;
-   else
-   iscsi_err_flag = ISCSI_ERR_CONN_FAILED;
-
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
@@ -450,7 +439,7 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
evt->physical_port);
 
iscsi_host_for_each_session(phba->shost,
-   be2iscsi_fail_session);
+   beiscsi_fail_session);
} else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 1883d32..f988164 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -1367,5 +1367,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int 
payload_len,
 void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
u8 subsystem, u8 opcode, int cmd_len);
 
-void be2iscsi_fail_session(struct iscsi_cls_session *cls_session);
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session);
 #endif /* !BEISCSI_CMDS_H */
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 61ce86b..2f3e118 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5315,7 +5315,6 @@ static void beiscsi_quiesce(struct beiscsi_hba *phba,
 
 static void beiscsi_remove(struct pci_dev *pcidev)
 {
-
struct beiscsi_hba *phba = NULL;
 
phba = pci_get_drvdata(pcidev);
@@ -5325,9 +5324,9 @@ static void beiscsi_remove(struct pci_dev *pcidev)
}
 
beiscsi_destroy_def_ifaces(phba);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
iscsi_boot_destroy_kset(phba->boot_kset);
iscsi_host_remove(phba->shost);
+   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
pci_dev_put(phba->pcidev);
iscsi_host_free(phba->shost);
pci_disable_pcie_error_reporting(pcidev);
@@ -5336,23 +5335,6 @@ static void beiscsi_remove(struct pci_dev *pcidev)
pci_disable_device(pcidev);
 }
 
-static void beiscsi_shutdown(struct pci_dev *pcidev)
-{
-
-   struct beiscsi_hba *phba = NULL;
-
-   phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
-   if (!phba) {
-   dev_err(>dev, "beiscsi_shutdown called with no phba\n");
-   return;
-   }
-
-   phba->state = BE_ADAPTER_STATE_SHUTDOWN;
-   iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
-   beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
-   pci_disable_device(pcidev);
-}
-
 static void beiscsi_msix_enable(struct beiscsi_hba *phba)
 {
int i, status;
@@ -5673,6 +5655,9 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto hba_free;
}
 
+   /*
+* FUNCTION_RESET should clean up any stale info in FW for this fn
+*/
ret = beiscsi_cmd_reset_function(phba);
if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -5861,7 +5846,6 @@ static struct pci_driver beiscsi_pci_driver = {
.name = DRV_NAME,
.probe = beiscsi_dev_probe,
.remove = beiscsi_remove,
-   .shutdown = beiscsi_shutdown,
.id_table = beiscsi_pci_id_table,
.err_han

[PATCH v3 10/17] be2iscsi: Add FW config validation

2015-12-23 Thread Jitendra Bhivare
System crash in I+T card personality

Fix to add validation for ULP in initiator mode, physical port number,
and supported queue, icd, cid counts.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.c |   2 +-
 drivers/scsi/be2iscsi/be_main.h |   2 +
 drivers/scsi/be2iscsi/be_mgmt.c | 188 ++--
 3 files changed, 125 insertions(+), 67 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 8967e05..a665e6a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -5670,6 +5670,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
goto free_port;
}
mgmt_get_port_name(>ctrl, phba);
+   beiscsi_get_params(phba);
 
if (enable_msix)
find_num_cpus(phba);
@@ -5687,7 +5688,6 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
}
 
phba->shost->max_id = phba->params.cxns_per_ctrl;
-   beiscsi_get_params(phba);
phba->shost->can_queue = phba->params.ios_per_ctrl;
ret = beiscsi_init_port(phba);
if (ret < 0) {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index c09082a..f89861b 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -397,7 +397,9 @@ struct beiscsi_hba {
 * group together since they are used most frequently
 * for cid to cri conversion
 */
+#define BEISCSI_PHYS_PORT_MAX  4
unsigned int phys_port;
+   /* valid values of phys_port id are 0, 1, 2, 3 */
unsigned int eqid_count;
unsigned int cqid_count;
unsigned int iscsi_cid_start[BEISCSI_ULP_COUNT];
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 5aae153..3eea8b8 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -373,90 +373,146 @@ int mgmt_get_fw_config(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba)
 {
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_fw_cfg *req = embedded_payload(wrb);
-   int status = 0;
+   struct be_fw_cfg *pfw_cfg = embedded_payload(wrb);
+   uint32_t cid_count, icd_count;
+   int status = -EINVAL;
+   uint8_t ulp_num = 0;
 
mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
+   be_wrb_hdr_prepare(wrb, sizeof(*pfw_cfg), true, 0);
 
-   be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-
-   be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
+   be_cmd_hdr_prepare(_cfg->hdr, CMD_SUBSYSTEM_COMMON,
   OPCODE_COMMON_QUERY_FIRMWARE_CONFIG,
   EMBED_MBX_MAX_PAYLOAD_SIZE);
-   status = be_mbox_notify(ctrl);
-   if (!status) {
-   uint8_t ulp_num = 0;
-   struct be_fw_cfg *pfw_cfg;
-   pfw_cfg = req;
 
-   if (!is_chip_be2_be3r(phba)) {
-   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
-   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (be_mbox_notify(ctrl)) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : Failed in mgmt_get_fw_config\n");
+   goto fail_init;
+   }
 
-   beiscsi_log(phba, KERN_INFO,
-   BEISCSI_LOG_INIT,
-   "BG_%d : EQ_Count : %d CQ_Count : %d\n",
-   phba->fw_config.eqid_count,
+   /* FW response formats depend on port id */
+   phba->fw_config.phys_port = pfw_cfg->phys_port;
+   if (phba->fw_config.phys_port >= BEISCSI_PHYS_PORT_MAX) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid physical port id %d\n",
+   phba->fw_config.phys_port);
+   goto fail_init;
+   }
+
+   /* populate and check FW config against min and max values */
+   if (!is_chip_be2_be3r(phba)) {
+   phba->fw_config.eqid_count = pfw_cfg->eqid_count;
+   phba->fw_config.cqid_count = pfw_cfg->cqid_count;
+   if (phba->fw_config.eqid_count == 0 ||
+   phba->fw_config.eqid_count > 2048) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
+   "BG_%d : invalid EQ count %d\n",
+   phba->fw_config.eqid_count);
+   goto fail_init;
+   }
+   if (phba->fw_config.cqid_count == 0 ||
+   phba->fw_config.cqid_count >

[PATCH v3 14/17] be2iscsi: Fix to process 25G link speed info from FW

2015-12-23 Thread Jitendra Bhivare
Async link event provides port_speed info. Cache the port_speed info
and use the same to report in ISCSI_HOST_PARAM_PORT_SPEED query.

Removed link status query IOCTL used to do the same.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  |  1 +
 drivers/scsi/be2iscsi/be_cmds.h  | 35 ++-
 drivers/scsi/be2iscsi/be_iscsi.c | 39 +--
 drivers/scsi/be2iscsi/be_main.h  |  1 +
 drivers/scsi/be2iscsi/be_mgmt.c  | 28 
 5 files changed, 21 insertions(+), 83 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index b294e54..cd14d26 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -408,6 +408,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
 static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
+   phba->port_speed = evt->port_speed;
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
 (evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 724974e..a194066 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -153,12 +153,21 @@ struct be_async_event_link_state {
u8 physical_port;
u8 port_link_status;
u8 port_duplex;
+/* BE2ISCSI_LINK_SPEED_ZERO0x00 - no link */
+#define BE2ISCSI_LINK_SPEED_10MBPS 0x01
+#define BE2ISCSI_LINK_SPEED_100MBPS0x02
+#define BE2ISCSI_LINK_SPEED_1GBPS  0x03
+#define BE2ISCSI_LINK_SPEED_10GBPS 0x04
+#define BE2ISCSI_LINK_SPEED_25GBPS 0x06
+#define BE2ISCSI_LINK_SPEED_40GBPS 0x07
u8 port_speed;
 #define BEISCSI_PHY_LINK_FAULT_NONE0x00
 #define BEISCSI_PHY_LINK_FAULT_LOCAL   0x01
 #define BEISCSI_PHY_LINK_FAULT_REMOTE  0x02
u8 port_fault;
-   u8 rsvd0[7];
+   u8 event_reason;
+   u16 qos_link_speed;
+   u32 event_tag;
struct be_async_event_trailer trailer;
 } __packed;
 
@@ -711,29 +720,6 @@ struct be_cmd_hba_name {
u8 initiator_alias[BEISCSI_ALIAS_LEN];
 } __packed;
 
-struct be_cmd_ntwk_link_status_req {
-   struct be_cmd_req_hdr hdr;
-   u32 rsvd0;
-} __packed;
-
-/*** Port Speed Values ***/
-#define BE2ISCSI_LINK_SPEED_ZERO   0x00
-#define BE2ISCSI_LINK_SPEED_10MBPS 0x01
-#define BE2ISCSI_LINK_SPEED_100MBPS0x02
-#define BE2ISCSI_LINK_SPEED_1GBPS  0x03
-#define BE2ISCSI_LINK_SPEED_10GBPS 0x04
-struct be_cmd_ntwk_link_status_resp {
-   struct be_cmd_resp_hdr hdr;
-   u8 phys_port;
-   u8 mac_duplex;
-   u8 mac_speed;
-   u8 mac_fault;
-   u8 mgmt_mac_duplex;
-   u8 mgmt_mac_speed;
-   u16 qos_link_speed;
-   u32 logical_link_speed;
-} __packed;
-
 int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
  struct be_queue_info *eq, int eq_delay);
 
@@ -752,7 +738,6 @@ int be_poll_mcc(struct be_ctrl_info *ctrl);
 int mgmt_check_supported_fw(struct be_ctrl_info *ctrl,
  struct beiscsi_hba *phba);
 unsigned int be_cmd_get_initname(struct beiscsi_hba *phba);
-unsigned int be_cmd_get_port_speed(struct beiscsi_hba *phba);
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag);
 
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 3545721..a3bc5e4 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -766,34 +766,13 @@ static void beiscsi_get_port_state(struct Scsi_Host 
*shost)
  * beiscsi_get_port_speed  - Get the Port Speed from Adapter
  * @shost : pointer to scsi_host structure
  *
- * returns Success/Failure
  */
-static int beiscsi_get_port_speed(struct Scsi_Host *shost)
+static void beiscsi_get_port_speed(struct Scsi_Host *shost)
 {
-   int rc;
-   unsigned int tag;
-   struct be_mcc_wrb *wrb;
-   struct be_cmd_ntwk_link_status_resp *resp;
struct beiscsi_hba *phba = iscsi_host_priv(shost);
struct iscsi_cls_host *ihost = shost->shost_data;
 
-   tag = be_cmd_get_port_speed(phba);
-   if (!tag) {
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
-   "BS_%d : Getting Port Speed Failed\n");
-
-return -EBUSY;
-   }
-   rc = beiscsi_mccq_compl(phba, tag, , NULL);
-   if (rc) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BS_%d : Port Speed MBX Failed\n");
-   return rc;
-   }
-   resp = embedded_payload(wrb);
-
-   switch (resp->mac_speed) {
+   switch (phba->port_speed) {
case

[PATCH v3 02/17] be2iscsi: Fix mbox synchronization replacing spinlock with mutex

2015-12-23 Thread Jitendra Bhivare
This is second part of actual fix for soft lockup.

All mbox cmds issued using BMBX and MCC are synchronized using mutex
mbox_lock instead of spin_lock. Used mutex_lock_interruptible where
ever possible.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  |   2 +-
 drivers/scsi/be2iscsi/be_cmds.c |  73 ++--
 drivers/scsi/be2iscsi/be_main.c |   2 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 105 +---
 4 files changed, 94 insertions(+), 88 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 77f992e..cf19bce 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -124,7 +124,7 @@ struct be_ctrl_info {
struct pci_dev *pdev;
 
/* Mbox used for cmd request/response */
-   spinlock_t mbox_lock;   /* For serializing mbox cmds to BE card */
+   struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
struct be_dma_mem mbox_mem;
/* Mbox mem is adjusted to align to 16 bytes. The allocated addr
 * is stored for freeing purpose */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cd50e3c..6fabded 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -164,9 +164,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
/* Set MBX Tag state to Active */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -178,9 +178,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
if (rc <= 0) {
struct be_dma_mem *tag_mem;
/* Set MBX Tag state to timeout */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Store resource addr to be freed later */
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
@@ -199,9 +199,9 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else {
rc = 0;
/* Set MBX Tag state to completed */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
}
 
mcc_tag_response = phba->ctrl.mcc_numtag[tag];
@@ -390,9 +390,9 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
tag_mem->va, tag_mem->dma);
 
/* Change tag state */
-   spin_lock(>ctrl.mbox_lock);
+   mutex_lock(>ctrl.mbox_lock);
ctrl->ptag_state[tag].tag_state = MCC_TAG_STATE_COMPLETED;
-   spin_unlock(>ctrl.mbox_lock);
+   mutex_unlock(>ctrl.mbox_lock);
 
/* Free MCC Tag */
free_mcc_tag(ctrl, tag);
@@ -831,7 +831,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
struct be_dma_mem *q_mem = >dma_mem;
int status;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
@@ -858,7 +858,7 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
eq->id = le16_to_cpu(resp->eq_id);
eq->created = true;
}
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -879,7 +879,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -898,7 +898,7 @@ int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
"BC_%d : be_cmd_fw_initialize Failed\n");
 
-   spin_unlock(>mbox_lock);
+   mutex_unlock(>mbox_lock);
return status;
 }
 
@@ -919,7 +919,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
int status;
u8 *endian_check;
 
-   spin_lock(>mbox_lock);
+   mutex_lock(>mbox_lock);
memset(wrb, 0, sizeof(*wrb));
 
endian_check = (u8 *) wrb;
@@ -939,7 +939,7 @@ int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,

[PATCH v3 03/17] be2iscsi: Fix to use atomic bit operations for tag_state

2015-12-23 Thread Jitendra Bhivare
beiscsi_mccq_compl sets MCC_TAG_STATE_TIMEOUT before setting up
tag_mem_state. be_mcc_compl_process_isr checks for
MCC_TAG_STATE_TIMEOUT first then accesses tag_mem_state which might be
still getting populated in the process context.

Fix:
Set MCC_TAG_STATE_TIMEOUT after tag_mem_state is populated.
Removed MCC_TAG_STATE_COMPLETED. When posted its in running state and
the running state is cleared in be_mcc_compl_process_isr.
be_mcc_notify now takes tag argument to set it to running state.
Use bit operations for tag_state. Use barriers before setting the state.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  |   7 ++-
 drivers/scsi/be2iscsi/be_cmds.c | 111 
 drivers/scsi/be2iscsi/be_cmds.h |   4 +-
 drivers/scsi/be2iscsi/be_mgmt.c |  39 --
 4 files changed, 84 insertions(+), 77 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index cf19bce..629c53d 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -110,10 +110,9 @@ struct be_mcc_obj {
 };
 
 struct beiscsi_mcc_tag_state {
-#define MCC_TAG_STATE_COMPLETED 0x00
-#define MCC_TAG_STATE_RUNNING   0x01
-#define MCC_TAG_STATE_TIMEOUT   0x02
-   uint8_t tag_state;
+   unsigned long tag_state;
+#define MCC_TAG_STATE_RUNNING  1
+#define MCC_TAG_STATE_TIMEOUT  2
struct be_dma_mem tag_mem_state;
 };
 
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 6fabded..1913e9e 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -104,13 +104,16 @@ int be_chk_reset_complete(struct beiscsi_hba *phba)
return 0;
 }
 
-void be_mcc_notify(struct beiscsi_hba *phba)
+void be_mcc_notify(struct beiscsi_hba *phba, unsigned int tag)
 {
struct be_queue_info *mccq = >ctrl.mcc_obj.q;
u32 val = 0;
 
+   set_bit(MCC_TAG_STATE_RUNNING, >ctrl.ptag_state[tag].tag_state);
val |= mccq->id & DB_MCCQ_RING_ID_MASK;
val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+   /* ring doorbell after all of request and state is written */
+   wmb();
iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
 }
 
@@ -122,6 +125,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
phba->ctrl.mcc_numtag[tag] = 0;
+   phba->ctrl.ptag_state[tag].tag_state = 0;
}
if (tag) {
phba->ctrl.mcc_tag_available--;
@@ -163,26 +167,25 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
return -EPERM;
}
 
-   /* Set MBX Tag state to Active */
-   mutex_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_RUNNING;
-   mutex_unlock(>ctrl.mbox_lock);
-
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
phba->ctrl.mcc_numtag[tag],
msecs_to_jiffies(
BEISCSI_HOST_MBX_TIMEOUT));
-
+   /**
+* If MBOX cmd timeout expired, tag and resource allocated
+* for cmd is not freed until FW returns completion.
+*/
if (rc <= 0) {
struct be_dma_mem *tag_mem;
-   /* Set MBX Tag state to timeout */
-   mutex_lock(>ctrl.mbox_lock);
-   phba->ctrl.ptag_state[tag].tag_state = MCC_TAG_STATE_TIMEOUT;
-   mutex_unlock(>ctrl.mbox_lock);
 
-   /* Store resource addr to be freed later */
+   /**
+* PCI/DMA memory allocated and posted in non-embedded mode
+* will have mbx_cmd_mem != NULL.
+* Save virtual and bus addresses for the command so that it
+* can be freed later.
+**/
tag_mem = >ctrl.ptag_state[tag].tag_mem_state;
if (mbx_cmd_mem) {
tag_mem->size = mbx_cmd_mem->size;
@@ -191,19 +194,19 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
} else
tag_mem->size = 0;
 
+   /* first make tag_mem_state visible to all */
+   wmb();
+   set_bit(MCC_TAG_STATE_TIMEOUT,
+   >ctrl.ptag_state[tag].tag_state);
+
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
BEISCSI_LOG_CONFIG,
"BC_%d : MBX Cmd Completion timed out\n");
return -EBUSY;
-   } else {
-   rc = 0;
-   /* Set MBX Tag state to completed */
-   mutex_

[PATCH v3 09/17] be2iscsi: Fix to handle misconfigured optics events

2015-12-23 Thread Jitendra Bhivare
Log messages for misconfigured transceivers reported by FW.

Register async events that driver handles using MCC_CREATE_EXT ioctl.
Errors messages for faulted/uncertified/unqualified optics are logged.
Added IOCTL to get port_name to be displayed in error message.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 164 +---
 drivers/scsi/be2iscsi/be_cmds.h |  47 ++--
 drivers/scsi/be2iscsi/be_main.c |  19 +
 drivers/scsi/be2iscsi/be_main.h |  10 ++-
 drivers/scsi/be2iscsi/be_mgmt.c |  42 ++
 drivers/scsi/be2iscsi/be_mgmt.h |   2 +
 6 files changed, 199 insertions(+), 85 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 705215e..d69fb0a 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -267,26 +267,6 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
spin_unlock_bh(>mcc_lock);
 }
 
-bool is_link_state_evt(u32 trailer)
-{
-   return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_LINK_STATE);
-}
-
-static bool is_iscsi_evt(u32 trailer)
-{
-   return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) &
- ASYNC_TRAILER_EVENT_CODE_MASK) ==
- ASYNC_EVENT_CODE_ISCSI;
-}
-
-static int iscsi_evt_type(u32 trailer)
-{
-   return (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) &
-ASYNC_TRAILER_EVENT_TYPE_MASK;
-}
-
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
if (compl->flags != 0) {
@@ -425,7 +405,7 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
+static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
struct be_async_event_link_state *evt)
 {
if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
@@ -453,6 +433,100 @@ void beiscsi_async_link_state_process(struct beiscsi_hba 
*phba,
}
 }
 
+static char *beiscsi_port_misconf_event_msg[] = {
+   "Physical Link is functional.",
+   "Optics faulted/incorrectly installed/not installed - Reseat optics, if 
issue not resolved, replace.",
+   "Optics of two types installed - Remove one optic or install matching 
pair of optics.",
+   "Incompatible optics - Replace with compatible optics for card to 
function.",
+   "Unqualified optics - Replace with Avago optics for Warranty and 
Technical Support.",
+   "Uncertified optics - Replace with Avago Certified optics to enable 
link operation."
+};
+
+static void beiscsi_process_async_sli(struct beiscsi_hba *phba,
+ struct be_mcc_compl *compl)
+{
+   struct be_async_event_sli *async_sli;
+   u8 evt_type, state, old_state, le;
+   char *sev = KERN_WARNING;
+   char *msg = NULL;
+
+   evt_type = compl->flags >> ASYNC_TRAILER_EVENT_TYPE_SHIFT;
+   evt_type &= ASYNC_TRAILER_EVENT_TYPE_MASK;
+
+   /* processing only MISCONFIGURED physical port event */
+   if (evt_type != ASYNC_SLI_EVENT_TYPE_MISCONFIGURED)
+   return;
+
+   async_sli = (struct be_async_event_sli *)compl;
+   state = async_sli->event_data1 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+   le = async_sli->event_data2 >>
+(phba->fw_config.phys_port * 8) & 0xff;
+
+   old_state = phba->optic_state;
+   phba->optic_state = state;
+
+   if (state >= ARRAY_SIZE(beiscsi_port_misconf_event_msg)) {
+   /* fw is reporting a state we don't know, log and return */
+   __beiscsi_log(phba, KERN_ERR,
+   "BC_%d : Port %c: Unrecognized optic state 0x%x\n",
+   phba->port_name, async_sli->event_data1);
+   return;
+   }
+
+   if (ASYNC_SLI_LINK_EFFECT_VALID(le)) {
+   /* log link effect for unqualified-4, uncertified-5 optics */
+   if (state > 3)
+   msg = (ASYNC_SLI_LINK_EFFECT_STATE(le)) ?
+   " Link is non-operational." :
+   " Link is operational.";
+   /* 1 - info */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 1)
+   sev = KERN_INFO;
+   /* 2 - error */
+   if (ASYNC_SLI_LINK_EFFECT_SEV(le) == 2)
+   sev = KERN_ERR;
+   }
+
+   if (old_state != phba->optic_state)
+   __beiscsi_log(ph

[PATCH v3 06/17] be2iscsi: Added return value check for mgmt_get_all_if_id

2015-12-23 Thread Jitendra Bhivare
Use of mutex_lock_interruptible can return -EINTR, handle and log
the error.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_iscsi.c |  7 ---
 drivers/scsi/be2iscsi/be_mgmt.c  | 10 ++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index b7087ba..188d83f 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -367,13 +367,14 @@ beiscsi_set_vlan_tag(struct Scsi_Host *shost,
  struct iscsi_iface_param_info *iface_param)
 {
struct beiscsi_hba *phba = iscsi_host_priv(shost);
-   int ret = 0;
+   int ret;
 
/* Get the Interface Handle */
-   if (mgmt_get_all_if_id(phba)) {
+   ret = mgmt_get_all_if_id(phba);
+   if (ret) {
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Getting Interface Handle Failed\n");
-   return -EIO;
+   return ret;
}
 
switch (iface_param->param) {
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 7f3f8268..7aa7a3c 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -1025,8 +1025,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
uint32_t ip_type;
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
BE2_IPV6 : BE2_IPV4 ;
@@ -1195,8 +1196,9 @@ int mgmt_get_if_info(struct beiscsi_hba *phba, int 
ip_type,
uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
int rc;
 
-   if (mgmt_get_all_if_id(phba))
-   return -EIO;
+   rc = mgmt_get_all_if_id(phba);
+   if (rc)
+   return rc;
 
do {
rc = mgmt_alloc_cmd_data(phba, _cmd,
-- 
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 v3 08/17] be2iscsi: Fix VLAN support for IPv6 network

2015-12-23 Thread Jitendra Bhivare
Configuring VLAN parameters through IPv6 interface was not supported in driver.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_iscsi.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 188d83f..c89a025 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -466,6 +466,10 @@ beiscsi_set_ipv6(struct Scsi_Host *shost,
ret = mgmt_set_ip(phba, iface_param, NULL,
  ISCSI_BOOTPROTO_STATIC);
break;
+   case ISCSI_NET_PARAM_VLAN_ENABLED:
+   case ISCSI_NET_PARAM_VLAN_TAG:
+   ret = beiscsi_set_vlan_tag(shost, iface_param);
+   break;
default:
beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
"BS_%d : Param %d not supported\n",
-- 
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 v3 12/17] be2iscsi: Fix IOPOLL implementation

2015-12-23 Thread Jitendra Bhivare
OS not responding when running 2 port traffic on 72 CPUs system.

be2iscsi IRQs gets affined to CPU0 when irqbalancer is disabled.
be_iopoll processing completions in BLOCK_IOPOLL_SOFTIRQ hogged CPU0.

1. Use budget to exit the polling loop. beiscsi_process_cq didn't honour it.
2. Rearming of EQ is done only after iopoll completes.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  |  2 +-
 drivers/scsi/be2iscsi/be_iscsi.c |  2 +-
 drivers/scsi/be2iscsi/be_main.c  | 91 ++--
 drivers/scsi/be2iscsi/be_main.h  |  5 ++-
 4 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1e6a1b6..b294e54 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -546,7 +546,7 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
}
 
if (num)
-   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1, 0);
+   hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index c89a025..3545721 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1298,7 +1298,7 @@ static void beiscsi_flush_cq(struct beiscsi_hba *phba)
for (i = 0; i < phba->num_cpus; i++) {
pbe_eq = _context->be_eq[i];
blk_iopoll_disable(_eq->iopoll);
-   beiscsi_process_cq(pbe_eq);
+   beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
blk_iopoll_enable(_eq->iopoll);
}
 }
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index a665e6a..9a86044 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -895,32 +895,21 @@ static irqreturn_t be_isr_mcc(int irq, void *dev_id)
 static irqreturn_t be_isr_msix(int irq, void *dev_id)
 {
struct beiscsi_hba *phba;
-   struct be_eq_entry *eqe = NULL;
struct be_queue_info *eq;
-   struct be_queue_info *cq;
-   unsigned int num_eq_processed;
struct be_eq_obj *pbe_eq;
 
pbe_eq = dev_id;
eq = _eq->q;
-   cq = pbe_eq->cq;
-   eqe = queue_tail_node(eq);
 
phba = pbe_eq->phba;
-   num_eq_processed = 0;
-   while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
-   & EQE_VALID_MASK) {
-   if (!blk_iopoll_sched_prep(_eq->iopoll))
-   blk_iopoll_sched(_eq->iopoll);
-
-   AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
-   queue_tail_inc(eq);
-   eqe = queue_tail_node(eq);
-   num_eq_processed++;
-   }
-
-   if (num_eq_processed)
-   hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
+   /* disable interrupt till iopoll completes */
+   hwi_ring_eq_db(phba, eq->id, 1, 0, 0, 1);
+   if (!blk_iopoll_sched_prep(_eq->iopoll))
+   blk_iopoll_sched(_eq->iopoll);
+   else
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_IO,
+   "BM_%d: received event while polling eq %d cq %d\n",
+   eq->id, pbe_eq->cq->id);
 
return IRQ_HANDLED;
 }
@@ -998,6 +987,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
return IRQ_NONE;
 }
 
+
 static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 {
struct pci_dev *pcidev = phba->pcidev;
@@ -1072,7 +1062,7 @@ free_msix_irqs:
 
 void hwi_ring_cq_db(struct beiscsi_hba *phba,
   unsigned int id, unsigned int num_processed,
-  unsigned char rearm, unsigned char event)
+  unsigned char rearm)
 {
u32 val = 0;
 
@@ -2044,7 +2034,7 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
 
if (num_processed >= 32) {
hwi_ring_cq_db(phba, mcc_cq->id,
-   num_processed, 0, 0);
+   num_processed, 0);
num_processed = 0;
}
if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
@@ -2062,24 +2052,25 @@ static void  beiscsi_process_mcc_isr(struct beiscsi_hba 
*phba)
}
 
if (num_processed > 0)
-   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
+   hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1);
 
 }
 
 /**
  * beiscsi_process_cq()- Process the Completion Queue
  * @pbe_eq: Event Q on which the Completion has come
+ * @budget: Max number of events to processed
  *
  * return
  * Numb

[PATCH v3 17/17] be2iscsi: Update the driver version

2015-12-23 Thread Jitendra Bhivare
Driver version: 11.0.0.0

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 41c708c..16a6fd0 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -36,7 +36,7 @@
 #include 
 
 #define DRV_NAME   "be2iscsi"
-#define BUILD_STR  "10.6.0.1"
+#define BUILD_STR  "11.0.0.0"
 #define BE_NAME"Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC   BE_NAME " " "Driver"
-- 
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 v3 13/17] scsi_transport_iscsi: Add 25G and 40G speed definition

2015-12-23 Thread Jitendra Bhivare
iscsi_port_speed and iscsi_port_speed_names have new entries for
25Gbps and 40Gbps link speeds.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/scsi_transport_iscsi.c | 2 ++
 include/scsi/iscsi_if.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/scsi/scsi_transport_iscsi.c 
b/drivers/scsi/scsi_transport_iscsi.c
index e4b3d8f..4414816 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -4308,6 +4308,8 @@ static const struct {
{ISCSI_PORT_SPEED_100MBPS,  "100 Mbps" },
{ISCSI_PORT_SPEED_1GBPS,"1 Gbps" },
{ISCSI_PORT_SPEED_10GBPS,   "10 Gbps" },
+   {ISCSI_PORT_SPEED_25GBPS,   "25 Gbps" },
+   {ISCSI_PORT_SPEED_40GBPS,   "40 Gbps" },
 };
 
 char *iscsi_get_port_speed_name(struct Scsi_Host *shost)
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 95ed942..d66c070 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -724,6 +724,8 @@ enum iscsi_port_speed {
ISCSI_PORT_SPEED_100MBPS= 0x4,
ISCSI_PORT_SPEED_1GBPS  = 0x8,
ISCSI_PORT_SPEED_10GBPS = 0x10,
+   ISCSI_PORT_SPEED_25GBPS = 0x20,
+   ISCSI_PORT_SPEED_40GBPS = 0x40,
 };
 
 /* iSCSI 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 v3 15/17] be2iscsi: Fix async link event processing

2015-12-23 Thread Jitendra Bhivare
Use only port_link_status only to determine link state change.
Only bit 0 is used to get the state.
Remove code for processing port_fault.

Fixed get_nic_conf structure definition. Removed rsvd[23] field in
be_cmd_get_nic_conf_resp.

Moved defintions of struct field values below the field.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  | 48 +++-
 drivers/scsi/be2iscsi/be_cmds.h  | 32 +--
 drivers/scsi/be2iscsi/be_iscsi.c |  2 +-
 3 files changed, 34 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cd14d26..a3dcd66 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -405,32 +405,31 @@ void beiscsi_fail_session(struct iscsi_cls_session 
*cls_session)
iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
 }
 
-static void beiscsi_async_link_state_process(struct beiscsi_hba *phba,
-   struct be_async_event_link_state *evt)
+static void beiscsi_process_async_link(struct beiscsi_hba *phba,
+  struct be_mcc_compl *compl)
 {
-   phba->port_speed = evt->port_speed;
-   if ((evt->port_link_status == ASYNC_EVENT_LINK_DOWN) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault != BEISCSI_PHY_LINK_FAULT_NONE))) {
-   phba->state = BE_ADAPTER_LINK_DOWN;
+   struct be_async_event_link_state *evt;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link Down on Port %d\n",
-   evt->physical_port);
+   evt = (struct be_async_event_link_state *)compl;
 
-   iscsi_host_for_each_session(phba->shost,
-   beiscsi_fail_session);
-   } else if ((evt->port_link_status & ASYNC_EVENT_LINK_UP) ||
-   ((evt->port_link_status & ASYNC_EVENT_LOGICAL) &&
-(evt->port_fault == BEISCSI_PHY_LINK_FAULT_NONE))) {
+   phba->port_speed = evt->port_speed;
+   /**
+* Check logical link status in ASYNC event.
+* This has been newly introduced in SKH-R Firmware 10.0.338.45.
+**/
+   if (evt->port_link_status & BE_ASYNC_LINK_UP_MASK) {
phba->state = BE_ADAPTER_LINK_UP | BE_ADAPTER_CHECK_BOOT;
phba->get_boot = BE_GET_BOOT_RETRIES;
-
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_INIT,
-   "BC_%d : Link UP on Port %d\n",
-   evt->physical_port);
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Up on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   } else {
+   phba->state = BE_ADAPTER_LINK_DOWN;
+   __beiscsi_log(phba, KERN_ERR,
+ "BC_%d : Link Down on Port %d tag 0x%x\n",
+ evt->physical_port, evt->event_tag);
+   iscsi_host_for_each_session(phba->shost,
+   beiscsi_fail_session);
}
 }
 
@@ -507,8 +506,7 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code &= ASYNC_TRAILER_EVENT_CODE_MASK;
switch (evt_code) {
case ASYNC_EVENT_CODE_LINK_STATE:
-   beiscsi_async_link_state_process(phba,
-   (struct be_async_event_link_state *)compl);
+   beiscsi_process_async_link(phba, compl);
break;
case ASYNC_EVENT_CODE_ISCSI:
phba->state |= BE_ADAPTER_CHECK_BOOT;
@@ -524,8 +522,8 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
}
 
beiscsi_log(phba, sev, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : ASYNC Event: status 0x%08x flags 0x%08x\n",
-   compl->status, compl->flags);
+   "BC_%d : ASYNC Event %x: status 0x%08x flags 0x%08x\n",
+   evt_code, compl->status, compl->flags);
 }
 
 int beiscsi_process_mcc(struct beiscsi_hba *phba)
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index a194066..7caf585 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -142,7 +142,6 @@ struct be_async_event_trailer {
 enum {
ASYNC_EVENT_LINK_DOWN = 0x0,
ASYNC_EVENT_LINK_UP = 0x1,
-   ASYNC_EVENT_LOGICAL = 0x2
 };
 
 /**
@@ -152,7 +151,15 @@ enum {
 struct be_async_event_link_state {
u8 physical_port;
u8 port_link

[PATCH v3 16/17] be2iscsi: Fix WRB leak in login/logout path

2015-12-23 Thread Jitendra Bhivare
Login/Logout loop was hanging after few hours. /var/log/message showed
that alloc_wrb_handle() function was not able to allocate any new WRB.

Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not send nopout
Sep 11 11:25:22 Jhelum10 kernel: scsi host10: BM_4989 : Alloc of WRB_HANDLE
Failedfor the CID : 384
Sep 11 11:25:22 Jhelum10 kernel: connection32513:0: Could not allocate pdu for
mgmt task.

Driver allocates WRB to pass login negotiated parameters information to FW
in beiscsi_offload_connection(). This allocated WRB was not freed so there
was WRB_Leak happening.

Put WRB used for posting the login-negotiated parameters back in pool.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_main.c | 72 -
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 9a86044..d8cdb4e 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1184,6 +1184,22 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index++;
 }
 
+static inline struct wrb_handle *
+beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  unsigned int wrbs_per_cxn)
+{
+   struct wrb_handle *pwrb_handle;
+
+   pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
+   pwrb_context->wrb_handles_available--;
+   if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
+   pwrb_context->alloc_index = 0;
+   else
+   pwrb_context->alloc_index++;
+
+   return pwrb_handle;
+}
+
 /**
  * alloc_wrb_handle - To allocate a wrb handle
  * @phba: The hba pointer
@@ -1193,30 +1209,30 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
  * This happens under session_lock until submission to chip
  */
 struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
-struct hwi_wrb_context **pcontext)
+   struct hwi_wrb_context **pcontext)
 {
struct hwi_wrb_context *pwrb_context;
struct hwi_controller *phwi_ctrlr;
-   struct wrb_handle *pwrb_handle;
uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
 
phwi_ctrlr = phba->phwi_ctrlr;
pwrb_context = _ctrlr->wrb_context[cri_index];
-   if (pwrb_context->wrb_handles_available >= 2) {
-   pwrb_handle = pwrb_context->pwrb_handle_base[
-   pwrb_context->alloc_index];
-   pwrb_context->wrb_handles_available--;
-   if (pwrb_context->alloc_index ==
-   (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->alloc_index = 0;
-   else
-   pwrb_context->alloc_index++;
+   /* return the context address */
+   *pcontext = pwrb_context;
+   return beiscsi_get_wrb_handle(pwrb_context, phba->params.wrbs_per_cxn);
+}
 
-   /* Return the context address */
-   *pcontext = pwrb_context;
-   } else
-   pwrb_handle = NULL;
-   return pwrb_handle;
+static inline void
+beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
+  struct wrb_handle *pwrb_handle,
+  unsigned int wrbs_per_cxn)
+{
+   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
+   pwrb_context->wrb_handles_available++;
+   if (pwrb_context->free_index == (wrbs_per_cxn - 1))
+   pwrb_context->free_index = 0;
+   else
+   pwrb_context->free_index++;
 }
 
 /**
@@ -1231,13 +1247,9 @@ static void
 free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
struct wrb_handle *pwrb_handle)
 {
-   pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
-   pwrb_context->wrb_handles_available++;
-   if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
-   pwrb_context->free_index = 0;
-   else
-   pwrb_context->free_index++;
-
+   beiscsi_put_wrb_handle(pwrb_context,
+  pwrb_handle,
+  phba->params.wrbs_per_cxn);
beiscsi_log(phba, KERN_INFO,
BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
"BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
@@ -4715,6 +4727,20 @@ beiscsi_offload_connection(struct beiscsi_conn 
*beiscsi_conn,
doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
iowrite32(doorbell, phba->db_va +
  beiscsi_conn->doorbell_offset);
+
+  

[PATCH v3 01/17] be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx

2015-12-23 Thread Jitendra Bhivare
We are taking mbox_lock spinlock which disables pre-emption before we poll
for mbox completion. Waiting there with spinlock held in excess of 20s will
cause soft lockup.

Actual fix is to change mbox_lock to mutex.
The changes are done in phases. This is the first part.
1. Changed mgmt_get_all_if_id to use MCC where after posting lock is released.
2. Changed be_mbox_db_ready_wait to busy wait for 12s max and removed
wait_event_timeout. Added error handling code for IO reads.
OPCODE_COMMON_QUERY_FIRMWARE_CONFIG mbox command takes 8s time when unreachable
boot targets configured.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 60 -
 drivers/scsi/be2iscsi/be_mgmt.c | 32 +++---
 2 files changed, 51 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 2778089..cd50e3c 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -587,47 +587,42 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT4000/* 4sec */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
-   bool read_flag = false;
-   int ret = 0, i;
u32 ready;
-   DECLARE_WAIT_QUEUE_HEAD_ONSTACK(rdybit_check_q);
 
-   if (beiscsi_error(phba))
-   return -EIO;
+   /*
+* This BMBX busy wait path is used during init only.
+* For the commands executed during init, 5s should suffice.
+*/
+   timeout = jiffies + msecs_to_jiffies(BEISCSI_MBX_RDY_BIT_TIMEOUT);
+   do {
+   if (beiscsi_error(phba))
+   return -EIO;
 
-   timeout = jiffies + (HZ * 110);
+   ready = ioread32(db);
+   if (ready == 0x)
+   return -EIO;
 
-   do {
-   for (i = 0; i < BEISCSI_MBX_RDY_BIT_TIMEOUT; i++) {
-   ready = ioread32(db) & MPU_MAILBOX_DB_RDY_MASK;
-   if (ready) {
-   read_flag = true;
-   break;
-   }
-   mdelay(1);
-   }
+   ready &= MPU_MAILBOX_DB_RDY_MASK;
+   if (ready)
+   return 0;
 
-   if (!read_flag) {
-   wait_event_timeout(rdybit_check_q,
- (read_flag != true),
-  HZ * 5);
-   }
-   } while ((time_before(jiffies, timeout)) && !read_flag);
+   if (time_after(jiffies, timeout))
+   break;
+   mdelay(1);
+   } while (!ready);
 
-   if (!read_flag) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : FW Timed Out\n");
-   phba->fw_timeout = true;
-   beiscsi_ue_detect(phba);
-   ret = -EBUSY;
-   }
+   beiscsi_log(phba, KERN_ERR,
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : FW Timed Out\n");
 
-   return ret;
+   phba->fw_timeout = true;
+   beiscsi_ue_detect(phba);
+
+   return -EBUSY;
 }
 
 /*
@@ -674,6 +669,9 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
if (status)
return status;
 
+   /* RDY is set; small delay before CQE read. */
+   udelay(1);
+
if (be_mcc_compl_is_new(compl)) {
status = be_mcc_compl_process(ctrl, >compl);
be_mcc_compl_use(compl);
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index aea3e6b..7b54b23 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -809,27 +809,39 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
 unsigned int mgmt_get_all_if_id(struct beiscsi_hba *phba)
 {
struct be_ctrl_info *ctrl = >ctrl;
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_cmd_get_all_if_id_req *req = embedded_payload(wrb);
-   struct be_cmd_get_all_if_id_req *pbe_allid = req;
+   struct be_mcc_wrb *wrb;
+   struct be_cmd_get_all_if_id_req *req;
+   struct be_cmd_get_all_if_id_req *pbe_allid;
+   unsigned int tag;
int status = 0;
 
-   memset(wrb, 0, sizeof(*wrb));
-
spin_lock(>mbox_lock);
+   tag = alloc_mcc_tag(phba);
+   if (!tag) {
+   spin_unlock(>mbox_lock)

[PATCH v3 00/17] be2iscsi: driver update 11.0.0.0

2015-12-23 Thread Jitendra Bhivare
This patch is generated against for-next branch.

Jitendra Bhivare (17):
  be2iscsi: Fix soft lockup in mgmt_get_all_if_id path using bmbx
  be2iscsi: Fix mbox synchronization replacing spinlock with mutex
  be2iscsi: Fix to use atomic bit operations for tag_state
  be2iscsi: Fix to synchronize tag allocation using spin_lock
  be2iscsi: Set mbox timeout to 30s
  be2iscsi: Added return value check for mgmt_get_all_if_id
  be2iscsi: Fix to remove shutdown entry point
  be2iscsi: Fix VLAN support for IPv6 network
  be2iscsi: Fix to handle misconfigured optics events
  be2iscsi: Add FW config validation
  be2iscsi: Fix return value for MCC completion
  be2iscsi: Fix IOPOLL implementation
  scsi_transport_iscsi: Add 25G and 40G speed definition
  be2iscsi: Fix to process 25G link speed info from FW
  be2iscsi: Fix async link event processing
  be2iscsi: Fix WRB leak in login/logout path
  be2iscsi: Update the driver version

 drivers/scsi/be2iscsi/be.h  |   9 +-
 drivers/scsi/be2iscsi/be_cmds.c | 453 +++-
 drivers/scsi/be2iscsi/be_cmds.h | 118 +-
 drivers/scsi/be2iscsi/be_iscsi.c|  54 ++---
 drivers/scsi/be2iscsi/be_main.c | 210 +
 drivers/scsi/be2iscsi/be_main.h |  23 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 426 -
 drivers/scsi/be2iscsi/be_mgmt.h |   2 +
 drivers/scsi/scsi_transport_iscsi.c |   2 +
 include/scsi/iscsi_if.h |   2 +
 10 files changed, 721 insertions(+), 578 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 v3 04/17] be2iscsi: Fix to synchronize tag allocation using spin_lock

2015-12-23 Thread Jitendra Bhivare
alloc_mcc_tag/free_mcc_tag is now done under mcc_lock spin_lock

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1913e9e..502c9b6 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -121,6 +121,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
unsigned int tag = 0;
 
+   spin_lock_bh(>ctrl.mcc_lock);
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
@@ -134,6 +135,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
else
phba->ctrl.mcc_alloc_index++;
}
+   spin_unlock_bh(>ctrl.mcc_lock);
return tag;
 }
 
@@ -254,7 +256,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
 
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 {
-   spin_lock(>mbox_lock);
+   spin_lock_bh(>mcc_lock);
tag = tag & 0x00FF;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
@@ -262,7 +264,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
-   spin_unlock(>mbox_lock);
+   spin_unlock_bh(>mcc_lock);
 }
 
 bool is_link_state_evt(u32 trailer)
-- 
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 v3 05/17] be2iscsi: Set mbox timeout to 30s

2015-12-23 Thread Jitendra Bhivare
FW recommended timeout for all mbox command is 30s.
Use msleep instead mdelay to relinquish CPU when polling for
mbox completion.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
Reviewed-by: Hannes Reinecke <h...@suse.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 502c9b6..034b868 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -590,7 +590,8 @@ int be_mcc_notify_wait(struct beiscsi_hba *phba, unsigned 
int tag)
  **/
 static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 {
-#define BEISCSI_MBX_RDY_BIT_TIMEOUT12000   /* 12sec */
+   /* wait 30s for generic non-flash MBOX operation */
+#define BEISCSI_MBX_RDY_BIT_TIMEOUT3
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
unsigned long timeout;
@@ -615,7 +616,7 @@ static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
 
if (time_after(jiffies, timeout))
break;
-   mdelay(1);
+   msleep(20);
} while (!ready);
 
beiscsi_log(phba, KERN_ERR,
-- 
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


RE: [PATCH v2 17/17] be2iscsi: Update the driver version

2015-12-23 Thread Jitendra Bhivare
Please ignore patch v2 set sending v3 shortly.

-Original Message-
From: Jitendra Bhivare [mailto:jitendra.bhiv...@avagotech.com]
Sent: Tuesday, December 22, 2015 10:46 PM
To: linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
Cc: Jitendra Bhivare
Subject: [PATCH v2 17/17] be2iscsi: Update the driver version

Driver version: 11.0.0.0

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.h
b/drivers/scsi/be2iscsi/be_main.h index 41c708c..16a6fd0 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -36,7 +36,7 @@
 #include 

 #define DRV_NAME   "be2iscsi"
-#define BUILD_STR  "10.6.0.1"
+#define BUILD_STR  "11.0.0.0"
 #define BE_NAME"Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC   BE_NAME " " "Driver"
--
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 v1 09/12] be2iscsi: Couple MCC tag and WRB alloc and free

2016-02-04 Thread Jitendra Bhivare
WARN_ON(atomic_read(>used) >= mccq->len) seen when FW gets into UE.

MCCQ overflow is happening because driver discards any new request and
frees up the tag. The tag allocation controls the number of MCC WRB posted.
It is being replenished but WRBs are not hence the WARN_ON.

Allocation and freeing of WRB and tags for MCC is now done in one place.
This helps to achieve proper accounting of WRB indices and MCC tags.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be.h  |   2 +-
 drivers/scsi/be2iscsi/be_cmds.c | 103 +-
 drivers/scsi/be2iscsi/be_cmds.h |   6 +-
 drivers/scsi/be2iscsi/be_main.c |   3 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 134 +++-
 5 files changed, 130 insertions(+), 118 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index da1d87a..ee5ace8 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -42,7 +42,7 @@ struct be_queue_info {
u16 id;
u16 tail, head;
bool created;
-   atomic_t used;  /* Number of valid elements in the queue */
+   u16 used;   /* Number of valid elements in the queue */
 };
 
 static inline u32 MODULO(u16 val, u16 limit)
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 728aa133..a55eaee 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -126,8 +126,62 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
return tag;
 }
 
-void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
+struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
+unsigned int *ref_tag)
 {
+   struct be_queue_info *mccq = >ctrl.mcc_obj.q;
+   struct be_mcc_wrb *wrb = NULL;
+   unsigned int tag;
+
+   spin_lock_bh(>ctrl.mcc_lock);
+   if (mccq->used == mccq->len) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : MCC queue full: WRB used %u tag avail 
%u\n",
+   mccq->used, phba->ctrl.mcc_tag_available);
+   goto alloc_failed;
+   }
+
+   if (!phba->ctrl.mcc_tag_available)
+   goto alloc_failed;
+
+   tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
+   if (!tag) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : MCC tag 0 allocated: tag avail %u alloc 
index %u\n",
+   phba->ctrl.mcc_tag_available,
+   phba->ctrl.mcc_alloc_index);
+   goto alloc_failed;
+   }
+
+   /* return this tag for further reference */
+   *ref_tag = tag;
+   phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
+   phba->ctrl.mcc_tag_status[tag] = 0;
+   phba->ctrl.ptag_state[tag].tag_state = 0;
+   phba->ctrl.mcc_tag_available--;
+   if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
+   phba->ctrl.mcc_alloc_index = 0;
+   else
+   phba->ctrl.mcc_alloc_index++;
+
+   wrb = queue_head_node(mccq);
+   memset(wrb, 0, sizeof(*wrb));
+   wrb->tag0 = tag;
+   wrb->tag0 |= (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
+   queue_head_inc(mccq);
+   mccq->used++;
+
+alloc_failed:
+   spin_unlock_bh(>ctrl.mcc_lock);
+   return wrb;
+}
+
+void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag)
+{
+   struct be_queue_info *mccq = >mcc_obj.q;
+
spin_lock_bh(>mcc_lock);
tag = tag & MCC_Q_CMD_TAG_MASK;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
@@ -136,6 +190,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
+   mccq->used--;
spin_unlock_bh(>mcc_lock);
 }
 
@@ -173,10 +228,8 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
struct be_cmd_resp_hdr *mbx_resp_hdr;
struct be_queue_info *mccq = >ctrl.mcc_obj.q;
 
-   if (beiscsi_error(phba)) {
-   free_mcc_tag(>ctrl, tag);
+   if (beiscsi_error(phba))
return -EPERM;
-   }
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -259,7 +312,7 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
}
}
 
-   free_mcc_tag(>ctrl, tag);
+   free_mcc_wrb(>ctrl, tag);
return rc;
 }
 
@@ -479,7 +532,7 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,

[PATCH v1 12/12] be2iscsi: Add lock to protect WRB alloc and free

2016-02-04 Thread Jitendra Bhivare
FW got into UE after running IO stress test

With kernel change to split session lock in frwd_lock and back_lock for tx
and rx path correspondingly, in the IO path, common resource used in driver
such as WRB was left unprotected.

Add wrb_lock spinlock to protect allocation and freeing of WRB.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_main.c | 5 +
 drivers/scsi/be2iscsi/be_main.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index fa2b589..0892ee2 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1190,12 +1190,14 @@ beiscsi_get_wrb_handle(struct hwi_wrb_context 
*pwrb_context,
 {
struct wrb_handle *pwrb_handle;
 
+   spin_lock_bh(_context->wrb_lock);
pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
pwrb_context->wrb_handles_available--;
if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
pwrb_context->alloc_index = 0;
else
pwrb_context->alloc_index++;
+   spin_unlock_bh(_context->wrb_lock);
 
return pwrb_handle;
 }
@@ -1227,12 +1229,14 @@ beiscsi_put_wrb_handle(struct hwi_wrb_context 
*pwrb_context,
   struct wrb_handle *pwrb_handle,
   unsigned int wrbs_per_cxn)
 {
+   spin_lock_bh(_context->wrb_lock);
pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
pwrb_context->wrb_handles_available++;
if (pwrb_context->free_index == (wrbs_per_cxn - 1))
pwrb_context->free_index = 0;
else
pwrb_context->free_index++;
+   spin_unlock_bh(_context->wrb_lock);
 }
 
 /**
@@ -2920,6 +2924,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba 
*phba)
}
num_cxn_wrbh--;
}
+   spin_lock_init(_context->wrb_lock);
}
idx = 0;
for (index = 0; index < phba->params.cxns_per_ctrl; index++) {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 5ded3fa..30a4606 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -304,6 +304,7 @@ struct invalidate_command_table {
 #define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \
(phwi_ctrlr->wrb_context[cri].ulp_num)
 struct hwi_wrb_context {
+   spinlock_t wrb_lock;
struct list_head wrb_handle_list;
struct list_head wrb_handle_drvr_list;
struct wrb_handle **pwrb_handle_base;
-- 
2.5.0

--
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 08/12] be2iscsi: Fix MCC WRB leak in open_connection

2016-02-04 Thread Jitendra Bhivare
In open with IP of unknown address family, only tag is freed and error
returned. MCC WRB allocated for the operation is not freed.

Added check for supported family of IP in the beginning before
allocating the tag and WRB.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_mgmt.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 85044b8..ccac1d7 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -829,6 +829,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
unsigned short cid = beiscsi_ep->ep_cid;
struct be_sge *sge;
 
+   if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+   "BG_%d : unknown addr family %d\n",
+   dst_addr->sa_family);
+   return -EINVAL;
+   }
+
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
 
@@ -868,7 +875,8 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
beiscsi_ep->ip_type = BE2_IPV4;
-   } else if (dst_addr->sa_family == PF_INET6) {
+   } else {
+   /* else its PF_INET6 family */
req->ip_address.ip_type = BE2_IPV6;
memcpy(>ip_address.addr,
   _in6->sin6_addr.in6_u.u6_addr8, 16);
@@ -877,14 +885,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
memcpy(_ep->dst6_addr,
   _in6->sin6_addr.in6_u.u6_addr8, 16);
beiscsi_ep->ip_type = BE2_IPV6;
-   } else{
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
-   "BG_%d : unknown addr family %d\n",
-   dst_addr->sa_family);
-   mutex_unlock(>mbox_lock);
-   free_mcc_tag(>ctrl, tag);
-   return -EINVAL;
-
}
req->cid = cid;
i = phba->nxt_cqid++;
-- 
2.5.0

--
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 11/12] be2iscsi: _bh for io_sgl_lock and mgmt_sgl_lock

2016-02-04 Thread Jitendra Bhivare
Processing of mgmt and IO tasks are done in process context and sofitrqs.

Allocation and freeing of sgl_handles needs to be done under
spin_lock_bh/spin_unlock_bh and move the locks to the routines.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_main.c | 25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 03265b6..fa2b589 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1132,6 +1132,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct 
beiscsi_hba *phba)
 {
struct sgl_handle *psgl_handle;
 
+   spin_lock_bh(>io_sgl_lock);
if (phba->io_sgl_hndl_avbl) {
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
"BM_%d : In alloc_io_sgl_handle,"
@@ -1149,12 +1150,14 @@ static struct sgl_handle *alloc_io_sgl_handle(struct 
beiscsi_hba *phba)
phba->io_sgl_alloc_index++;
} else
psgl_handle = NULL;
+   spin_unlock_bh(>io_sgl_lock);
return psgl_handle;
 }
 
 static void
 free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
+   spin_lock_bh(>io_sgl_lock);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
"BM_%d : In free_,io_sgl_free_index=%d\n",
phba->io_sgl_free_index);
@@ -1169,6 +1172,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
 "value there=%p\n", phba->io_sgl_free_index,
 phba->io_sgl_hndl_base
 [phba->io_sgl_free_index]);
+spin_unlock_bh(>io_sgl_lock);
return;
}
phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle;
@@ -1177,6 +1181,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index = 0;
else
phba->io_sgl_free_index++;
+   spin_unlock_bh(>io_sgl_lock);
 }
 
 static inline struct wrb_handle *
@@ -1257,6 +1262,7 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct 
beiscsi_hba *phba)
 {
struct sgl_handle *psgl_handle;
 
+   spin_lock_bh(>mgmt_sgl_lock);
if (phba->eh_sgl_hndl_avbl) {
psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
@@ -1274,13 +1280,14 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct 
beiscsi_hba *phba)
phba->eh_sgl_alloc_index++;
} else
psgl_handle = NULL;
+   spin_unlock_bh(>mgmt_sgl_lock);
return psgl_handle;
 }
 
 void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
-
+   spin_lock_bh(>mgmt_sgl_lock);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BM_%d : In  free_mgmt_sgl_handle,"
"eh_sgl_free_index=%d\n",
@@ -1295,6 +1302,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
"BM_%d : Double Free in eh SGL ,"
"eh_sgl_free_index=%d\n",
phba->eh_sgl_free_index);
+   spin_unlock_bh(>mgmt_sgl_lock);
return;
}
phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle;
@@ -1304,6 +1312,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->eh_sgl_free_index = 0;
else
phba->eh_sgl_free_index++;
+   spin_unlock_bh(>mgmt_sgl_lock);
 }
 
 static void
@@ -4616,11 +4625,9 @@ beiscsi_free_mgmt_task_handles(struct beiscsi_conn 
*beiscsi_conn,
}
 
if (io_task->psgl_handle) {
-   spin_lock_bh(>mgmt_sgl_lock);
free_mgmt_sgl_handle(phba,
 io_task->psgl_handle);
io_task->psgl_handle = NULL;
-   spin_unlock_bh(>mgmt_sgl_lock);
}
 
if (io_task->mtask_addr) {
@@ -4666,9 +4673,7 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
}
 
if (io_task->psgl_handle) {
-   spin_lock(>io_sgl_lock);
free_io_sgl_handle(phba, io_task->psgl_handle);
-   spin_unlock(>io_sgl_lock);
io_task->psgl_handle = NULL;
}
 
@@ -4784,9 +4789,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, 
uint8_t opcode)
  

[PATCH v1 05/12] be2iscsi: Remove be_mbox_notify_wait function

2016-02-04 Thread Jitendra Bhivare
be_mbox_notify_wait does exactly same thing as be_mbox_notify.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_cmds.c | 79 +++--
 1 file changed, 4 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1fe8eb8..12b60dd 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -625,8 +625,6 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct be_dma_mem *mbox_mem = >mbox_mem;
struct be_mcc_mailbox *mbox = mbox_mem->va;
-   struct be_mcc_compl *compl = >compl;
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
 
status = be_mbox_db_ready_poll(ctrl);
if (status)
@@ -654,77 +652,8 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
/* RDY is set; small delay before CQE read. */
udelay(1);
 
-   if (be_mcc_compl_is_new(compl)) {
-   status = beiscsi_process_mbox_compl(ctrl, compl);
-   be_mcc_compl_use(compl);
-   if (status) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : After 
beiscsi_process_mbox_compl\n");
-
-   return status;
-   }
-   } else {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : Invalid Mailbox Completion\n");
-
-   return -EBUSY;
-   }
-   return 0;
-}
-
-/*
- * Insert the mailbox address into the doorbell in two steps
- * Polls on the mbox doorbell till a command completion (or a timeout) occurs
- */
-static int be_mbox_notify_wait(struct beiscsi_hba *phba)
-{
-   int status;
-   u32 val = 0;
-   void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
-   struct be_dma_mem *mbox_mem = >ctrl.mbox_mem;
-   struct be_mcc_mailbox *mbox = mbox_mem->va;
-   struct be_mcc_compl *compl = >compl;
-   struct be_ctrl_info *ctrl = >ctrl;
-
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status)
-   return status;
-
-   val |= MPU_MAILBOX_DB_HI_MASK;
-   /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
-   val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
-   iowrite32(val, db);
-
-   /* wait for ready to be set */
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status != 0)
-   return status;
-
-   val = 0;
-   /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
-   val |= (u32)(mbox_mem->dma >> 4) << 2;
-   iowrite32(val, db);
-
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status != 0)
-   return status;
-
-   /* A cq entry has been made now */
-   if (be_mcc_compl_is_new(compl)) {
-   status = beiscsi_process_mbox_compl(ctrl, >compl);
-   be_mcc_compl_use(compl);
-   if (status)
-   return status;
-   } else {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : invalid mailbox completion\n");
-
-   return -EBUSY;
-   }
-   return 0;
+   status = beiscsi_process_mbox_compl(ctrl, >compl);
+   return status;
 }
 
 void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
@@ -1039,7 +968,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
 
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-   status = be_mbox_notify_wait(phba);
+   status = be_mbox_notify(ctrl);
if (!status) {
struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
mccq->id = le16_to_cpu(resp->id);
@@ -1381,7 +1310,7 @@ int beiscsi_cmd_reset_function(struct beiscsi_hba  *phba)
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
   OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
-   status = be_mbox_notify_wait(phba);
+   status = be_mbox_notify(ctrl);
 
mutex_unlock(>mbox_lock);
return status;
-- 
2.5.0

--
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 10/12] be2iscsi: Fix ExpStatSn in management tasks

2016-02-04 Thread Jitendra Bhivare
Connection resets observed from some targets when NOP-Out with wrong
ExpStatSn is sent.

FW keeps track of StatSn and fills up ExpStatSn accordingly.
The header filled up by the stack needs to be modified by driver to clear
ExpStatSn. If the field is not cleared, FW recalculates ExpStatSn and
wrong offset'ed ExpStatSn is seen in the wire trace.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_main.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 3f08a11..03265b6 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4926,7 +4926,6 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct 
scatterlist *sg,
 
pwrb = io_task->pwrb_handle->pwrb;
 
-   io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
if (writedir) {
@@ -4987,7 +4986,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct 
scatterlist *sg,
unsigned int doorbell = 0;
 
pwrb = io_task->pwrb_handle->pwrb;
-   io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
if (writedir) {
@@ -5159,23 +5157,21 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
 {
struct beiscsi_io_task *io_task = task->dd_data;
struct scsi_cmnd *sc = task->sc;
-   struct beiscsi_hba *phba = NULL;
+   struct beiscsi_hba *phba;
struct scatterlist *sg;
int num_sg;
unsigned int  writedir = 0, xferlen = 0;
 
-   phba = ((struct beiscsi_conn *)task->conn->dd_data)->phba;
+   if (!io_task->conn->login_in_progress)
+   task->hdr->exp_statsn = 0;
 
if (!sc)
return beiscsi_mtask(task);
 
io_task->scsi_cmnd = sc;
num_sg = scsi_dma_map(sc);
+   phba = io_task->conn->phba;
if (num_sg < 0) {
-   struct iscsi_conn *conn = task->conn;
-   struct beiscsi_hba *phba = NULL;
-
-   phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI,
"BM_%d : scsi_dma_map Failed "
-- 
2.5.0

--
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 07/12] be2iscsi: Cleanup processing of BMBX completion

2016-02-04 Thread Jitendra Bhivare
Remove confusingly named be_mcc_compl_is_new and be_mcc_compl_use functions
in processing of BMBX. Rearrange beiscsi_process_mbox_compl function.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_cmds.c | 75 -
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 60db2de..728aa133 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -263,21 +263,6 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
return rc;
 }
 
-static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
-{
-   if (compl->flags != 0) {
-   compl->flags = le32_to_cpu(compl->flags);
-   WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
-   return true;
-   } else
-   return false;
-}
-
-static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
-{
-   compl->flags = 0;
-}
-
 /*
  * beiscsi_process_mbox_compl()- Check the MBX completion status
  * @ctrl: Function specific MBX data structure
@@ -298,30 +283,46 @@ static int beiscsi_process_mbox_compl(struct be_ctrl_info 
*ctrl,
struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
struct be_cmd_resp_hdr *resp_hdr;
 
-   be_dws_le_to_cpu(compl, 4);
+   /**
+* To check if valid bit is set, check the entire word as we don't know
+* the endianness of the data (old entry is host endian while a new
+* entry is little endian)
+*/
+   if (!compl->flags) {
+   beiscsi_log(phba, KERN_ERR,
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : BMBX busy, no completion\n");
+   return -EBUSY;
+   }
+   compl->flags = le32_to_cpu(compl->flags);
+   WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
 
+   /**
+* Just swap the status to host endian;
+* mcc tag is opaquely copied from mcc_wrb.
+*/
+   be_dws_le_to_cpu(compl, 4);
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
-   CQE_STATUS_COMPL_MASK;
-   if (compl_status != MCC_STATUS_SUCCESS) {
-   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
-   CQE_STATUS_EXTD_MASK;
+   CQE_STATUS_COMPL_MASK;
+   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+   CQE_STATUS_EXTD_MASK;
+   /* Need to reset the entire word that houses the valid bit */
+   compl->flags = 0;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : error in cmd completion: "
-   "Subsystem : %d Opcode : %d "
-   "status(compl/extd)=%d/%d\n",
-   hdr->subsystem, hdr->opcode,
-   compl_status, extd_status);
-
-   if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
-   resp_hdr = (struct be_cmd_resp_hdr *) hdr;
-   if (resp_hdr->response_length)
-   return 0;
-   }
-   return -EINVAL;
+   if (compl_status == MCC_STATUS_SUCCESS)
+   return 0;
+
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : error in cmd completion: Subsystem : %d Opcode : 
%d status(compl/extd)=%d/%d\n",
+   hdr->subsystem, hdr->opcode, compl_status, extd_status);
+
+   if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
+   /* if status is insufficient buffer, check the length */
+   resp_hdr = (struct be_cmd_resp_hdr *) hdr;
+   if (resp_hdr->response_length)
+   return 0;
}
-   return 0;
+   return -EINVAL;
 }
 
 static void beiscsi_process_async_link(struct beiscsi_hba *phba,
@@ -453,10 +454,6 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
struct be_dma_mem *tag_mem;
unsigned int tag, wrb_idx;
 
-   /**
-* Just swap the status to host endian; mcc tag is opaquely copied
-* from mcc_wrb
-*/
be_dws_le_to_cpu(compl, 4);
tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
-- 
2.5.0

--
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 04/12] be2iscsi: Rename MCC and BMBX processing functions

2016-02-04 Thread Jitendra Bhivare
beiscsi_mccq_compl -> beiscsi_mccq_compl_wait - indicate blocking call.
be_mcc_wait_compl -> be_mcc_compl_poll - indicate polling for completion.
be_mbox_db_ready_wait -> be_mbox_db_ready_poll - indicate polling for RDY.
be_mcc_compl_process -> beiscsi_process_mbox_compl - indicate BMBX compl.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_cmds.c  | 38 +++---
 drivers/scsi/be2iscsi/be_cmds.h  |  6 +++---
 drivers/scsi/be2iscsi/be_iscsi.c |  8 
 drivers/scsi/be2iscsi/be_main.c  |  8 
 drivers/scsi/be2iscsi/be_mgmt.c  | 12 ++--
 5 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index f59dbdf..1fe8eb8 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -140,7 +140,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 }
 
 /*
- * beiscsi_mccq_compl()- Wait for completion of MBX
+ * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
  * @phba: Driver private structure
  * @tag: Tag for the MBX Command
  * @wrb: the WRB used for the MBX Command
@@ -152,9 +152,9 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
  * Success: 0
  * Failure: Non-Zero
  **/
-int beiscsi_mccq_compl(struct beiscsi_hba *phba,
-   uint32_t tag, struct be_mcc_wrb **wrb,
-   struct be_dma_mem *mbx_cmd_mem)
+int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
+   uint32_t tag, struct be_mcc_wrb **wrb,
+   struct be_dma_mem *mbx_cmd_mem)
 {
int rc = 0;
uint32_t mcc_tag_status;
@@ -283,7 +283,7 @@ static inline void be_mcc_compl_use(struct be_mcc_compl 
*compl)
 }
 
 /*
- * be_mcc_compl_process()- Check the MBX comapletion status
+ * beiscsi_process_mbox_compl()- Check the MBX completion status
  * @ctrl: Function specific MBX data structure
  * @compl: Completion status of MBX Command
  *
@@ -293,8 +293,8 @@ static inline void be_mcc_compl_use(struct be_mcc_compl 
*compl)
  * Success: Zero
  * Failure: Non-Zero
  **/
-static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
-   struct be_mcc_compl *compl)
+static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
+ struct be_mcc_compl *compl)
 {
u16 compl_status, extd_status;
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
@@ -520,7 +520,7 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
 }
 
 /*
- * be_mcc_wait_compl()- Wait for MBX completion
+ * be_mcc_compl_poll()- Wait for MBX completion
  * @phba: driver private structure
  *
  * Wait till no more pending mcc requests are present
@@ -556,7 +556,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned 
int tag)
 }
 
 /*
- * be_mbox_db_ready_wait()- Check ready status
+ * be_mbox_db_ready_poll()- Check ready status
  * @ctrl: Function specific MBX data structure
  *
  * Check for the ready status of FW to send BMBX
@@ -566,7 +566,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned 
int tag)
  * Success: 0
  * Failure: Non-Zero
  **/
-static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
+static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
 {
/* wait 30s for generic non-flash MBOX operation */
 #define BEISCSI_MBX_RDY_BIT_TIMEOUT3
@@ -628,7 +628,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
struct be_mcc_compl *compl = >compl;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -637,7 +637,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
iowrite32(val, db);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -647,7 +647,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
val |= (u32) (mbox_mem->dma >> 4) << 2;
iowrite32(val, db);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -655,12 +655,12 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
udelay(1);
 
if (be_mcc_compl_is_new(compl)) {
-   status = be_mcc_compl_process(ctrl, >compl);
+   status = beiscsi_process_mbox_compl(ctrl, compl);
be_mcc_compl_use(compl);
if (status) {
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : After be_mcc_compl_process\n");
+ 

[PATCH v1 03/12] be2iscsi: Remove redundant MCC processing code

2016-02-04 Thread Jitendra Bhivare
be_mcc_compl_process_isr is removed.
MCC CQ processing is done only in beiscsi_process_mcc_cq and MCC CQE
processing is done only in beiscsi_process_mcc_compl.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be_cmds.c | 165 ++--
 drivers/scsi/be2iscsi/be_cmds.h |   7 +-
 drivers/scsi/be2iscsi/be_main.c |   8 +-
 drivers/scsi/be2iscsi/be_main.h |   1 +
 drivers/scsi/be2iscsi/be_mgmt.c |   3 +-
 5 files changed, 68 insertions(+), 116 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index c5e7739..f59dbdf 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -328,76 +328,6 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
return 0;
 }
 
-int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
-   struct be_mcc_compl *compl)
-{
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
-   u16 compl_status, extd_status;
-   struct be_dma_mem *tag_mem;
-   unsigned int tag, wrb_idx;
-
-   be_dws_le_to_cpu(compl, 4);
-   tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
-   wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
-
-   if (!test_bit(MCC_TAG_STATE_RUNNING,
- >ptag_state[tag].tag_state)) {
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX |
-   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-   "BC_%d : MBX cmd completed but not posted\n");
-   return 0;
-   }
-
-   if (test_bit(MCC_TAG_STATE_TIMEOUT,
->ptag_state[tag].tag_state)) {
-   beiscsi_log(phba, KERN_WARNING,
-   BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
-   BEISCSI_LOG_CONFIG,
-   "BC_%d : MBX Completion for timeout Command from 
FW\n");
-   /**
-* Check for the size before freeing resource.
-* Only for non-embedded cmd, PCI resource is allocated.
-**/
-   tag_mem = >ptag_state[tag].tag_mem_state;
-   if (tag_mem->size)
-   pci_free_consistent(ctrl->pdev, tag_mem->size,
-   tag_mem->va, tag_mem->dma);
-   free_mcc_tag(ctrl, tag);
-   return 0;
-   }
-
-   compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
-  CQE_STATUS_COMPL_MASK;
-   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
- CQE_STATUS_EXTD_MASK;
-   /* The ctrl.mcc_tag_status[tag] is filled with
-* [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
-* [7:0] = compl_status
-*/
-   ctrl->mcc_tag_status[tag] = CQE_VALID_MASK;
-   ctrl->mcc_tag_status[tag] |= (wrb_idx << CQE_STATUS_WRB_SHIFT);
-   ctrl->mcc_tag_status[tag] |= (extd_status << CQE_STATUS_ADDL_SHIFT) &
-CQE_STATUS_ADDL_MASK;
-   ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
-
-   /* write ordering implied in wake_up_interruptible */
-   clear_bit(MCC_TAG_STATE_RUNNING, >ptag_state[tag].tag_state);
-   wake_up_interruptible(>mcc_wait[tag]);
-   return 0;
-}
-
-static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
-{
-   struct be_queue_info *mcc_cq = >ctrl.mcc_obj.cq;
-   struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
-
-   if (be_mcc_compl_is_new(compl)) {
-   queue_tail_inc(mcc_cq);
-   return compl;
-   }
-   return NULL;
-}
-
 /**
  * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
@@ -528,27 +458,65 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code, compl->status, compl->flags);
 }
 
-int beiscsi_process_mcc(struct beiscsi_hba *phba)
+int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
+ struct be_mcc_compl *compl)
 {
-   struct be_mcc_compl *compl;
-   int num = 0, status = 0;
-   struct be_ctrl_info *ctrl = >ctrl;
+   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
+   u16 compl_status, extd_status;
+   struct be_dma_mem *tag_mem;
+   unsigned int tag, wrb_idx;
 
-   while ((compl = be_mcc_compl_get(phba))) {
-   if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
-   beiscsi_process_async_event(phba, compl);
-   } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
-   status = be_mcc_compl_process(ctrl, compl);
-  

[PATCH v1 01/12] be2iscsi: Remove unused mcc_cq_lock

2016-02-04 Thread Jitendra Bhivare
mcc_cq_lock spin_lock is used only in beiscsi_process_mcc which is called
only when all interrupts are disabled from mgmt_epfw_cleanup during
unloading of driver. There is no other context where there can be
contention for the processing of CQ.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
Reviewed-by: Johannes Thumshirn <jthumsh...@suse.de>
---
 drivers/scsi/be2iscsi/be.h  | 1 -
 drivers/scsi/be2iscsi/be_cmds.c | 2 --
 drivers/scsi/be2iscsi/be_main.c | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 7d425af..1524fe4 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -132,7 +132,6 @@ struct be_ctrl_info {
/* MCC Rings */
struct be_mcc_obj mcc_obj;
spinlock_t mcc_lock;/* For serializing mcc cmds to BE card */
-   spinlock_t mcc_cq_lock;
 
wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
unsigned int mcc_tag[MAX_MCC_CMD];
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 34c33d4..e8e9d22 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -532,7 +532,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
int num = 0, status = 0;
struct be_ctrl_info *ctrl = >ctrl;
 
-   spin_lock_bh(>ctrl.mcc_cq_lock);
while ((compl = be_mcc_compl_get(phba))) {
if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
beiscsi_process_async_event(phba, compl);
@@ -547,7 +546,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
if (num)
hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
-   spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
 }
 
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 70179e1..314fd2c 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -730,7 +730,6 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct 
pci_dev *pdev)
memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
mutex_init(>mbox_lock);
spin_lock_init(>ctrl.mcc_lock);
-   spin_lock_init(>ctrl.mcc_cq_lock);
 
return status;
 }
-- 
2.5.0

--
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] be2iscsi: Fix memory leak in beiscsi_alloc_mem()

2016-02-11 Thread Jitendra Bhivare
In case of error, the memory allocated for phwi_ctrlr was not freed.

Signed-off-by: Maurizio Lombardi <mlomb...@redhat.com>
---
 drivers/scsi/be2iscsi/be_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 7a6dbfb..360aa88 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -2706,8 +2706,10 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba)
phwi_ctrlr->wrb_context = kzalloc(sizeof(struct hwi_wrb_context) *
  phba->params.cxns_per_ctrl,
  GFP_KERNEL);
-   if (!phwi_ctrlr->wrb_context)
+   if (!phwi_ctrlr->wrb_context) {
+   kfree(phba->phwi_ctrlr);
return -ENOMEM;
+   }

phba->init_mem = kcalloc(SE_MEM_MAX, sizeof(*mem_descr),
 GFP_KERNEL);
--
Maurizio Lombardi

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

Reviewed-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>

Thanks,

JB


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH v4 00/17] be2iscsi: driver update 11.0.0.0

2016-01-27 Thread Jitendra Bhivare
> -Original Message-
> From: Martin K. Petersen [mailto:martin.peter...@oracle.com]
> Sent: Wednesday, January 27, 2016 7:15 AM
> To: Jitendra Bhivare
> Cc: linux-scsi@vger.kernel.org; micha...@cs.wisc.edu
> Subject: Re: [PATCH v4 00/17] be2iscsi: driver update 11.0.0.0
>
> >>>>> "Jitendra" == Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
writes:
>
> Applied to 4.6/scsi-queue.
>
> PATCH 12/17: "be2iscsi: Fix IOPOLL implementation" conflicted with
Christoph's
> irq_poll changes. I fixed it up but please verify:
>
>
http://git.kernel.org/cgit/linux/kernel/git/mkp/scsi.git/commit/?h=4.6/scs
i-
> queue=fa512e1a3156
>
> --
> Martin K. PetersenOracle Linux Engineering
Reviewed by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>

Thanks,

JB
--
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/12] be2iscsi: _bh for io_sgl_lock and mgmt_sgl_lock

2016-02-01 Thread Jitendra Bhivare
Processing of mgmt and IO tasks are done in process context and sofitrqs.

Allocation and freeing of sgl_handles needs to be done under
spin_lock_bh/spin_unlock_bh and move the locks to the routines.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.c | 25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 03265b6..fa2b589 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1132,6 +1132,7 @@ static struct sgl_handle *alloc_io_sgl_handle(struct 
beiscsi_hba *phba)
 {
struct sgl_handle *psgl_handle;
 
+   spin_lock_bh(>io_sgl_lock);
if (phba->io_sgl_hndl_avbl) {
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
"BM_%d : In alloc_io_sgl_handle,"
@@ -1149,12 +1150,14 @@ static struct sgl_handle *alloc_io_sgl_handle(struct 
beiscsi_hba *phba)
phba->io_sgl_alloc_index++;
} else
psgl_handle = NULL;
+   spin_unlock_bh(>io_sgl_lock);
return psgl_handle;
 }
 
 static void
 free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
+   spin_lock_bh(>io_sgl_lock);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
"BM_%d : In free_,io_sgl_free_index=%d\n",
phba->io_sgl_free_index);
@@ -1169,6 +1172,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
 "value there=%p\n", phba->io_sgl_free_index,
 phba->io_sgl_hndl_base
 [phba->io_sgl_free_index]);
+spin_unlock_bh(>io_sgl_lock);
return;
}
phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle;
@@ -1177,6 +1181,7 @@ free_io_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->io_sgl_free_index = 0;
else
phba->io_sgl_free_index++;
+   spin_unlock_bh(>io_sgl_lock);
 }
 
 static inline struct wrb_handle *
@@ -1257,6 +1262,7 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct 
beiscsi_hba *phba)
 {
struct sgl_handle *psgl_handle;
 
+   spin_lock_bh(>mgmt_sgl_lock);
if (phba->eh_sgl_hndl_avbl) {
psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
@@ -1274,13 +1280,14 @@ static struct sgl_handle *alloc_mgmt_sgl_handle(struct 
beiscsi_hba *phba)
phba->eh_sgl_alloc_index++;
} else
psgl_handle = NULL;
+   spin_unlock_bh(>mgmt_sgl_lock);
return psgl_handle;
 }
 
 void
 free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
 {
-
+   spin_lock_bh(>mgmt_sgl_lock);
beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
"BM_%d : In  free_mgmt_sgl_handle,"
"eh_sgl_free_index=%d\n",
@@ -1295,6 +1302,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
"BM_%d : Double Free in eh SGL ,"
"eh_sgl_free_index=%d\n",
phba->eh_sgl_free_index);
+   spin_unlock_bh(>mgmt_sgl_lock);
return;
}
phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle;
@@ -1304,6 +1312,7 @@ free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct 
sgl_handle *psgl_handle)
phba->eh_sgl_free_index = 0;
else
phba->eh_sgl_free_index++;
+   spin_unlock_bh(>mgmt_sgl_lock);
 }
 
 static void
@@ -4616,11 +4625,9 @@ beiscsi_free_mgmt_task_handles(struct beiscsi_conn 
*beiscsi_conn,
}
 
if (io_task->psgl_handle) {
-   spin_lock_bh(>mgmt_sgl_lock);
free_mgmt_sgl_handle(phba,
 io_task->psgl_handle);
io_task->psgl_handle = NULL;
-   spin_unlock_bh(>mgmt_sgl_lock);
}
 
if (io_task->mtask_addr) {
@@ -4666,9 +4673,7 @@ static void beiscsi_cleanup_task(struct iscsi_task *task)
}
 
if (io_task->psgl_handle) {
-   spin_lock(>io_sgl_lock);
free_io_sgl_handle(phba, io_task->psgl_handle);
-   spin_unlock(>io_sgl_lock);
io_task->psgl_handle = NULL;
}
 
@@ -4784,9 +4789,7 @@ static int beiscsi_alloc_pdu(struct iscsi_task *task, 
uint8_t opcode)
io_task->pwrb_handle = NULL;
 
if

[PATCH 01/12] be2iscsi: Remove unused mcc_cq_lock

2016-02-01 Thread Jitendra Bhivare
mcc_cq_lock spin_lock is used only in beiscsi_process_mcc which is called
only when all interrupts are disabled from mgmt_epfw_cleanup during
unloading of driver. There is no other context where there can be
contention for the processing of CQ.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  | 1 -
 drivers/scsi/be2iscsi/be_cmds.c | 2 --
 drivers/scsi/be2iscsi/be_main.c | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 7d425af..1524fe4 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -132,7 +132,6 @@ struct be_ctrl_info {
/* MCC Rings */
struct be_mcc_obj mcc_obj;
spinlock_t mcc_lock;/* For serializing mcc cmds to BE card */
-   spinlock_t mcc_cq_lock;
 
wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
unsigned int mcc_tag[MAX_MCC_CMD];
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 34c33d4..e8e9d22 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -532,7 +532,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
int num = 0, status = 0;
struct be_ctrl_info *ctrl = >ctrl;
 
-   spin_lock_bh(>ctrl.mcc_cq_lock);
while ((compl = be_mcc_compl_get(phba))) {
if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
beiscsi_process_async_event(phba, compl);
@@ -547,7 +546,6 @@ int beiscsi_process_mcc(struct beiscsi_hba *phba)
if (num)
hwi_ring_cq_db(phba, phba->ctrl.mcc_obj.cq.id, num, 1);
 
-   spin_unlock_bh(>ctrl.mcc_cq_lock);
return status;
 }
 
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 70179e1..314fd2c 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -730,7 +730,6 @@ static int be_ctrl_init(struct beiscsi_hba *phba, struct 
pci_dev *pdev)
memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
mutex_init(>mbox_lock);
spin_lock_init(>ctrl.mcc_lock);
-   spin_lock_init(>ctrl.mcc_cq_lock);
 
return status;
 }
-- 
2.5.0

--
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 08/12] be2iscsi: Fix MCC WRB leak in open_connection

2016-02-01 Thread Jitendra Bhivare
In open with IP of unknown address family, only tag is freed and error
returned. MCC WRB allocated for the operation is not freed.

Added check for supported family of IP in the beginning before
allocating the tag and WRB.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_mgmt.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index 85044b8..ccac1d7 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -829,6 +829,13 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
unsigned short cid = beiscsi_ep->ep_cid;
struct be_sge *sge;
 
+   if (dst_addr->sa_family != PF_INET && dst_addr->sa_family != PF_INET6) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
+   "BG_%d : unknown addr family %d\n",
+   dst_addr->sa_family);
+   return -EINVAL;
+   }
+
phwi_ctrlr = phba->phwi_ctrlr;
phwi_context = phwi_ctrlr->phwi_ctxt;
 
@@ -868,7 +875,8 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
beiscsi_ep->dst_addr = daddr_in->sin_addr.s_addr;
beiscsi_ep->dst_tcpport = ntohs(daddr_in->sin_port);
beiscsi_ep->ip_type = BE2_IPV4;
-   } else if (dst_addr->sa_family == PF_INET6) {
+   } else {
+   /* else its PF_INET6 family */
req->ip_address.ip_type = BE2_IPV6;
memcpy(>ip_address.addr,
   _in6->sin6_addr.in6_u.u6_addr8, 16);
@@ -877,14 +885,6 @@ int mgmt_open_connection(struct beiscsi_hba *phba,
memcpy(_ep->dst6_addr,
   _in6->sin6_addr.in6_u.u6_addr8, 16);
beiscsi_ep->ip_type = BE2_IPV6;
-   } else{
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
-   "BG_%d : unknown addr family %d\n",
-   dst_addr->sa_family);
-   mutex_unlock(>mbox_lock);
-   free_mcc_tag(>ctrl, tag);
-   return -EINVAL;
-
}
req->cid = cid;
i = phba->nxt_cqid++;
-- 
2.5.0

--
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/12] be2iscsi: critical fixes for 11.0.0.0

2016-02-01 Thread Jitendra Bhivare
This driver update has critical fixes for following issues:
- Management tasks with incorrect ExpStatSn
- WRB allocation failures in IO path
- MCC WRB leak

Jitendra Bhivare (12):
  be2iscsi: Remove unused mcc_cq_lock
  be2iscsi: Use macros for MCC WRB and CQE fields
  be2iscsi: Remove redundant MCC processing code
  be2iscsi: Rename MCC and BMBX processing functions
  be2iscsi: Remove be_mbox_notify_wait function
  be2iscsi: Fix be_mcc_compl_poll to use tag_state
  be2iscsi: Cleanup processing of BMBX completion
  be2iscsi: Fix MCC WRB leak in open_connection
  be2iscsi: Couple MCC tag and WRB alloc and free
  be2iscsi: Fix ExpStatSn in management tasks
  be2iscsi: _bh for io_sgl_lock and mgmt_sgl_lock
  be2iscsi: Add lock to protect WRB alloc and free

 drivers/scsi/be2iscsi/be.h   |  11 +-
 drivers/scsi/be2iscsi/be_cmds.c  | 522 +--
 drivers/scsi/be2iscsi/be_cmds.h  |  32 +--
 drivers/scsi/be2iscsi/be_iscsi.c |   8 +-
 drivers/scsi/be2iscsi/be_main.c  |  73 +++---
 drivers/scsi/be2iscsi/be_main.h  |   2 +
 drivers/scsi/be2iscsi/be_mgmt.c  | 167 +
 7 files changed, 355 insertions(+), 460 deletions(-)

-- 
2.5.0

--
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/12] be2iscsi: Couple MCC tag and WRB alloc and free

2016-02-01 Thread Jitendra Bhivare
WARN_ON(atomic_read(>used) >= mccq->len) seen when FW gets into UE.

MCCQ overflow is happening because driver discards any new request and
frees up the tag. The tag allocation controls the number of MCC WRB posted.
It is being replenished but WRBs are not hence the WARN_ON.

Allocation and freeing of WRB and tags for MCC is now done in one place.
This helps to achieve proper accounting of WRB indices and MCC tags.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  |   2 +-
 drivers/scsi/be2iscsi/be_cmds.c | 103 +-
 drivers/scsi/be2iscsi/be_cmds.h |   6 +-
 drivers/scsi/be2iscsi/be_main.c |   3 +-
 drivers/scsi/be2iscsi/be_mgmt.c | 134 +++-
 5 files changed, 130 insertions(+), 118 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index da1d87a..ee5ace8 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -42,7 +42,7 @@ struct be_queue_info {
u16 id;
u16 tail, head;
bool created;
-   atomic_t used;  /* Number of valid elements in the queue */
+   u16 used;   /* Number of valid elements in the queue */
 };
 
 static inline u32 MODULO(u16 val, u16 limit)
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 728aa133..a55eaee 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -126,8 +126,62 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
return tag;
 }
 
-void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
+struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
+unsigned int *ref_tag)
 {
+   struct be_queue_info *mccq = >ctrl.mcc_obj.q;
+   struct be_mcc_wrb *wrb = NULL;
+   unsigned int tag;
+
+   spin_lock_bh(>ctrl.mcc_lock);
+   if (mccq->used == mccq->len) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : MCC queue full: WRB used %u tag avail 
%u\n",
+   mccq->used, phba->ctrl.mcc_tag_available);
+   goto alloc_failed;
+   }
+
+   if (!phba->ctrl.mcc_tag_available)
+   goto alloc_failed;
+
+   tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
+   if (!tag) {
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT |
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : MCC tag 0 allocated: tag avail %u alloc 
index %u\n",
+   phba->ctrl.mcc_tag_available,
+   phba->ctrl.mcc_alloc_index);
+   goto alloc_failed;
+   }
+
+   /* return this tag for further reference */
+   *ref_tag = tag;
+   phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
+   phba->ctrl.mcc_tag_status[tag] = 0;
+   phba->ctrl.ptag_state[tag].tag_state = 0;
+   phba->ctrl.mcc_tag_available--;
+   if (phba->ctrl.mcc_alloc_index == (MAX_MCC_CMD - 1))
+   phba->ctrl.mcc_alloc_index = 0;
+   else
+   phba->ctrl.mcc_alloc_index++;
+
+   wrb = queue_head_node(mccq);
+   memset(wrb, 0, sizeof(*wrb));
+   wrb->tag0 = tag;
+   wrb->tag0 |= (mccq->head << MCC_Q_WRB_IDX_SHIFT) & MCC_Q_WRB_IDX_MASK;
+   queue_head_inc(mccq);
+   mccq->used++;
+
+alloc_failed:
+   spin_unlock_bh(>ctrl.mcc_lock);
+   return wrb;
+}
+
+void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag)
+{
+   struct be_queue_info *mccq = >mcc_obj.q;
+
spin_lock_bh(>mcc_lock);
tag = tag & MCC_Q_CMD_TAG_MASK;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
@@ -136,6 +190,7 @@ void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int 
tag)
else
ctrl->mcc_free_index++;
ctrl->mcc_tag_available++;
+   mccq->used--;
spin_unlock_bh(>mcc_lock);
 }
 
@@ -173,10 +228,8 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
struct be_cmd_resp_hdr *mbx_resp_hdr;
struct be_queue_info *mccq = >ctrl.mcc_obj.q;
 
-   if (beiscsi_error(phba)) {
-   free_mcc_tag(>ctrl, tag);
+   if (beiscsi_error(phba))
return -EPERM;
-   }
 
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
@@ -259,7 +312,7 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
}
}
 
-   free_mcc_tag(>ctrl, tag);
+   free_mcc_wrb(>ctrl, tag);
return rc;
 }
 
@@ -479,7 +532,7 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
if (tag_mem->size)
 

[PATCH 05/12] be2iscsi: Remove be_mbox_notify_wait function

2016-02-01 Thread Jitendra Bhivare
be_mbox_notify_wait does exactly same thing as be_mbox_notify.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 79 +++--
 1 file changed, 4 insertions(+), 75 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 8dd8521..12b60dd 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -625,8 +625,6 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
void __iomem *db = ctrl->db + MPU_MAILBOX_DB_OFFSET;
struct be_dma_mem *mbox_mem = >mbox_mem;
struct be_mcc_mailbox *mbox = mbox_mem->va;
-   struct be_mcc_compl *compl = >compl;
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
 
status = be_mbox_db_ready_poll(ctrl);
if (status)
@@ -654,77 +652,8 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
/* RDY is set; small delay before CQE read. */
udelay(1);
 
-   if (be_mcc_compl_is_new(compl)) {
-   status = beiscsi_process_mbox_compl(ctrl, compl);
-   be_mcc_compl_use(compl);
-   if (status) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : After be_mcc_compl_process\n");
-
-   return status;
-   }
-   } else {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : Invalid Mailbox Completion\n");
-
-   return -EBUSY;
-   }
-   return 0;
-}
-
-/*
- * Insert the mailbox address into the doorbell in two steps
- * Polls on the mbox doorbell till a command completion (or a timeout) occurs
- */
-static int be_mbox_notify_wait(struct beiscsi_hba *phba)
-{
-   int status;
-   u32 val = 0;
-   void __iomem *db = phba->ctrl.db + MPU_MAILBOX_DB_OFFSET;
-   struct be_dma_mem *mbox_mem = >ctrl.mbox_mem;
-   struct be_mcc_mailbox *mbox = mbox_mem->va;
-   struct be_mcc_compl *compl = >compl;
-   struct be_ctrl_info *ctrl = >ctrl;
-
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status)
-   return status;
-
-   val |= MPU_MAILBOX_DB_HI_MASK;
-   /* at bits 2 - 31 place mbox dma addr msb bits 34 - 63 */
-   val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
-   iowrite32(val, db);
-
-   /* wait for ready to be set */
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status != 0)
-   return status;
-
-   val = 0;
-   /* at bits 2 - 31 place mbox dma addr lsb bits 4 - 33 */
-   val |= (u32)(mbox_mem->dma >> 4) << 2;
-   iowrite32(val, db);
-
-   status = be_mbox_db_ready_poll(ctrl);
-   if (status != 0)
-   return status;
-
-   /* A cq entry has been made now */
-   if (be_mcc_compl_is_new(compl)) {
-   status = be_mcc_compl_process(ctrl, >compl);
-   be_mcc_compl_use(compl);
-   if (status)
-   return status;
-   } else {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : invalid mailbox completion\n");
-
-   return -EBUSY;
-   }
-   return 0;
+   status = beiscsi_process_mbox_compl(ctrl, >compl);
+   return status;
 }
 
 void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len,
@@ -1039,7 +968,7 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba,
 
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
 
-   status = be_mbox_notify_wait(phba);
+   status = be_mbox_notify(ctrl);
if (!status) {
struct be_cmd_resp_mcc_create *resp = embedded_payload(wrb);
mccq->id = le16_to_cpu(resp->id);
@@ -1381,7 +1310,7 @@ int beiscsi_cmd_reset_function(struct beiscsi_hba  *phba)
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM_COMMON,
   OPCODE_COMMON_FUNCTION_RESET, sizeof(*req));
-   status = be_mbox_notify_wait(phba);
+   status = be_mbox_notify(ctrl);
 
mutex_unlock(>mbox_lock);
return status;
-- 
2.5.0

--
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 12/12] be2iscsi: Add lock to protect WRB alloc and free

2016-02-01 Thread Jitendra Bhivare
FW got into UE after running IO stress test

With kernel change to split session lock in frwd_lock and back_lock for tx
and rx path correspondingly, in the IO path, common resource used in driver
such as WRB was left unprotected.

Add wrb_lock spinlock to protect allocation and freeing of WRB.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.c | 5 +
 drivers/scsi/be2iscsi/be_main.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index fa2b589..0892ee2 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -1190,12 +1190,14 @@ beiscsi_get_wrb_handle(struct hwi_wrb_context 
*pwrb_context,
 {
struct wrb_handle *pwrb_handle;
 
+   spin_lock_bh(_context->wrb_lock);
pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
pwrb_context->wrb_handles_available--;
if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
pwrb_context->alloc_index = 0;
else
pwrb_context->alloc_index++;
+   spin_unlock_bh(_context->wrb_lock);
 
return pwrb_handle;
 }
@@ -1227,12 +1229,14 @@ beiscsi_put_wrb_handle(struct hwi_wrb_context 
*pwrb_context,
   struct wrb_handle *pwrb_handle,
   unsigned int wrbs_per_cxn)
 {
+   spin_lock_bh(_context->wrb_lock);
pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
pwrb_context->wrb_handles_available++;
if (pwrb_context->free_index == (wrbs_per_cxn - 1))
pwrb_context->free_index = 0;
else
pwrb_context->free_index++;
+   spin_unlock_bh(_context->wrb_lock);
 }
 
 /**
@@ -2920,6 +2924,7 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba 
*phba)
}
num_cxn_wrbh--;
}
+   spin_lock_init(_context->wrb_lock);
}
idx = 0;
for (index = 0; index < phba->params.cxns_per_ctrl; index++) {
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 5ded3fa..30a4606 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -304,6 +304,7 @@ struct invalidate_command_table {
 #define BEISCSI_GET_ULP_FROM_CRI(phwi_ctrlr, cri) \
(phwi_ctrlr->wrb_context[cri].ulp_num)
 struct hwi_wrb_context {
+   spinlock_t wrb_lock;
struct list_head wrb_handle_list;
struct list_head wrb_handle_drvr_list;
struct wrb_handle **pwrb_handle_base;
-- 
2.5.0

--
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/12] be2iscsi: Remove redundant MCC processing code

2016-02-01 Thread Jitendra Bhivare
be_mcc_compl_process_isr is removed.
MCC CQ processing is done only in beiscsi_process_mcc_cq and MCC CQE
processing is done only in beiscsi_process_mcc_compl.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 164 ++--
 drivers/scsi/be2iscsi/be_cmds.h |   7 +-
 drivers/scsi/be2iscsi/be_main.c |   8 +-
 drivers/scsi/be2iscsi/be_main.h |   1 +
 drivers/scsi/be2iscsi/be_mgmt.c |   3 +-
 5 files changed, 68 insertions(+), 115 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index c5e7739..fa010ac 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -328,76 +328,6 @@ static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
return 0;
 }
 
-int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
-   struct be_mcc_compl *compl)
-{
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
-   u16 compl_status, extd_status;
-   struct be_dma_mem *tag_mem;
-   unsigned int tag, wrb_idx;
-
-   be_dws_le_to_cpu(compl, 4);
-   tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
-   wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
-
-   if (!test_bit(MCC_TAG_STATE_RUNNING,
- >ptag_state[tag].tag_state)) {
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX |
-   BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
-   "BC_%d : MBX cmd completed but not posted\n");
-   return 0;
-   }
-
-   if (test_bit(MCC_TAG_STATE_TIMEOUT,
->ptag_state[tag].tag_state)) {
-   beiscsi_log(phba, KERN_WARNING,
-   BEISCSI_LOG_MBOX | BEISCSI_LOG_INIT |
-   BEISCSI_LOG_CONFIG,
-   "BC_%d : MBX Completion for timeout Command from 
FW\n");
-   /**
-* Check for the size before freeing resource.
-* Only for non-embedded cmd, PCI resource is allocated.
-**/
-   tag_mem = >ptag_state[tag].tag_mem_state;
-   if (tag_mem->size)
-   pci_free_consistent(ctrl->pdev, tag_mem->size,
-   tag_mem->va, tag_mem->dma);
-   free_mcc_tag(ctrl, tag);
-   return 0;
-   }
-
-   compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
-  CQE_STATUS_COMPL_MASK;
-   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
- CQE_STATUS_EXTD_MASK;
-   /* The ctrl.mcc_tag_status[tag] is filled with
-* [31] = valid, [30:24] = Rsvd, [23:16] = wrb, [15:8] = extd_status,
-* [7:0] = compl_status
-*/
-   ctrl->mcc_tag_status[tag] = CQE_VALID_MASK;
-   ctrl->mcc_tag_status[tag] |= (wrb_idx << CQE_STATUS_WRB_SHIFT);
-   ctrl->mcc_tag_status[tag] |= (extd_status << CQE_STATUS_ADDL_SHIFT) &
-CQE_STATUS_ADDL_MASK;
-   ctrl->mcc_tag_status[tag] |= (compl_status & CQE_STATUS_MASK);
-
-   /* write ordering implied in wake_up_interruptible */
-   clear_bit(MCC_TAG_STATE_RUNNING, >ptag_state[tag].tag_state);
-   wake_up_interruptible(>mcc_wait[tag]);
-   return 0;
-}
-
-static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba)
-{
-   struct be_queue_info *mcc_cq = >ctrl.mcc_obj.cq;
-   struct be_mcc_compl *compl = queue_tail_node(mcc_cq);
-
-   if (be_mcc_compl_is_new(compl)) {
-   queue_tail_inc(mcc_cq);
-   return compl;
-   }
-   return NULL;
-}
-
 /**
  * beiscsi_fail_session(): Closing session with appropriate error
  * @cls_session: ptr to session
@@ -528,27 +458,65 @@ void beiscsi_process_async_event(struct beiscsi_hba *phba,
evt_code, compl->status, compl->flags);
 }
 
-int beiscsi_process_mcc(struct beiscsi_hba *phba)
+int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
+ struct be_mcc_compl *compl)
 {
-   struct be_mcc_compl *compl;
-   int num = 0, status = 0;
-   struct be_ctrl_info *ctrl = >ctrl;
+   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
+   u16 compl_status, extd_status;
+   struct be_dma_mem *tag_mem;
+   unsigned int tag, wrb_idx;
 
-   while ((compl = be_mcc_compl_get(phba))) {
-   if (compl->flags & CQE_FLAGS_ASYNC_MASK) {
-   beiscsi_process_async_event(phba, compl);
-   } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
-   status = be_mcc_compl_process(ctrl, compl);
-   atomic_dec(>ctrl.mcc_obj.q.used);

[PATCH 02/12] be2iscsi: Use macros for MCC WRB and CQE fields

2016-02-01 Thread Jitendra Bhivare
Rename mcc_numtag to mcc_tag_status.
MCC CQE status is processed using macros already defined in be_cmds.h.

Add MCC_Q_WRB_ and MCC_Q_CMD_TAG_MASK macros to map to already defined
CQE_STATUS_ macros to be consistent when posting MCC.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be.h  |  8 +++-
 drivers/scsi/be2iscsi/be_cmds.c | 40 +---
 drivers/scsi/be2iscsi/be_cmds.h | 13 +++--
 drivers/scsi/be2iscsi/be_main.c | 11 ++-
 4 files changed, 41 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h
index 1524fe4..da1d87a 100644
--- a/drivers/scsi/be2iscsi/be.h
+++ b/drivers/scsi/be2iscsi/be.h
@@ -135,7 +135,7 @@ struct be_ctrl_info {
 
wait_queue_head_t mcc_wait[MAX_MCC_CMD + 1];
unsigned int mcc_tag[MAX_MCC_CMD];
-   unsigned int mcc_numtag[MAX_MCC_CMD + 1];
+   unsigned int mcc_tag_status[MAX_MCC_CMD + 1];
unsigned short mcc_alloc_index;
unsigned short mcc_free_index;
unsigned int mcc_tag_available;
@@ -145,6 +145,12 @@ struct be_ctrl_info {
 
 #include "be_cmds.h"
 
+/* WRB index mask for MCC_Q_LEN queue entries */
+#define MCC_Q_WRB_IDX_MASK CQE_STATUS_WRB_MASK
+#define MCC_Q_WRB_IDX_SHIFTCQE_STATUS_WRB_SHIFT
+/* TAG is from 1...MAX_MCC_CMD, MASK includes MAX_MCC_CMD */
+#define MCC_Q_CMD_TAG_MASK ((MAX_MCC_CMD << 1) - 1)
+
 #define PAGE_SHIFT_4K 12
 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K)
 #define mcc_timeout12 /* 12s timeout */
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index e8e9d22..c5e7739 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -125,7 +125,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
if (phba->ctrl.mcc_tag_available) {
tag = phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index];
phba->ctrl.mcc_tag[phba->ctrl.mcc_alloc_index] = 0;
-   phba->ctrl.mcc_numtag[tag] = 0;
+   phba->ctrl.mcc_tag_status[tag] = 0;
phba->ctrl.ptag_state[tag].tag_state = 0;
}
if (tag) {
@@ -157,7 +157,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
struct be_dma_mem *mbx_cmd_mem)
 {
int rc = 0;
-   uint32_t mcc_tag_response;
+   uint32_t mcc_tag_status;
uint16_t status = 0, addl_status = 0, wrb_num = 0;
struct be_mcc_wrb *temp_wrb;
struct be_cmd_req_hdr *mbx_hdr;
@@ -172,7 +172,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
/* wait for the mccq completion */
rc = wait_event_interruptible_timeout(
phba->ctrl.mcc_wait[tag],
-   phba->ctrl.mcc_numtag[tag],
+   phba->ctrl.mcc_tag_status[tag],
msecs_to_jiffies(
BEISCSI_HOST_MBX_TIMEOUT));
/**
@@ -209,15 +209,15 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
}
 
rc = 0;
-   mcc_tag_response = phba->ctrl.mcc_numtag[tag];
-   status = (mcc_tag_response & CQE_STATUS_MASK);
-   addl_status = ((mcc_tag_response & CQE_STATUS_ADDL_MASK) >>
+   mcc_tag_status = phba->ctrl.mcc_tag_status[tag];
+   status = (mcc_tag_status & CQE_STATUS_MASK);
+   addl_status = ((mcc_tag_status & CQE_STATUS_ADDL_MASK) >>
CQE_STATUS_ADDL_SHIFT);
 
if (mbx_cmd_mem) {
mbx_hdr = (struct be_cmd_req_hdr *)mbx_cmd_mem->va;
} else {
-   wrb_num = (mcc_tag_response & CQE_STATUS_WRB_MASK) >>
+   wrb_num = (mcc_tag_status & CQE_STATUS_WRB_MASK) >>
   CQE_STATUS_WRB_SHIFT;
temp_wrb = (struct be_mcc_wrb *)queue_get_wrb(mccq, wrb_num);
mbx_hdr = embedded_payload(temp_wrb);
@@ -257,7 +257,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
 void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
 {
spin_lock(>mcc_lock);
-   tag = tag & 0x00FF;
+   tag = tag & MCC_Q_CMD_TAG_MASK;
ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
ctrl->mcc_free_index = 0;
@@ -334,10 +334,11 @@ int be_mcc_compl_process_isr(struct be_ctrl_info *ctrl,
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
u16 compl_status, extd_status;
struct be_dma_mem *tag_mem;
-   unsigned short tag;
+   unsigned int tag, wrb_idx;
 
be_dws_le_to_cpu(compl, 4);
-   tag = (compl->tag0 & 0x00FF);
+   tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
+   wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;

[PATCH 07/12] be2iscsi: Cleanup processing of BMBX completion

2016-02-01 Thread Jitendra Bhivare
Remove confusingly named be_mcc_compl_is_new and be_mcc_compl_use functions
in processing of BMBX. Rearrange beiscsi_process_mbox_compl function.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 75 -
 1 file changed, 36 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 60db2de..728aa133 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -263,21 +263,6 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
return rc;
 }
 
-static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
-{
-   if (compl->flags != 0) {
-   compl->flags = le32_to_cpu(compl->flags);
-   WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
-   return true;
-   } else
-   return false;
-}
-
-static inline void be_mcc_compl_use(struct be_mcc_compl *compl)
-{
-   compl->flags = 0;
-}
-
 /*
  * beiscsi_process_mbox_compl()- Check the MBX completion status
  * @ctrl: Function specific MBX data structure
@@ -298,30 +283,46 @@ static int beiscsi_process_mbox_compl(struct be_ctrl_info 
*ctrl,
struct be_cmd_req_hdr *hdr = embedded_payload(wrb);
struct be_cmd_resp_hdr *resp_hdr;
 
-   be_dws_le_to_cpu(compl, 4);
+   /**
+* To check if valid bit is set, check the entire word as we don't know
+* the endianness of the data (old entry is host endian while a new
+* entry is little endian)
+*/
+   if (!compl->flags) {
+   beiscsi_log(phba, KERN_ERR,
+   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : BMBX busy, no completion\n");
+   return -EBUSY;
+   }
+   compl->flags = le32_to_cpu(compl->flags);
+   WARN_ON((compl->flags & CQE_FLAGS_VALID_MASK) == 0);
 
+   /**
+* Just swap the status to host endian;
+* mcc tag is opaquely copied from mcc_wrb.
+*/
+   be_dws_le_to_cpu(compl, 4);
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
-   CQE_STATUS_COMPL_MASK;
-   if (compl_status != MCC_STATUS_SUCCESS) {
-   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
-   CQE_STATUS_EXTD_MASK;
+   CQE_STATUS_COMPL_MASK;
+   extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
+   CQE_STATUS_EXTD_MASK;
+   /* Need to reset the entire word that houses the valid bit */
+   compl->flags = 0;
 
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : error in cmd completion: "
-   "Subsystem : %d Opcode : %d "
-   "status(compl/extd)=%d/%d\n",
-   hdr->subsystem, hdr->opcode,
-   compl_status, extd_status);
-
-   if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
-   resp_hdr = (struct be_cmd_resp_hdr *) hdr;
-   if (resp_hdr->response_length)
-   return 0;
-   }
-   return -EINVAL;
+   if (compl_status == MCC_STATUS_SUCCESS)
+   return 0;
+
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : error in cmd completion: Subsystem : %d Opcode : 
%d status(compl/extd)=%d/%d\n",
+   hdr->subsystem, hdr->opcode, compl_status, extd_status);
+
+   if (compl_status == MCC_STATUS_INSUFFICIENT_BUFFER) {
+   /* if status is insufficient buffer, check the length */
+   resp_hdr = (struct be_cmd_resp_hdr *) hdr;
+   if (resp_hdr->response_length)
+   return 0;
}
-   return 0;
+   return -EINVAL;
 }
 
 static void beiscsi_process_async_link(struct beiscsi_hba *phba,
@@ -453,10 +454,6 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
struct be_dma_mem *tag_mem;
unsigned int tag, wrb_idx;
 
-   /**
-* Just swap the status to host endian; mcc tag is opaquely copied
-* from mcc_wrb
-*/
be_dws_le_to_cpu(compl, 4);
tag = (compl->tag0 & MCC_Q_CMD_TAG_MASK);
wrb_idx = (compl->tag0 & CQE_STATUS_WRB_MASK) >> CQE_STATUS_WRB_SHIFT;
-- 
2.5.0

--
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/12] be2iscsi: Rename MCC and BMBX processing functions

2016-02-01 Thread Jitendra Bhivare
beiscsi_mccq_compl -> beiscsi_mccq_compl_wait - indicate blocking call.
be_mcc_wait_compl -> be_mcc_compl_poll - indicate polling for completion.
be_mbox_db_ready_wait -> be_mbox_db_ready_poll - indicate polling for RDY.
be_mcc_compl_process -> beiscsi_process_mbox_compl - indicate BMBX compl.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c  | 35 +--
 drivers/scsi/be2iscsi/be_cmds.h  |  6 +++---
 drivers/scsi/be2iscsi/be_iscsi.c |  8 
 drivers/scsi/be2iscsi/be_main.c  |  8 
 drivers/scsi/be2iscsi/be_mgmt.c  | 12 ++--
 5 files changed, 34 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index fa010ac..8dd8521 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -140,7 +140,7 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 }
 
 /*
- * beiscsi_mccq_compl()- Wait for completion of MBX
+ * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
  * @phba: Driver private structure
  * @tag: Tag for the MBX Command
  * @wrb: the WRB used for the MBX Command
@@ -152,9 +152,9 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
  * Success: 0
  * Failure: Non-Zero
  **/
-int beiscsi_mccq_compl(struct beiscsi_hba *phba,
-   uint32_t tag, struct be_mcc_wrb **wrb,
-   struct be_dma_mem *mbx_cmd_mem)
+int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
+   uint32_t tag, struct be_mcc_wrb **wrb,
+   struct be_dma_mem *mbx_cmd_mem)
 {
int rc = 0;
uint32_t mcc_tag_status;
@@ -283,7 +283,7 @@ static inline void be_mcc_compl_use(struct be_mcc_compl 
*compl)
 }
 
 /*
- * be_mcc_compl_process()- Check the MBX comapletion status
+ * beiscsi_process_mbox_compl()- Check the MBX completion status
  * @ctrl: Function specific MBX data structure
  * @compl: Completion status of MBX Command
  *
@@ -293,8 +293,8 @@ static inline void be_mcc_compl_use(struct be_mcc_compl 
*compl)
  * Success: Zero
  * Failure: Non-Zero
  **/
-static int be_mcc_compl_process(struct be_ctrl_info *ctrl,
-   struct be_mcc_compl *compl)
+static int beiscsi_process_mbox_compl(struct be_ctrl_info *ctrl,
+ struct be_mcc_compl *compl)
 {
u16 compl_status, extd_status;
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
@@ -520,7 +520,7 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
 }
 
 /*
- * be_mcc_wait_compl()- Wait for MBX completion
+ * be_mcc_compl_poll()- Wait for MBX completion
  * @phba: driver private structure
  *
  * Wait till no more pending mcc requests are present
@@ -556,8 +556,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned 
int tag)
 }
 
 /*
-/*
- * be_mbox_db_ready_wait()- Check ready status
+ * be_mbox_db_ready_poll()- Check ready status
  * @ctrl: Function specific MBX data structure
  *
  * Check for the ready status of FW to send BMBX
@@ -567,7 +566,7 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned 
int tag)
  * Success: 0
  * Failure: Non-Zero
  **/
-static int be_mbox_db_ready_wait(struct be_ctrl_info *ctrl)
+static int be_mbox_db_ready_poll(struct be_ctrl_info *ctrl)
 {
/* wait 30s for generic non-flash MBOX operation */
 #define BEISCSI_MBX_RDY_BIT_TIMEOUT3
@@ -629,7 +628,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
struct be_mcc_compl *compl = >compl;
struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -638,7 +637,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
val |= (upper_32_bits(mbox_mem->dma) >> 2) << 2;
iowrite32(val, db);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -648,7 +647,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
val |= (u32) (mbox_mem->dma >> 4) << 2;
iowrite32(val, db);
 
-   status = be_mbox_db_ready_wait(ctrl);
+   status = be_mbox_db_ready_poll(ctrl);
if (status)
return status;
 
@@ -656,7 +655,7 @@ int be_mbox_notify(struct be_ctrl_info *ctrl)
udelay(1);
 
if (be_mcc_compl_is_new(compl)) {
-   status = be_mcc_compl_process(ctrl, >compl);
+   status = beiscsi_process_mbox_compl(ctrl, compl);
be_mcc_compl_use(compl);
if (status) {
beiscsi_log(phba, KERN_ERR,
@@ -689,7 +688,7 @@ static int be_mbox_notify_wait(struct beiscsi_hba *phba)
struct be_mcc_compl *compl = >compl;
struct be_ctrl_info *ctrl = >ctrl;
 
-   status = be_mbox_db_ready_wait(ctrl)

[PATCH 06/12] be2iscsi: Fix be_mcc_compl_poll to use tag_state

2016-02-01 Thread Jitendra Bhivare
be_mcc_compl_poll waits till 'used' count of MCC WRBQ is zero. This is to
determine the completion of an MCC sent.

Change function to poll for the tag of MCC sent, instead, and wait till
its tag_state is cleared.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 92 +
 1 file changed, 47 insertions(+), 45 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 12b60dd..60db2de 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -104,19 +104,6 @@ int be_chk_reset_complete(struct beiscsi_hba *phba)
return 0;
 }
 
-void be_mcc_notify(struct beiscsi_hba *phba, unsigned int tag)
-{
-   struct be_queue_info *mccq = >ctrl.mcc_obj.q;
-   u32 val = 0;
-
-   set_bit(MCC_TAG_STATE_RUNNING, >ctrl.ptag_state[tag].tag_state);
-   val |= mccq->id & DB_MCCQ_RING_ID_MASK;
-   val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
-   /* ring doorbell after all of request and state is written */
-   wmb();
-   iowrite32(val, phba->db_va + DB_MCCQ_OFFSET);
-}
-
 unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
 {
unsigned int tag = 0;
@@ -139,6 +126,28 @@ unsigned int alloc_mcc_tag(struct beiscsi_hba *phba)
return tag;
 }
 
+void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
+{
+   spin_lock_bh(>mcc_lock);
+   tag = tag & MCC_Q_CMD_TAG_MASK;
+   ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
+   if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
+   ctrl->mcc_free_index = 0;
+   else
+   ctrl->mcc_free_index++;
+   ctrl->mcc_tag_available++;
+   spin_unlock_bh(>mcc_lock);
+}
+
+/**
+ * beiscsi_fail_session(): Closing session with appropriate error
+ * @cls_session: ptr to session
+ **/
+void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
+{
+   iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
+}
+
 /*
  * beiscsi_mccq_compl_wait()- Process completion in MCC CQ
  * @phba: Driver private structure
@@ -254,19 +263,6 @@ int beiscsi_mccq_compl_wait(struct beiscsi_hba *phba,
return rc;
 }
 
-void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag)
-{
-   spin_lock(>mcc_lock);
-   tag = tag & MCC_Q_CMD_TAG_MASK;
-   ctrl->mcc_tag[ctrl->mcc_free_index] = tag;
-   if (ctrl->mcc_free_index == (MAX_MCC_CMD - 1))
-   ctrl->mcc_free_index = 0;
-   else
-   ctrl->mcc_free_index++;
-   ctrl->mcc_tag_available++;
-   spin_unlock(>mcc_lock);
-}
-
 static inline bool be_mcc_compl_is_new(struct be_mcc_compl *compl)
 {
if (compl->flags != 0) {
@@ -328,15 +324,6 @@ static int beiscsi_process_mbox_compl(struct be_ctrl_info 
*ctrl,
return 0;
 }
 
-/**
- * beiscsi_fail_session(): Closing session with appropriate error
- * @cls_session: ptr to session
- **/
-void beiscsi_fail_session(struct iscsi_cls_session *cls_session)
-{
-   iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED);
-}
-
 static void beiscsi_process_async_link(struct beiscsi_hba *phba,
   struct be_mcc_compl *compl)
 {
@@ -532,6 +519,7 @@ int beiscsi_process_mcc_compl(struct be_ctrl_info *ctrl,
  **/
 int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned int tag)
 {
+   struct be_ctrl_info *ctrl = >ctrl;
int i;
 
for (i = 0; i < mcc_timeout; i++) {
@@ -540,19 +528,33 @@ int be_mcc_compl_poll(struct beiscsi_hba *phba, unsigned 
int tag)
 
beiscsi_process_mcc_cq(phba);
 
-   if (atomic_read(>ctrl.mcc_obj.q.used) == 0)
+   if (!test_bit(MCC_TAG_STATE_RUNNING,
+ >ptag_state[tag].tag_state))
break;
udelay(100);
}
-   if (i == mcc_timeout) {
-   beiscsi_log(phba, KERN_ERR,
-   BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
-   "BC_%d : FW Timed Out\n");
-   phba->fw_timeout = true;
-   beiscsi_ue_detect(phba);
-   return -EBUSY;
-   }
-   return 0;
+
+   if (i < mcc_timeout)
+   return 0;
+
+   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
+   "BC_%d : FW Timed Out\n");
+   phba->fw_timeout = true;
+   beiscsi_ue_detect(phba);
+   return -EBUSY;
+}
+
+void be_mcc_notify(struct beiscsi_hba *phba, unsigned int tag)
+{
+   struct be_queue_info *mccq = >ctrl.mcc_obj.q;
+   u32 val = 0;
+
+   set_bit(MCC_TAG_STATE_RUNNING, >ctrl.ptag_state[tag].tag_state);
+   val |= mccq->id & DB_MCCQ_RING_ID_MASK;
+   val |= 1 << DB_MCCQ_NUM_POSTED_SHIFT;
+   /* make request available for DMA */
+ 

[PATCH 10/12] be2iscsi: Fix ExpStatSn in management tasks

2016-02-01 Thread Jitendra Bhivare
Connection resets observed from some targets when NOP-Out with wrong
ExpStatSn is sent.

FW keeps track of StatSn and fills up ExpStatSn accordingly.
The header filled up by the stack needs to be modified by driver to clear
ExpStatSn. If the field is not cleared, FW recalculates ExpStatSn and
wrong offset'ed ExpStatSn is seen in the wire trace.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@avagotech.com>
---
 drivers/scsi/be2iscsi/be_main.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 3f08a11..03265b6 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -4926,7 +4926,6 @@ int beiscsi_iotask_v2(struct iscsi_task *task, struct 
scatterlist *sg,
 
pwrb = io_task->pwrb_handle->pwrb;
 
-   io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
if (writedir) {
@@ -4987,7 +4986,6 @@ static int beiscsi_iotask(struct iscsi_task *task, struct 
scatterlist *sg,
unsigned int doorbell = 0;
 
pwrb = io_task->pwrb_handle->pwrb;
-   io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
io_task->bhs_len = sizeof(struct be_cmd_bhs);
 
if (writedir) {
@@ -5159,23 +5157,21 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
 {
struct beiscsi_io_task *io_task = task->dd_data;
struct scsi_cmnd *sc = task->sc;
-   struct beiscsi_hba *phba = NULL;
+   struct beiscsi_hba *phba;
struct scatterlist *sg;
int num_sg;
unsigned int  writedir = 0, xferlen = 0;
 
-   phba = ((struct beiscsi_conn *)task->conn->dd_data)->phba;
+   if (!io_task->conn->login_in_progress)
+   task->hdr->exp_statsn = 0;
 
if (!sc)
return beiscsi_mtask(task);
 
io_task->scsi_cmnd = sc;
num_sg = scsi_dma_map(sc);
+   phba = io_task->conn->phba;
if (num_sg < 0) {
-   struct iscsi_conn *conn = task->conn;
-   struct beiscsi_hba *phba = NULL;
-
-   phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
beiscsi_log(phba, KERN_ERR,
BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI,
"BM_%d : scsi_dma_map Failed "
-- 
2.5.0

--
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 resend 1/2] be2iscsi: Remove unnecessary synchronize_irq() before free_irq()

2016-03-06 Thread Jitendra Bhivare
>-Original Message-
>From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>ow...@vger.kernel.org] On Behalf Of Lars-Peter Clausen
>Sent: Friday, March 04, 2016 3:45 PM
>To: James E.J. Bottomley; Martin K. Petersen
>Cc: Sathya Prakash; Chaitra P B; Suganath Prabu Subramani; Jitendra
Bhivare;
>linux-scsi@vger.kernel.org; mpt-fusionlinux@broadcom.com; Lars-Peter
>Clausen
>Subject: [PATCH resend 1/2] be2iscsi: Remove unnecessary
synchronize_irq()
>before free_irq()
>
>Calling synchronize_irq() right before free_irq() is quite useless. On
one hand the
>IRQ can easily fire again before free_irq() is entered, on the other hand
free_irq()
>itself calls synchronize_irq() internally (in a race condition free way),
before any
>state associated with the IRQ is freed.
>
>Patch was generated using the following semantic patch:
>// 
>@@
>expression irq;
>@@
>-synchronize_irq(irq);
> free_irq(irq, ...);
>// 
>
>Signed-off-by: Lars-Peter Clausen <l...@metafoo.de>
>---
> drivers/scsi/be2iscsi/be_main.c | 5 +
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
>diff --git a/drivers/scsi/be2iscsi/be_main.c
b/drivers/scsi/be2iscsi/be_main.c
>index b51e726..e89a0f8d 100644
>--- a/drivers/scsi/be2iscsi/be_main.c
>+++ b/drivers/scsi/be2iscsi/be_main.c
>@@ -5303,15 +5303,12 @@ static void beiscsi_quiesce(struct beiscsi_hba
*phba,
>   if (phba->msix_enabled) {
>   for (i = 0; i <= phba->num_cpus; i++) {
>   msix_vec = phba->msix_entries[i].vector;
>-  synchronize_irq(msix_vec);
>   free_irq(msix_vec, _context->be_eq[i]);
>   kfree(phba->msi_name[i]);
>   }
>   } else
>-  if (phba->pcidev->irq) {
>-  synchronize_irq(phba->pcidev->irq);
>+  if (phba->pcidev->irq)
>   free_irq(phba->pcidev->irq, phba);
>-  }
>   pci_disable_msix(phba->pcidev);
>   cancel_delayed_work_sync(>beiscsi_hw_check_task);
>
>--
>2.1.4

Reviewed-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>

Thanks,

JB
--
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] be2iscsi: set the boot_kset pointer to NULL in case of failure

2016-03-06 Thread Jitendra Bhivare
>-Original Message-
>From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi-
>ow...@vger.kernel.org] On Behalf Of Maurizio Lombardi
>Sent: Friday, March 04, 2016 3:12 PM
>To: jayamohan.kallic...@avagotech.com
>Cc: ketan.muka...@avagotech.com; sony.j...@avagotech.com; linux-
>s...@vger.kernel.org
>Subject: [PATCH] be2iscsi: set the boot_kset pointer to NULL in case of
failure
>
>In beiscsi_setup_boot_info(), the boot_kset pointer should be set to NULL
in case
>of failure otherwise an invalid pointer dereference may occur later.
>
>Signed-off-by: Maurizio Lombardi <mlomb...@redhat.com>
>---
> drivers/scsi/be2iscsi/be_main.c | 1 +
> 1 file changed, 1 insertion(+)
>
>diff --git a/drivers/scsi/be2iscsi/be_main.c
b/drivers/scsi/be2iscsi/be_main.c
>index cb9072a..069e5c5 100644
>--- a/drivers/scsi/be2iscsi/be_main.c
>+++ b/drivers/scsi/be2iscsi/be_main.c
>@@ -4468,6 +4468,7 @@ put_shost:
>   scsi_host_put(phba->shost);
> free_kset:
>   iscsi_boot_destroy_kset(phba->boot_kset);
>+  phba->boot_kset = NULL;
>   return -ENOMEM;
> }
>
>--
>Maurizio Lombardi
>
>--
>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

Reviewed-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>

Thanks,

JB
--
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 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore

2016-08-10 Thread Jitendra Bhivare
> -Original Message-
> From: Mike Christie [mailto:mchri...@redhat.com]
> Sent: Tuesday, August 09, 2016 11:19 PM
> To: Jitendra Bhivare; Martin K. Petersen
> Cc: linux-scsi@vger.kernel.org
> Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore
>
> On 08/09/2016 03:29 AM, Jitendra Bhivare wrote:
> >> -Original Message-
> >> From: Martin K. Petersen [mailto:martin.peter...@oracle.com]
> >> Sent: Tuesday, August 09, 2016 6:35 AM
> >> To: Mike Christie
> >> Cc: Jitendra Bhivare; linux-scsi@vger.kernel.org
> >> Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > _irqsave/irqrestore
> >>
> >>>>>>> "Mike" == Mike Christie <mchri...@redhat.com> writes:
> >>
> >>>> In beiscsi_alloc_pdu, _bh versions of spin_lock are being used for
> >>>> protecting SGLs and WRBs. _bh versions are needed as the function
> >>>> gets invoked in process context and BLOCK_IOPOLL softirq.
> >>>>
> >>>> In spin_unlock_bh, after releasing the lock and enabling BH,
> >>>> do_softirq is called which executes till last SOFTIRQ.
> >>>>
> >>>> beiscsi_alloc_pdu is called under session lock. Through block
> >>>> layer, iSCSI stack in some cases send IOs with interrupts disabled.
> >>>> In such paths,
> >>
> >>
> >> Mike> What path is this? Is this with mq enabled or disabled?
> >>
> >> Jitendra?
> >>
> >> --
> >> Martin K. Petersen Oracle Linux Engineering
> > [JB] Sorry for the delayed response, there was some issue with my mail
> > client.
> > There are paths block layer where IRQs are disabled with request_queue
> > queue_lock.
> > - blk_timeout_work : this triggers NOP-OUT thru' iscsi_eh_cmd_timed_out.
> > - blk_execute_rq_nowait
>
> I am not sure I understand the problem/solution. Why does the patch only
> need
> to modify be2iscsi's locking? Why wouldn't you need to also change the
> libiscsi
> session lock locking? You don't need irqs to be running right? You are
> just doing
> this so the locking calls (irq vs bh) matches up?
>
> Don't you also need to fix the non-mq IO path. scsi_request_fn needs a fix
> to use
> spin_lock_irqsave/spin_unlock_irqrestore because blk_execute_rq_nowait
> already disables them right?
>
[JB] The issue is hard lockup seen on a CPU which is waiting for session
lock taken by another
CPU processing do_softirq. This do_softirq is getting called from be2iscsi
spin_unlock_bh.

The contention gets easily exposed with be2iscsi as it data structures are
accessed in process context
and IRQ_POLL softirq.

iscsi_eh_cmd_timed_out gets saved because it is using base spin_lock version
for session lock (frwd and back).
iscsi_queuecommand is using _bh which is bit scary.

Yes, that needs to be fixed too... and then this other path looks buggy
too -
blk_run_queue (takes queue_lock with irqsave) ->scsi_request_fn (unlocks it
with _irq)
--
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 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore

2016-08-12 Thread Jitendra Bhivare
> -Original Message-
> From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> Sent: Friday, August 12, 2016 1:26 PM
> To: 'Mike Christie'; 'Martin K. Petersen'
> Cc: 'linux-scsi@vger.kernel.org'
> Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore
>
>
>
> > -Original Message-
> > From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> > Sent: Thursday, August 11, 2016 11:12 AM
> > To: 'Mike Christie'; 'Martin K. Petersen'
> > Cc: 'linux-scsi@vger.kernel.org'
> > Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with
> > _irqsave/irqrestore
> >
> >
> >
> > > -Original Message-
> > > From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> > > Sent: Wednesday, August 10, 2016 6:16 PM
> > > To: 'Mike Christie'; 'Martin K. Petersen'
> > > Cc: 'linux-scsi@vger.kernel.org'
> > > Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with
> > > _irqsave/irqrestore
> > >
> > > > -Original Message-
> > > > From: Mike Christie [mailto:mchri...@redhat.com]
> > > > Sent: Tuesday, August 09, 2016 11:19 PM
> > > > To: Jitendra Bhivare; Martin K. Petersen
> > > > Cc: linux-scsi@vger.kernel.org
> > > > Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > > > _irqsave/irqrestore
> > > >
> > > > On 08/09/2016 03:29 AM, Jitendra Bhivare wrote:
> > > > >> -Original Message-
> > > > >> From: Martin K. Petersen [mailto:martin.peter...@oracle.com]
> > > > >> Sent: Tuesday, August 09, 2016 6:35 AM
> > > > >> To: Mike Christie
> > > > >> Cc: Jitendra Bhivare; linux-scsi@vger.kernel.org
> > > > >> Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > > > > _irqsave/irqrestore
> > > > >>
> > > > >>>>>>> "Mike" == Mike Christie <mchri...@redhat.com> writes:
> > > > >>
> > > > >>>> In beiscsi_alloc_pdu, _bh versions of spin_lock are being
> > > > >>>> used for protecting SGLs and WRBs. _bh versions are needed as
> > > > >>>> the function gets invoked in process context and BLOCK_IOPOLL
> softirq.
> > > > >>>>
> > > > >>>> In spin_unlock_bh, after releasing the lock and enabling BH,
> > > > >>>> do_softirq is called which executes till last SOFTIRQ.
> > > > >>>>
> > > > >>>> beiscsi_alloc_pdu is called under session lock. Through block
> > > > >>>> layer, iSCSI stack in some cases send IOs with interrupts
> > > > >>>> disabled.
> > > > >>>> In such paths,
> > > > >>
> > > > >>
> > > > >> Mike> What path is this? Is this with mq enabled or disabled?
> > > > >>
> > > > >> Jitendra?
> > > > >>
> > > > >> --
> > > > >> Martin K. Petersen   Oracle Linux Engineering
> > > > > [JB] Sorry for the delayed response, there was some issue with
> > > > > my mail client.
> > > > > There are paths block layer where IRQs are disabled with
> > > > > request_queue queue_lock.
> > > > > - blk_timeout_work : this triggers NOP-OUT thru'
> iscsi_eh_cmd_timed_out.
> > > > > - blk_execute_rq_nowait
> > > >
> > > > I am not sure I understand the problem/solution. Why does the
> > > > patch only need to modify be2iscsi's locking? Why wouldn't you
> > > > need to also change the libiscsi session lock locking? You don't
> > > > need irqs to be running right? You are just doing this so the
> > > > locking calls (irq vs bh) matches
> > > up?
> > > >
> > > > Don't you also need to fix the non-mq IO path. scsi_request_fn
> > > > needs a fix to use spin_lock_irqsave/spin_unlock_irqrestore
> > > > because blk_execute_rq_nowait already disables them right?
> > > >
> > > [JB] The issue is hard lockup seen on a CPU which is waiting for
> > > session lock taken by another CPU processing do_softirq. This
> > > do_softirq is getting called from be2iscsi spin_unlock_bh.
> > >
> > > The contention gets easily exposed with be2iscsi as it data
> > > structures are accessed in process context and IRQ_POLL softirq.
> > >
> &g

RE: [PATCH 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore

2016-08-12 Thread Jitendra Bhivare
> -Original Message-
> From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> Sent: Thursday, August 11, 2016 11:12 AM
> To: 'Mike Christie'; 'Martin K. Petersen'
> Cc: 'linux-scsi@vger.kernel.org'
> Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore
>
>
>
> > -Original Message-
> > From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> > Sent: Wednesday, August 10, 2016 6:16 PM
> > To: 'Mike Christie'; 'Martin K. Petersen'
> > Cc: 'linux-scsi@vger.kernel.org'
> > Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with
> > _irqsave/irqrestore
> >
> > > -Original Message-
> > > From: Mike Christie [mailto:mchri...@redhat.com]
> > > Sent: Tuesday, August 09, 2016 11:19 PM
> > > To: Jitendra Bhivare; Martin K. Petersen
> > > Cc: linux-scsi@vger.kernel.org
> > > Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > > _irqsave/irqrestore
> > >
> > > On 08/09/2016 03:29 AM, Jitendra Bhivare wrote:
> > > >> -Original Message-----
> > > >> From: Martin K. Petersen [mailto:martin.peter...@oracle.com]
> > > >> Sent: Tuesday, August 09, 2016 6:35 AM
> > > >> To: Mike Christie
> > > >> Cc: Jitendra Bhivare; linux-scsi@vger.kernel.org
> > > >> Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > > > _irqsave/irqrestore
> > > >>
> > > >>>>>>> "Mike" == Mike Christie <mchri...@redhat.com> writes:
> > > >>
> > > >>>> In beiscsi_alloc_pdu, _bh versions of spin_lock are being used
> > > >>>> for protecting SGLs and WRBs. _bh versions are needed as the
> > > >>>> function gets invoked in process context and BLOCK_IOPOLL
> > > >>>> softirq.
> > > >>>>
> > > >>>> In spin_unlock_bh, after releasing the lock and enabling BH,
> > > >>>> do_softirq is called which executes till last SOFTIRQ.
> > > >>>>
> > > >>>> beiscsi_alloc_pdu is called under session lock. Through block
> > > >>>> layer, iSCSI stack in some cases send IOs with interrupts
> > > >>>> disabled.
> > > >>>> In such paths,
> > > >>
> > > >>
> > > >> Mike> What path is this? Is this with mq enabled or disabled?
> > > >>
> > > >> Jitendra?
> > > >>
> > > >> --
> > > >> Martin K. Petersen Oracle Linux Engineering
> > > > [JB] Sorry for the delayed response, there was some issue with my
> > > > mail client.
> > > > There are paths block layer where IRQs are disabled with
> > > > request_queue queue_lock.
> > > > - blk_timeout_work : this triggers NOP-OUT thru'
> > > > iscsi_eh_cmd_timed_out.
> > > > - blk_execute_rq_nowait
> > >
> > > I am not sure I understand the problem/solution. Why does the patch
> > > only need to modify be2iscsi's locking? Why wouldn't you need to
> > > also change the libiscsi session lock locking? You don't need irqs
> > > to be running right? You are just doing this so the locking calls
> > > (irq vs bh) matches
> > up?
> > >
> > > Don't you also need to fix the non-mq IO path. scsi_request_fn needs
> > > a fix to use spin_lock_irqsave/spin_unlock_irqrestore because
> > > blk_execute_rq_nowait already disables them right?
> > >
> > [JB] The issue is hard lockup seen on a CPU which is waiting for
> > session lock taken by another CPU processing do_softirq. This
> > do_softirq is getting called from be2iscsi spin_unlock_bh.
> >
> > The contention gets easily exposed with be2iscsi as it data structures
> > are accessed in process context and IRQ_POLL softirq.
> >
> > iscsi_eh_cmd_timed_out gets saved because it is using base spin_lock
> > version for session lock (frwd and back).
> > iscsi_queuecommand is using _bh which is bit scary.
> >
> > Yes, that needs to be fixed too... and then this other path looks
> > buggy too - blk_run_queue (takes queue_lock with irqsave)
> > ->scsi_request_fn (unlocks it with
> > _irq)
> [JB] In this case, the other CPU executing do_softirq was too sending IO
> under
> session lock.
> When be2iscsi does spin_unlock_bh after getting resources for the IO,
> unlock_bh finds pending IRQ_POLL softirq.
>
> The issue is more to do with driver using _unlock_bh.
> It is causing a WARN_ON too in unlock_bh where ever used  for disabled
> IRQs.
[JB] My apologies. blk_execute_rq_nowait and the call trace shown is with
older kernel.
Only valid kernel trace with latest kernel is:
[  180.957062][] dump_stack+0x19/0x1b
[  180.957070]  [] warn_slowpath_common+0x6b/0xb0
[  180.957072]  [] warn_slowpath_null+0x1a/0x20
[  180.957073]  [] local_bh_enable_ip+0x7a/0xa0
[  180.957077]  [] _raw_spin_unlock_bh+0x1b/0x40
[  180.957084]  [] alloc_mgmt_sgl_handle+0x83/0xe0
[be2iscsi]
[  180.957089]  [] beiscsi_alloc_pdu+0x21e/0x5d0
[be2iscsi]
[  180.957094]  [] __iscsi_conn_send_pdu+0x101/0x2e0
[libiscsi]
[  180.957099]  [] iscsi_send_nopout+0xb8/0x100 [libiscsi]
[  180.957104]  [] iscsi_eh_cmd_timed_out+0x2a4/0x2d0
[libiscsi]
[  180.957107]  [] scsi_times_out+0x5e/0x320
--
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 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore

2016-08-10 Thread Jitendra Bhivare
> -Original Message-
> From: Jitendra Bhivare [mailto:jitendra.bhiv...@broadcom.com]
> Sent: Wednesday, August 10, 2016 6:16 PM
> To: 'Mike Christie'; 'Martin K. Petersen'
> Cc: 'linux-scsi@vger.kernel.org'
> Subject: RE: [PATCH 02/28] be2iscsi: Replace _bh with _irqsave/irqrestore
>
> > -Original Message-
> > From: Mike Christie [mailto:mchri...@redhat.com]
> > Sent: Tuesday, August 09, 2016 11:19 PM
> > To: Jitendra Bhivare; Martin K. Petersen
> > Cc: linux-scsi@vger.kernel.org
> > Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > _irqsave/irqrestore
> >
> > On 08/09/2016 03:29 AM, Jitendra Bhivare wrote:
> > >> -Original Message-
> > >> From: Martin K. Petersen [mailto:martin.peter...@oracle.com]
> > >> Sent: Tuesday, August 09, 2016 6:35 AM
> > >> To: Mike Christie
> > >> Cc: Jitendra Bhivare; linux-scsi@vger.kernel.org
> > >> Subject: Re: [PATCH 02/28] be2iscsi: Replace _bh with
> > > _irqsave/irqrestore
> > >>
> > >>>>>>> "Mike" == Mike Christie <mchri...@redhat.com> writes:
> > >>
> > >>>> In beiscsi_alloc_pdu, _bh versions of spin_lock are being used
> > >>>> for protecting SGLs and WRBs. _bh versions are needed as the
> > >>>> function gets invoked in process context and BLOCK_IOPOLL softirq.
> > >>>>
> > >>>> In spin_unlock_bh, after releasing the lock and enabling BH,
> > >>>> do_softirq is called which executes till last SOFTIRQ.
> > >>>>
> > >>>> beiscsi_alloc_pdu is called under session lock. Through block
> > >>>> layer, iSCSI stack in some cases send IOs with interrupts disabled.
> > >>>> In such paths,
> > >>
> > >>
> > >> Mike> What path is this? Is this with mq enabled or disabled?
> > >>
> > >> Jitendra?
> > >>
> > >> --
> > >> Martin K. Petersen   Oracle Linux Engineering
> > > [JB] Sorry for the delayed response, there was some issue with my
> > > mail client.
> > > There are paths block layer where IRQs are disabled with
> > > request_queue queue_lock.
> > > - blk_timeout_work : this triggers NOP-OUT thru'
> > > iscsi_eh_cmd_timed_out.
> > > - blk_execute_rq_nowait
> >
> > I am not sure I understand the problem/solution. Why does the patch
> > only need to modify be2iscsi's locking? Why wouldn't you need to also
> > change the libiscsi session lock locking? You don't need irqs to be
> > running right? You are just doing this so the locking calls (irq vs bh)
> > matches
> up?
> >
> > Don't you also need to fix the non-mq IO path. scsi_request_fn needs a
> > fix to use spin_lock_irqsave/spin_unlock_irqrestore because
> > blk_execute_rq_nowait already disables them right?
> >
> [JB] The issue is hard lockup seen on a CPU which is waiting for session
> lock
> taken by another CPU processing do_softirq. This do_softirq is getting
> called
> from be2iscsi spin_unlock_bh.
>
> The contention gets easily exposed with be2iscsi as it data structures are
> accessed in process context and IRQ_POLL softirq.
>
> iscsi_eh_cmd_timed_out gets saved because it is using base spin_lock
> version
> for session lock (frwd and back).
> iscsi_queuecommand is using _bh which is bit scary.
>
> Yes, that needs to be fixed too... and then this other path looks buggy
> too -
> blk_run_queue (takes queue_lock with irqsave) ->scsi_request_fn (unlocks
> it with
> _irq)
[JB] In this case, the other CPU executing do_softirq was too sending IO
under session lock.
When be2iscsi does spin_unlock_bh after getting resources for the IO,
unlock_bh finds pending IRQ_POLL softirq.

The issue is more to do with driver using _unlock_bh.
It is causing a WARN_ON too in unlock_bh where ever used  for disabled IRQs.
--
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 20/28] be2iscsi: Fix POST check and reset sequence

2016-07-21 Thread Jitendra Bhivare
SLIPORT FUNCTION_RESET does not reset the chip.
So POST status needs to be checked before issuing FUNCTION_RESET.
The completion of FUNCTION_RESET is indicated in BMBX Rdy bit.

be_cmd_fw_initialize too needs to be done before issuing any cmd to FW.
be_cmd_fw_initialize is renamed as beiscsi_cmd_special_wrb.
Rearrange and rename few functions in init and cleanup path.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 250 +++-
 drivers/scsi/be2iscsi/be_cmds.h |  38 +++---
 drivers/scsi/be2iscsi/be_main.c |  64 --
 drivers/scsi/be2iscsi/be_main.h |   8 --
 4 files changed, 164 insertions(+), 196 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index 1ebb6ce..771670c 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -21,35 +21,6 @@
 #include "be.h"
 #include "be_mgmt.h"
 
-int be_chk_reset_complete(struct beiscsi_hba *phba)
-{
-   unsigned int num_loop;
-   u8 *mpu_sem = 0;
-   u32 status;
-
-   num_loop = 1000;
-   mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE;
-   msleep(5000);
-
-   while (num_loop) {
-   status = readl((void *)mpu_sem);
-
-   if ((status & 0x8000) || (status & 0x) == 0xC000)
-   break;
-   msleep(60);
-   num_loop--;
-   }
-
-   if ((status & 0x8000) || (!num_loop)) {
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-   "BC_%d : Failed in be_chk_reset_complete"
-   "status = 0x%x\n", status);
-   return -EIO;
-   }
-
-   return 0;
-}
-
 struct be_mcc_wrb *alloc_mcc_wrb(struct beiscsi_hba *phba,
 unsigned int *ref_tag)
 {
@@ -769,87 +740,6 @@ int beiscsi_cmd_eq_create(struct be_ctrl_info *ctrl,
return status;
 }
 
-/**
- * be_cmd_fw_initialize()- Initialize FW
- * @ctrl: Pointer to function control structure
- *
- * Send FW initialize pattern for the function.
- *
- * return
- * Success: 0
- * Failure: Non-Zero value
- **/
-int be_cmd_fw_initialize(struct be_ctrl_info *ctrl)
-{
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
-   int status;
-   u8 *endian_check;
-
-   mutex_lock(>mbox_lock);
-   memset(wrb, 0, sizeof(*wrb));
-
-   endian_check = (u8 *) wrb;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0x12;
-   *endian_check++ = 0x34;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0x56;
-   *endian_check++ = 0x78;
-   *endian_check++ = 0xFF;
-   be_dws_cpu_to_le(wrb, sizeof(*wrb));
-
-   status = be_mbox_notify(ctrl);
-   if (status)
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-   "BC_%d : be_cmd_fw_initialize Failed\n");
-
-   mutex_unlock(>mbox_lock);
-   return status;
-}
-
-/**
- * be_cmd_fw_uninit()- Uinitialize FW
- * @ctrl: Pointer to function control structure
- *
- * Send FW uninitialize pattern for the function
- *
- * return
- * Success: 0
- * Failure: Non-Zero value
- **/
-int be_cmd_fw_uninit(struct be_ctrl_info *ctrl)
-{
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct beiscsi_hba *phba = pci_get_drvdata(ctrl->pdev);
-   int status;
-   u8 *endian_check;
-
-   mutex_lock(>mbox_lock);
-   memset(wrb, 0, sizeof(*wrb));
-
-   endian_check = (u8 *) wrb;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0xAA;
-   *endian_check++ = 0xBB;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0xFF;
-   *endian_check++ = 0xCC;
-   *endian_check++ = 0xDD;
-   *endian_check = 0xFF;
-
-   be_dws_cpu_to_le(wrb, sizeof(*wrb));
-
-   status = be_mbox_notify(ctrl);
-   if (status)
-   beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
-   "BC_%d : be_cmd_fw_uninit Failed\n");
-
-   mutex_unlock(>mbox_lock);
-   return status;
-}
-
 int beiscsi_cmd_cq_create(struct be_ctrl_info *ctrl,
  struct be_queue_info *cq, struct be_queue_info *eq,
  bool sol_evts, bool no_delay, int coalesce_wm)
@@ -1293,25 +1183,6 @@ error:
return status;
 }
 
-int beiscsi_cmd_reset_function(struct beiscsi_hba  *phba)
-{
-   struct be_ctrl_info *ctrl = >ctrl;
-   struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
-   struct be_post_sgl_pages_req *req = embedded_payload(wrb);
-   int status;
-
-   mutex_lock(>mbox_lock);
-
-   req = embedded_payload(wrb);
-   be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0);
-   be_cmd_hdr_prepare(>hdr, CMD_SUBSYSTEM

[PATCH 24/28] be2iscsi: Add FUNCTION_RESET during driver unload

2016-07-21 Thread Jitendra Bhivare
Driver unload should call COMMON_FUNCTION_RESET. For TPE feature, this
ensures that FW has knowledge about driver getting unloaded and can
reset its bit vector.

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
---
 drivers/scsi/be2iscsi/be_cmds.c | 2 +-
 drivers/scsi/be2iscsi/be_cmds.h | 2 ++
 drivers/scsi/be2iscsi/be_main.c | 3 +++
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index ad7405d..5fe1610 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -1595,7 +1595,7 @@ int beiscsi_check_fw_rdy(struct beiscsi_hba *phba)
return rdy;
 }
 
-static int beiscsi_cmd_function_reset(struct beiscsi_hba  *phba)
+int beiscsi_cmd_function_reset(struct beiscsi_hba *phba)
 {
struct be_ctrl_info *ctrl = >ctrl;
struct be_mcc_wrb *wrb = wrb_from_mbox(>mbox_mem);
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h
index 26d7921..8283344 100644
--- a/drivers/scsi/be2iscsi/be_cmds.h
+++ b/drivers/scsi/be2iscsi/be_cmds.h
@@ -762,6 +762,8 @@ struct be_cmd_set_features {
} param;
 } __packed;
 
+int beiscsi_cmd_function_reset(struct beiscsi_hba *phba);
+
 int beiscsi_cmd_special_wrb(struct be_ctrl_info *ctrl, u32 load);
 
 int beiscsi_check_fw_rdy(struct beiscsi_hba *phba);
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 29d5291..1cc155b 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -3780,9 +3780,12 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba)
beiscsi_cmd_q_destroy(ctrl, q, QTYPE_EQ);
}
}
+   /* this ensures complete FW cleanup */
+   beiscsi_cmd_function_reset(phba);
/* last communication, indicate driver is unloading */
beiscsi_cmd_special_wrb(>ctrl, 0);
 }
+
 static int hwi_init_port(struct beiscsi_hba *phba)
 {
struct hwi_controller *phwi_ctrlr;
-- 
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 27/28] be2iscsi: Update the driver version

2016-07-21 Thread Jitendra Bhivare
Driver version: 11.2.0.0

Signed-off-by: Jitendra Bhivare <jitendra.bhiv...@broadcom.com>
---
 drivers/scsi/be2iscsi/be_main.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 7173c03..6376657 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -36,7 +36,7 @@
 #include 
 
 #define DRV_NAME   "be2iscsi"
-#define BUILD_STR  "11.0.0.0"
+#define BUILD_STR  "11.2.0.0"
 #define BE_NAME"Emulex OneConnect" \
"Open-iSCSI Driver version" BUILD_STR
 #define DRV_DESC   BE_NAME " " "Driver"
-- 
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


  1   2   3   >