[AL] fix XP build errors
[mirror/winof/.git] / core / al / kernel / al_proxy_ndi.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  * Copyright (c) 1996-2003 Intel Corporation. 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: al_proxy_verbs.c 548 2006-11-27 20:03:51Z leonidk $\r
32  */\r
33 \r
34 \r
35 #include <complib/comp_lib.h>\r
36 #include <iba/ib_al.h>\r
37 #include <iba/ib_al_ioctl.h>\r
38 #include "al.h"\r
39 #include "al_qp.h"\r
40 #include "al_debug.h"\r
41 #include "al_cm_cep.h"\r
42 \r
43 #if defined(EVENT_TRACING)\r
44 #ifdef offsetof\r
45 #undef offsetof\r
46 #endif\r
47 #include "al_proxy_ndi.tmh"\r
48 #endif\r
49 \r
50 #include "al_dev.h"\r
51 /* Get the internal definitions of apis for the proxy */\r
52 #include "al_ca.h"\r
53 #include "ib_common.h"\r
54 #include "al_proxy_ndi.h"\r
55 #include "al_ndi_cm.h"\r
56 \r
57 #if WINVER <= 0x501\r
58 #include "csq.h"\r
59 #endif\r
60 \r
61 /*******************************************************************\r
62  *\r
63  * IOCTLS\r
64  *\r
65  ******************************************************************/\r
66 \r
67 /*\r
68  * Process the ioctl UAL_NDI_CREATE_CQ:\r
69  */\r
70 static cl_status_t\r
71 __ndi_create_cq(\r
72         IN              void                                    *p_open_context,\r
73         IN              cl_ioctl_handle_t               h_ioctl,\r
74                 OUT     size_t                                  *p_ret_bytes )\r
75 {\r
76         ual_create_cq_ioctl_t   *p_ioctl =\r
77                 (ual_create_cq_ioctl_t *)cl_ioctl_in_buf( h_ioctl );\r
78         al_dev_open_context_t   *p_context =\r
79                 (al_dev_open_context_t *)p_open_context;\r
80         ib_ca_handle_t                  h_ca;\r
81         ib_cq_handle_t                  h_cq;\r
82         ib_cq_create_t                  cq_create;\r
83         ci_umv_buf_t                    *p_umv_buf = NULL;\r
84         ib_api_status_t                 status;\r
85         ib_pfn_event_cb_t               pfn_ev;\r
86 \r
87         AL_ENTER( AL_DBG_NDI );\r
88 \r
89         /* Validate input buffers. */\r
90         if( !cl_ioctl_in_buf( h_ioctl ) || !cl_ioctl_out_buf( h_ioctl ) ||\r
91                 cl_ioctl_in_size( h_ioctl ) != sizeof(p_ioctl->in) ||\r
92                 cl_ioctl_out_size( h_ioctl ) != sizeof(p_ioctl->out) )\r
93         {\r
94                 status = CL_INVALID_PARAMETER;\r
95                 goto exit;\r
96         }\r
97 \r
98         /* Validate CA handle */\r
99         h_ca = (ib_ca_handle_t)\r
100                 al_hdl_ref( p_context->h_al, p_ioctl->in.h_ca, AL_OBJ_TYPE_H_CA );\r
101         if( !h_ca )\r
102         {\r
103                 status = IB_INVALID_CA_HANDLE;\r
104                 goto proxy_create_cq_err1;\r
105         }\r
106 \r
107         cq_create.size = p_ioctl->in.size;\r
108 \r
109         /* Override with proxy's cq callback */\r
110         cq_create.pfn_comp_cb = ndi_cq_compl_cb;\r
111         cq_create.h_wait_obj = NULL;\r
112         pfn_ev = ndi_cq_error_cb;\r
113 \r
114         status = cpyin_umvbuf( &p_ioctl->in.umv_buf, &p_umv_buf );\r
115         if( status != IB_SUCCESS )\r
116                 goto proxy_create_cq_err2;\r
117 \r
118         status = create_cq( h_ca, &cq_create,\r
119                 (void*)(ULONG_PTR)p_ioctl->in.context, pfn_ev, &h_cq, p_umv_buf );\r
120 \r
121         if( status != IB_SUCCESS )\r
122                 goto proxy_create_cq_err2;\r
123 \r
124         status = cpyout_umvbuf( &p_ioctl->out.umv_buf, p_umv_buf );\r
125         if( status == IB_SUCCESS )\r
126         {\r
127                 p_ioctl->out.size = cq_create.size;\r
128                 p_ioctl->out.h_cq = h_cq->obj.hdl;\r
129                 h_cq->obj.hdl_valid = TRUE;\r
130                 deref_al_obj( &h_cq->obj );\r
131         }\r
132         else\r
133         {\r
134                 h_cq->obj.pfn_destroy( &h_cq->obj, NULL );\r
135 \r
136 proxy_create_cq_err2:\r
137                 cl_waitobj_deref( cq_create.h_wait_obj );\r
138 \r
139 proxy_create_cq_err1:\r
140                 p_ioctl->out.umv_buf = p_ioctl->in.umv_buf;\r
141                 p_ioctl->out.h_cq = AL_INVALID_HANDLE;\r
142                 p_ioctl->out.size = 0;\r
143         }\r
144         free_umvbuf( p_umv_buf );\r
145 \r
146         if( h_ca )\r
147                 deref_al_obj( &h_ca->obj );\r
148 \r
149         p_ioctl->out.status = status;\r
150         *p_ret_bytes = sizeof(p_ioctl->out);\r
151 \r
152 exit:\r
153         AL_EXIT( AL_DBG_NDI );\r
154         return CL_SUCCESS;\r
155 }\r
156 \r
157 \r
158 static cl_status_t\r
159 __ndi_notify_cq(\r
160         IN              void                                    *p_open_context,\r
161         IN              cl_ioctl_handle_t               h_ioctl,\r
162                 OUT     size_t                                  *p_ret_bytes )\r
163 {\r
164         cl_status_t cl_status;\r
165         ual_ndi_notify_cq_ioctl_in_t *p_ioctl;\r
166         al_dev_open_context_t *p_context;\r
167         ib_cq_handle_t h_cq;\r
168         UNUSED_PARAM(p_ret_bytes);\r
169         \r
170         AL_ENTER( AL_DBG_NDI );\r
171 \r
172         p_context = (al_dev_open_context_t*)p_open_context;\r
173         p_ioctl = (ual_ndi_notify_cq_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
174 \r
175         /* Validate user parameters. */\r
176         if( cl_ioctl_in_size( h_ioctl ) != sizeof(ual_ndi_notify_cq_ioctl_in_t) )\r
177         {\r
178                 cl_status = CL_INVALID_PARAMETER;\r
179                 goto exit;\r
180         }\r
181 \r
182         /* Validate CQ handle */\r
183         h_cq = (ib_cq_handle_t)\r
184                 al_hdl_ref( p_context->h_al, p_ioctl->h_cq, AL_OBJ_TYPE_H_CQ );\r
185         if( !h_cq )\r
186         {\r
187                 cl_status = CL_INVALID_HANDLE;\r
188                 goto exit;\r
189         }\r
190 \r
191         /* enqueue the IRP (h_cq is referenced in al_hdl_ref) */\r
192         if (p_ioctl->notify_comps)\r
193                 IoCsqInsertIrp( &h_cq->compl.csq, h_ioctl, NULL );\r
194         else\r
195                 IoCsqInsertIrp( &h_cq->error.csq, h_ioctl, NULL );\r
196 \r
197         cl_status = CL_PENDING;\r
198 \r
199 exit:\r
200         AL_EXIT( AL_DBG_NDI );\r
201         return cl_status;\r
202 }\r
203 \r
204 static cl_status_t\r
205 __ndi_cancel_cq(\r
206         IN              void                                    *p_open_context,\r
207         IN              cl_ioctl_handle_t               h_ioctl,\r
208                 OUT     size_t                                  *p_ret_bytes )\r
209 {\r
210         cl_status_t cl_status;\r
211         ib_cq_handle_t h_cq = NULL;\r
212         al_dev_open_context_t *p_context;\r
213         UNUSED_PARAM(p_ret_bytes);\r
214         \r
215         AL_ENTER( AL_DBG_NDI );\r
216 \r
217         p_context = (al_dev_open_context_t*)p_open_context;\r
218 \r
219         /* Validate user parameters. */\r
220         if( cl_ioctl_in_size( h_ioctl ) != sizeof(uint64_t) )\r
221         {\r
222                 cl_status = CL_INVALID_PARAMETER;\r
223                 goto exit;\r
224         }\r
225 \r
226         /* Validate CQ handle */\r
227         h_cq = (ib_cq_handle_t)\r
228                 al_hdl_ref( p_context->h_al, \r
229                         *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_CQ );\r
230         if( !h_cq )\r
231         {\r
232                 cl_status = CL_INVALID_HANDLE;\r
233                 goto exit;\r
234         }\r
235 \r
236         /* flush IRP queues */\r
237         ndi_cq_flush_ques( h_cq );\r
238 \r
239         cl_status = CL_SUCCESS;\r
240         deref_al_obj( &h_cq->obj );\r
241 \r
242 exit:\r
243         AL_EXIT( AL_DBG_NDI );\r
244         return cl_status;\r
245 }\r
246 \r
247 static cl_status_t\r
248 __ndi_modify_qp(\r
249         IN              void                                    *p_open_context,\r
250         IN              cl_ioctl_handle_t               h_ioctl,\r
251                 OUT     size_t                                  *p_ret_bytes )\r
252 {\r
253         cl_status_t cl_status;\r
254         ib_api_status_t status;\r
255         ib_qp_handle_t h_qp = NULL;\r
256         al_dev_open_context_t *p_context;\r
257         ual_ndi_modify_qp_ioctl_in_t *p_req = \r
258                 (ual_ndi_modify_qp_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
259 \r
260         UNUSED_PARAM(p_ret_bytes);\r
261         \r
262         AL_ENTER( AL_DBG_NDI );\r
263 \r
264         p_context = (al_dev_open_context_t*)p_open_context;\r
265 \r
266         /* Validate user parameters. */\r
267         if( cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_modify_qp_ioctl_in_t))\r
268         {\r
269                 cl_status = CL_INVALID_PARAMETER;\r
270                 goto exit;\r
271         }\r
272 \r
273         /* Validate QP handle */\r
274         h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_req->h_qp, AL_OBJ_TYPE_H_QP );\r
275         if( !h_qp )\r
276         {\r
277                 cl_status = CL_INVALID_HANDLE;\r
278                 goto exit;\r
279         }\r
280 \r
281         /* Check QP type */\r
282         if( h_qp->type != IB_QPT_RELIABLE_CONN )\r
283         {\r
284                 cl_status = CL_INVALID_HANDLE;\r
285                 goto err;\r
286         }\r
287 \r
288         /* perform the ioctl */\r
289         status = ndi_modify_qp( h_qp, &p_req->qp_mod, \r
290                 cl_ioctl_out_size( h_ioctl ), cl_ioctl_out_buf( h_ioctl ) );\r
291         if ( status != IB_SUCCESS )\r
292         {\r
293                 AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
294                         ("ndi_modify_qp returned %s.\n", ib_get_err_str(status) ) );\r
295                 cl_status = CL_ERROR;\r
296         }\r
297         else\r
298         {\r
299                 cl_status = CL_SUCCESS;\r
300                 *p_ret_bytes = cl_ioctl_out_size( h_ioctl );\r
301         }\r
302 \r
303 err:\r
304         deref_al_obj( &h_qp->obj );\r
305 \r
306 exit:\r
307         AL_EXIT( AL_DBG_NDI );\r
308         return cl_status;\r
309 }\r
310 \r
311 static cl_status_t\r
312 __ndi_req_cm(\r
313         IN              void                                    *p_open_context,\r
314         IN              cl_ioctl_handle_t               h_ioctl,\r
315                 OUT     size_t                                  *p_ret_bytes )\r
316 {\r
317         cl_status_t cl_status;\r
318         ib_qp_handle_t h_qp = NULL;\r
319         al_dev_open_context_t *p_context;\r
320         ual_ndi_req_cm_ioctl_in_t *p_req = \r
321                 (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
322         UNUSED_PARAM(p_ret_bytes);\r
323         \r
324         AL_ENTER( AL_DBG_NDI );\r
325 \r
326         p_context = (al_dev_open_context_t*)p_open_context;\r
327 \r
328         /* Validate user parameters. */\r
329         if( cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_req_cm_ioctl_in_t) )\r
330         {\r
331                 cl_status = CL_INVALID_PARAMETER;\r
332                 goto exit;\r
333         }\r
334 \r
335         /* Validate QP handle */\r
336         h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_req->h_qp, AL_OBJ_TYPE_H_QP );\r
337         if( !h_qp )\r
338         {\r
339                 cl_status = CL_INVALID_HANDLE;\r
340                 goto exit;\r
341         }\r
342 \r
343         /* Check QP type */\r
344         if( h_qp->type != IB_QPT_RELIABLE_CONN )\r
345         {\r
346                 cl_status = CL_INVALID_HANDLE;\r
347                 goto err;\r
348         }\r
349 \r
350         /* Check psize */\r
351         if ( p_req->pdata_size > sizeof(p_req->pdata) )\r
352         {\r
353                 cl_status = CL_INVALID_PARAMETER;\r
354                 goto err;\r
355         }\r
356 \r
357         /* perform the ioctl */\r
358         cl_status = ndi_req_cm( p_context->h_al, h_ioctl );\r
359 \r
360 err:\r
361         deref_al_obj( &h_qp->obj );\r
362 \r
363 exit:\r
364         AL_EXIT( AL_DBG_NDI );\r
365         return cl_status;\r
366 }\r
367 \r
368 static cl_status_t\r
369 __ndi_rep_cm(\r
370         IN              void                                    *p_open_context,\r
371         IN              cl_ioctl_handle_t               h_ioctl,\r
372                 OUT     size_t                                  *p_ret_bytes )\r
373 {\r
374         cl_status_t cl_status;\r
375         ib_qp_handle_t h_qp = NULL;\r
376         al_dev_open_context_t *p_context;\r
377         ual_ndi_rep_cm_ioctl_in_t *p_rep = \r
378                 (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
379         UNUSED_PARAM(p_ret_bytes);\r
380 \r
381         AL_ENTER( AL_DBG_NDI );\r
382 \r
383         p_context = (al_dev_open_context_t*)p_open_context;\r
384 \r
385         /* Validate user parameters. */\r
386         if( (cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_rep_cm_ioctl_in_t)) )\r
387         {\r
388                 cl_status = CL_INVALID_PARAMETER;\r
389                 goto exit;\r
390         }\r
391 \r
392         AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
393                 ("CID = %d\n", p_rep->cid) );\r
394 \r
395         /* Get and validate QP handle */\r
396         h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_rep->h_qp, AL_OBJ_TYPE_H_QP );\r
397         if( !h_qp )\r
398         {\r
399                 cl_status = CL_INVALID_HANDLE;\r
400                 goto exit;\r
401         }\r
402 \r
403         if( h_qp->type != IB_QPT_RELIABLE_CONN )\r
404         {\r
405                 cl_status = CL_INVALID_HANDLE;\r
406                 goto err;\r
407         }\r
408 \r
409         /* Check psize */\r
410         if ( p_rep->pdata_size >= sizeof(p_rep->pdata) )\r
411         {\r
412                 cl_status = CL_INVALID_PARAMETER;\r
413                 goto err;\r
414         }\r
415 \r
416         /* perform the ioctls */\r
417         cl_status = ndi_rep_cm( p_context->h_al, h_ioctl );\r
418 \r
419 err:\r
420         deref_al_obj( &h_qp->obj );\r
421 \r
422 exit:\r
423         AL_EXIT( AL_DBG_NDI );\r
424         return cl_status;\r
425 }\r
426 \r
427 \r
428 static cl_status_t\r
429 __ndi_rej_cm(\r
430         IN              void                                    *p_open_context,\r
431         IN              cl_ioctl_handle_t               h_ioctl,\r
432                 OUT     size_t                                  *p_ret_bytes )\r
433 {\r
434         al_dev_open_context_t *p_context;\r
435         ib_api_status_t status;\r
436         ual_ndi_rej_cm_ioctl_in_t *p_rej = \r
437                 (ual_ndi_rej_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
438         NTSTATUS ntstatus;\r
439         UNUSED_PARAM(p_ret_bytes);\r
440 \r
441         AL_ENTER( AL_DBG_NDI );\r
442 \r
443         p_context = (al_dev_open_context_t*)p_open_context;\r
444 \r
445         /* Check psize */\r
446         if ( p_rej->pdata_size >= sizeof(p_rej->pdata) )\r
447         {\r
448                 ntstatus = CL_INVALID_PARAMETER;\r
449                 goto exit;\r
450         }\r
451 \r
452         /* perform the ioctl */\r
453         status = al_cep_rej( p_context->h_al, p_rej->cid, IB_REJ_USER_DEFINED,\r
454                 NULL, 0, p_rej->pdata, p_rej->pdata_size);\r
455         if (status != IB_SUCCESS)\r
456         {\r
457                 ntstatus = CL_INVALID_HANDLE;\r
458                 goto exit;\r
459         }\r
460 \r
461         ntstatus = STATUS_SUCCESS;\r
462 \r
463 exit:\r
464         AL_EXIT( AL_DBG_NDI );\r
465         return ntstatus;\r
466 }\r
467 \r
468 static cl_status_t\r
469 __ndi_rtu_cm(\r
470         IN              void                                    *p_open_context,\r
471         IN              cl_ioctl_handle_t               h_ioctl,\r
472                 OUT     size_t                                  *p_ret_bytes )\r
473 {\r
474         cl_status_t cl_status;\r
475         nd_csq_t* p_csq;\r
476         al_dev_open_context_t *p_context;\r
477 \r
478         UNUSED_PARAM(p_ret_bytes);\r
479         \r
480         AL_ENTER( AL_DBG_NDI );\r
481 \r
482         p_context = (al_dev_open_context_t*)p_open_context;\r
483 \r
484         /* Validate user parameters. */\r
485         if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
486         {\r
487                 cl_status = CL_INVALID_PARAMETER;\r
488                 goto exit;\r
489         }\r
490 \r
491         p_csq = kal_cep_get_context(\r
492                 p_context->h_al,\r
493                 *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
494                 nd_cm_handler,\r
495                 nd_csq_ref\r
496                 );\r
497         if( p_csq == NULL )\r
498         {\r
499                 cl_status = CL_INVALID_HANDLE;\r
500                 goto exit;\r
501         }\r
502 \r
503         /* perform the ioctl */\r
504         cl_status = ndi_rtu_cm( p_csq, h_ioctl );\r
505 \r
506         nd_csq_release( p_csq );\r
507 \r
508 exit:\r
509         AL_EXIT( AL_DBG_NDI );\r
510         return cl_status;\r
511 }\r
512 \r
513 static cl_status_t\r
514 __ndi_dreq_cm(\r
515         IN              void                                    *p_open_context,\r
516         IN              cl_ioctl_handle_t               h_ioctl,\r
517                 OUT     size_t                                  *p_ret_bytes )\r
518 {\r
519         cl_status_t cl_status;\r
520         nd_csq_t *p_csq;\r
521         al_dev_open_context_t *p_context;\r
522 \r
523         UNUSED_PARAM(p_ret_bytes);\r
524         \r
525         AL_ENTER( AL_DBG_NDI );\r
526 \r
527         p_context = (al_dev_open_context_t*)p_open_context;\r
528 \r
529         /* Validate user parameters. */\r
530         if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
531         {\r
532                 cl_status = CL_INVALID_PARAMETER;\r
533                 goto exit;\r
534         }\r
535 \r
536         /* Validate CID */\r
537         p_csq = (nd_csq_t*)kal_cep_get_context(\r
538                 p_context->h_al,\r
539                 *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
540                 nd_cm_handler,\r
541                 nd_csq_ref\r
542                 );\r
543 \r
544         if( p_csq == NULL )\r
545         {\r
546                 cl_status = CL_CONNECTION_INVALID;\r
547                 goto exit;\r
548         }\r
549 \r
550         /* perform the ioctl */\r
551         cl_status = ndi_dreq_cm( p_csq, h_ioctl );\r
552 \r
553         nd_csq_release( p_csq );\r
554 \r
555 exit:\r
556         AL_EXIT( AL_DBG_NDI );\r
557         return cl_status;\r
558 }\r
559 \r
560 static NTSTATUS\r
561 __ndi_notify_dreq_cm(\r
562         IN              void                                    *p_open_context,\r
563         IN              cl_ioctl_handle_t               h_ioctl,\r
564                 OUT     size_t                                  *p_ret_bytes )\r
565 {\r
566         NTSTATUS status;\r
567         nd_csq_t *p_csq;\r
568         al_dev_open_context_t *p_context;\r
569 \r
570         UNUSED_PARAM(p_ret_bytes);\r
571         \r
572         AL_ENTER( AL_DBG_NDI );\r
573 \r
574         p_context = (al_dev_open_context_t*)p_open_context;\r
575 \r
576         /* Validate user parameters. */\r
577         if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
578         {\r
579                 status = STATUS_INVALID_PARAMETER;\r
580                 goto exit;\r
581         }\r
582 \r
583         /* Validate CID */\r
584         p_csq = (nd_csq_t*)kal_cep_get_context(\r
585                 p_context->h_al,\r
586                 *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
587                 nd_cm_handler,\r
588                 nd_csq_ref\r
589                 );\r
590 \r
591         if( p_csq == NULL )\r
592         {\r
593                 status = STATUS_CONNECTION_INVALID;\r
594                 goto exit;\r
595         }\r
596 \r
597         /* perform the ioctl */\r
598         status = IoCsqInsertIrpEx(\r
599                 &p_csq->csq,\r
600                 h_ioctl,\r
601                 NULL,\r
602                 (VOID*)(ULONG_PTR)NDI_CM_CONNECTED_DREQ_RCVD\r
603                 );\r
604 \r
605         nd_csq_release( p_csq );\r
606 \r
607 exit:\r
608         AL_EXIT( AL_DBG_NDI );\r
609         return status;\r
610 }\r
611 \r
612 static cl_status_t\r
613 __ndi_cancel_cm_irps(\r
614         IN              void                                    *p_open_context,\r
615         IN              cl_ioctl_handle_t               h_ioctl,\r
616                 OUT     size_t                                  *p_ret_bytes )\r
617 {\r
618         nd_csq_t *p_csq;\r
619         al_dev_open_context_t *p_context;\r
620 \r
621         UNUSED_PARAM(p_ret_bytes);\r
622         \r
623         AL_ENTER( AL_DBG_NDI );\r
624 \r
625         p_context = (al_dev_open_context_t*)p_open_context;\r
626 \r
627         /* Validate user parameters. */\r
628         if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
629         {\r
630                 AL_EXIT( AL_DBG_NDI );\r
631                 return STATUS_INVALID_PARAMETER;\r
632         }\r
633 \r
634         /* Validate CID */\r
635         p_csq = (nd_csq_t*)kal_cep_get_context(\r
636                 p_context->h_al,\r
637                 *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
638                 nd_cm_handler,\r
639                 nd_csq_ref\r
640                 );\r
641 \r
642         if( p_csq == NULL )\r
643         {\r
644                 AL_EXIT( AL_DBG_NDI );\r
645                 return STATUS_UNSUCCESSFUL;\r
646         }\r
647 \r
648         /* perform the ioctl */\r
649         ndi_cancel_cm_irps( p_csq );\r
650         nd_csq_release( p_csq );\r
651 \r
652         AL_EXIT( AL_DBG_NDI );\r
653         return STATUS_SUCCESS;\r
654 }\r
655 \r
656 static cl_status_t\r
657 __ndi_listen_cm(\r
658         IN              void                                    *p_open_context,\r
659         IN              cl_ioctl_handle_t               h_ioctl,\r
660                 OUT     size_t                                  *p_ret_bytes )\r
661 {\r
662         al_dev_open_context_t *p_context;\r
663         ual_cep_listen_ioctl_t *p_listen = \r
664                 (ual_cep_listen_ioctl_t*)cl_ioctl_in_buf( h_ioctl );\r
665         net32_t* p_cid =\r
666                 (net32_t*)cl_ioctl_out_buf( h_ioctl );\r
667 \r
668         AL_ENTER( AL_DBG_NDI );\r
669 \r
670         p_context = (al_dev_open_context_t*)p_open_context;\r
671 \r
672         /* Validate user parameters. */\r
673         if( cl_ioctl_in_size( h_ioctl ) < sizeof(*p_listen) ||\r
674                 cl_ioctl_out_size( h_ioctl ) != sizeof(*p_cid) )\r
675         {\r
676                 AL_EXIT( AL_DBG_NDI );\r
677                 return CL_INVALID_PARAMETER;\r
678         }\r
679 \r
680         /* Set the private data compare buffer to our kernel copy. */\r
681         if( p_listen->cep_listen.p_cmp_buf )\r
682                 p_listen->cep_listen.p_cmp_buf = p_listen->compare;\r
683 \r
684         AL_EXIT( AL_DBG_NDI );\r
685         return ndi_listen_cm( p_context->h_al, &p_listen->cep_listen, p_cid, p_ret_bytes );\r
686 }\r
687 \r
688 static cl_status_t\r
689 __ndi_get_req_cm(\r
690         IN              void                                    *p_open_context,\r
691         IN              cl_ioctl_handle_t               h_ioctl,\r
692                 OUT     size_t                                  *p_ret_bytes )\r
693 {\r
694         al_dev_open_context_t *p_context;\r
695         nd_csq_t *p_csq;\r
696         NTSTATUS status;\r
697 \r
698         AL_ENTER( AL_DBG_NDI );\r
699 \r
700         UNREFERENCED_PARAMETER( p_ret_bytes );\r
701 \r
702         p_context = (al_dev_open_context_t*)p_open_context;\r
703 \r
704         /* Validate user parameters. */\r
705         if( cl_ioctl_in_size( h_ioctl ) != sizeof(net32_t) ||\r
706                 cl_ioctl_out_size( h_ioctl ) != sizeof(net32_t) )\r
707         {\r
708                 AL_EXIT( AL_DBG_NDI );\r
709                 return CL_INVALID_PARAMETER;\r
710         }\r
711 \r
712         /* Validate CID */\r
713         p_csq = (nd_csq_t*)kal_cep_get_context(\r
714                 p_context->h_al,\r
715                 *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
716                 nd_cm_handler,\r
717                 nd_csq_ref\r
718                 );\r
719 \r
720         if( p_csq == NULL )\r
721         {\r
722                 AL_EXIT( AL_DBG_NDI );\r
723                 return STATUS_UNSUCCESSFUL;\r
724         }\r
725 \r
726         status = ndi_get_req_cm( p_csq, h_ioctl );\r
727         nd_csq_release( p_csq );\r
728         AL_EXIT( AL_DBG_NDI );\r
729         return status;\r
730 }\r
731 \r
732 cl_status_t\r
733 ndi_ioctl(\r
734         IN              cl_ioctl_handle_t               h_ioctl,\r
735                 OUT     size_t                                  *p_ret_bytes )\r
736 {\r
737         cl_status_t                             cl_status;\r
738         IO_STACK_LOCATION               *p_io_stack;\r
739         void                                    *p_context;\r
740 \r
741         AL_ENTER( AL_DBG_NDI );\r
742 \r
743         p_io_stack = IoGetCurrentIrpStackLocation( h_ioctl );\r
744         p_context = p_io_stack->FileObject->FsContext;\r
745 \r
746         if( !p_context )\r
747         {\r
748                 AL_EXIT( AL_DBG_DEV );\r
749                 return CL_INVALID_PARAMETER;\r
750         }\r
751 \r
752         switch( cl_ioctl_ctl_code( h_ioctl ) )\r
753         {\r
754         case UAL_NDI_CREATE_CQ:\r
755                 cl_status = __ndi_create_cq( p_context, h_ioctl, p_ret_bytes );\r
756                 break;\r
757         case UAL_NDI_NOTIFY_CQ:\r
758                 cl_status = __ndi_notify_cq( p_context, h_ioctl, p_ret_bytes );\r
759                 break;\r
760         case UAL_NDI_CANCEL_CQ:\r
761                 cl_status = __ndi_cancel_cq( p_context, h_ioctl, p_ret_bytes );\r
762                 break;\r
763         case UAL_NDI_MODIFY_QP:\r
764                 cl_status = __ndi_modify_qp( p_context, h_ioctl, p_ret_bytes );\r
765                 break;\r
766         case UAL_NDI_REQ_CM:\r
767                 cl_status = __ndi_req_cm( p_context, h_ioctl, p_ret_bytes );\r
768                 break;\r
769         case UAL_NDI_REP_CM:\r
770                 cl_status = __ndi_rep_cm( p_context, h_ioctl, p_ret_bytes );\r
771                 break;\r
772         case UAL_NDI_RTU_CM:\r
773                 cl_status = __ndi_rtu_cm( p_context, h_ioctl, p_ret_bytes );\r
774                 break;\r
775         case UAL_NDI_REJ_CM:\r
776                 cl_status = __ndi_rej_cm( p_context, h_ioctl, p_ret_bytes );\r
777                 break;\r
778         case UAL_NDI_DREQ_CM:\r
779                 cl_status = __ndi_dreq_cm( p_context, h_ioctl, p_ret_bytes );\r
780                 break;\r
781     case UAL_NDI_NOOP:\r
782         IoMarkIrpPending( h_ioctl );\r
783         if( cl_ioctl_in_size( h_ioctl ) != 0 )\r
784             h_ioctl->IoStatus.Status = STATUS_TIMEOUT;\r
785         else\r
786             h_ioctl->IoStatus.Status = CL_SUCCESS;\r
787         h_ioctl->IoStatus.Information = 0;\r
788 \r
789                 AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
790                         ("UAL_NDI_NOOP completed with %08x\n", h_ioctl->IoStatus.Status) );\r
791         IoCompleteRequest( h_ioctl, IO_NETWORK_INCREMENT );\r
792         cl_status = CL_PENDING;\r
793         break;\r
794         case UAL_NDI_NOTIFY_DREQ:\r
795                 cl_status = __ndi_notify_dreq_cm( p_context, h_ioctl, p_ret_bytes );\r
796                 break;\r
797         case UAL_NDI_CANCEL_CM_IRPS:\r
798                 cl_status = __ndi_cancel_cm_irps( p_context, h_ioctl, p_ret_bytes );\r
799                 break;\r
800         case UAL_NDI_LISTEN_CM:\r
801                 cl_status = __ndi_listen_cm( p_context, h_ioctl, p_ret_bytes );\r
802                 break;\r
803         case UAL_NDI_GET_REQ_CM:\r
804                 cl_status = __ndi_get_req_cm( p_context, h_ioctl, p_ret_bytes );\r
805                 break;\r
806         default:\r
807                 cl_status = CL_INVALID_PARAMETER;\r
808                 break;\r
809         }\r
810 \r
811         AL_EXIT( AL_DBG_NDI );\r
812         return cl_status;\r
813 }\r
814 \r