net/mlx5_core: Identify resources by their type
[linux-2.6-block.git] / drivers / net / ethernet / mellanox / mlx5 / core / qp.c
index 415b67ce379e97ebe1c8af4f76021e1f8e871688..5261a2b0da436b3a4359787c11dbc3686ee70689 100644 (file)
 
 #include "mlx5_core.h"
 
-void mlx5_qp_event(struct mlx5_core_dev *dev, u32 qpn, int event_type)
+static struct mlx5_core_rsc_common *mlx5_get_rsc(struct mlx5_core_dev *dev,
+                                                u32 rsn)
 {
        struct mlx5_qp_table *table = &dev->priv.qp_table;
-       struct mlx5_core_qp *qp;
+       struct mlx5_core_rsc_common *common;
 
        spin_lock(&table->lock);
 
-       qp = radix_tree_lookup(&table->tree, qpn);
-       if (qp)
-               atomic_inc(&qp->refcount);
+       common = radix_tree_lookup(&table->tree, rsn);
+       if (common)
+               atomic_inc(&common->refcount);
 
        spin_unlock(&table->lock);
 
-       if (!qp) {
-               mlx5_core_warn(dev, "Async event for bogus QP 0x%x\n", qpn);
-               return;
+       if (!common) {
+               mlx5_core_warn(dev, "Async event for bogus resource 0x%x\n",
+                              rsn);
+               return NULL;
        }
+       return common;
+}
 
-       qp->event(qp, event_type);
+void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
+{
+       if (atomic_dec_and_test(&common->refcount))
+               complete(&common->free);
+}
+
+void mlx5_rsc_event(struct mlx5_core_dev *dev, u32 rsn, int event_type)
+{
+       struct mlx5_core_rsc_common *common = mlx5_get_rsc(dev, rsn);
+       struct mlx5_core_qp *qp;
+
+       if (!common)
+               return;
+
+       switch (common->res) {
+       case MLX5_RES_QP:
+               qp = (struct mlx5_core_qp *)common;
+               qp->event(qp, event_type);
+               break;
+
+       default:
+               mlx5_core_warn(dev, "invalid resource type for 0x%x\n", rsn);
+       }
 
-       if (atomic_dec_and_test(&qp->refcount))
-               complete(&qp->free);
+       mlx5_core_put_rsc(common);
 }
 
 int mlx5_core_create_qp(struct mlx5_core_dev *dev,
@@ -92,6 +117,7 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
        qp->qpn = be32_to_cpu(out.qpn) & 0xffffff;
        mlx5_core_dbg(dev, "qpn = 0x%x\n", qp->qpn);
 
+       qp->common.res = MLX5_RES_QP;
        spin_lock_irq(&table->lock);
        err = radix_tree_insert(&table->tree, qp->qpn, qp);
        spin_unlock_irq(&table->lock);
@@ -106,9 +132,9 @@ int mlx5_core_create_qp(struct mlx5_core_dev *dev,
                              qp->qpn);
 
        qp->pid = current->pid;
-       atomic_set(&qp->refcount, 1);
+       atomic_set(&qp->common.refcount, 1);
        atomic_inc(&dev->num_qps);
-       init_completion(&qp->free);
+       init_completion(&qp->common.free);
 
        return 0;
 
@@ -138,9 +164,8 @@ int mlx5_core_destroy_qp(struct mlx5_core_dev *dev,
        radix_tree_delete(&table->tree, qp->qpn);
        spin_unlock_irqrestore(&table->lock, flags);
 
-       if (atomic_dec_and_test(&qp->refcount))
-               complete(&qp->free);
-       wait_for_completion(&qp->free);
+       mlx5_core_put_rsc((struct mlx5_core_rsc_common *)qp);
+       wait_for_completion(&qp->common.free);
 
        memset(&in, 0, sizeof(in));
        memset(&out, 0, sizeof(out));