All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH rdma-core 00/10] Rework the verb init scheme
@ 2017-09-19 21:18 Jason Gunthorpe
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA

This changes how verbs providers register with the core and are bound to
drivers.

The end goal is to have textual a list of 'modalias' that each provider
supports, similar to the kernel. This list can then ultimately be used to
demand load the modules instead of loading every module like we do today.

This series does the work to bring all providers to use common code to match
their supported devices, and provides the core code the supported device
list. This is done by extending the verbs_driver_ops to include the matching
information that the driver needs.

Quite a lot of duplicated driver code is removed in the process, and verbs
startup reads fewer sysfs files.

https://github.com/linux-rdma/rdma-core/pull/214

Jason Gunthorpe (10):
  verbs: Change verbs_register_driver to accept the ops struct directly
  cxgb4: Move sysconf up to driver_init
  verbs: Split init_device into a match and alloc/bind step
  providers: Use the new match_device and allocate_device ops
  verbs: Remove the init_device entry point
  verbs: Provide common code to match providers against kernel devices
  providers: Use the new common PCI matching infrastructure
  cxgb: Use the new common PCI matching infrastructure
  hns: Use the generic modalias matcher
  rxe: Use VERBS_NAME_MATCH to match the rxe device

 libibverbs/driver.h                |  77 +++++++++++++++++-
 libibverbs/init.c                  | 162 +++++++++++++++++++++++++++++--------
 providers/bnxt_re/main.c           |  69 ++++------------
 providers/cxgb3/iwch.c             | 102 ++++++++---------------
 providers/cxgb4/dev.c              | 110 ++++++++++---------------
 providers/hfi1verbs/hfiverbs.c     |  65 +++++----------
 providers/hns/hns_roce_u.c         |  80 +++++-------------
 providers/hns/hns_roce_u.h         |   1 +
 providers/hns/hns_roce_u_hw_v1.c   |   1 +
 providers/i40iw/i40iw_umain.c      |  69 +++++-----------
 providers/ipathverbs/ipathverbs.c  |  66 +++++----------
 providers/mlx4/mlx4.c              |  75 +++++------------
 providers/mlx5/mlx5.c              |  77 +++++-------------
 providers/mthca/mthca.c            |  75 +++++------------
 providers/nes/nes_umain.c          |  80 +++++-------------
 providers/ocrdma/ocrdma_main.c     |  84 +++++--------------
 providers/qedr/qelr_main.c         |  73 ++++-------------
 providers/rxe/rxe.c                |  50 +++++-------
 providers/vmw_pvrdma/pvrdma_main.c |  76 +++++------------
 19 files changed, 530 insertions(+), 862 deletions(-)

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-2-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 02/10] cxgb4: Move sysconf up to driver_init Jason Gunthorpe
                     ` (9 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: Doug Ledford, Yishai Hadas, Devesh Sharma, Steve Wise,
	Mike Marciniszyn, Dennis Dalessandro, Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Vladimir Sokolovsky, Ram Amrani, Ariel Elior,
	Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER for hf1.ko,
	open list:IPATH/QIB USERSPACE PROVIDER for ib_qib.ko,
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

This is analogous to the kernel scheme where code describes a driver
with a static structure and then a helper macro registers that
driver with the core code.

In this case we have an 'ops' that is both the 'driver' and 'device'
ops.

This is preparation to add more steps to the device startup. Rework
all the providers to use this scheme.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 libibverbs/driver.h                | 15 ++++++++++++++-
 libibverbs/init.c                  | 20 ++++++++++----------
 providers/bnxt_re/main.c           | 17 +++++++----------
 providers/cxgb3/iwch.c             | 19 ++++++++-----------
 providers/cxgb4/dev.c              | 17 +++++++++--------
 providers/hfi1verbs/hfiverbs.c     | 19 ++++++++-----------
 providers/hns/hns_roce_u.c         | 19 ++++++++-----------
 providers/i40iw/i40iw_umain.c      | 19 ++++++++-----------
 providers/ipathverbs/ipathverbs.c  | 19 ++++++++-----------
 providers/mlx4/mlx4.c              | 19 ++++++++-----------
 providers/mlx5/mlx5.c              | 19 ++++++++-----------
 providers/mthca/mthca.c            | 19 ++++++++-----------
 providers/nes/nes_umain.c          | 26 ++++++++------------------
 providers/ocrdma/ocrdma_main.c     | 23 ++++++++---------------
 providers/qedr/qelr_main.c         | 21 ++++++++-------------
 providers/rxe/rxe.c                | 20 ++++++++------------
 providers/vmw_pvrdma/pvrdma_main.c | 19 ++++++++-----------
 17 files changed, 144 insertions(+), 186 deletions(-)

diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index 887412de6327c3..f9f5cfa2308c2f 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -97,6 +97,8 @@ struct verbs_qp {
 
 /* Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed */
 struct verbs_device_ops {
+	const char *name;
+
 	/* Old interface, do not use in new code. */
 	struct ibv_context *(*alloc_context)(struct ibv_device *device,
 					     int cmd_fd);
@@ -107,6 +109,9 @@ struct verbs_device_ops {
 			    struct ibv_context *ctx, int cmd_fd);
 	void (*uninit_context)(struct verbs_device *device,
 			       struct ibv_context *ctx);
+
+	struct verbs_device *(*init_device)(const char *uverbs_sys_path,
+					    int abi_version);
 	void (*uninit_device)(struct verbs_device *device);
 };
 
@@ -139,7 +144,15 @@ typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_pa
 #define __make_verbs_register_driver(x)  ___make_verbs_register_driver(x)
 #define verbs_register_driver __make_verbs_register_driver(IBVERBS_PABI_VERSION)
 
-void verbs_register_driver(const char *name, verbs_driver_init_func init_func);
+void verbs_register_driver(const struct verbs_device_ops *ops);
+
+/* Macro for providers to use to supply verbs_device_ops to the core code */
+#define PROVIDER_DRIVER(drv)                                                   \
+	static __attribute__((constructor)) void drv##__register_driver(void)  \
+	{                                                                      \
+		verbs_register_driver(&drv);                                   \
+	}
+
 void verbs_init_cq(struct ibv_cq *cq, struct ibv_context *context,
 		       struct ibv_comp_channel *channel,
 		       void *cq_context);
diff --git a/libibverbs/init.c b/libibverbs/init.c
index e94a65b000ac4b..996406e2efa258 100644
--- a/libibverbs/init.c
+++ b/libibverbs/init.c
@@ -70,8 +70,7 @@ struct ibv_driver_name {
 
 struct ibv_driver {
 	struct list_node	entry;
-	const char	       *name;
-	verbs_driver_init_func	verbs_init_func;
+	const struct verbs_device_ops *ops;
 };
 
 static LIST_HEAD(driver_name_list);
@@ -164,19 +163,19 @@ static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list)
 	return ret;
 }
 
-void verbs_register_driver(const char *name,
-			   verbs_driver_init_func verbs_init_func)
+void verbs_register_driver(const struct verbs_device_ops *ops)
 {
 	struct ibv_driver *driver;
 
 	driver = malloc(sizeof *driver);
 	if (!driver) {
-		fprintf(stderr, PFX "Warning: couldn't allocate driver for %s\n", name);
+		fprintf(stderr,
+			PFX "Warning: couldn't allocate driver for %s\n",
+			ops->name);
 		return;
 	}
 
-	driver->name            = name;
-	driver->verbs_init_func = verbs_init_func;
+	driver->ops = ops;
 
 	list_add_tail(&driver_list, &driver->entry);
 }
@@ -354,16 +353,17 @@ out:
 	closedir(conf_dir);
 }
 
-static struct verbs_device *try_driver(struct ibv_driver *driver,
+static struct verbs_device *try_driver(const struct verbs_device_ops *ops,
 				       struct ibv_sysfs_dev *sysfs_dev)
 {
 	struct verbs_device *vdev;
 	struct ibv_device *dev;
 	char value[16];
 
-	vdev = driver->verbs_init_func(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
+	vdev = ops->init_device(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
 	if (!vdev)
 		return NULL;
+	vdev->ops = ops;
 
 	atomic_init(&vdev->refcount, 1);
 	dev = &vdev->device;
@@ -415,7 +415,7 @@ static struct verbs_device *try_drivers(struct ibv_sysfs_dev *sysfs_dev)
 	struct verbs_device *dev;
 
 	list_for_each(&driver_list, driver, entry) {
-		dev = try_driver(driver, sysfs_dev);
+		dev = try_driver(driver->ops, sysfs_dev);
 		if (dev)
 			return dev;
 	}
diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
index 3c21bec2ea8608..d2c2a6847e3c71 100644
--- a/providers/bnxt_re/main.c
+++ b/providers/bnxt_re/main.c
@@ -174,11 +174,6 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
 	}
 }
 
-static struct verbs_device_ops bnxt_re_dev_ops = {
-	.init_context = bnxt_re_init_context,
-	.uninit_context = bnxt_re_uninit_context,
-};
-
 static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,
 						int abi_version)
 {
@@ -220,12 +215,14 @@ found:
 	dev->vdev.sz = sizeof(*dev);
 	dev->vdev.size_of_context =
 		sizeof(struct bnxt_re_context) - sizeof(struct ibv_context);
-	dev->vdev.ops = &bnxt_re_dev_ops;
 
 	return &dev->vdev;
 }
 
-static __attribute__((constructor)) void bnxt_re_register_driver(void)
-{
-	verbs_register_driver("bnxt_re", bnxt_re_driver_init);
-}
+static const struct verbs_device_ops bnxt_re_dev_ops = {
+	.name = "bnxt_re",
+	.init_device = bnxt_re_driver_init,
+	.init_context = bnxt_re_init_context,
+	.uninit_context = bnxt_re_uninit_context,
+};
+PROVIDER_DRIVER(bnxt_re_dev_ops);
diff --git a/providers/cxgb3/iwch.c b/providers/cxgb3/iwch.c
index 26cc7bbc3b0e64..c2423a7ee2cc32 100644
--- a/providers/cxgb3/iwch.c
+++ b/providers/cxgb3/iwch.c
@@ -173,12 +173,6 @@ static void iwch_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops iwch_dev_ops = {
-	.alloc_context = iwch_alloc_context,
-	.free_context = iwch_free_context,
-	.uninit_device = iwch_uninit_device
-};
-
 static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
 					      int abi_version)
 {
@@ -259,7 +253,6 @@ found:
 	}
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
-	dev->ibv_dev.ops = &iwch_dev_ops;
 	dev->hca_type = hca_table[i].type;
 	dev->abi_version = abi_version;
 
@@ -290,7 +283,11 @@ err1:
 	return NULL;
 }
 
-static __attribute__((constructor)) void cxgb3_register_driver(void)
-{
-	verbs_register_driver("cxgb3", cxgb3_driver_init);
-}
+static const struct verbs_device_ops iwch_dev_ops = {
+	.name = "cxgb3",
+	.init_device = cxgb3_driver_init,
+	.uninit_device = iwch_uninit_device,
+	.alloc_context = iwch_alloc_context,
+	.free_context = iwch_free_context,
+};
+PROVIDER_DRIVER(iwch_dev_ops);
diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
index 30182cb152f83f..fea9b5527072ec 100644
--- a/providers/cxgb4/dev.c
+++ b/providers/cxgb4/dev.c
@@ -227,12 +227,6 @@ static void c4iw_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops c4iw_dev_ops = {
-	.alloc_context = c4iw_alloc_context,
-	.free_context = c4iw_free_context,
-	.uninit_device = c4iw_uninit_device
-};
-
 #ifdef STALL_DETECTION
 
 int stall_to;
@@ -478,7 +472,6 @@ found:
 	}
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
-	dev->ibv_dev.ops = &c4iw_dev_ops;
 	dev->chip_version = CHELSIO_CHIP_VERSION(hca_table[i].device >> 8);
 	dev->abi_version = abi_version;
 	list_node_init(&dev->list);
@@ -515,12 +508,20 @@ found:
 	return &dev->ibv_dev;
 }
 
+static const struct verbs_device_ops c4iw_dev_ops = {
+	.name = "cxgb4",
+	.init_device = cxgb4_driver_init,
+	.uninit_device = c4iw_uninit_device,
+	.alloc_context = c4iw_alloc_context,
+	.free_context = c4iw_free_context,
+};
+
 static __attribute__((constructor)) void cxgb4_register_driver(void)
 {
 	c4iw_page_size = sysconf(_SC_PAGESIZE);
 	c4iw_page_shift = long_log2(c4iw_page_size);
 	c4iw_page_mask = ~(c4iw_page_size - 1);
-	verbs_register_driver("cxgb4", cxgb4_driver_init);
+	verbs_register_driver(&c4iw_dev_ops);
 }
 
 #ifdef STATS
diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
index b5d0099585cd9a..247831eb211804 100644
--- a/providers/hfi1verbs/hfiverbs.c
+++ b/providers/hfi1verbs/hfiverbs.c
@@ -180,12 +180,6 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops hfi1_dev_ops = {
-	.alloc_context	= hfi1_alloc_context,
-	.free_context	= hfi1_free_context,
-	.uninit_device  = hf11_uninit_device
-};
-
 static struct verbs_device *hfi1_driver_init(const char *uverbs_sys_path,
 					     int abi_version)
 {
@@ -219,13 +213,16 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &hfi1_dev_ops;
 	dev->abi_version = abi_version;
 
 	return &dev->ibv_dev;
 }
 
-static __attribute__((constructor)) void hfi1_register_driver(void)
-{
-	verbs_register_driver("hfi1verbs", hfi1_driver_init);
-}
+static const struct verbs_device_ops hfi1_dev_ops = {
+	.name = "hfi1verbs",
+	.init_device = hfi1_driver_init,
+	.uninit_device  = hf11_uninit_device,
+	.alloc_context = hfi1_alloc_context,
+	.free_context = hfi1_free_context,
+};
+PROVIDER_DRIVER(hfi1_dev_ops);
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index 7dae5fdc71e332..fe2d009ebe3737 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -180,12 +180,6 @@ static void hns_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops hns_roce_dev_ops = {
-	.alloc_context = hns_roce_alloc_context,
-	.free_context	= hns_roce_free_context,
-	.uninit_device = hns_uninit_device
-};
-
 static struct verbs_device *hns_roce_driver_init(const char *uverbs_sys_path,
 						 int abi_version)
 {
@@ -223,14 +217,17 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &hns_roce_dev_ops;
 	dev->u_hw = (struct hns_roce_u_hw *)u_hw;
 	dev->hw_version = hw_version;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 	return &dev->ibv_dev;
 }
 
-static __attribute__((constructor)) void hns_roce_register_driver(void)
-{
-	verbs_register_driver("hns", hns_roce_driver_init);
-}
+static const struct verbs_device_ops hns_roce_dev_ops = {
+	.name = "hns",
+	.init_device = hns_roce_driver_init,
+	.uninit_device = hns_uninit_device,
+	.alloc_context = hns_roce_alloc_context,
+	.free_context = hns_roce_free_context,
+};
+PROVIDER_DRIVER(hns_roce_dev_ops);
diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
index 3b7aebba06a4fe..90d37651d1f702 100644
--- a/providers/i40iw/i40iw_umain.c
+++ b/providers/i40iw/i40iw_umain.c
@@ -215,12 +215,6 @@ static void i40iw_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops i40iw_udev_ops = {
-	.alloc_context	= i40iw_ualloc_context,
-	.free_context	= i40iw_ufree_context,
-	.uninit_device  = i40iw_uninit_device
-};
-
 /**
  * i40iw_driver_init - create device struct and provide callback routines for user context
  * @uverbs_sys_path: sys path
@@ -256,13 +250,16 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &i40iw_udev_ops;
 	dev->hca_type = hca_table[i].type;
 	dev->page_size = I40IW_HW_PAGE_SIZE;
 	return &dev->ibv_dev;
 }
 
-static __attribute__ ((constructor)) void i40iw_register_driver(void)
-{
-	verbs_register_driver("i40iw", i40iw_driver_init);
-}
+static const struct verbs_device_ops i40iw_udev_ops = {
+	.name = "i40iw",
+	.init_device = i40iw_driver_init,
+	.uninit_device  = i40iw_uninit_device,
+	.alloc_context = i40iw_ualloc_context,
+	.free_context = i40iw_ufree_context,
+};
+PROVIDER_DRIVER(i40iw_udev_ops);
diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
index 96bc4d7f281a1f..ebdf5b828e1784 100644
--- a/providers/ipathverbs/ipathverbs.c
+++ b/providers/ipathverbs/ipathverbs.c
@@ -179,12 +179,6 @@ static void ipath_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops ipath_dev_ops = {
-	.alloc_context	= ipath_alloc_context,
-	.free_context	= ipath_free_context,
-	.uninit_device  = ipath_uninit_device
-};
-
 static struct verbs_device *ipath_driver_init(const char *uverbs_sys_path,
 					      int abi_version)
 {
@@ -218,13 +212,16 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &ipath_dev_ops;
 	dev->abi_version = abi_version;
 
 	return &dev->ibv_dev;
 }
 
-static __attribute__((constructor)) void ipath_register_driver(void)
-{
-	verbs_register_driver("ipathverbs", ipath_driver_init);
-}
+static const struct verbs_device_ops ipath_dev_ops = {
+	.name = "ipathverbs",
+	.init_device = ipath_driver_init,
+	.uninit_device  = ipath_uninit_device,
+	.alloc_context = ipath_alloc_context,
+	.free_context = ipath_free_context,
+};
+PROVIDER_DRIVER(ipath_dev_ops);
diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
index 3571234b27578d..0eefa40af16d83 100644
--- a/providers/mlx4/mlx4.c
+++ b/providers/mlx4/mlx4.c
@@ -286,12 +286,6 @@ static void mlx4_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops mlx4_dev_ops = {
-	.init_context = mlx4_init_context,
-	.uninit_context = mlx4_uninit_context,
-	.uninit_device = mlx4_uninit_device
-};
-
 static struct verbs_device *mlx4_driver_init(const char *uverbs_sys_path, int abi_version)
 {
 	char			value[8];
@@ -337,7 +331,6 @@ found:
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 	dev->abi_version = abi_version;
 
-	dev->verbs_dev.ops = &mlx4_dev_ops;
 	dev->verbs_dev.sz = sizeof(*dev);
 	dev->verbs_dev.size_of_context =
 		sizeof(struct mlx4_context) - sizeof(struct ibv_context);
@@ -345,10 +338,14 @@ found:
 	return &dev->verbs_dev;
 }
 
-static __attribute__((constructor)) void mlx4_register_driver(void)
-{
-	verbs_register_driver("mlx4", mlx4_driver_init);
-}
+static const struct verbs_device_ops mlx4_dev_ops = {
+	.name = "mlx4",
+	.init_device = mlx4_driver_init,
+	.uninit_device = mlx4_uninit_device,
+	.init_context = mlx4_init_context,
+	.uninit_context = mlx4_uninit_context,
+};
+PROVIDER_DRIVER(mlx4_dev_ops);
 
 static int mlx4dv_get_qp(struct ibv_qp *qp_in,
 			 struct mlx4dv_qp *qp_out)
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index e7adf1483ccfcd..68cca7cde97ef2 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -1026,12 +1026,6 @@ static void mlx5_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops mlx5_dev_ops = {
-	.init_context = mlx5_init_context,
-	.uninit_context = mlx5_cleanup_context,
-	.uninit_device = mlx5_uninit_device
-};
-
 static struct verbs_device *mlx5_driver_init(const char *uverbs_sys_path,
 					     int abi_version)
 {
@@ -1078,7 +1072,6 @@ found:
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 	dev->driver_abi_ver = abi_version;
 
-	dev->verbs_dev.ops = &mlx5_dev_ops;
 	dev->verbs_dev.sz = sizeof(*dev);
 	dev->verbs_dev.size_of_context = sizeof(struct mlx5_context) -
 		sizeof(struct ibv_context);
@@ -1086,7 +1079,11 @@ found:
 	return &dev->verbs_dev;
 }
 
-static __attribute__((constructor)) void mlx5_register_driver(void)
-{
-	verbs_register_driver("mlx5", mlx5_driver_init);
-}
+static const struct verbs_device_ops mlx5_dev_ops = {
+	.name = "mlx5",
+	.init_device = mlx5_driver_init,
+	.uninit_device = mlx5_uninit_device,
+	.init_context = mlx5_init_context,
+	.uninit_context = mlx5_cleanup_context,
+};
+PROVIDER_DRIVER(mlx5_dev_ops);
diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
index 62c912a312f04f..7194539b2d6ab1 100644
--- a/providers/mthca/mthca.c
+++ b/providers/mthca/mthca.c
@@ -216,12 +216,6 @@ static void mthca_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops mthca_dev_ops = {
-	.alloc_context = mthca_alloc_context,
-	.free_context  = mthca_free_context,
-	.uninit_device = mthca_uninit_device
-};
-
 static struct verbs_device *mthca_driver_init(const char *uverbs_sys_path,
 					    int abi_version)
 {
@@ -261,14 +255,17 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &mthca_dev_ops;
 	dev->hca_type    = hca_table[i].type;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 
 	return &dev->ibv_dev;
 }
 
-static __attribute__((constructor)) void mthca_register_driver(void)
-{
-	verbs_register_driver("mthca", mthca_driver_init);
-}
+static const struct verbs_device_ops mthca_dev_ops = {
+	.name = "mthca",
+	.init_device = mthca_driver_init,
+	.uninit_device = mthca_uninit_device,
+	.alloc_context = mthca_alloc_context,
+	.free_context = mthca_free_context,
+};
+PROVIDER_DRIVER(mthca_dev_ops);
diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
index c9ce700749555d..d02e010d2524a2 100644
--- a/providers/nes/nes_umain.c
+++ b/providers/nes/nes_umain.c
@@ -191,13 +191,6 @@ static void nes_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops nes_udev_ops = {
-	.alloc_context = nes_ualloc_context,
-	.free_context = nes_ufree_context,
-	.uninit_device = nes_uninit_device
-};
-
-
 /**
  * nes_driver_init
  */
@@ -243,7 +236,6 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &nes_udev_ops;
 	dev->hca_type = hca_table[i].type;
 	dev->page_size = sysconf(_SC_PAGESIZE);
 
@@ -252,13 +244,11 @@ found:
 	return &dev->ibv_dev;
 }
 
-
-/**
- * nes_register_driver
- */
-static __attribute__((constructor)) void nes_register_driver(void)
-{
-	/* fprintf(stderr, PFX "nes_register_driver: call ibv_register_driver()\n"); */
-
-	verbs_register_driver("nes", nes_driver_init);
-}
+static const struct verbs_device_ops nes_udev_ops = {
+	.name = "nes",
+	.init_device = nes_driver_init,
+	.uninit_device = nes_uninit_device,
+	.alloc_context = nes_ualloc_context,
+	.free_context = nes_ufree_context,
+};
+PROVIDER_DRIVER(nes_udev_ops);
diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
index 8888067761ab37..09c00d21ce2af6 100644
--- a/providers/ocrdma/ocrdma_main.c
+++ b/providers/ocrdma/ocrdma_main.c
@@ -107,12 +107,6 @@ static void ocrdma_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops ocrdma_dev_ops = {
-	.alloc_context = ocrdma_alloc_context,
-	.free_context = ocrdma_free_context,
-	.uninit_device = ocrdma_uninit_device
-};
-
 /*
  * ocrdma_alloc_context
  */
@@ -225,18 +219,17 @@ found:
 	bzero(dev->qp_tbl, OCRDMA_MAX_QP * sizeof(struct ocrdma_qp *));
 	pthread_mutex_init(&dev->dev_lock, NULL);
 	pthread_spin_init(&dev->flush_q_lock, PTHREAD_PROCESS_PRIVATE);
-	dev->ibv_dev.ops = &ocrdma_dev_ops;
 	return &dev->ibv_dev;
 qp_err:
 	free(dev);
 	return NULL;
 }
 
-/*
- * ocrdma_register_driver
- */
-static __attribute__ ((constructor))
-void ocrdma_register_driver(void)
-{
-	verbs_register_driver("ocrdma", ocrdma_driver_init);
-}
+static const struct verbs_device_ops ocrdma_dev_ops = {
+	.name = "ocrdma",
+	.init_device = ocrdma_driver_init,
+	.uninit_device = ocrdma_uninit_device,
+	.alloc_context = ocrdma_alloc_context,
+	.free_context = ocrdma_free_context,
+};
+PROVIDER_DRIVER(ocrdma_dev_ops);
diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
index 4d4390bdaf9a7c..0be4a8c82a1e05 100644
--- a/providers/qedr/qelr_main.c
+++ b/providers/qedr/qelr_main.c
@@ -115,12 +115,6 @@ static void qelr_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops qelr_dev_ops = {
-	.alloc_context = qelr_alloc_context,
-	.free_context = qelr_free_context,
-	.uninit_device = qelr_uninit_device
-};
-
 static void qelr_open_debug_file(struct qelr_devctx *ctx)
 {
 	char *env;
@@ -274,13 +268,14 @@ found:
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &qelr_dev_ops;
-
 	return &dev->ibv_dev;
 }
 
-static __attribute__ ((constructor))
-void qelr_register_driver(void)
-{
-	verbs_register_driver("qelr", qelr_driver_init);
-}
+static const struct verbs_device_ops qelr_dev_ops = {
+	.name = "qelr",
+	.init_device = qelr_driver_init,
+	.uninit_device = qelr_uninit_device,
+	.alloc_context = qelr_alloc_context,
+	.free_context = qelr_free_context,
+};
+PROVIDER_DRIVER(qelr_dev_ops);
diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c
index 21820f9fcea561..655800ec3410fd 100644
--- a/providers/rxe/rxe.c
+++ b/providers/rxe/rxe.c
@@ -893,12 +893,6 @@ static void rxe_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops rxe_dev_ops = {
-	.alloc_context = rxe_alloc_context,
-	.free_context = rxe_free_context,
-	.uninit_device = rxe_uninit_device
-};
-
 static struct verbs_device *rxe_driver_init(const char *uverbs_sys_path,
 					    int abi_version)
 {
@@ -921,14 +915,16 @@ static struct verbs_device *rxe_driver_init(const char *uverbs_sys_path,
 		return NULL;
 	}
 
-	dev->ibv_dev.ops = &rxe_dev_ops;
 	dev->abi_version = abi_version;
 
 	return &dev->ibv_dev;
 }
 
-static __attribute__ ((constructor))
-void rxe_register_driver(void)
-{
-	verbs_register_driver("rxe", rxe_driver_init);
-}
+static const struct verbs_device_ops rxe_dev_ops = {
+	.name = "rxe",
+	.init_device = rxe_driver_init,
+	.uninit_device = rxe_uninit_device,
+	.alloc_context = rxe_alloc_context,
+	.free_context = rxe_free_context,
+};
+PROVIDER_DRIVER(rxe_dev_ops);
diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
index d3886634d7ae7b..75b9296c6e24e3 100644
--- a/providers/vmw_pvrdma/pvrdma_main.c
+++ b/providers/vmw_pvrdma/pvrdma_main.c
@@ -169,12 +169,6 @@ static void pvrdma_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device_ops pvrdma_dev_ops = {
-	.alloc_context = pvrdma_alloc_context,
-	.free_context  = pvrdma_free_context,
-	.uninit_device = pvrdma_uninit_device
-};
-
 static struct pvrdma_device *pvrdma_driver_init_shared(
 						const char *uverbs_sys_path,
 						int abi_version)
@@ -215,7 +209,6 @@ static struct pvrdma_device *pvrdma_driver_init_shared(
 
 	dev->abi_version = abi_version;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
-	dev->ibv_dev.ops = &pvrdma_dev_ops;
 
 	return dev;
 }
@@ -231,7 +224,11 @@ static struct verbs_device *pvrdma_driver_init(const char *uverbs_sys_path,
 	return &dev->ibv_dev;
 }
 
-static __attribute__((constructor)) void pvrdma_register_driver(void)
-{
-	verbs_register_driver("pvrdma", pvrdma_driver_init);
-}
+static const struct verbs_device_ops pvrdma_dev_ops = {
+	.name = "pvrdma",
+	.init_device = pvrdma_driver_init,
+	.uninit_device = pvrdma_uninit_device,
+	.alloc_context = pvrdma_alloc_context,
+	.free_context  = pvrdma_free_context,
+};
+PROVIDER_DRIVER(pvrdma_dev_ops);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 02/10] cxgb4: Move sysconf up to driver_init
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-3-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step Jason Gunthorpe
                     ` (8 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Steve Wise

This follows the pattern of the rest of the providers and lets us
use the PROVIDER_DRIVER macro.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/cxgb4/dev.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
index fea9b5527072ec..492b3978995607 100644
--- a/providers/cxgb4/dev.c
+++ b/providers/cxgb4/dev.c
@@ -466,6 +466,10 @@ found:
 	PDBG("%s found vendor %d device %d type %d\n",
 	     __FUNCTION__, vendor, device, CHELSIO_CHIP_VERSION(hca_table[i].device >> 8));
 
+	c4iw_page_size = sysconf(_SC_PAGESIZE);
+	c4iw_page_shift = long_log2(c4iw_page_size);
+	c4iw_page_mask = ~(c4iw_page_size - 1);
+
 	dev = calloc(1, sizeof *dev);
 	if (!dev) {
 		return NULL;
@@ -515,14 +519,7 @@ static const struct verbs_device_ops c4iw_dev_ops = {
 	.alloc_context = c4iw_alloc_context,
 	.free_context = c4iw_free_context,
 };
-
-static __attribute__((constructor)) void cxgb4_register_driver(void)
-{
-	c4iw_page_size = sysconf(_SC_PAGESIZE);
-	c4iw_page_shift = long_log2(c4iw_page_size);
-	c4iw_page_mask = ~(c4iw_page_size - 1);
-	verbs_register_driver(&c4iw_dev_ops);
-}
+PROVIDER_DRIVER(c4iw_dev_ops);
 
 #ifdef STATS
 void __attribute__ ((destructor)) cs_fini(void);
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly Jason Gunthorpe
  2017-09-19 21:18   ` [PATCH rdma-core 02/10] cxgb4: Move sysconf up to driver_init Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-4-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops Jason Gunthorpe
                     ` (7 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Doug Ledford, Yishai Hadas

The match step determines if the provider should bind to the sysfs device,
and the allocation step creates the verbs_device and cleanly matches the
uninit_device step which frees it.

This split makes it simpler to factor out all the duplicated code in the
match step.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 libibverbs/driver.h | 21 ++++++++++++++-
 libibverbs/init.c   | 74 ++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index f9f5cfa2308c2f..397441f49a0e5a 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -40,6 +40,7 @@
 #include <infiniband/kern-abi.h>
 #include <ccan/list.h>
 #include <config.h>
+#include <stdbool.h>
 
 #ifdef __cplusplus
 #  define BEGIN_C_DECLS extern "C" {
@@ -95,10 +96,27 @@ struct verbs_qp {
 	struct verbs_xrcd       *xrcd;
 };
 
+/* A rdma device detected in sysfs */
+struct verbs_sysfs_dev {
+	struct list_node entry;
+	void *provider_data;
+	char sysfs_name[IBV_SYSFS_NAME_MAX];
+	char ibdev_name[IBV_SYSFS_NAME_MAX];
+	char sysfs_path[IBV_SYSFS_PATH_MAX];
+	char ibdev_path[IBV_SYSFS_PATH_MAX];
+	int abi_ver;
+	struct timespec time_created;
+};
+
 /* Must change the PRIVATE IBVERBS_PRIVATE_ symbol if this is changed */
 struct verbs_device_ops {
 	const char *name;
 
+	int match_min_abi_version;
+	int match_max_abi_version;
+
+	bool (*match_device)(struct verbs_sysfs_dev *sysfs_dev);
+
 	/* Old interface, do not use in new code. */
 	struct ibv_context *(*alloc_context)(struct ibv_device *device,
 					     int cmd_fd);
@@ -110,6 +128,7 @@ struct verbs_device_ops {
 	void (*uninit_context)(struct verbs_device *device,
 			       struct ibv_context *ctx);
 
+	struct verbs_device *(*alloc_device)(struct verbs_sysfs_dev *sysfs_dev);
 	struct verbs_device *(*init_device)(const char *uverbs_sys_path,
 					    int abi_version);
 	void (*uninit_device)(struct verbs_device *device);
@@ -123,7 +142,7 @@ struct verbs_device {
 	size_t	size_of_context;
 	atomic_int refcount;
 	struct list_node entry;
-	struct ibv_sysfs_dev *sysfs;
+	struct verbs_sysfs_dev *sysfs;
 };
 
 static inline struct verbs_device *
diff --git a/libibverbs/init.c b/libibverbs/init.c
index 996406e2efa258..2369a1df6e1fbd 100644
--- a/libibverbs/init.c
+++ b/libibverbs/init.c
@@ -47,22 +47,11 @@
 #include <errno.h>
 #include <assert.h>
 
-#include <ccan/list.h>
 #include <util/util.h>
 #include "ibverbs.h"
 
 int abi_ver;
 
-struct ibv_sysfs_dev {
-	struct list_node	entry;
-	char		        sysfs_name[IBV_SYSFS_NAME_MAX];
-	char		        ibdev_name[IBV_SYSFS_NAME_MAX];
-	char		        sysfs_path[IBV_SYSFS_PATH_MAX];
-	char		        ibdev_path[IBV_SYSFS_PATH_MAX];
-	int			abi_ver;
-	struct timespec		time_created;
-};
-
 struct ibv_driver_name {
 	struct list_node	entry;
 	char		       *name;
@@ -81,7 +70,7 @@ static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list)
 	char class_path[IBV_SYSFS_PATH_MAX];
 	DIR *class_dir;
 	struct dirent *dent;
-	struct ibv_sysfs_dev *sysfs_dev = NULL;
+	struct verbs_sysfs_dev *sysfs_dev = NULL;
 	char value[8];
 	int ret = 0;
 
@@ -100,7 +89,7 @@ static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list)
 			continue;
 
 		if (!sysfs_dev)
-			sysfs_dev = malloc(sizeof *sysfs_dev);
+			sysfs_dev = calloc(1, sizeof(*sysfs_dev));
 		if (!sysfs_dev) {
 			ret = ENOMEM;
 			goto out;
@@ -148,8 +137,6 @@ static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list)
 		if (ibv_read_sysfs_file(sysfs_dev->sysfs_path, "abi_version",
 					value, sizeof value) > 0)
 			sysfs_dev->abi_ver = strtol(value, NULL, 10);
-		else
-			sysfs_dev->abi_ver = 0;
 
 		list_add(tmp_sysfs_dev_list, &sysfs_dev->entry);
 		sysfs_dev      = NULL;
@@ -353,16 +340,51 @@ out:
 	closedir(conf_dir);
 }
 
+/* True if the provider matches the selected rdma sysfs device */
+static bool match_device(const struct verbs_device_ops *ops,
+			 struct verbs_sysfs_dev *sysfs_dev)
+{
+	if (!ops->match_device(sysfs_dev))
+		return false;
+
+	if (sysfs_dev->abi_ver < ops->match_min_abi_version ||
+	    sysfs_dev->abi_ver > ops->match_max_abi_version) {
+		fprintf(stderr, PFX
+			"Warning: Driver %s does not support the kernel ABI of %u (supports %u to %u) for device %s\n",
+			ops->name, sysfs_dev->abi_ver,
+			ops->match_min_abi_version,
+			ops->match_max_abi_version,
+			sysfs_dev->ibdev_path);
+		return false;
+	}
+	return true;
+}
+
 static struct verbs_device *try_driver(const struct verbs_device_ops *ops,
-				       struct ibv_sysfs_dev *sysfs_dev)
+				       struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct verbs_device *vdev;
 	struct ibv_device *dev;
 	char value[16];
 
-	vdev = ops->init_device(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
-	if (!vdev)
-		return NULL;
+	if (ops->alloc_device) {
+		if (!match_device(ops, sysfs_dev))
+			return NULL;
+
+		vdev = ops->alloc_device(sysfs_dev);
+		if (!vdev) {
+			fprintf(stderr, PFX
+				"Fatal: couldn't allocate device for %s\n",
+				sysfs_dev->ibdev_path);
+			return NULL;
+		}
+	} else {
+		vdev =
+		    ops->init_device(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
+		if (!vdev)
+			return NULL;
+	}
+
 	vdev->ops = ops;
 
 	atomic_init(&vdev->refcount, 1);
@@ -409,7 +431,7 @@ static struct verbs_device *try_driver(const struct verbs_device_ops *ops,
 	return vdev;
 }
 
-static struct verbs_device *try_drivers(struct ibv_sysfs_dev *sysfs_dev)
+static struct verbs_device *try_drivers(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct ibv_driver *driver;
 	struct verbs_device *dev;
@@ -463,8 +485,8 @@ static void check_memlock_limit(void)
 			rlim.rlim_cur);
 }
 
-static int same_sysfs_dev(struct ibv_sysfs_dev *sysfs1,
-			  struct ibv_sysfs_dev *sysfs2)
+static int same_sysfs_dev(struct verbs_sysfs_dev *sysfs1,
+			  struct verbs_sysfs_dev *sysfs2)
 {
 	if (!strcmp(sysfs1->sysfs_name, sysfs2->sysfs_name) &&
 	    ts_cmp(&sysfs1->time_created,
@@ -481,8 +503,8 @@ static void try_all_drivers(struct list_head *sysfs_list,
 			    struct list_head *device_list,
 			    unsigned int *num_devices)
 {
-	struct ibv_sysfs_dev *sysfs_dev;
-	struct ibv_sysfs_dev *tmp;
+	struct verbs_sysfs_dev *sysfs_dev;
+	struct verbs_sysfs_dev *tmp;
 	struct verbs_device *vdev;
 
 	list_for_each_safe(sysfs_list, sysfs_dev, tmp, entry) {
@@ -499,7 +521,7 @@ static void try_all_drivers(struct list_head *sysfs_list,
 int ibverbs_get_device_list(struct list_head *device_list)
 {
 	LIST_HEAD(sysfs_list);
-	struct ibv_sysfs_dev *sysfs_dev, *next_dev;
+	struct verbs_sysfs_dev *sysfs_dev, *next_dev;
 	struct verbs_device *vdev, *tmp;
 	static int drivers_loaded;
 	unsigned int num_devices = 0;
@@ -515,7 +537,7 @@ int ibverbs_get_device_list(struct list_head *device_list)
 	 * present in the sysfs_list.
 	 */
 	list_for_each_safe(device_list, vdev, tmp, entry) {
-		struct ibv_sysfs_dev *old_sysfs = NULL;
+		struct verbs_sysfs_dev *old_sysfs = NULL;
 
 		list_for_each(&sysfs_list, sysfs_dev, entry) {
 			if (same_sysfs_dev(vdev->sysfs, sysfs_dev)) {
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (2 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-5-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 05/10] verbs: Remove the init_device entry point Jason Gunthorpe
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: Devesh Sharma, Steve Wise, Mike Marciniszyn, Dennis Dalessandro,
	Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Ram Amrani,
	Ariel Elior, Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER for hf1.ko,
	open list:IPATH/QIB USERSPACE PROVIDER for ib_qib.ko,
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

This is the first step to simplify the provider binding process.

Checking of the ABI version is hoisted into the core code, as are some
of the common error messages.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/bnxt_re/main.c           | 36 ++++++++++------------
 providers/cxgb3/iwch.c             | 60 ++++++++++++++++--------------------
 providers/cxgb4/dev.c              | 60 +++++++++++++++++++-----------------
 providers/hfi1verbs/hfiverbs.c     | 31 ++++++++++---------
 providers/hns/hns_roce_u.c         | 63 +++++++++++++++++++-------------------
 providers/i40iw/i40iw_umain.c      | 39 ++++++++++++++---------
 providers/ipathverbs/ipathverbs.c  | 32 ++++++++++---------
 providers/mlx4/mlx4.c              | 42 +++++++++++--------------
 providers/mlx5/mlx5.c              | 42 ++++++++++---------------
 providers/mthca/mthca.c            | 43 +++++++++++++-------------
 providers/nes/nes_umain.c          | 48 ++++++++++++++++-------------
 providers/ocrdma/ocrdma_main.c     | 46 ++++++++++++----------------
 providers/qedr/qelr_main.c         | 35 ++++++++++-----------
 providers/rxe/rxe.c                | 28 +++++++++--------
 providers/vmw_pvrdma/pvrdma_main.c | 49 ++++++++++-------------------
 15 files changed, 317 insertions(+), 337 deletions(-)

diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
index d2c2a6847e3c71..c83baacbb9f749 100644
--- a/providers/bnxt_re/main.c
+++ b/providers/bnxt_re/main.c
@@ -174,43 +174,38 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
 	}
 }
 
-static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,
-						int abi_version)
+static bool bnxt_re_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[10];
-	struct bnxt_re_dev *dev;
 	unsigned int vendor, device;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 	vendor = strtol(value, NULL, 16);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 	device = strtol(value, NULL, 16);
 
 	for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
 		if (vendor == cna_table[i].vendor &&
 		    device == cna_table[i].device)
-			goto found;
-	return NULL;
-found:
-	if (abi_version != BNXT_RE_ABI_VERSION) {
-		fprintf(stderr, DEV "FATAL: Max supported ABI of %s is %d "
-			"check for the latest version of kernel driver and"
-			"user library\n", uverbs_sys_path, abi_version);
-		return NULL;
-	}
+			return true;
+	return false;
+}
+
+static struct verbs_device *
+bnxt_re_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct bnxt_re_dev *dev;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, DEV "Failed to allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
 	dev->vdev.sz = sizeof(*dev);
 	dev->vdev.size_of_context =
@@ -221,7 +216,10 @@ found:
 
 static const struct verbs_device_ops bnxt_re_dev_ops = {
 	.name = "bnxt_re",
-	.init_device = bnxt_re_driver_init,
+	.match_min_abi_version = BNXT_RE_ABI_VERSION,
+	.match_max_abi_version = BNXT_RE_ABI_VERSION,
+	.match_device = bnxt_re_device_match,
+	.alloc_device = bnxt_re_device_alloc,
 	.init_context = bnxt_re_init_context,
 	.uninit_context = bnxt_re_uninit_context,
 };
diff --git a/providers/cxgb3/iwch.c b/providers/cxgb3/iwch.c
index c2423a7ee2cc32..7eb283bd9a89e1 100644
--- a/providers/cxgb3/iwch.c
+++ b/providers/cxgb3/iwch.c
@@ -61,7 +61,7 @@
 	  .device = PCI_DEVICE_ID_CHELSIO_##d,		\
 	  .type = CHELSIO_##t }
 
-static struct {
+static struct hca_ent {
 	unsigned vendor;
 	unsigned device;
 	enum iwch_hca_type type;
@@ -173,30 +173,31 @@ static void iwch_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
-					      int abi_version)
+static bool iwch_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
-	struct iwch_device *dev;
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
+	char value[32], *cp;
 	unsigned vendor, device, fw_maj, fw_min;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
+		    device == hca_table[i].device) {
+			sysfs_dev->provider_data = &hca_table[i];
 			goto found;
+		}
 
-	return NULL;
+	return false;
 
 found:
 
@@ -204,15 +205,9 @@ found:
 	 * Verify that the firmware major number matches.  Major number
 	 * mismatches are fatal.  Minor number mismatches are tolerated.
 	 */
-	if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev", 
-				ibdev, sizeof ibdev) < 0)
-		return NULL;
-
-	memset(devstr, 0, sizeof devstr);
-	snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s", 
-		 ibv_get_sysfs_path(), ibdev);
-	if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
-		return NULL;
+	if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
+				sizeof(value)) < 0)
+		return false;
 
 	cp = strtok(value+1, ".");
 	sscanf(cp, "%i", &fw_maj);
@@ -224,7 +219,7 @@ found:
 			"Firmware major number is %u and libcxgb3 needs %u.\n",
 			fw_maj, FW_MAJ);	
 		fflush(stderr);
-		return NULL;
+		return false;
 	}
 
 	DBGLOG("libcxgb3");
@@ -236,25 +231,21 @@ found:
 		fflush(stderr);
 	}
 
-	if (abi_version > ABI_VERS) {
-		PDBG("libcxgb3: ABI version mismatch.  "
-			"Kernel driver ABI is %u and libcxgb3 needs <= %u.\n",
-			abi_version, ABI_VERS);	
-		fflush(stderr);
-		return NULL;
-	}
+	return true;
+}
 
-	PDBG("%s found vendor %d device %d type %d\n", 
-	     __FUNCTION__, vendor, device, hca_table[i].type);
+static struct verbs_device *iwch_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct iwch_device *dev;
+	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
+	if (!dev)
 		return NULL;
-	}
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
-	dev->hca_type = hca_table[i].type;
-	dev->abi_version = abi_version;
+	dev->hca_type = hca_ent->type;
+	dev->abi_version = sysfs_dev->abi_ver;
 
 	iwch_page_size = sysconf(_SC_PAGESIZE);
 	iwch_page_shift = long_log2(iwch_page_size);
