aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_mgmt.c
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/be_mgmt.c
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/be_mgmt.c')
-rw-r--r--drivers/scsi/be2iscsi/be_mgmt.c83
1 files changed, 62 insertions, 21 deletions
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,