aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_iscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/be2iscsi/be_iscsi.c')
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index 9014690fe841..ef36be003f67 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) 2005 - 2012 Emulex 2 * Copyright (C) 2005 - 2013 Emulex
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -161,7 +161,9 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
161 struct beiscsi_conn *beiscsi_conn, 161 struct beiscsi_conn *beiscsi_conn,
162 unsigned int cid) 162 unsigned int cid)
163{ 163{
164 if (phba->conn_table[cid]) { 164 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
165
166 if (phba->conn_table[cri_index]) {
165 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 167 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
166 "BS_%d : Connection table already occupied. Detected clash\n"); 168 "BS_%d : Connection table already occupied. Detected clash\n");
167 169
@@ -169,9 +171,9 @@ static int beiscsi_bindconn_cid(struct beiscsi_hba *phba,
169 } else { 171 } else {
170 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 172 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
171 "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n", 173 "BS_%d : phba->conn_table[%d]=%p(beiscsi_conn)\n",
172 cid, beiscsi_conn); 174 cri_index, beiscsi_conn);
173 175
174 phba->conn_table[cid] = beiscsi_conn; 176 phba->conn_table[cri_index] = beiscsi_conn;
175 } 177 }
176 return 0; 178 return 0;
177} 179}
@@ -990,9 +992,27 @@ static void beiscsi_put_cid(struct beiscsi_hba *phba, unsigned short cid)
990static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) 992static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep)
991{ 993{
992 struct beiscsi_hba *phba = beiscsi_ep->phba; 994 struct beiscsi_hba *phba = beiscsi_ep->phba;
995 struct beiscsi_conn *beiscsi_conn;
993 996
994 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 997 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
995 beiscsi_ep->phba = NULL; 998 beiscsi_ep->phba = NULL;
999 phba->ep_array[BE_GET_CRI_FROM_CID
1000 (beiscsi_ep->ep_cid)] = NULL;
1001
1002 /**
1003 * Check if any connection resource allocated by driver
1004 * is to be freed.This case occurs when target redirection
1005 * or connection retry is done.
1006 **/
1007 if (!beiscsi_ep->conn)
1008 return;
1009
1010 beiscsi_conn = beiscsi_ep->conn;
1011 if (beiscsi_conn->login_in_progress) {
1012 beiscsi_free_mgmt_task_handles(beiscsi_conn,
1013 beiscsi_conn->task);
1014 beiscsi_conn->login_in_progress = 0;
1015 }
996} 1016}
997 1017
998/** 1018/**
@@ -1009,7 +1029,6 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1009{ 1029{
1010 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data; 1030 struct beiscsi_endpoint *beiscsi_ep = ep->dd_data;
1011 struct beiscsi_hba *phba = beiscsi_ep->phba; 1031 struct beiscsi_hba *phba = beiscsi_ep->phba;
1012 struct be_mcc_wrb *wrb;
1013 struct tcp_connect_and_offload_out *ptcpcnct_out; 1032 struct tcp_connect_and_offload_out *ptcpcnct_out;
1014 struct be_dma_mem nonemb_cmd; 1033 struct be_dma_mem nonemb_cmd;
1015 unsigned int tag; 1034 unsigned int tag;
@@ -1029,15 +1048,8 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1029 "BS_%d : In beiscsi_open_conn, ep_cid=%d\n", 1048 "BS_%d : In beiscsi_open_conn, ep_cid=%d\n",
1030 beiscsi_ep->ep_cid); 1049 beiscsi_ep->ep_cid);
1031 1050
1032 phba->ep_array[beiscsi_ep->ep_cid - 1051 phba->ep_array[BE_GET_CRI_FROM_CID
1033 phba->fw_config.iscsi_cid_start] = ep; 1052 (beiscsi_ep->ep_cid)] = ep;
1034 if (beiscsi_ep->ep_cid > (phba->fw_config.iscsi_cid_start +
1035 phba->params.cxns_per_ctrl * 2)) {
1036
1037 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1038 "BS_%d : Failed in allocate iscsi cid\n");
1039 goto free_ep;
1040 }
1041 1053
1042 beiscsi_ep->cid_vld = 0; 1054 beiscsi_ep->cid_vld = 0;
1043 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, 1055 nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev,
@@ -1049,24 +1061,24 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1049 "BS_%d : Failed to allocate memory for" 1061 "BS_%d : Failed to allocate memory for"
1050 " mgmt_open_connection\n"); 1062 " mgmt_open_connection\n");
1051 1063
1052 beiscsi_put_cid(phba, beiscsi_ep->ep_cid); 1064 beiscsi_free_ep(beiscsi_ep);
1053 return -ENOMEM; 1065 return -ENOMEM;
1054 } 1066 }
1055 nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in); 1067 nonemb_cmd.size = sizeof(struct tcp_connect_and_offload_in);
1056 memset(nonemb_cmd.va, 0, nonemb_cmd.size); 1068 memset(nonemb_cmd.va, 0, nonemb_cmd.size);
1057 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd); 1069 tag = mgmt_open_connection(phba, dst_addr, beiscsi_ep, &nonemb_cmd);
1058 if (!tag) { 1070 if (tag <= 0) {
1059 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, 1071 beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG,
1060 "BS_%d : mgmt_open_connection Failed for cid=%d\n", 1072 "BS_%d : mgmt_open_connection Failed for cid=%d\n",
1061 beiscsi_ep->ep_cid); 1073 beiscsi_ep->ep_cid);
1062 1074
1063 beiscsi_put_cid(phba, beiscsi_ep->ep_cid);
1064 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1075 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1065 nonemb_cmd.va, nonemb_cmd.dma); 1076 nonemb_cmd.va, nonemb_cmd.dma);
1077 beiscsi_free_ep(beiscsi_ep);
1066 return -EAGAIN; 1078 return -EAGAIN;
1067 } 1079 }
1068 1080
1069 ret = beiscsi_mccq_compl(phba, tag, &wrb, NULL); 1081 ret = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd.va);
1070 if (ret) { 1082 if (ret) {
1071 beiscsi_log(phba, KERN_ERR, 1083 beiscsi_log(phba, KERN_ERR,
1072 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 1084 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
@@ -1074,10 +1086,11 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1074 1086
1075 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1087 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1076 nonemb_cmd.va, nonemb_cmd.dma); 1088 nonemb_cmd.va, nonemb_cmd.dma);
1077 goto free_ep; 1089 beiscsi_free_ep(beiscsi_ep);
1090 return -EBUSY;
1078 } 1091 }
1079 1092
1080 ptcpcnct_out = embedded_payload(wrb); 1093 ptcpcnct_out = (struct tcp_connect_and_offload_out *)nonemb_cmd.va;
1081 beiscsi_ep = ep->dd_data; 1094 beiscsi_ep = ep->dd_data;
1082 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle; 1095 beiscsi_ep->fw_handle = ptcpcnct_out->connection_handle;
1083 beiscsi_ep->cid_vld = 1; 1096 beiscsi_ep->cid_vld = 1;
@@ -1087,10 +1100,6 @@ static int beiscsi_open_conn(struct iscsi_endpoint *ep,
1087 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, 1100 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1088 nonemb_cmd.va, nonemb_cmd.dma); 1101 nonemb_cmd.va, nonemb_cmd.dma);
1089 return 0; 1102 return 0;
1090
1091free_ep:
1092 beiscsi_free_ep(beiscsi_ep);
1093 return -EBUSY;
1094} 1103}
1095 1104
1096/** 1105/**
@@ -1119,6 +1128,13 @@ beiscsi_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr,
1119 return ERR_PTR(ret); 1128 return ERR_PTR(ret);
1120 } 1129 }
1121 1130
1131 if (beiscsi_error(phba)) {
1132 ret = -EIO;
1133 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
1134 "BS_%d : The FW state Not Stable!!!\n");
1135 return ERR_PTR(ret);
1136 }
1137
1122 if (phba->state != BE_ADAPTER_UP) { 1138 if (phba->state != BE_ADAPTER_UP) {
1123 ret = -EBUSY; 1139 ret = -EBUSY;
1124 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 1140 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
@@ -1201,8 +1217,10 @@ static int beiscsi_close_conn(struct beiscsi_endpoint *beiscsi_ep, int flag)
1201static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, 1217static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba,
1202 unsigned int cid) 1218 unsigned int cid)
1203{ 1219{
1204 if (phba->conn_table[cid]) 1220 uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
1205 phba->conn_table[cid] = NULL; 1221
1222 if (phba->conn_table[cri_index])
1223 phba->conn_table[cri_index] = NULL;
1206 else { 1224 else {
1207 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, 1225 beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
1208 "BS_%d : Connection table Not occupied.\n"); 1226 "BS_%d : Connection table Not occupied.\n");