1d6b92ffaSHans Petter Selasky /*
2d6b92ffaSHans Petter Selasky * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3d6b92ffaSHans Petter Selasky * Copyright (c) 2006, 2007 Cisco Systems, Inc. All rights reserved.
4d6b92ffaSHans Petter Selasky *
5d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
6d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
7d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
8d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
9d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
10d6b92ffaSHans Petter Selasky *
11d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
12d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
13d6b92ffaSHans Petter Selasky * conditions are met:
14d6b92ffaSHans Petter Selasky *
15d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
16d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
17d6b92ffaSHans Petter Selasky * disclaimer.
18d6b92ffaSHans Petter Selasky *
19d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
20d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
21d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
22d6b92ffaSHans Petter Selasky * provided with the distribution.
23d6b92ffaSHans Petter Selasky *
24d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31d6b92ffaSHans Petter Selasky * SOFTWARE.
32d6b92ffaSHans Petter Selasky */
33d6b92ffaSHans Petter Selasky #define _GNU_SOURCE
34d6b92ffaSHans Petter Selasky #include <config.h>
35d6b92ffaSHans Petter Selasky
36d6b92ffaSHans Petter Selasky #include <infiniband/endian.h>
37d6b92ffaSHans Petter Selasky #include <stdio.h>
38d6b92ffaSHans Petter Selasky #include <sys/types.h>
39d6b92ffaSHans Petter Selasky #include <sys/stat.h>
40d6b92ffaSHans Petter Selasky #include <fcntl.h>
41d6b92ffaSHans Petter Selasky #include <unistd.h>
42d6b92ffaSHans Petter Selasky #include <stdlib.h>
43d6b92ffaSHans Petter Selasky #include <alloca.h>
44d6b92ffaSHans Petter Selasky #include <errno.h>
45d6b92ffaSHans Petter Selasky
46d6b92ffaSHans Petter Selasky #include "ibverbs.h"
47d6b92ffaSHans Petter Selasky
48d6b92ffaSHans Petter Selasky /* Hack to avoid GCC's -Wmissing-prototypes and the similar error from sparse
49d6b92ffaSHans Petter Selasky with these prototypes. Symbol versionining requires the goofy names, the
50d6b92ffaSHans Petter Selasky prototype must match the version in verbs.h.
51d6b92ffaSHans Petter Selasky */
52d6b92ffaSHans Petter Selasky struct ibv_device **__ibv_get_device_list(int *num_devices);
53d6b92ffaSHans Petter Selasky void __ibv_free_device_list(struct ibv_device **list);
54d6b92ffaSHans Petter Selasky const char *__ibv_get_device_name(struct ibv_device *device);
55d6b92ffaSHans Petter Selasky __be64 __ibv_get_device_guid(struct ibv_device *device);
56d6b92ffaSHans Petter Selasky struct ibv_context *__ibv_open_device(struct ibv_device *device);
57d6b92ffaSHans Petter Selasky int __ibv_close_device(struct ibv_context *context);
58d6b92ffaSHans Petter Selasky int __ibv_get_async_event(struct ibv_context *context,
59d6b92ffaSHans Petter Selasky struct ibv_async_event *event);
60d6b92ffaSHans Petter Selasky void __ibv_ack_async_event(struct ibv_async_event *event);
61d6b92ffaSHans Petter Selasky
62d6b92ffaSHans Petter Selasky static pthread_once_t device_list_once = PTHREAD_ONCE_INIT;
63d6b92ffaSHans Petter Selasky static int num_devices;
64d6b92ffaSHans Petter Selasky static struct ibv_device **device_list;
65d6b92ffaSHans Petter Selasky
count_devices(void)66d6b92ffaSHans Petter Selasky static void count_devices(void)
67d6b92ffaSHans Petter Selasky {
68d6b92ffaSHans Petter Selasky num_devices = ibverbs_init(&device_list);
69d6b92ffaSHans Petter Selasky }
70d6b92ffaSHans Petter Selasky
__ibv_get_device_list(int * num)71d6b92ffaSHans Petter Selasky struct ibv_device **__ibv_get_device_list(int *num)
72d6b92ffaSHans Petter Selasky {
73d6b92ffaSHans Petter Selasky struct ibv_device **l;
74d6b92ffaSHans Petter Selasky int i;
75d6b92ffaSHans Petter Selasky
76d6b92ffaSHans Petter Selasky if (num)
77d6b92ffaSHans Petter Selasky *num = 0;
78d6b92ffaSHans Petter Selasky
79d6b92ffaSHans Petter Selasky pthread_once(&device_list_once, count_devices);
80d6b92ffaSHans Petter Selasky
81d6b92ffaSHans Petter Selasky if (num_devices < 0) {
82d6b92ffaSHans Petter Selasky errno = -num_devices;
83d6b92ffaSHans Petter Selasky return NULL;
84d6b92ffaSHans Petter Selasky }
85d6b92ffaSHans Petter Selasky
86d6b92ffaSHans Petter Selasky l = calloc(num_devices + 1, sizeof (struct ibv_device *));
87d6b92ffaSHans Petter Selasky if (!l) {
88d6b92ffaSHans Petter Selasky errno = ENOMEM;
89d6b92ffaSHans Petter Selasky return NULL;
90d6b92ffaSHans Petter Selasky }
91d6b92ffaSHans Petter Selasky
92d6b92ffaSHans Petter Selasky for (i = 0; i < num_devices; ++i)
93d6b92ffaSHans Petter Selasky l[i] = device_list[i];
94d6b92ffaSHans Petter Selasky if (num)
95d6b92ffaSHans Petter Selasky *num = num_devices;
96d6b92ffaSHans Petter Selasky
97d6b92ffaSHans Petter Selasky return l;
98d6b92ffaSHans Petter Selasky }
99d6b92ffaSHans Petter Selasky default_symver(__ibv_get_device_list, ibv_get_device_list);
100d6b92ffaSHans Petter Selasky
__ibv_free_device_list(struct ibv_device ** list)101d6b92ffaSHans Petter Selasky void __ibv_free_device_list(struct ibv_device **list)
102d6b92ffaSHans Petter Selasky {
103d6b92ffaSHans Petter Selasky free(list);
104d6b92ffaSHans Petter Selasky }
105d6b92ffaSHans Petter Selasky default_symver(__ibv_free_device_list, ibv_free_device_list);
106d6b92ffaSHans Petter Selasky
__ibv_get_device_name(struct ibv_device * device)107d6b92ffaSHans Petter Selasky const char *__ibv_get_device_name(struct ibv_device *device)
108d6b92ffaSHans Petter Selasky {
109d6b92ffaSHans Petter Selasky return device->name;
110d6b92ffaSHans Petter Selasky }
111d6b92ffaSHans Petter Selasky default_symver(__ibv_get_device_name, ibv_get_device_name);
112d6b92ffaSHans Petter Selasky
__ibv_get_device_guid(struct ibv_device * device)113d6b92ffaSHans Petter Selasky __be64 __ibv_get_device_guid(struct ibv_device *device)
114d6b92ffaSHans Petter Selasky {
115d6b92ffaSHans Petter Selasky char attr[24];
116d6b92ffaSHans Petter Selasky uint64_t guid = 0;
117d6b92ffaSHans Petter Selasky uint16_t parts[4];
118d6b92ffaSHans Petter Selasky int i;
119d6b92ffaSHans Petter Selasky
120d6b92ffaSHans Petter Selasky if (ibv_read_sysfs_file(device->ibdev_path, "node_guid",
121d6b92ffaSHans Petter Selasky attr, sizeof attr) < 0)
122d6b92ffaSHans Petter Selasky return 0;
123d6b92ffaSHans Petter Selasky
124d6b92ffaSHans Petter Selasky if (sscanf(attr, "%hx:%hx:%hx:%hx",
125d6b92ffaSHans Petter Selasky parts, parts + 1, parts + 2, parts + 3) != 4)
126d6b92ffaSHans Petter Selasky return 0;
127d6b92ffaSHans Petter Selasky
128d6b92ffaSHans Petter Selasky for (i = 0; i < 4; ++i)
129d6b92ffaSHans Petter Selasky guid = (guid << 16) | parts[i];
130d6b92ffaSHans Petter Selasky
131d6b92ffaSHans Petter Selasky return htobe64(guid);
132d6b92ffaSHans Petter Selasky }
133d6b92ffaSHans Petter Selasky default_symver(__ibv_get_device_guid, ibv_get_device_guid);
134d6b92ffaSHans Petter Selasky
verbs_init_cq(struct ibv_cq * cq,struct ibv_context * context,struct ibv_comp_channel * channel,void * cq_context)135a687910fSSean Lim int verbs_init_cq(struct ibv_cq *cq, struct ibv_context *context,
136d6b92ffaSHans Petter Selasky struct ibv_comp_channel *channel,
137d6b92ffaSHans Petter Selasky void *cq_context)
138d6b92ffaSHans Petter Selasky {
139a687910fSSean Lim int err = 0;
140a687910fSSean Lim
141d6b92ffaSHans Petter Selasky cq->context = context;
142d6b92ffaSHans Petter Selasky cq->channel = channel;
143d6b92ffaSHans Petter Selasky
144a687910fSSean Lim err = pthread_mutex_init(&cq->mutex, NULL);
145a687910fSSean Lim if (err)
146a687910fSSean Lim return err;
147a687910fSSean Lim err = pthread_cond_init(&cq->cond, NULL);
148a687910fSSean Lim if (err)
149a687910fSSean Lim goto err;
150a687910fSSean Lim
151d6b92ffaSHans Petter Selasky if (cq->channel) {
152d6b92ffaSHans Petter Selasky pthread_mutex_lock(&context->mutex);
153d6b92ffaSHans Petter Selasky ++cq->channel->refcnt;
154d6b92ffaSHans Petter Selasky pthread_mutex_unlock(&context->mutex);
155d6b92ffaSHans Petter Selasky }
156d6b92ffaSHans Petter Selasky
157d6b92ffaSHans Petter Selasky cq->cq_context = cq_context;
158d6b92ffaSHans Petter Selasky cq->comp_events_completed = 0;
159d6b92ffaSHans Petter Selasky cq->async_events_completed = 0;
160a687910fSSean Lim
161a687910fSSean Lim return err;
162a687910fSSean Lim
163a687910fSSean Lim err:
164a687910fSSean Lim pthread_mutex_destroy(&cq->mutex);
165a687910fSSean Lim
166a687910fSSean Lim return err;
167a687910fSSean Lim }
168a687910fSSean Lim
verbs_cleanup_cq(struct ibv_cq * cq)169a687910fSSean Lim void verbs_cleanup_cq(struct ibv_cq *cq)
170a687910fSSean Lim {
171a687910fSSean Lim pthread_cond_destroy(&cq->cond);
172a687910fSSean Lim pthread_mutex_destroy(&cq->mutex);
173d6b92ffaSHans Petter Selasky }
174d6b92ffaSHans Petter Selasky
175d6b92ffaSHans Petter Selasky static struct ibv_cq_ex *
__lib_ibv_create_cq_ex(struct ibv_context * context,struct ibv_cq_init_attr_ex * cq_attr)176d6b92ffaSHans Petter Selasky __lib_ibv_create_cq_ex(struct ibv_context *context,
177d6b92ffaSHans Petter Selasky struct ibv_cq_init_attr_ex *cq_attr)
178d6b92ffaSHans Petter Selasky {
179d6b92ffaSHans Petter Selasky struct verbs_context *vctx = verbs_get_ctx(context);
180d6b92ffaSHans Petter Selasky struct ibv_cq_ex *cq;
181a687910fSSean Lim int err = 0;
182d6b92ffaSHans Petter Selasky
183d6b92ffaSHans Petter Selasky if (cq_attr->wc_flags & ~IBV_CREATE_CQ_SUP_WC_FLAGS) {
184d6b92ffaSHans Petter Selasky errno = EOPNOTSUPP;
185d6b92ffaSHans Petter Selasky return NULL;
186d6b92ffaSHans Petter Selasky }
187d6b92ffaSHans Petter Selasky
188d6b92ffaSHans Petter Selasky cq = vctx->priv->create_cq_ex(context, cq_attr);
189a687910fSSean Lim if (!cq)
190a687910fSSean Lim return NULL;
191d6b92ffaSHans Petter Selasky
192a687910fSSean Lim err = verbs_init_cq(ibv_cq_ex_to_cq(cq), context,
193d6b92ffaSHans Petter Selasky cq_attr->channel, cq_attr->cq_context);
194a687910fSSean Lim if (err)
195a687910fSSean Lim goto err;
196d6b92ffaSHans Petter Selasky
197d6b92ffaSHans Petter Selasky return cq;
198a687910fSSean Lim
199a687910fSSean Lim err:
200a687910fSSean Lim context->ops.destroy_cq(ibv_cq_ex_to_cq(cq));
201a687910fSSean Lim
202a687910fSSean Lim return NULL;
203d6b92ffaSHans Petter Selasky }
204d6b92ffaSHans Petter Selasky
__ibv_open_device(struct ibv_device * device)205d6b92ffaSHans Petter Selasky struct ibv_context *__ibv_open_device(struct ibv_device *device)
206d6b92ffaSHans Petter Selasky {
207d6b92ffaSHans Petter Selasky struct verbs_device *verbs_device = verbs_get_device(device);
208d6b92ffaSHans Petter Selasky char *devpath;
209d6b92ffaSHans Petter Selasky int cmd_fd, ret;
210d6b92ffaSHans Petter Selasky struct ibv_context *context;
211d6b92ffaSHans Petter Selasky struct verbs_context *context_ex;
212d6b92ffaSHans Petter Selasky
213d6b92ffaSHans Petter Selasky if (asprintf(&devpath, "/dev/%s", device->dev_name) < 0)
214d6b92ffaSHans Petter Selasky return NULL;
215d6b92ffaSHans Petter Selasky
216d6b92ffaSHans Petter Selasky /*
217d6b92ffaSHans Petter Selasky * We'll only be doing writes, but we need O_RDWR in case the
218d6b92ffaSHans Petter Selasky * provider needs to mmap() the file.
219d6b92ffaSHans Petter Selasky */
220d6b92ffaSHans Petter Selasky cmd_fd = open(devpath, O_RDWR | O_CLOEXEC);
221d6b92ffaSHans Petter Selasky free(devpath);
222d6b92ffaSHans Petter Selasky
223d6b92ffaSHans Petter Selasky if (cmd_fd < 0)
224d6b92ffaSHans Petter Selasky return NULL;
225d6b92ffaSHans Petter Selasky
226d6b92ffaSHans Petter Selasky if (!verbs_device->ops->init_context) {
227d6b92ffaSHans Petter Selasky context = verbs_device->ops->alloc_context(device, cmd_fd);
228d6b92ffaSHans Petter Selasky if (!context)
229d6b92ffaSHans Petter Selasky goto err;
230a687910fSSean Lim
231a687910fSSean Lim if (pthread_mutex_init(&context->mutex, NULL)) {
232a687910fSSean Lim verbs_device->ops->free_context(context);
233a687910fSSean Lim goto err;
234a687910fSSean Lim }
235d6b92ffaSHans Petter Selasky } else {
236d6b92ffaSHans Petter Selasky struct verbs_ex_private *priv;
237d6b92ffaSHans Petter Selasky
238d6b92ffaSHans Petter Selasky /* Library now allocates the context */
239d6b92ffaSHans Petter Selasky context_ex = calloc(1, sizeof(*context_ex) +
240d6b92ffaSHans Petter Selasky verbs_device->size_of_context);
241d6b92ffaSHans Petter Selasky if (!context_ex) {
242d6b92ffaSHans Petter Selasky errno = ENOMEM;
243d6b92ffaSHans Petter Selasky goto err;
244d6b92ffaSHans Petter Selasky }
245d6b92ffaSHans Petter Selasky
246d6b92ffaSHans Petter Selasky priv = calloc(1, sizeof(*priv));
247d6b92ffaSHans Petter Selasky if (!priv) {
248d6b92ffaSHans Petter Selasky errno = ENOMEM;
249a687910fSSean Lim goto err_context;
250d6b92ffaSHans Petter Selasky }
251d6b92ffaSHans Petter Selasky
252d6b92ffaSHans Petter Selasky context_ex->priv = priv;
253d6b92ffaSHans Petter Selasky context_ex->context.abi_compat = __VERBS_ABI_IS_EXTENDED;
254d6b92ffaSHans Petter Selasky context_ex->sz = sizeof(*context_ex);
255d6b92ffaSHans Petter Selasky
256d6b92ffaSHans Petter Selasky context = &context_ex->context;
257a687910fSSean Lim if (pthread_mutex_init(&context->mutex, NULL))
258a687910fSSean Lim goto verbs_err;
259a687910fSSean Lim
260d6b92ffaSHans Petter Selasky ret = verbs_device->ops->init_context(verbs_device, context, cmd_fd);
261d6b92ffaSHans Petter Selasky if (ret)
262a687910fSSean Lim goto err_mutex;
263d6b92ffaSHans Petter Selasky /*
264d6b92ffaSHans Petter Selasky * In order to maintain backward/forward binary compatibility
265d6b92ffaSHans Petter Selasky * with apps compiled against libibverbs-1.1.8 that use the
266d6b92ffaSHans Petter Selasky * flow steering addition, we need to set the two
267d6b92ffaSHans Petter Selasky * ABI_placeholder entries to match the driver set flow
268d6b92ffaSHans Petter Selasky * entries. This is because apps compiled against
269d6b92ffaSHans Petter Selasky * libibverbs-1.1.8 use an inline ibv_create_flow and
270d6b92ffaSHans Petter Selasky * ibv_destroy_flow function that looks in the placeholder
271d6b92ffaSHans Petter Selasky * spots for the proper entry points. For apps compiled
272d6b92ffaSHans Petter Selasky * against libibverbs-1.1.9 and later, the inline functions
273d6b92ffaSHans Petter Selasky * will be looking in the right place.
274d6b92ffaSHans Petter Selasky */
275d6b92ffaSHans Petter Selasky context_ex->ABI_placeholder1 = (void (*)(void)) context_ex->ibv_create_flow;
276d6b92ffaSHans Petter Selasky context_ex->ABI_placeholder2 = (void (*)(void)) context_ex->ibv_destroy_flow;
277d6b92ffaSHans Petter Selasky
278d6b92ffaSHans Petter Selasky if (context_ex->create_cq_ex) {
279d6b92ffaSHans Petter Selasky priv->create_cq_ex = context_ex->create_cq_ex;
280d6b92ffaSHans Petter Selasky context_ex->create_cq_ex = __lib_ibv_create_cq_ex;
281d6b92ffaSHans Petter Selasky }
282d6b92ffaSHans Petter Selasky }
283d6b92ffaSHans Petter Selasky
284d6b92ffaSHans Petter Selasky context->device = device;
285d6b92ffaSHans Petter Selasky context->cmd_fd = cmd_fd;
286d6b92ffaSHans Petter Selasky
287d6b92ffaSHans Petter Selasky return context;
288d6b92ffaSHans Petter Selasky
289a687910fSSean Lim err_mutex:
290a687910fSSean Lim pthread_mutex_destroy(&context->mutex);
291d6b92ffaSHans Petter Selasky verbs_err:
292d6b92ffaSHans Petter Selasky free(context_ex->priv);
293a687910fSSean Lim err_context:
294d6b92ffaSHans Petter Selasky free(context_ex);
295d6b92ffaSHans Petter Selasky err:
296d6b92ffaSHans Petter Selasky close(cmd_fd);
297d6b92ffaSHans Petter Selasky return NULL;
298d6b92ffaSHans Petter Selasky }
299d6b92ffaSHans Petter Selasky default_symver(__ibv_open_device, ibv_open_device);
300d6b92ffaSHans Petter Selasky
__ibv_close_device(struct ibv_context * context)301d6b92ffaSHans Petter Selasky int __ibv_close_device(struct ibv_context *context)
302d6b92ffaSHans Petter Selasky {
303d6b92ffaSHans Petter Selasky int async_fd = context->async_fd;
304d6b92ffaSHans Petter Selasky int cmd_fd = context->cmd_fd;
305d6b92ffaSHans Petter Selasky struct verbs_context *context_ex;
306d6b92ffaSHans Petter Selasky struct verbs_device *verbs_device = verbs_get_device(context->device);
307d6b92ffaSHans Petter Selasky
308a687910fSSean Lim pthread_mutex_destroy(&context->mutex);
309d6b92ffaSHans Petter Selasky context_ex = verbs_get_ctx(context);
310d6b92ffaSHans Petter Selasky if (context_ex) {
311d6b92ffaSHans Petter Selasky verbs_device->ops->uninit_context(verbs_device, context);
312d6b92ffaSHans Petter Selasky free(context_ex->priv);
313d6b92ffaSHans Petter Selasky free(context_ex);
314d6b92ffaSHans Petter Selasky } else {
315d6b92ffaSHans Petter Selasky verbs_device->ops->free_context(context);
316d6b92ffaSHans Petter Selasky }
317d6b92ffaSHans Petter Selasky
318d6b92ffaSHans Petter Selasky close(async_fd);
319d6b92ffaSHans Petter Selasky close(cmd_fd);
320d6b92ffaSHans Petter Selasky
321d6b92ffaSHans Petter Selasky return 0;
322d6b92ffaSHans Petter Selasky }
323d6b92ffaSHans Petter Selasky default_symver(__ibv_close_device, ibv_close_device);
324d6b92ffaSHans Petter Selasky
__ibv_get_async_event(struct ibv_context * context,struct ibv_async_event * event)325d6b92ffaSHans Petter Selasky int __ibv_get_async_event(struct ibv_context *context,
326d6b92ffaSHans Petter Selasky struct ibv_async_event *event)
327d6b92ffaSHans Petter Selasky {
328d6b92ffaSHans Petter Selasky struct ibv_kern_async_event ev;
329d6b92ffaSHans Petter Selasky
330d6b92ffaSHans Petter Selasky if (read(context->async_fd, &ev, sizeof ev) != sizeof ev)
331d6b92ffaSHans Petter Selasky return -1;
332d6b92ffaSHans Petter Selasky
333d6b92ffaSHans Petter Selasky event->event_type = ev.event_type;
334d6b92ffaSHans Petter Selasky
335d6b92ffaSHans Petter Selasky switch (event->event_type) {
336d6b92ffaSHans Petter Selasky case IBV_EVENT_CQ_ERR:
337d6b92ffaSHans Petter Selasky event->element.cq = (void *) (uintptr_t) ev.element;
338d6b92ffaSHans Petter Selasky break;
339d6b92ffaSHans Petter Selasky
340d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_FATAL:
341d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_REQ_ERR:
342d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_ACCESS_ERR:
343d6b92ffaSHans Petter Selasky case IBV_EVENT_COMM_EST:
344d6b92ffaSHans Petter Selasky case IBV_EVENT_SQ_DRAINED:
345d6b92ffaSHans Petter Selasky case IBV_EVENT_PATH_MIG:
346d6b92ffaSHans Petter Selasky case IBV_EVENT_PATH_MIG_ERR:
347d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_LAST_WQE_REACHED:
348d6b92ffaSHans Petter Selasky event->element.qp = (void *) (uintptr_t) ev.element;
349d6b92ffaSHans Petter Selasky break;
350d6b92ffaSHans Petter Selasky
351d6b92ffaSHans Petter Selasky case IBV_EVENT_SRQ_ERR:
352d6b92ffaSHans Petter Selasky case IBV_EVENT_SRQ_LIMIT_REACHED:
353d6b92ffaSHans Petter Selasky event->element.srq = (void *) (uintptr_t) ev.element;
354d6b92ffaSHans Petter Selasky break;
355d6b92ffaSHans Petter Selasky
356d6b92ffaSHans Petter Selasky case IBV_EVENT_WQ_FATAL:
357d6b92ffaSHans Petter Selasky event->element.wq = (void *) (uintptr_t) ev.element;
358d6b92ffaSHans Petter Selasky break;
359d6b92ffaSHans Petter Selasky default:
360d6b92ffaSHans Petter Selasky event->element.port_num = ev.element;
361d6b92ffaSHans Petter Selasky break;
362d6b92ffaSHans Petter Selasky }
363d6b92ffaSHans Petter Selasky
364d6b92ffaSHans Petter Selasky if (context->ops.async_event)
365d6b92ffaSHans Petter Selasky context->ops.async_event(event);
366d6b92ffaSHans Petter Selasky
367d6b92ffaSHans Petter Selasky return 0;
368d6b92ffaSHans Petter Selasky }
369d6b92ffaSHans Petter Selasky default_symver(__ibv_get_async_event, ibv_get_async_event);
370d6b92ffaSHans Petter Selasky
__ibv_ack_async_event(struct ibv_async_event * event)371d6b92ffaSHans Petter Selasky void __ibv_ack_async_event(struct ibv_async_event *event)
372d6b92ffaSHans Petter Selasky {
373d6b92ffaSHans Petter Selasky switch (event->event_type) {
374d6b92ffaSHans Petter Selasky case IBV_EVENT_CQ_ERR:
375d6b92ffaSHans Petter Selasky {
376d6b92ffaSHans Petter Selasky struct ibv_cq *cq = event->element.cq;
377d6b92ffaSHans Petter Selasky
378d6b92ffaSHans Petter Selasky pthread_mutex_lock(&cq->mutex);
379d6b92ffaSHans Petter Selasky ++cq->async_events_completed;
380d6b92ffaSHans Petter Selasky pthread_cond_signal(&cq->cond);
381d6b92ffaSHans Petter Selasky pthread_mutex_unlock(&cq->mutex);
382d6b92ffaSHans Petter Selasky
383d6b92ffaSHans Petter Selasky return;
384d6b92ffaSHans Petter Selasky }
385d6b92ffaSHans Petter Selasky
386d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_FATAL:
387d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_REQ_ERR:
388d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_ACCESS_ERR:
389d6b92ffaSHans Petter Selasky case IBV_EVENT_COMM_EST:
390d6b92ffaSHans Petter Selasky case IBV_EVENT_SQ_DRAINED:
391d6b92ffaSHans Petter Selasky case IBV_EVENT_PATH_MIG:
392d6b92ffaSHans Petter Selasky case IBV_EVENT_PATH_MIG_ERR:
393d6b92ffaSHans Petter Selasky case IBV_EVENT_QP_LAST_WQE_REACHED:
394d6b92ffaSHans Petter Selasky {
395d6b92ffaSHans Petter Selasky struct ibv_qp *qp = event->element.qp;
396d6b92ffaSHans Petter Selasky
397d6b92ffaSHans Petter Selasky pthread_mutex_lock(&qp->mutex);
398d6b92ffaSHans Petter Selasky ++qp->events_completed;
399d6b92ffaSHans Petter Selasky pthread_cond_signal(&qp->cond);
400d6b92ffaSHans Petter Selasky pthread_mutex_unlock(&qp->mutex);
401d6b92ffaSHans Petter Selasky
402d6b92ffaSHans Petter Selasky return;
403d6b92ffaSHans Petter Selasky }
404d6b92ffaSHans Petter Selasky
405d6b92ffaSHans Petter Selasky case IBV_EVENT_SRQ_ERR:
406d6b92ffaSHans Petter Selasky case IBV_EVENT_SRQ_LIMIT_REACHED:
407d6b92ffaSHans Petter Selasky {
408d6b92ffaSHans Petter Selasky struct ibv_srq *srq = event->element.srq;
409d6b92ffaSHans Petter Selasky
410d6b92ffaSHans Petter Selasky pthread_mutex_lock(&srq->mutex);
411d6b92ffaSHans Petter Selasky ++srq->events_completed;
412d6b92ffaSHans Petter Selasky pthread_cond_signal(&srq->cond);
413d6b92ffaSHans Petter Selasky pthread_mutex_unlock(&srq->mutex);
414d6b92ffaSHans Petter Selasky
415d6b92ffaSHans Petter Selasky return;
416d6b92ffaSHans Petter Selasky }
417d6b92ffaSHans Petter Selasky
418d6b92ffaSHans Petter Selasky case IBV_EVENT_WQ_FATAL:
419d6b92ffaSHans Petter Selasky {
420d6b92ffaSHans Petter Selasky struct ibv_wq *wq = event->element.wq;
421d6b92ffaSHans Petter Selasky
422d6b92ffaSHans Petter Selasky pthread_mutex_lock(&wq->mutex);
423d6b92ffaSHans Petter Selasky ++wq->events_completed;
424d6b92ffaSHans Petter Selasky pthread_cond_signal(&wq->cond);
425d6b92ffaSHans Petter Selasky pthread_mutex_unlock(&wq->mutex);
426d6b92ffaSHans Petter Selasky
427d6b92ffaSHans Petter Selasky return;
428d6b92ffaSHans Petter Selasky }
429d6b92ffaSHans Petter Selasky
430d6b92ffaSHans Petter Selasky default:
431d6b92ffaSHans Petter Selasky return;
432d6b92ffaSHans Petter Selasky }
433d6b92ffaSHans Petter Selasky }
434d6b92ffaSHans Petter Selasky default_symver(__ibv_ack_async_event, ibv_ack_async_event);
435a687910fSSean Lim
__ibv_init_wq(struct ibv_wq * wq)436a687910fSSean Lim int __ibv_init_wq(struct ibv_wq *wq)
437a687910fSSean Lim {
438a687910fSSean Lim int err = 0;
439a687910fSSean Lim wq->events_completed = 0;
440a687910fSSean Lim err = pthread_mutex_init(&wq->mutex, NULL);
441a687910fSSean Lim if (err)
442a687910fSSean Lim return err;
443a687910fSSean Lim
444a687910fSSean Lim err = pthread_cond_init(&wq->cond, NULL);
445a687910fSSean Lim if (err)
446a687910fSSean Lim goto err;
447a687910fSSean Lim
448a687910fSSean Lim return err;
449a687910fSSean Lim
450a687910fSSean Lim err:
451a687910fSSean Lim pthread_mutex_destroy(&wq->mutex);
452a687910fSSean Lim
453a687910fSSean Lim return err;
454a687910fSSean Lim }
455a687910fSSean Lim default_symver(__ibv_init_wq, ibv_init_wq);
456a687910fSSean Lim
__ibv_cleanup_wq(struct ibv_wq * wq)457a687910fSSean Lim void __ibv_cleanup_wq(struct ibv_wq *wq)
458a687910fSSean Lim {
4598e1f58caSBartosz Sobczak pthread_cond_destroy(&wq->cond);
460a687910fSSean Lim pthread_mutex_destroy(&wq->mutex);
461a687910fSSean Lim }
462a687910fSSean Lim default_symver(__ibv_cleanup_wq, ibv_cleanup_wq);
463