diff options
Diffstat (limited to 'drivers/scsi/be2iscsi/be_iscsi.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 70 |
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) | |||
990 | static void beiscsi_free_ep(struct beiscsi_endpoint *beiscsi_ep) | 992 | static 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 | |||
1091 | free_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) | |||
1201 | static int beiscsi_unbind_conn_to_cid(struct beiscsi_hba *phba, | 1217 | static 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"); |