cqe = ehea_poll_rq1(pr->qp, &wqe_index);
                cqe_skb = ehea_poll_cq(pr->send_cq);
 
-               if (!cqe && !cqe_skb) 
+               if (!cqe && !cqe_skb)
                        return 0;
 
-               if (!netif_rx_reschedule(dev, dev->quota)) 
+               if (!netif_rx_reschedule(dev, dev->quota))
                        return 0;
        }
-       
+
        cqe = ehea_proc_rwqes(dev, pr, budget);
        cqe_skb = ehea_proc_cqes(pr, 300);
 
        if (cqe || cqe_skb)
                pr->poll_counter++;
-       
+
        return 1;
 }
 
                else
                        cb0->default_qpn_arr[i] =
                                port->port_res[0].qp->init_attr.qp_nr;
-       
+
        if (netif_msg_ifup(port))
                ehea_dump(cb0, sizeof(*cb0), "ehea_configure_port");
 
        return ret;
 }
 
-static int ehea_gen_smrs(struct ehea_port_res *pr)
+int ehea_gen_smrs(struct ehea_port_res *pr)
 {
-       u64 hret;
+       int ret;
        struct ehea_adapter *adapter = pr->port->adapter;
 
-       hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle,
-                                  adapter->mr.vaddr, EHEA_MR_ACC_CTRL,
-                                  adapter->pd, &pr->send_mr);
-       if (hret != H_SUCCESS)
+       ret = ehea_gen_smr(adapter, &adapter->mr, &pr->send_mr);
+       if (ret)
                goto out;
 
-       hret = ehea_h_register_smr(adapter->handle, adapter->mr.handle,
-                                  adapter->mr.vaddr, EHEA_MR_ACC_CTRL,
-                                  adapter->pd, &pr->recv_mr);
-       if (hret != H_SUCCESS)
-               goto out_freeres;
+       ret = ehea_gen_smr(adapter, &adapter->mr, &pr->recv_mr);
+       if (ret)
+               goto out_free;
 
        return 0;
 
-out_freeres:
-       hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle);
-       if (hret != H_SUCCESS)
-               ehea_error("failed freeing SMR");
+out_free:
+       ehea_rem_mr(&pr->send_mr);
 out:
+       ehea_error("Generating SMRS failed\n");
        return -EIO;
 }
 
-static int ehea_rem_smrs(struct ehea_port_res *pr)
+int ehea_rem_smrs(struct ehea_port_res *pr)
 {
-       struct ehea_adapter *adapter = pr->port->adapter;
-       int ret = 0;
-       u64 hret;
-
-       hret = ehea_h_free_resource(adapter->handle, pr->send_mr.handle);
-       if (hret != H_SUCCESS) {
-               ret = -EIO;
-               ehea_error("failed freeing send SMR for pr=%p", pr);
-       }
-
-       hret = ehea_h_free_resource(adapter->handle, pr->recv_mr.handle);
-       if (hret != H_SUCCESS) {
-               ret = -EIO;
-               ehea_error("failed freeing recv SMR for pr=%p", pr);
-       }
-
-       return ret;
+       if ((ehea_rem_mr(&pr->send_mr))
+           || (ehea_rem_mr(&pr->recv_mr)))
+               return -EIO;
+       else
+               return 0;
 }
 
 static int ehea_init_q_skba(struct ehea_q_skb_arr *q_skba, int max_q_entries)
        ehea_free_interrupts(dev);
 
        for (i = 0; i < port->num_def_qps; i++)
-               while (test_bit(__LINK_STATE_RX_SCHED, 
+               while (test_bit(__LINK_STATE_RX_SCHED,
                                &port->port_res[i].d_netdev->state))
                        msleep(1);
 
                ehea_error("failed to register attributes, ret=%d", ret);
                goto out_unreg_of_dev;
        }
-       
+
        return &port->ofdev.dev;
 
 out_unreg_of_dev:
        }
 
        ret = ehea_get_jumboframe_status(port, &jumbo);
