Fix bug where UVP would return non-NULL handle in case of failure
[mirror/winof/.git] / hw / mt23108 / user / mlnx_ual_pd.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  *\r
5  * This software is available to you under the OpenIB.org BSD license\r
6  * below:\r
7  *\r
8  *     Redistribution and use in source and binary forms, with or\r
9  *     without modification, are permitted provided that the following\r
10  *     conditions are met:\r
11  *\r
12  *      - Redistributions of source code must retain the above\r
13  *        copyright notice, this list of conditions and the following\r
14  *        disclaimer.\r
15  *\r
16  *      - Redistributions in binary form must reproduce the above\r
17  *        copyright notice, this list of conditions and the following\r
18  *        disclaimer in the documentation and/or other materials\r
19  *        provided with the distribution.\r
20  *\r
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
28  * SOFTWARE.\r
29  *\r
30  * $Id$\r
31  */\r
32 \r
33 \r
34 #include "mlnx_ual_main.h"\r
35 \r
36 extern u_int32_t        mlnx_dbg_lvl;\r
37 \r
38 void\r
39 mlnx_get_pd_interface (\r
40     IN OUT      uvp_interface_t         *p_uvp )\r
41 {\r
42     FUNC_ENTER;\r
43 \r
44     CL_ASSERT(p_uvp);\r
45 \r
46     /*\r
47      * Protection Domain\r
48      */\r
49     p_uvp->pre_allocate_pd    = mlnx_pre_allocate_pd;\r
50     p_uvp->post_allocate_pd   = mlnx_post_allocate_pd;\r
51     p_uvp->pre_deallocate_pd  = mlnx_pre_deallocate_pd;\r
52     p_uvp->post_deallocate_pd = mlnx_post_deallocate_pd;\r
53 \r
54     FUNC_EXIT;\r
55 }\r
56 \r
57 \r
58     \r
59 ib_api_status_t\r
60 mlnx_pre_allocate_pd (\r
61     IN          const uvp_ca_handle_t           h_uvp_ca,\r
62     IN OUT      ci_umv_buf_t                    *p_umv_buf)\r
63 {\r
64     ib_api_status_t status = IB_SUCCESS;\r
65     mlnx_ual_hobul_t *p_hobul = (mlnx_ual_hobul_t *)((void *)h_uvp_ca);\r
66     mlnx_ual_pd_info_t *p_new_pd = NULL;\r
67     MT_size_t size;\r
68 \r
69     FUNC_ENTER;\r
70 \r
71     CL_ASSERT(p_hobul);\r
72     CL_ASSERT(p_umv_buf);\r
73 \r
74     do \r
75     {\r
76         /* CA should be initialized */\r
77         if (!p_hobul->p_hca_ul_info) \r
78         {\r
79             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
80                       ("INVALID hca_ul_info buffer\n"));\r
81             status = IB_INVALID_CA_HANDLE;\r
82             break;\r
83         }\r
84         \r
85         /* Currently supporting multiple PDs per process */\r
86         if (!p_hobul->p_hca_ul_resources) \r
87         {\r
88             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
89                       ("INVALID hca_ul_resources buffer\n"));\r
90             status = IB_RESOURCE_BUSY;\r
91             break;\r
92         }\r
93 \r
94         p_new_pd = cl_zalloc (sizeof(mlnx_ual_pd_info_t));\r
95         if (!p_new_pd) \r
96         {\r
97             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
98                       ("Failed alloc new PD\n"));\r
99             status = IB_INSUFFICIENT_MEMORY;\r
100             break;\r
101         }\r
102 \r
103         p_new_pd->p_pd_ul_resources = \r
104             cl_zalloc(p_hobul->p_hca_ul_info->pd_ul_resources_sz);\r
105         if (!p_new_pd->p_pd_ul_resources) \r
106         {\r
107             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
108                       ("Failed alloc new PD UL resources\n"));\r
109             status = IB_INSUFFICIENT_MEMORY;\r
110             break;\r
111         }\r
112 \r
113         if (HH_OK != \r
114             THHUL_pdm_alloc_pd_avs_prep (p_hobul->hhul_hca_hndl,\r
115                                          MLNX_MAX_AVS_PER_PD,\r
116                                          PD_NO_FLAGS,  // TBD \r
117                                          &p_new_pd->hhul_pd_hndl,\r
118                                          p_new_pd->p_pd_ul_resources))\r
119         {\r
120             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
121                       ("Calling THHUL_alloc_pd_prep Failed\n"));\r
122             status = IB_RESOURCE_BUSY;\r
123             break;\r
124         }\r
125         p_new_pd->p_hobul = p_hobul;\r
126         \r
127         size = p_hobul->p_hca_ul_info->pd_ul_resources_sz + \r
128                        sizeof (u_int32_t) + sizeof (mlnx_ual_pd_info_t *);\r
129 \r
130         p_umv_buf->p_inout_buf = cl_zalloc(size);\r
131 \r
132         if (!p_umv_buf->p_inout_buf)\r
133         {\r
134             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
135                       ("Failed alloc user private buffer\n"));\r
136             status = IB_INSUFFICIENT_MEMORY;\r
137             break;\r
138         }\r
139         p_umv_buf->command = TRUE;\r
140         p_umv_buf->input_size = p_umv_buf->output_size = \r
141             (uint32_t)size - sizeof (mlnx_ual_pd_info_t *); \r
142             \r
143         CL_TRACE (MLNX_TRACE_LVL_6, mlnx_dbg_lvl,\r
144                   ("umv_buf->input_size %ld, pd_ul_res_sz %d\n",\r
145                    p_umv_buf->input_size, \r
146                    p_hobul->p_hca_ul_info->pd_ul_resources_sz));\r
147 \r
148         cl_memcpy (p_umv_buf->p_inout_buf,\r
149                    p_new_pd->p_pd_ul_resources,\r
150                    p_hobul->p_hca_ul_info->pd_ul_resources_sz);\r
151         cl_memcpy (( (u_int8_t *)p_umv_buf->p_inout_buf + size - \r
152                      sizeof (mlnx_ual_pd_info_t *)),\r
153                    &p_new_pd,\r
154                    sizeof (mlnx_ual_pd_info_t *));\r
155         \r
156     } while (0);\r
157 \r
158     /* \r
159      * clean_up if required \r
160      */\r
161     if (IB_SUCCESS != status) \r
162     {\r
163         if (p_new_pd) \r
164         {\r
165             if (p_new_pd->p_pd_ul_resources);\r
166             {\r
167                 cl_free (p_new_pd->p_pd_ul_resources);\r
168 \r
169                 if (!p_umv_buf->p_inout_buf)\r
170                 {\r
171                     THHUL_pdm_free_pd_prep (p_hobul->hhul_hca_hndl, \r
172                                             p_new_pd->hhul_pd_hndl, FALSE);\r
173                     THHUL_pdm_free_pd_done (p_hobul->hhul_hca_hndl, \r
174                                             p_new_pd->hhul_pd_hndl);\r
175                 }\r
176             }\r
177             cl_free (p_new_pd);\r
178         }\r
179     }\r
180     \r
181     FUNC_EXIT;\r
182     return status;\r
183 }\r
184 \r
185 \r
186 void\r
187 mlnx_post_allocate_pd (\r
188         IN                              ib_ca_handle_t                          h_uvp_ca,\r
189         IN                              ib_api_status_t                         ioctl_status,\r
190                 OUT                     ib_pd_handle_t                          *ph_uvp_pd,\r
191         IN                              ci_umv_buf_t                            *p_umv_buf )\r
192 {\r
193         mlnx_ual_hobul_t *p_hobul = (mlnx_ual_hobul_t *)((void *)h_uvp_ca);\r
194         mlnx_ual_pd_info_t *p_new_pd;\r
195 \r
196         MT_size_t size;\r
197 \r
198         FUNC_ENTER;\r
199 \r
200         CL_ASSERT(p_hobul);\r
201         CL_ASSERT(p_umv_buf);\r
202 \r
203         size = p_hobul->p_hca_ul_info->pd_ul_resources_sz + \r
204                 sizeof (u_int32_t) + sizeof (mlnx_ual_pd_info_t *);\r
205 \r
206         cl_memcpy (&p_new_pd,\r
207                 ((u_int8_t *)p_umv_buf->p_inout_buf + size - \r
208                 sizeof (mlnx_ual_pd_info_t*)),\r
209                 sizeof (mlnx_ual_pd_info_t *));\r
210         CL_ASSERT(p_new_pd);\r
211         *ph_uvp_pd = (uvp_pd_handle_t) p_new_pd;\r
212 \r
213         if ( ioctl_status == IB_SUCCESS )\r
214         {\r
215                 if (IB_SUCCESS != p_umv_buf->status) \r
216                 {\r
217                         CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
218                                 ("post_allocate_pd return status %s\n", \r
219                                 ib_get_err_str(p_umv_buf->status)));\r
220                         goto err;\r
221                 }\r
222                 else if ((size - sizeof (mlnx_ual_pd_info_t *)) != \r
223                         p_umv_buf->output_size )\r
224                 {\r
225                         CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
226                                 ("Bad user priv buffer size exp = %d, res = %ld\n",\r
227                                 size, p_umv_buf->output_size));\r
228                         goto err;\r
229                 }\r
230 \r
231                 cl_memcpy (p_new_pd->p_pd_ul_resources,\r
232                         p_umv_buf->p_inout_buf,\r
233                         p_hobul->p_hca_ul_info->pd_ul_resources_sz);\r
234                 cl_memcpy (&p_new_pd->pd_idx,\r
235                         ((u_int8_t *)p_umv_buf->p_inout_buf + \r
236                         p_hobul->p_hca_ul_info->pd_ul_resources_sz),\r
237                         sizeof (u_int32_t));\r
238 \r
239                 if (HH_OK !=\r
240                         THHUL_pdm_alloc_pd_done (p_hobul->hhul_hca_hndl,\r
241                         p_new_pd->hhul_pd_hndl,\r
242                         p_new_pd->pd_idx,\r
243                         p_new_pd->p_pd_ul_resources))\r
244                 {\r
245                         CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
246                                 ("Call THHUL_pdm_alloc_pd_done Failed\n"));\r
247                         goto err;\r
248                 }\r
249         }\r
250         else\r
251         {\r
252 err:\r
253                 if (p_new_pd->p_pd_ul_resources)\r
254                         cl_free (p_new_pd->p_pd_ul_resources);\r
255 \r
256                 cl_free (p_new_pd);\r
257                 *ph_uvp_pd = NULL;\r
258         }\r
259 \r
260         cl_free (p_umv_buf->p_inout_buf);\r
261 \r
262         FUNC_EXIT;\r
263         return;\r
264 }\r
265 \r
266 \r
267 ib_api_status_t\r
268 mlnx_pre_deallocate_pd (\r
269     IN          const uvp_pd_handle_t           h_uvp_pd)\r
270 {\r
271     ib_api_status_t status = IB_SUCCESS;\r
272     mlnx_ual_pd_info_t *p_pd_info = (mlnx_ual_pd_info_t *)((void *)h_uvp_pd);\r
273     mlnx_ual_hobul_t *p_hobul;\r
274 \r
275     FUNC_ENTER;\r
276 \r
277     CL_ASSERT(p_pd_info);\r
278 \r
279     p_hobul = p_pd_info->p_hobul;\r
280     CL_ASSERT(p_hobul);\r
281 \r
282     do \r
283     {\r
284         if (!p_pd_info->p_pd_ul_resources) \r
285         {\r
286             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
287                       ("INVALID PD UL resources\n"));\r
288             status = IB_INVALID_PD_HANDLE;\r
289             break;\r
290         }\r
291 \r
292         if (HH_OK != THHUL_pdm_free_pd_prep(p_hobul->hhul_hca_hndl, p_pd_info->hhul_pd_hndl, FALSE))\r
293         {\r
294             CL_TRACE (MLNX_TRACE_LVL_1, mlnx_dbg_lvl,\r
295                       ("Calling THHUL_free_pd_prep Failed\n"));\r
296             status = IB_RESOURCE_BUSY;\r
297             break;\r
298                 }\r
299     } while (0);\r
300   \r
301     FUNC_EXIT;\r
302     return IB_SUCCESS;\r
303 }\r
304 \r
305 \r
306 void\r
307 mlnx_post_deallocate_pd (\r
308     IN          const uvp_pd_handle_t           h_uvp_pd,\r
309     IN          ib_api_status_t                 ioctl_status )\r
310 {\r
311     mlnx_ual_pd_info_t *p_pd_info = (mlnx_ual_pd_info_t *)((void *)h_uvp_pd);\r
312     mlnx_ual_hobul_t *p_hobul;\r
313     UNREFERENCED_PARAMETER(ioctl_status);\r
314 \r
315     FUNC_ENTER;\r
316     CL_ASSERT(p_pd_info);\r
317 \r
318     p_hobul = p_pd_info->p_hobul;\r
319     CL_ASSERT(p_hobul);\r
320 \r
321     if (p_pd_info->p_pd_ul_resources) \r
322     {\r
323         cl_free (p_pd_info->p_pd_ul_resources );\r
324         p_pd_info->p_pd_ul_resources = NULL; \r
325     }\r
326 \r
327     THHUL_pdm_free_pd_done (p_hobul->hhul_hca_hndl, p_pd_info->hhul_pd_hndl); \r
328     cl_free (p_pd_info);\r
329     FUNC_EXIT;\r
330     return;\r
331 }\r