diff options
author | Thomas Klein <tklein@de.ibm.com> | 2010-04-20 19:10:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-22 01:32:43 -0400 |
commit | ea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a (patch) | |
tree | 1d7225d032cff478b9b01609cd739b3e5ebfa7bf /drivers/net/ehea/ehea_qmr.c | |
parent | a1aa8822d577c8714f8d343eea028befbab3da9d (diff) |
ehea: error handling improvement
Reset a port's resources only if they're actually in an error state
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ehea/ehea_qmr.c')
-rw-r--r-- | drivers/net/ehea/ehea_qmr.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index a1b4c7e5636..89128b6373e 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c | |||
@@ -229,14 +229,14 @@ u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force) | |||
229 | 229 | ||
230 | int ehea_destroy_cq(struct ehea_cq *cq) | 230 | int ehea_destroy_cq(struct ehea_cq *cq) |
231 | { | 231 | { |
232 | u64 hret; | 232 | u64 hret, aer, aerr; |
233 | if (!cq) | 233 | if (!cq) |
234 | return 0; | 234 | return 0; |
235 | 235 | ||
236 | hcp_epas_dtor(&cq->epas); | 236 | hcp_epas_dtor(&cq->epas); |
237 | hret = ehea_destroy_cq_res(cq, NORMAL_FREE); | 237 | hret = ehea_destroy_cq_res(cq, NORMAL_FREE); |
238 | if (hret == H_R_STATE) { | 238 | if (hret == H_R_STATE) { |
239 | ehea_error_data(cq->adapter, cq->fw_handle); | 239 | ehea_error_data(cq->adapter, cq->fw_handle, &aer, &aerr); |
240 | hret = ehea_destroy_cq_res(cq, FORCE_FREE); | 240 | hret = ehea_destroy_cq_res(cq, FORCE_FREE); |
241 | } | 241 | } |
242 | 242 | ||
@@ -357,7 +357,7 @@ u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force) | |||
357 | 357 | ||
358 | int ehea_destroy_eq(struct ehea_eq *eq) | 358 | int ehea_destroy_eq(struct ehea_eq *eq) |
359 | { | 359 | { |
360 | u64 hret; | 360 | u64 hret, aer, aerr; |
361 | if (!eq) | 361 | if (!eq) |
362 | return 0; | 362 | return 0; |
363 | 363 | ||
@@ -365,7 +365,7 @@ int ehea_destroy_eq(struct ehea_eq *eq) | |||
365 | 365 | ||
366 | hret = ehea_destroy_eq_res(eq, NORMAL_FREE); | 366 | hret = ehea_destroy_eq_res(eq, NORMAL_FREE); |
367 | if (hret == H_R_STATE) { | 367 | if (hret == H_R_STATE) { |
368 | ehea_error_data(eq->adapter, eq->fw_handle); | 368 | ehea_error_data(eq->adapter, eq->fw_handle, &aer, &aerr); |
369 | hret = ehea_destroy_eq_res(eq, FORCE_FREE); | 369 | hret = ehea_destroy_eq_res(eq, FORCE_FREE); |
370 | } | 370 | } |
371 | 371 | ||
@@ -540,7 +540,7 @@ u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force) | |||
540 | 540 | ||
541 | int ehea_destroy_qp(struct ehea_qp *qp) | 541 | int ehea_destroy_qp(struct ehea_qp *qp) |
542 | { | 542 | { |
543 | u64 hret; | 543 | u64 hret, aer, aerr; |
544 | if (!qp) | 544 | if (!qp) |
545 | return 0; | 545 | return 0; |
546 | 546 | ||
@@ -548,7 +548,7 @@ int ehea_destroy_qp(struct ehea_qp *qp) | |||
548 | 548 | ||
549 | hret = ehea_destroy_qp_res(qp, NORMAL_FREE); | 549 | hret = ehea_destroy_qp_res(qp, NORMAL_FREE); |
550 | if (hret == H_R_STATE) { | 550 | if (hret == H_R_STATE) { |
551 | ehea_error_data(qp->adapter, qp->fw_handle); | 551 | ehea_error_data(qp->adapter, qp->fw_handle, &aer, &aerr); |
552 | hret = ehea_destroy_qp_res(qp, FORCE_FREE); | 552 | hret = ehea_destroy_qp_res(qp, FORCE_FREE); |
553 | } | 553 | } |
554 | 554 | ||
@@ -986,42 +986,45 @@ void print_error_data(u64 *data) | |||
986 | if (length > EHEA_PAGESIZE) | 986 | if (length > EHEA_PAGESIZE) |
987 | length = EHEA_PAGESIZE; | 987 | length = EHEA_PAGESIZE; |
988 | 988 | ||
989 | if (type == 0x8) /* Queue Pair */ | 989 | if (type == EHEA_AER_RESTYPE_QP) |
990 | ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " | 990 | ehea_error("QP (resource=%llX) state: AER=0x%llX, AERR=0x%llX, " |
991 | "port=%llX", resource, data[6], data[12], data[22]); | 991 | "port=%llX", resource, data[6], data[12], data[22]); |
992 | 992 | else if (type == EHEA_AER_RESTYPE_CQ) | |
993 | if (type == 0x4) /* Completion Queue */ | ||
994 | ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, | 993 | ehea_error("CQ (resource=%llX) state: AER=0x%llX", resource, |
995 | data[6]); | 994 | data[6]); |
996 | 995 | else if (type == EHEA_AER_RESTYPE_EQ) | |
997 | if (type == 0x3) /* Event Queue */ | ||
998 | ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, | 996 | ehea_error("EQ (resource=%llX) state: AER=0x%llX", resource, |
999 | data[6]); | 997 | data[6]); |
1000 | 998 | ||
1001 | ehea_dump(data, length, "error data"); | 999 | ehea_dump(data, length, "error data"); |
1002 | } | 1000 | } |
1003 | 1001 | ||
1004 | void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle) | 1002 | u64 ehea_error_data(struct ehea_adapter *adapter, u64 res_handle, |
1003 | u64 *aer, u64 *aerr) | ||
1005 | { | 1004 | { |
1006 | unsigned long ret; | 1005 | unsigned long ret; |
1007 | u64 *rblock; | 1006 | u64 *rblock; |
1007 | u64 type = 0; | ||
1008 | 1008 | ||
1009 | rblock = (void *)get_zeroed_page(GFP_KERNEL); | 1009 | rblock = (void *)get_zeroed_page(GFP_KERNEL); |
1010 | if (!rblock) { | 1010 | if (!rblock) { |
1011 | ehea_error("Cannot allocate rblock memory."); | 1011 | ehea_error("Cannot allocate rblock memory."); |
1012 | return; | 1012 | goto out; |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | ret = ehea_h_error_data(adapter->handle, | 1015 | ret = ehea_h_error_data(adapter->handle, res_handle, rblock); |
1016 | res_handle, | ||
1017 | rblock); | ||
1018 | 1016 | ||
1019 | if (ret == H_R_STATE) | 1017 | if (ret == H_SUCCESS) { |
1020 | ehea_error("No error data is available: %llX.", res_handle); | 1018 | type = EHEA_BMASK_GET(ERROR_DATA_TYPE, rblock[2]); |
1021 | else if (ret == H_SUCCESS) | 1019 | *aer = rblock[6]; |
1020 | *aerr = rblock[12]; | ||
1022 | print_error_data(rblock); | 1021 | print_error_data(rblock); |
1023 | else | 1022 | } else if (ret == H_R_STATE) { |
1023 | ehea_error("No error data available: %llX.", res_handle); | ||
1024 | } else | ||
1024 | ehea_error("Error data could not be fetched: %llX", res_handle); | 1025 | ehea_error("Error data could not be fetched: %llX", res_handle); |
1025 | 1026 | ||
1026 | free_page((unsigned long)rblock); | 1027 | free_page((unsigned long)rblock); |
1028 | out: | ||
1029 | return type; | ||
1027 | } | 1030 | } |