-       if (ret) 
+       if (ret)
                ehea_error("failed determining jumbo frame status for %s",
                           port->netdev->name);
 
 
        lhea_dn = adapter->ebus_dev->ofdev.node;
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
-               
+
                dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
                                                    NULL);
                if (!dn_log_port_id) {
                                                          eth_dn);
                if (adapter->port[i])
                        ehea_info("%s -> logical port id #%d",
-                                 adapter->port[i]->netdev->name, 
+                                 adapter->port[i]->netdev->name,
                                  *dn_log_port_id);
                i++;
        };
        return -EINVAL;
 }
 
-static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter, 
-                                          u32 logical_port_id) 
+static struct device_node *ehea_get_eth_dn(struct ehea_adapter *adapter,
+                                          u32 logical_port_id)
 {
        struct device_node *lhea_dn;
        struct device_node *eth_dn = NULL;
 
        lhea_dn = adapter->ebus_dev->ofdev.node;
        while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
-               
+
                dn_log_port_id = (u32*)get_property(eth_dn, "ibm,hea-port-no",
                                                    NULL);
                if (dn_log_port_id)
                          port->netdev->name);
                return -EINVAL;
        }
-       
+
        eth_dn = ehea_get_eth_dn(adapter, logical_port_id);
 
        if (!eth_dn) {
                ehea_info("no logical port with id %d found", logical_port_id);
                return -EINVAL;
        }
-               
+
        port = ehea_setup_single_port(adapter, logical_port_id, eth_dn);
 
        of_node_put(eth_dn);
 
                ehea_info("added %s (logical port id=%d)", port->netdev->name,
                          logical_port_id);
-       } else 
-               return -EIO;           
+       } else
+               return -EIO;
 
        return (ssize_t) count;
 }
 
        dev->ofdev.dev.driver_data = adapter;
 
-       ret = ehea_reg_mr_adapter(adapter);
+       ret = ehea_reg_kernel_mr(adapter, &adapter->mr);
        if (ret) {
                dev_err(&dev->ofdev.dev, "reg_mr_adapter failed\n");
                goto out_free_ad;
        ehea_destroy_eq(adapter->neq);
 
 out_free_res:
-       ehea_h_free_resource(adapter->handle, adapter->mr.handle);
+       ehea_rem_mr(&adapter->mr);
 
 out_free_ad:
        kfree(adapter);
 static int __devexit ehea_remove(struct ibmebus_dev *dev)
 {
        struct ehea_adapter *adapter = dev->ofdev.dev.driver_data;
-       u64 hret;
        int i;
 
        for (i = 0; i < EHEA_MAX_PORTS; i++)
        tasklet_kill(&adapter->neq_tasklet);
 
        ehea_destroy_eq(adapter->neq);
-
-       hret = ehea_h_free_resource(adapter->handle, adapter->mr.handle);
-       if (hret) {
-               dev_err(&dev->ofdev.dev, "free_resource_mr failed");
-               return -EIO;
-       }
+       ehea_rem_mr(&adapter->mr);
        kfree(adapter);
        return 0;
 }
 
        hw_queue_dtor(&cq->hw_queue);
 
 out_freeres:
-       ehea_h_free_resource(adapter->handle, cq->fw_handle);
+       ehea_h_free_resource(adapter->handle, cq->fw_handle, FORCE_FREE);
 
 out_freemem:
        kfree(cq);
        return NULL;
 }
 
-int ehea_destroy_cq(struct ehea_cq *cq)
+u64 ehea_destroy_cq_res(struct ehea_cq *cq, u64 force)
 {
-       u64 adapter_handle, hret;
+       u64 hret;
+       u64 adapter_handle = cq->adapter->handle;
+
+        /* deregister all previous registered pages */
+       hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force);
+       if (hret != H_SUCCESS)
+               return hret;
+
+       hw_queue_dtor(&cq->hw_queue);
+       kfree(cq);
+
+       return hret;
+}
 
