aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@gmail.com>2013-09-28 18:35:56 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-10-25 04:58:09 -0400
commit1f536d49cba96fa2f1ac47d267ff5d30a586e04c (patch)
treec99efd8a86561281c3d683d1b2d99bb562c58f7a /drivers/scsi/be2iscsi
parentafb9605844d117276532aabc5087e9fc3c0a08d2 (diff)
[SCSI] be2iscsi: Fix Insufficient Buffer Error returned in MBX Completion
When MBX_Cmd completion happens with error code Insufficient Buffer, the MBX_Cmd is posted again with the new buffer size posted by FW. Signed-off-by: John Soni Jose <sony.john-n@emulex.com> Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c20
-rw-r--r--drivers/scsi/be2iscsi/be_iscsi.c37
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c83
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.h2
4 files changed, 99 insertions, 43 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c
index cc37a4e5ce45..fce298ba4b41 100644
--- a/drivers/scsi/be2iscsi/be_cmds.c
+++ b/drivers/scsi/be2iscsi/be_cmds.c
@@ -158,8 +158,10 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
158 struct be_cmd_resp_hdr *ioctl_resp_hdr; 158 struct be_cmd_resp_hdr *ioctl_resp_hdr;
159 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; 159 struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q;
160 160
161 if (beiscsi_error(phba)) 161 if (beiscsi_error(phba)) {
162 free_mcc_tag(&phba->ctrl, tag);
162 return -EIO; 163 return -EIO;
164 }
163 165
164 /* wait for the mccq completion */ 166 /* wait for the mccq completion */
165 rc = wait_event_interruptible_timeout( 167 rc = wait_event_interruptible_timeout(
@@ -173,7 +175,7 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
173 BEISCSI_LOG_INIT | BEISCSI_LOG_EH | 175 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
174 BEISCSI_LOG_CONFIG, 176 BEISCSI_LOG_CONFIG,
175 "BC_%d : MBX Cmd Completion timed out\n"); 177 "BC_%d : MBX Cmd Completion timed out\n");
176 rc = -EAGAIN; 178 rc = -EBUSY;
177 179
178 /* decrement the mccq used count */ 180 /* decrement the mccq used count */
179 atomic_dec(&phba->ctrl.mcc_obj.q.used); 181 atomic_dec(&phba->ctrl.mcc_obj.q.used);
@@ -212,10 +214,18 @@ int beiscsi_mccq_compl(struct beiscsi_hba *phba,
212 214
213 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) { 215 if (status == MCC_STATUS_INSUFFICIENT_BUFFER) {
214 ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr; 216 ioctl_resp_hdr = (struct be_cmd_resp_hdr *) ioctl_hdr;
215 if (ioctl_resp_hdr->response_length) 217 beiscsi_log(phba, KERN_WARNING,
216 goto release_mcc_tag; 218 BEISCSI_LOG_INIT | BEISCSI_LOG_EH |
219 BEISCSI_LOG_CONFIG,
220 "BC_%d : Insufficent Buffer Error "
221 "Resp_Len : %d Actual_Resp_Len : %d\n",
222 ioctl_resp_hdr->response_length,
223 ioctl_resp_hdr->actual_resp_len);
224
225 rc = -EAGAIN;
226 goto release_mcc_tag;
217 } 227 }
218 rc = -EAGAIN; 228 rc = -EIO;
219 } 229 }
220 230
221release_mcc_tag: 231release_mcc_tag:
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c
index a7cd92c3c383..e82ab8124958 100644
--- a/drivers/scsi/be2iscsi/be_iscsi.c
+++ b/drivers/scsi/be2iscsi/be_iscsi.c
@@ -271,13 +271,17 @@ static int beiscsi_create_ipv6_iface(struct beiscsi_hba *phba)
271 271
272void beiscsi_create_def_ifaces(struct beiscsi_hba *phba) 272void beiscsi_create_def_ifaces(struct beiscsi_hba *phba)
273{ 273{
274 struct be_cmd_get_if_info_resp if_info; 274 struct be_cmd_get_if_info_resp *if_info;
275 275
276 if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) 276 if (!mgmt_get_if_info(phba, BE2_IPV4, &if_info)) {
277 beiscsi_create_ipv4_iface(phba); 277 beiscsi_create_ipv4_iface(phba);
278 kfree(if_info);
279 }
278 280
279 if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) 281 if (!mgmt_get_if_info(phba, BE2_IPV6, &if_info)) {
280 beiscsi_create_ipv6_iface(phba); 282 beiscsi_create_ipv6_iface(phba);
283 kfree(if_info);
284 }
281} 285}
282 286
283void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba) 287void beiscsi_destroy_def_ifaces(struct beiscsi_hba *phba)
@@ -518,59 +522,60 @@ static int be2iscsi_get_if_param(struct beiscsi_hba *phba,
518 struct iscsi_iface *iface, int param, 522 struct iscsi_iface *iface, int param,
519 char *buf) 523 char *buf)
520{ 524{
521 struct be_cmd_get_if_info_resp if_info; 525 struct be_cmd_get_if_info_resp *if_info;
522 int len, ip_type = BE2_IPV4; 526 int len, ip_type = BE2_IPV4;
523 527
524 memset(&if_info, 0, sizeof(if_info));
525
526 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6) 528 if (iface->iface_type == ISCSI_IFACE_TYPE_IPV6)
527 ip_type = BE2_IPV6; 529 ip_type = BE2_IPV6;
528 530
529 len = mgmt_get_if_info(phba, ip_type, &if_info); 531 len = mgmt_get_if_info(phba, ip_type, &if_info);
530 if (len) 532 if (len) {
533 kfree(if_info);
531 return len; 534 return len;
535 }
532 536
533 switch (param) { 537 switch (param) {
534 case ISCSI_NET_PARAM_IPV4_ADDR: 538 case ISCSI_NET_PARAM_IPV4_ADDR:
535 len = sprintf(buf, "%pI4\n", &if_info.ip_addr.addr); 539 len = sprintf(buf, "%pI4\n", if_info->ip_addr.addr);
536 break; 540 break;
537 case ISCSI_NET_PARAM_IPV6_ADDR: 541 case ISCSI_NET_PARAM_IPV6_ADDR:
538 len = sprintf(buf, "%pI6\n", &if_info.ip_addr.addr); 542 len = sprintf(buf, "%pI6\n", if_info->ip_addr.addr);
539 break; 543 break;
540 case ISCSI_NET_PARAM_IPV4_BOOTPROTO: 544 case ISCSI_NET_PARAM_IPV4_BOOTPROTO:
541 if (!if_info.dhcp_state) 545 if (!if_info->dhcp_state)
542 len = sprintf(buf, "static\n"); 546 len = sprintf(buf, "static\n");
543 else 547 else
544 len = sprintf(buf, "dhcp\n"); 548 len = sprintf(buf, "dhcp\n");
545 break; 549 break;
546 case ISCSI_NET_PARAM_IPV4_SUBNET: 550 case ISCSI_NET_PARAM_IPV4_SUBNET:
547 len = sprintf(buf, "%pI4\n", &if_info.ip_addr.subnet_mask); 551 len = sprintf(buf, "%pI4\n", if_info->ip_addr.subnet_mask);
548 break; 552 break;
549 case ISCSI_NET_PARAM_VLAN_ENABLED: 553 case ISCSI_NET_PARAM_VLAN_ENABLED:
550 len = sprintf(buf, "%s\n", 554 len = sprintf(buf, "%s\n",
551 (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) 555 (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
552 ? "Disabled\n" : "Enabled\n"); 556 ? "Disabled\n" : "Enabled\n");
553 break; 557 break;
554 case ISCSI_NET_PARAM_VLAN_ID: 558 case ISCSI_NET_PARAM_VLAN_ID:
555 if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) 559 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
556 return -EINVAL; 560 return -EINVAL;
557 else 561 else
558 len = sprintf(buf, "%d\n", 562 len = sprintf(buf, "%d\n",
559 (if_info.vlan_priority & 563 (if_info->vlan_priority &
560 ISCSI_MAX_VLAN_ID)); 564 ISCSI_MAX_VLAN_ID));
561 break; 565 break;
562 case ISCSI_NET_PARAM_VLAN_PRIORITY: 566 case ISCSI_NET_PARAM_VLAN_PRIORITY:
563 if (if_info.vlan_priority == BEISCSI_VLAN_DISABLE) 567 if (if_info->vlan_priority == BEISCSI_VLAN_DISABLE)
564 return -EINVAL; 568 return -EINVAL;
565 else 569 else
566 len = sprintf(buf, "%d\n", 570 len = sprintf(buf, "%d\n",
567 ((if_info.vlan_priority >> 13) & 571 ((if_info->vlan_priority >> 13) &
568 ISCSI_MAX_VLAN_PRIORITY)); 572 ISCSI_MAX_VLAN_PRIORITY));
569 break; 573 break;
570 default: 574 default:
571 WARN_ON(1); 575 WARN_ON(1);
572 } 576 }
573 577
578 kfree(if_info);
574 return len; 579 return len;
575} 580}
576 581
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c
index befeace18257..1f2b546a3fc4 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.c
+++ b/drivers/scsi/be2iscsi/be_mgmt.c
@@ -824,11 +824,14 @@ static int mgmt_exec_nonemb_cmd(struct beiscsi_hba *phba,
824 824
825 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va); 825 rc = beiscsi_mccq_compl(phba, tag, NULL, nonemb_cmd->va);
826 if (rc) { 826 if (rc) {
827 /* Check if the IOCTL needs to be re-issued */
828 if (rc == -EAGAIN)
829 return rc;
830
827 beiscsi_log(phba, KERN_ERR, 831 beiscsi_log(phba, KERN_ERR,
828 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, 832 BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX,
829 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n"); 833 "BG_%d : mgmt_exec_nonemb_cmd Failed status\n");
830 834
831 rc = -EIO;
832 goto free_cmd; 835 goto free_cmd;
833 } 836 }
834 837
@@ -937,7 +940,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
937 uint32_t boot_proto) 940 uint32_t boot_proto)
938{ 941{
939 struct be_cmd_get_def_gateway_resp gtway_addr_set; 942 struct be_cmd_get_def_gateway_resp gtway_addr_set;
940 struct be_cmd_get_if_info_resp if_info; 943 struct be_cmd_get_if_info_resp *if_info;
941 struct be_cmd_set_dhcp_req *dhcpreq; 944 struct be_cmd_set_dhcp_req *dhcpreq;
942 struct be_cmd_rel_dhcp_req *reldhcp; 945 struct be_cmd_rel_dhcp_req *reldhcp;
943 struct be_dma_mem nonemb_cmd; 946 struct be_dma_mem nonemb_cmd;
@@ -948,16 +951,17 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
948 if (mgmt_get_all_if_id(phba)) 951 if (mgmt_get_all_if_id(phba))
949 return -EIO; 952 return -EIO;
950 953
951 memset(&if_info, 0, sizeof(if_info));
952 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ? 954 ip_type = (ip_param->param == ISCSI_NET_PARAM_IPV6_ADDR) ?
953 BE2_IPV6 : BE2_IPV4 ; 955 BE2_IPV6 : BE2_IPV4 ;
954 956
955 rc = mgmt_get_if_info(phba, ip_type, &if_info); 957 rc = mgmt_get_if_info(phba, ip_type, &if_info);
956 if (rc) 958 if (rc) {
959 kfree(if_info);
957 return rc; 960 return rc;
961 }
958 962
959 if (boot_proto == ISCSI_BOOTPROTO_DHCP) { 963 if (boot_proto == ISCSI_BOOTPROTO_DHCP) {
960 if (if_info.dhcp_state) { 964 if (if_info->dhcp_state) {
961 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG, 965 beiscsi_log(phba, KERN_WARNING, BEISCSI_LOG_CONFIG,
962 "BG_%d : DHCP Already Enabled\n"); 966 "BG_%d : DHCP Already Enabled\n");
963 return 0; 967 return 0;
@@ -970,9 +974,9 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
970 IP_V6_LEN : IP_V4_LEN; 974 IP_V6_LEN : IP_V4_LEN;
971 975
972 } else { 976 } else {
973 if (if_info.dhcp_state) { 977 if (if_info->dhcp_state) {
974 978
975 memset(&if_info, 0, sizeof(if_info)); 979 memset(if_info, 0, sizeof(*if_info));
976 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 980 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
977 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR, 981 OPCODE_COMMON_ISCSI_NTWK_REL_STATELESS_IP_ADDR,
978 sizeof(*reldhcp)); 982 sizeof(*reldhcp));
@@ -995,8 +999,8 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
995 } 999 }
996 1000
997 /* Delete the Static IP Set */ 1001 /* Delete the Static IP Set */
998 if (if_info.ip_addr.addr[0]) { 1002 if (if_info->ip_addr.addr[0]) {
999 rc = mgmt_static_ip_modify(phba, &if_info, ip_param, NULL, 1003 rc = mgmt_static_ip_modify(phba, if_info, ip_param, NULL,
1000 IP_ACTION_DEL); 1004 IP_ACTION_DEL);
1001 if (rc) 1005 if (rc)
1002 return rc; 1006 return rc;
@@ -1042,7 +1046,7 @@ int mgmt_set_ip(struct beiscsi_hba *phba,
1042 1046
1043 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0); 1047 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, NULL, 0);
1044 } else { 1048 } else {
1045 return mgmt_static_ip_modify(phba, &if_info, ip_param, 1049 return mgmt_static_ip_modify(phba, if_info, ip_param,
1046 subnet_param, IP_ACTION_ADD); 1050 subnet_param, IP_ACTION_ADD);
1047 } 1051 }
1048 1052
@@ -1107,27 +1111,64 @@ int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
1107} 1111}
1108 1112
1109int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, 1113int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
1110 struct be_cmd_get_if_info_resp *if_info) 1114 struct be_cmd_get_if_info_resp **if_info)
1111{ 1115{
1112 struct be_cmd_get_if_info_req *req; 1116 struct be_cmd_get_if_info_req *req;
1113 struct be_dma_mem nonemb_cmd; 1117 struct be_dma_mem nonemb_cmd;
1118 uint32_t ioctl_size = sizeof(struct be_cmd_get_if_info_resp);
1114 int rc; 1119 int rc;
1115 1120
1116 if (mgmt_get_all_if_id(phba)) 1121 if (mgmt_get_all_if_id(phba))
1117 return -EIO; 1122 return -EIO;
1118 1123
1119 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd, 1124 do {
1120 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO, 1125 rc = mgmt_alloc_cmd_data(phba, &nonemb_cmd,
1121 sizeof(*if_info)); 1126 OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO,
1122 if (rc) 1127 ioctl_size);
1123 return rc; 1128 if (rc)
1129 return rc;
1124 1130
1125 req = nonemb_cmd.va; 1131 req = nonemb_cmd.va;
1126 req->interface_hndl = phba->interface_handle; 1132 req->interface_hndl = phba->interface_handle;
1127 req->ip_type = ip_type; 1133 req->ip_type = ip_type;
1134
1135 /* Allocate memory for if_info */
1136 *if_info = kzalloc(ioctl_size, GFP_KERNEL);
1137 if (!*if_info) {
1138 beiscsi_log(phba, KERN_ERR,
1139 BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
1140 "BG_%d : Memory Allocation Failure\n");
1141
1142 /* Free the DMA memory for the IOCTL issuing */
1143 pci_free_consistent(phba->ctrl.pdev,
1144 nonemb_cmd.size,
1145 nonemb_cmd.va,
1146 nonemb_cmd.dma);
1147 return -ENOMEM;
1148 }
1128 1149
1129 return mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, if_info, 1150 rc = mgmt_exec_nonemb_cmd(phba, &nonemb_cmd, *if_info,
1130 sizeof(*if_info)); 1151 ioctl_size);
1152
1153 /* Check if the error is because of Insufficent_Buffer */
1154 if (rc == -EAGAIN) {
1155
1156 /* Get the new memory size */
1157 ioctl_size = ((struct be_cmd_resp_hdr *)
1158 nonemb_cmd.va)->actual_resp_len;
1159 ioctl_size += sizeof(struct be_cmd_req_hdr);
1160
1161 /* Free the previous allocated DMA memory */
1162 pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
1163 nonemb_cmd.va,
1164 nonemb_cmd.dma);
1165
1166 /* Free the virtual memory */
1167 kfree(*if_info);
1168 } else
1169 break;
1170 } while (true);
1171 return rc;
1131} 1172}
1132 1173
1133int mgmt_get_nic_conf(struct beiscsi_hba *phba, 1174int mgmt_get_nic_conf(struct beiscsi_hba *phba,
diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h
index 645e144622c9..01b8c97284c0 100644
--- a/drivers/scsi/be2iscsi/be_mgmt.h
+++ b/drivers/scsi/be2iscsi/be_mgmt.h
@@ -294,7 +294,7 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba,
294 struct be_cmd_get_nic_conf_resp *mac); 294 struct be_cmd_get_nic_conf_resp *mac);
295 295
296int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type, 296int mgmt_get_if_info(struct beiscsi_hba *phba, int ip_type,
297 struct be_cmd_get_if_info_resp *if_info); 297 struct be_cmd_get_if_info_resp **if_info);
298 298
299int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type, 299int mgmt_get_gateway(struct beiscsi_hba *phba, int ip_type,
300 struct be_cmd_get_def_gateway_resp *gateway); 300 struct be_cmd_get_def_gateway_resp *gateway);