1219820Sjeff/* 2219820Sjeff * Copyright (c) 2005 Topspin Communications. All rights reserved. 3219820Sjeff * Copyright (c) 2005, 2006 Cisco Systems. All rights reserved. 4219820Sjeff * Copyright (c) 2005 Mellanox Technologies. All rights reserved. 5219820Sjeff * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 6219820Sjeff * Copyright (c) 2005 PathScale, Inc. All rights reserved. 7219820Sjeff * 8219820Sjeff * This software is available to you under a choice of one of two 9219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 10219820Sjeff * General Public License (GPL) Version 2, available from the file 11219820Sjeff * COPYING in the main directory of this source tree, or the 12219820Sjeff * OpenIB.org BSD license below: 13219820Sjeff * 14219820Sjeff * Redistribution and use in source and binary forms, with or 15219820Sjeff * without modification, are permitted provided that the following 16219820Sjeff * conditions are met: 17219820Sjeff * 18219820Sjeff * - Redistributions of source code must retain the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer. 21219820Sjeff * 22219820Sjeff * - Redistributions in binary form must reproduce the above 23219820Sjeff * copyright notice, this list of conditions and the following 24219820Sjeff * disclaimer in the documentation and/or other materials 25219820Sjeff * provided with the distribution. 26219820Sjeff * 27219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 31219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 32219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34219820Sjeff * SOFTWARE. 35331772Shselasky * 36331772Shselasky * $FreeBSD: stable/11/sys/ofed/drivers/infiniband/core/uverbs.h 337071 2018-08-02 08:07:10Z hselasky $ 37219820Sjeff */ 38219820Sjeff 39219820Sjeff#ifndef UVERBS_H 40219820Sjeff#define UVERBS_H 41219820Sjeff 42219820Sjeff#include <linux/kref.h> 43219820Sjeff#include <linux/idr.h> 44219820Sjeff#include <linux/mutex.h> 45219820Sjeff#include <linux/completion.h> 46278886Shselasky#include <linux/cdev.h> 47331769Shselasky#include <linux/srcu.h> 48331769Shselasky#include <linux/rcupdate.h> 49278886Shselasky#include <linux/rbtree.h> 50219820Sjeff 51219820Sjeff#include <rdma/ib_verbs.h> 52219820Sjeff#include <rdma/ib_umem.h> 53219820Sjeff#include <rdma/ib_user_verbs.h> 54219820Sjeff 55331769Shselasky#define INIT_UDATA(udata, ibuf, obuf, ilen, olen) \ 56331769Shselasky do { \ 57331769Shselasky (udata)->inbuf = (const void __user *) (ibuf); \ 58331769Shselasky (udata)->outbuf = (void __user *) (obuf); \ 59331769Shselasky (udata)->inlen = (ilen); \ 60331769Shselasky (udata)->outlen = (olen); \ 61331769Shselasky } while (0) 62331769Shselasky 63331769Shselasky#define INIT_UDATA_BUF_OR_NULL(udata, ibuf, obuf, ilen, olen) \ 64331769Shselasky do { \ 65331769Shselasky (udata)->inbuf = (ilen) ? (const void __user *) (ibuf) : NULL; \ 66331769Shselasky (udata)->outbuf = (olen) ? (void __user *) (obuf) : NULL; \ 67331769Shselasky (udata)->inlen = (ilen); \ 68331769Shselasky (udata)->outlen = (olen); \ 69331769Shselasky } while (0) 70331769Shselasky 71219820Sjeff/* 72219820Sjeff * Our lifetime rules for these structs are the following: 73219820Sjeff * 74219820Sjeff * struct ib_uverbs_device: One reference is held by the module and 75219820Sjeff * released in ib_uverbs_remove_one(). Another reference is taken by 76219820Sjeff * ib_uverbs_open() each time the character special file is opened, 77219820Sjeff * and released in ib_uverbs_release_file() when the file is released. 78219820Sjeff * 79219820Sjeff * struct ib_uverbs_file: One reference is held by the VFS and 80219820Sjeff * released when the file is closed. Another reference is taken when 81219820Sjeff * an asynchronous event queue file is created and released when the 82219820Sjeff * event file is closed. 83219820Sjeff * 84219820Sjeff * struct ib_uverbs_event_file: One reference is held by the VFS and 85219820Sjeff * released when the file is closed. For asynchronous event files, 86219820Sjeff * another reference is held by the corresponding main context file 87219820Sjeff * and released when that file is closed. For completion event files, 88219820Sjeff * a reference is taken when a CQ is created that uses the file, and 89219820Sjeff * released when the CQ is destroyed. 90219820Sjeff */ 91219820Sjeff 92219820Sjeffstruct ib_uverbs_device { 93331769Shselasky atomic_t refcount; 94278886Shselasky int num_comp_vectors; 95219820Sjeff struct completion comp; 96219820Sjeff struct device *dev; 97331769Shselasky struct ib_device __rcu *ib_dev; 98278886Shselasky int devnum; 99278886Shselasky struct cdev cdev; 100278886Shselasky struct rb_root xrcd_tree; 101278886Shselasky struct mutex xrcd_tree_mutex; 102331769Shselasky struct kobject kobj; 103331769Shselasky struct srcu_struct disassociate_srcu; 104331769Shselasky struct mutex lists_mutex; /* protect lists */ 105331769Shselasky struct list_head uverbs_file_list; 106331769Shselasky struct list_head uverbs_events_file_list; 107219820Sjeff}; 108219820Sjeff 109219820Sjeffstruct ib_uverbs_event_file { 110219820Sjeff struct kref ref; 111278886Shselasky int is_async; 112219820Sjeff struct ib_uverbs_file *uverbs_file; 113219820Sjeff spinlock_t lock; 114278886Shselasky int is_closed; 115219820Sjeff wait_queue_head_t poll_wait; 116219820Sjeff struct fasync_struct *async_queue; 117219820Sjeff struct list_head event_list; 118331769Shselasky struct list_head list; 119219820Sjeff}; 120219820Sjeff 121219820Sjeffstruct ib_uverbs_file { 122219820Sjeff struct kref ref; 123219820Sjeff struct mutex mutex; 124331769Shselasky struct mutex cleanup_mutex; /* protect cleanup */ 125219820Sjeff struct ib_uverbs_device *device; 126219820Sjeff struct ib_ucontext *ucontext; 127219820Sjeff struct ib_event_handler event_handler; 128219820Sjeff struct ib_uverbs_event_file *async_file; 129331769Shselasky struct list_head list; 130331769Shselasky int is_closed; 131219820Sjeff}; 132219820Sjeff 133219820Sjeffstruct ib_uverbs_event { 134219820Sjeff union { 135219820Sjeff struct ib_uverbs_async_event_desc async; 136219820Sjeff struct ib_uverbs_comp_event_desc comp; 137219820Sjeff } desc; 138219820Sjeff struct list_head list; 139219820Sjeff struct list_head obj_list; 140219820Sjeff u32 *counter; 141219820Sjeff}; 142219820Sjeff 143219820Sjeffstruct ib_uverbs_mcast_entry { 144219820Sjeff struct list_head list; 145219820Sjeff union ib_gid gid; 146219820Sjeff u16 lid; 147219820Sjeff}; 148219820Sjeff 149219820Sjeffstruct ib_uevent_object { 150219820Sjeff struct ib_uobject uobject; 151219820Sjeff struct list_head event_list; 152219820Sjeff u32 events_reported; 153219820Sjeff}; 154219820Sjeff 155278886Shselaskystruct ib_uxrcd_object { 156278886Shselasky struct ib_uobject uobject; 157278886Shselasky atomic_t refcnt; 158278886Shselasky}; 159278886Shselasky 160278886Shselaskystruct ib_usrq_object { 161278886Shselasky struct ib_uevent_object uevent; 162278886Shselasky struct ib_uxrcd_object *uxrcd; 163278886Shselasky}; 164278886Shselasky 165219820Sjeffstruct ib_uqp_object { 166219820Sjeff struct ib_uevent_object uevent; 167337071Shselasky /* lock for mcast list */ 168337071Shselasky struct mutex mcast_lock; 169219820Sjeff struct list_head mcast_list; 170278886Shselasky struct ib_uxrcd_object *uxrcd; 171219820Sjeff}; 172219820Sjeff 173331769Shselaskystruct ib_uwq_object { 174331769Shselasky struct ib_uevent_object uevent; 175331769Shselasky}; 176331769Shselasky 177219820Sjeffstruct ib_ucq_object { 178219820Sjeff struct ib_uobject uobject; 179219820Sjeff struct ib_uverbs_file *uverbs_file; 180219820Sjeff struct list_head comp_list; 181219820Sjeff struct list_head async_list; 182219820Sjeff u32 comp_events_reported; 183219820Sjeff u32 async_events_reported; 184219820Sjeff}; 185219820Sjeff 186219820Sjeffextern spinlock_t ib_uverbs_idr_lock; 187219820Sjeffextern struct idr ib_uverbs_pd_idr; 188219820Sjeffextern struct idr ib_uverbs_mr_idr; 189219820Sjeffextern struct idr ib_uverbs_mw_idr; 190219820Sjeffextern struct idr ib_uverbs_ah_idr; 191219820Sjeffextern struct idr ib_uverbs_cq_idr; 192219820Sjeffextern struct idr ib_uverbs_qp_idr; 193219820Sjeffextern struct idr ib_uverbs_srq_idr; 194278886Shselaskyextern struct idr ib_uverbs_xrcd_idr; 195278886Shselaskyextern struct idr ib_uverbs_rule_idr; 196331769Shselaskyextern struct idr ib_uverbs_wq_idr; 197331769Shselaskyextern struct idr ib_uverbs_rwq_ind_tbl_idr; 198219820Sjeff 199219820Sjeffvoid idr_remove_uobj(struct idr *idp, struct ib_uobject *uobj); 200219820Sjeff 201219820Sjeffstruct file *ib_uverbs_alloc_event_file(struct ib_uverbs_file *uverbs_file, 202331769Shselasky struct ib_device *ib_dev, 203278886Shselasky int is_async); 204331769Shselaskyvoid ib_uverbs_free_async_event_file(struct ib_uverbs_file *uverbs_file); 205219820Sjeffstruct ib_uverbs_event_file *ib_uverbs_lookup_comp_file(int fd); 206219820Sjeff 207219820Sjeffvoid ib_uverbs_release_ucq(struct ib_uverbs_file *file, 208219820Sjeff struct ib_uverbs_event_file *ev_file, 209219820Sjeff struct ib_ucq_object *uobj); 210219820Sjeffvoid ib_uverbs_release_uevent(struct ib_uverbs_file *file, 211219820Sjeff struct ib_uevent_object *uobj); 212219820Sjeff 213219820Sjeffvoid ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); 214219820Sjeffvoid ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); 215219820Sjeffvoid ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); 216331769Shselaskyvoid ib_uverbs_wq_event_handler(struct ib_event *event, void *context_ptr); 217219820Sjeffvoid ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr); 218219820Sjeffvoid ib_uverbs_event_handler(struct ib_event_handler *handler, 219219820Sjeff struct ib_event *event); 220278886Shselaskyvoid ib_uverbs_dealloc_xrcd(struct ib_uverbs_device *dev, struct ib_xrcd *xrcd); 221219820Sjeff 222331769Shselaskyint uverbs_dealloc_mw(struct ib_mw *mw); 223331769Shselasky 224278886Shselaskystruct ib_uverbs_flow_spec { 225278886Shselasky union { 226278886Shselasky union { 227278886Shselasky struct ib_uverbs_flow_spec_hdr hdr; 228278886Shselasky struct { 229278886Shselasky __u32 type; 230278886Shselasky __u16 size; 231278886Shselasky __u16 reserved; 232278886Shselasky }; 233278886Shselasky }; 234278886Shselasky struct ib_uverbs_flow_spec_eth eth; 235278886Shselasky struct ib_uverbs_flow_spec_ipv4 ipv4; 236278886Shselasky struct ib_uverbs_flow_spec_tcp_udp tcp_udp; 237331769Shselasky struct ib_uverbs_flow_spec_ipv6 ipv6; 238278886Shselasky }; 239278886Shselasky}; 240278886Shselasky 241219820Sjeff#define IB_UVERBS_DECLARE_CMD(name) \ 242219820Sjeff ssize_t ib_uverbs_##name(struct ib_uverbs_file *file, \ 243331769Shselasky struct ib_device *ib_dev, \ 244219820Sjeff const char __user *buf, int in_len, \ 245219820Sjeff int out_len) 246219820Sjeff 247219820SjeffIB_UVERBS_DECLARE_CMD(get_context); 248219820SjeffIB_UVERBS_DECLARE_CMD(query_device); 249219820SjeffIB_UVERBS_DECLARE_CMD(query_port); 250219820SjeffIB_UVERBS_DECLARE_CMD(alloc_pd); 251219820SjeffIB_UVERBS_DECLARE_CMD(dealloc_pd); 252219820SjeffIB_UVERBS_DECLARE_CMD(reg_mr); 253331769ShselaskyIB_UVERBS_DECLARE_CMD(rereg_mr); 254219820SjeffIB_UVERBS_DECLARE_CMD(dereg_mr); 255278886ShselaskyIB_UVERBS_DECLARE_CMD(alloc_mw); 256278886ShselaskyIB_UVERBS_DECLARE_CMD(dealloc_mw); 257219820SjeffIB_UVERBS_DECLARE_CMD(create_comp_channel); 258219820SjeffIB_UVERBS_DECLARE_CMD(create_cq); 259219820SjeffIB_UVERBS_DECLARE_CMD(resize_cq); 260219820SjeffIB_UVERBS_DECLARE_CMD(poll_cq); 261219820SjeffIB_UVERBS_DECLARE_CMD(req_notify_cq); 262219820SjeffIB_UVERBS_DECLARE_CMD(destroy_cq); 263219820SjeffIB_UVERBS_DECLARE_CMD(create_qp); 264278886ShselaskyIB_UVERBS_DECLARE_CMD(open_qp); 265219820SjeffIB_UVERBS_DECLARE_CMD(query_qp); 266219820SjeffIB_UVERBS_DECLARE_CMD(modify_qp); 267219820SjeffIB_UVERBS_DECLARE_CMD(destroy_qp); 268219820SjeffIB_UVERBS_DECLARE_CMD(post_send); 269219820SjeffIB_UVERBS_DECLARE_CMD(post_recv); 270219820SjeffIB_UVERBS_DECLARE_CMD(post_srq_recv); 271219820SjeffIB_UVERBS_DECLARE_CMD(create_ah); 272219820SjeffIB_UVERBS_DECLARE_CMD(destroy_ah); 273219820SjeffIB_UVERBS_DECLARE_CMD(attach_mcast); 274219820SjeffIB_UVERBS_DECLARE_CMD(detach_mcast); 275219820SjeffIB_UVERBS_DECLARE_CMD(create_srq); 276219820SjeffIB_UVERBS_DECLARE_CMD(modify_srq); 277219820SjeffIB_UVERBS_DECLARE_CMD(query_srq); 278219820SjeffIB_UVERBS_DECLARE_CMD(destroy_srq); 279278886ShselaskyIB_UVERBS_DECLARE_CMD(create_xsrq); 280278886ShselaskyIB_UVERBS_DECLARE_CMD(open_xrcd); 281278886ShselaskyIB_UVERBS_DECLARE_CMD(close_xrcd); 282219820Sjeff 283278886Shselasky#define IB_UVERBS_DECLARE_EX_CMD(name) \ 284331769Shselasky int ib_uverbs_ex_##name(struct ib_uverbs_file *file, \ 285331769Shselasky struct ib_device *ib_dev, \ 286331769Shselasky struct ib_udata *ucore, \ 287278886Shselasky struct ib_udata *uhw) 288219820Sjeff 289278886ShselaskyIB_UVERBS_DECLARE_EX_CMD(create_flow); 290278886ShselaskyIB_UVERBS_DECLARE_EX_CMD(destroy_flow); 291331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(query_device); 292331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(create_cq); 293331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(create_qp); 294331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(create_wq); 295331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(modify_wq); 296331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(destroy_wq); 297331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(create_rwq_ind_table); 298331769ShselaskyIB_UVERBS_DECLARE_EX_CMD(destroy_rwq_ind_table); 299278886Shselasky 300219820Sjeff#endif /* UVERBS_H */ 301