+int ehea_destroy_cq(struct ehea_cq *cq)
+{
+       u64 hret;
        if (!cq)
                return 0;
 
-       adapter_handle = cq->adapter->handle;
+       if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) {
+               ehea_error_data(cq->adapter, cq->fw_handle);
+               hret = ehea_destroy_cq_res(cq, FORCE_FREE);
+       }
 
-       /* deregister all previous registered pages */
-       hret = ehea_h_free_resource(adapter_handle, cq->fw_handle);
        if (hret != H_SUCCESS) {
                ehea_error("destroy CQ failed");
                return -EIO;
        }
 
-       hw_queue_dtor(&cq->hw_queue);
-       kfree(cq);
-
        return 0;
 }
 
        hw_queue_dtor(&eq->hw_queue);
 
 out_freeres:
-       ehea_h_free_resource(adapter->handle, eq->fw_handle);
+       ehea_h_free_resource(adapter->handle, eq->fw_handle, FORCE_FREE);
 
 out_freemem:
        kfree(eq);
        return eqe;
 }
 
-int ehea_destroy_eq(struct ehea_eq *eq)
+u64 ehea_destroy_eq_res(struct ehea_eq *eq, u64 force)
 {
        u64 hret;
        unsigned long flags;
 
-       if (!eq)
-               return 0;
-
        spin_lock_irqsave(&eq->spinlock, flags);
 
-       hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle);
+       hret = ehea_h_free_resource(eq->adapter->handle, eq->fw_handle, force);
        spin_unlock_irqrestore(&eq->spinlock, flags);
 
-       if (hret != H_SUCCESS) {
-               ehea_error("destroy_eq failed");
-               return -EIO;
-       }
+       if (hret != H_SUCCESS)
+               return hret;
 
        hw_queue_dtor(&eq->hw_queue);
        kfree(eq);
 
+       return hret;
+}
+
+int ehea_destroy_eq(struct ehea_eq *eq)
+{
+       u64 hret;
+       if (!eq)
+               return 0;
+
+       if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) {
+               ehea_error_data(eq->adapter, eq->fw_handle);
+               hret = ehea_destroy_eq_res(eq, FORCE_FREE);
+       }
+
+       if (hret != H_SUCCESS) {
+               ehea_error("destroy EQ failed");
+               return -EIO;
+        }
+
        return 0;
 }
 
 
 out_freeres:
        ehea_h_disable_and_get_hea(adapter->handle, qp->fw_handle);
-       ehea_h_free_resource(adapter->handle, qp->fw_handle);
+       ehea_h_free_resource(adapter->handle, qp->fw_handle, FORCE_FREE);
 
 out_freemem:
        kfree(qp);
        return NULL;
 }
 
-int ehea_destroy_qp(struct ehea_qp *qp)
+u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force)
 {
-       u64 hret;
-       struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
+        u64 hret;
+        struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
 
-       if (!qp)
-               return 0;
 
-       ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
-       hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle);
-       if (hret != H_SUCCESS) {
-               ehea_error("destroy_qp failed");
-               return -EIO;
-       }
+        ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
+        hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
+        if (hret != H_SUCCESS)
+                return hret;
 
-       hw_queue_dtor(&qp->hw_squeue);
-       hw_queue_dtor(&qp->hw_rqueue1);
+        hw_queue_dtor(&qp->hw_squeue);
+        hw_queue_dtor(&qp->hw_rqueue1);
 
-       if (qp_attr->rq_count > 1)
-               hw_queue_dtor(&qp->hw_rqueue2);
-       if (qp_attr->rq_count > 2)
-               hw_queue_dtor(&qp->hw_rqueue3);
-       kfree(qp);
+        if (qp_attr->rq_count > 1)
+                hw_queue_dtor(&qp->hw_rqueue2);
+        if (qp_attr->rq_count > 2)
+                hw_queue_dtor(&qp->hw_rqueue3);
+        kfree(qp);
 
-       return 0;
+        return hret;
 }
 
