1*c39526b7SPramod Gunjikar /*
2*c39526b7SPramod Gunjikar * CDDL HEADER START
3*c39526b7SPramod Gunjikar *
4*c39526b7SPramod Gunjikar * The contents of this file are subject to the terms of the
5*c39526b7SPramod Gunjikar * Common Development and Distribution License (the "License").
6*c39526b7SPramod Gunjikar * You may not use this file except in compliance with the License.
7*c39526b7SPramod Gunjikar *
8*c39526b7SPramod Gunjikar * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*c39526b7SPramod Gunjikar * or http://www.opensolaris.org/os/licensing.
10*c39526b7SPramod Gunjikar * See the License for the specific language governing permissions
11*c39526b7SPramod Gunjikar * and limitations under the License.
12*c39526b7SPramod Gunjikar *
13*c39526b7SPramod Gunjikar * When distributing Covered Code, include this CDDL HEADER in each
14*c39526b7SPramod Gunjikar * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*c39526b7SPramod Gunjikar * If applicable, add the following below this CDDL HEADER, with the
16*c39526b7SPramod Gunjikar * fields enclosed by brackets "[]" replaced with your own identifying
17*c39526b7SPramod Gunjikar * information: Portions Copyright [yyyy] [name of copyright owner]
18*c39526b7SPramod Gunjikar *
19*c39526b7SPramod Gunjikar * CDDL HEADER END
20*c39526b7SPramod Gunjikar */
21*c39526b7SPramod Gunjikar
22*c39526b7SPramod Gunjikar /*
23*c39526b7SPramod Gunjikar * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*c39526b7SPramod Gunjikar */
25*c39526b7SPramod Gunjikar /*
26*c39526b7SPramod Gunjikar * sol_uverbs_hca.c
27*c39526b7SPramod Gunjikar *
28*c39526b7SPramod Gunjikar * Provides the Solaris OFED User Verbs thin common hca interface for
29*c39526b7SPramod Gunjikar * sharing of IBT client handle, device list, and asynchronous event
30*c39526b7SPramod Gunjikar * delivery.
31*c39526b7SPramod Gunjikar */
32*c39526b7SPramod Gunjikar #include <sys/vfs.h>
33*c39526b7SPramod Gunjikar #ifdef VFS_OPS
34*c39526b7SPramod Gunjikar #include <sys/vfs_opreg.h>
35*c39526b7SPramod Gunjikar #include <sys/vnode.h>
36*c39526b7SPramod Gunjikar #endif
37*c39526b7SPramod Gunjikar #include <sys/errno.h>
38*c39526b7SPramod Gunjikar #include <sys/cred.h>
39*c39526b7SPramod Gunjikar #include <sys/uio.h>
40*c39526b7SPramod Gunjikar #include <sys/semaphore.h>
41*c39526b7SPramod Gunjikar #include <sys/ddi.h>
42*c39526b7SPramod Gunjikar #include <sys/sunddi.h>
43*c39526b7SPramod Gunjikar
44*c39526b7SPramod Gunjikar #include <sys/ib/ibtl/ibvti.h>
45*c39526b7SPramod Gunjikar #include <sys/ib/clients/of/ofa_solaris.h>
46*c39526b7SPramod Gunjikar #include <sys/ib/clients/of/sol_ofs/sol_ofs_common.h>
47*c39526b7SPramod Gunjikar #include <sys/ib/clients/of/sol_uverbs/sol_uverbs_hca.h>
48*c39526b7SPramod Gunjikar #include <sys/ib/clients/of/sol_uverbs/sol_uverbs.h>
49*c39526b7SPramod Gunjikar
50*c39526b7SPramod Gunjikar extern char *sol_uverbs_dbg_str;
51*c39526b7SPramod Gunjikar
52*c39526b7SPramod Gunjikar /*
53*c39526b7SPramod Gunjikar * Globals for managing the list of HCA's and the registered clients.
54*c39526b7SPramod Gunjikar */
55*c39526b7SPramod Gunjikar kmutex_t sol_uverbs_hca_lock;
56*c39526b7SPramod Gunjikar llist_head_t sol_uverbs_hca_list;
57*c39526b7SPramod Gunjikar llist_head_t sol_uverbs_client_list;
58*c39526b7SPramod Gunjikar static uint32_t sol_uverbs_common_hca_initialized = 0;
59*c39526b7SPramod Gunjikar
60*c39526b7SPramod Gunjikar typedef struct sol_uverbs_hca_client_data {
61*c39526b7SPramod Gunjikar llist_head_t list;
62*c39526b7SPramod Gunjikar sol_uverbs_ib_client_t *client;
63*c39526b7SPramod Gunjikar void *data;
64*c39526b7SPramod Gunjikar } sol_uverbs_hca_client_data_t;
65*c39526b7SPramod Gunjikar
66*c39526b7SPramod Gunjikar static
67*c39526b7SPramod Gunjikar int sol_uverbs_hca_add_client_context(sol_uverbs_hca_t *hca,
68*c39526b7SPramod Gunjikar sol_uverbs_ib_client_t *client);
69*c39526b7SPramod Gunjikar
70*c39526b7SPramod Gunjikar /*
71*c39526b7SPramod Gunjikar * Function:
72*c39526b7SPramod Gunjikar * sol_uverbs_ib_register_client
73*c39526b7SPramod Gunjikar * Input:
74*c39526b7SPramod Gunjikar * client - Pointer to the client structure
75*c39526b7SPramod Gunjikar * Output:
76*c39526b7SPramod Gunjikar * None
77*c39526b7SPramod Gunjikar * Returns:
78*c39526b7SPramod Gunjikar * Zero on success, else error code.
79*c39526b7SPramod Gunjikar * Description:
80*c39526b7SPramod Gunjikar * The Solaris User Verbs kernel agent provides a single
81*c39526b7SPramod Gunjikar * common view of the IBTF devices. This function allows
82*c39526b7SPramod Gunjikar * Solaris OFA kernel implementations to share this view
83*c39526b7SPramod Gunjikar * by registerng a client callback for notification of HCA
84*c39526b7SPramod Gunjikar * addtion and removal. Note that when this function is
85*c39526b7SPramod Gunjikar * called, the client will get an "add" callback for all
86*c39526b7SPramod Gunjikar * existing devices.
87*c39526b7SPramod Gunjikar */
88*c39526b7SPramod Gunjikar int
sol_uverbs_ib_register_client(sol_uverbs_ib_client_t * client)89*c39526b7SPramod Gunjikar sol_uverbs_ib_register_client(sol_uverbs_ib_client_t *client)
90*c39526b7SPramod Gunjikar {
91*c39526b7SPramod Gunjikar llist_head_t *entry;
92*c39526b7SPramod Gunjikar sol_uverbs_hca_t *hca;
93*c39526b7SPramod Gunjikar
94*c39526b7SPramod Gunjikar ASSERT(client != NULL);
95*c39526b7SPramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
96*c39526b7SPramod Gunjikar llist_head_init(&client->list, client);
97*c39526b7SPramod Gunjikar llist_add_tail(&client->list, &sol_uverbs_client_list);
98*c39526b7SPramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
99*c39526b7SPramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
100*c39526b7SPramod Gunjikar
101*c39526b7SPramod Gunjikar if (client->add &&
102*c39526b7SPramod Gunjikar !sol_uverbs_hca_add_client_context(hca, client)) {
103*c39526b7SPramod Gunjikar client->add(hca);
104*c39526b7SPramod Gunjikar }
105*c39526b7SPramod Gunjikar }
106*c39526b7SPramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
107*c39526b7SPramod Gunjikar
108*c39526b7SPramod Gunjikar return (0);
109*c39526b7SPramod Gunjikar }
110*c39526b7SPramod Gunjikar
111*c39526b7SPramod Gunjikar /*
112*c39526b7SPramod Gunjikar * Function:
113*c39526b7SPramod Gunjikar * sol_uverbs_ib_unregister_client
114*c39526b7SPramod Gunjikar * Input:
115*c39526b7SPramod Gunjikar * client - Pointer to the client structure
116*c39526b7SPramod Gunjikar * Output:
117*c39526b7SPramod Gunjikar * None
118*c39526b7SPramod Gunjikar * Returns:
119*c39526b7SPramod Gunjikar * None
120*c39526b7SPramod Gunjikar * Description:
121*c39526b7SPramod Gunjikar * Removes a client registration previously created with
122*c39526b7SPramod Gunjikar * the sol_uverbs_ib_register_client() call.
123*c39526b7SPramod Gunjikar */
124*c39526b7SPramod Gunjikar void
sol_uverbs_ib_unregister_client(sol_uverbs_ib_client_t * client)125*c39526b7SPramod Gunjikar sol_uverbs_ib_unregister_client(sol_uverbs_ib_client_t *client)
126*c39526b7SPramod Gunjikar {
127*c39526b7SPramod Gunjikar llist_head_t *entry, *centry, *tmp;
128*c39526b7SPramod Gunjikar sol_uverbs_hca_t *hca;
129*c39526b7SPramod Gunjikar sol_uverbs_hca_client_data_t *context;
130*c39526b7SPramod Gunjikar
131*c39526b7SPramod Gunjikar ASSERT(client != NULL);
132*c39526b7SPramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
133*c39526b7SPramod Gunjikar
134*c39526b7SPramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
135*c39526b7SPramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
136*c39526b7SPramod Gunjikar
137*c39526b7SPramod Gunjikar ASSERT(hca != NULL);
138*c39526b7SPramod Gunjikar
139*c39526b7SPramod Gunjikar if (client->remove) {
140*c39526b7SPramod Gunjikar client->remove(hca);
141*c39526b7SPramod Gunjikar }
142*c39526b7SPramod Gunjikar mutex_enter(&hca->client_data_lock);
143*c39526b7SPramod Gunjikar centry = hca->client_data_list.nxt;
144*c39526b7SPramod Gunjikar tmp = centry->nxt;
145*c39526b7SPramod Gunjikar
146*c39526b7SPramod Gunjikar while (centry != &hca->client_data_list) {
147*c39526b7SPramod Gunjikar ASSERT(centry);
148*c39526b7SPramod Gunjikar context = (sol_uverbs_hca_client_data_t *)centry->ptr;
149*c39526b7SPramod Gunjikar ASSERT(context != NULL);
150*c39526b7SPramod Gunjikar
151*c39526b7SPramod Gunjikar if (context->client == client) {
152*c39526b7SPramod Gunjikar llist_del(centry);
153*c39526b7SPramod Gunjikar kmem_free(context, sizeof (*context));
154*c39526b7SPramod Gunjikar }
155*c39526b7SPramod Gunjikar centry = tmp;
156*c39526b7SPramod Gunjikar tmp = centry->nxt;
157*c39526b7SPramod Gunjikar }
158*c39526b7SPramod Gunjikar mutex_exit(&hca->client_data_lock);
159*c39526b7SPramod Gunjikar }
160*c39526b7SPramod Gunjikar llist_del(&client->list);
161*c39526b7SPramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
162*c39526b7SPramod Gunjikar }
163*c39526b7SPramod Gunjikar
164*c39526b7SPramod Gunjikar /*
165*c39526b7SPramod Gunjikar * Function:
166*c39526b7SPramod Gunjikar * sol_uverbs_ib_get_client_data
167*c39526b7SPramod Gunjikar * Input:
168*c39526b7SPramod Gunjikar * hca - Pointer to HCA struct passed in the client
169*c39526b7SPramod Gunjikar * add function callback.
170*c39526b7SPramod Gunjikar * client - A pointer to the client structure.
171*c39526b7SPramod Gunjikar * Output:
172*c39526b7SPramod Gunjikar * None
173*c39526b7SPramod Gunjikar * Returns:
174*c39526b7SPramod Gunjikar * The client data, or NULL on error.
175*c39526b7SPramod Gunjikar * Description:
176*c39526b7SPramod Gunjikar * Returns the client data associated with the given
177*c39526b7SPramod Gunjikar * HCA. The data is set/specified via the
178*c39526b7SPramod Gunjikar * sol_uverbs_ib_set_client_data() function.
179*c39526b7SPramod Gunjikar */
180*c39526b7SPramod Gunjikar void *
sol_uverbs_ib_get_client_data(sol_uverbs_hca_t * hca,sol_uverbs_ib_client_t * client)181*c39526b7SPramod Gunjikar sol_uverbs_ib_get_client_data(sol_uverbs_hca_t *hca,
182*c39526b7SPramod Gunjikar sol_uverbs_ib_client_t *client)
183*c39526b7SPramod Gunjikar {
184*c39526b7SPramod Gunjikar llist_head_t *entry;
185*c39526b7SPramod Gunjikar sol_uverbs_hca_client_data_t *context;
186*c39526b7SPramod Gunjikar void *data = NULL;
187*c39526b7SPramod Gunjikar
188*c39526b7SPramod Gunjikar ASSERT(hca != NULL);
189*c39526b7SPramod Gunjikar ASSERT(client != NULL);
190*c39526b7SPramod Gunjikar
191*c39526b7SPramod Gunjikar mutex_enter(&hca->client_data_lock);
192*c39526b7SPramod Gunjikar
193*c39526b7SPramod Gunjikar list_for_each(entry, &hca->client_data_list) {
194*c39526b7SPramod Gunjikar context = (sol_uverbs_hca_client_data_t *)entry->ptr;
195*c39526b7SPramod Gunjikar
196*c39526b7SPramod Gunjikar ASSERT(context != NULL);
197*c39526b7SPramod Gunjikar
198*c39526b7SPramod Gunjikar if (context->client == client) {
199*c39526b7SPramod Gunjikar data = context->data;
200*c39526b7SPramod Gunjikar break;
201*c39526b7SPramod Gunjikar }
202*c39526b7SPramod Gunjikar }
203*c39526b7SPramod Gunjikar mutex_exit(&hca->client_data_lock);
204*c39526b7SPramod Gunjikar return (data);
205*c39526b7SPramod Gunjikar }
206*c39526b7SPramod Gunjikar
207*c39526b7SPramod Gunjikar /*
208*c39526b7SPramod Gunjikar * Function:
209*c39526b7SPramod Gunjikar * sol_uverbs_ib_set_client_data
210*c39526b7SPramod Gunjikar * Input:
211*c39526b7SPramod Gunjikar * hca - Pointer to HCA struct passed in the client
212*c39526b7SPramod Gunjikar * add function.
213*c39526b7SPramod Gunjikar * client - A pointer to the client structure.
214*c39526b7SPramod Gunjikar * data - The client data to associate with the HCA.
215*c39526b7SPramod Gunjikar * Output:
216*c39526b7SPramod Gunjikar * None
217*c39526b7SPramod Gunjikar * Returns:
218*c39526b7SPramod Gunjikar * None
219*c39526b7SPramod Gunjikar * Description:
220*c39526b7SPramod Gunjikar * Sets the client data associated with the given
221*c39526b7SPramod Gunjikar * HCA.
222*c39526b7SPramod Gunjikar */
223*c39526b7SPramod Gunjikar void
sol_uverbs_ib_set_client_data(sol_uverbs_hca_t * hca,sol_uverbs_ib_client_t * client,void * data)224*c39526b7SPramod Gunjikar sol_uverbs_ib_set_client_data(sol_uverbs_hca_t *hca,
225*c39526b7SPramod Gunjikar sol_uverbs_ib_client_t *client, void *data)
226*c39526b7SPramod Gunjikar {
227*c39526b7SPramod Gunjikar llist_head_t *entry;
228*c39526b7SPramod Gunjikar sol_uverbs_hca_client_data_t *context;
229*c39526b7SPramod Gunjikar
230*c39526b7SPramod Gunjikar ASSERT(hca != NULL);
231*c39526b7SPramod Gunjikar ASSERT(client != NULL);
232*c39526b7SPramod Gunjikar
233*c39526b7SPramod Gunjikar mutex_enter(&hca->client_data_lock);
234*c39526b7SPramod Gunjikar
235*c39526b7SPramod Gunjikar list_for_each(entry, &hca->client_data_list) {
236*c39526b7SPramod Gunjikar context = (sol_uverbs_hca_client_data_t *)entry->ptr;
237*c39526b7SPramod Gunjikar
238*c39526b7SPramod Gunjikar ASSERT(context != NULL);
239*c39526b7SPramod Gunjikar
240*c39526b7SPramod Gunjikar if (context->client == client) {
241*c39526b7SPramod Gunjikar context->data = data;
242*c39526b7SPramod Gunjikar goto out;
243*c39526b7SPramod Gunjikar }
244*c39526b7SPramod Gunjikar }
245*c39526b7SPramod Gunjikar SOL_OFS_DPRINTF_L5(sol_uverbs_dbg_str,
246*c39526b7SPramod Gunjikar "HCA SET CLIENT DATA: No client found for %s\n",
247*c39526b7SPramod Gunjikar client->name != NULL ? client->name : "NULL Client Name");
248*c39526b7SPramod Gunjikar
249*c39526b7SPramod Gunjikar out:
250*c39526b7SPramod Gunjikar mutex_exit(&hca->client_data_lock);
251*c39526b7SPramod Gunjikar }
252*c39526b7SPramod Gunjikar
253*c39526b7SPramod Gunjikar /*
254*c39526b7SPramod Gunjikar * Function:
255*c39526b7SPramod Gunjikar * sol_uverbs_ib_register_event_handler
256*c39526b7SPramod Gunjikar * Input:
257*c39526b7SPramod Gunjikar * handler - Pointer to handler structure
258*c39526b7SPramod Gunjikar * Output:
259*c39526b7SPramod Gunjikar * None
260*c39526b7SPramod Gunjikar * Returns:
261*c39526b7SPramod Gunjikar * Zero
262*c39526b7SPramod Gunjikar * Description:
263*c39526b7SPramod Gunjikar * Register to receive ansynchronous notifications
264*c39526b7SPramod Gunjikar * for the HCA defined in the handler struct. The notifications
265*c39526b7SPramod Gunjikar * are delivered via the callback function defined in the handler
266*c39526b7SPramod Gunjikar * struct.
267*c39526b7SPramod Gunjikar */
268*c39526b7SPramod Gunjikar int
sol_uverbs_ib_register_event_handler(sol_uverbs_ib_event_handler_t * handler)269*c39526b7SPramod Gunjikar sol_uverbs_ib_register_event_handler(sol_uverbs_ib_event_handler_t *handler)
270*c39526b7SPramod Gunjikar {
271*c39526b7SPramod Gunjikar ASSERT(handler != NULL);
272*c39526b7SPramod Gunjikar ASSERT(handler->hca != NULL);
273*c39526b7SPramod Gunjikar
274*c39526b7SPramod Gunjikar mutex_enter(&handler->hca->event_handler_lock);
275*c39526b7SPramod Gunjikar llist_head_init(&handler->list, handler);
276*c39526b7SPramod Gunjikar llist_add_tail(&handler->list, &handler->hca->event_handler_list);
277*c39526b7SPramod Gunjikar mutex_exit(&handler->hca->event_handler_lock);
278*c39526b7SPramod Gunjikar return (0);
279*c39526b7SPramod Gunjikar }
280*c39526b7SPramod Gunjikar
281*c39526b7SPramod Gunjikar /*
282*c39526b7SPramod Gunjikar * Function:
283*c39526b7SPramod Gunjikar * sol_uverbs_ib_unregister_event_handler
284*c39526b7SPramod Gunjikar * Input:
285*c39526b7SPramod Gunjikar * handler - Pointer to handler structure
286*c39526b7SPramod Gunjikar * Output:
287*c39526b7SPramod Gunjikar * None
288*c39526b7SPramod Gunjikar * Returns:
289*c39526b7SPramod Gunjikar * Zero
290*c39526b7SPramod Gunjikar * Description:
291*c39526b7SPramod Gunjikar * Unregister a ansynchronous notification handler previously
292*c39526b7SPramod Gunjikar * registered via the osl_uverbs_ib_register_event_handler() call.
293*c39526b7SPramod Gunjikar */
294*c39526b7SPramod Gunjikar int
sol_uverbs_ib_unregister_event_handler(sol_uverbs_ib_event_handler_t * handler)295*c39526b7SPramod Gunjikar sol_uverbs_ib_unregister_event_handler(sol_uverbs_ib_event_handler_t *handler)
296*c39526b7SPramod Gunjikar {
297*c39526b7SPramod Gunjikar ASSERT(handler != NULL);
298*c39526b7SPramod Gunjikar ASSERT(handler->hca != NULL);
299*c39526b7SPramod Gunjikar
300*c39526b7SPramod Gunjikar mutex_enter(&handler->hca->event_handler_lock);
301*c39526b7SPramod Gunjikar llist_del(&handler->list);
302*c39526b7SPramod Gunjikar mutex_exit(&handler->hca->event_handler_lock);
303*c39526b7SPramod Gunjikar return (0);
304*c39526b7SPramod Gunjikar }
305*c39526b7SPramod Gunjikar
306*c39526b7SPramod Gunjikar /*
307*c39526b7SPramod Gunjikar * Function:
308*c39526b7SPramod Gunjikar * sol_uverbs_common_hca_init
309*c39526b7SPramod Gunjikar * Input:
310*c39526b7SPramod Gunjikar * None
311*c39526b7SPramod Gunjikar * Output:
312*c39526b7SPramod Gunjikar * None
313*c39526b7SPramod Gunjikar * Returns:
314*c39526b7SPramod Gunjikar * Zero
315*c39526b7SPramod Gunjikar * Description:
316*c39526b7SPramod Gunjikar * Perform initialization required by the common hca client API.
317*c39526b7SPramod Gunjikar */
318*c39526b7SPramod Gunjikar int
sol_uverbs_common_hca_init()319*c39526b7SPramod Gunjikar sol_uverbs_common_hca_init()
320*c39526b7SPramod Gunjikar {
321*c39526b7SPramod Gunjikar llist_head_init(&sol_uverbs_hca_list, NULL);
322*c39526b7SPramod Gunjikar llist_head_init(&sol_uverbs_client_list, NULL);
323*c39526b7SPramod Gunjikar mutex_init(&sol_uverbs_hca_lock, NULL, MUTEX_DRIVER, NULL);
324*c39526b7SPramod Gunjikar sol_uverbs_common_hca_initialized = 1;
325*c39526b7SPramod Gunjikar return (0);
326*c39526b7SPramod Gunjikar }
327*c39526b7SPramod Gunjikar
328*c39526b7SPramod Gunjikar /*
329*c39526b7SPramod Gunjikar * Function:
330*c39526b7SPramod Gunjikar * sol_uverbs_common_hca_fini
331*c39526b7SPramod Gunjikar * Input:
332*c39526b7SPramod Gunjikar * None
333*c39526b7SPramod Gunjikar * Output:
334*c39526b7SPramod Gunjikar * None
335*c39526b7SPramod Gunjikar * Returns:
336*c39526b7SPramod Gunjikar * None
337*c39526b7SPramod Gunjikar * Description:
338*c39526b7SPramod Gunjikar * Perform cleanup required by the common hca client API.
339*c39526b7SPramod Gunjikar */
340*c39526b7SPramod Gunjikar void
sol_uverbs_common_hca_fini()341*c39526b7SPramod Gunjikar sol_uverbs_common_hca_fini()
342*c39526b7SPramod Gunjikar {
343*c39526b7SPramod Gunjikar ASSERT(llist_empty(&sol_uverbs_client_list));
344*c39526b7SPramod Gunjikar sol_uverbs_common_hca_initialized = 0;
345*c39526b7SPramod Gunjikar mutex_destroy(&sol_uverbs_hca_lock);
346*c39526b7SPramod Gunjikar }
347*c39526b7SPramod Gunjikar
348*c39526b7SPramod Gunjikar /*
349*c39526b7SPramod Gunjikar * Helpers for internal use only
350*c39526b7SPramod Gunjikar */
351*c39526b7SPramod Gunjikar /*
352*c39526b7SPramod Gunjikar * Function:
353*c39526b7SPramod Gunjikar * sol_uverbs_hca_add_client_context
354*c39526b7SPramod Gunjikar * Input:
355*c39526b7SPramod Gunjikar * hca - Pointer to the hca struct to add a client context.
356*c39526b7SPramod Gunjikar * client - Pointer to the client.
357*c39526b7SPramod Gunjikar * Output:
358*c39526b7SPramod Gunjikar * None
359*c39526b7SPramod Gunjikar * Returns:
360*c39526b7SPramod Gunjikar * 0 on success, else the error.
361*c39526b7SPramod Gunjikar * Description:
362*c39526b7SPramod Gunjikar * Create a context for the specified client and attach it to
363*c39526b7SPramod Gunjikar * the specified hca.
364*c39526b7SPramod Gunjikar */
365*c39526b7SPramod Gunjikar static
sol_uverbs_hca_add_client_context(sol_uverbs_hca_t * hca,sol_uverbs_ib_client_t * client)366*c39526b7SPramod Gunjikar int sol_uverbs_hca_add_client_context(sol_uverbs_hca_t *hca,
367*c39526b7SPramod Gunjikar sol_uverbs_ib_client_t *client)
368*c39526b7SPramod Gunjikar {
369*c39526b7SPramod Gunjikar sol_uverbs_hca_client_data_t *context;
370*c39526b7SPramod Gunjikar
371*c39526b7SPramod Gunjikar context = kmem_zalloc(sizeof (*context), KM_NOSLEEP);
372*c39526b7SPramod Gunjikar
373*c39526b7SPramod Gunjikar if (!context) {
374*c39526b7SPramod Gunjikar SOL_OFS_DPRINTF_L5(sol_uverbs_dbg_str,
375*c39526b7SPramod Gunjikar "HCA: Couldn't allocate client context for %s",
376*c39526b7SPramod Gunjikar client->name ? client->name : "Name is NULL");
377*c39526b7SPramod Gunjikar return (ENOMEM);
378*c39526b7SPramod Gunjikar }
379*c39526b7SPramod Gunjikar
380*c39526b7SPramod Gunjikar context->client = client;
381*c39526b7SPramod Gunjikar context->data = NULL;
382*c39526b7SPramod Gunjikar llist_head_init(&context->list, context);
383*c39526b7SPramod Gunjikar
384*c39526b7SPramod Gunjikar mutex_enter(&hca->client_data_lock);
385*c39526b7SPramod Gunjikar llist_add(&context->list, &hca->client_data_list);
386*c39526b7SPramod Gunjikar mutex_exit(&hca->client_data_lock);
387*c39526b7SPramod Gunjikar return (0);
388*c39526b7SPramod Gunjikar }
389*c39526b7SPramod Gunjikar
390*c39526b7SPramod Gunjikar /*
391*c39526b7SPramod Gunjikar * Function:
392*c39526b7SPramod Gunjikar * sol_uverbs_ibt_hdl_to_hca
393*c39526b7SPramod Gunjikar * Input:
394*c39526b7SPramod Gunjikar * hca_hdl - IBT handle to an HCA.
395*c39526b7SPramod Gunjikar * Output:
396*c39526b7SPramod Gunjikar * None
397*c39526b7SPramod Gunjikar * Returns:
398*c39526b7SPramod Gunjikar * A pointer to the sol_uverbs HCA structure associated with the handle,
399*c39526b7SPramod Gunjikar * or NULL if no associated HCA is found.
400*c39526b7SPramod Gunjikar * Description:
401*c39526b7SPramod Gunjikar * Given an IBT hca handle, return the user verbs HCA structure associated
402*c39526b7SPramod Gunjikar * with that handle.
403*c39526b7SPramod Gunjikar */
404*c39526b7SPramod Gunjikar sol_uverbs_hca_t *
sol_uverbs_ibt_hdl_to_hca(ibt_hca_hdl_t hca_hdl)405*c39526b7SPramod Gunjikar sol_uverbs_ibt_hdl_to_hca(ibt_hca_hdl_t hca_hdl)
406*c39526b7SPramod Gunjikar {
407*c39526b7SPramod Gunjikar llist_head_t *entry;
408*c39526b7SPramod Gunjikar sol_uverbs_hca_t *hca;
409*c39526b7SPramod Gunjikar sol_uverbs_hca_t *ret = NULL;
410*c39526b7SPramod Gunjikar
411*c39526b7SPramod Gunjikar mutex_enter(&sol_uverbs_hca_lock);
412*c39526b7SPramod Gunjikar list_for_each(entry, &sol_uverbs_hca_list) {
413*c39526b7SPramod Gunjikar hca = (sol_uverbs_hca_t *)entry->ptr;
414*c39526b7SPramod Gunjikar
415*c39526b7SPramod Gunjikar if (hca->hdl == hca_hdl) {
416*c39526b7SPramod Gunjikar ret = hca;
417*c39526b7SPramod Gunjikar break;
418*c39526b7SPramod Gunjikar }
419*c39526b7SPramod Gunjikar }
420*c39526b7SPramod Gunjikar mutex_exit(&sol_uverbs_hca_lock);
421*c39526b7SPramod Gunjikar
422*c39526b7SPramod Gunjikar return (ret);
423*c39526b7SPramod Gunjikar }
424