@@ -36,6 +36,7 @@
#include <rdma/uverbs_types.h>
#include <linux/rcupdate.h>
#include <rdma/uverbs_ioctl.h>
+#include <rdma/ib_user_ioctl_verbs.h>
#include "uverbs.h"
#include "core_priv.h"
#include "rdma_core.h"
@@ -209,6 +209,45 @@ static int uverbs_hot_unplug_completion_event_file(struct ib_uobject_file *uobj_
return 0;
};
+/*
+ * This spec is used in order to pass information to the hardware driver in a
+ * legacy way. Every verb that could get driver specific data should get this
+ * spec.
+ */
+static DECLARE_UVERBS_ATTR_SPEC(
+ uverbs_uhw_compat_spec,
+ UVERBS_ATTR_PTR_IN_SZ(UVERBS_UHW_IN, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ)),
+ UVERBS_ATTR_PTR_OUT_SZ(UVERBS_UHW_OUT, 0, UA_FLAGS(UVERBS_ATTR_SPEC_F_MIN_SZ)));
+
+static void create_udata(struct uverbs_attr_array *ctx, size_t num,
+ struct ib_udata *udata)
+{
+ /*
+ * This is for ease of conversion. The purpose is to convert all drivers
+ * to use uverbs_attr_array instead of ib_udata.
+ * Assume attr == 0 is input and attr == 1 is output.
+ */
+ void __user *inbuf;
+ size_t inbuf_len = 0;
+ void __user *outbuf;
+ size_t outbuf_len = 0;
+
+ if (num > UVERBS_UDATA_DRIVER_DATA_GROUP) {
+ struct uverbs_attr_array *driver = &ctx[UVERBS_UDATA_DRIVER_DATA_GROUP];
+
+ if (uverbs_is_valid(driver, UVERBS_UHW_IN)) {
+ inbuf = driver->attrs[UVERBS_UHW_IN].ptr_attr.ptr;
+ inbuf_len = driver->attrs[UVERBS_UHW_IN].ptr_attr.len;
+ }
+
+ if (driver->num_attrs >= UVERBS_UHW_OUT &&
+ uverbs_is_valid(driver, UVERBS_UHW_OUT)) {
+ outbuf = driver->attrs[UVERBS_UHW_OUT].ptr_attr.ptr;
+ outbuf_len = driver->attrs[UVERBS_UHW_OUT].ptr_attr.len;
+ }
+ }
+ INIT_UDATA_BUF_OR_NULL(udata, inbuf, outbuf, inbuf_len, outbuf_len);
+}
DECLARE_UVERBS_TYPE(uverbs_type_comp_channel,
&UVERBS_TYPE_ALLOC_FD(0,
sizeof(struct ib_uverbs_completion_event_file),
@@ -46,9 +46,6 @@
* =======================================
*/
-#define UVERBS_ID_GROUP_MASK 0xF000
-#define UVERBS_ID_GROUP_SHIFT 12
-
enum uverbs_attr_type {
UVERBS_ATTR_TYPE_NA,
UVERBS_ATTR_TYPE_PTR_IN,
@@ -33,6 +33,11 @@
#ifndef IB_USER_IOCTL_VERBS_H
#define IB_USER_IOCTL_VERBS_H
+#define UVERBS_ID_GROUP_MASK 0xF000
+#define UVERBS_ID_GROUP_SHIFT 12
+#define UVERBS_UDATA_DRIVER_DATA_GROUP 1
+#define UVERBS_UDATA_DRIVER_DATA_FLAG (1UL << UVERBS_ID_GROUP_SHIFT)
+
enum uverbs_common_types {
UVERBS_TYPE_DEVICE, /* No instances of DEVICE are allowed */
UVERBS_TYPE_PD,
@@ -50,5 +55,10 @@ enum uverbs_common_types {
UVERBS_TYPE_LAST,
};
+enum {
+ UVERBS_UHW_IN,
+ UVERBS_UHW_OUT,
+};
+
#endif