-int ehea_reg_mr_adapter(struct ehea_adapter *adapter)
+int ehea_destroy_qp(struct ehea_qp *qp)
+{
+        u64 hret;
+        if (!qp)
+                return 0;
+
+        if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
+                ehea_error_data(qp->adapter, qp->fw_handle);
+                hret = ehea_destroy_qp_res(qp, FORCE_FREE);
+        }
+
+        if (hret != H_SUCCESS) {
+                ehea_error("destroy QP failed");
+                return -EIO;
+        }
+
+        return 0;
+}
+
+int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 {
        int i, k, ret;
        u64 hret, pt_abs, start, end, nr_pages;
 
        hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start,
                                        acc_ctrl, adapter->pd,
-                                       &adapter->mr.handle, &adapter->mr.lkey);
+                                       &mr->handle, &mr->lkey);
        if (hret != H_SUCCESS) {
                ehea_error("alloc_resource_mr failed");
                ret = -EIO;
                goto out;
        }
 
-       adapter->mr.vaddr = KERNELBASE;
+       mr->vaddr = KERNELBASE;
        k = 0;
 
        while (nr_pages > 0) {
                                                             EHEA_PAGESIZE)));
 
                        hret = ehea_h_register_rpage_mr(adapter->handle,
-                                                       adapter->mr.handle, 0,
+                                                       mr->handle, 0,
                                                        0, (u64)pt_abs,
                                                        num_pages);
                        nr_pages -= num_pages;
                                                          (k * EHEA_PAGESIZE)));
 
                        hret = ehea_h_register_rpage_mr(adapter->handle,
-                                                       adapter->mr.handle, 0,
+                                                       mr->handle, 0,
                                                        0, abs_adr,1);
                        nr_pages--;
                }
 
                if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) {
                        ehea_h_free_resource(adapter->handle,
-                                               adapter->mr.handle);
-                       ehea_error("register_rpage_mr failed: hret = %lX",
-                                  hret);
+                                            mr->handle, FORCE_FREE);
+                       ehea_error("register_rpage_mr failed");
                        ret = -EIO;
                        goto out;
                }
        }
 
        if (hret != H_SUCCESS) {
-               ehea_h_free_resource(adapter->handle, adapter->mr.handle);
-               ehea_error("register_rpage failed for last page: hret = %lX",
-                          hret);
+               ehea_h_free_resource(adapter->handle, mr->handle,
+                                    FORCE_FREE);
+               ehea_error("register_rpage failed for last page");
                ret = -EIO;
                goto out;
        }
+
+       mr->adapter = adapter;
        ret = 0;
 out:
        kfree(pt);
        return ret;
 }
 
+int ehea_rem_mr(struct ehea_mr *mr)
+{
+       u64 hret;
+
+       if (!mr || !mr->adapter)
+               return -EINVAL;
+
+       hret = ehea_h_free_resource(mr->adapter->handle, mr->handle,
+                                   FORCE_FREE);
+       if (hret != H_SUCCESS) {
+               ehea_error("destroy MR failed");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+int ehea_gen_smr(struct ehea_adapter *adapter, struct ehea_mr *old_mr,
+                struct ehea_mr *shared_mr)
+{
+       u64 hret;
+
+       hret = ehea_h_register_smr(adapter->handle, old_mr->handle,
+                                  old_mr->vaddr, EHEA_MR_ACC_CTRL,
+                                  adapter->pd, shared_mr);
+       if (hret != H_SUCCESS)
+               return -EIO;
+
+       shared_mr->adapter = adapter;
+
+       return 0;
+}
+
 void print_error_data(u64 *data)
 {
        int length;
                ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, "
                           "port=%lX", resource, data[6], data[12], data[22]);
 
+       if (type == 0x4) /* Completion Queue */
+               ehea_error("CQ (resource=%lX) state: AER=0x%lX", resource,
+                          data[6]);
+
+       if (type == 0x3) /* Event Queue */
+               ehea_error("EQ (resource=%lX) state: AER=0x%lX", resource,
+                          data[6]);
+
        ehea_dump(data, length, "error data");
 }