Linux Audio

Check our new training course

Loading...
  1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
  2/*
  3 * Copyright (c) 2017, Mellanox Technologies inc.  All rights reserved.
  4 */
  5
  6#ifndef _UVERBS_STD_TYPES__
  7#define _UVERBS_STD_TYPES__
  8
  9#include <rdma/uverbs_types.h>
 10#include <rdma/uverbs_ioctl.h>
 11#include <rdma/ib_user_ioctl_verbs.h>
 12
 13/* Returns _id, or causes a compile error if _id is not a u32.
 14 *
 15 * The uobj APIs should only be used with the write based uAPI to access
 16 * object IDs. The write API must use a u32 for the object handle, which is
 17 * checked by this macro.
 18 */
 19#define _uobj_check_id(_id) ((_id) * typecheck(u32, _id))
 20
 21#define uobj_get_type(_attrs, _object)                                         \
 22	uapi_get_object((_attrs)->ufile->device->uapi, _object)
 23
 24#define uobj_get_read(_type, _id, _attrs)                                      \
 25	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
 26				_uobj_check_id(_id), UVERBS_LOOKUP_READ,       \
 27				_attrs)
 28
 29#define ufd_get_read(_type, _fdnum, _attrs)                                    \
 30	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
 31				(_fdnum)*typecheck(s32, _fdnum),               \
 32				UVERBS_LOOKUP_READ, _attrs)
 33
 34static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
 35{
 36	if (IS_ERR(uobj))
 37		return NULL;
 38	return uobj->object;
 39}
 40#define uobj_get_obj_read(_object, _type, _id, _attrs)                         \
 41	((struct ib_##_object *)_uobj_get_obj_read(                            \
 42		uobj_get_read(_type, _id, _attrs)))
 43
 44#define uobj_get_write(_type, _id, _attrs)                                     \
 45	rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
 46				_uobj_check_id(_id), UVERBS_LOOKUP_WRITE,      \
 47				_attrs)
 48
 49int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
 50			   struct uverbs_attr_bundle *attrs);
 51#define uobj_perform_destroy(_type, _id, _attrs)                               \
 52	__uobj_perform_destroy(uobj_get_type(_attrs, _type),                   \
 53			       _uobj_check_id(_id), _attrs)
 54
 55struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
 56				      u32 id, struct uverbs_attr_bundle *attrs);
 57
 58#define uobj_get_destroy(_type, _id, _attrs)                                   \
 59	__uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id),  \
 60			   _attrs)
 61
 62static inline void uobj_put_destroy(struct ib_uobject *uobj)
 63{
 64	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_DESTROY);
 65}
 66
 67static inline void uobj_put_read(struct ib_uobject *uobj)
 68{
 69	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_READ);
 70}
 71
 72#define uobj_put_obj_read(_obj)					\
 73	uobj_put_read((_obj)->uobject)
 74
 75static inline void uobj_put_write(struct ib_uobject *uobj)
 76{
 77	rdma_lookup_put_uobject(uobj, UVERBS_LOOKUP_WRITE);
 78}
 79
 80static inline void uobj_alloc_abort(struct ib_uobject *uobj,
 81				    struct uverbs_attr_bundle *attrs)
 82{
 83	rdma_alloc_abort_uobject(uobj, attrs, false);
 84}
 85
 86static inline void uobj_finalize_uobj_create(struct ib_uobject *uobj,
 87					     struct uverbs_attr_bundle *attrs)
 88{
 89	/*
 90	 * Tell the core code that the write() handler has completed
 91	 * initializing the object and that the core should commit or
 92	 * abort this object based upon the return code from the write()
 93	 * method. Similar to what uverbs_finalize_uobj_create() does for
 94	 * ioctl()
 95	 */
 96	WARN_ON(attrs->uobject);
 97	attrs->uobject = uobj;
 98}
 99
100static inline struct ib_uobject *
101__uobj_alloc(const struct uverbs_api_object *obj,
102	     struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
103{
104	struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs);
105
106	if (!IS_ERR(uobj))
107		*ib_dev = attrs->context->device;
108	return uobj;
109}
110
111#define uobj_alloc(_type, _attrs, _ib_dev)                                     \
112	__uobj_alloc(uobj_get_type(_attrs, _type), _attrs, _ib_dev)
113
114static inline void uverbs_flow_action_fill_action(struct ib_flow_action *action,
115						  struct ib_uobject *uobj,
116						  struct ib_device *ib_dev,
117						  enum ib_flow_action_type type)
118{
119	atomic_set(&action->usecnt, 0);
120	action->device = ib_dev;
121	action->type = type;
122	action->uobject = uobj;
123	uobj->object = action;
124}
125
126struct ib_uflow_resources {
127	size_t			max;
128	size_t			num;
129	size_t			collection_num;
130	size_t			counters_num;
131	struct ib_counters	**counters;
132	struct ib_flow_action	**collection;
133};
134
135struct ib_uflow_object {
136	struct ib_uobject		uobject;
137	struct ib_uflow_resources	*resources;
138};
139
140struct ib_uflow_resources *flow_resources_alloc(size_t num_specs);
141void flow_resources_add(struct ib_uflow_resources *uflow_res,
142			enum ib_flow_spec_type type,
143			void *ibobj);
144void ib_uverbs_flow_resources_free(struct ib_uflow_resources *uflow_res);
145
146static inline void ib_set_flow(struct ib_uobject *uobj, struct ib_flow *ibflow,
147			       struct ib_qp *qp, struct ib_device *device,
148			       struct ib_uflow_resources *uflow_res)
149{
150	struct ib_uflow_object *uflow;
151
152	uobj->object = ibflow;
153	ibflow->uobject = uobj;
154
155	if (qp) {
156		atomic_inc(&qp->usecnt);
157		ibflow->qp = qp;
158	}
159
160	ibflow->device = device;
161	uflow = container_of(uobj, typeof(*uflow), uobject);
162	uflow->resources = uflow_res;
163}
164
165struct uverbs_api_object {
166	const struct uverbs_obj_type *type_attrs;
167	const struct uverbs_obj_type_class *type_class;
168	u8 disabled:1;
169	u32 id;
170};
171
172static inline u32 uobj_get_object_id(struct ib_uobject *uobj)
173{
174	return uobj->uapi_object->id;
175}
176
177#endif
178