@@ -285,7 +276,10 @@ err1:
 
 static const struct verbs_device_ops iwch_dev_ops = {
 	.name = "cxgb3",
-	.init_device = cxgb3_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = ABI_VERS,
+	.match_device = iwch_device_match,
+	.alloc_device = iwch_device_alloc,
 	.uninit_device = iwch_uninit_device,
 	.alloc_context = iwch_alloc_context,
 	.free_context = iwch_free_context,
diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
index 492b3978995607..43c5a3c97bc864 100644
--- a/providers/cxgb4/dev.c
+++ b/providers/cxgb4/dev.c
@@ -49,7 +49,7 @@
  * Macros needed to support the PCI Device ID Table ...
  */
 #define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
-	static struct { \
+	static struct hca_ent { \
 		unsigned vendor; \
 		unsigned device; \
 	} hca_table[] = {
@@ -399,47 +399,40 @@ void dump_state(void)
  */
 int c4iw_abi_version = 1;
 
-static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,
-					      int abi_version)
+static bool c4iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
-	struct c4iw_dev *dev;
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
+	char value[32], *cp;
 	unsigned vendor, device, fw_maj, fw_min;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
+		    device == hca_table[i].device) {
+			sysfs_dev->provider_data = &hca_table[i];
 			goto found;
+		}
 
-	return NULL;
+	return false;
 
 found:
-	c4iw_abi_version = abi_version;	
-
 	/*
 	 * Verify that the firmware major number matches.  Major number
 	 * mismatches are fatal.  Minor number mismatches are tolerated.
 	 */
-	if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
-				ibdev, sizeof ibdev) < 0)
-		return NULL;
-
-	memset(devstr, 0, sizeof devstr);
-	snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s",
-		 ibv_get_sysfs_path(), ibdev);
-	if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
-		return NULL;
+	if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
+				sizeof(value)) < 0)
+		return false;
 
 	cp = strtok(value+1, ".");
 	sscanf(cp, "%i", &fw_maj);
@@ -451,7 +444,7 @@ found:
 			"Firmware major number is %u and libcxgb4 needs %u.\n",
 			fw_maj, FW_MAJ);
 		fflush(stderr);
-		return NULL;
+		return false;
 	}
 
 	DBGLOG("libcxgb4");
@@ -462,22 +455,30 @@ found:
 			fw_min, FW_MIN);
 		fflush(stderr);
 	}
+	return true;
+}
 
-	PDBG("%s found vendor %d device %d type %d\n",
-	     __FUNCTION__, vendor, device, CHELSIO_CHIP_VERSION(hca_table[i].device >> 8));
+static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct c4iw_dev *dev;
+	struct hca_ent *hca_ent = sysfs_dev->provider_data;
+
+	c4iw_page_size = sysconf(_SC_PAGESIZE);
+	c4iw_page_shift = long_log2(c4iw_page_size);
+	c4iw_page_mask = ~(c4iw_page_size - 1);
 
 	c4iw_page_size = sysconf(_SC_PAGESIZE);
 	c4iw_page_shift = long_log2(c4iw_page_size);
 	c4iw_page_mask = ~(c4iw_page_size - 1);
 
 	dev = calloc(1, sizeof *dev);
-	if (!dev) {
+	if (!dev)
 		return NULL;
-	}
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
-	dev->chip_version = CHELSIO_CHIP_VERSION(hca_table[i].device >> 8);
-	dev->abi_version = abi_version;
+	c4iw_abi_version = sysfs_dev->abi_ver;
+	dev->chip_version = CHELSIO_CHIP_VERSION(hca_ent->device >> 8);
+	dev->abi_version = sysfs_dev->abi_ver;
 	list_node_init(&dev->list);
 
 	PDBG("%s device claimed\n", __FUNCTION__);
@@ -514,7 +515,10 @@ found:
 
 static const struct verbs_device_ops c4iw_dev_ops = {
 	.name = "cxgb4",
-	.init_device = cxgb4_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = c4iw_device_match,
+	.alloc_device = c4iw_device_alloc,
 	.uninit_device = c4iw_uninit_device,
 	.alloc_context = c4iw_alloc_context,
 	.free_context = c4iw_free_context,
diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
index 247831eb211804..5bb436593517e1 100644
--- a/providers/hfi1verbs/hfiverbs.c
+++ b/providers/hfi1verbs/hfiverbs.c
@@ -180,47 +180,50 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *hfi1_driver_init(const char *uverbs_sys_path,
-					     int abi_version)
+static bool hfi1_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			value[8];
-	struct hfi1_device    *dev;
 	unsigned                vendor, device;
 	int                     i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
 		    device == hca_table[i].device)
-			goto found;
+			return true;
 
-	return NULL;
+	return false;
+}
+
+static struct verbs_device *hfi1_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct hfi1_device    *dev;
 
-found:
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->abi_version = abi_version;
+	dev->abi_version = sysfs_dev->abi_ver;
 
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops hfi1_dev_ops = {
 	.name = "hfi1verbs",
-	.init_device = hfi1_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = hfi1_device_match,
+	.alloc_device = hfi1_device_alloc,
 	.uninit_device  = hf11_uninit_device,
 	.alloc_context = hfi1_alloc_context,
 	.free_context = hfi1_free_context,
diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index fe2d009ebe3737..88389721811fce 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -44,20 +44,18 @@
 #define HID_LEN			15
 #define DEV_MATCH_LEN		128
 
-static const struct {
-	char	 hid[HID_LEN];
-	void	 *data;
-	int	 version;
-} acpi_table[] = {
+struct hca_ent {
+	const char *str;
+	struct hns_roce_u_hw *data;
+	int version;
+};
+
+static const struct hca_ent acpi_table[] = {
 	 {"acpi:HISI00D1:", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
 	 {},
 };
 
-static const struct {
-	char	 compatible[DEV_MATCH_LEN];
-	void	 *data;
-	int	 version;
-} dt_table[] = {
+static const struct hca_ent dt_table[] = {
 	{"hisilicon,hns-roce-v1", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
 	{},
 };
@@ -180,52 +178,53 @@ static void hns_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *hns_roce_driver_init(const char *uverbs_sys_path,
-						 int abi_version)
+static bool hns_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	struct hns_roce_device  *dev;
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			 value[128];
 	int			 i;
-	void			 *u_hw;
-	int			 hw_version;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/modalias",
 				value, sizeof(value)) > 0)
 		for (i = 0; i < sizeof(acpi_table) / sizeof(acpi_table[0]); ++i)
-			if (!strcmp(value, acpi_table[i].hid)) {
-				u_hw = acpi_table[i].data;
-				hw_version = acpi_table[i].version;
-				goto found;
+			if (!strcmp(value, acpi_table[i].str)) {
+				sysfs_dev->provider_data =
+				    (void *)&acpi_table[i];
+				return true;
 			}
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/of_node/compatible",
 				value, sizeof(value)) > 0)
 		for (i = 0; i < sizeof(dt_table) / sizeof(dt_table[0]); ++i)
-			if (!strcmp(value, dt_table[i].compatible)) {
-				u_hw = dt_table[i].data;
-				hw_version = dt_table[i].version;
-				goto found;
+			if (!strcmp(value, dt_table[i].str)) {
+				sysfs_dev->provider_data = (void *)&dt_table[i];
+				return true;
 			}
 
-	return NULL;
+	return false;
+}
+
+static struct verbs_device *hns_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct hns_roce_device  *dev;
+	const struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
-found:
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->u_hw = (struct hns_roce_u_hw *)u_hw;
-	dev->hw_version = hw_version;
+	dev->u_hw = hca_ent->data;
+	dev->hw_version = hca_ent->version;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops hns_roce_dev_ops = {
 	.name = "hns",
-	.init_device = hns_roce_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = hns_device_match,
+	.alloc_device = hns_device_alloc,
 	.uninit_device = hns_uninit_device,
 	.alloc_context = hns_roce_alloc_context,
 	.free_context = hns_roce_free_context,
diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
index 90d37651d1f702..bcba6158e60e40 100644
--- a/providers/i40iw/i40iw_umain.c
+++ b/providers/i40iw/i40iw_umain.c
@@ -55,7 +55,7 @@
 	  .device = d,		\
 	  .type = INTEL_ ## t }
 
-static struct {
+static struct hca_ent {
 	unsigned int vendor;
 	unsigned int device;
 	enum i40iw_uhca_type type;
@@ -220,44 +220,53 @@ static void i40iw_uninit_device(struct verbs_device *verbs_device)
  * @uverbs_sys_path: sys path
  * @abi_version: not used
  */
-static struct verbs_device *i40iw_driver_init(const char *uverbs_sys_path,
-					      int abi_version)
+static bool i40iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[16];
-	struct i40iw_udevice *dev;
 	unsigned int vendor, device;
 	int i;
 
 	if ((ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", value, sizeof(value)) < 0) ||
 	    (sscanf(value, "%i", &vendor) != 1))
-		return NULL;
+		return false;
 
 	if ((ibv_read_sysfs_file(uverbs_sys_path, "device/device", value, sizeof(value)) < 0) ||
 	    (sscanf(value, "%i", &device) != 1))
-		return NULL;
+		return false;
 
 	for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i) {
 		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			goto found;
+		    device == hca_table[i].device) {
+			sysfs_dev->provider_data = &hca_table[i];
+			return true;
+		}
 	}
 
-	return NULL;
-found:
+	return false;
+}
+
+static struct verbs_device *
+i40iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct i40iw_udevice *dev;
+	struct hca_ent *hca_ent = sysfs_dev->provider_data;
+
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "%s: failed to allocate memory for device object\n", __func__);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->hca_type = hca_table[i].type;
+	dev->hca_type = hca_ent->type;
 	dev->page_size = I40IW_HW_PAGE_SIZE;
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops i40iw_udev_ops = {
 	.name = "i40iw",
-	.init_device = i40iw_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = i40iw_device_match,
+	.alloc_device = i40iw_device_alloc,
 	.uninit_device  = i40iw_uninit_device,
 	.alloc_context = i40iw_ualloc_context,
 	.free_context = i40iw_ufree_context,
diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
index ebdf5b828e1784..3c141263d8ff86 100644
--- a/providers/ipathverbs/ipathverbs.c
+++ b/providers/ipathverbs/ipathverbs.c
@@ -179,47 +179,51 @@ static void ipath_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *ipath_driver_init(const char *uverbs_sys_path,
-					      int abi_version)
+static bool ipath_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			value[8];
-	struct ipath_device    *dev;
 	unsigned                vendor, device;
 	int                     i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
 		    device == hca_table[i].device)
-			goto found;
+			return true;
 
-	return NULL;
+	return false;
+}
+
+static struct verbs_device *
+ipath_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct ipath_device    *dev;
 
-found:
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->abi_version = abi_version;
+	dev->abi_version = sysfs_dev->abi_ver;
 
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops ipath_dev_ops = {
 	.name = "ipathverbs",
-	.init_device = ipath_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = ipath_device_match,
+	.alloc_device = ipath_device_alloc,
 	.uninit_device  = ipath_uninit_device,
 	.alloc_context = ipath_alloc_context,
 	.free_context = ipath_free_context,
diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
index 0eefa40af16d83..b52684a563b495 100644
--- a/providers/mlx4/mlx4.c
+++ b/providers/mlx4/mlx4.c
@@ -286,50 +286,41 @@ static void mlx4_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *mlx4_driver_init(const char *uverbs_sys_path, int abi_version)
+static bool mlx4_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			value[8];
-	struct mlx4_device    *dev;
 	unsigned		vendor, device;
 	int			i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	vendor = strtol(value, NULL, 16);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	device = strtol(value, NULL, 16);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
 		    device == hca_table[i].device)
-			goto found;
-
-	return NULL;
-
-found:
-	if (abi_version < MLX4_UVERBS_MIN_ABI_VERSION ||
-	    abi_version > MLX4_UVERBS_MAX_ABI_VERSION) {
-		fprintf(stderr, PFX "Fatal: ABI version %d of %s is not supported "
-			"(min supported %d, max supported %d)\n",
-			abi_version, uverbs_sys_path,
-			MLX4_UVERBS_MIN_ABI_VERSION,
-			MLX4_UVERBS_MAX_ABI_VERSION);
-		return NULL;
-	}
+			return true;
+
+	return false;
+}
+
+static struct verbs_device *mlx4_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct mlx4_device *dev;
 
 	dev = calloc(1, sizeof *dev);
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
 	dev->page_size   = sysconf(_SC_PAGESIZE);
