*/
u8 alloc_and_copy:1;
u8 mandatory:1;
+ /* True if this is from UVERBS_ATTR_UHW */
+ u8 is_udata:1;
union {
struct {
u32 flags;
size_t num_attrs;
const struct uverbs_attr_def * const (*attrs)[];
- int (*handler)(struct ib_uverbs_file *ufile,
- struct uverbs_attr_bundle *ctx);
+ int (*handler)(struct uverbs_attr_bundle *attrs);
};
struct uverbs_object_def {
u16 object_id;
} object_start;
struct {
- u8 is_ex;
u16 command_num;
+ u8 is_ex:1;
+ u8 has_udata:1;
+ u8 has_resp:1;
+ u8 req_size;
+ u8 resp_size;
} write;
};
union {
bool (*func_is_supported)(struct ib_device *device);
- ssize_t (*func_write)(struct uverbs_attr_bundle *attrs,
- const char __user *buf, int in_len,
- int out_len);
- int (*func_write_ex)(struct uverbs_attr_bundle *attrs,
- struct ib_udata *ucore,
- struct ib_udata *uhw);
+ int (*func_write)(struct uverbs_attr_bundle *attrs);
const struct uapi_definition *chain;
const struct uverbs_object_def *chain_obj_tree;
size_t needs_fn_offset;
##__VA_ARGS__
/* Use in a var_args of DECLARE_UVERBS_OBJECT */
-#define DECLARE_UVERBS_WRITE(_command_num, _func, ...) \
+#define DECLARE_UVERBS_WRITE(_command_num, _func, _cmd_desc, ...) \
{ \
.kind = UAPI_DEF_WRITE, \
.scope = UAPI_SCOPE_OBJECT, \
.write = { .is_ex = 0, .command_num = _command_num }, \
.func_write = _func, \
+ _cmd_desc, \
}, \
##__VA_ARGS__
/* Use in a var_args of DECLARE_UVERBS_OBJECT */
-#define DECLARE_UVERBS_WRITE_EX(_command_num, _func, ...) \
+#define DECLARE_UVERBS_WRITE_EX(_command_num, _func, _cmd_desc, ...) \
{ \
.kind = UAPI_DEF_WRITE, \
.scope = UAPI_SCOPE_OBJECT, \
.write = { .is_ex = 1, .command_num = _command_num }, \
- .func_write_ex = _func, \
+ .func_write = _func, \
+ _cmd_desc, \
}, \
##__VA_ARGS__
.kind = UAPI_DEF_IS_SUPPORTED_DEV_FN, \
.scope = UAPI_SCOPE_OBJECT, \
.needs_fn_offset = \
- offsetof(struct ib_device, ibdev_fn) + \
+ offsetof(struct ib_device_ops, ibdev_fn) + \
BUILD_BUG_ON_ZERO( \
- sizeof(((struct ib_device *)0)->ibdev_fn) != \
- sizeof(void *)), \
+ sizeof(((struct ib_device_ops *)0)->ibdev_fn) != \
+ sizeof(void *)), \
}
/*
.kind = UAPI_DEF_IS_SUPPORTED_DEV_FN, \
.scope = UAPI_SCOPE_METHOD, \
.needs_fn_offset = \
- offsetof(struct ib_device, ibdev_fn) + \
+ offsetof(struct ib_device_ops, ibdev_fn) + \
BUILD_BUG_ON_ZERO( \
- sizeof(((struct ib_device *)0)->ibdev_fn) != \
- sizeof(void *)), \
+ sizeof(((struct ib_device_ops *)0)->ibdev_fn) != \
+ sizeof(void *)), \
}
/* Call a function to determine if the entire object is supported or not */
}
/* Temporary until the tree base description is replaced */
-#define UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, _object_ptr) \
+#define UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, _object_ptr, ...) \
{ \
.kind = UAPI_DEF_CHAIN_OBJ_TREE, \
.object_start = { .object_id = _object_enum }, \
.chain_obj_tree = _object_ptr, \
- }
-#define UAPI_DEF_CHAIN_OBJ_TREE_NAMED(_object_enum, ...) \
- UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, &UVERBS_OBJECT(_object_enum)), \
+ }, \
##__VA_ARGS__
+#define UAPI_DEF_CHAIN_OBJ_TREE_NAMED(_object_enum, ...) \
+ UAPI_DEF_CHAIN_OBJ_TREE(_object_enum, &UVERBS_OBJECT(_object_enum), \
+ ##__VA_ARGS__)
/*
* =======================================
.u2.objs_arr.max_len = _max_len, \
__VA_ARGS__ } })
+/*
+ * Only for use with UVERBS_ATTR_IDR, allows any uobject type to be accepted,
+ * the user must validate the type of the uobject instead.
+ */
+#define UVERBS_IDR_ANY_OBJECT 0xFFFF
+
#define UVERBS_ATTR_IDR(_attr_id, _idr_type, _access, ...) \
(&(const struct uverbs_attr_def){ \
.id = _attr_id, \
#define UVERBS_ATTR_UHW() \
UVERBS_ATTR_PTR_IN(UVERBS_ATTR_UHW_IN, \
UVERBS_ATTR_MIN_SIZE(0), \
- UA_OPTIONAL), \
+ UA_OPTIONAL, \
+ .is_udata = 1), \
UVERBS_ATTR_PTR_OUT(UVERBS_ATTR_UHW_OUT, \
UVERBS_ATTR_MIN_SIZE(0), \
- UA_OPTIONAL)
+ UA_OPTIONAL, \
+ .is_udata = 1)
/* =================================================
* Parsing infrastructure
};
struct uverbs_attr_bundle {
+ struct ib_udata driver_udata;
+ struct ib_udata ucore;
struct ib_uverbs_file *ufile;
DECLARE_BITMAP(attr_present, UVERBS_API_ATTR_BKEY_LEN);
struct uverbs_attr attrs[];
return attr->ptr_attr.len;
}
+/*
+ * uverbs_attr_ptr_get_array_size() - Get array size pointer by a ptr
+ * attribute.
+ * @attrs: The attribute bundle
+ * @idx: The ID of the attribute
+ * @elem_size: The size of the element in the array
+ */
+static inline int
+uverbs_attr_ptr_get_array_size(struct uverbs_attr_bundle *attrs, u16 idx,
+ size_t elem_size)
+{
+ int size = uverbs_attr_get_len(attrs, idx);
+
+ if (size < 0)
+ return size;
+
+ if (size % elem_size)
+ return -EINVAL;
+
+ return size / elem_size;
+}
+
/**
* uverbs_attr_get_uobjs_arr() - Provides array's properties for attribute for
* UVERBS_ATTR_TYPE_IDRS_ARRAY.
int _uverbs_get_const(s64 *to, const struct uverbs_attr_bundle *attrs_bundle,
size_t idx, s64 lower_bound, u64 upper_bound,
s64 *def_val);
+int uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
+ size_t idx, const void *from, size_t size);
#else
static inline int
uverbs_get_flags64(u64 *to, const struct uverbs_attr_bundle *attrs_bundle,
{
return -EINVAL;
}
+static inline int
+uverbs_copy_to_struct_or_zero(const struct uverbs_attr_bundle *bundle,
+ size_t idx, const void *from, size_t size)
+{
+ return -EINVAL;
+}
#endif
#define uverbs_get_const(_to, _attrs_bundle, _idx) \