typedef struct ibv_device *(*ibv_driver_init_func)(const char *uverbs_sys_path,
int abi_version);
+typedef struct verbs_device *(*verbs_driver_init_func)(const char *uverbs_sys_path,
+ int abi_version);
void ibv_register_driver(const char *name, ibv_driver_init_func init_func);
-void verbs_register_driver(const char *name, ibv_driver_init_func init_func);
+void verbs_register_driver(const char *name, verbs_driver_init_func init_func);
int ibv_cmd_get_context(struct ibv_context *context, struct ibv_get_context *cmd,
size_t cmd_size, struct ibv_get_context_resp *resp,
size_t resp_size);
static inline struct verbs_context *verbs_get_ctx(
const struct ibv_context *ctx)
{
- if (ctx->abi_compat != ((uint8_t *)NULL)-1)
- return NULL;
-
- return container_of(ctx, struct verbs_context, context);
+ return (ctx->abi_compat != ((uint8_t *) NULL) - 1) ?
+ NULL : container_of(ctx, struct verbs_context, context);
}
static inline struct verbs_device *verbs_get_device(
const struct ibv_device *dev)
{
- return container_of(dev, struct verbs_device, device);
+ return (dev->ops.alloc_context) ?
+ NULL : container_of(dev, struct verbs_device, device);
}
/**
struct ibv_context *__ibv_open_device(struct ibv_device *device)
{
+ struct verbs_device *verbs_device = verbs_get_device(device);
char *devpath;
- int cmd_fd;
+ int cmd_fd, ret;
struct ibv_context *context;
struct verbs_context *context_ex;
if (cmd_fd < 0)
return NULL;
- context = device->ops.alloc_context(device, cmd_fd);
- if (!context)
- goto err;
- if (context == (struct ibv_context *)(((uint8_t *)NULL)-1)) {
- /* New provider that supports verbs extension was detected */
- struct verbs_device *verbs_device =
- verbs_get_device(device);
- int ret;
-
+ if (!verbs_device) {
+ context = device->ops.alloc_context(device, cmd_fd);
+ if (!context)
+ goto err;
+ } else {
/* Library now allocates the context */
context_ex = calloc(1, sizeof(*context_ex) +
- verbs_device->size_of_context);
-
+ verbs_device->size_of_context);
if (!context_ex) {
errno = ENOMEM;
goto err;
}
- context = &context_ex->context;
- /* Init new verbs_context */
- context_ex->context.abi_compat = ((uint8_t *)NULL)-1;
+
+ context_ex->context.abi_compat = ((uint8_t *) NULL) - 1;
context_ex->sz = sizeof(*context_ex);
- /* Call provider to initialize its calls first */
- ret = verbs_device->init_context(verbs_device,
- &context_ex->context, cmd_fd);
+ context = &context_ex->context;
+ ret = verbs_device->init_context(verbs_device, context; cmd_fd);
if (ret)
goto verbs_err;
+
/* initialize *all* library ops to either lib calls or
- * directly to provider calls.
- context_ex-> lib_new_func1= __verbs_new_func1;
- context_ex-> lib_new_func2= __verbs_new_func2;
- */
+ * directly to provider calls.
+ * context_ex->lib_new_func1 = __verbs_new_func1;
+ * context_ex->lib_new_func2 = __verbs_new_func2;
+ */
}
context->device = device;
free(context_ex);
err:
close(cmd_fd);
-
return NULL;
}
default_symver(__ibv_open_device, ibv_open_device);
context_ex = verbs_get_ctx(context);
if (context_ex) {
- struct verbs_device *verbs_device =
- verbs_get_device(context->device);
- /* Provider supports verbs extension */
+ struct verbs_device *verbs_device = verbs_get_device(context->device);
verbs_device->uninit_context(verbs_device, context);
free(context_ex);
} else
struct ibv_driver {
const char *name;
ibv_driver_init_func init_func;
+ verbs_driver_init_func verbs_init_func;
struct ibv_driver *next;
};
return ret;
}
-void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
+static void register_driver(const char *name, ibv_driver_init_func init_func,
+ verbs_driver_init_func verbs_init_func)
{
struct ibv_driver *driver;
return;
}
- driver->name = name;
- driver->init_func = init_func;
- driver->next = NULL;
+ driver->name = name;
+ driver->init_func = init_func;
+ driver->verbs_init_func = verbs_init_func;
+ driver->next = NULL;
if (tail_driver)
tail_driver->next = driver;
tail_driver = driver;
}
+void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
+{
+ register_driver(name, init_func, NULL);
+}
+
/* New registration symbol with same functionality - used by providers to
* validate that library supports verbs extension.
*/
-void verbs_register_driver(const char *name, ibv_driver_init_func init_func)
+void verbs_register_driver(const char *name, verbs_driver_init_func init_func)
{
- ibv_register_driver(name, init_func);
+ register_driver(name, NULL, init_func);
}
static void load_driver(const char *name)
static struct ibv_device *try_driver(struct ibv_driver *driver,
struct ibv_sysfs_dev *sysfs_dev)
{
+ struct verbs_device *vdev;
struct ibv_device *dev;
char value[8];
- dev = driver->init_func(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
- if (!dev)
- return NULL;
+ if (driver->init_func) {
+ dev = driver->init_func(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
+ if (!dev)
+ return NULL;
+ } else {
+ vdev = driver->verbs_init_func(sysfs_dev->sysfs_path, sysfs_dev->abi_ver);
+ if (!vdev)
+ return NULL;
+
+ dev = &vdev->device;
+ dev->ops.alloc_context = NULL;
+ dev->ops.free_context = NULL;
+ }
if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "node_type", value, sizeof value) < 0) {
fprintf(stderr, PFX "Warning: no node_type attr under %s.\n",