1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved. 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef _UVERBS_NAMED_IOCTL_ 7*4882a593Smuzhiyun #define _UVERBS_NAMED_IOCTL_ 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <rdma/uverbs_ioctl.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef UVERBS_MODULE_NAME 12*4882a593Smuzhiyun #error "Please #define UVERBS_MODULE_NAME before including rdma/uverbs_named_ioctl.h" 13*4882a593Smuzhiyun #endif 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define _UVERBS_PASTE(x, y) x ## y 16*4882a593Smuzhiyun #define _UVERBS_NAME(x, y) _UVERBS_PASTE(x, y) 17*4882a593Smuzhiyun #define UVERBS_METHOD(id) _UVERBS_NAME(UVERBS_MODULE_NAME, _method_##id) 18*4882a593Smuzhiyun #define UVERBS_HANDLER(id) _UVERBS_NAME(UVERBS_MODULE_NAME, _handler_##id) 19*4882a593Smuzhiyun #define UVERBS_OBJECT(id) _UVERBS_NAME(UVERBS_MODULE_NAME, _object_##id) 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* These are static so they do not need to be qualified */ 22*4882a593Smuzhiyun #define UVERBS_METHOD_ATTRS(method_id) _method_attrs_##method_id 23*4882a593Smuzhiyun #define UVERBS_OBJECT_METHODS(object_id) _object_methods_##object_id 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #define DECLARE_UVERBS_NAMED_METHOD(_method_id, ...) \ 26*4882a593Smuzhiyun static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ 27*4882a593Smuzhiyun _method_id)[] = { __VA_ARGS__ }; \ 28*4882a593Smuzhiyun static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ 29*4882a593Smuzhiyun .id = _method_id, \ 30*4882a593Smuzhiyun .handler = UVERBS_HANDLER(_method_id), \ 31*4882a593Smuzhiyun .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ 32*4882a593Smuzhiyun .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ 33*4882a593Smuzhiyun } 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Create a standard destroy method using the default handler. The handle_attr 36*4882a593Smuzhiyun * argument must be the attribute specifying the handle to destroy, the 37*4882a593Smuzhiyun * default handler does not support any other attributes. 38*4882a593Smuzhiyun */ 39*4882a593Smuzhiyun #define DECLARE_UVERBS_NAMED_METHOD_DESTROY(_method_id, _handle_attr) \ 40*4882a593Smuzhiyun static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ 41*4882a593Smuzhiyun _method_id)[] = { _handle_attr }; \ 42*4882a593Smuzhiyun static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ 43*4882a593Smuzhiyun .id = _method_id, \ 44*4882a593Smuzhiyun .handler = uverbs_destroy_def_handler, \ 45*4882a593Smuzhiyun .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ 46*4882a593Smuzhiyun .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ 47*4882a593Smuzhiyun } 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun #define DECLARE_UVERBS_NAMED_OBJECT(_object_id, _type_attrs, ...) \ 50*4882a593Smuzhiyun static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ 51*4882a593Smuzhiyun _object_id)[] = { __VA_ARGS__ }; \ 52*4882a593Smuzhiyun static const struct uverbs_object_def UVERBS_OBJECT(_object_id) = { \ 53*4882a593Smuzhiyun .id = _object_id, \ 54*4882a593Smuzhiyun .type_attrs = &_type_attrs, \ 55*4882a593Smuzhiyun .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ 56*4882a593Smuzhiyun .methods = &UVERBS_OBJECT_METHODS(_object_id) \ 57*4882a593Smuzhiyun } 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun /* 60*4882a593Smuzhiyun * Declare global methods. These still have a unique object_id because we 61*4882a593Smuzhiyun * identify all uapi methods with a (object,method) tuple. However, they have 62*4882a593Smuzhiyun * no type pointer. 63*4882a593Smuzhiyun */ 64*4882a593Smuzhiyun #define DECLARE_UVERBS_GLOBAL_METHODS(_object_id, ...) \ 65*4882a593Smuzhiyun static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ 66*4882a593Smuzhiyun _object_id)[] = { __VA_ARGS__ }; \ 67*4882a593Smuzhiyun static const struct uverbs_object_def UVERBS_OBJECT(_object_id) = { \ 68*4882a593Smuzhiyun .id = _object_id, \ 69*4882a593Smuzhiyun .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ 70*4882a593Smuzhiyun .methods = &UVERBS_OBJECT_METHODS(_object_id) \ 71*4882a593Smuzhiyun } 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* Used by drivers to declare a complete parsing tree for new methods 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun #define ADD_UVERBS_METHODS(_name, _object_id, ...) \ 76*4882a593Smuzhiyun static const struct uverbs_method_def *const UVERBS_OBJECT_METHODS( \ 77*4882a593Smuzhiyun _object_id)[] = { __VA_ARGS__ }; \ 78*4882a593Smuzhiyun static const struct uverbs_object_def _name = { \ 79*4882a593Smuzhiyun .id = _object_id, \ 80*4882a593Smuzhiyun .num_methods = ARRAY_SIZE(UVERBS_OBJECT_METHODS(_object_id)), \ 81*4882a593Smuzhiyun .methods = &UVERBS_OBJECT_METHODS(_object_id) \ 82*4882a593Smuzhiyun }; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* Used by drivers to declare a complete parsing tree for a single method that 85*4882a593Smuzhiyun * differs only in having additional driver specific attributes. 86*4882a593Smuzhiyun */ 87*4882a593Smuzhiyun #define ADD_UVERBS_ATTRIBUTES_SIMPLE(_name, _object_id, _method_id, ...) \ 88*4882a593Smuzhiyun static const struct uverbs_attr_def *const UVERBS_METHOD_ATTRS( \ 89*4882a593Smuzhiyun _method_id)[] = { __VA_ARGS__ }; \ 90*4882a593Smuzhiyun static const struct uverbs_method_def UVERBS_METHOD(_method_id) = { \ 91*4882a593Smuzhiyun .id = _method_id, \ 92*4882a593Smuzhiyun .num_attrs = ARRAY_SIZE(UVERBS_METHOD_ATTRS(_method_id)), \ 93*4882a593Smuzhiyun .attrs = &UVERBS_METHOD_ATTRS(_method_id), \ 94*4882a593Smuzhiyun }; \ 95*4882a593Smuzhiyun ADD_UVERBS_METHODS(_name, _object_id, &UVERBS_METHOD(_method_id)) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun #endif 98