c432f2cd3244fc29b5abeb412c62eec5e1994002
[mirror/winof/.git] / hw / mlx4 / kernel / hca / pd.c
1 /*
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
3  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 
4  *
5  * This software is available to you under the OpenIB.org BSD license
6  * below:
7  *
8  *     Redistribution and use in source and binary forms, with or
9  *     without modification, are permitted provided that the following
10  *     conditions are met:
11  *
12  *      - Redistributions of source code must retain the above
13  *        copyright notice, this list of conditions and the following
14  *        disclaimer.
15  *
16  *      - Redistributions in binary form must reproduce the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer in the documentation and/or other materials
19  *        provided with the distribution.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
25  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
26  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28  * SOFTWARE.
29  *
30  * $Id: al.c 1611 2006-08-20 14:48:55Z sleybo $
31  */
32
33 #include "precomp.h"
34 #if defined(EVENT_TRACING)
35 #ifdef offsetof
36 #undef offsetof
37 #endif
38 #include "pd.tmh"
39 #endif
40
41
42 /* Protection domains */
43
44 ib_api_status_t
45 mlnx_allocate_pd (
46         IN              const   ib_ca_handle_t                          h_ca,
47         IN              const   ib_pd_type_t                            type,
48                 OUT                     ib_pd_handle_t                          *ph_pd,
49         IN      OUT                     ci_umv_buf_t                            *p_umv_buf )
50 {
51         ib_api_status_t         status;
52         struct ib_device *p_ibdev;
53         struct ib_ucontext *p_uctx;
54         struct ib_pd *p_ib_pd;
55         struct ib_udata udata;
56         struct ibv_alloc_pd_resp *p_resp = NULL;
57         int err;
58
59         //TODO: how are we to use it ?
60         UNREFERENCED_PARAMETER(type);
61         
62         HCA_ENTER(HCA_DBG_PD);
63
64         if( p_umv_buf ) {
65                 p_uctx = (struct ib_ucontext *)h_ca;
66                 p_ibdev = p_uctx->device;
67
68                 if( p_umv_buf->command ) {
69                         // sanity checks 
70                         if (p_umv_buf->output_size < sizeof(struct ibv_alloc_pd_resp) ||
71                                 !p_umv_buf->p_inout_buf) {
72                                 status = IB_INVALID_PARAMETER;
73                                 goto err_alloc_pd;
74                         }
75
76                         // prepare user parameters
77                         p_resp = (struct ibv_alloc_pd_resp*)(void*)p_umv_buf->p_inout_buf;
78                         INIT_UDATA(&udata, NULL, &p_resp->pdn, 
79                                 0, sizeof(p_resp->pdn));
80                 }
81                 else {
82                         u32 pdn;
83                         INIT_UDATA(&udata, NULL, &pdn, 
84                                 0, sizeof(pdn));
85                 }
86         }
87         else {
88                 mlnx_hca_t *p_hca = (mlnx_hca_t *)h_ca;
89                 p_ibdev = hca2ibdev(p_hca);
90                 p_uctx = NULL;
91         }
92         
93         // create PD
94         p_ib_pd = p_ibdev->alloc_pd(p_ibdev, p_uctx, &udata);
95
96         if (IS_ERR(p_ib_pd)){
97                 err = PTR_ERR(p_ib_pd);
98                 status = errno_to_iberr(err);
99                 HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_PD,
100                         ("ibv_alloc_pd failed (%#x)\n", status));
101                 goto err_alloc_pd;
102         }
103         else {
104                 p_ib_pd->device  = p_ibdev;
105                 p_ib_pd->p_uctx = p_uctx;
106                 atomic_set(&p_ib_pd->usecnt, 0);
107                 HCA_PRINT(TRACE_LEVEL_INFORMATION ,HCA_DBG_PD ,("pdn %d, usecnt %d, pd_handle %p, ctx %p \n", 
108                         ((struct mlx4_ib_pd*)p_ib_pd)->pdn, p_ib_pd->usecnt, p_ib_pd, p_ib_pd->p_uctx));
109         }
110
111         // complete user response
112         if (p_umv_buf && p_umv_buf->command) {
113                 p_resp->pd_handle = (u64)(ULONG_PTR)p_ib_pd;
114         }
115         
116         // return the result
117         if (ph_pd) *ph_pd = (ib_pd_handle_t)p_ib_pd;
118
119         status = IB_SUCCESS;
120         
121 err_alloc_pd:   
122         if (p_umv_buf && p_umv_buf->command) 
123                 p_umv_buf->status = status;
124         HCA_EXIT(HCA_DBG_PD);
125         return status;
126 }
127
128 ib_api_status_t
129 mlnx_deallocate_pd (
130         IN                              ib_pd_handle_t                          h_pd)
131 {
132         ib_api_status_t         status;
133         int err;
134         struct ib_pd *p_ib_pd = (struct ib_pd *)h_pd;
135
136         HCA_ENTER( HCA_DBG_PD);
137
138         HCA_PRINT(TRACE_LEVEL_INFORMATION,HCA_DBG_PD,
139                 ("pcs %p\n", PsGetCurrentProcess()));
140         
141         if (!hca_is_livefish(p_ib_pd->device->x.p_fdo)) {
142                 if (atomic_read(&p_ib_pd->usecnt)) {
143                         HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_PD,
144                                 ("resources are not released (pdn %d, cnt %d)\n", 
145                                 ((struct mlx4_ib_pd*)p_ib_pd)->pdn, p_ib_pd->usecnt));
146                         status = IB_RESOURCE_BUSY;
147                         goto err_dealloc_pd;
148                 }               
149         }
150
151         err = p_ib_pd->device->dealloc_pd(p_ib_pd);
152         if (err) {
153                 status = errno_to_iberr(err);
154                 HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_PD
155                         ,("ibv_dealloc_pd failed (%#x)\n", status));
156                 goto err_dealloc_pd;
157         }
158         status = IB_SUCCESS;
159
160 err_dealloc_pd:
161         HCA_EXIT(HCA_DBG_PD);
162         return status;
163 }
164
165
166 void
167 mlnx_pd_if(
168         IN      OUT                     ci_interface_t                          *p_interface )
169 {
170         p_interface->allocate_pd = mlnx_allocate_pd;
171         p_interface->deallocate_pd = mlnx_deallocate_pd;
172 }
173