-	dev->abi_version = abi_version;
+	dev->abi_version = sysfs_dev->abi_ver;
 
 	dev->verbs_dev.sz = sizeof(*dev);
 	dev->verbs_dev.size_of_context =
@@ -340,7 +331,10 @@ found:
 
 static const struct verbs_device_ops mlx4_dev_ops = {
 	.name = "mlx4",
-	.init_device = mlx4_driver_init,
+	.match_min_abi_version = MLX4_UVERBS_MIN_ABI_VERSION,
+	.match_max_abi_version = MLX4_UVERBS_MAX_ABI_VERSION,
+	.match_device = mlx4_device_match,
+	.alloc_device = mlx4_device_alloc,
 	.uninit_device = mlx4_uninit_device,
 	.init_context = mlx4_init_context,
 	.uninit_context = mlx4_uninit_context,
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index 68cca7cde97ef2..44cfd97b73cbbb 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -1026,51 +1026,40 @@ static void mlx5_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *mlx5_driver_init(const char *uverbs_sys_path,
-					     int abi_version)
+static bool mlx5_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			value[8];
-	struct mlx5_device     *dev;
 	unsigned		vendor, device;
 	int			i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
 		    device == hca_table[i].device)
-			goto found;
-
-	return NULL;
-
-found:
-	if (abi_version < MLX5_UVERBS_MIN_ABI_VERSION ||
-	    abi_version > MLX5_UVERBS_MAX_ABI_VERSION) {
-		fprintf(stderr, PFX "Fatal: ABI version %d of %s is not supported "
-			"(min supported %d, max supported %d)\n",
-			abi_version, uverbs_sys_path,
-			MLX5_UVERBS_MIN_ABI_VERSION,
-			MLX5_UVERBS_MAX_ABI_VERSION);
-		return NULL;
-	}
+			return true;
+	return false;
+}
+
+static struct verbs_device *mlx5_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct mlx5_device *dev;
 
 	dev = calloc(1, sizeof *dev);
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
 	dev->page_size   = sysconf(_SC_PAGESIZE);
-	dev->driver_abi_ver = abi_version;
+	dev->driver_abi_ver = sysfs_dev->abi_ver;
 
 	dev->verbs_dev.sz = sizeof(*dev);
 	dev->verbs_dev.size_of_context = sizeof(struct mlx5_context) -
@@ -1081,7 +1070,10 @@ found:
 
 static const struct verbs_device_ops mlx5_dev_ops = {
 	.name = "mlx5",
-	.init_device = mlx5_driver_init,
+	.match_min_abi_version = MLX5_UVERBS_MIN_ABI_VERSION,
+	.match_max_abi_version = MLX5_UVERBS_MAX_ABI_VERSION,
+	.match_device = mlx5_device_match,
+	.alloc_device = mlx5_device_alloc,
 	.uninit_device = mlx5_uninit_device,
 	.init_context = mlx5_init_context,
 	.uninit_context = mlx5_cleanup_context,
diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
index 7194539b2d6ab1..521e5b9afe4f2b 100644
--- a/providers/mthca/mthca.c
+++ b/providers/mthca/mthca.c
@@ -77,7 +77,7 @@
 	  .device = PCI_DEVICE_ID_MELLANOX_##d,		\
 	  .type = MTHCA_##t }
 
-static struct {
+static struct hca_ent {
 	unsigned		vendor;
 	unsigned		device;
 	enum mthca_hca_type	type;
@@ -216,46 +216,44 @@ static void mthca_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *mthca_driver_init(const char *uverbs_sys_path,
-					    int abi_version)
+static bool mthca_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char			value[8];
-	struct mthca_device    *dev;
 	unsigned                vendor, device;
 	int                     i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof value) < 0)
-		return NULL;
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			goto found;
+		    device == hca_table[i].device) {
+			sysfs_dev->provider_data = &hca_table[i];
+			return true;
+		}
 
-	return NULL;
+	return false;
+}
 
-found:
-	if (abi_version > MTHCA_UVERBS_ABI_VERSION) {
-		fprintf(stderr, PFX "Fatal: ABI version %d of %s is too new (expected %d)\n",
-			abi_version, uverbs_sys_path, MTHCA_UVERBS_ABI_VERSION);
-		return NULL;
-	}
+static struct verbs_device *
+mthca_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct mthca_device    *dev;
+	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->hca_type    = hca_table[i].type;
+	dev->hca_type    = hca_ent->type;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 
 	return &dev->ibv_dev;
@@ -263,7 +261,10 @@ found:
 
 static const struct verbs_device_ops mthca_dev_ops = {
 	.name = "mthca",
-	.init_device = mthca_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = MTHCA_UVERBS_ABI_VERSION,
+	.match_device = mthca_device_match,
+	.alloc_device = mthca_device_alloc,
 	.uninit_device = mthca_uninit_device,
 	.alloc_context = mthca_alloc_context,
 	.free_context = mthca_free_context,
diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
index d02e010d2524a2..fc021a9196b6ad 100644
--- a/providers/nes/nes_umain.c
+++ b/providers/nes/nes_umain.c
@@ -60,7 +60,7 @@ long int page_size;
 	  .device = d,    \
 	  .type = NETEFFECT_##t }
 
-static struct {
+static struct hca_ent {
 	unsigned vendor;
 	unsigned device;
 	enum nes_uhca_type type;
@@ -191,37 +191,40 @@ static void nes_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-/**
- * nes_driver_init
- */
-static struct verbs_device *nes_driver_init(const char *uverbs_sys_path,
-					    int abi_version)
+static bool nes_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[16];
-	struct nes_udevice *dev;
 	unsigned vendor, device;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-			value, sizeof(value)) < 0) {
-		return NULL;
-	}
+			value, sizeof(value)) < 0)
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-			value, sizeof(value)) < 0) {
-		return NULL;
-	}
+			value, sizeof(value)) < 0)
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
 		if (vendor == hca_table[i].vendor &&
-				device == hca_table[i].device)
-			goto found;
+		    device == hca_table[i].device) {
+			sysfs_dev->provider_data = &hca_table[i];
+			return true;
+		}
 
-	return NULL;
+	return false;
+}
+
+static struct verbs_device *
+nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct nes_udevice *dev;
+	struct hca_ent *hca_ent = sysfs_dev->provider_data;
+	char value[16];
 
-found:
 	if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/debug_level",
 			value, sizeof(value)) > 0) {
 		sscanf(value, "%u", &nes_debug_level);
@@ -231,12 +234,10 @@ found:
 	}
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		nes_debug(NES_DBG_INIT, "Fatal: couldn't allocate device for libnes\n");
+	if (!dev)
 		return NULL;
-	}
 
-	dev->hca_type = hca_table[i].type;
+	dev->hca_type = hca_ent->type;
 	dev->page_size = sysconf(_SC_PAGESIZE);
 
 	nes_debug(NES_DBG_INIT, "libnes initialized\n");
@@ -246,7 +247,10 @@ found:
 
 static const struct verbs_device_ops nes_udev_ops = {
 	.name = "nes",
-	.init_device = nes_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = nes_device_match,
+	.alloc_device = nes_device_alloc,
 	.uninit_device = nes_uninit_device,
 	.alloc_context = nes_ualloc_context,
 	.free_context = nes_ufree_context,
diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
index 09c00d21ce2af6..f08a49fb73e021 100644
--- a/providers/ocrdma/ocrdma_main.c
+++ b/providers/ocrdma/ocrdma_main.c
@@ -168,50 +168,39 @@ static void ocrdma_free_context(struct ibv_context *ibctx)
 	free(ctx);
 }
 
-/**
- * ocrdma_driver_init
- */
-static struct verbs_device *ocrdma_driver_init(const char *uverbs_sys_path,
-					       int abi_version)
+static bool ocrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[16];
-	struct ocrdma_device *dev;
 	unsigned vendor, device;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof(value)) < 0) {
-		return NULL;
-	}
+				value, sizeof(value)) < 0)
+		return false;
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof(value)) < 0) {
-		return NULL;
-	}
+				value, sizeof(value)) < 0)
+		return false;
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof ucna_table / sizeof ucna_table[0]; ++i) {
 		if (vendor == ucna_table[i].vendor &&
 		    device == ucna_table[i].device)
-			goto found;
-	}
-	return NULL;
-found:
-	if (abi_version != OCRDMA_ABI_VERSION) {
-		fprintf(stderr,
-		  "Fatal: libocrdma ABI version %d of %s is not supported.\n",
-		  abi_version, uverbs_sys_path);
-		return NULL;
+			return true;
 	}
+	return false;
+}
+
+static struct verbs_device *
+ocrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct ocrdma_device *dev;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		ocrdma_err("%s() Fatal: fail allocate device for libocrdma\n",
-			   __func__);
+	if (!dev)
 		return NULL;
-	}
 
 	dev->qp_tbl = malloc(OCRDMA_MAX_QP * sizeof(struct ocrdma_qp *));
 	if (!dev->qp_tbl)
@@ -227,7 +216,10 @@ qp_err:
 
 static const struct verbs_device_ops ocrdma_dev_ops = {
 	.name = "ocrdma",
-	.init_device = ocrdma_driver_init,
+	.match_min_abi_version = OCRDMA_ABI_VERSION,
+	.match_max_abi_version = OCRDMA_ABI_VERSION,
+	.match_device = ocrdma_device_match,
+	.alloc_device = ocrdma_device_alloc,
 	.uninit_device = ocrdma_uninit_device,
 	.alloc_context = ocrdma_alloc_context,
 	.free_context = ocrdma_free_context,
diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
index 0be4a8c82a1e05..4d1b92f40a413a 100644
--- a/providers/qedr/qelr_main.c
+++ b/providers/qedr/qelr_main.c
@@ -227,53 +227,50 @@ static void qelr_free_context(struct ibv_context *ibctx)
 	free(ctx);
 }
 
-static struct verbs_device *qelr_driver_init(const char *uverbs_sys_path,
-					     int abi_version)
+static bool qedr_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[16];
-	struct qelr_device *dev;
 	unsigned int vendor, device;
 	int i;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 
 	sscanf(value, "%i", &vendor);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 
 	sscanf(value, "%i", &device);
 
 	for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i)
 		if (vendor == hca_table[i].vendor &&
 		    device == hca_table[i].device)
-			goto found;
+			return true;
 
-	return NULL;
-found:
-	if (abi_version != QELR_ABI_VERSION) {
-		fprintf(stderr,
-			"Fatal: libqedr ABI version %d of %s is not supported.\n",
-			abi_version, uverbs_sys_path);
-		return NULL;
-	}
+	return false;
+}
+
+static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct qelr_device *dev;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		qelr_err("%s() Fatal: fail allocate device for libqedr\n",
-			 __func__);
+	if (!dev)
 		return NULL;
-	}
 
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops qelr_dev_ops = {
 	.name = "qelr",
-	.init_device = qelr_driver_init,
+	.match_min_abi_version = QELR_ABI_VERSION,
+	.match_max_abi_version = QELR_ABI_VERSION,
+	.match_device = qedr_device_match,
+	.alloc_device = qedr_device_alloc,
 	.uninit_device = qelr_uninit_device,
 	.alloc_context = qelr_alloc_context,
 	.free_context = qelr_free_context,
diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c
index 655800ec3410fd..d9857aac70d745 100644
--- a/providers/rxe/rxe.c
+++ b/providers/rxe/rxe.c
@@ -893,36 +893,40 @@ static void rxe_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct verbs_device *rxe_driver_init(const char *uverbs_sys_path,
-					    int abi_version)
+static bool rxe_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	struct rxe_device *dev;
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[16];
 
 	/* make sure it is a rxe device */
 	if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 
 	if (strncmp(value, "rxe", 3))
-		return NULL;
+		return false;
+
+	return true;
+}
 
+static struct verbs_device *rxe_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct rxe_device *dev;
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr,
-			"rxe: Fatal: couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->abi_version = abi_version;
+	dev->abi_version = sysfs_dev->abi_ver;
 
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops rxe_dev_ops = {
 	.name = "rxe",
-	.init_device = rxe_driver_init,
+	.match_min_abi_version = 0,
+	.match_max_abi_version = INT_MAX,
+	.match_device = rxe_device_match,
+	.alloc_device = rxe_device_alloc,
 	.uninit_device = rxe_uninit_device,
 	.alloc_context = rxe_alloc_context,
 	.free_context = rxe_free_context,
diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
index 75b9296c6e24e3..9bcf2ddd172afb 100644
--- a/providers/vmw_pvrdma/pvrdma_main.c
+++ b/providers/vmw_pvrdma/pvrdma_main.c
@@ -169,64 +169,49 @@ static void pvrdma_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static struct pvrdma_device *pvrdma_driver_init_shared(
-						const char *uverbs_sys_path,
-						int abi_version)
+static bool pvrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	struct pvrdma_device *dev;
+	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[8];
 	unsigned int vendor_id, device_id;
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 	vendor_id = strtol(value, NULL, 16);
 
 	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
 				value, sizeof(value)) < 0)
-		return NULL;
+		return false;
 	device_id = strtol(value, NULL, 16);
 
 	if (vendor_id != PCI_VENDOR_ID_VMWARE ||
 	    device_id != PCI_DEVICE_ID_VMWARE_PVRDMA)
-		return NULL;
+		return false;
+	return true;
+}
 
-	/* We support only a single ABI version for now. */
-	if (abi_version != PVRDMA_UVERBS_ABI_VERSION) {
-		fprintf(stderr, PFX "ABI version %d of %s is not "
-			"supported (supported %d)\n",
-			abi_version, uverbs_sys_path,
-			PVRDMA_UVERBS_ABI_VERSION);
-		return NULL;
-	}
+static struct verbs_device *
+pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+{
+	struct pvrdma_device *dev;
 
 	dev = calloc(1, sizeof(*dev));
-	if (!dev) {
-		fprintf(stderr, PFX "couldn't allocate device for %s\n",
-			uverbs_sys_path);
+	if (!dev)
 		return NULL;
-	}
 
-	dev->abi_version = abi_version;
+	dev->abi_version = sysfs_dev->abi_ver;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 
-	return dev;
-}
-
-static struct verbs_device *pvrdma_driver_init(const char *uverbs_sys_path,
-					       int abi_version)
-{
-	struct pvrdma_device *dev = pvrdma_driver_init_shared(uverbs_sys_path,
-							      abi_version);
-	if (!dev)
-		return NULL;
-
 	return &dev->ibv_dev;
 }
 
 static const struct verbs_device_ops pvrdma_dev_ops = {
 	.name = "pvrdma",
-	.init_device = pvrdma_driver_init,
+	.match_min_abi_version = PVRDMA_UVERBS_ABI_VERSION,
+	.match_max_abi_version = PVRDMA_UVERBS_ABI_VERSION,
+	.match_device = pvrdma_device_match,
+	.alloc_device = pvrdma_device_alloc,
 	.uninit_device = pvrdma_uninit_device,
 	.alloc_context = pvrdma_alloc_context,
 	.free_context  = pvrdma_free_context,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 05/10] verbs: Remove the init_device entry point
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (3 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
  2017-09-19 21:18   ` [PATCH rdma-core 06/10] verbs: Provide common code to match providers against kernel devices Jason Gunthorpe
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Doug Ledford, Yishai Hadas

All providers are converted now.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 libibverbs/driver.h |  2 --
 libibverbs/init.c   | 22 +++++++---------------
 2 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index 397441f49a0e5a..168728cfa1a524 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -129,8 +129,6 @@ struct verbs_device_ops {
 			       struct ibv_context *ctx);
 
 	struct verbs_device *(*alloc_device)(struct verbs_sysfs_dev *sysfs_dev);
-	struct verbs_device *(*init_device)(const char *uverbs_sys_path,
-					    int abi_version);
 	void (*uninit_device)(struct verbs_device *device);
 };
 
diff --git a/libibverbs/init.c b/libibverbs/init.c
index 2369a1df6e1fbd..d75d70b195a6f6 100644
--- a/libibverbs/init.c
+++ b/libibverbs/init.c
@@ -367,22 +367,14 @@ static struct verbs_device *try_driver(const struct verbs_device_ops *ops,
 	struct ibv_device *dev;
 	char value[16];
 
-	if (ops->alloc_device) {
-		if (!match_device(ops, sysfs_dev))
-			return NULL;
+	if (!match_device(ops, sysfs_dev))
+		return NULL;
 
-		vdev = ops->alloc_device(sysfs_dev);
-		if (!vdev) {
-			fprintf(stderr, PFX
-				"Fatal: couldn't allocate device for %s\n",
-				sysfs_dev->ibdev_path);
-			return NULL;
-		}
-	} else {
-		vdev =
-		    ops->init_device(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
-		if (!vdev)
-			return NULL;
+	vdev = ops->alloc_device(sysfs_dev);
+	if (!vdev) {
+		fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
+			sysfs_dev->ibdev_path);
+		return NULL;
 	}
 
 	vdev->ops = ops;
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 06/10] verbs: Provide common code to match providers against kernel devices
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (4 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 05/10] verbs: Remove the init_device entry point Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
  2017-09-19 21:18   ` [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure Jason Gunthorpe
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Doug Ledford, Yishai Hadas

Checking the PCI device against a table is basically duplicated in every
driver. Follow the pattern from the kernel and attach a matching table to
the verbs_device_ops driver entry point that describes all the kernel
devices the provider can handle and have the core code match against that
table.

The driver gets a pointer to the table entry that matches in the allocation
function.

This implementation is based around modalias instead of reading the PCI
specific vendor & device files. modalias lets us support the ACPI and OF
provider and provides a straightforward path to make the providers demand
load based on their supported modalias strings, like the kernel.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 libibverbs/driver.h | 43 +++++++++++++++++++++++++++
 libibverbs/init.c   | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 125 insertions(+), 2 deletions(-)

diff --git a/libibverbs/driver.h b/libibverbs/driver.h
index 168728cfa1a524..a3cdbe1e60cbad 100644
--- a/libibverbs/driver.h
+++ b/libibverbs/driver.h
@@ -96,14 +96,56 @@ struct verbs_qp {
 	struct verbs_xrcd       *xrcd;
 };
 
+enum {
+	VERBS_MATCH_SENTINEL = 0,
+	VERBS_MATCH_PCI = 1,
+	VERBS_MATCH_MODALIAS = 2,
+};
+
+struct verbs_match_ent {
+	void *driver_data;
+	const char *modalias;
+	uint16_t vendor;
+	uint16_t device;
+	uint8_t kind;
+};
+#define VERBS_PCI_MATCH(_vendor, _device, _data)                               \
+	{                                                                      \
+	    .driver_data = (_data),                                            \
+	    .vendor = (_vendor),                                               \
+	    .device = (_device),                                               \
+	    .kind = VERBS_MATCH_PCI,                                           \
+	}
+
+#define VERBS_MODALIAS_MATCH(_mod_str, _data)                                  \
+	{                                                                      \
+	    .driver_data = (_data),                                            \
+	    .modalias = (_mod_str),                                            \
+	    .kind = VERBS_MATCH_MODALIAS,                                      \
+	}
+
+/* Matching on the IB device name is STRONGLY discouraged. This will only
+ * match if there is no device/modalias file available, and it will eventually
+ * be disabled entirely if the kernel supports renaming. Use is strongly
+ * discouraged.
+ */
+#define VERBS_NAME_MATCH(_name_prefix, _data)                                  \
+	{                                                                      \
+	    .driver_data = (_data),                                            \
+	    .modalias = "rdma_device:*N" _name_prefix "*",                     \
+	    .kind = VERBS_MATCH_MODALIAS,                                      \
+	}
+
 /* A rdma device detected in sysfs */
 struct verbs_sysfs_dev {
 	struct list_node entry;
 	void *provider_data;
+	const struct verbs_match_ent *match;
 	char sysfs_name[IBV_SYSFS_NAME_MAX];
 	char ibdev_name[IBV_SYSFS_NAME_MAX];
 	char sysfs_path[IBV_SYSFS_PATH_MAX];
 	char ibdev_path[IBV_SYSFS_PATH_MAX];
+	char modalias[512];
 	int abi_ver;
 	struct timespec time_created;
 };
@@ -114,6 +156,7 @@ struct verbs_device_ops {
 
 	int match_min_abi_version;
 	int match_max_abi_version;
+	const struct verbs_match_ent *match_table;
 
 	bool (*match_device)(struct verbs_sysfs_dev *sysfs_dev);
 
diff --git a/libibverbs/init.c b/libibverbs/init.c
index d75d70b195a6f6..ff2c60ffcbc963 100644
--- a/libibverbs/init.c
+++ b/libibverbs/init.c
@@ -46,6 +46,7 @@
 #include <dirent.h>
 #include <errno.h>
 #include <assert.h>
+#include <fnmatch.h>
 
 #include <util/util.h>
 #include "ibverbs.h"
@@ -138,6 +139,11 @@ static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list)
 					value, sizeof value) > 0)
 			sysfs_dev->abi_ver = strtol(value, NULL, 10);
 
+		if (ibv_read_sysfs_file(sysfs_dev->sysfs_path,
+					"device/modalias", sysfs_dev->modalias,
+					sizeof(sysfs_dev->modalias)) <= 0)
+			sysfs_dev->modalias[0] = 0;
+
 		list_add(tmp_sysfs_dev_list, &sysfs_dev->entry);
 		sysfs_dev      = NULL;
 	}
@@ -340,12 +346,86 @@ out:
 	closedir(conf_dir);
 }
 
