u32 num_ccell;
int ofld_conns_active;
+ wait_queue_head_t eh_wait;
int max_active_conns;
struct iscsi_cid_queue cid_que;
spinlock_t lock; /* protects hba structure access */
struct mutex net_dev_lock;/* sync net device access */
+ int hba_shutdown_tmo;
/*
* PCI related info.
*/
struct bnx2i_hba *hba = handle;
/* check if cleanup happened in GOING_DOWN context */
- clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
&hba->adapter_state))
iscsi_host_for_each_session(hba->shost,
bnx2i_drop_session);
+
+ /* Wait for all endpoints to be torn down, Chip will be reset once
+ * control returns to network driver. So it is required to cleanup and
+ * release all connection resources before returning from this routine.
+ */
+ wait_event_interruptible_timeout(hba->eh_wait,
+ (hba->ofld_conns_active == 0),
+ hba->hba_shutdown_tmo);
+ /* This flag should be cleared last so that ep_disconnect() gracefully
+ * cleans up connection context
+ */
+ clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
}
/**
spin_lock_init(&hba->lock);
mutex_init(&hba->net_dev_lock);
+ init_waitqueue_head(&hba->eh_wait);
+ if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type))
+ hba->hba_shutdown_tmo = 240 * HZ;
+ else /* 5706/5708/5709 */
+ hba->hba_shutdown_tmo = 30 * HZ;
if (iscsi_host_add(shost, &hba->pcidev->dev))
goto free_dump_mem;
*/
hba = bnx2i_check_route(dst_addr);
- if (!hba) {
- rc = -ENOMEM;
+ if (!hba || test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state)) {
+ rc = -EINVAL;
goto check_busy;
}
(bnx2i_ep->state ==
EP_STATE_CONNECT_COMPL)),
msecs_to_jiffies(timeout_ms));
- if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED))
+ if (bnx2i_ep->state == EP_STATE_OFLD_FAILED)
rc = -1;
if (rc > 0)
if (!hba->ofld_conns_active)
bnx2i_unreg_dev_all();
+
+ wake_up_interruptible(&hba->eh_wait);
}