0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef RDMA_CORE_H
0038 #define RDMA_CORE_H
0039
0040 #include <linux/idr.h>
0041 #include <rdma/uverbs_types.h>
0042 #include <rdma/uverbs_ioctl.h>
0043 #include <rdma/ib_verbs.h>
0044 #include <linux/mutex.h>
0045
0046 struct ib_uverbs_device;
0047
0048 void uverbs_destroy_ufile_hw(struct ib_uverbs_file *ufile,
0049 enum rdma_remove_reason reason);
0050
0051 int uobj_destroy(struct ib_uobject *uobj, struct uverbs_attr_bundle *attrs);
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062 struct ib_uobject *
0063 uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
0064 s64 id, struct uverbs_attr_bundle *attrs);
0065
0066 void uverbs_finalize_object(struct ib_uobject *uobj,
0067 enum uverbs_obj_access access, bool hw_obj_valid,
0068 bool commit, struct uverbs_attr_bundle *attrs);
0069
0070 int uverbs_output_written(const struct uverbs_attr_bundle *bundle, size_t idx);
0071
0072 void setup_ufile_idr_uobject(struct ib_uverbs_file *ufile);
0073 void release_ufile_idr_uobject(struct ib_uverbs_file *ufile);
0074
0075 struct ib_udata *uverbs_get_cleared_udata(struct uverbs_attr_bundle *attrs);
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 struct uverbs_api_ioctl_method {
0088 int(__rcu *handler)(struct uverbs_attr_bundle *attrs);
0089 DECLARE_BITMAP(attr_mandatory, UVERBS_API_ATTR_BKEY_LEN);
0090 u16 bundle_size;
0091 u8 use_stack:1;
0092 u8 driver_method:1;
0093 u8 disabled:1;
0094 u8 has_udata:1;
0095 u8 key_bitmap_len;
0096 u8 destroy_bkey;
0097 };
0098
0099 struct uverbs_api_write_method {
0100 int (*handler)(struct uverbs_attr_bundle *attrs);
0101 u8 disabled:1;
0102 u8 is_ex:1;
0103 u8 has_udata:1;
0104 u8 has_resp:1;
0105 u8 req_size;
0106 u8 resp_size;
0107 };
0108
0109 struct uverbs_api_attr {
0110 struct uverbs_attr_spec spec;
0111 };
0112
0113 struct uverbs_api {
0114
0115 struct radix_tree_root radix;
0116 enum rdma_driver_id driver_id;
0117
0118 unsigned int num_write;
0119 unsigned int num_write_ex;
0120 struct uverbs_api_write_method notsupp_method;
0121 const struct uverbs_api_write_method **write_methods;
0122 const struct uverbs_api_write_method **write_ex_methods;
0123 };
0124
0125
0126
0127
0128
0129
0130 static inline const struct uverbs_api_object *
0131 uapi_get_object(struct uverbs_api *uapi, u16 object_id)
0132 {
0133 const struct uverbs_api_object *res;
0134
0135 if (object_id == UVERBS_IDR_ANY_OBJECT)
0136 return ERR_PTR(-ENOMSG);
0137
0138 res = radix_tree_lookup(&uapi->radix, uapi_key_obj(object_id));
0139 if (!res)
0140 return ERR_PTR(-ENOENT);
0141
0142 return res;
0143 }
0144
0145 char *uapi_key_format(char *S, unsigned int key);
0146 struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev);
0147 void uverbs_disassociate_api_pre(struct ib_uverbs_device *uverbs_dev);
0148 void uverbs_disassociate_api(struct uverbs_api *uapi);
0149 void uverbs_destroy_api(struct uverbs_api *uapi);
0150 void uapi_compute_bundle_size(struct uverbs_api_ioctl_method *method_elm,
0151 unsigned int num_attrs);
0152 void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile);
0153
0154 extern const struct uapi_definition uverbs_def_obj_async_fd[];
0155 extern const struct uapi_definition uverbs_def_obj_counters[];
0156 extern const struct uapi_definition uverbs_def_obj_cq[];
0157 extern const struct uapi_definition uverbs_def_obj_device[];
0158 extern const struct uapi_definition uverbs_def_obj_dm[];
0159 extern const struct uapi_definition uverbs_def_obj_flow_action[];
0160 extern const struct uapi_definition uverbs_def_obj_intf[];
0161 extern const struct uapi_definition uverbs_def_obj_mr[];
0162 extern const struct uapi_definition uverbs_def_obj_qp[];
0163 extern const struct uapi_definition uverbs_def_obj_srq[];
0164 extern const struct uapi_definition uverbs_def_obj_wq[];
0165 extern const struct uapi_definition uverbs_def_write_intf[];
0166
0167 static inline const struct uverbs_api_write_method *
0168 uapi_get_method(const struct uverbs_api *uapi, u32 command)
0169 {
0170 u32 cmd_idx = command & IB_USER_VERBS_CMD_COMMAND_MASK;
0171
0172 if (command & ~(u32)(IB_USER_VERBS_CMD_FLAG_EXTENDED |
0173 IB_USER_VERBS_CMD_COMMAND_MASK))
0174 return ERR_PTR(-EINVAL);
0175
0176 if (command & IB_USER_VERBS_CMD_FLAG_EXTENDED) {
0177 if (cmd_idx >= uapi->num_write_ex)
0178 return ERR_PTR(-EOPNOTSUPP);
0179 return uapi->write_ex_methods[cmd_idx];
0180 }
0181
0182 if (cmd_idx >= uapi->num_write)
0183 return ERR_PTR(-EOPNOTSUPP);
0184 return uapi->write_methods[cmd_idx];
0185 }
0186
0187 void uverbs_fill_udata(struct uverbs_attr_bundle *bundle,
0188 struct ib_udata *udata, unsigned int attr_in,
0189 unsigned int attr_out);
0190
0191 #endif