+/* Match a single modalias value */
+static bool match_modalias(const struct verbs_match_ent *ent, const char *value)
+{
+	char pci_ma[100];
+
+	switch (ent->kind) {
+	case VERBS_MATCH_MODALIAS:
+		return fnmatch(ent->modalias, value, 0) == 0;
+	case VERBS_MATCH_PCI:
+		snprintf(pci_ma, sizeof(pci_ma), "pci:v%08Xd%08Xsv*",
+			 ent->vendor, ent->device);
+		return fnmatch(pci_ma, value, 0) == 0;
+	default:
+		return false;
+	}
+}
+
+/* Search a null terminated table of verbs_match_ent's and return the one
+ * that matches the device the verbs sysfs device is bound to or NULL.
+ */
+static const struct verbs_match_ent *
+match_modalias_device(const struct verbs_device_ops *ops,
+		      struct verbs_sysfs_dev *sysfs_dev)
+{
+	const struct verbs_match_ent *i;
+
+	for (i = ops->match_table; i->kind != VERBS_MATCH_SENTINEL; i++)
+		if (match_modalias(i, sysfs_dev->modalias))
+			return i;
+
+	return NULL;
+}
+
+/* Match the device name itself */
+static const struct verbs_match_ent *
+match_name(const struct verbs_device_ops *ops,
+		      struct verbs_sysfs_dev *sysfs_dev)
+{
+	char name_ma[100];
+	const struct verbs_match_ent *i;
+
+	if (!check_snprintf(name_ma, sizeof(name_ma),
+			    "rdma_device:N%s", sysfs_dev->ibdev_name))
+		return NULL;
+
+	for (i = ops->match_table; i->kind != VERBS_MATCH_SENTINEL; i++)
+		if (match_modalias(i, name_ma))
+			return i;
+
+	return NULL;
+}
+
 /* True if the provider matches the selected rdma sysfs device */
 static bool match_device(const struct verbs_device_ops *ops,
 			 struct verbs_sysfs_dev *sysfs_dev)
 {
-	if (!ops->match_device(sysfs_dev))
-		return false;
+	if (ops->match_table) {
+		/* The internally generated alias is checked first, since some
+		 * devices like rxe can attach to a random modalias, including
+		 * ones that match other providers.
+		 */
+		sysfs_dev->match = match_name(ops, sysfs_dev);
+		if (!sysfs_dev->match)
+			sysfs_dev->match =
+			    match_modalias_device(ops, sysfs_dev);
+	}
+
+	if (ops->match_device) {
+		/* If a matching function is provided then it is called
+		 * unconditionally after the table match above, it is
+		 * responsible for determining if the device matches based on
+		 * the match pointer and any other internal information.
+		 */
+		if (!ops->match_device(sysfs_dev))
+			return false;
+	} else {
+		/* With no match function, we must have a table match */
+		if (!sysfs_dev->match)
+			return false;
+	}
 
 	if (sysfs_dev->abi_ver < ops->match_min_abi_version ||
 	    sysfs_dev->abi_ver > ops->match_max_abi_version) {
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (5 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 06/10] verbs: Provide common code to match providers against kernel devices Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-8-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 08/10] cxgb: " Jason Gunthorpe
                     ` (3 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: Devesh Sharma, Mike Marciniszyn, Dennis Dalessandro,
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Ram Amrani,
	Ariel Elior, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER for hf1.ko,
	open list:IPATH/QIB USERSPACE PROVIDER for ib_qib.ko,
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

Migrate all trivial cases, these are all just copies of a few variations of
the table scan.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/bnxt_re/main.c           | 40 ++++---------------------------
 providers/hfi1verbs/hfiverbs.c     | 39 ++++--------------------------
 providers/i40iw/i40iw_umain.c      | 49 ++++----------------------------------
 providers/ipathverbs/ipathverbs.c  | 39 ++++--------------------------
 providers/mlx4/mlx4.c              | 38 ++++-------------------------
 providers/mlx5/mlx5.c              | 38 ++++-------------------------
 providers/mthca/mthca.c            | 47 ++++++------------------------------
 providers/nes/nes_umain.c          | 46 +++++------------------------------
 providers/ocrdma/ocrdma_main.c     | 43 +++++++--------------------------
 providers/qedr/qelr_main.c         | 41 ++++---------------------------
 providers/vmw_pvrdma/pvrdma_main.c | 30 ++++++-----------------
 11 files changed, 61 insertions(+), 389 deletions(-)

diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
index c83baacbb9f749..998c9fe3313389 100644
--- a/providers/bnxt_re/main.c
+++ b/providers/bnxt_re/main.c
@@ -52,15 +52,8 @@
 
 #define PCI_VENDOR_ID_BROADCOM		0x14E4
 
-#define CNA(v, d)					\
-	{	.vendor = PCI_VENDOR_ID_##v,		\
-		.device = d }
-
-static const struct {
-	unsigned int vendor;
-	unsigned int device;
-} cna_table[] = {
-	CNA(BROADCOM, 0x1614),  /* BCM57454 */
+#define CNA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
+static const struct verbs_match_ent cna_table[] = {
 	CNA(BROADCOM, 0x16C0),  /* BCM57417 NPAR */
 	CNA(BROADCOM, 0x16CE),  /* BMC57311 */
 	CNA(BROADCOM, 0x16CF),  /* BMC57312 */
@@ -78,7 +71,8 @@ static const struct {
 	CNA(BROADCOM, 0x16EB),  /* BCM57412 NPAR */
 	CNA(BROADCOM, 0x16F0),  /* BCM58730 */
 	CNA(BROADCOM, 0x16F1),  /* BCM57452 */
-	CNA(BROADCOM, 0xD802)   /* BCM58802 */
+	CNA(BROADCOM, 0xD802),  /* BCM58802 */
+	{}
 };
 
 static struct ibv_context_ops bnxt_re_cntx_ops = {
@@ -174,30 +168,6 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
 	}
 }
 
-static bool bnxt_re_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[10];
-	unsigned int vendor, device;
-	int i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof(value)) < 0)
-		return false;
-	vendor = strtol(value, NULL, 16);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof(value)) < 0)
-		return false;
-	device = strtol(value, NULL, 16);
-
-	for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
-		if (vendor == cna_table[i].vendor &&
-		    device == cna_table[i].device)
-			return true;
-	return false;
-}
-
 static struct verbs_device *
 bnxt_re_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
@@ -218,7 +188,7 @@ static const struct verbs_device_ops bnxt_re_dev_ops = {
 	.name = "bnxt_re",
 	.match_min_abi_version = BNXT_RE_ABI_VERSION,
 	.match_max_abi_version = BNXT_RE_ABI_VERSION,
-	.match_device = bnxt_re_device_match,
+	.match_table = cna_table,
 	.alloc_device = bnxt_re_device_alloc,
 	.init_context = bnxt_re_init_context,
 	.uninit_context = bnxt_re_uninit_context,
diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
index 5bb436593517e1..7f8f5714db1630 100644
--- a/providers/hfi1verbs/hfiverbs.c
+++ b/providers/hfi1verbs/hfiverbs.c
@@ -77,16 +77,12 @@
 #define PCI_DEVICE_ID_HFI_INTEL1		0x24f1
 #endif
 
-#define HFI(v, d) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = PCI_DEVICE_ID_HFI_##d }
-
-static struct {
-	unsigned		vendor;
-	unsigned		device;
-} hca_table[] = {
+#define HFI(v, d)                                                              \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_HFI_##d, NULL)
+static const struct verbs_match_ent hca_table[] = {
 	HFI(INTEL, INTEL0),
 	HFI(INTEL, INTEL1),
+	{}
 };
 
 static struct ibv_context_ops hfi1_ctx_ops = {
@@ -180,31 +176,6 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool hfi1_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			value[8];
-	unsigned                vendor, device;
-	int                     i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			return true;
-
-	return false;
-}
-
 static struct verbs_device *hfi1_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct hfi1_device    *dev;
@@ -222,7 +193,7 @@ static const struct verbs_device_ops hfi1_dev_ops = {
 	.name = "hfi1verbs",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = hfi1_device_match,
+	.match_table = hca_table,
 	.alloc_device = hfi1_device_alloc,
 	.uninit_device  = hf11_uninit_device,
 	.alloc_context = hfi1_alloc_context,
diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
index bcba6158e60e40..61c2a92dd6734c 100644
--- a/providers/i40iw/i40iw_umain.c
+++ b/providers/i40iw/i40iw_umain.c
@@ -50,16 +50,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
-#define INTEL_HCA(v, d, t)		\
-	{ .vendor = v,		\
-	  .device = d,		\
-	  .type = INTEL_ ## t }
-
-static struct hca_ent {
-	unsigned int vendor;
-	unsigned int device;
-	enum i40iw_uhca_type type;
-} hca_table[] = {
+#define INTEL_HCA(v, d, t) VERBS_PCI_MATCH(v, d, (void *)(INTEL_##t))
+static const struct verbs_match_ent hca_table[] = {
 #ifdef I40E_DEV_ID_X722_A0
 	INTEL_HCA(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_A0, i40iw),
 #endif
@@ -96,6 +88,7 @@ static struct hca_ent {
 #ifdef I40E_DEV_ID_X722_FPGA_VF
 	INTEL_HCA(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_FPGA_VF, i40iw),
 #endif
+	{}
 };
 
 static struct ibv_context *i40iw_ualloc_context(struct ibv_device *, int);
@@ -215,48 +208,16 @@ static void i40iw_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-/**
- * i40iw_driver_init - create device struct and provide callback routines for user context
- * @uverbs_sys_path: sys path
- * @abi_version: not used
- */
-static bool i40iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[16];
-	unsigned int vendor, device;
-	int i;
-
-	if ((ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", value, sizeof(value)) < 0) ||
-	    (sscanf(value, "%i", &vendor) != 1))
-		return false;
-
-	if ((ibv_read_sysfs_file(uverbs_sys_path, "device/device", value, sizeof(value)) < 0) ||
-	    (sscanf(value, "%i", &device) != 1))
-		return false;
-
-	for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i) {
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device) {
-			sysfs_dev->provider_data = &hca_table[i];
-			return true;
-		}
-	}
-
-	return false;
-}
-
 static struct verbs_device *
 i40iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct i40iw_udevice *dev;
-	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
 	if (!dev)
 		return NULL;
 
-	dev->hca_type = hca_ent->type;
+	dev->hca_type = (uintptr_t)sysfs_dev->match->driver_data;
 	dev->page_size = I40IW_HW_PAGE_SIZE;
 	return &dev->ibv_dev;
 }
@@ -265,7 +226,7 @@ static const struct verbs_device_ops i40iw_udev_ops = {
 	.name = "i40iw",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = i40iw_device_match,
+	.match_table = hca_table,
 	.alloc_device = i40iw_device_alloc,
 	.uninit_device  = i40iw_uninit_device,
 	.alloc_context = i40iw_ualloc_context,
diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
index 3c141263d8ff86..449abb0489955a 100644
--- a/providers/ipathverbs/ipathverbs.c
+++ b/providers/ipathverbs/ipathverbs.c
@@ -73,19 +73,15 @@
 #define PCI_DEVICE_ID_INFINIPATH_7322		0x7322
 #endif
 
-#define HCA(v, d) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = PCI_DEVICE_ID_INFINIPATH_##d }
-
-static struct {
-	unsigned		vendor;
-	unsigned		device;
-} hca_table[] = {
+#define HCA(v, d)                                                              \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_INFINIPATH_##d, NULL)
+static const struct verbs_match_ent hca_table[] = {
 	HCA(PATHSCALE,	HT),
 	HCA(PATHSCALE,	PE800),
 	HCA(QLOGIC,	6220),
 	HCA(QLOGIC,	7220),
 	HCA(QLOGIC,	7322),
+	{}
 };
 
 static struct ibv_context_ops ipath_ctx_ops = {
@@ -179,31 +175,6 @@ static void ipath_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool ipath_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			value[8];
-	unsigned                vendor, device;
-	int                     i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			return true;
-
-	return false;
-}
-
 static struct verbs_device *
 ipath_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
@@ -222,7 +193,7 @@ static const struct verbs_device_ops ipath_dev_ops = {
 	.name = "ipathverbs",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = ipath_device_match,
+	.match_table = hca_table,
 	.alloc_device = ipath_device_alloc,
 	.uninit_device  = ipath_uninit_device,
 	.alloc_context = ipath_alloc_context,
diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
index b52684a563b495..6de0bee559e79f 100644
--- a/providers/mlx4/mlx4.c
+++ b/providers/mlx4/mlx4.c
@@ -49,14 +49,8 @@ int mlx4_cleanup_upon_device_fatal = 0;
 #define PCI_VENDOR_ID_MELLANOX			0x15b3
 #endif
 
-#define HCA(v, d) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = d }
-
-static struct {
-	unsigned		vendor;
-	unsigned		device;
-} hca_table[] = {
+#define HCA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
+static const struct verbs_match_ent hca_table[] = {
 	HCA(MELLANOX, 0x6340),	/* MT25408 "Hermon" SDR */
 	HCA(MELLANOX, 0x634a),	/* MT25408 "Hermon" DDR */
 	HCA(MELLANOX, 0x6354),	/* MT25408 "Hermon" QDR */
@@ -84,6 +78,7 @@ static struct {
 	HCA(MELLANOX, 0x100e),	/* MT27551 Family */
 	HCA(MELLANOX, 0x100f),	/* MT27560 Family */
 	HCA(MELLANOX, 0x1010),	/* MT27561 Family */
+	{}
 };
 
 static struct ibv_context_ops mlx4_ctx_ops = {
@@ -286,31 +281,6 @@ static void mlx4_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool mlx4_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			value[8];
-	unsigned		vendor, device;
-	int			i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	vendor = strtol(value, NULL, 16);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	device = strtol(value, NULL, 16);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			return true;
-
-	return false;
-}
-
 static struct verbs_device *mlx4_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct mlx4_device *dev;
@@ -333,7 +303,7 @@ static const struct verbs_device_ops mlx4_dev_ops = {
 	.name = "mlx4",
 	.match_min_abi_version = MLX4_UVERBS_MIN_ABI_VERSION,
 	.match_max_abi_version = MLX4_UVERBS_MAX_ABI_VERSION,
-	.match_device = mlx4_device_match,
+	.match_table = hca_table,
 	.alloc_device = mlx4_device_alloc,
 	.uninit_device = mlx4_uninit_device,
 	.init_context = mlx4_init_context,
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index 44cfd97b73cbbb..15f258dfca7387 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -59,15 +59,8 @@
 #define CPU_EQUAL(x, y) 1
 #endif
 
-
-#define HCA(v, d) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = d }
-
-static struct {
-	unsigned		vendor;
-	unsigned		device;
-} hca_table[] = {
+#define HCA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
+static const struct verbs_match_ent hca_table[] = {
 	HCA(MELLANOX, 0x1011),	/* MT4113 Connect-IB */
 	HCA(MELLANOX, 0x1012),	/* Connect-IB Virtual Function */
 	HCA(MELLANOX, 0x1013),	/* ConnectX-4 */
@@ -82,6 +75,7 @@ static struct {
 	HCA(MELLANOX, 0x101c),	/* ConnectX-6 VF */
 	HCA(MELLANOX, 0xa2d2),	/* BlueField integrated ConnectX-5 network controller */
 	HCA(MELLANOX, 0xa2d3),	/* BlueField integrated ConnectX-5 network controller VF */
+	{}
 };
 
 uint32_t mlx5_debug_mask = 0;
@@ -1026,30 +1020,6 @@ static void mlx5_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool mlx5_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			value[8];
-	unsigned		vendor, device;
-	int			i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			return true;
-	return false;
-}
-
 static struct verbs_device *mlx5_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct mlx5_device *dev;
@@ -1072,7 +1042,7 @@ static const struct verbs_device_ops mlx5_dev_ops = {
 	.name = "mlx5",
 	.match_min_abi_version = MLX5_UVERBS_MIN_ABI_VERSION,
 	.match_max_abi_version = MLX5_UVERBS_MAX_ABI_VERSION,
-	.match_device = mlx5_device_match,
+	.match_table = hca_table,
 	.alloc_device = mlx5_device_alloc,
 	.uninit_device = mlx5_uninit_device,
 	.init_context = mlx5_init_context,
diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
index 521e5b9afe4f2b..511b8d5139af9c 100644
--- a/providers/mthca/mthca.c
+++ b/providers/mthca/mthca.c
@@ -72,16 +72,10 @@
 #define PCI_VENDOR_ID_TOPSPIN			0x1867
 #endif
 
-#define HCA(v, d, t) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = PCI_DEVICE_ID_MELLANOX_##d,		\
-	  .type = MTHCA_##t }
-
-static struct hca_ent {
-	unsigned		vendor;
-	unsigned		device;
-	enum mthca_hca_type	type;
-} hca_table[] = {
+#define HCA(v, d, t)                                                           \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_MELLANOX_##d,         \
+			(void *)(MTHCA_##t))
+static const struct verbs_match_ent hca_table[] = {
 	HCA(MELLANOX, TAVOR,	    TAVOR),
 	HCA(MELLANOX, ARBEL_COMPAT, TAVOR),
 	HCA(MELLANOX, ARBEL,	    ARBEL),
@@ -92,6 +86,7 @@ static struct hca_ent {
 	HCA(TOPSPIN,  ARBEL,	    ARBEL),
 	HCA(TOPSPIN,  SINAI_OLD,    ARBEL),
 	HCA(TOPSPIN,  SINAI,	    ARBEL),
+	{}
 };
 
 static struct ibv_context_ops mthca_ctx_ops = {
@@ -216,44 +211,16 @@ static void mthca_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool mthca_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			value[8];
-	unsigned                vendor, device;
-	int                     i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device) {
-			sysfs_dev->provider_data = &hca_table[i];
-			return true;
-		}
-
-	return false;
-}
-
 static struct verbs_device *
 mthca_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct mthca_device    *dev;
-	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
 	if (!dev)
 		return NULL;
 
-	dev->hca_type    = hca_ent->type;
+	dev->hca_type    = (uintptr_t)sysfs_dev->match->driver_data;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 
 	return &dev->ibv_dev;
@@ -263,7 +230,7 @@ static const struct verbs_device_ops mthca_dev_ops = {
 	.name = "mthca",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = MTHCA_UVERBS_ABI_VERSION,
-	.match_device = mthca_device_match,
+	.match_table = hca_table,
 	.alloc_device = mthca_device_alloc,
 	.uninit_device = mthca_uninit_device,
 	.alloc_context = mthca_alloc_context,
diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
index fc021a9196b6ad..fd3d19def399b2 100644
--- a/providers/nes/nes_umain.c
+++ b/providers/nes/nes_umain.c
@@ -55,18 +55,12 @@ long int page_size;
 #define PCI_VENDOR_ID_NETEFFECT		0x1678
 #endif
 
-#define HCA(v, d, t)                            \
-	{ .vendor = PCI_VENDOR_ID_##v,              \
-	  .device = d,    \
-	  .type = NETEFFECT_##t }
-
-static struct hca_ent {
-	unsigned vendor;
-	unsigned device;
-	enum nes_uhca_type type;
-} hca_table[] = {
+#define HCA(v, d, t)                                                           \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, (void *)(NETEFFECT_##t))
+static const struct verbs_match_ent hca_table[] = {
 	HCA(NETEFFECT, 0x0100, nes),
 	HCA(NETEFFECT, 0x0110, nes),
+	{},
 };
 
 static struct ibv_context *nes_ualloc_context(struct ibv_device *, int);
@@ -191,38 +185,10 @@ static void nes_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool nes_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[16];
-	unsigned vendor, device;
-	int i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-			value, sizeof(value)) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-			value, sizeof(value)) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device) {
-			sysfs_dev->provider_data = &hca_table[i];
-			return true;
-		}
-
-	return false;
-}
-
 static struct verbs_device *
 nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct nes_udevice *dev;
-	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 	char value[16];
 
 	if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/debug_level",
@@ -237,7 +203,7 @@ nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 	if (!dev)
 		return NULL;
 
-	dev->hca_type = hca_ent->type;
+	dev->hca_type = (uintptr_t)sysfs_dev->match->driver_data;
 	dev->page_size = sysconf(_SC_PAGESIZE);
 
 	nes_debug(NES_DBG_INIT, "libnes initialized\n");
@@ -249,7 +215,7 @@ static const struct verbs_device_ops nes_udev_ops = {
 	.name = "nes",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = nes_device_match,
+	.match_table = hca_table,
 	.alloc_device = nes_device_alloc,
 	.uninit_device = nes_uninit_device,
 	.alloc_context = nes_ualloc_context,
diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
index f08a49fb73e021..92a5b8a5d1c86c 100644
--- a/providers/ocrdma/ocrdma_main.c
+++ b/providers/ocrdma/ocrdma_main.c
@@ -55,15 +55,13 @@
 #define PCI_DEVICE_ID_EMULEX_GEN2        0x720
 #define PCI_DEVICE_ID_EMULEX_GEN2_VF     0x728
 
-#define UCNA(v, d)                            \
-	{ .vendor = PCI_VENDOR_ID_##v,        \
-	  .device = PCI_DEVICE_ID_EMULEX_##d }
-
-static struct {
-	unsigned vendor;
-	unsigned device;
-} ucna_table[] = {
-	UCNA(EMULEX, GEN1), UCNA(EMULEX, GEN2), UCNA(EMULEX, GEN2_VF)
+#define UCNA(v, d)                                                             \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_EMULEX_##d, NULL)
+static const struct verbs_match_ent ucna_table[] = {
+	UCNA(EMULEX, GEN1),
+	UCNA(EMULEX, GEN2),
+	UCNA(EMULEX, GEN2_VF),
+	{}
 };
 
 static struct ibv_context *ocrdma_alloc_context(struct ibv_device *, int);
@@ -168,31 +166,6 @@ static void ocrdma_free_context(struct ibv_context *ibctx)
 	free(ctx);
 }
 
-static bool ocrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[16];
-	unsigned vendor, device;
-	int i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof(value)) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof(value)) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof ucna_table / sizeof ucna_table[0]; ++i) {
-		if (vendor == ucna_table[i].vendor &&
-		    device == ucna_table[i].device)
-			return true;
-	}
-	return false;
-}
-
 static struct verbs_device *
 ocrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
@@ -218,7 +191,7 @@ static const struct verbs_device_ops ocrdma_dev_ops = {
 	.name = "ocrdma",
 	.match_min_abi_version = OCRDMA_ABI_VERSION,
 	.match_max_abi_version = OCRDMA_ABI_VERSION,
-	.match_device = ocrdma_device_match,
+	.match_table = ucna_table,
 	.alloc_device = ocrdma_device_alloc,
 	.uninit_device = ocrdma_uninit_device,
 	.alloc_context = ocrdma_alloc_context,
diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
index 4d1b92f40a413a..1297e8e16acee5 100644
--- a/providers/qedr/qelr_main.c
+++ b/providers/qedr/qelr_main.c
@@ -64,14 +64,9 @@
 uint32_t qelr_dp_level;
 uint32_t qelr_dp_module;
 
-#define QHCA(d)					\
-	{ .vendor = PCI_VENDOR_ID_QLOGIC,	\
-	  .device = PCI_DEVICE_ID_QLOGIC_##d }
-
-static const struct {
-	unsigned int vendor;
-	unsigned int device;
-} hca_table[] = {
+#define QHCA(d)                                                                \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_##d, NULL)
+static const struct verbs_match_ent hca_table[] = {
 	QHCA(57980S),
 	QHCA(57980S_40),
 	QHCA(57980S_10),
@@ -82,6 +77,7 @@ static const struct {
 	QHCA(57980S_IOV),
 	QHCA(AH),
 	QHCA(AH_IOV),
+	{}
 };
 
 static struct ibv_context *qelr_alloc_context(struct ibv_device *, int);
@@ -227,33 +223,6 @@ static void qelr_free_context(struct ibv_context *ibctx)
 	free(ctx);
 }
 
-static bool qedr_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[16];
-	unsigned int vendor, device;
-	int i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof(value)) < 0)
-		return false;
-
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof(value)) < 0)
-		return false;
-
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device)
-			return true;
-
-	return false;
-}
-
 static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct qelr_device *dev;
@@ -269,7 +238,7 @@ static const struct verbs_device_ops qelr_dev_ops = {
 	.name = "qelr",
 	.match_min_abi_version = QELR_ABI_VERSION,
 	.match_max_abi_version = QELR_ABI_VERSION,
-	.match_device = qedr_device_match,
+	.match_table = hca_table,
 	.alloc_device = qedr_device_alloc,
 	.uninit_device = qelr_uninit_device,
 	.alloc_context = qelr_alloc_context,
diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
index 9bcf2ddd172afb..0826629c081018 100644
--- a/providers/vmw_pvrdma/pvrdma_main.c
+++ b/providers/vmw_pvrdma/pvrdma_main.c
@@ -169,28 +169,6 @@ static void pvrdma_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool pvrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[8];
-	unsigned int vendor_id, device_id;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof(value)) < 0)
-		return false;
-	vendor_id = strtol(value, NULL, 16);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof(value)) < 0)
-		return false;
-	device_id = strtol(value, NULL, 16);
-
-	if (vendor_id != PCI_VENDOR_ID_VMWARE ||
-	    device_id != PCI_DEVICE_ID_VMWARE_PVRDMA)
-		return false;
-	return true;
-}
-
 static struct verbs_device *
 pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
@@ -206,11 +184,17 @@ pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 	return &dev->ibv_dev;
 }
 
+static const struct verbs_match_ent hca_table[] = {
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_PVRDMA,
+			NULL),
+	{}
+};
+
 static const struct verbs_device_ops pvrdma_dev_ops = {
 	.name = "pvrdma",
 	.match_min_abi_version = PVRDMA_UVERBS_ABI_VERSION,
 	.match_max_abi_version = PVRDMA_UVERBS_ABI_VERSION,
-	.match_device = pvrdma_device_match,
+	.match_table = hca_table,
 	.alloc_device = pvrdma_device_alloc,
 	.uninit_device = pvrdma_uninit_device,
 	.alloc_context = pvrdma_alloc_context,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 08/10] cxgb: Use the new common PCI matching infrastructure
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (6 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-9-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 09/10] hns: Use the generic modalias matcher Jason Gunthorpe
                     ` (2 subsequent siblings)
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Steve Wise

cxgb has an additional check for firmware version that will still
be handled by the matching function, after the core code has setup
the match pointer.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/cxgb3/iwch.c | 43 +++++++++----------------------------------
 providers/cxgb4/dev.c  | 44 ++++++++++----------------------------------
 2 files changed, 19 insertions(+), 68 deletions(-)

diff --git a/providers/cxgb3/iwch.c b/providers/cxgb3/iwch.c
index 7eb283bd9a89e1..3cc1d4c185e97e 100644
--- a/providers/cxgb3/iwch.c
+++ b/providers/cxgb3/iwch.c
@@ -56,16 +56,10 @@
 #define PCI_DEVICE_ID_CHELSIO_T3C20	0x0035
 #define PCI_DEVICE_ID_CHELSIO_S320E	0x0036
 
-#define HCA(v, d, t) \
-	{ .vendor = PCI_VENDOR_ID_##v,			\
-	  .device = PCI_DEVICE_ID_CHELSIO_##d,		\
-	  .type = CHELSIO_##t }
-
-static struct hca_ent {
-	unsigned vendor;
-	unsigned device;
-	enum iwch_hca_type type;
-} hca_table[] = {
+#define HCA(v, d, t)                                                           \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_CHELSIO_##d,          \
+			(void *)(CHELSIO_##t))
+static const struct verbs_match_ent hca_table[] = {
 	HCA(CHELSIO, PE9000_2C, T3B),
 	HCA(CHELSIO, T302E, T3A),
 	HCA(CHELSIO, T302X, T3A),
@@ -175,31 +169,12 @@ static void iwch_uninit_device(struct verbs_device *verbs_device)
 
 static bool iwch_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[32], *cp;
-	unsigned vendor, device, fw_maj, fw_min;
-	int i;
+	unsigned int fw_maj, fw_min;
 
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
+	/* Rely on the core code to match PCI devices */
+	if (!sysfs_dev->match)
 		return false;
-	sscanf(value, "%i", &vendor);
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device) {
-			sysfs_dev->provider_data = &hca_table[i];
-			goto found;
-		}
-
-	return false;
-
-found:
 
 	/* 
 	 * Verify that the firmware major number matches.  Major number
@@ -237,14 +212,13 @@ found:
 static struct verbs_device *iwch_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct iwch_device *dev;
-	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
 	if (!dev)
 		return NULL;
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
-	dev->hca_type = hca_ent->type;
+	dev->hca_type = (uintptr_t)sysfs_dev->match->driver_data;
 	dev->abi_version = sysfs_dev->abi_ver;
 
 	iwch_page_size = sysconf(_SC_PAGESIZE);
@@ -278,6 +252,7 @@ static const struct verbs_device_ops iwch_dev_ops = {
 	.name = "cxgb3",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = ABI_VERS,
+	.match_table = hca_table,
 	.match_device = iwch_device_match,
 	.alloc_device = iwch_device_alloc,
 	.uninit_device = iwch_uninit_device,
diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
index 43c5a3c97bc864..c99b9e35515f89 100644
--- a/providers/cxgb4/dev.c
+++ b/providers/cxgb4/dev.c
@@ -48,23 +48,17 @@
 /*
  * Macros needed to support the PCI Device ID Table ...
  */
-#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
-	static struct hca_ent { \
-		unsigned vendor; \
-		unsigned device; \
-	} hca_table[] = {
+#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN                                    \
+	static const struct verbs_match_ent hca_table[] = {
 
 #define CH_PCI_DEVICE_ID_FUNCTION \
 		0x4
 
-#define CH_PCI_ID_TABLE_ENTRY(__DeviceID) \
-		{ \
-			.vendor = PCI_VENDOR_ID_CHELSIO, \
-			.device = (__DeviceID), \
-		}
+#define CH_PCI_ID_TABLE_ENTRY(__DeviceID)                                      \
+	VERBS_PCI_MATCH(PCI_VENDOR_ID_CHELSIO, __DeviceID, NULL)
 
 #define CH_PCI_DEVICE_ID_TABLE_DEFINE_END \
-	}
+	{} }
 
 #include "t4_chip_type.h"
 #include "t4_pci_id_tbl.h"
@@ -401,31 +395,13 @@ int c4iw_abi_version = 1;
 
 static bool c4iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
 {
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
 	char value[32], *cp;
-	unsigned vendor, device, fw_maj, fw_min;
-	int i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
-				value, sizeof value) < 0)
-		return false;
-	sscanf(value, "%i", &vendor);
+	unsigned int fw_maj, fw_min;
 
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
-				value, sizeof value) < 0)
+	/* Rely on the core code to match PCI devices */
+	if (!sysfs_dev->match)
 		return false;
-	sscanf(value, "%i", &device);
-
-	for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
-		if (vendor == hca_table[i].vendor &&
-		    device == hca_table[i].device) {
-			sysfs_dev->provider_data = &hca_table[i];
-			goto found;
-		}
-
-	return false;
 
-found:
 	/*
 	 * Verify that the firmware major number matches.  Major number
 	 * mismatches are fatal.  Minor number mismatches are tolerated.
@@ -461,7 +437,6 @@ found:
 static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct c4iw_dev *dev;
-	struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	c4iw_page_size = sysconf(_SC_PAGESIZE);
 	c4iw_page_shift = long_log2(c4iw_page_size);
@@ -477,7 +452,7 @@ static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 
 	pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
 	c4iw_abi_version = sysfs_dev->abi_ver;
-	dev->chip_version = CHELSIO_CHIP_VERSION(hca_ent->device >> 8);
+	dev->chip_version = CHELSIO_CHIP_VERSION(sysfs_dev->match->device >> 8);
 	dev->abi_version = sysfs_dev->abi_ver;
 	list_node_init(&dev->list);
 
@@ -517,6 +492,7 @@ static const struct verbs_device_ops c4iw_dev_ops = {
 	.name = "cxgb4",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
+	.match_table = hca_table,
 	.match_device = c4iw_device_match,
 	.alloc_device = c4iw_device_alloc,
 	.uninit_device = c4iw_uninit_device,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 09/10] hns: Use the generic modalias matcher
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (7 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 08/10] cxgb: " Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
       [not found]     ` <1505855931-4956-10-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:18   ` [PATCH rdma-core 10/10] rxe: Use VERBS_NAME_MATCH to match the rxe device Jason Gunthorpe
  2017-09-28 14:03   ` [PATCH rdma-core 00/10] Rework the verb init scheme Leon Romanovsky
  10 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Lijun Ou, Wei Hu(Xavier)

Use the new verbs infrastructure to match providers against modalias
files. This changes the parse of the compatible string to one
that is based on modalias instead of directly reading the compatible
string.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/hns/hns_roce_u.c       | 52 +++++++---------------------------------
 providers/hns/hns_roce_u.h       |  1 +
 providers/hns/hns_roce_u_hw_v1.c |  1 +
 3 files changed, 10 insertions(+), 44 deletions(-)

diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
index 88389721811fce..c27212ac7fb603 100644
--- a/providers/hns/hns_roce_u.c
+++ b/providers/hns/hns_roce_u.c
@@ -44,20 +44,11 @@
 #define HID_LEN			15
 #define DEV_MATCH_LEN		128
 
-struct hca_ent {
-	const char *str;
-	struct hns_roce_u_hw *data;
-	int version;
-};
-
-static const struct hca_ent acpi_table[] = {
-	 {"acpi:HISI00D1:", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
-	 {},
-};
-
-static const struct hca_ent dt_table[] = {
-	{"hisilicon,hns-roce-v1", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
-	{},
+static const struct verbs_match_ent hca_table[] = {
+	VERBS_MODALIAS_MATCH("acpi*:HISI00D1:*", &hns_roce_u_hw_v1),
+	VERBS_MODALIAS_MATCH("of:N*T*Chisilicon,hns-roce-v1C*", &hns_roce_u_hw_v1),
+	VERBS_MODALIAS_MATCH("of:N*T*Chisilicon,hns-roce-v1", &hns_roce_u_hw_v1),
+	{}
 };
 
 static struct ibv_context *hns_roce_alloc_context(struct ibv_device *ibdev,
@@ -178,43 +169,16 @@ static void hns_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool hns_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char			 value[128];
-	int			 i;
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/modalias",
-				value, sizeof(value)) > 0)
-		for (i = 0; i < sizeof(acpi_table) / sizeof(acpi_table[0]); ++i)
-			if (!strcmp(value, acpi_table[i].str)) {
-				sysfs_dev->provider_data =
-				    (void *)&acpi_table[i];
-				return true;
-			}
-
-	if (ibv_read_sysfs_file(uverbs_sys_path, "device/of_node/compatible",
-				value, sizeof(value)) > 0)
-		for (i = 0; i < sizeof(dt_table) / sizeof(dt_table[0]); ++i)
-			if (!strcmp(value, dt_table[i].str)) {
-				sysfs_dev->provider_data = (void *)&dt_table[i];
-				return true;
-			}
-
-	return false;
-}
-
 static struct verbs_device *hns_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct hns_roce_device  *dev;
-	const struct hca_ent *hca_ent = sysfs_dev->provider_data;
 
 	dev = calloc(1, sizeof(*dev));
 	if (!dev)
 		return NULL;
 
-	dev->u_hw = hca_ent->data;
-	dev->hw_version = hca_ent->version;
+	dev->u_hw = sysfs_dev->match->driver_data;
+	dev->hw_version = dev->u_hw->hw_version;
 	dev->page_size   = sysconf(_SC_PAGESIZE);
 	return &dev->ibv_dev;
 }
@@ -223,7 +187,7 @@ static const struct verbs_device_ops hns_roce_dev_ops = {
 	.name = "hns",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = hns_device_match,
+	.match_table = hca_table,
 	.alloc_device = hns_device_alloc,
 	.uninit_device = hns_uninit_device,
 	.alloc_context = hns_roce_alloc_context,
diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
index dc8956af4f8fae..d0e2351fc7fc4c 100644
--- a/providers/hns/hns_roce_u.h
+++ b/providers/hns/hns_roce_u.h
@@ -170,6 +170,7 @@ struct hns_roce_qp {
 };
 
 struct hns_roce_u_hw {
+	uint32_t hw_version;
 	int (*poll_cq)(struct ibv_cq *ibvcq, int ne, struct ibv_wc *wc);
 	int (*arm_cq)(struct ibv_cq *ibvcq, int solicited);
 	int (*post_send)(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
diff --git a/providers/hns/hns_roce_u_hw_v1.c b/providers/hns/hns_roce_u_hw_v1.c
index 0de94e1fabd3d9..482eac90df2183 100644
--- a/providers/hns/hns_roce_u_hw_v1.c
+++ b/providers/hns/hns_roce_u_hw_v1.c
@@ -829,6 +829,7 @@ out:
 }
 
 struct hns_roce_u_hw hns_roce_u_hw_v1 = {
+	.hw_version = HNS_ROCE_HW_VER1,
 	.poll_cq = hns_roce_u_v1_poll_cq,
 	.arm_cq = hns_roce_u_v1_arm_cq,
 	.post_send = hns_roce_u_v1_post_send,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH rdma-core 10/10] rxe: Use VERBS_NAME_MATCH to match the rxe device
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (8 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 09/10] hns: Use the generic modalias matcher Jason Gunthorpe
@ 2017-09-19 21:18   ` Jason Gunthorpe
  2017-09-28 14:03   ` [PATCH rdma-core 00/10] Rework the verb init scheme Leon Romanovsky
  10 siblings, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 21:18 UTC (permalink / raw)
  To: linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Moni Shoua

This is a placeholder, it obviously cannot work this way once we
add rdma device renaming.

A synthetic modalias is produced that contains the device name,
and the existing modalias framework is used to match it.

Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
---
 providers/rxe/rxe.c | 24 +++++++-----------------
 1 file changed, 7 insertions(+), 17 deletions(-)

diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c
index d9857aac70d745..683ffaa2a8af9c 100644
--- a/providers/rxe/rxe.c
+++ b/providers/rxe/rxe.c
@@ -57,6 +57,12 @@
 #include "rxe-abi.h"
 #include "rxe.h"
 
+static const struct verbs_match_ent hca_table[] = {
+	/* FIXME: rxe needs a more reliable way to detect the rxe device */
+	VERBS_NAME_MATCH("rxe", NULL),
+	{},
+};
+
 static int rxe_query_device(struct ibv_context *context,
 			    struct ibv_device_attr *attr)
 {
@@ -893,22 +899,6 @@ static void rxe_uninit_device(struct verbs_device *verbs_device)
 	free(dev);
 }
 
