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