diff options
author | Manish Rangankar <manish.rangankar@qlogic.com> | 2011-10-07 19:55:46 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-16 12:10:06 -0400 |
commit | 736cf369c9a514a9ed596e97375c49ef1fdf920a (patch) | |
tree | 1b5a9bd343152f315982125edd36a33f2c1b3fde /drivers/scsi/qla4xxx | |
parent | 166dd20d794e7885b23c8d5fc533949ed82cc337 (diff) |
[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: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 12 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 11 |
2 files changed, 14 insertions, 9 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index 064a3a311e7..ca155bb9fd0 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -880,6 +880,10 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
880 | if (ddb_entry == NULL) { | 880 | if (ddb_entry == NULL) { |
881 | ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", | 881 | ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n", |
882 | __func__, fw_ddb_index); | 882 | __func__, fw_ddb_index); |
883 | |||
884 | if (state == DDB_DS_NO_CONNECTION_ACTIVE) | ||
885 | clear_bit(fw_ddb_index, ha->ddb_idx_map); | ||
886 | |||
883 | goto exit_ddb_event; | 887 | goto exit_ddb_event; |
884 | } | 888 | } |
885 | 889 | ||
@@ -910,7 +914,8 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index, | |||
910 | } | 914 | } |
911 | break; | 915 | break; |
912 | case DDB_DS_SESSION_ACTIVE: | 916 | case DDB_DS_SESSION_ACTIVE: |
913 | if (state == DDB_DS_SESSION_FAILED) { | 917 | switch (state) { |
918 | case DDB_DS_SESSION_FAILED: | ||
914 | /* | 919 | /* |
915 | * iscsi_session failure will cause userspace to | 920 | * iscsi_session failure will cause userspace to |
916 | * stop the connection which in turn would block the | 921 | * 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 | iscsi_session_failure(ddb_entry->sess->dd_data, | 924 | iscsi_session_failure(ddb_entry->sess->dd_data, |
920 | ISCSI_ERR_CONN_FAILED); | 925 | ISCSI_ERR_CONN_FAILED); |
921 | status = QLA_SUCCESS; | 926 | status = QLA_SUCCESS; |
927 | break; | ||
928 | case DDB_DS_NO_CONNECTION_ACTIVE: | ||
929 | clear_bit(fw_ddb_index, ha->ddb_idx_map); | ||
930 | status = QLA_SUCCESS; | ||
931 | break; | ||
922 | } | 932 | } |
923 | break; | 933 | break; |
924 | default: | 934 | default: |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 5266d97640c..bea78a7f6bc 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -1004,6 +1004,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep, | |||
1004 | qla_ep = ep->dd_data; | 1004 | qla_ep = ep->dd_data; |
1005 | dst_addr = (struct sockaddr *)&qla_ep->dst_addr; | 1005 | dst_addr = (struct sockaddr *)&qla_ep->dst_addr; |
1006 | ha = to_qla_host(qla_ep->host); | 1006 | ha = to_qla_host(qla_ep->host); |
1007 | |||
1007 | get_ddb_index: | 1008 | get_ddb_index: |
1008 | ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); | 1009 | ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); |
1009 | 1010 | ||
@@ -1063,6 +1064,8 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess) | |||
1063 | ddb_entry = sess->dd_data; | 1064 | ddb_entry = sess->dd_data; |
1064 | ha = ddb_entry->ha; | 1065 | ha = ddb_entry->ha; |
1065 | 1066 | ||
1067 | qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); | ||
1068 | |||
1066 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1069 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1067 | qla4xxx_free_ddb(ha, ddb_entry); | 1070 | qla4xxx_free_ddb(ha, ddb_entry); |
1068 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1071 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -1183,14 +1186,6 @@ static void qla4xxx_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
1183 | options = LOGOUT_OPTION_CLOSE_SESSION; | 1186 | options = LOGOUT_OPTION_CLOSE_SESSION; |
1184 | if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) | 1187 | if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) |
1185 | ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__); | 1188 | ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__); |
1186 | else | ||
1187 | qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); | ||
1188 | |||
1189 | /* | ||
1190 | * Clear the DDB bit so that next login can use the bit | ||
1191 | * if FW is not clearing the DDB entry then set DDB will fail anyways | ||
1192 | */ | ||
1193 | clear_bit(ddb_entry->fw_ddb_index, ha->ddb_idx_map); | ||
1194 | } | 1189 | } |
1195 | 1190 | ||
1196 | static void qla4xxx_task_work(struct work_struct *wdata) | 1191 | static void qla4xxx_task_work(struct work_struct *wdata) |