-static bool rxe_device_match(struct verbs_sysfs_dev *sysfs_dev)
-{
-	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
-	char value[16];
-
-	/* make sure it is a rxe device */
-	if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
-				value, sizeof(value)) < 0)
-		return false;
-
-	if (strncmp(value, "rxe", 3))
-		return false;
-
-	return true;
-}
-
 static struct verbs_device *rxe_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
 	struct rxe_device *dev;
@@ -925,7 +915,7 @@ static const struct verbs_device_ops rxe_dev_ops = {
 	.name = "rxe",
 	.match_min_abi_version = 0,
 	.match_max_abi_version = INT_MAX,
-	.match_device = rxe_device_match,
+	.match_table = hca_table,
 	.alloc_device = rxe_device_alloc,
 	.uninit_device = rxe_uninit_device,
 	.alloc_context = rxe_alloc_context,
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 02/10] cxgb4: Move sysconf up to driver_init
       [not found]     ` <1505855931-4956-3-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-19 21:23       ` Steve Wise
  0 siblings, 0 replies; 31+ messages in thread
From: Steve Wise @ 2017-09-19 21:23 UTC (permalink / raw)
  To: 'Jason Gunthorpe', linux-rdma-u79uwXL29TY76Z2rM5mHXA

> 
> This follows the pattern of the rest of the providers and lets us
> use the PROVIDER_DRIVER macro.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Acked-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 08/10] cxgb: Use the new common PCI matching infrastructure
       [not found]     ` <1505855931-4956-9-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-19 21:24       ` Steve Wise
  0 siblings, 0 replies; 31+ messages in thread
From: Steve Wise @ 2017-09-19 21:24 UTC (permalink / raw)
  To: 'Jason Gunthorpe', linux-rdma-u79uwXL29TY76Z2rM5mHXA

> cxgb has an additional check for firmware version that will still
> be handled by the matching function, after the core code has setup
> the match pointer.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Acked-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found]     ` <1505855931-4956-5-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-19 21:29       ` Steve Wise
  2017-09-19 22:32         ` Jason Gunthorpe
  2017-09-24 13:44       ` Amrani, Ram
  2017-09-25  7:41       ` Devesh Sharma
  2 siblings, 1 reply; 31+ messages in thread
From: Steve Wise @ 2017-09-19 21:29 UTC (permalink / raw)
  To: 'Jason Gunthorpe', linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: 'Devesh Sharma', 'Mike Marciniszyn',
	'Dennis Dalessandro', 'Lijun Ou',
	'Wei Hu(Xavier)', 'Tatyana Nikolova',
	'Yishai Hadas', 'Vladimir Sokolovsky',
	'Ram Amrani', 'Ariel Elior', 'Moni Shoua',
	'Adit Ranadive',
	'moderated list:HF1 USERSPACE PROVIDER (for hf1.ko)',
	'open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko)',
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA


> 
> This is the first step to simplify the provider binding process.
> 
> Checking of the ABI version is hoisted into the core code, as are some
> of the common error messages.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---

<snip>

> diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
> index 492b3978995607..43c5a3c97bc864 100644
> --- a/providers/cxgb4/dev.c
> +++ b/providers/cxgb4/dev.c


<snip>

> @@ -462,22 +455,30 @@ found:
>  			fw_min, FW_MIN);
>  		fflush(stderr);
>  	}
> +	return true;
> +}
> 
> -	PDBG("%s found vendor %d device %d type %d\n",
> -	     __FUNCTION__, vendor, device,
> CHELSIO_CHIP_VERSION(hca_table[i].device >> 8));
> +static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev
> *sysfs_dev)
> +{
> +	struct c4iw_dev *dev;
> +	struct hca_ent *hca_ent = sysfs_dev->provider_data;
> +
> +	c4iw_page_size = sysconf(_SC_PAGESIZE);
> +	c4iw_page_shift = long_log2(c4iw_page_size);
> +	c4iw_page_mask = ~(c4iw_page_size - 1);
> 
>  	c4iw_page_size = sysconf(_SC_PAGESIZE);
>  	c4iw_page_shift = long_log2(c4iw_page_size);
>  	c4iw_page_mask = ~(c4iw_page_size - 1);


The above doesn't look right.

Other than this, the cxgb bits look ok.  Did you test it? 😊

Acked-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly
       [not found]     ` <1505855931-4956-2-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-19 21:31       ` Steve Wise
  2017-09-25  6:46         ` Devesh Sharma
  0 siblings, 1 reply; 31+ messages in thread
From: Steve Wise @ 2017-09-19 21:31 UTC (permalink / raw)
  To: 'Jason Gunthorpe', linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: 'Doug Ledford', 'Yishai Hadas',
	'Devesh Sharma', 'Mike Marciniszyn',
	'Dennis Dalessandro', 'Lijun Ou',
	'Wei Hu(Xavier)', 'Tatyana Nikolova',
	'Vladimir Sokolovsky', 'Ram Amrani',
	'Ariel Elior', 'Moni Shoua',
	'Adit Ranadive',
	'moderated list:HF1 USERSPACE PROVIDER (for hf1.ko)',
	'open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko)',
	pv-drivers

> 
> This is analogous to the kernel scheme where code describes a driver
> with a static structure and then a helper macro registers that
> driver with the core code.
> 
> In this case we have an 'ops' that is both the 'driver' and 'device'
> ops.
> 
> This is preparation to add more steps to the device startup. Rework
> all the providers to use this scheme.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>

Cxgb bits looks ok.

Acked-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
  2017-09-19 21:29       ` Steve Wise
@ 2017-09-19 22:32         ` Jason Gunthorpe
  0 siblings, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-19 22:32 UTC (permalink / raw)
  To: Steve Wise
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, 'Devesh Sharma',
	'Mike Marciniszyn', 'Dennis Dalessandro',
	'Lijun Ou', 'Wei Hu(Xavier)',
	'Tatyana Nikolova', 'Yishai Hadas',
	'Vladimir Sokolovsky', 'Ram Amrani',
	'Ariel Elior', 'Moni Shoua',
	'Adit Ranadive',
	'open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko)',
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

On Tue, Sep 19, 2017 at 04:29:17PM -0500, Steve Wise wrote:
> > +	struct c4iw_dev *dev;
> > +	struct hca_ent *hca_ent = sysfs_dev->provider_data;
> > +
> > +	c4iw_page_size = sysconf(_SC_PAGESIZE);
> > +	c4iw_page_shift = long_log2(c4iw_page_size);
> > +	c4iw_page_mask = ~(c4iw_page_size - 1);
> > 
> >  	c4iw_page_size = sysconf(_SC_PAGESIZE);
> >  	c4iw_page_shift = long_log2(c4iw_page_size);
> >  	c4iw_page_mask = ~(c4iw_page_size - 1);
> 
> 
> The above doesn't look right.

Oops, that is a rebasing-caused error I missed in this big series,
thank you I will correct it.

> Other than this, the cxgb bits look ok.  Did you test it? ????

Not on cxgb, I tested other mlx4 and rxe to see that things were
working as expected. Since the matching code is now general that
covers a pretty big space..

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 09/10] hns: Use the generic modalias matcher
       [not found]     ` <1505855931-4956-10-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-20  3:28       ` oulijun
  0 siblings, 0 replies; 31+ messages in thread
From: oulijun @ 2017-09-20  3:28 UTC (permalink / raw)
  To: Jason Gunthorpe, linux-rdma-u79uwXL29TY76Z2rM5mHXA; +Cc: Wei Hu(Xavier)

