aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan-Bernd Themann <ossthema@de.ibm.com>2007-02-09 03:10:51 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-09 16:09:46 -0500
commitd2db9eea7901d83e494340c93d131fc1fd463e4c (patch)
tree061610fc0237654c38308b6b1ccdabdc5d59102a
parenteaefd5fb7d793c9c1bcef1b0c0d5ec3824a85b91 (diff)
ehea: Fixed error recovery
Error recovery for QP errors: Reset QPs and dump error information Signed-off-by: Jan-Bernd Themann <themann@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/ehea/ehea.h2
-rw-r--r--drivers/net/ehea/ehea_main.c8
-rw-r--r--drivers/net/ehea/ehea_phyp.c10
-rw-r--r--drivers/net/ehea/ehea_phyp.h3
-rw-r--r--drivers/net/ehea/ehea_qmr.c42
-rw-r--r--drivers/net/ehea/ehea_qmr.h5
6 files changed, 68 insertions, 2 deletions
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 272e1ec51aa2..42295d61ecd8 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
39#include <asm/io.h> 39#include <asm/io.h>
40 40
41#define DRV_NAME "ehea" 41#define DRV_NAME "ehea"
42#define DRV_VERSION "EHEA_0045" 42#define DRV_VERSION "EHEA_0046"
43 43
44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ 44#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 45 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 9de2d38a5321..1ef3846a5ea0 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -76,7 +76,7 @@ void ehea_dump(void *adr, int len, char *msg) {
76 int x; 76 int x;
77 unsigned char *deb = adr; 77 unsigned char *deb = adr;
78 for (x = 0; x < len; x += 16) { 78 for (x = 0; x < len; x += 16) {
79 printk(DRV_NAME "%s adr=%p ofs=%04x %016lx %016lx\n", msg, 79 printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg,
80 deb, x, *((u64*)&deb[0]), *((u64*)&deb[8])); 80 deb, x, *((u64*)&deb[0]), *((u64*)&deb[8]));
81 deb += 16; 81 deb += 16;
82 } 82 }
@@ -555,6 +555,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
555{ 555{
556 struct ehea_port *port = param; 556 struct ehea_port *port = param;
557 struct ehea_eqe *eqe; 557 struct ehea_eqe *eqe;
558 struct ehea_qp *qp;
558 u32 qp_token; 559 u32 qp_token;
559 560
560 eqe = ehea_poll_eq(port->qp_eq); 561 eqe = ehea_poll_eq(port->qp_eq);
@@ -563,9 +564,14 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
563 qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry); 564 qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry);
564 ehea_error("QP aff_err: entry=0x%lx, token=0x%x", 565 ehea_error("QP aff_err: entry=0x%lx, token=0x%x",
565 eqe->entry, qp_token); 566 eqe->entry, qp_token);
567
568 qp = port->port_res[qp_token].qp;
569 ehea_error_data(port->adapter, qp->fw_handle);
566 eqe = ehea_poll_eq(port->qp_eq); 570 eqe = ehea_poll_eq(port->qp_eq);
567 } 571 }
568 572
573 queue_work(port->adapter->ehea_wq, &port->reset_task);
574
569 return IRQ_HANDLED; 575 return IRQ_HANDLED;
570} 576}
571 577
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index 37716e05e808..bc3c00547264 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -612,3 +612,13 @@ u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
612 event_mask, /* R6 */ 612 event_mask, /* R6 */
613 0, 0, 0, 0); /* R7-R12 */ 613 0, 0, 0, 0); /* R7-R12 */
614} 614}
615
616u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle,
617 void *rblock)
618{
619 return ehea_plpar_hcall_norets(H_ERROR_DATA,
620 adapter_handle, /* R4 */
621 ressource_handle, /* R5 */
622 virt_to_abs(rblock), /* R6 */
623 0, 0, 0, 0); /* R7-R12 */
624}
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index 919f94b75933..90acddb068a1 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -454,4 +454,7 @@ u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num,
454u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle, 454u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
455 const u64 event_mask); 455 const u64 event_mask);
456 456
457u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle,
458 void *rblock);
459
457#endif /* __EHEA_PHYP_H__ */ 460#endif /* __EHEA_PHYP_H__ */
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index f143e13b229d..96ff3b679996 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -486,6 +486,7 @@ int ehea_destroy_qp(struct ehea_qp *qp)
486 if (!qp) 486 if (!qp)
487 return 0; 487 return 0;
488 488
489 ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
489 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle); 490 hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle);
490 if (hret != H_SUCCESS) { 491 if (hret != H_SUCCESS) {
491 ehea_error("destroy_qp failed"); 492 ehea_error("destroy_qp failed");
@@ -581,4 +582,45 @@ out:
581 return ret; 582 return ret;
582} 583}
583 584
585void print_error_data(u64 *data)
586{
587 int length;
588 u64 type = EHEA_BMASK_GET(ERROR_DATA_TYPE, data[2]);
589 u64 resource = data[1];
590
591 length = EHEA_BMASK_GET(ERROR_DATA_LENGTH, data[0]);
592
593 if (length > EHEA_PAGESIZE)
594 length = EHEA_PAGESIZE;
595
596 if (type == 0x8) /* Queue Pair */
597 ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, "
598 "port=%lX", resource, data[6], data[12], data[22]);
599
600 ehea_dump(data, length, "error data");
601}
602
603void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
604{
605 unsigned long ret;
606 u64 *rblock;
607
608 rblock = kzalloc(PAGE_SIZE, GFP_KERNEL);
609 if (!rblock) {
610 ehea_error("Cannot allocate rblock memory.");
611 return;
612 }
584 613
614 ret = ehea_h_error_data(adapter->handle,
615 res_handle,
616 rblock);
617
618 if (ret == H_R_STATE)
619 ehea_error("No error data is available: %lX.", res_handle);
620 else if (ret == H_SUCCESS)
621 print_error_data(rblock);
622 else
623 ehea_error("Error data could not be fetched: %lX", res_handle);
624
625 kfree(rblock);
626}
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index 7efdc96919ca..1ff60983504d 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -180,6 +180,9 @@ struct ehea_eqe {
180 u64 entry; 180 u64 entry;
181}; 181};
182 182
183#define ERROR_DATA_LENGTH EHEA_BMASK_IBM(52,63)
184#define ERROR_DATA_TYPE EHEA_BMASK_IBM(0,7)
185
183static inline void *hw_qeit_calc(struct hw_queue *queue, u64 q_offset) 186static inline void *hw_qeit_calc(struct hw_queue *queue, u64 q_offset)
184{ 187{
185 struct ehea_page *current_page; 188 struct ehea_page *current_page;
@@ -355,4 +358,6 @@ int ehea_destroy_qp(struct ehea_qp *qp);
355 358
356int ehea_reg_mr_adapter(struct ehea_adapter *adapter); 359int ehea_reg_mr_adapter(struct ehea_adapter *adapter);
357 360
361void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle);
362
358#endif /* __EHEA_QMR_H__ */ 363#endif /* __EHEA_QMR_H__ */