diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-11-22 17:02:45 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-23 13:44:31 -0500 |
commit | 713d039426a80ed78e71294cfb5d0a009bb20b42 (patch) | |
tree | 730b990542128235aa1d2d75186aa53f7cdb62e8 /drivers/net/benet/be_cmds.c | |
parent | 8d56ff11708e5809c644a6d687a5dff4551043b4 (diff) |
be2net: remove BUG_ON() when be2net runs out of mccq wrbs
The driver can run out of mccq wrbs when completions don't arrive
due to an unresponsive card. This must not hit a BUG_ON(); instead
log a msg and return an error.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_cmds.c')
-rw-r--r-- | drivers/net/benet/be_cmds.c | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 2af87f100307..8bd531560043 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -349,7 +349,11 @@ static struct be_mcc_wrb *wrb_from_mccq(struct be_adapter *adapter) | |||
349 | struct be_queue_info *mccq = &adapter->mcc_obj.q; | 349 | struct be_queue_info *mccq = &adapter->mcc_obj.q; |
350 | struct be_mcc_wrb *wrb; | 350 | struct be_mcc_wrb *wrb; |
351 | 351 | ||
352 | BUG_ON(atomic_read(&mccq->used) >= mccq->len); | 352 | if (atomic_read(&mccq->used) >= mccq->len) { |
353 | dev_err(&adapter->pdev->dev, "Out of MCCQ wrbs\n"); | ||
354 | return NULL; | ||
355 | } | ||
356 | |||
353 | wrb = queue_head_node(mccq); | 357 | wrb = queue_head_node(mccq); |
354 | queue_head_inc(mccq); | 358 | queue_head_inc(mccq); |
355 | atomic_inc(&mccq->used); | 359 | atomic_inc(&mccq->used); |
@@ -499,6 +503,10 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
499 | spin_lock_bh(&adapter->mcc_lock); | 503 | spin_lock_bh(&adapter->mcc_lock); |
500 | 504 | ||
501 | wrb = wrb_from_mccq(adapter); | 505 | wrb = wrb_from_mccq(adapter); |
506 | if (!wrb) { | ||
507 | status = -EBUSY; | ||
508 | goto err; | ||
509 | } | ||
502 | req = embedded_payload(wrb); | 510 | req = embedded_payload(wrb); |
503 | 511 | ||
504 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 512 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -515,6 +523,7 @@ int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr, | |||
515 | *pmac_id = le32_to_cpu(resp->pmac_id); | 523 | *pmac_id = le32_to_cpu(resp->pmac_id); |
516 | } | 524 | } |
517 | 525 | ||
526 | err: | ||
518 | spin_unlock_bh(&adapter->mcc_lock); | 527 | spin_unlock_bh(&adapter->mcc_lock); |
519 | return status; | 528 | return status; |
520 | } | 529 | } |
@@ -529,6 +538,10 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) | |||
529 | spin_lock_bh(&adapter->mcc_lock); | 538 | spin_lock_bh(&adapter->mcc_lock); |
530 | 539 | ||
531 | wrb = wrb_from_mccq(adapter); | 540 | wrb = wrb_from_mccq(adapter); |
541 | if (!wrb) { | ||
542 | status = -EBUSY; | ||
543 | goto err; | ||
544 | } | ||
532 | req = embedded_payload(wrb); | 545 | req = embedded_payload(wrb); |
533 | 546 | ||
534 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 547 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -541,8 +554,8 @@ int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id, u32 pmac_id) | |||
541 | 554 | ||
542 | status = be_mcc_notify_wait(adapter); | 555 | status = be_mcc_notify_wait(adapter); |
543 | 556 | ||
557 | err: | ||
544 | spin_unlock_bh(&adapter->mcc_lock); | 558 | spin_unlock_bh(&adapter->mcc_lock); |
545 | |||
546 | return status; | 559 | return status; |
547 | } | 560 | } |
548 | 561 | ||
@@ -861,10 +874,15 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) | |||
861 | struct be_mcc_wrb *wrb; | 874 | struct be_mcc_wrb *wrb; |
862 | struct be_cmd_req_get_stats *req; | 875 | struct be_cmd_req_get_stats *req; |
863 | struct be_sge *sge; | 876 | struct be_sge *sge; |
877 | int status = 0; | ||
864 | 878 | ||
865 | spin_lock_bh(&adapter->mcc_lock); | 879 | spin_lock_bh(&adapter->mcc_lock); |
866 | 880 | ||
867 | wrb = wrb_from_mccq(adapter); | 881 | wrb = wrb_from_mccq(adapter); |
882 | if (!wrb) { | ||
883 | status = -EBUSY; | ||
884 | goto err; | ||
885 | } | ||
868 | req = nonemb_cmd->va; | 886 | req = nonemb_cmd->va; |
869 | sge = nonembedded_sgl(wrb); | 887 | sge = nonembedded_sgl(wrb); |
870 | 888 | ||
@@ -879,8 +897,9 @@ int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd) | |||
879 | 897 | ||
880 | be_mcc_notify(adapter); | 898 | be_mcc_notify(adapter); |
881 | 899 | ||
900 | err: | ||
882 | spin_unlock_bh(&adapter->mcc_lock); | 901 | spin_unlock_bh(&adapter->mcc_lock); |
883 | return 0; | 902 | return status; |
884 | } | 903 | } |
885 | 904 | ||
886 | /* Uses synchronous mcc */ | 905 | /* Uses synchronous mcc */ |
@@ -894,6 +913,10 @@ int be_cmd_link_status_query(struct be_adapter *adapter, | |||
894 | spin_lock_bh(&adapter->mcc_lock); | 913 | spin_lock_bh(&adapter->mcc_lock); |
895 | 914 | ||
896 | wrb = wrb_from_mccq(adapter); | 915 | wrb = wrb_from_mccq(adapter); |
916 | if (!wrb) { | ||
917 | status = -EBUSY; | ||
918 | goto err; | ||
919 | } | ||
897 | req = embedded_payload(wrb); | 920 | req = embedded_payload(wrb); |
898 | 921 | ||
899 | *link_up = false; | 922 | *link_up = false; |
@@ -913,6 +936,7 @@ int be_cmd_link_status_query(struct be_adapter *adapter, | |||
913 | } | 936 | } |
914 | } | 937 | } |
915 | 938 | ||
939 | err: | ||
916 | spin_unlock_bh(&adapter->mcc_lock); | 940 | spin_unlock_bh(&adapter->mcc_lock); |
917 | return status; | 941 | return status; |
918 | } | 942 | } |
@@ -951,10 +975,15 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) | |||
951 | { | 975 | { |
952 | struct be_mcc_wrb *wrb; | 976 | struct be_mcc_wrb *wrb; |
953 | struct be_cmd_req_modify_eq_delay *req; | 977 | struct be_cmd_req_modify_eq_delay *req; |
978 | int status = 0; | ||
954 | 979 | ||
955 | spin_lock_bh(&adapter->mcc_lock); | 980 | spin_lock_bh(&adapter->mcc_lock); |
956 | 981 | ||
957 | wrb = wrb_from_mccq(adapter); | 982 | wrb = wrb_from_mccq(adapter); |
983 | if (!wrb) { | ||
984 | status = -EBUSY; | ||
985 | goto err; | ||
986 | } | ||
958 | req = embedded_payload(wrb); | 987 | req = embedded_payload(wrb); |
959 | 988 | ||
960 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 989 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -969,8 +998,9 @@ int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd) | |||
969 | 998 | ||
970 | be_mcc_notify(adapter); | 999 | be_mcc_notify(adapter); |
971 | 1000 | ||
1001 | err: | ||
972 | spin_unlock_bh(&adapter->mcc_lock); | 1002 | spin_unlock_bh(&adapter->mcc_lock); |
973 | return 0; | 1003 | return status; |
974 | } | 1004 | } |
975 | 1005 | ||
976 | /* Uses sycnhronous mcc */ | 1006 | /* Uses sycnhronous mcc */ |
@@ -984,6 +1014,10 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, | |||
984 | spin_lock_bh(&adapter->mcc_lock); | 1014 | spin_lock_bh(&adapter->mcc_lock); |
985 | 1015 | ||
986 | wrb = wrb_from_mccq(adapter); | 1016 | wrb = wrb_from_mccq(adapter); |
1017 | if (!wrb) { | ||
1018 | status = -EBUSY; | ||
1019 | goto err; | ||
1020 | } | ||
987 | req = embedded_payload(wrb); | 1021 | req = embedded_payload(wrb); |
988 | 1022 | ||
989 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1023 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1002,6 +1036,7 @@ int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, u16 *vtag_array, | |||
1002 | 1036 | ||
1003 | status = be_mcc_notify_wait(adapter); | 1037 | status = be_mcc_notify_wait(adapter); |
1004 | 1038 | ||
1039 | err: | ||
1005 | spin_unlock_bh(&adapter->mcc_lock); | 1040 | spin_unlock_bh(&adapter->mcc_lock); |
1006 | return status; | 1041 | return status; |
1007 | } | 1042 | } |
@@ -1018,6 +1053,10 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) | |||
1018 | spin_lock_bh(&adapter->mcc_lock); | 1053 | spin_lock_bh(&adapter->mcc_lock); |
1019 | 1054 | ||
1020 | wrb = wrb_from_mccq(adapter); | 1055 | wrb = wrb_from_mccq(adapter); |
1056 | if (!wrb) { | ||
1057 | status = -EBUSY; | ||
1058 | goto err; | ||
1059 | } | ||
1021 | req = embedded_payload(wrb); | 1060 | req = embedded_payload(wrb); |
1022 | 1061 | ||
1023 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1062 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1032,6 +1071,7 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) | |||
1032 | 1071 | ||
1033 | status = be_mcc_notify_wait(adapter); | 1072 | status = be_mcc_notify_wait(adapter); |
1034 | 1073 | ||
1074 | err: | ||
1035 | spin_unlock_bh(&adapter->mcc_lock); | 1075 | spin_unlock_bh(&adapter->mcc_lock); |
1036 | return status; | 1076 | return status; |
1037 | } | 1077 | } |
@@ -1052,6 +1092,10 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1052 | spin_lock_bh(&adapter->mcc_lock); | 1092 | spin_lock_bh(&adapter->mcc_lock); |
1053 | 1093 | ||
1054 | wrb = wrb_from_mccq(adapter); | 1094 | wrb = wrb_from_mccq(adapter); |
1095 | if (!wrb) { | ||
1096 | status = -EBUSY; | ||
1097 | goto err; | ||
1098 | } | ||
1055 | sge = nonembedded_sgl(wrb); | 1099 | sge = nonembedded_sgl(wrb); |
1056 | memset(req, 0, sizeof(*req)); | 1100 | memset(req, 0, sizeof(*req)); |
1057 | 1101 | ||
@@ -1078,6 +1122,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1078 | 1122 | ||
1079 | status = be_mcc_notify_wait(adapter); | 1123 | status = be_mcc_notify_wait(adapter); |
1080 | 1124 | ||
1125 | err: | ||
1081 | spin_unlock_bh(&adapter->mcc_lock); | 1126 | spin_unlock_bh(&adapter->mcc_lock); |
1082 | return status; | 1127 | return status; |
1083 | } | 1128 | } |
@@ -1092,6 +1137,10 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) | |||
1092 | spin_lock_bh(&adapter->mcc_lock); | 1137 | spin_lock_bh(&adapter->mcc_lock); |
1093 | 1138 | ||
1094 | wrb = wrb_from_mccq(adapter); | 1139 | wrb = wrb_from_mccq(adapter); |
1140 | if (!wrb) { | ||
1141 | status = -EBUSY; | ||
1142 | goto err; | ||
1143 | } | ||
1095 | req = embedded_payload(wrb); | 1144 | req = embedded_payload(wrb); |
1096 | 1145 | ||
1097 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1146 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1104,6 +1153,7 @@ int be_cmd_set_flow_control(struct be_adapter *adapter, u32 tx_fc, u32 rx_fc) | |||
1104 | 1153 | ||
1105 | status = be_mcc_notify_wait(adapter); | 1154 | status = be_mcc_notify_wait(adapter); |
1106 | 1155 | ||
1156 | err: | ||
1107 | spin_unlock_bh(&adapter->mcc_lock); | 1157 | spin_unlock_bh(&adapter->mcc_lock); |
1108 | return status; | 1158 | return status; |
1109 | } | 1159 | } |
@@ -1118,6 +1168,10 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) | |||
1118 | spin_lock_bh(&adapter->mcc_lock); | 1168 | spin_lock_bh(&adapter->mcc_lock); |
1119 | 1169 | ||
1120 | wrb = wrb_from_mccq(adapter); | 1170 | wrb = wrb_from_mccq(adapter); |
1171 | if (!wrb) { | ||
1172 | status = -EBUSY; | ||
1173 | goto err; | ||
1174 | } | ||
1121 | req = embedded_payload(wrb); | 1175 | req = embedded_payload(wrb); |
1122 | 1176 | ||
1123 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1177 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1133,6 +1187,7 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) | |||
1133 | *rx_fc = le16_to_cpu(resp->rx_flow_control); | 1187 | *rx_fc = le16_to_cpu(resp->rx_flow_control); |
1134 | } | 1188 | } |
1135 | 1189 | ||
1190 | err: | ||
1136 | spin_unlock_bh(&adapter->mcc_lock); | 1191 | spin_unlock_bh(&adapter->mcc_lock); |
1137 | return status; | 1192 | return status; |
1138 | } | 1193 | } |
@@ -1199,6 +1254,10 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, | |||
1199 | spin_lock_bh(&adapter->mcc_lock); | 1254 | spin_lock_bh(&adapter->mcc_lock); |
1200 | 1255 | ||
1201 | wrb = wrb_from_mccq(adapter); | 1256 | wrb = wrb_from_mccq(adapter); |
1257 | if (!wrb) { | ||
1258 | status = -EBUSY; | ||
1259 | goto err; | ||
1260 | } | ||
1202 | req = embedded_payload(wrb); | 1261 | req = embedded_payload(wrb); |
1203 | 1262 | ||
1204 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1263 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1213,6 +1272,7 @@ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, | |||
1213 | 1272 | ||
1214 | status = be_mcc_notify_wait(adapter); | 1273 | status = be_mcc_notify_wait(adapter); |
1215 | 1274 | ||
1275 | err: | ||
1216 | spin_unlock_bh(&adapter->mcc_lock); | 1276 | spin_unlock_bh(&adapter->mcc_lock); |
1217 | return status; | 1277 | return status; |
1218 | } | 1278 | } |
@@ -1227,6 +1287,10 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) | |||
1227 | spin_lock_bh(&adapter->mcc_lock); | 1287 | spin_lock_bh(&adapter->mcc_lock); |
1228 | 1288 | ||
1229 | wrb = wrb_from_mccq(adapter); | 1289 | wrb = wrb_from_mccq(adapter); |
1290 | if (!wrb) { | ||
1291 | status = -EBUSY; | ||
1292 | goto err; | ||
1293 | } | ||
1230 | req = embedded_payload(wrb); | 1294 | req = embedded_payload(wrb); |
1231 | 1295 | ||
1232 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | 1296 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); |
@@ -1243,6 +1307,7 @@ int be_cmd_get_beacon_state(struct be_adapter *adapter, u8 port_num, u32 *state) | |||
1243 | *state = resp->beacon_state; | 1307 | *state = resp->beacon_state; |
1244 | } | 1308 | } |
1245 | 1309 | ||
1310 | err: | ||
1246 | spin_unlock_bh(&adapter->mcc_lock); | 1311 | spin_unlock_bh(&adapter->mcc_lock); |
1247 | return status; | 1312 | return status; |
1248 | } | 1313 | } |
@@ -1258,6 +1323,10 @@ int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, | |||
1258 | spin_lock_bh(&adapter->mcc_lock); | 1323 | spin_lock_bh(&adapter->mcc_lock); |
1259 | 1324 | ||
1260 | wrb = wrb_from_mccq(adapter); | 1325 | wrb = wrb_from_mccq(adapter); |
1326 | if (!wrb) { | ||
1327 | status = -EBUSY; | ||
1328 | goto err; | ||
1329 | } | ||
1261 | req = embedded_payload(wrb); | 1330 | req = embedded_payload(wrb); |
1262 | 1331 | ||
1263 | be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0); | 1332 | be_wrb_hdr_prepare(wrb, sizeof(struct be_cmd_resp_port_type), true, 0); |
@@ -1273,6 +1342,7 @@ int be_cmd_read_port_type(struct be_adapter *adapter, u32 port, | |||
1273 | *connector = resp->data.connector; | 1342 | *connector = resp->data.connector; |
1274 | } | 1343 | } |
1275 | 1344 | ||
1345 | err: | ||
1276 | spin_unlock_bh(&adapter->mcc_lock); | 1346 | spin_unlock_bh(&adapter->mcc_lock); |
1277 | return status; | 1347 | return status; |
1278 | } | 1348 | } |
@@ -1288,6 +1358,11 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, | |||
1288 | spin_lock_bh(&adapter->mcc_lock); | 1358 | spin_lock_bh(&adapter->mcc_lock); |
1289 | 1359 | ||
1290 | wrb = wrb_from_mccq(adapter); | 1360 | wrb = wrb_from_mccq(adapter); |
1361 | if (!wrb) { | ||
1362 | status = -EBUSY; | ||
1363 | goto err; | ||
1364 | } | ||
1365 | req = cmd->va; | ||
1291 | sge = nonembedded_sgl(wrb); | 1366 | sge = nonembedded_sgl(wrb); |
1292 | 1367 | ||
1293 | be_wrb_hdr_prepare(wrb, cmd->size, false, 1); | 1368 | be_wrb_hdr_prepare(wrb, cmd->size, false, 1); |
@@ -1304,6 +1379,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, | |||
1304 | 1379 | ||
1305 | status = be_mcc_notify_wait(adapter); | 1380 | status = be_mcc_notify_wait(adapter); |
1306 | 1381 | ||
1382 | err: | ||
1307 | spin_unlock_bh(&adapter->mcc_lock); | 1383 | spin_unlock_bh(&adapter->mcc_lock); |
1308 | return status; | 1384 | return status; |
1309 | } | 1385 | } |
@@ -1317,6 +1393,10 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc) | |||
1317 | spin_lock_bh(&adapter->mcc_lock); | 1393 | spin_lock_bh(&adapter->mcc_lock); |
1318 | 1394 | ||
1319 | wrb = wrb_from_mccq(adapter); | 1395 | wrb = wrb_from_mccq(adapter); |
1396 | if (!wrb) { | ||
1397 | status = -EBUSY; | ||
1398 | goto err; | ||
1399 | } | ||
1320 | req = embedded_payload(wrb); | 1400 | req = embedded_payload(wrb); |
1321 | 1401 | ||
1322 | be_wrb_hdr_prepare(wrb, sizeof(*req)+4, true, 0); | 1402 | be_wrb_hdr_prepare(wrb, sizeof(*req)+4, true, 0); |
@@ -1333,6 +1413,7 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc) | |||
1333 | if (!status) | 1413 | if (!status) |
1334 | memcpy(flashed_crc, req->params.data_buf, 4); | 1414 | memcpy(flashed_crc, req->params.data_buf, 4); |
1335 | 1415 | ||
1416 | err: | ||
1336 | spin_unlock_bh(&adapter->mcc_lock); | 1417 | spin_unlock_bh(&adapter->mcc_lock); |
1337 | return status; | 1418 | return status; |
1338 | } | 1419 | } |