[IBAL, HW] Remove pointers from ci_umv_buf_t.
[mirror/winof/.git] / hw / mthca / user / mlnx_ual_ca.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 2004-2005 Mellanox Technologies, Inc. All rights reserved. \r
4  * Portions Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
5  *\r
6  * This software is available to you under the OpenIB.org BSD license\r
7  * below:\r
8  *\r
9  *     Redistribution and use in source and binary forms, with or\r
10  *     without modification, are permitted provided that the following\r
11  *     conditions are met:\r
12  *\r
13  *      - Redistributions of source code must retain the above\r
14  *        copyright notice, this list of conditions and the following\r
15  *        disclaimer.\r
16  *\r
17  *      - Redistributions in binary form must reproduce the above\r
18  *        copyright notice, this list of conditions and the following\r
19  *        disclaimer in the documentation and/or other materials\r
20  *        provided with the distribution.\r
21  *\r
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
23  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
25  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
26  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
27  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
28  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
29  * SOFTWARE.\r
30  *\r
31  * $Id$\r
32  */\r
33 \r
34 #include "mlnx_ual_main.h"\r
35 #include "mt_l2w.h"\r
36 #include "mlnx_uvp.h"\r
37 #include "mlnx_uvp_verbs.h"\r
38 #include "mx_abi.h"\r
39 \r
40 #if defined(EVENT_TRACING)\r
41 #include "mlnx_ual_ca.tmh"\r
42 #endif\r
43 \r
44 extern uint32_t mlnx_dbg_lvl;\r
45 \r
46 static ib_api_status_t\r
47 __pre_open_ca (\r
48         IN              const   ib_net64_t                                      ca_guid,\r
49         IN      OUT                     ci_umv_buf_t                            *p_umv_buf,\r
50                 OUT                     ib_ca_handle_t                          *ph_uvp_ca)\r
51 {\r
52         ib_api_status_t  status = IB_SUCCESS;\r
53 \r
54         UNREFERENCED_PARAMETER(ph_uvp_ca);\r
55                 \r
56         UVP_ENTER(UVP_DBG_SHIM);\r
57         if( p_umv_buf )\r
58         {\r
59                 if( !p_umv_buf->p_inout_buf )\r
60                 {\r
61                         p_umv_buf->p_inout_buf =\r
62                                 (ULONG_PTR)cl_zalloc( sizeof(struct ibv_get_context_resp) );\r
63                         if( !p_umv_buf->p_inout_buf )\r
64                         {\r
65                                 status = IB_INSUFFICIENT_MEMORY;\r
66                                 goto err_memory;\r
67                         }\r
68                 }\r
69                 p_umv_buf->input_size = p_umv_buf->output_size = sizeof(struct ibv_get_context_resp);\r
70                 p_umv_buf->command = TRUE;\r
71         }\r
72 err_memory:     \r
73         UVP_EXIT(UVP_DBG_SHIM);\r
74         return IB_SUCCESS;\r
75 }\r
76 \r
77 \r
78 static ib_api_status_t\r
79 __post_open_ca (\r
80         IN                              const ib_net64_t                        ca_guid,\r
81         IN                              ib_api_status_t                         ioctl_status,\r
82         IN      OUT                     ib_ca_handle_t                          *ph_uvp_ca,\r
83         IN                              ci_umv_buf_t                            *p_umv_buf )\r
84 {\r
85         ib_api_status_t  status = ioctl_status;\r
86         mlnx_ual_hobul_t *new_ca;\r
87         struct ibv_get_context_resp *p_resp;\r
88         struct ibv_context * ibvcontext;\r
89         int err;\r
90 \r
91         UVP_ENTER(UVP_DBG_SHIM);\r
92 \r
93         p_resp = (struct ibv_get_context_resp *)p_umv_buf->p_inout_buf;\r
94 \r
95         if (IB_SUCCESS == status) {\r
96                 /* allocate ibv context */\r
97                 ibvcontext = mthca_alloc_context(p_resp);\r
98                 if (IS_ERR(ibvcontext)) {\r
99                         err = PTR_ERR(ibvcontext);\r
100                         UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM ,("mthca_alloc_context failed (%d)\n", err));\r
101                         status = errno_to_iberr(err);\r
102                         goto err_alloc_context;\r
103                 }\r
104 \r
105                 /* allocate mthca context */\r
106                 new_ca = (mlnx_ual_hobul_t *)cl_zalloc( sizeof(mlnx_ual_hobul_t) );\r
107                 if( !new_ca ) {\r
108                         status = IB_INSUFFICIENT_MEMORY;\r
109                         goto err_memory;\r
110                 }\r
111 \r
112                 /* return results */\r
113                 new_ca->ibv_ctx = ibvcontext;\r
114                 new_ca->p_hca_attr = NULL;\r
115                 *ph_uvp_ca = (ib_ca_handle_t)new_ca;\r
116         }\r
117 \r
118 err_memory:     \r
119 err_alloc_context:\r
120         if (p_resp)\r
121                 cl_free( p_resp );\r
122         UVP_EXIT(UVP_DBG_SHIM);\r
123         return status;\r
124 }\r
125 \r
126 static ib_api_status_t\r
127 __pre_query_ca (\r
128         IN                              ib_ca_handle_t                          h_uvp_ca,\r
129         IN                              ib_ca_attr_t                            *p_ca_attr,\r
130         IN                              size_t                                          byte_count,\r
131         IN                              ci_umv_buf_t                            *p_umv_buf )\r
132 {\r
133         ib_api_status_t status = IB_SUCCESS;\r
134 \r
135         UVP_ENTER(UVP_DBG_SHIM);\r
136 \r
137         CL_ASSERT(h_uvp_ca);\r
138 \r
139         /*\r
140          * First time call query_ca - populate our internal cached attributes\r
141          * so we can access the GID table.  Note that query_ca calls *always*\r
142          * get their attributes from the kernel.\r
143          */\r
144         if ( !h_uvp_ca->p_hca_attr )\r
145         {\r
146                 /*\r
147                  * Assume if user buffer is valid then byte_cnt is valid too \r
148                  * so we can preallocate ca attr buffer for post ioctl data saving\r
149                  *\r
150                  * Note that we squirel the buffer away into the umv_buf and only\r
151                  * set it into the HCA if the query is successful.\r
152                  */\r
153                 if ( p_ca_attr != NULL )\r
154                 {\r
155                         p_umv_buf->p_inout_buf = (ULONG_PTR)cl_zalloc(byte_count);\r
156                         if ( !p_umv_buf->p_inout_buf )\r
157                         {\r
158                                 UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM ,\r
159                                         ("Failed to alloc new_ca\n"));\r
160                                 status = IB_INSUFFICIENT_RESOURCES;\r
161                                 return status;\r
162                         }\r
163                 }\r
164                 p_umv_buf->input_size = p_umv_buf->output_size = 0;\r
165         }\r
166 \r
167         UVP_EXIT(UVP_DBG_SHIM);\r
168         return status;\r
169 }\r
170 \r
171 \r
172 static void\r
173 __post_query_ca (\r
174         IN                              ib_ca_handle_t                          h_uvp_ca,\r
175         IN                              ib_api_status_t                         ioctl_status,\r
176         IN                              ib_ca_attr_t                            *p_ca_attr,\r
177         IN                              size_t                                          byte_count,\r
178         IN                              ci_umv_buf_t                            *p_umv_buf )\r
179 {\r
180         UVP_ENTER(UVP_DBG_SHIM);\r
181 \r
182         CL_ASSERT(h_uvp_ca);\r
183         CL_ASSERT(p_umv_buf);\r
184 \r
185         if ( ioctl_status == IB_SUCCESS && p_ca_attr &&\r
186                 byte_count && !h_uvp_ca->p_hca_attr )\r
187         {\r
188                 CL_ASSERT( byte_count >= p_ca_attr->size );\r
189                 h_uvp_ca->p_hca_attr = (ib_ca_attr_t*)(ULONG_PTR)p_umv_buf->p_inout_buf;\r
190                 ib_copy_ca_attr( h_uvp_ca->p_hca_attr, p_ca_attr );\r
191         }\r
192         else if (p_umv_buf->p_inout_buf) \r
193         {\r
194                 cl_free( (void*)(ULONG_PTR)p_umv_buf->p_inout_buf );\r
195         }\r
196 \r
197         UVP_EXIT(UVP_DBG_SHIM);\r
198         return;\r
199 }\r
200 \r
201 \r
202 static ib_api_status_t\r
203 __pre_modify_ca (\r
204     IN          ib_ca_handle_t                          h_uvp_ca,\r
205     IN          uint8_t                                         port_num,\r
206     IN          ib_ca_mod_t                                     ca_mod,\r
207     IN          const ib_port_attr_mod_t*       p_port_attr_mod)\r
208 {\r
209     UVP_ENTER(UVP_DBG_SHIM);\r
210     UVP_EXIT(UVP_DBG_SHIM);\r
211     return IB_SUCCESS;\r
212 }\r
213 \r
214 \r
215 static void\r
216 __post_modify_ca (\r
217         IN              ib_ca_handle_t                  h_uvp_ca,\r
218         IN              ib_api_status_t                 ioctl_status)\r
219 {\r
220         UVP_ENTER(UVP_DBG_SHIM);\r
221         UVP_EXIT(UVP_DBG_SHIM);\r
222 }\r
223 \r
224 \r
225 static ib_api_status_t\r
226 __pre_close_ca (\r
227         IN              ib_ca_handle_t          h_uvp_ca)\r
228 {\r
229         UVP_ENTER(UVP_DBG_SHIM);\r
230         UVP_EXIT(UVP_DBG_SHIM);\r
231         return IB_SUCCESS;\r
232 }\r
233 \r
234 \r
235 static ib_api_status_t\r
236 __post_close_ca (\r
237         IN              ib_ca_handle_t          h_uvp_ca,\r
238         IN              ib_api_status_t         ioctl_status )\r
239 {\r
240         mlnx_ual_hobul_t *p_hobul = (mlnx_ual_hobul_t *)((void*)h_uvp_ca);\r
241 \r
242         UVP_ENTER(UVP_DBG_SHIM);\r
243 \r
244         CL_ASSERT(p_hobul);\r
245 \r
246         if (IB_SUCCESS == ioctl_status) {\r
247                 if (p_hobul->ibv_ctx) {\r
248                         mthca_free_context(p_hobul->ibv_ctx);\r
249                         p_hobul->ibv_ctx = NULL;\r
250                 }\r
251 \r
252                 if (p_hobul->p_hca_attr) {\r
253                         cl_free( p_hobul->p_hca_attr);\r
254                         p_hobul->p_hca_attr = NULL;\r
255                 }\r
256 \r
257                 cl_free(p_hobul);\r
258         }\r
259         \r
260         UVP_EXIT(UVP_DBG_SHIM);\r
261         return IB_SUCCESS;\r
262 }\r
263 \r
264 void\r
265 mlnx_get_ca_interface (\r
266         IN OUT  uvp_interface_t         *p_uvp )\r
267 {\r
268         CL_ASSERT(p_uvp);\r
269 \r
270         /*\r
271          * HCA Access Verbs\r
272          */\r
273         p_uvp->pre_open_ca  = __pre_open_ca;\r
274         p_uvp->post_open_ca = __post_open_ca;\r
275 \r
276 \r
277         p_uvp->pre_query_ca  = __pre_query_ca;\r
278         p_uvp->post_query_ca = __post_query_ca;\r
279 \r
280         p_uvp->pre_modify_ca  = NULL;\r
281         p_uvp->post_modify_ca = NULL;\r
282 \r
283         p_uvp->pre_close_ca  = __pre_close_ca;\r
284         p_uvp->post_close_ca = __post_close_ca;\r
285 \r
286 }\r
287 \r
288 \r