在 2017/9/20 5:18, Jason Gunthorpe 写道:
> Use the new verbs infrastructure to match providers against modalias
> files. This changes the parse of the compatible string to one
> that is based on modalias instead of directly reading the compatible
> string.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>  providers/hns/hns_roce_u.c       | 52 +++++++---------------------------------
>  providers/hns/hns_roce_u.h       |  1 +
>  providers/hns/hns_roce_u_hw_v1.c |  1 +
>  3 files changed, 10 insertions(+), 44 deletions(-)
> 
> diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
> index 88389721811fce..c27212ac7fb603 100644
> --- a/providers/hns/hns_roce_u.c
> +++ b/providers/hns/hns_roce_u.c
> @@ -44,20 +44,11 @@
>  #define HID_LEN			15
>  #define DEV_MATCH_LEN		128
>  
> -struct hca_ent {
> -	const char *str;
> -	struct hns_roce_u_hw *data;
> -	int version;
> -};
> -
> -static const struct hca_ent acpi_table[] = {
> -	 {"acpi:HISI00D1:", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
> -	 {},
> -};
> -
> -static const struct hca_ent dt_table[] = {
> -	{"hisilicon,hns-roce-v1", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
> -	{},
> +static const struct verbs_match_ent hca_table[] = {
> +	VERBS_MODALIAS_MATCH("acpi*:HISI00D1:*", &hns_roce_u_hw_v1),
> +	VERBS_MODALIAS_MATCH("of:N*T*Chisilicon,hns-roce-v1C*", &hns_roce_u_hw_v1),
> +	VERBS_MODALIAS_MATCH("of:N*T*Chisilicon,hns-roce-v1", &hns_roce_u_hw_v1),
> +	{}
>  };
>  
>  static struct ibv_context *hns_roce_alloc_context(struct ibv_device *ibdev,
> @@ -178,43 +169,16 @@ static void hns_uninit_device(struct verbs_device *verbs_device)
>  	free(dev);
>  }
>  
> -static bool hns_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -	char			 value[128];
> -	int			 i;
> -
> -	if (ibv_read_sysfs_file(uverbs_sys_path, "device/modalias",
> -				value, sizeof(value)) > 0)
> -		for (i = 0; i < sizeof(acpi_table) / sizeof(acpi_table[0]); ++i)
> -			if (!strcmp(value, acpi_table[i].str)) {
> -				sysfs_dev->provider_data =
> -				    (void *)&acpi_table[i];
> -				return true;
> -			}
> -
> -	if (ibv_read_sysfs_file(uverbs_sys_path, "device/of_node/compatible",
> -				value, sizeof(value)) > 0)
> -		for (i = 0; i < sizeof(dt_table) / sizeof(dt_table[0]); ++i)
> -			if (!strcmp(value, dt_table[i].str)) {
> -				sysfs_dev->provider_data = (void *)&dt_table[i];
> -				return true;
> -			}
> -
> -	return false;
> -}
> -
>  static struct verbs_device *hns_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>  	struct hns_roce_device  *dev;
> -	const struct hca_ent *hca_ent = sysfs_dev->provider_data;
>  
>  	dev = calloc(1, sizeof(*dev));
>  	if (!dev)
>  		return NULL;
>  
> -	dev->u_hw = hca_ent->data;
> -	dev->hw_version = hca_ent->version;
> +	dev->u_hw = sysfs_dev->match->driver_data;
> +	dev->hw_version = dev->u_hw->hw_version;
>  	dev->page_size   = sysconf(_SC_PAGESIZE);
>  	return &dev->ibv_dev;
>  }
> @@ -223,7 +187,7 @@ static const struct verbs_device_ops hns_roce_dev_ops = {
>  	.name = "hns",
>  	.match_min_abi_version = 0,
>  	.match_max_abi_version = INT_MAX,
> -	.match_device = hns_device_match,
> +	.match_table = hca_table,
>  	.alloc_device = hns_device_alloc,
>  	.uninit_device = hns_uninit_device,
>  	.alloc_context = hns_roce_alloc_context,
> diff --git a/providers/hns/hns_roce_u.h b/providers/hns/hns_roce_u.h
> index dc8956af4f8fae..d0e2351fc7fc4c 100644
> --- a/providers/hns/hns_roce_u.h
> +++ b/providers/hns/hns_roce_u.h
> @@ -170,6 +170,7 @@ struct hns_roce_qp {
>  };
>  
>  struct hns_roce_u_hw {
> +	uint32_t hw_version;
>  	int (*poll_cq)(struct ibv_cq *ibvcq, int ne, struct ibv_wc *wc);
>  	int (*arm_cq)(struct ibv_cq *ibvcq, int solicited);
>  	int (*post_send)(struct ibv_qp *ibvqp, struct ibv_send_wr *wr,
> diff --git a/providers/hns/hns_roce_u_hw_v1.c b/providers/hns/hns_roce_u_hw_v1.c
> index 0de94e1fabd3d9..482eac90df2183 100644
> --- a/providers/hns/hns_roce_u_hw_v1.c
> +++ b/providers/hns/hns_roce_u_hw_v1.c
> @@ -829,6 +829,7 @@ out:
>  }
>  
>  struct hns_roce_u_hw hns_roce_u_hw_v1 = {
> +	.hw_version = HNS_ROCE_HW_VER1,
>  	.poll_cq = hns_roce_u_v1_poll_cq,
>  	.arm_cq = hns_roce_u_v1_arm_cq,
>  	.post_send = hns_roce_u_v1_post_send,
> 
Acked-by: Lijun Ou <oulijun-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure
       [not found]     ` <1505855931-4956-8-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-24 13:29       ` Amrani, Ram
       [not found]         ` <BN3PR07MB2578333789DA041401297EC0F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  2017-09-25  7:48       ` Devesh Sharma
  1 sibling, 1 reply; 31+ messages in thread
From: Amrani, Ram @ 2017-09-24 13:29 UTC (permalink / raw)
  To: Jason Gunthorpe, linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: Devesh Sharma, Mike Marciniszyn, Dennis Dalessandro,
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Elior,
	Ariel, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

For qedr:
Signed-off-by: Ram Amrani <Ram.Amrani-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>

See the following question though, not directly related to the patch:

>  static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>  	struct qelr_device *dev;
> @@ -269,7 +238,7 @@ static const struct verbs_device_ops qelr_dev_ops = {
>  	.name = "qelr",

Should this be the driver name or the library name?
The driver name is qedr and the library name is libqedr. It is usually abbreviated to qelr.
I reckon that this should be the driver name (otherwise auto-load will fail?!).

>  	.match_min_abi_version = QELR_ABI_VERSION,
>  	.match_max_abi_version = QELR_ABI_VERSION,
> -	.match_device = qedr_device_match,
> +	.match_table = hca_table,
>  	.alloc_device = qedr_device_alloc,
>  	.uninit_device = qelr_uninit_device,
>  	.alloc_context = qelr_alloc_context,

Following the above, and still not directly related to the patch, is usage of both names.
I'll fix this after your submission to qelr_...

Thanks,
Ram

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found]     ` <1505855931-4956-5-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:29       ` Steve Wise
@ 2017-09-24 13:44       ` Amrani, Ram
       [not found]         ` <BN3PR07MB257813BD7D36694EBF97BA91F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
  2017-09-25  7:41       ` Devesh Sharma
  2 siblings, 1 reply; 31+ messages in thread
From: Amrani, Ram @ 2017-09-24 13:44 UTC (permalink / raw)
  To: Jason Gunthorpe, linux-rdma-u79uwXL29TY76Z2rM5mHXA
  Cc: Devesh Sharma, Steve Wise, Mike Marciniszyn, Dennis Dalessandro,
	Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Elior,
	Ariel, Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

> diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
> index 0be4a8c82a1e05..4d1b92f40a413a 100644
> --- a/providers/qedr/qelr_main.c
> +++ b/providers/qedr/qelr_main.c
> @@ -227,53 +227,50 @@ static void qelr_free_context(struct ibv_context *ibctx)
>  	free(ctx);
>  }
> 
> -static struct verbs_device *qelr_driver_init(const char *uverbs_sys_path,
> -					     int abi_version)
> +static bool qedr_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +	const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>  	char value[16];
> -	struct qelr_device *dev;
>  	unsigned int vendor, device;
>  	int i;
> 
>  	if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>  				value, sizeof(value)) < 0)
> -		return NULL;
> +		return false;
> 
>  	sscanf(value, "%i", &vendor);
> 
>  	if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>  				value, sizeof(value)) < 0)
> -		return NULL;
> +		return false;
> 
>  	sscanf(value, "%i", &device);
> 
>  	for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i)
>  		if (vendor == hca_table[i].vendor &&
>  		    device == hca_table[i].device)
> -			goto found;
> +			return true;
> 
> -	return NULL;
> -found:
> -	if (abi_version != QELR_ABI_VERSION) {
> -		fprintf(stderr,
> -			"Fatal: libqedr ABI version %d of %s is not supported.\n",
> -			abi_version, uverbs_sys_path);
> -		return NULL;
> -	}
> +	return false;
> +}
> +
> +static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +	struct qelr_device *dev;
> 
>  	dev = calloc(1, sizeof(*dev));
> -	if (!dev) {
> -		qelr_err("%s() Fatal: fail allocate device for libqedr\n",
> -			 __func__);
> +	if (!dev)
>  		return NULL;
> -	}
> 
>  	return &dev->ibv_dev;
>  }
> 
>  static const struct verbs_device_ops qelr_dev_ops = {
>  	.name = "qelr",
> -	.init_device = qelr_driver_init,
> +	.match_min_abi_version = QELR_ABI_VERSION,
> +	.match_max_abi_version = QELR_ABI_VERSION,
> +	.match_device = qedr_device_match,
> +	.alloc_device = qedr_device_alloc,
>  	.uninit_device = qelr_uninit_device,
>  	.alloc_context = qelr_alloc_context,
>  	.free_context = qelr_free_context,

Please use qelr_ prefix for the functions.
There shouldn't be any qedr in this file except for a comment, maybe.

Other than that:
Signed-off-by: Ram Amrani <Ram.Amrani-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure
       [not found]         ` <BN3PR07MB2578333789DA041401297EC0F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2017-09-24 15:58           ` Jason Gunthorpe
       [not found]             ` <20170924155845.GB14796-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-24 15:58 UTC (permalink / raw)
  To: Amrani, Ram
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Devesh Sharma,
	Mike Marciniszyn, Dennis Dalessandro, Tatyana Nikolova,
	Yishai Hadas, Vladimir Sokolovsky, Elior, Ariel, Adit Ranadive,
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

On Sun, Sep 24, 2017 at 01:29:09PM +0000, Amrani, Ram wrote:
> >  static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> >  {
> >  	struct qelr_device *dev;
> > @@ -269,7 +238,7 @@ static const struct verbs_device_ops qelr_dev_ops = {
> >  	.name = "qelr",
> 
> Should this be the driver name or the library name?
> The driver name is qedr and the library name is libqedr. It is usually abbreviated to qelr.
> I reckon that this should be the driver name (otherwise auto-load will fail?!).

I will fix all the names, it is confusing as all the other drivers use
their lib name as prefix..

The above string is only used for diagnostic prints.

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found]         ` <BN3PR07MB257813BD7D36694EBF97BA91F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
@ 2017-09-24 20:10           ` Jason Gunthorpe
       [not found]             ` <20170924201053.GA31652-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  0 siblings, 1 reply; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-24 20:10 UTC (permalink / raw)
  To: Amrani, Ram
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Devesh Sharma, Steve Wise,
	Mike Marciniszyn, Dennis Dalessandro, Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Elior,
	Ariel, Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org

On Sun, Sep 24, 2017 at 01:44:58PM +0000, Amrani, Ram wrote:
> Please use qelr_ prefix for the functions.
> There shouldn't be any qedr in this file except for a comment, maybe.

I changed the series like so:

diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
index 1297e8e16acee5..fa2be455edc93e 100644
--- a/providers/qedr/qelr_main.c
+++ b/providers/qedr/qelr_main.c
@@ -223,7 +223,7 @@ static void qelr_free_context(struct ibv_context *ibctx)
        free(ctx);
 }
 
-static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
+static struct verbs_device *qelr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 {
        struct qelr_device *dev;
 
@@ -235,11 +235,11 @@ static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
 }
 
 static const struct verbs_device_ops qelr_dev_ops = {
-       .name = "qelr",
+       .name = "qedr",
        .match_min_abi_version = QELR_ABI_VERSION,
        .match_max_abi_version = QELR_ABI_VERSION,
        .match_table = hca_table,
-       .alloc_device = qedr_device_alloc,
+       .alloc_device = qelr_device_alloc,
        .uninit_device = qelr_uninit_device,
        .alloc_context = qelr_alloc_context,
        .free_context = qelr_free_context,

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly
  2017-09-19 21:31       ` Steve Wise
@ 2017-09-25  6:46         ` Devesh Sharma
  0 siblings, 0 replies; 31+ messages in thread
From: Devesh Sharma @ 2017-09-25  6:46 UTC (permalink / raw)
  To: Steve Wise
  Cc: Jason Gunthorpe, linux-rdma, Doug Ledford, Yishai Hadas,
	Mike Marciniszyn, Dennis Dalessandro, Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Vladimir Sokolovsky, Ram Amrani, Ariel Elior,
	Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

bnxt_re part looks good to me.

Acked-by: Devesh Sharma <devesh.sharma-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

On Wed, Sep 20, 2017 at 3:01 AM, Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org> wrote:
>>
>> This is analogous to the kernel scheme where code describes a driver
>> with a static structure and then a helper macro registers that
>> driver with the core code.
>>
>> In this case we have an 'ops' that is both the 'driver' and 'device'
>> ops.
>>
>> This is preparation to add more steps to the device startup. Rework
>> all the providers to use this scheme.
>>
>> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
>
> Cxgb bits looks ok.
>
> Acked-by: Steve Wise <swise-7bPotxP6k4+P2YhJcF5u+vpXobYPEAuW@public.gmane.org>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found]     ` <1505855931-4956-5-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-19 21:29       ` Steve Wise
  2017-09-24 13:44       ` Amrani, Ram
@ 2017-09-25  7:41       ` Devesh Sharma
  2 siblings, 0 replies; 31+ messages in thread
From: Devesh Sharma @ 2017-09-25  7:41 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-rdma, Steve Wise, Mike Marciniszyn, Dennis Dalessandro,
	Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Ram Amrani,
	Ariel Elior, Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

bnxt_re related part looks good to me

Acked-by: Devesh Sharma <devesh.sharma-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

On Wed, Sep 20, 2017 at 2:48 AM, Jason Gunthorpe
<jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote:
> This is the first step to simplify the provider binding process.
>
> Checking of the ABI version is hoisted into the core code, as are some
> of the common error messages.
>
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>  providers/bnxt_re/main.c           | 36 ++++++++++------------
>  providers/cxgb3/iwch.c             | 60 ++++++++++++++++--------------------
>  providers/cxgb4/dev.c              | 60 +++++++++++++++++++-----------------
>  providers/hfi1verbs/hfiverbs.c     | 31 ++++++++++---------
>  providers/hns/hns_roce_u.c         | 63 +++++++++++++++++++-------------------
>  providers/i40iw/i40iw_umain.c      | 39 ++++++++++++++---------
>  providers/ipathverbs/ipathverbs.c  | 32 ++++++++++---------
>  providers/mlx4/mlx4.c              | 42 +++++++++++--------------
>  providers/mlx5/mlx5.c              | 42 ++++++++++---------------
>  providers/mthca/mthca.c            | 43 +++++++++++++-------------
>  providers/nes/nes_umain.c          | 48 ++++++++++++++++-------------
>  providers/ocrdma/ocrdma_main.c     | 46 ++++++++++++----------------
>  providers/qedr/qelr_main.c         | 35 ++++++++++-----------
>  providers/rxe/rxe.c                | 28 +++++++++--------
>  providers/vmw_pvrdma/pvrdma_main.c | 49 ++++++++++-------------------
>  15 files changed, 317 insertions(+), 337 deletions(-)
>
> diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
> index d2c2a6847e3c71..c83baacbb9f749 100644
> --- a/providers/bnxt_re/main.c
> +++ b/providers/bnxt_re/main.c
> @@ -174,43 +174,38 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
>         }
>  }
>
> -static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,
> -                                               int abi_version)
> +static bool bnxt_re_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[10];
> -       struct bnxt_re_dev *dev;
>         unsigned int vendor, device;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>         vendor = strtol(value, NULL, 16);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>         device = strtol(value, NULL, 16);
>
>         for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
>                 if (vendor == cna_table[i].vendor &&
>                     device == cna_table[i].device)
> -                       goto found;
> -       return NULL;
> -found:
> -       if (abi_version != BNXT_RE_ABI_VERSION) {
> -               fprintf(stderr, DEV "FATAL: Max supported ABI of %s is %d "
> -                       "check for the latest version of kernel driver and"
> -                       "user library\n", uverbs_sys_path, abi_version);
> -               return NULL;
> -       }
> +                       return true;
> +       return false;
> +}
> +
> +static struct verbs_device *
> +bnxt_re_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct bnxt_re_dev *dev;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, DEV "Failed to allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
>         dev->vdev.sz = sizeof(*dev);
>         dev->vdev.size_of_context =
> @@ -221,7 +216,10 @@ found:
>
>  static const struct verbs_device_ops bnxt_re_dev_ops = {
>         .name = "bnxt_re",
> -       .init_device = bnxt_re_driver_init,
> +       .match_min_abi_version = BNXT_RE_ABI_VERSION,
> +       .match_max_abi_version = BNXT_RE_ABI_VERSION,
> +       .match_device = bnxt_re_device_match,
> +       .alloc_device = bnxt_re_device_alloc,
>         .init_context = bnxt_re_init_context,
>         .uninit_context = bnxt_re_uninit_context,
>  };
> diff --git a/providers/cxgb3/iwch.c b/providers/cxgb3/iwch.c
> index c2423a7ee2cc32..7eb283bd9a89e1 100644
> --- a/providers/cxgb3/iwch.c
> +++ b/providers/cxgb3/iwch.c
> @@ -61,7 +61,7 @@
>           .device = PCI_DEVICE_ID_CHELSIO_##d,          \
>           .type = CHELSIO_##t }
>
> -static struct {
> +static struct hca_ent {
>         unsigned vendor;
>         unsigned device;
>         enum iwch_hca_type type;
> @@ -173,30 +173,31 @@ static void iwch_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
> -                                             int abi_version)
> +static bool iwch_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -       char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
> -       struct iwch_device *dev;
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> +       char value[32], *cp;
>         unsigned vendor, device, fw_maj, fw_min;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> +                   device == hca_table[i].device) {
> +                       sysfs_dev->provider_data = &hca_table[i];
>                         goto found;
> +               }
>
> -       return NULL;
> +       return false;
>
>  found:
>
> @@ -204,15 +205,9 @@ found:
>          * Verify that the firmware major number matches.  Major number
>          * mismatches are fatal.  Minor number mismatches are tolerated.
>          */
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
> -                               ibdev, sizeof ibdev) < 0)
> -               return NULL;
> -
> -       memset(devstr, 0, sizeof devstr);
> -       snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s",
> -                ibv_get_sysfs_path(), ibdev);
> -       if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
> -               return NULL;
> +       if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
> +                               sizeof(value)) < 0)
> +               return false;
>
>         cp = strtok(value+1, ".");
>         sscanf(cp, "%i", &fw_maj);
> @@ -224,7 +219,7 @@ found:
>                         "Firmware major number is %u and libcxgb3 needs %u.\n",
>                         fw_maj, FW_MAJ);
>                 fflush(stderr);
> -               return NULL;
> +               return false;
>         }
>
>         DBGLOG("libcxgb3");
> @@ -236,25 +231,21 @@ found:
>                 fflush(stderr);
>         }
>
> -       if (abi_version > ABI_VERS) {
> -               PDBG("libcxgb3: ABI version mismatch.  "
> -                       "Kernel driver ABI is %u and libcxgb3 needs <= %u.\n",
> -                       abi_version, ABI_VERS);
> -               fflush(stderr);
> -               return NULL;
> -       }
> +       return true;
> +}
>
> -       PDBG("%s found vendor %d device %d type %d\n",
> -            __FUNCTION__, vendor, device, hca_table[i].type);
> +static struct verbs_device *iwch_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct iwch_device *dev;
> +       struct hca_ent *hca_ent = sysfs_dev->provider_data;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> +       if (!dev)
>                 return NULL;
> -       }
>
>         pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
> -       dev->hca_type = hca_table[i].type;
> -       dev->abi_version = abi_version;
> +       dev->hca_type = hca_ent->type;
> +       dev->abi_version = sysfs_dev->abi_ver;
>
>         iwch_page_size = sysconf(_SC_PAGESIZE);
>         iwch_page_shift = long_log2(iwch_page_size);
> @@ -285,7 +276,10 @@ err1:
>
>  static const struct verbs_device_ops iwch_dev_ops = {
>         .name = "cxgb3",
> -       .init_device = cxgb3_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = ABI_VERS,
> +       .match_device = iwch_device_match,
> +       .alloc_device = iwch_device_alloc,
>         .uninit_device = iwch_uninit_device,
>         .alloc_context = iwch_alloc_context,
>         .free_context = iwch_free_context,
> diff --git a/providers/cxgb4/dev.c b/providers/cxgb4/dev.c
> index 492b3978995607..43c5a3c97bc864 100644
> --- a/providers/cxgb4/dev.c
> +++ b/providers/cxgb4/dev.c
> @@ -49,7 +49,7 @@
>   * Macros needed to support the PCI Device ID Table ...
>   */
>  #define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
> -       static struct { \
> +       static struct hca_ent { \
>                 unsigned vendor; \
>                 unsigned device; \
>         } hca_table[] = {
> @@ -399,47 +399,40 @@ void dump_state(void)
>   */
>  int c4iw_abi_version = 1;
>
> -static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,
> -                                             int abi_version)
> +static bool c4iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -       char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
> -       struct c4iw_dev *dev;
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> +       char value[32], *cp;
>         unsigned vendor, device, fw_maj, fw_min;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> +                   device == hca_table[i].device) {
> +                       sysfs_dev->provider_data = &hca_table[i];
>                         goto found;
> +               }
>
> -       return NULL;
> +       return false;
>
>  found:
> -       c4iw_abi_version = abi_version;
> -
>         /*
>          * Verify that the firmware major number matches.  Major number
>          * mismatches are fatal.  Minor number mismatches are tolerated.
>          */
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
> -                               ibdev, sizeof ibdev) < 0)
> -               return NULL;
> -
> -       memset(devstr, 0, sizeof devstr);
> -       snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s",
> -                ibv_get_sysfs_path(), ibdev);
> -       if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
> -               return NULL;
> +       if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
> +                               sizeof(value)) < 0)
> +               return false;
>
>         cp = strtok(value+1, ".");
>         sscanf(cp, "%i", &fw_maj);
> @@ -451,7 +444,7 @@ found:
>                         "Firmware major number is %u and libcxgb4 needs %u.\n",
>                         fw_maj, FW_MAJ);
>                 fflush(stderr);
> -               return NULL;
> +               return false;
>         }
>
>         DBGLOG("libcxgb4");
> @@ -462,22 +455,30 @@ found:
>                         fw_min, FW_MIN);
>                 fflush(stderr);
>         }
> +       return true;
> +}
>
> -       PDBG("%s found vendor %d device %d type %d\n",
> -            __FUNCTION__, vendor, device, CHELSIO_CHIP_VERSION(hca_table[i].device >> 8));
> +static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct c4iw_dev *dev;
> +       struct hca_ent *hca_ent = sysfs_dev->provider_data;
> +
> +       c4iw_page_size = sysconf(_SC_PAGESIZE);
> +       c4iw_page_shift = long_log2(c4iw_page_size);
> +       c4iw_page_mask = ~(c4iw_page_size - 1);
>
>         c4iw_page_size = sysconf(_SC_PAGESIZE);
>         c4iw_page_shift = long_log2(c4iw_page_size);
>         c4iw_page_mask = ~(c4iw_page_size - 1);
>
>         dev = calloc(1, sizeof *dev);
> -       if (!dev) {
> +       if (!dev)
>                 return NULL;
> -       }
>
>         pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
> -       dev->chip_version = CHELSIO_CHIP_VERSION(hca_table[i].device >> 8);
> -       dev->abi_version = abi_version;
> +       c4iw_abi_version = sysfs_dev->abi_ver;
> +       dev->chip_version = CHELSIO_CHIP_VERSION(hca_ent->device >> 8);
> +       dev->abi_version = sysfs_dev->abi_ver;
>         list_node_init(&dev->list);
>
>         PDBG("%s device claimed\n", __FUNCTION__);
> @@ -514,7 +515,10 @@ found:
>
>  static const struct verbs_device_ops c4iw_dev_ops = {
>         .name = "cxgb4",
> -       .init_device = cxgb4_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = c4iw_device_match,
> +       .alloc_device = c4iw_device_alloc,
>         .uninit_device = c4iw_uninit_device,
>         .alloc_context = c4iw_alloc_context,
>         .free_context = c4iw_free_context,
> diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
> index 247831eb211804..5bb436593517e1 100644
> --- a/providers/hfi1verbs/hfiverbs.c
> +++ b/providers/hfi1verbs/hfiverbs.c
> @@ -180,47 +180,50 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *hfi1_driver_init(const char *uverbs_sys_path,
> -                                            int abi_version)
> +static bool hfi1_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                    value[8];
> -       struct hfi1_device    *dev;
>         unsigned                vendor, device;
>         int                     i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
>                     device == hca_table[i].device)
> -                       goto found;
> +                       return true;
>
> -       return NULL;
> +       return false;
> +}
> +
> +static struct verbs_device *hfi1_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct hfi1_device    *dev;
>
> -found:
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->abi_version = abi_version;
> +       dev->abi_version = sysfs_dev->abi_ver;
>
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops hfi1_dev_ops = {
>         .name = "hfi1verbs",
> -       .init_device = hfi1_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = hfi1_device_match,
> +       .alloc_device = hfi1_device_alloc,
>         .uninit_device  = hf11_uninit_device,
>         .alloc_context = hfi1_alloc_context,
>         .free_context = hfi1_free_context,
> diff --git a/providers/hns/hns_roce_u.c b/providers/hns/hns_roce_u.c
> index fe2d009ebe3737..88389721811fce 100644
> --- a/providers/hns/hns_roce_u.c
> +++ b/providers/hns/hns_roce_u.c
> @@ -44,20 +44,18 @@
>  #define HID_LEN                        15
>  #define DEV_MATCH_LEN          128
>
> -static const struct {
> -       char     hid[HID_LEN];
> -       void     *data;
> -       int      version;
> -} acpi_table[] = {
> +struct hca_ent {
> +       const char *str;
> +       struct hns_roce_u_hw *data;
> +       int version;
> +};
> +
> +static const struct hca_ent acpi_table[] = {
>          {"acpi:HISI00D1:", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
>          {},
>  };
>
> -static const struct {
> -       char     compatible[DEV_MATCH_LEN];
> -       void     *data;
> -       int      version;
> -} dt_table[] = {
> +static const struct hca_ent dt_table[] = {
>         {"hisilicon,hns-roce-v1", &hns_roce_u_hw_v1, HNS_ROCE_HW_VER1},
>         {},
>  };
> @@ -180,52 +178,53 @@ static void hns_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *hns_roce_driver_init(const char *uverbs_sys_path,
> -                                                int abi_version)
> +static bool hns_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -       struct hns_roce_device  *dev;
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                     value[128];
>         int                      i;
> -       void                     *u_hw;
> -       int                      hw_version;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/modalias",
>                                 value, sizeof(value)) > 0)
>                 for (i = 0; i < sizeof(acpi_table) / sizeof(acpi_table[0]); ++i)
> -                       if (!strcmp(value, acpi_table[i].hid)) {
> -                               u_hw = acpi_table[i].data;
> -                               hw_version = acpi_table[i].version;
> -                               goto found;
> +                       if (!strcmp(value, acpi_table[i].str)) {
> +                               sysfs_dev->provider_data =
> +                                   (void *)&acpi_table[i];
> +                               return true;
>                         }
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/of_node/compatible",
>                                 value, sizeof(value)) > 0)
>                 for (i = 0; i < sizeof(dt_table) / sizeof(dt_table[0]); ++i)
> -                       if (!strcmp(value, dt_table[i].compatible)) {
> -                               u_hw = dt_table[i].data;
> -                               hw_version = dt_table[i].version;
> -                               goto found;
> +                       if (!strcmp(value, dt_table[i].str)) {
> +                               sysfs_dev->provider_data = (void *)&dt_table[i];
> +                               return true;
>                         }
>
> -       return NULL;
> +       return false;
> +}
> +
> +static struct verbs_device *hns_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct hns_roce_device  *dev;
> +       const struct hca_ent *hca_ent = sysfs_dev->provider_data;
>
> -found:
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->u_hw = (struct hns_roce_u_hw *)u_hw;
> -       dev->hw_version = hw_version;
> +       dev->u_hw = hca_ent->data;
> +       dev->hw_version = hca_ent->version;
>         dev->page_size   = sysconf(_SC_PAGESIZE);
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops hns_roce_dev_ops = {
>         .name = "hns",
> -       .init_device = hns_roce_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = hns_device_match,
> +       .alloc_device = hns_device_alloc,
>         .uninit_device = hns_uninit_device,
>         .alloc_context = hns_roce_alloc_context,
>         .free_context = hns_roce_free_context,
> diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
> index 90d37651d1f702..bcba6158e60e40 100644
> --- a/providers/i40iw/i40iw_umain.c
> +++ b/providers/i40iw/i40iw_umain.c
> @@ -55,7 +55,7 @@
>           .device = d,          \
>           .type = INTEL_ ## t }
>
> -static struct {
> +static struct hca_ent {
>         unsigned int vendor;
>         unsigned int device;
>         enum i40iw_uhca_type type;
> @@ -220,44 +220,53 @@ static void i40iw_uninit_device(struct verbs_device *verbs_device)
>   * @uverbs_sys_path: sys path
>   * @abi_version: not used
>   */
> -static struct verbs_device *i40iw_driver_init(const char *uverbs_sys_path,
> -                                             int abi_version)
> +static bool i40iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[16];
> -       struct i40iw_udevice *dev;
>         unsigned int vendor, device;
>         int i;
>
>         if ((ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", value, sizeof(value)) < 0) ||
>             (sscanf(value, "%i", &vendor) != 1))
> -               return NULL;
> +               return false;
>
>         if ((ibv_read_sysfs_file(uverbs_sys_path, "device/device", value, sizeof(value)) < 0) ||
>             (sscanf(value, "%i", &device) != 1))
> -               return NULL;
> +               return false;
>
>         for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i) {
>                 if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       goto found;
> +                   device == hca_table[i].device) {
> +                       sysfs_dev->provider_data = &hca_table[i];
> +                       return true;
> +               }
>         }
>
> -       return NULL;
> -found:
> +       return false;
> +}
> +
> +static struct verbs_device *
> +i40iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct i40iw_udevice *dev;
> +       struct hca_ent *hca_ent = sysfs_dev->provider_data;
> +
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "%s: failed to allocate memory for device object\n", __func__);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->hca_type = hca_table[i].type;
> +       dev->hca_type = hca_ent->type;
>         dev->page_size = I40IW_HW_PAGE_SIZE;
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops i40iw_udev_ops = {
>         .name = "i40iw",
> -       .init_device = i40iw_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = i40iw_device_match,
> +       .alloc_device = i40iw_device_alloc,
>         .uninit_device  = i40iw_uninit_device,
>         .alloc_context = i40iw_ualloc_context,
>         .free_context = i40iw_ufree_context,
> diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
> index ebdf5b828e1784..3c141263d8ff86 100644
> --- a/providers/ipathverbs/ipathverbs.c
> +++ b/providers/ipathverbs/ipathverbs.c
> @@ -179,47 +179,51 @@ static void ipath_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *ipath_driver_init(const char *uverbs_sys_path,
> -                                             int abi_version)
> +static bool ipath_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                    value[8];
> -       struct ipath_device    *dev;
>         unsigned                vendor, device;
>         int                     i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
>                     device == hca_table[i].device)
> -                       goto found;
> +                       return true;
>
> -       return NULL;
> +       return false;
> +}
> +
> +static struct verbs_device *
> +ipath_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct ipath_device    *dev;
>
> -found:
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->abi_version = abi_version;
> +       dev->abi_version = sysfs_dev->abi_ver;
>
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops ipath_dev_ops = {
>         .name = "ipathverbs",
> -       .init_device = ipath_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = ipath_device_match,
> +       .alloc_device = ipath_device_alloc,
>         .uninit_device  = ipath_uninit_device,
>         .alloc_context = ipath_alloc_context,
>         .free_context = ipath_free_context,
> diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
> index 0eefa40af16d83..b52684a563b495 100644
> --- a/providers/mlx4/mlx4.c
> +++ b/providers/mlx4/mlx4.c
> @@ -286,50 +286,41 @@ static void mlx4_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *mlx4_driver_init(const char *uverbs_sys_path, int abi_version)
> +static bool mlx4_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                    value[8];
> -       struct mlx4_device    *dev;
>         unsigned                vendor, device;
>         int                     i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         vendor = strtol(value, NULL, 16);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         device = strtol(value, NULL, 16);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
>                     device == hca_table[i].device)
> -                       goto found;
> -
> -       return NULL;
> -
> -found:
> -       if (abi_version < MLX4_UVERBS_MIN_ABI_VERSION ||
> -           abi_version > MLX4_UVERBS_MAX_ABI_VERSION) {
> -               fprintf(stderr, PFX "Fatal: ABI version %d of %s is not supported "
> -                       "(min supported %d, max supported %d)\n",
> -                       abi_version, uverbs_sys_path,
> -                       MLX4_UVERBS_MIN_ABI_VERSION,
> -                       MLX4_UVERBS_MAX_ABI_VERSION);
> -               return NULL;
> -       }
> +                       return true;
> +
> +       return false;
> +}
> +
> +static struct verbs_device *mlx4_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct mlx4_device *dev;
>
>         dev = calloc(1, sizeof *dev);
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
>         dev->page_size   = sysconf(_SC_PAGESIZE);
> -       dev->abi_version = abi_version;
> +       dev->abi_version = sysfs_dev->abi_ver;
>
>         dev->verbs_dev.sz = sizeof(*dev);
>         dev->verbs_dev.size_of_context =
> @@ -340,7 +331,10 @@ found:
>
>  static const struct verbs_device_ops mlx4_dev_ops = {
>         .name = "mlx4",
> -       .init_device = mlx4_driver_init,
> +       .match_min_abi_version = MLX4_UVERBS_MIN_ABI_VERSION,
> +       .match_max_abi_version = MLX4_UVERBS_MAX_ABI_VERSION,
> +       .match_device = mlx4_device_match,
> +       .alloc_device = mlx4_device_alloc,
>         .uninit_device = mlx4_uninit_device,
>         .init_context = mlx4_init_context,
>         .uninit_context = mlx4_uninit_context,
> diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
> index 68cca7cde97ef2..44cfd97b73cbbb 100644
> --- a/providers/mlx5/mlx5.c
> +++ b/providers/mlx5/mlx5.c
> @@ -1026,51 +1026,40 @@ static void mlx5_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *mlx5_driver_init(const char *uverbs_sys_path,
> -                                            int abi_version)
> +static bool mlx5_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                    value[8];
> -       struct mlx5_device     *dev;
>         unsigned                vendor, device;
>         int                     i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
>                     device == hca_table[i].device)
> -                       goto found;
> -
> -       return NULL;
> -
> -found:
> -       if (abi_version < MLX5_UVERBS_MIN_ABI_VERSION ||
> -           abi_version > MLX5_UVERBS_MAX_ABI_VERSION) {
> -               fprintf(stderr, PFX "Fatal: ABI version %d of %s is not supported "
> -                       "(min supported %d, max supported %d)\n",
> -                       abi_version, uverbs_sys_path,
> -                       MLX5_UVERBS_MIN_ABI_VERSION,
> -                       MLX5_UVERBS_MAX_ABI_VERSION);
> -               return NULL;
> -       }
> +                       return true;
> +       return false;
> +}
> +
> +static struct verbs_device *mlx5_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct mlx5_device *dev;
>
>         dev = calloc(1, sizeof *dev);
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
>         dev->page_size   = sysconf(_SC_PAGESIZE);
> -       dev->driver_abi_ver = abi_version;
> +       dev->driver_abi_ver = sysfs_dev->abi_ver;
>
>         dev->verbs_dev.sz = sizeof(*dev);
>         dev->verbs_dev.size_of_context = sizeof(struct mlx5_context) -
> @@ -1081,7 +1070,10 @@ found:
>
>  static const struct verbs_device_ops mlx5_dev_ops = {
>         .name = "mlx5",
> -       .init_device = mlx5_driver_init,
> +       .match_min_abi_version = MLX5_UVERBS_MIN_ABI_VERSION,
> +       .match_max_abi_version = MLX5_UVERBS_MAX_ABI_VERSION,
> +       .match_device = mlx5_device_match,
> +       .alloc_device = mlx5_device_alloc,
>         .uninit_device = mlx5_uninit_device,
>         .init_context = mlx5_init_context,
>         .uninit_context = mlx5_cleanup_context,
> diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
> index 7194539b2d6ab1..521e5b9afe4f2b 100644
> --- a/providers/mthca/mthca.c
> +++ b/providers/mthca/mthca.c
> @@ -77,7 +77,7 @@
>           .device = PCI_DEVICE_ID_MELLANOX_##d,         \
>           .type = MTHCA_##t }
>
> -static struct {
> +static struct hca_ent {
>         unsigned                vendor;
>         unsigned                device;
>         enum mthca_hca_type     type;
> @@ -216,46 +216,44 @@ static void mthca_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *mthca_driver_init(const char *uverbs_sys_path,
> -                                           int abi_version)
> +static bool mthca_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char                    value[8];
> -       struct mthca_device    *dev;
>         unsigned                vendor, device;
>         int                     i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof value) < 0)
> -               return NULL;
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       goto found;
> +                   device == hca_table[i].device) {
> +                       sysfs_dev->provider_data = &hca_table[i];
> +                       return true;
> +               }
>
> -       return NULL;
> +       return false;
> +}
>
> -found:
> -       if (abi_version > MTHCA_UVERBS_ABI_VERSION) {
> -               fprintf(stderr, PFX "Fatal: ABI version %d of %s is too new (expected %d)\n",
> -                       abi_version, uverbs_sys_path, MTHCA_UVERBS_ABI_VERSION);
> -               return NULL;
> -       }
> +static struct verbs_device *
> +mthca_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct mthca_device    *dev;
> +       struct hca_ent *hca_ent = sysfs_dev->provider_data;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->hca_type    = hca_table[i].type;
> +       dev->hca_type    = hca_ent->type;
>         dev->page_size   = sysconf(_SC_PAGESIZE);
>
>         return &dev->ibv_dev;
> @@ -263,7 +261,10 @@ found:
>
>  static const struct verbs_device_ops mthca_dev_ops = {
>         .name = "mthca",
> -       .init_device = mthca_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = MTHCA_UVERBS_ABI_VERSION,
> +       .match_device = mthca_device_match,
> +       .alloc_device = mthca_device_alloc,
>         .uninit_device = mthca_uninit_device,
>         .alloc_context = mthca_alloc_context,
>         .free_context = mthca_free_context,
> diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
> index d02e010d2524a2..fc021a9196b6ad 100644
> --- a/providers/nes/nes_umain.c
> +++ b/providers/nes/nes_umain.c
> @@ -60,7 +60,7 @@ long int page_size;
>           .device = d,    \
>           .type = NETEFFECT_##t }
>
> -static struct {
> +static struct hca_ent {
>         unsigned vendor;
>         unsigned device;
>         enum nes_uhca_type type;
> @@ -191,37 +191,40 @@ static void nes_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -/**
> - * nes_driver_init
> - */
> -static struct verbs_device *nes_driver_init(const char *uverbs_sys_path,
> -                                           int abi_version)
> +static bool nes_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[16];
> -       struct nes_udevice *dev;
>         unsigned vendor, device;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                       value, sizeof(value)) < 0) {
> -               return NULL;
> -       }
> +                       value, sizeof(value)) < 0)
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                       value, sizeof(value)) < 0) {
> -               return NULL;
> -       }
> +                       value, sizeof(value)) < 0)
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
>                 if (vendor == hca_table[i].vendor &&
> -                               device == hca_table[i].device)
> -                       goto found;
> +                   device == hca_table[i].device) {
> +                       sysfs_dev->provider_data = &hca_table[i];
> +                       return true;
> +               }
>
> -       return NULL;
> +       return false;
> +}
> +
> +static struct verbs_device *
> +nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct nes_udevice *dev;
> +       struct hca_ent *hca_ent = sysfs_dev->provider_data;
> +       char value[16];
>
> -found:
>         if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/debug_level",
>                         value, sizeof(value)) > 0) {
>                 sscanf(value, "%u", &nes_debug_level);
> @@ -231,12 +234,10 @@ found:
>         }
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               nes_debug(NES_DBG_INIT, "Fatal: couldn't allocate device for libnes\n");
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->hca_type = hca_table[i].type;
> +       dev->hca_type = hca_ent->type;
>         dev->page_size = sysconf(_SC_PAGESIZE);
>
>         nes_debug(NES_DBG_INIT, "libnes initialized\n");
> @@ -246,7 +247,10 @@ found:
>
>  static const struct verbs_device_ops nes_udev_ops = {
>         .name = "nes",
> -       .init_device = nes_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = nes_device_match,
> +       .alloc_device = nes_device_alloc,
>         .uninit_device = nes_uninit_device,
>         .alloc_context = nes_ualloc_context,
>         .free_context = nes_ufree_context,
> diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
> index 09c00d21ce2af6..f08a49fb73e021 100644
> --- a/providers/ocrdma/ocrdma_main.c
> +++ b/providers/ocrdma/ocrdma_main.c
> @@ -168,50 +168,39 @@ static void ocrdma_free_context(struct ibv_context *ibctx)
>         free(ctx);
>  }
>
> -/**
> - * ocrdma_driver_init
> - */
> -static struct verbs_device *ocrdma_driver_init(const char *uverbs_sys_path,
> -                                              int abi_version)
> +static bool ocrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[16];
> -       struct ocrdma_device *dev;
>         unsigned vendor, device;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof(value)) < 0) {
> -               return NULL;
> -       }
> +                               value, sizeof(value)) < 0)
> +               return false;
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof(value)) < 0) {
> -               return NULL;
> -       }
> +                               value, sizeof(value)) < 0)
> +               return false;
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof ucna_table / sizeof ucna_table[0]; ++i) {
>                 if (vendor == ucna_table[i].vendor &&
>                     device == ucna_table[i].device)
> -                       goto found;
> -       }
> -       return NULL;
> -found:
> -       if (abi_version != OCRDMA_ABI_VERSION) {
> -               fprintf(stderr,
> -                 "Fatal: libocrdma ABI version %d of %s is not supported.\n",
> -                 abi_version, uverbs_sys_path);
> -               return NULL;
> +                       return true;
>         }
> +       return false;
> +}
> +
> +static struct verbs_device *
> +ocrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct ocrdma_device *dev;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               ocrdma_err("%s() Fatal: fail allocate device for libocrdma\n",
> -                          __func__);
> +       if (!dev)
>                 return NULL;
> -       }
>
>         dev->qp_tbl = malloc(OCRDMA_MAX_QP * sizeof(struct ocrdma_qp *));
>         if (!dev->qp_tbl)
> @@ -227,7 +216,10 @@ qp_err:
>
>  static const struct verbs_device_ops ocrdma_dev_ops = {
>         .name = "ocrdma",
> -       .init_device = ocrdma_driver_init,
> +       .match_min_abi_version = OCRDMA_ABI_VERSION,
> +       .match_max_abi_version = OCRDMA_ABI_VERSION,
> +       .match_device = ocrdma_device_match,
> +       .alloc_device = ocrdma_device_alloc,
>         .uninit_device = ocrdma_uninit_device,
>         .alloc_context = ocrdma_alloc_context,
>         .free_context = ocrdma_free_context,
> diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
> index 0be4a8c82a1e05..4d1b92f40a413a 100644
> --- a/providers/qedr/qelr_main.c
> +++ b/providers/qedr/qelr_main.c
> @@ -227,53 +227,50 @@ static void qelr_free_context(struct ibv_context *ibctx)
>         free(ctx);
>  }
>
> -static struct verbs_device *qelr_driver_init(const char *uverbs_sys_path,
> -                                            int abi_version)
> +static bool qedr_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[16];
> -       struct qelr_device *dev;
>         unsigned int vendor, device;
>         int i;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>
>         sscanf(value, "%i", &vendor);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>
>         sscanf(value, "%i", &device);
>
>         for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i)
>                 if (vendor == hca_table[i].vendor &&
>                     device == hca_table[i].device)
> -                       goto found;
> +                       return true;
>
> -       return NULL;
> -found:
> -       if (abi_version != QELR_ABI_VERSION) {
> -               fprintf(stderr,
> -                       "Fatal: libqedr ABI version %d of %s is not supported.\n",
> -                       abi_version, uverbs_sys_path);
> -               return NULL;
> -       }
> +       return false;
> +}
> +
> +static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct qelr_device *dev;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               qelr_err("%s() Fatal: fail allocate device for libqedr\n",
> -                        __func__);
> +       if (!dev)
>                 return NULL;
> -       }
>
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops qelr_dev_ops = {
>         .name = "qelr",
> -       .init_device = qelr_driver_init,
> +       .match_min_abi_version = QELR_ABI_VERSION,
> +       .match_max_abi_version = QELR_ABI_VERSION,
> +       .match_device = qedr_device_match,
> +       .alloc_device = qedr_device_alloc,
>         .uninit_device = qelr_uninit_device,
>         .alloc_context = qelr_alloc_context,
>         .free_context = qelr_free_context,
> diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c
> index 655800ec3410fd..d9857aac70d745 100644
> --- a/providers/rxe/rxe.c
> +++ b/providers/rxe/rxe.c
> @@ -893,36 +893,40 @@ static void rxe_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct verbs_device *rxe_driver_init(const char *uverbs_sys_path,
> -                                           int abi_version)
> +static bool rxe_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -       struct rxe_device *dev;
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[16];
>
>         /* make sure it is a rxe device */
>         if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>
>         if (strncmp(value, "rxe", 3))
> -               return NULL;
> +               return false;
> +
> +       return true;
> +}
>
> +static struct verbs_device *rxe_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct rxe_device *dev;
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr,
> -                       "rxe: Fatal: couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->abi_version = abi_version;
> +       dev->abi_version = sysfs_dev->abi_ver;
>
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops rxe_dev_ops = {
>         .name = "rxe",
> -       .init_device = rxe_driver_init,
> +       .match_min_abi_version = 0,
> +       .match_max_abi_version = INT_MAX,
> +       .match_device = rxe_device_match,
> +       .alloc_device = rxe_device_alloc,
>         .uninit_device = rxe_uninit_device,
>         .alloc_context = rxe_alloc_context,
>         .free_context = rxe_free_context,
> diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
> index 75b9296c6e24e3..9bcf2ddd172afb 100644
> --- a/providers/vmw_pvrdma/pvrdma_main.c
> +++ b/providers/vmw_pvrdma/pvrdma_main.c
> @@ -169,64 +169,49 @@ static void pvrdma_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static struct pvrdma_device *pvrdma_driver_init_shared(
> -                                               const char *uverbs_sys_path,
> -                                               int abi_version)
> +static bool pvrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
>  {
> -       struct pvrdma_device *dev;
> +       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
>         char value[8];
>         unsigned int vendor_id, device_id;
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>         vendor_id = strtol(value, NULL, 16);
>
>         if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
>                                 value, sizeof(value)) < 0)
> -               return NULL;
> +               return false;
>         device_id = strtol(value, NULL, 16);
>
>         if (vendor_id != PCI_VENDOR_ID_VMWARE ||
>             device_id != PCI_DEVICE_ID_VMWARE_PVRDMA)
> -               return NULL;
> +               return false;
> +       return true;
> +}
>
> -       /* We support only a single ABI version for now. */
> -       if (abi_version != PVRDMA_UVERBS_ABI_VERSION) {
> -               fprintf(stderr, PFX "ABI version %d of %s is not "
> -                       "supported (supported %d)\n",
> -                       abi_version, uverbs_sys_path,
> -                       PVRDMA_UVERBS_ABI_VERSION);
> -               return NULL;
> -       }
> +static struct verbs_device *
> +pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +{
> +       struct pvrdma_device *dev;
>
>         dev = calloc(1, sizeof(*dev));
> -       if (!dev) {
> -               fprintf(stderr, PFX "couldn't allocate device for %s\n",
> -                       uverbs_sys_path);
> +       if (!dev)
>                 return NULL;
> -       }
>
> -       dev->abi_version = abi_version;
> +       dev->abi_version = sysfs_dev->abi_ver;
>         dev->page_size   = sysconf(_SC_PAGESIZE);
>
> -       return dev;
> -}
> -
> -static struct verbs_device *pvrdma_driver_init(const char *uverbs_sys_path,
> -                                              int abi_version)
> -{
> -       struct pvrdma_device *dev = pvrdma_driver_init_shared(uverbs_sys_path,
> -                                                             abi_version);
> -       if (!dev)
> -               return NULL;
> -
>         return &dev->ibv_dev;
>  }
>
>  static const struct verbs_device_ops pvrdma_dev_ops = {
>         .name = "pvrdma",
> -       .init_device = pvrdma_driver_init,
> +       .match_min_abi_version = PVRDMA_UVERBS_ABI_VERSION,
> +       .match_max_abi_version = PVRDMA_UVERBS_ABI_VERSION,
> +       .match_device = pvrdma_device_match,
> +       .alloc_device = pvrdma_device_alloc,
>         .uninit_device = pvrdma_uninit_device,
>         .alloc_context = pvrdma_alloc_context,
>         .free_context  = pvrdma_free_context,
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure
       [not found]     ` <1505855931-4956-8-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
  2017-09-24 13:29       ` Amrani, Ram
@ 2017-09-25  7:48       ` Devesh Sharma
  1 sibling, 0 replies; 31+ messages in thread
From: Devesh Sharma @ 2017-09-25  7:48 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-rdma, Mike Marciniszyn, Dennis Dalessandro,
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Ram Amrani,
	Ariel Elior, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

bnxt_re related part looks good to me.

Acked-by: Devesh Sharma <devesh.sharma-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

On Wed, Sep 20, 2017 at 2:48 AM, Jason Gunthorpe
<jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org> wrote:
> Migrate all trivial cases, these are all just copies of a few variations of
> the table scan.
>
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>  providers/bnxt_re/main.c           | 40 ++++---------------------------
>  providers/hfi1verbs/hfiverbs.c     | 39 ++++--------------------------
>  providers/i40iw/i40iw_umain.c      | 49 ++++----------------------------------
>  providers/ipathverbs/ipathverbs.c  | 39 ++++--------------------------
>  providers/mlx4/mlx4.c              | 38 ++++-------------------------
>  providers/mlx5/mlx5.c              | 38 ++++-------------------------
>  providers/mthca/mthca.c            | 47 ++++++------------------------------
>  providers/nes/nes_umain.c          | 46 +++++------------------------------
>  providers/ocrdma/ocrdma_main.c     | 43 +++++++--------------------------
>  providers/qedr/qelr_main.c         | 41 ++++---------------------------
>  providers/vmw_pvrdma/pvrdma_main.c | 30 ++++++-----------------
>  11 files changed, 61 insertions(+), 389 deletions(-)
>
> diff --git a/providers/bnxt_re/main.c b/providers/bnxt_re/main.c
> index c83baacbb9f749..998c9fe3313389 100644
> --- a/providers/bnxt_re/main.c
> +++ b/providers/bnxt_re/main.c
> @@ -52,15 +52,8 @@
>
>  #define PCI_VENDOR_ID_BROADCOM         0x14E4
>
> -#define CNA(v, d)                                      \
> -       {       .vendor = PCI_VENDOR_ID_##v,            \
> -               .device = d }
> -
> -static const struct {
> -       unsigned int vendor;
> -       unsigned int device;
> -} cna_table[] = {
> -       CNA(BROADCOM, 0x1614),  /* BCM57454 */
> +#define CNA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
> +static const struct verbs_match_ent cna_table[] = {
>         CNA(BROADCOM, 0x16C0),  /* BCM57417 NPAR */
>         CNA(BROADCOM, 0x16CE),  /* BMC57311 */
>         CNA(BROADCOM, 0x16CF),  /* BMC57312 */
> @@ -78,7 +71,8 @@ static const struct {
>         CNA(BROADCOM, 0x16EB),  /* BCM57412 NPAR */
>         CNA(BROADCOM, 0x16F0),  /* BCM58730 */
>         CNA(BROADCOM, 0x16F1),  /* BCM57452 */
> -       CNA(BROADCOM, 0xD802)   /* BCM58802 */
> +       CNA(BROADCOM, 0xD802),  /* BCM58802 */
> +       {}
>  };
>
>  static struct ibv_context_ops bnxt_re_cntx_ops = {
> @@ -174,30 +168,6 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
>         }
>  }
>
> -static bool bnxt_re_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[10];
> -       unsigned int vendor, device;
> -       int i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       vendor = strtol(value, NULL, 16);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       device = strtol(value, NULL, 16);
> -
> -       for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
> -               if (vendor == cna_table[i].vendor &&
> -                   device == cna_table[i].device)
> -                       return true;
> -       return false;
> -}
> -
>  static struct verbs_device *
>  bnxt_re_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
> @@ -218,7 +188,7 @@ static const struct verbs_device_ops bnxt_re_dev_ops = {
>         .name = "bnxt_re",
>         .match_min_abi_version = BNXT_RE_ABI_VERSION,
>         .match_max_abi_version = BNXT_RE_ABI_VERSION,
> -       .match_device = bnxt_re_device_match,
> +       .match_table = cna_table,
>         .alloc_device = bnxt_re_device_alloc,
>         .init_context = bnxt_re_init_context,
>         .uninit_context = bnxt_re_uninit_context,
> diff --git a/providers/hfi1verbs/hfiverbs.c b/providers/hfi1verbs/hfiverbs.c
> index 5bb436593517e1..7f8f5714db1630 100644
> --- a/providers/hfi1verbs/hfiverbs.c
> +++ b/providers/hfi1verbs/hfiverbs.c
> @@ -77,16 +77,12 @@
>  #define PCI_DEVICE_ID_HFI_INTEL1               0x24f1
>  #endif
>
> -#define HFI(v, d) \
> -       { .vendor = PCI_VENDOR_ID_##v,                  \
> -         .device = PCI_DEVICE_ID_HFI_##d }
> -
> -static struct {
> -       unsigned                vendor;
> -       unsigned                device;
> -} hca_table[] = {
> +#define HFI(v, d)                                                              \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_HFI_##d, NULL)
> +static const struct verbs_match_ent hca_table[] = {
>         HFI(INTEL, INTEL0),
>         HFI(INTEL, INTEL1),
> +       {}
>  };
>
>  static struct ibv_context_ops hfi1_ctx_ops = {
> @@ -180,31 +176,6 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool hfi1_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char                    value[8];
> -       unsigned                vendor, device;
> -       int                     i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       return true;
> -
> -       return false;
> -}
> -
>  static struct verbs_device *hfi1_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct hfi1_device    *dev;
> @@ -222,7 +193,7 @@ static const struct verbs_device_ops hfi1_dev_ops = {
>         .name = "hfi1verbs",
>         .match_min_abi_version = 0,
>         .match_max_abi_version = INT_MAX,
> -       .match_device = hfi1_device_match,
> +       .match_table = hca_table,
>         .alloc_device = hfi1_device_alloc,
>         .uninit_device  = hf11_uninit_device,
>         .alloc_context = hfi1_alloc_context,
> diff --git a/providers/i40iw/i40iw_umain.c b/providers/i40iw/i40iw_umain.c
> index bcba6158e60e40..61c2a92dd6734c 100644
> --- a/providers/i40iw/i40iw_umain.c
> +++ b/providers/i40iw/i40iw_umain.c
> @@ -50,16 +50,8 @@
>  #include <sys/stat.h>
>  #include <fcntl.h>
>
> -#define INTEL_HCA(v, d, t)             \
> -       { .vendor = v,          \
> -         .device = d,          \
> -         .type = INTEL_ ## t }
> -
> -static struct hca_ent {
> -       unsigned int vendor;
> -       unsigned int device;
> -       enum i40iw_uhca_type type;
> -} hca_table[] = {
> +#define INTEL_HCA(v, d, t) VERBS_PCI_MATCH(v, d, (void *)(INTEL_##t))
> +static const struct verbs_match_ent hca_table[] = {
>  #ifdef I40E_DEV_ID_X722_A0
>         INTEL_HCA(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_A0, i40iw),
>  #endif
> @@ -96,6 +88,7 @@ static struct hca_ent {
>  #ifdef I40E_DEV_ID_X722_FPGA_VF
>         INTEL_HCA(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X722_FPGA_VF, i40iw),
>  #endif
> +       {}
>  };
>
>  static struct ibv_context *i40iw_ualloc_context(struct ibv_device *, int);
> @@ -215,48 +208,16 @@ static void i40iw_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -/**
> - * i40iw_driver_init - create device struct and provide callback routines for user context
> - * @uverbs_sys_path: sys path
> - * @abi_version: not used
> - */
> -static bool i40iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[16];
> -       unsigned int vendor, device;
> -       int i;
> -
> -       if ((ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", value, sizeof(value)) < 0) ||
> -           (sscanf(value, "%i", &vendor) != 1))
> -               return false;
> -
> -       if ((ibv_read_sysfs_file(uverbs_sys_path, "device/device", value, sizeof(value)) < 0) ||
> -           (sscanf(value, "%i", &device) != 1))
> -               return false;
> -
> -       for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i) {
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device) {
> -                       sysfs_dev->provider_data = &hca_table[i];
> -                       return true;
> -               }
> -       }
> -
> -       return false;
> -}
> -
>  static struct verbs_device *
>  i40iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct i40iw_udevice *dev;
> -       struct hca_ent *hca_ent = sysfs_dev->provider_data;
>
>         dev = calloc(1, sizeof(*dev));
>         if (!dev)
>                 return NULL;
>
> -       dev->hca_type = hca_ent->type;
> +       dev->hca_type = (uintptr_t)sysfs_dev->match->driver_data;
>         dev->page_size = I40IW_HW_PAGE_SIZE;
>         return &dev->ibv_dev;
>  }
> @@ -265,7 +226,7 @@ static const struct verbs_device_ops i40iw_udev_ops = {
>         .name = "i40iw",
>         .match_min_abi_version = 0,
>         .match_max_abi_version = INT_MAX,
> -       .match_device = i40iw_device_match,
> +       .match_table = hca_table,
>         .alloc_device = i40iw_device_alloc,
>         .uninit_device  = i40iw_uninit_device,
>         .alloc_context = i40iw_ualloc_context,
> diff --git a/providers/ipathverbs/ipathverbs.c b/providers/ipathverbs/ipathverbs.c
> index 3c141263d8ff86..449abb0489955a 100644
> --- a/providers/ipathverbs/ipathverbs.c
> +++ b/providers/ipathverbs/ipathverbs.c
> @@ -73,19 +73,15 @@
>  #define PCI_DEVICE_ID_INFINIPATH_7322          0x7322
>  #endif
>
> -#define HCA(v, d) \
> -       { .vendor = PCI_VENDOR_ID_##v,                  \
> -         .device = PCI_DEVICE_ID_INFINIPATH_##d }
> -
> -static struct {
> -       unsigned                vendor;
> -       unsigned                device;
> -} hca_table[] = {
> +#define HCA(v, d)                                                              \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_INFINIPATH_##d, NULL)
> +static const struct verbs_match_ent hca_table[] = {
>         HCA(PATHSCALE,  HT),
>         HCA(PATHSCALE,  PE800),
>         HCA(QLOGIC,     6220),
>         HCA(QLOGIC,     7220),
>         HCA(QLOGIC,     7322),
> +       {}
>  };
>
>  static struct ibv_context_ops ipath_ctx_ops = {
> @@ -179,31 +175,6 @@ static void ipath_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool ipath_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char                    value[8];
> -       unsigned                vendor, device;
> -       int                     i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       return true;
> -
> -       return false;
> -}
> -
>  static struct verbs_device *
>  ipath_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
> @@ -222,7 +193,7 @@ static const struct verbs_device_ops ipath_dev_ops = {
>         .name = "ipathverbs",
>         .match_min_abi_version = 0,
>         .match_max_abi_version = INT_MAX,
> -       .match_device = ipath_device_match,
> +       .match_table = hca_table,
>         .alloc_device = ipath_device_alloc,
>         .uninit_device  = ipath_uninit_device,
>         .alloc_context = ipath_alloc_context,
> diff --git a/providers/mlx4/mlx4.c b/providers/mlx4/mlx4.c
> index b52684a563b495..6de0bee559e79f 100644
> --- a/providers/mlx4/mlx4.c
> +++ b/providers/mlx4/mlx4.c
> @@ -49,14 +49,8 @@ int mlx4_cleanup_upon_device_fatal = 0;
>  #define PCI_VENDOR_ID_MELLANOX                 0x15b3
>  #endif
>
> -#define HCA(v, d) \
> -       { .vendor = PCI_VENDOR_ID_##v,                  \
> -         .device = d }
> -
> -static struct {
> -       unsigned                vendor;
> -       unsigned                device;
> -} hca_table[] = {
> +#define HCA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
> +static const struct verbs_match_ent hca_table[] = {
>         HCA(MELLANOX, 0x6340),  /* MT25408 "Hermon" SDR */
>         HCA(MELLANOX, 0x634a),  /* MT25408 "Hermon" DDR */
>         HCA(MELLANOX, 0x6354),  /* MT25408 "Hermon" QDR */
> @@ -84,6 +78,7 @@ static struct {
>         HCA(MELLANOX, 0x100e),  /* MT27551 Family */
>         HCA(MELLANOX, 0x100f),  /* MT27560 Family */
>         HCA(MELLANOX, 0x1010),  /* MT27561 Family */
> +       {}
>  };
>
>  static struct ibv_context_ops mlx4_ctx_ops = {
> @@ -286,31 +281,6 @@ static void mlx4_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool mlx4_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char                    value[8];
> -       unsigned                vendor, device;
> -       int                     i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof value) < 0)
> -               return false;
> -       vendor = strtol(value, NULL, 16);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof value) < 0)
> -               return false;
> -       device = strtol(value, NULL, 16);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       return true;
> -
> -       return false;
> -}
> -
>  static struct verbs_device *mlx4_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct mlx4_device *dev;
> @@ -333,7 +303,7 @@ static const struct verbs_device_ops mlx4_dev_ops = {
>         .name = "mlx4",
>         .match_min_abi_version = MLX4_UVERBS_MIN_ABI_VERSION,
>         .match_max_abi_version = MLX4_UVERBS_MAX_ABI_VERSION,
> -       .match_device = mlx4_device_match,
> +       .match_table = hca_table,
>         .alloc_device = mlx4_device_alloc,
>         .uninit_device = mlx4_uninit_device,
>         .init_context = mlx4_init_context,
> diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
> index 44cfd97b73cbbb..15f258dfca7387 100644
> --- a/providers/mlx5/mlx5.c
> +++ b/providers/mlx5/mlx5.c
> @@ -59,15 +59,8 @@
>  #define CPU_EQUAL(x, y) 1
>  #endif
>
> -
> -#define HCA(v, d) \
> -       { .vendor = PCI_VENDOR_ID_##v,                  \
> -         .device = d }
> -
> -static struct {
> -       unsigned                vendor;
> -       unsigned                device;
> -} hca_table[] = {
> +#define HCA(v, d) VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, NULL)
> +static const struct verbs_match_ent hca_table[] = {
>         HCA(MELLANOX, 0x1011),  /* MT4113 Connect-IB */
>         HCA(MELLANOX, 0x1012),  /* Connect-IB Virtual Function */
>         HCA(MELLANOX, 0x1013),  /* ConnectX-4 */
> @@ -82,6 +75,7 @@ static struct {
>         HCA(MELLANOX, 0x101c),  /* ConnectX-6 VF */
>         HCA(MELLANOX, 0xa2d2),  /* BlueField integrated ConnectX-5 network controller */
>         HCA(MELLANOX, 0xa2d3),  /* BlueField integrated ConnectX-5 network controller VF */
> +       {}
>  };
>
>  uint32_t mlx5_debug_mask = 0;
> @@ -1026,30 +1020,6 @@ static void mlx5_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool mlx5_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char                    value[8];
> -       unsigned                vendor, device;
> -       int                     i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       return true;
> -       return false;
> -}
> -
>  static struct verbs_device *mlx5_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct mlx5_device *dev;
> @@ -1072,7 +1042,7 @@ static const struct verbs_device_ops mlx5_dev_ops = {
>         .name = "mlx5",
>         .match_min_abi_version = MLX5_UVERBS_MIN_ABI_VERSION,
>         .match_max_abi_version = MLX5_UVERBS_MAX_ABI_VERSION,
> -       .match_device = mlx5_device_match,
> +       .match_table = hca_table,
>         .alloc_device = mlx5_device_alloc,
>         .uninit_device = mlx5_uninit_device,
>         .init_context = mlx5_init_context,
> diff --git a/providers/mthca/mthca.c b/providers/mthca/mthca.c
> index 521e5b9afe4f2b..511b8d5139af9c 100644
> --- a/providers/mthca/mthca.c
> +++ b/providers/mthca/mthca.c
> @@ -72,16 +72,10 @@
>  #define PCI_VENDOR_ID_TOPSPIN                  0x1867
>  #endif
>
> -#define HCA(v, d, t) \
> -       { .vendor = PCI_VENDOR_ID_##v,                  \
> -         .device = PCI_DEVICE_ID_MELLANOX_##d,         \
> -         .type = MTHCA_##t }
> -
> -static struct hca_ent {
> -       unsigned                vendor;
> -       unsigned                device;
> -       enum mthca_hca_type     type;
> -} hca_table[] = {
> +#define HCA(v, d, t)                                                           \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_MELLANOX_##d,         \
> +                       (void *)(MTHCA_##t))
> +static const struct verbs_match_ent hca_table[] = {
>         HCA(MELLANOX, TAVOR,        TAVOR),
>         HCA(MELLANOX, ARBEL_COMPAT, TAVOR),
>         HCA(MELLANOX, ARBEL,        ARBEL),
> @@ -92,6 +86,7 @@ static struct hca_ent {
>         HCA(TOPSPIN,  ARBEL,        ARBEL),
>         HCA(TOPSPIN,  SINAI_OLD,    ARBEL),
>         HCA(TOPSPIN,  SINAI,        ARBEL),
> +       {}
>  };
>
>  static struct ibv_context_ops mthca_ctx_ops = {
> @@ -216,44 +211,16 @@ static void mthca_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool mthca_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char                    value[8];
> -       unsigned                vendor, device;
> -       int                     i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof value) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device) {
> -                       sysfs_dev->provider_data = &hca_table[i];
> -                       return true;
> -               }
> -
> -       return false;
> -}
> -
>  static struct verbs_device *
>  mthca_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct mthca_device    *dev;
> -       struct hca_ent *hca_ent = sysfs_dev->provider_data;
>
>         dev = calloc(1, sizeof(*dev));
>         if (!dev)
>                 return NULL;
>
> -       dev->hca_type    = hca_ent->type;
> +       dev->hca_type    = (uintptr_t)sysfs_dev->match->driver_data;
>         dev->page_size   = sysconf(_SC_PAGESIZE);
>
>         return &dev->ibv_dev;
> @@ -263,7 +230,7 @@ static const struct verbs_device_ops mthca_dev_ops = {
>         .name = "mthca",
>         .match_min_abi_version = 0,
>         .match_max_abi_version = MTHCA_UVERBS_ABI_VERSION,
> -       .match_device = mthca_device_match,
> +       .match_table = hca_table,
>         .alloc_device = mthca_device_alloc,
>         .uninit_device = mthca_uninit_device,
>         .alloc_context = mthca_alloc_context,
> diff --git a/providers/nes/nes_umain.c b/providers/nes/nes_umain.c
> index fc021a9196b6ad..fd3d19def399b2 100644
> --- a/providers/nes/nes_umain.c
> +++ b/providers/nes/nes_umain.c
> @@ -55,18 +55,12 @@ long int page_size;
>  #define PCI_VENDOR_ID_NETEFFECT                0x1678
>  #endif
>
> -#define HCA(v, d, t)                            \
> -       { .vendor = PCI_VENDOR_ID_##v,              \
> -         .device = d,    \
> -         .type = NETEFFECT_##t }
> -
> -static struct hca_ent {
> -       unsigned vendor;
> -       unsigned device;
> -       enum nes_uhca_type type;
> -} hca_table[] = {
> +#define HCA(v, d, t)                                                           \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, d, (void *)(NETEFFECT_##t))
> +static const struct verbs_match_ent hca_table[] = {
>         HCA(NETEFFECT, 0x0100, nes),
>         HCA(NETEFFECT, 0x0110, nes),
> +       {},
>  };
>
>  static struct ibv_context *nes_ualloc_context(struct ibv_device *, int);
> @@ -191,38 +185,10 @@ static void nes_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool nes_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[16];
> -       unsigned vendor, device;
> -       int i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                       value, sizeof(value)) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                       value, sizeof(value)) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device) {
> -                       sysfs_dev->provider_data = &hca_table[i];
> -                       return true;
> -               }
> -
> -       return false;
> -}
> -
>  static struct verbs_device *
>  nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct nes_udevice *dev;
> -       struct hca_ent *hca_ent = sysfs_dev->provider_data;
>         char value[16];
>
>         if (ibv_read_sysfs_file("/sys/module/iw_nes", "parameters/debug_level",
> @@ -237,7 +203,7 @@ nes_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>         if (!dev)
>                 return NULL;
>
> -       dev->hca_type = hca_ent->type;
> +       dev->hca_type = (uintptr_t)sysfs_dev->match->driver_data;
>         dev->page_size = sysconf(_SC_PAGESIZE);
>
>         nes_debug(NES_DBG_INIT, "libnes initialized\n");
> @@ -249,7 +215,7 @@ static const struct verbs_device_ops nes_udev_ops = {
>         .name = "nes",
>         .match_min_abi_version = 0,
>         .match_max_abi_version = INT_MAX,
> -       .match_device = nes_device_match,
> +       .match_table = hca_table,
>         .alloc_device = nes_device_alloc,
>         .uninit_device = nes_uninit_device,
>         .alloc_context = nes_ualloc_context,
> diff --git a/providers/ocrdma/ocrdma_main.c b/providers/ocrdma/ocrdma_main.c
> index f08a49fb73e021..92a5b8a5d1c86c 100644
> --- a/providers/ocrdma/ocrdma_main.c
> +++ b/providers/ocrdma/ocrdma_main.c
> @@ -55,15 +55,13 @@
>  #define PCI_DEVICE_ID_EMULEX_GEN2        0x720
>  #define PCI_DEVICE_ID_EMULEX_GEN2_VF     0x728
>
> -#define UCNA(v, d)                            \
> -       { .vendor = PCI_VENDOR_ID_##v,        \
> -         .device = PCI_DEVICE_ID_EMULEX_##d }
> -
> -static struct {
> -       unsigned vendor;
> -       unsigned device;
> -} ucna_table[] = {
> -       UCNA(EMULEX, GEN1), UCNA(EMULEX, GEN2), UCNA(EMULEX, GEN2_VF)
> +#define UCNA(v, d)                                                             \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_##v, PCI_DEVICE_ID_EMULEX_##d, NULL)
> +static const struct verbs_match_ent ucna_table[] = {
> +       UCNA(EMULEX, GEN1),
> +       UCNA(EMULEX, GEN2),
> +       UCNA(EMULEX, GEN2_VF),
> +       {}
>  };
>
>  static struct ibv_context *ocrdma_alloc_context(struct ibv_device *, int);
> @@ -168,31 +166,6 @@ static void ocrdma_free_context(struct ibv_context *ibctx)
>         free(ctx);
>  }
>
> -static bool ocrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[16];
> -       unsigned vendor, device;
> -       int i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof ucna_table / sizeof ucna_table[0]; ++i) {
> -               if (vendor == ucna_table[i].vendor &&
> -                   device == ucna_table[i].device)
> -                       return true;
> -       }
> -       return false;
> -}
> -
>  static struct verbs_device *
>  ocrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
> @@ -218,7 +191,7 @@ static const struct verbs_device_ops ocrdma_dev_ops = {
>         .name = "ocrdma",
>         .match_min_abi_version = OCRDMA_ABI_VERSION,
>         .match_max_abi_version = OCRDMA_ABI_VERSION,
> -       .match_device = ocrdma_device_match,
> +       .match_table = ucna_table,
>         .alloc_device = ocrdma_device_alloc,
>         .uninit_device = ocrdma_uninit_device,
>         .alloc_context = ocrdma_alloc_context,
> diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
> index 4d1b92f40a413a..1297e8e16acee5 100644
> --- a/providers/qedr/qelr_main.c
> +++ b/providers/qedr/qelr_main.c
> @@ -64,14 +64,9 @@
>  uint32_t qelr_dp_level;
>  uint32_t qelr_dp_module;
>
> -#define QHCA(d)                                        \
> -       { .vendor = PCI_VENDOR_ID_QLOGIC,       \
> -         .device = PCI_DEVICE_ID_QLOGIC_##d }
> -
> -static const struct {
> -       unsigned int vendor;
> -       unsigned int device;
> -} hca_table[] = {
> +#define QHCA(d)                                                                \
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_##d, NULL)
> +static const struct verbs_match_ent hca_table[] = {
>         QHCA(57980S),
>         QHCA(57980S_40),
>         QHCA(57980S_10),
> @@ -82,6 +77,7 @@ static const struct {
>         QHCA(57980S_IOV),
>         QHCA(AH),
>         QHCA(AH_IOV),
> +       {}
>  };
>
>  static struct ibv_context *qelr_alloc_context(struct ibv_device *, int);
> @@ -227,33 +223,6 @@ static void qelr_free_context(struct ibv_context *ibctx)
>         free(ctx);
>  }
>
> -static bool qedr_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[16];
> -       unsigned int vendor, device;
> -       int i;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -
> -       sscanf(value, "%i", &vendor);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -
> -       sscanf(value, "%i", &device);
> -
> -       for (i = 0; i < sizeof(hca_table) / sizeof(hca_table[0]); ++i)
> -               if (vendor == hca_table[i].vendor &&
> -                   device == hca_table[i].device)
> -                       return true;
> -
> -       return false;
> -}
> -
>  static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct qelr_device *dev;
> @@ -269,7 +238,7 @@ static const struct verbs_device_ops qelr_dev_ops = {
>         .name = "qelr",
>         .match_min_abi_version = QELR_ABI_VERSION,
>         .match_max_abi_version = QELR_ABI_VERSION,
> -       .match_device = qedr_device_match,
> +       .match_table = hca_table,
>         .alloc_device = qedr_device_alloc,
>         .uninit_device = qelr_uninit_device,
>         .alloc_context = qelr_alloc_context,
> diff --git a/providers/vmw_pvrdma/pvrdma_main.c b/providers/vmw_pvrdma/pvrdma_main.c
> index 9bcf2ddd172afb..0826629c081018 100644
> --- a/providers/vmw_pvrdma/pvrdma_main.c
> +++ b/providers/vmw_pvrdma/pvrdma_main.c
> @@ -169,28 +169,6 @@ static void pvrdma_uninit_device(struct verbs_device *verbs_device)
>         free(dev);
>  }
>
> -static bool pvrdma_device_match(struct verbs_sysfs_dev *sysfs_dev)
> -{
> -       const char *uverbs_sys_path = sysfs_dev->sysfs_path;
> -       char value[8];
> -       unsigned int vendor_id, device_id;
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       vendor_id = strtol(value, NULL, 16);
> -
> -       if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
> -                               value, sizeof(value)) < 0)
> -               return false;
> -       device_id = strtol(value, NULL, 16);
> -
> -       if (vendor_id != PCI_VENDOR_ID_VMWARE ||
> -           device_id != PCI_DEVICE_ID_VMWARE_PVRDMA)
> -               return false;
> -       return true;
> -}
> -
>  static struct verbs_device *
>  pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
> @@ -206,11 +184,17 @@ pvrdma_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>         return &dev->ibv_dev;
>  }
>
> +static const struct verbs_match_ent hca_table[] = {
> +       VERBS_PCI_MATCH(PCI_VENDOR_ID_VMWARE, PCI_DEVICE_ID_VMWARE_PVRDMA,
> +                       NULL),
> +       {}
> +};
> +
>  static const struct verbs_device_ops pvrdma_dev_ops = {
>         .name = "pvrdma",
>         .match_min_abi_version = PVRDMA_UVERBS_ABI_VERSION,
>         .match_max_abi_version = PVRDMA_UVERBS_ABI_VERSION,
> -       .match_device = pvrdma_device_match,
> +       .match_table = hca_table,
>         .alloc_device = pvrdma_device_alloc,
>         .uninit_device = pvrdma_uninit_device,
>         .alloc_context = pvrdma_alloc_context,
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops
       [not found]             ` <20170924201053.GA31652-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-25 12:52               ` Amrani, Ram
  0 siblings, 0 replies; 31+ messages in thread
From: Amrani, Ram @ 2017-09-25 12:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Devesh Sharma, Steve Wise,
	Mike Marciniszyn, Dennis Dalessandro, Lijun Ou, Wei Hu(Xavier),
	Tatyana Nikolova, Yishai Hadas, Vladimir Sokolovsky, Elior,
	Ariel, Moni Shoua, Adit Ranadive,
	moderated list:HF1 USERSPACE PROVIDER (for hf1.ko),
	open list:IPATH/QIB USERSPACE PROVIDER (for ib_qib.ko),
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA@public.gmane.org

> I changed the series like so:
> 
> diff --git a/providers/qedr/qelr_main.c b/providers/qedr/qelr_main.c
> index 1297e8e16acee5..fa2be455edc93e 100644
> --- a/providers/qedr/qelr_main.c
> +++ b/providers/qedr/qelr_main.c
> @@ -223,7 +223,7 @@ static void qelr_free_context(struct ibv_context *ibctx)
>         free(ctx);
>  }
> 
> -static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> +static struct verbs_device *qelr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  {
>         struct qelr_device *dev;
> 
> @@ -235,11 +235,11 @@ static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
>  }
> 
>  static const struct verbs_device_ops qelr_dev_ops = {
> -       .name = "qelr",
> +       .name = "qedr",
>         .match_min_abi_version = QELR_ABI_VERSION,
>         .match_max_abi_version = QELR_ABI_VERSION,
>         .match_table = hca_table,
> -       .alloc_device = qedr_device_alloc,
> +       .alloc_device = qelr_device_alloc,
>         .uninit_device = qelr_uninit_device,
>         .alloc_context = qelr_alloc_context,
>         .free_context = qelr_free_context,
> 
> Jason

OK, thanks.

Ram

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure
       [not found]             ` <20170924155845.GB14796-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-25 12:52               ` Amrani, Ram
  0 siblings, 0 replies; 31+ messages in thread
From: Amrani, Ram @ 2017-09-25 12:52 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Devesh Sharma,
	Mike Marciniszyn, Dennis Dalessandro, Tatyana Nikolova,
	Yishai Hadas, Vladimir Sokolovsky, Elior, Ariel, Adit Ranadive,
	pv-drivers-pghWNbHTmq7QT0dZR+AlfA

> On Sun, Sep 24, 2017 at 01:29:09PM +0000, Amrani, Ram wrote:
> > >  static struct verbs_device *qedr_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
> > >  {
> > >  	struct qelr_device *dev;
> > > @@ -269,7 +238,7 @@ static const struct verbs_device_ops qelr_dev_ops = {
> > >  	.name = "qelr",
> >
> > Should this be the driver name or the library name?
> > The driver name is qedr and the library name is libqedr. It is usually abbreviated to qelr.
> > I reckon that this should be the driver name (otherwise auto-load will fail?!).
> 
> I will fix all the names, it is confusing as all the other drivers use
> their lib name as prefix..
> 
> The above string is only used for diagnostic prints.
> 
> Jason

Thank you.

Ram

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step
       [not found]     ` <1505855931-4956-4-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
@ 2017-09-26 16:00       ` Yishai Hadas
       [not found]         ` <5a30e4a3-e22c-5d1a-435d-d3c5d94333fd-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
  0 siblings, 1 reply; 31+ messages in thread
From: Yishai Hadas @ 2017-09-26 16:00 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Doug Ledford, Yishai Hadas

On 9/20/2017 12:18 AM, Jason Gunthorpe wrote:
> The match step determines if the provider should bind to the sysfs device,
> and the allocation step creates the verbs_device and cleanly matches the
> uninit_device step which frees it.
> 
> This split makes it simpler to factor out all the duplicated code in the
> match step.
> 
> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> ---
>   libibverbs/driver.h | 21 ++++++++++++++-
>   libibverbs/init.c   | 74 ++++++++++++++++++++++++++++++++++-------------------
>   2 files changed, 68 insertions(+), 27 deletions(-)
> 
> diff --git a/libibverbs/driver.h b/libibverbs/driver.h
> index f9f5cfa2308c2f..397441f49a0e5a 100644
> --- a/libibverbs/driver.h
> +++ b/libibverbs/driver.h
> @@ -40,6 +40,7 @@
>   #include <infiniband/kern-abi.h>
>   #include <ccan/list.h>
>   #include <config.h>
> +#include <stdbool.h>
>   
>   #ifdef __cplusplus
>   #  define BEGIN_C_DECLS extern "C" {
> @@ -95,10 +96,27 @@ struct verbs_qp {
>   	struct verbs_xrcd       *xrcd;
>   };
>   
> +/* A rdma device detected in sysfs */
> +struct verbs_sysfs_dev {
> +	struct list_node entry;
> +	void *provider_data;

It looks as this field isn't used in the series, correct ? if this is 
the case better add when it'll become applicable.

> +	char sysfs_name[IBV_SYSFS_NAME_MAX];
> +	char ibdev_name[IBV_SYSFS_NAME_MAX];
> +	char sysfs_path[IBV_SYSFS_PATH_MAX];
> +	char ibdev_path[IBV_SYSFS_PATH_MAX];
> +	int abi_ver;
> +	struct timespec time_created;
> +};
> +
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step
       [not found]         ` <5a30e4a3-e22c-5d1a-435d-d3c5d94333fd-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
@ 2017-09-27  7:55           ` Leon Romanovsky
       [not found]             ` <20170927075552.GC2297-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
  2017-09-28 15:56           ` Jason Gunthorpe
  1 sibling, 1 reply; 31+ messages in thread
From: Leon Romanovsky @ 2017-09-27  7:55 UTC (permalink / raw)
  To: Yishai Hadas
  Cc: Jason Gunthorpe, linux-rdma-u79uwXL29TY76Z2rM5mHXA, Doug Ledford,
	Yishai Hadas

[-- Attachment #1: Type: text/plain, Size: 1678 bytes --]

On Tue, Sep 26, 2017 at 07:00:16PM +0300, Yishai Hadas wrote:
> On 9/20/2017 12:18 AM, Jason Gunthorpe wrote:
> > The match step determines if the provider should bind to the sysfs device,
> > and the allocation step creates the verbs_device and cleanly matches the
> > uninit_device step which frees it.
> >
> > This split makes it simpler to factor out all the duplicated code in the
> > match step.
> >
> > Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
> > ---
> >   libibverbs/driver.h | 21 ++++++++++++++-
> >   libibverbs/init.c   | 74 ++++++++++++++++++++++++++++++++++-------------------
> >   2 files changed, 68 insertions(+), 27 deletions(-)
> >
> > diff --git a/libibverbs/driver.h b/libibverbs/driver.h
> > index f9f5cfa2308c2f..397441f49a0e5a 100644
> > --- a/libibverbs/driver.h
> > +++ b/libibverbs/driver.h
> > @@ -40,6 +40,7 @@
> >   #include <infiniband/kern-abi.h>
> >   #include <ccan/list.h>
> >   #include <config.h>
> > +#include <stdbool.h>
> >   #ifdef __cplusplus
> >   #  define BEGIN_C_DECLS extern "C" {
> > @@ -95,10 +96,27 @@ struct verbs_qp {
> >   	struct verbs_xrcd       *xrcd;
> >   };
> > +/* A rdma device detected in sysfs */
> > +struct verbs_sysfs_dev {
> > +	struct list_node entry;
> > +	void *provider_data;
>
> It looks as this field isn't used in the series, correct ? if this is the
> case better add when it'll become applicable.

Yishai,

Jason is a little bit overwhelmed now and because this series was posted
long time here and got a lot of Acked-by tags, I would be happy to take it
and move forward. Do you see any issues which he can't fix after this
series merged?

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step
       [not found]             ` <20170927075552.GC2297-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
@ 2017-09-27 13:49               ` Yishai Hadas
  0 siblings, 0 replies; 31+ messages in thread
From: Yishai Hadas @ 2017-09-27 13:49 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Jason Gunthorpe, linux-rdma-u79uwXL29TY76Z2rM5mHXA, Doug Ledford,
	Yishai Hadas

On 9/27/2017 10:55 AM, Leon Romanovsky wrote:
> On Tue, Sep 26, 2017 at 07:00:16PM +0300, Yishai Hadas wrote:
>> On 9/20/2017 12:18 AM, Jason Gunthorpe wrote:
>>> The match step determines if the provider should bind to the sysfs device,
>>> and the allocation step creates the verbs_device and cleanly matches the
>>> uninit_device step which frees it.
>>>
>>> This split makes it simpler to factor out all the duplicated code in the
>>> match step.
>>>
>>> Signed-off-by: Jason Gunthorpe <jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
>>> ---
>>>    libibverbs/driver.h | 21 ++++++++++++++-
>>>    libibverbs/init.c   | 74 ++++++++++++++++++++++++++++++++++-------------------
>>>    2 files changed, 68 insertions(+), 27 deletions(-)
>>>
>>> diff --git a/libibverbs/driver.h b/libibverbs/driver.h
>>> index f9f5cfa2308c2f..397441f49a0e5a 100644
>>> --- a/libibverbs/driver.h
>>> +++ b/libibverbs/driver.h
>>> @@ -40,6 +40,7 @@
>>>    #include <infiniband/kern-abi.h>
>>>    #include <ccan/list.h>
>>>    #include <config.h>
>>> +#include <stdbool.h>
>>>    #ifdef __cplusplus
>>>    #  define BEGIN_C_DECLS extern "C" {
>>> @@ -95,10 +96,27 @@ struct verbs_qp {
>>>    	struct verbs_xrcd       *xrcd;
>>>    };
>>> +/* A rdma device detected in sysfs */
>>> +struct verbs_sysfs_dev {
>>> +	struct list_node entry;
>>> +	void *provider_data;
>>
>> It looks as this field isn't used in the series, correct ? if this is the
>> case better add when it'll become applicable.
> 
> Yishai,
> 
> Jason is a little bit overwhelmed now and because this series was posted
> long time here and got a lot of Acked-by tags, I would be happy to take it
> and move forward. Do you see any issues which he can't fix after this
> series merged?
> 

The above is some cleanup note that can be done later if we want to 
merge the series soon.

Other verbs changes in the series looks fine to me.
Reviewed-by: Yishai Hadas <yishaih-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 00/10] Rework the verb init scheme
       [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
                     ` (9 preceding siblings ...)
  2017-09-19 21:18   ` [PATCH rdma-core 10/10] rxe: Use VERBS_NAME_MATCH to match the rxe device Jason Gunthorpe
@ 2017-09-28 14:03   ` Leon Romanovsky
  10 siblings, 0 replies; 31+ messages in thread
From: Leon Romanovsky @ 2017-09-28 14:03 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1440 bytes --]

On Tue, Sep 19, 2017 at 03:18:41PM -0600, Jason Gunthorpe wrote:
> This changes how verbs providers register with the core and are bound to
> drivers.
>
> The end goal is to have textual a list of 'modalias' that each provider
> supports, similar to the kernel. This list can then ultimately be used to
> demand load the modules instead of loading every module like we do today.
>
> This series does the work to bring all providers to use common code to match
> their supported devices, and provides the core code the supported device
> list. This is done by extending the verbs_driver_ops to include the matching
> information that the driver needs.
>
> Quite a lot of duplicated driver code is removed in the process, and verbs
> startup reads fewer sysfs files.
>
> https://github.com/linux-rdma/rdma-core/pull/214
>
> Jason Gunthorpe (10):
>   verbs: Change verbs_register_driver to accept the ops struct directly
>   cxgb4: Move sysconf up to driver_init
>   verbs: Split init_device into a match and alloc/bind step
>   providers: Use the new match_device and allocate_device ops
>   verbs: Remove the init_device entry point
>   verbs: Provide common code to match providers against kernel devices
>   providers: Use the new common PCI matching infrastructure
>   cxgb: Use the new common PCI matching infrastructure
>   hns: Use the generic modalias matcher
>   rxe: Use VERBS_NAME_MATCH to match the rxe device
>

Thanks, applied.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step
       [not found]         ` <5a30e4a3-e22c-5d1a-435d-d3c5d94333fd-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
  2017-09-27  7:55           ` Leon Romanovsky
@ 2017-09-28 15:56           ` Jason Gunthorpe
  1 sibling, 0 replies; 31+ messages in thread
From: Jason Gunthorpe @ 2017-09-28 15:56 UTC (permalink / raw)
  To: Yishai Hadas
  Cc: linux-rdma-u79uwXL29TY76Z2rM5mHXA, Doug Ledford, Yishai Hadas

On Tue, Sep 26, 2017 at 07:00:16PM +0300, Yishai Hadas wrote:

> >+/* A rdma device detected in sysfs */
> >+struct verbs_sysfs_dev {
> >+	struct list_node entry;
> >+	void *provider_data;
> 
> It looks as this field isn't used in the series, correct ? if this is the
> case better add when it'll become applicable.

Ah, interesting. It is used during the series, but during the series
all the uses get removed and replaced with verbs_match_ent.driver_data
instead.

So it could be dropped at the patch that removes the last use.. I'll
look at that today.

Jason
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2017-09-28 15:56 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-19 21:18 [PATCH rdma-core 00/10] Rework the verb init scheme Jason Gunthorpe
     [not found] ` <1505855931-4956-1-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-19 21:18   ` [PATCH rdma-core 01/10] verbs: Change verbs_register_driver to accept the ops struct directly Jason Gunthorpe
     [not found]     ` <1505855931-4956-2-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-19 21:31       ` Steve Wise
2017-09-25  6:46         ` Devesh Sharma
2017-09-19 21:18   ` [PATCH rdma-core 02/10] cxgb4: Move sysconf up to driver_init Jason Gunthorpe
     [not found]     ` <1505855931-4956-3-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-19 21:23       ` Steve Wise
2017-09-19 21:18   ` [PATCH rdma-core 03/10] verbs: Split init_device into a match and alloc/bind step Jason Gunthorpe
     [not found]     ` <1505855931-4956-4-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-26 16:00       ` Yishai Hadas
     [not found]         ` <5a30e4a3-e22c-5d1a-435d-d3c5d94333fd-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
2017-09-27  7:55           ` Leon Romanovsky
     [not found]             ` <20170927075552.GC2297-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
2017-09-27 13:49               ` Yishai Hadas
2017-09-28 15:56           ` Jason Gunthorpe
2017-09-19 21:18   ` [PATCH rdma-core 04/10] providers: Use the new match_device and allocate_device ops Jason Gunthorpe
     [not found]     ` <1505855931-4956-5-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-19 21:29       ` Steve Wise
2017-09-19 22:32         ` Jason Gunthorpe
2017-09-24 13:44       ` Amrani, Ram
     [not found]         ` <BN3PR07MB257813BD7D36694EBF97BA91F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-09-24 20:10           ` Jason Gunthorpe
     [not found]             ` <20170924201053.GA31652-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-25 12:52               ` Amrani, Ram
2017-09-25  7:41       ` Devesh Sharma
2017-09-19 21:18   ` [PATCH rdma-core 05/10] verbs: Remove the init_device entry point Jason Gunthorpe
2017-09-19 21:18   ` [PATCH rdma-core 06/10] verbs: Provide common code to match providers against kernel devices Jason Gunthorpe
2017-09-19 21:18   ` [PATCH rdma-core 07/10] providers: Use the new common PCI matching infrastructure Jason Gunthorpe
     [not found]     ` <1505855931-4956-8-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-24 13:29       ` Amrani, Ram
     [not found]         ` <BN3PR07MB2578333789DA041401297EC0F8650-EldUQEzkDQfpW3VS/XPqkOFPX92sqiQdvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2017-09-24 15:58           ` Jason Gunthorpe
     [not found]             ` <20170924155845.GB14796-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-25 12:52               ` Amrani, Ram
2017-09-25  7:48       ` Devesh Sharma
2017-09-19 21:18   ` [PATCH rdma-core 08/10] cxgb: " Jason Gunthorpe
     [not found]     ` <1505855931-4956-9-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-19 21:24       ` Steve Wise
2017-09-19 21:18   ` [PATCH rdma-core 09/10] hns: Use the generic modalias matcher Jason Gunthorpe
     [not found]     ` <1505855931-4956-10-git-send-email-jgunthorpe-ePGOBjL8dl3ta4EC/59zMFaTQe2KTcn/@public.gmane.org>
2017-09-20  3:28       ` oulijun
2017-09-19 21:18   ` [PATCH rdma-core 10/10] rxe: Use VERBS_NAME_MATCH to match the rxe device Jason Gunthorpe
2017-09-28 14:03   ` [PATCH rdma-core 00/10] Rework the verb init scheme Leon Romanovsky

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.