@@ -617,12 +617,19 @@ struct ibv_device {
enum ibv_transport_type transport_type;
/* Name of underlying kernel IB device, eg "mthca0" */
char name[IBV_SYSFS_NAME_MAX];
+ /*
+ * Support for extended operations is recorded at the end of
+ * the name character array.
+ */
+#define ext_ops_supported name[IBV_SYSFS_NAME_MAX - 1]
/* Name of uverbs device, eg "uverbs0" */
char dev_name[IBV_SYSFS_NAME_MAX];
/* Path to infiniband_verbs class device in sysfs */
char dev_path[IBV_SYSFS_PATH_MAX];
/* Path to infiniband class device in sysfs */
char ibdev_path[IBV_SYSFS_PATH_MAX];
+ int (*have_ext_ops)(char *ext_name);
+ void * (*get_ext_device_ops)(char *ext_name);
};
struct ibv_context_ops {
@@ -683,6 +690,14 @@ struct ibv_context_ops {
void (*async_event)(struct ibv_async_event *event);
};
+#define IBV_XRC_OPS "ibv_xrc"
+
+struct ibv_xrc_ops {
+ struct ibv_xrcd (*open_xrcd)();
+ int (*close_xrcd)();
+ struct ibv_src (*create_srq)();
+};
+
struct ibv_context {
struct ibv_device *device;
struct ibv_context_ops ops;
@@ -691,6 +706,7 @@ struct ibv_context {
int num_comp_vectors;
pthread_mutex_t mutex;
void *abi_compat;
+ void * (*get_ext_ops)(char *ext_name);
};
/**
@@ -724,6 +740,17 @@ const char *ibv_get_device_name(struct ibv_device *device);
uint64_t ibv_get_device_guid(struct ibv_device *device);
/**
+ * ibv_have_ext_ops - Return true if device supports the requested
+ * extended operations.
+ */
+int ibv_have_ext_ops(struct ibv_device *device, const char *name);
+
+/**
+ * ibv_get_device_ext_ops - Return extended operations.
+ */
+void *ibv_get_device_ext_ops(struct ibv_device *device, const char *name);
+
+/**
* ibv_open_device - Initialize device for use
*/
struct ibv_context *ibv_open_device(struct ibv_device *device);
@@ -734,6 +761,11 @@ struct ibv_context *ibv_open_device(struct ibv_device *device);
int ibv_close_device(struct ibv_context *context);
/**
+ * ibv_get_ext_ops - Return extended operations.
+ */
+void *ibv_get_ext_ops(struct ibv_context *context, const char *name);
+
+/**
* ibv_get_async_event - Get next async event
* @event: Pointer to use to return async event
*
@@ -181,6 +181,24 @@ int __ibv_close_device(struct ibv_context *context)
}
default_symver(__ibv_close_device, ibv_close_device);
+int __ibv_have_ext_ops(struct ibv_device *device, const char *name)
+{
+ if (!device->ext_ops_supported)
+ return ENOSYS;
+
+ return device->have_ext_ops(device, name);
+}
+default_symver(__ibv_have_ext_ops, ibv_have_ext_ops);
+
+void *__ibv_get_device_ext_ops(struct ibv_device *device, const char *name)
+{
+ if (!device->ext_ops_supported)
+ return NULL;
+
+ return device->get_device_ext_ops(device, name);
+}
+default_symver(__ibv_get_device_ext_ops, ibv_get_device_ext_ops);
+
int __ibv_get_async_event(struct ibv_context *context,
struct ibv_async_event *event)
{
@@ -71,6 +71,7 @@ struct ibv_driver {
const char *name;
ibv_driver_init_func init_func;
struct ibv_driver *next;
+ int ext_ops_supported;
};
static struct ibv_sysfs_dev *sysfs_dev_list;
@@ -153,7 +154,8 @@ static int find_sysfs_devs(void)
return ret;
}
-void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
+void ibv_register_driver_ext(const char *name, ibv_driver_init_func init_func,
+ int ext_ops_supported)
{
struct ibv_driver *driver;
@@ -174,6 +176,11 @@ void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
tail_driver = driver;
}
+void ibv_register_driver(const char *name, ibv_driver_init_func init_func)
+{
+ ibv_register_driver_ext(name, init_func, 0);
+}
+
static void load_driver(const char *name)
{
char *so_name;
@@ -368,6 +375,9 @@ static struct ibv_device *try_driver(struct ibv_driver *driver,
strcpy(dev->name, sysfs_dev->ibdev_name);
strcpy(dev->ibdev_path, sysfs_dev->ibdev_path);
+ if (strlen(dev->name) < sizeof(dev->name))
+ dev->ext_ops_supported = driver->ext_ops_supported;
+
return dev;
}
@@ -96,4 +96,9 @@ IBVERBS_1.1 {
ibv_port_state_str;
ibv_event_type_str;
ibv_wc_status_str;
+
+ ibv_register_driver_ext;
+ ibv_have_ext_ops;
+ ibv_get_device_ext_ops;
+ ibv_get_ext_ops;
} IBVERBS_1.0;
@@ -76,6 +76,15 @@ enum ibv_rate mult_to_ibv_rate(int mult)
}
}
+void *__ibv_get_ext_ops(struct ibv_context *context, const char *name)
+{
+ if (!context->device->ext_ops_supported)
+ return NULL;
+
+ return context->get_ext_ops(context, name);
+}
+default_symver(__ibv_get_ext_ops, ibv_get_ext_ops);
+
int __ibv_query_device(struct ibv_context *context,
struct ibv_device_attr *device_attr)
{