diff options
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r-- | drivers/net/ehea/ehea_main.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3f445efa9482..39774817c3eb 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -791,11 +791,17 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | |||
791 | cqe_counter++; | 791 | cqe_counter++; |
792 | rmb(); | 792 | rmb(); |
793 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { | 793 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { |
794 | ehea_error("Send Completion Error: Resetting port"); | 794 | ehea_error("Bad send completion status=0x%04X", |
795 | cqe->status); | ||
796 | |||
795 | if (netif_msg_tx_err(pr->port)) | 797 | if (netif_msg_tx_err(pr->port)) |
796 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); | 798 | ehea_dump(cqe, sizeof(*cqe), "Send CQE"); |
797 | ehea_schedule_port_reset(pr->port); | 799 | |
798 | break; | 800 | if (cqe->status & EHEA_CQE_STAT_RESET_MASK) { |
801 | ehea_error("Resetting port"); | ||
802 | ehea_schedule_port_reset(pr->port); | ||
803 | break; | ||
804 | } | ||
799 | } | 805 | } |
800 | 806 | ||
801 | if (netif_msg_tx_done(pr->port)) | 807 | if (netif_msg_tx_done(pr->port)) |
@@ -901,6 +907,8 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) | |||
901 | struct ehea_eqe *eqe; | 907 | struct ehea_eqe *eqe; |
902 | struct ehea_qp *qp; | 908 | struct ehea_qp *qp; |
903 | u32 qp_token; | 909 | u32 qp_token; |
910 | u64 resource_type, aer, aerr; | ||
911 | int reset_port = 0; | ||
904 | 912 | ||
905 | eqe = ehea_poll_eq(port->qp_eq); | 913 | eqe = ehea_poll_eq(port->qp_eq); |
906 | 914 | ||
@@ -910,11 +918,24 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param) | |||
910 | eqe->entry, qp_token); | 918 | eqe->entry, qp_token); |
911 | 919 | ||
912 | qp = port->port_res[qp_token].qp; | 920 | qp = port->port_res[qp_token].qp; |
913 | ehea_error_data(port->adapter, qp->fw_handle); | 921 | |
922 | resource_type = ehea_error_data(port->adapter, qp->fw_handle, | ||
923 | &aer, &aerr); | ||
924 | |||
925 | if (resource_type == EHEA_AER_RESTYPE_QP) { | ||
926 | if ((aer & EHEA_AER_RESET_MASK) || | ||
927 | (aerr & EHEA_AERR_RESET_MASK)) | ||
928 | reset_port = 1; | ||
929 | } else | ||
930 | reset_port = 1; /* Reset in case of CQ or EQ error */ | ||
931 | |||
914 | eqe = ehea_poll_eq(port->qp_eq); | 932 | eqe = ehea_poll_eq(port->qp_eq); |
915 | } | 933 | } |
916 | 934 | ||
917 | ehea_schedule_port_reset(port); | 935 | if (reset_port) { |
936 | ehea_error("Resetting port"); | ||
937 | ehea_schedule_port_reset(port); | ||
938 | } | ||
918 | 939 | ||
919 | return IRQ_HANDLED; | 940 | return IRQ_HANDLED; |
920 | } | 941 | } |
@@ -2868,7 +2889,6 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2868 | int ret, i; | 2889 | int ret, i; |
2869 | struct ehea_adapter *adapter; | 2890 | struct ehea_adapter *adapter; |
2870 | 2891 | ||
2871 | mutex_lock(&dlpar_mem_lock); | ||
2872 | ehea_info("LPAR memory changed - re-initializing driver"); | 2892 | ehea_info("LPAR memory changed - re-initializing driver"); |
2873 | 2893 | ||
2874 | list_for_each_entry(adapter, &adapter_list, list) | 2894 | list_for_each_entry(adapter, &adapter_list, list) |
@@ -2938,7 +2958,6 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2938 | } | 2958 | } |
2939 | ehea_info("re-initializing driver complete"); | 2959 | ehea_info("re-initializing driver complete"); |
2940 | out: | 2960 | out: |
2941 | mutex_unlock(&dlpar_mem_lock); | ||
2942 | return; | 2961 | return; |
2943 | } | 2962 | } |
2944 | 2963 | ||
@@ -3521,7 +3540,14 @@ void ehea_crash_handler(void) | |||
3521 | static int ehea_mem_notifier(struct notifier_block *nb, | 3540 | static int ehea_mem_notifier(struct notifier_block *nb, |
3522 | unsigned long action, void *data) | 3541 | unsigned long action, void *data) |
3523 | { | 3542 | { |
3543 | int ret = NOTIFY_BAD; | ||
3524 | struct memory_notify *arg = data; | 3544 | struct memory_notify *arg = data; |
3545 | |||
3546 | if (!mutex_trylock(&dlpar_mem_lock)) { | ||
3547 | ehea_info("ehea_mem_notifier must not be called parallelized"); | ||
3548 | goto out; | ||
3549 | } | ||
3550 | |||
3525 | switch (action) { | 3551 | switch (action) { |
3526 | case MEM_CANCEL_OFFLINE: | 3552 | case MEM_CANCEL_OFFLINE: |
3527 | ehea_info("memory offlining canceled"); | 3553 | ehea_info("memory offlining canceled"); |
@@ -3530,14 +3556,14 @@ static int ehea_mem_notifier(struct notifier_block *nb, | |||
3530 | ehea_info("memory is going online"); | 3556 | ehea_info("memory is going online"); |
3531 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | 3557 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); |
3532 | if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) | 3558 | if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) |
3533 | return NOTIFY_BAD; | 3559 | goto out_unlock; |
3534 | ehea_rereg_mrs(NULL); | 3560 | ehea_rereg_mrs(NULL); |
3535 | break; | 3561 | break; |
3536 | case MEM_GOING_OFFLINE: | 3562 | case MEM_GOING_OFFLINE: |
3537 | ehea_info("memory is going offline"); | 3563 | ehea_info("memory is going offline"); |
3538 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); | 3564 | set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); |
3539 | if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) | 3565 | if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) |
3540 | return NOTIFY_BAD; | 3566 | goto out_unlock; |
3541 | ehea_rereg_mrs(NULL); | 3567 | ehea_rereg_mrs(NULL); |
3542 | break; | 3568 | break; |
3543 | default: | 3569 | default: |
@@ -3545,8 +3571,12 @@ static int ehea_mem_notifier(struct notifier_block *nb, | |||
3545 | } | 3571 | } |
3546 | 3572 | ||
3547 | ehea_update_firmware_handles(); | 3573 | ehea_update_firmware_handles(); |
3574 | ret = NOTIFY_OK; | ||
3548 | 3575 | ||
3549 | return NOTIFY_OK; | 3576 | out_unlock: |
3577 | mutex_unlock(&dlpar_mem_lock); | ||
3578 | out: | ||
3579 | return ret; | ||
3550 | } | 3580 | } |
3551 | 3581 | ||
3552 | static struct notifier_block ehea_mem_nb = { | 3582 | static struct notifier_block ehea_mem_nb = { |