Commit 736cf369 authored by Manish Rangankar's avatar Manish Rangankar Committed by James Bottomley

[SCSI] qla4xxx: Clear DDB map index on the basis of AEN.

Unable to login to session if login-logout issued consecutively for
multiple sessions. Solution is to clear idx in DDB map on the basis
of no-active connection asynchronous event (AEN).

JIRA Key: UPSISCSI-135
Signed-off-by: default avatarManish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: default avatarVikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 166dd20d
...@@ -880,6 +880,10 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, ...@@ -880,6 +880,10 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
if (ddb_entry == NULL) { if (ddb_entry == NULL) {
ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n",
__func__, fw_ddb_index); __func__, fw_ddb_index);
if (state == DDB_DS_NO_CONNECTION_ACTIVE)
clear_bit(fw_ddb_index, ha->ddb_idx_map);
goto exit_ddb_event; goto exit_ddb_event;
} }
...@@ -910,7 +914,8 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, ...@@ -910,7 +914,8 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
} }
break; break;
case DDB_DS_SESSION_ACTIVE: case DDB_DS_SESSION_ACTIVE:
if (state == DDB_DS_SESSION_FAILED) { switch (state) {
case DDB_DS_SESSION_FAILED:
/* /*
* iscsi_session failure will cause userspace to * iscsi_session failure will cause userspace to
* stop the connection which in turn would block the * stop the connection which in turn would block the
...@@ -919,6 +924,11 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, ...@@ -919,6 +924,11 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
iscsi_session_failure(ddb_entry->sess->dd_data, iscsi_session_failure(ddb_entry->sess->dd_data,
ISCSI_ERR_CONN_FAILED); ISCSI_ERR_CONN_FAILED);
status = QLA_SUCCESS; status = QLA_SUCCESS;
break;
case DDB_DS_NO_CONNECTION_ACTIVE:
clear_bit(fw_ddb_index, ha->ddb_idx_map);
status = QLA_SUCCESS;
break;
} }
break; break;
default: default:
......
...@@ -1004,6 +1004,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, ...@@ -1004,6 +1004,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep,
qla_ep = ep->dd_data; qla_ep = ep->dd_data;
dst_addr = (struct sockaddr *)&qla_ep->dst_addr; dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
ha = to_qla_host(qla_ep->host); ha = to_qla_host(qla_ep->host);
get_ddb_index: get_ddb_index:
ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES);
...@@ -1063,6 +1064,8 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) ...@@ -1063,6 +1064,8 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess)
ddb_entry = sess->dd_data; ddb_entry = sess->dd_data;
ha = ddb_entry->ha; ha = ddb_entry->ha;
qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qla4xxx_free_ddb(ha, ddb_entry); qla4xxx_free_ddb(ha, ddb_entry);
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -1183,14 +1186,6 @@ static void qla4xxx_conn_destroy(struct iscsi_cls_conn *cls_conn) ...@@ -1183,14 +1186,6 @@ static void qla4xxx_conn_destroy(struct iscsi_cls_conn *cls_conn)
options = LOGOUT_OPTION_CLOSE_SESSION; options = LOGOUT_OPTION_CLOSE_SESSION;
if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR)
ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__); ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__);
else
qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
/*
* Clear the DDB bit so that next login can use the bit
* if FW is not clearing the DDB entry then set DDB will fail anyways
*/
clear_bit(ddb_entry->fw_ddb_index, ha->ddb_idx_map);
} }
static void qla4xxx_task_work(struct work_struct *wdata) static void qla4xxx_task_work(struct work_struct *wdata)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment