]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[IBAL] added support of NDI_CREATE_CQ, NDI_NOTIFY_CQ and NDI_CANCEL_CQ ioctls.
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 16 Sep 2007 16:54:23 +0000 (16:54 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Sun, 16 Sep 2007 16:54:23 +0000 (16:54 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@800 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

branches/Ndi/core/al/al_cq.c
branches/Ndi/core/al/al_cq.h
branches/Ndi/core/al/al_debug.h
branches/Ndi/core/al/al_dev.h
branches/Ndi/core/al/al_proxy.h
branches/Ndi/core/al/kernel/SOURCES
branches/Ndi/core/al/kernel/al_dev.c
branches/Ndi/core/al/kernel/al_proxy_ndi.c [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_proxy_ndi.h [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_proxy_verbs.c
branches/Ndi/inc/iba/ib_al_ioctl.h

index 243be6e1520d8c770303fd84c94b09f321b337d0..f70f24dba2ff437f619e33379e241853ab88dfa2 100644 (file)
@@ -44,6 +44,7 @@
 #include "al_pd.h"\r
 #include "al_qp.h"\r
 #include "al_verbs.h"\r
+#include "kernel\al_proxy_ndi.h"\r
 \r
 /*\r
  * Function prototypes.\r
@@ -208,6 +209,12 @@ destroying_cq(
                        cl_spinlock_acquire( &h_cq->obj.lock );\r
                }\r
        }\r
+\r
+#ifdef CL_KERNEL\r
+       /* cancel pending IRPS for NDI type CQ */\r
+       proxy_ndi_flush_ques( h_cq );\r
+#endif\r
+\r
        cl_spinlock_release( &h_cq->obj.lock );\r
 }\r
 \r
index d3ff45607ed8c70a41aa59b5e17a58c225f1e483..0a3302876c99b185acee32a9d1f044c7228ee50a 100644 (file)
@@ -35,8 +35,6 @@
 \r
 #include "al_ca.h"\r
 \r
-\r
-\r
 typedef void\r
 (*pfn_proc_comp_t)(\r
        IN              const   ib_cq_handle_t                          h_cq );\r
@@ -62,6 +60,18 @@ typedef ib_api_status_t
        IN              const   ib_cq_handle_t                          h_cq,\r
        IN              const   uint32_t                                        n_cqes );\r
 \r
+#ifdef CL_KERNEL\r
+\r
+typedef struct _ib_cq  ib_cq_t;\r
+\r
+typedef struct _ndi_io_csq\r
+{\r
+       IO_CSQ                                          csq;\r
+       ib_cq_t*                                        h_cq;\r
+       LIST_ENTRY                                      que;\r
+} ndi_io_csq_t;\r
+\r
+#endif\r
 \r
 /*\r
  * Completion queue information required by the access layer.  This structure\r
@@ -95,6 +105,12 @@ typedef struct _ib_cq
 \r
        ib_pfn_event_cb_t                       pfn_event_cb;\r
 \r
+       /* NDI CQ fields */\r
+#ifdef CL_KERNEL\r
+       ndi_io_csq_t                            compl;\r
+       ndi_io_csq_t                            error;\r
+#endif\r
+\r
 }      ib_cq_t;\r
 \r
 \r
index 3d24c195039ff67591e9476ae57c3554a40b30a4..d3f153424d73a5f9d2a0ad5fe990b1a938f335d9 100644 (file)
@@ -76,7 +76,7 @@ extern uint32_t                       g_al_dbg_flags;
        WPP_DEFINE_BIT( AL_DBG_QP)\\r
        WPP_DEFINE_BIT( AL_DBG_SRQ)\\r
        WPP_DEFINE_BIT( AL_DBG_MW)\\r
-       WPP_DEFINE_BIT( AL_DBG_RES4) \\r
+       WPP_DEFINE_BIT( AL_DBG_NDI) \\r
        WPP_DEFINE_BIT( AL_DBG_PROXY_CB)\\r
        WPP_DEFINE_BIT( AL_DBG_UAL)\\r
        WPP_DEFINE_BIT( AL_DBG_QUERY)\\r
@@ -111,7 +111,7 @@ extern uint32_t                     g_al_dbg_flags;
        WPP_DEFINE_BIT( AL_DBG_QP)\\r
        WPP_DEFINE_BIT( AL_DBG_SRQ)\\r
        WPP_DEFINE_BIT( AL_DBG_MW)\\r
-       WPP_DEFINE_BIT( AL_DBG_RES4) \\r
+       WPP_DEFINE_BIT( AL_DBG_NDI) \\r
        WPP_DEFINE_BIT( AL_DBG_PROXY_CB)\\r
        WPP_DEFINE_BIT( AL_DBG_UAL)\\r
        WPP_DEFINE_BIT( AL_DBG_QUERY)\\r
@@ -171,6 +171,7 @@ extern uint32_t                     g_al_dbg_flags;
 #define AL_DBG_QP              (1 << 19)\r
 #define AL_DBG_SRQ             (1 << 20)\r
 #define AL_DBG_MW              (1 << 21)\r
+#define AL_DBG_NDI             (1 << 22)\r
 #define AL_DBG_PROXY_CB        (1 << 23)\r
 #define AL_DBG_UAL             (1 << 24)\r
 #define AL_DBG_QUERY   (1 << 25)\r
index c201f326d2b1e9b89fa2ef486eb5115ed9ec8067..5529c0506f4759bd49caac0633c0cd16df305365 100644 (file)
@@ -374,6 +374,31 @@ typedef enum _al_dev_ops
 #define IS_AL_IOCTL(cmd)               \\r
        ((cmd) > AL_OPS_START && (cmd) < AL_MAXOPS)\r
 \r
+/* NDI ioctls */\r
+\r
+typedef enum _al_ndi_ops\r
+{\r
+       al_ndi_ops_start = al_maxops,\r
+\r
+       ual_ndi_create_cq_ioctl_cmd,\r
+       ual_ndi_notify_cq_ioctl_cmd,\r
+       ual_ndi_cancel_cq_ioctl_cmd,\r
+\r
+       al_ndi_maxops\r
+\r
+}      al_ndi_ops_t;\r
+\r
+#define AL_NDI_OPS_START                       IOCTL_CODE(ALDEV_KEY, al_ndi_ops_start)\r
+#define AL_NDI_MAXOPS                          IOCTL_CODE(ALDEV_KEY, al_ndi_maxops)\r
+\r
+#define IS_NDI_IOCTL(cmd)              \\r
+       ((cmd) > AL_NDI_OPS_START && (cmd) < AL_NDI_MAXOPS)\r
+\r
+/* NDI Related ioctl commands */\r
+#define UAL_NDI_CREATE_CQ              IOCTL_CODE(ALDEV_KEY, ual_ndi_create_cq_ioctl_cmd)\r
+#define UAL_NDI_NOTIFY_CQ              IOCTL_CODE(ALDEV_KEY, ual_ndi_notify_cq_ioctl_cmd)\r
+#define UAL_NDI_CANCEL_CQ              IOCTL_CODE(ALDEV_KEY, ual_ndi_cancel_cq_ioctl_cmd)\r
+\r
 /*\r
  * Various Opration Allowable on the System Helper\r
  */\r
index fccf903b9e0c6c06f18d135de86ba0878d8a2db8..ea392379196fc9aa0cd7dff9c78eaaacaa9967c6 100644 (file)
@@ -54,7 +54,6 @@
 #include "al_proxy_ioctl.h"\r
 #include "al_mcast.h"\r
 \r
-\r
 #define AL_CB_POOL_START_SIZE                  10\r
 #define AL_CB_POOL_GROW_SIZE                   5\r
 \r
@@ -238,6 +237,10 @@ cl_status_t ioc_ioctl(
        IN              cl_ioctl_handle_t               h_ioctl,\r
                OUT     size_t                                  *p_ret_bytes );\r
 \r
+cl_status_t ndi_ioctl(\r
+       IN              cl_ioctl_handle_t               h_ioctl,\r
+               OUT     size_t                                  *p_ret_bytes );\r
+\r
 boolean_t\r
 proxy_queue_cb_buf(\r
        IN              uintn_t                                 cb_type,\r
index b45085bba5f105b461ba38c23169d5ad84205915..b36e48f55997ac00fb9c916cadd873c9d7b16f84 100644 (file)
@@ -29,6 +29,7 @@ SOURCES= ibal.rc                      \
        al_proxy_ioc.c                  \\r
        al_proxy_subnet.c               \\r
        al_proxy_verbs.c                \\r
+       al_proxy_ndi.c                  \\r
        al_sa_req.c                             \\r
        al_smi.c                                \\r
        ..\al.c                                 \\r
index 1969830bb8b41988ff7460fc437400cea3f8e3fd..767d2dcc75dd8d628fe4676c1a22b42e6a2707bb 100644 (file)
@@ -460,6 +460,8 @@ al_dev_ioctl(
                cl_status = subnet_ioctl( h_ioctl, &ret_bytes );\r
        else if( IS_IOC_IOCTL(cl_ioctl_ctl_code( h_ioctl )) )\r
                cl_status = ioc_ioctl( h_ioctl, &ret_bytes );\r
+       else if( IS_NDI_IOCTL(cl_ioctl_ctl_code( h_ioctl )) )\r
+               cl_status = ndi_ioctl( h_ioctl, &ret_bytes );\r
        else\r
                cl_status = CL_INVALID_REQUEST;\r
 \r
diff --git a/branches/Ndi/core/al/kernel/al_proxy_ndi.c b/branches/Ndi/core/al/kernel/al_proxy_ndi.c
new file mode 100644 (file)
index 0000000..a21ed34
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: al_proxy_verbs.c 548 2006-11-27 20:03:51Z leonidk $
+ */
+
+
+#include <complib/comp_lib.h>
+#include <iba/ib_al.h>
+#include <iba/ib_al_ioctl.h>
+#include "al.h"
+#include "al_debug.h"
+
+#if defined(EVENT_TRACING)
+#ifdef offsetof
+#undef offsetof
+#endif
+#include "al_proxy_ndi.tmh"
+#endif
+
+#include "al_dev.h"
+/* Get the internal definitions of apis for the proxy */
+#include "al_ca.h"
+#include "al_pd.h"
+#include "al_cq.h"
+#include "ib_common.h"
+#include "al_proxy_ndi.h"
+
+/*******************************************************************
+ *
+ * Helpers
+ *
+ ******************************************************************/
+
+#pragma warning(disable:4706)
+static inline void __ndi_flush_que(
+       IN      ib_cq_handle_t                                                  h_cq,
+       IN      PIO_CSQ                                                                 Csq,
+       IN      NTSTATUS                                                                completion_code
+       )
+{
+       PIRP Irp;
+       while( Irp = IoCsqRemoveNextIrp( Csq, NULL ) )
+       {
+               cl_ioctl_complete( Irp, completion_code, 0 );
+               deref_al_obj( &h_cq->obj );
+       }
+}
+#pragma warning(default:4706)
+
+/*******************************************************************
+ *
+ * Callbacks
+ *
+ ******************************************************************/
+
+static void __ndi_cq_compl_cb(
+       IN              const   ib_cq_handle_t                          h_cq,
+       IN                              void                                            *cq_context )
+{
+       UNUSED_PARAM( cq_context );
+       AL_ENTER( AL_DBG_NDI );
+       __ndi_flush_que( h_cq, (PIO_CSQ)&h_cq->compl, STATUS_SUCCESS );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static void __ndi_cq_error_cb(
+       IN                              ib_async_event_rec_t            *p_err_rec)
+{
+       ib_cq_handle_t h_cq = p_err_rec->handle.h_cq;
+       AL_ENTER( AL_DBG_NDI );
+       __ndi_flush_que( h_cq, (PIO_CSQ)&h_cq->compl, STATUS_INTERNAL_ERROR );
+       __ndi_flush_que( h_cq, (PIO_CSQ)&h_cq->error, STATUS_INTERNAL_ERROR );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+/*******************************************************************
+ *
+ * Public routines
+ *
+ ******************************************************************/
+
+/* flush a queue of pending requests */
+void
+proxy_ndi_flush_ques(
+       IN      ib_cq_handle_t                                                  h_cq
+       )
+{
+       AL_ENTER( AL_DBG_NDI );
+       if ( h_cq->pfn_user_comp_cb == __ndi_cq_compl_cb )
+       {
+               __ndi_flush_que( h_cq, (PIO_CSQ)&h_cq->compl, STATUS_CANCELLED );
+               __ndi_flush_que( h_cq, (PIO_CSQ)&h_cq->error, STATUS_CANCELLED );
+       }
+       AL_EXIT( AL_DBG_NDI );
+}
+
+
+/*******************************************************************
+ *
+ * CSQ
+ *
+ ******************************************************************/
+
+static VOID __ndi_insert_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       ndi_io_csq_t *p_ndi_csq = (ndi_io_csq_t*)Csq;
+
+       AL_ENTER( AL_DBG_NDI );
+       InsertTailList( &p_ndi_csq->que, &Irp->Tail.Overlay.ListEntry );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static VOID __ndi_remove_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       UNUSED_PARAM( Csq );
+
+       AL_ENTER( AL_DBG_NDI );
+       RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static PIRP __ndi_peek_next_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp,
+       IN      PVOID                                                                   PeekContext
+       )
+{
+       PIRP nextIrp = NULL;
+       PLIST_ENTRY nextEntry;
+       PLIST_ENTRY listHead;
+       ndi_io_csq_t *p_ndi_csq = (ndi_io_csq_t*)Csq;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       listHead = &p_ndi_csq->que;
+
+       // 
+       // If the IRP is NULL, we will start peeking from the listhead, else
+       // we will start from that IRP onwards. This is done under the
+       // assumption that new IRPs are always inserted at the tail.
+       //
+
+       if(Irp == NULL)
+               nextEntry = listHead->Flink;
+       else
+               nextEntry = Irp->Tail.Overlay.ListEntry.Flink;
+
+       while(nextEntry != listHead) {
+               nextIrp = CONTAINING_RECORD(nextEntry, IRP, Tail.Overlay.ListEntry);
+
+               //
+               // If context is present, continue until you find a matching one.
+               // Else you break out as you got next one.
+               //
+
+               if(PeekContext) 
+               {
+                       /* for now PeekContext is not used */
+               } 
+               else
+                       break;
+
+               nextIrp = NULL;
+               nextEntry = nextEntry->Flink;
+       }
+
+       AL_EXIT( AL_DBG_NDI );
+       return nextIrp;
+}
+
+static VOID __ndi_acquire_lock(
+       IN      PIO_CSQ                                                                 Csq,
+       OUT     PKIRQL                                                                  Irql
+       )
+{
+       ndi_io_csq_t *p_ndi_csq = (ndi_io_csq_t*)Csq;
+       ib_cq_handle_t h_cq = p_ndi_csq->h_cq;
+       UNUSED_PARAM( Irql );
+
+       AL_ENTER( AL_DBG_NDI );
+       cl_spinlock_acquire( &h_cq->obj.lock );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static VOID __ndi_release_lock(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      KIRQL                                                                   Irql
+       )
+{
+       ndi_io_csq_t *p_ndi_csq = (ndi_io_csq_t*)Csq;
+       ib_cq_handle_t h_cq = p_ndi_csq->h_cq;
+       UNUSED_PARAM( Irql );
+
+       AL_ENTER( AL_DBG_NDI );
+       cl_spinlock_release( &h_cq->obj.lock );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static VOID __ndi_complete_cancelled_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       ndi_io_csq_t *p_ndi_csq = (ndi_io_csq_t*)Csq;
+       ib_cq_handle_t h_cq = p_ndi_csq->h_cq;
+
+       AL_ENTER( AL_DBG_NDI );
+       cl_ioctl_complete( Irp, CL_CANCELED, 0 );
+       deref_al_obj( &h_cq->obj );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static NTSTATUS
+__ndi_init(
+       IN                              ib_cq_handle_t                          h_cq )
+{
+
+       NTSTATUS status;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       status = IoCsqInitialize( (PIO_CSQ)&h_cq->compl, 
+               __ndi_insert_irp, __ndi_remove_irp,
+               __ndi_peek_next_irp, __ndi_acquire_lock,
+               __ndi_release_lock, __ndi_complete_cancelled_irp );
+       if ( !NT_SUCCESS( status ) )
+               goto exit;
+
+       status = IoCsqInitialize( (PIO_CSQ)&h_cq->error, 
+               __ndi_insert_irp, __ndi_remove_irp,
+               __ndi_peek_next_irp, __ndi_acquire_lock,
+               __ndi_release_lock, __ndi_complete_cancelled_irp );
+       if ( !NT_SUCCESS( status ) )
+               goto exit;
+
+       InitializeListHead( &h_cq->compl.que );
+       InitializeListHead( &h_cq->error.que );
+       h_cq->compl.h_cq = h_cq;
+       h_cq->error.h_cq = h_cq;
+       status = STATUS_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return status;
+}
+
+
+/*******************************************************************
+ *
+ * IOCTLS
+ *
+ ******************************************************************/
+
+/*
+ * Process the ioctl UAL_CREATE_CQ:
+ */
+static cl_status_t
+__ndi_create_cq(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       ual_create_cq_ioctl_t   *p_ioctl =
+               (ual_create_cq_ioctl_t *)cl_ioctl_in_buf( h_ioctl );
+       al_dev_open_context_t   *p_context =
+               (al_dev_open_context_t *)p_open_context;
+       ib_ca_handle_t                  h_ca;
+       ib_cq_handle_t                  h_cq;
+       ib_cq_create_t                  cq_create;
+       ci_umv_buf_t                    *p_umv_buf = NULL;
+       ib_api_status_t                 status;
+       ib_pfn_event_cb_t               pfn_ev;
+
+       AL_ENTER( AL_DBG_CQ );
+
+       /* Validate input buffers. */
+       if( !cl_ioctl_in_buf( h_ioctl ) || !cl_ioctl_out_buf( h_ioctl ) ||
+               cl_ioctl_in_size( h_ioctl ) != sizeof(p_ioctl->in) ||
+               cl_ioctl_out_size( h_ioctl ) != sizeof(p_ioctl->out) )
+       {
+               AL_EXIT( AL_DBG_CQ );
+               return CL_INVALID_PARAMETER;
+       }
+
+       /* Validate CA handle */
+       h_ca = (ib_ca_handle_t)
+               al_hdl_ref( p_context->h_al, p_ioctl->in.h_ca, AL_OBJ_TYPE_H_CA );
+       if( !h_ca )
+       {
+               status = IB_INVALID_CA_HANDLE;
+               goto proxy_create_cq_err1;
+       }
+
+       cq_create.size = p_ioctl->in.size;
+
+       /* Override with proxy's cq callback */
+       cq_create.pfn_comp_cb = __ndi_cq_compl_cb;
+       cq_create.h_wait_obj = NULL;
+       pfn_ev = __ndi_cq_error_cb;
+
+       status = cpyin_umvbuf( &p_ioctl->in.umv_buf, &p_umv_buf );
+       if( status != IB_SUCCESS )
+               goto proxy_create_cq_err2;
+
+       status = create_cq( h_ca, &cq_create, p_ioctl->in.context,
+               pfn_ev, &h_cq, p_umv_buf );
+
+       if( status != IB_SUCCESS )
+               goto proxy_create_cq_err2;
+
+       if( !NT_SUCCESS( __ndi_init( h_cq ) ) )
+       {
+               status = IB_ERROR;
+               goto proxy_create_cq_err3;
+       }
+       
+       status = cpyout_umvbuf( &p_ioctl->out.umv_buf, p_umv_buf );
+       if( status == IB_SUCCESS )
+       {
+               p_ioctl->out.size = cq_create.size;
+               p_ioctl->out.h_cq = h_cq->obj.hdl;
+               h_cq->obj.hdl_valid = TRUE;
+               deref_al_obj( &h_cq->obj );
+       }
+       else
+       {
+proxy_create_cq_err3:  
+               h_cq->obj.pfn_destroy( &h_cq->obj, NULL );
+
+proxy_create_cq_err2:
+               if( cq_create.h_wait_obj )
+                       cl_waitobj_deref( cq_create.h_wait_obj );
+
+proxy_create_cq_err1:
+               p_ioctl->out.umv_buf = p_ioctl->in.umv_buf;
+               p_ioctl->out.h_cq = AL_INVALID_HANDLE;
+               p_ioctl->out.size = 0;
+       }
+       free_umvbuf( p_umv_buf );
+
+       if( h_ca )
+               deref_al_obj( &h_ca->obj );
+
+       p_ioctl->out.status = status;
+       *p_ret_bytes = sizeof(p_ioctl->out);
+
+       AL_EXIT( AL_DBG_CQ );
+       return CL_SUCCESS;
+}
+
+
+static cl_status_t
+__ndi_notify_cq(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ual_ndi_notify_cq_ioctl_cmd_in_t *p_ioctl;
+       al_dev_open_context_t *p_context;
+       ib_cq_handle_t h_cq;
+       
+       AL_ENTER( AL_DBG_NDI );
+
+       p_context = (al_dev_open_context_t*)p_open_context;
+       p_ioctl = (ual_ndi_notify_cq_ioctl_cmd_in_t*)cl_ioctl_in_buf( h_ioctl );
+
+       /* Validate user parameters. */
+       if( cl_ioctl_in_size( h_ioctl ) != sizeof(ual_ndi_notify_cq_ioctl_cmd_in_t) )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate CQ handle */
+       h_cq = (ib_cq_handle_t)
+               al_hdl_ref( p_context->h_al, p_ioctl->h_cq, AL_OBJ_TYPE_H_CQ );
+       if( !h_cq )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate notification type */
+       if ( (unsigned)p_ioctl->notify_type >= (unsigned)NdCqNotifyCount)
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* enqueue the IRP */
+       ref_al_obj( &h_cq->obj );
+       if (p_ioctl->notify_type == NdCqNotifyErrors)
+               IoCsqInsertIrp( (PIO_CSQ)&h_cq->error, h_ioctl, NULL );
+       else
+               IoCsqInsertIrp( (PIO_CSQ)&h_cq->compl, h_ioctl, NULL );
+
+       *p_ret_bytes = 0;
+       cl_status = CL_PENDING;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+static cl_status_t
+__ndi_cancel_cq(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ib_cq_handle_t h_cq;
+       al_dev_open_context_t *p_context;
+       
+       AL_ENTER( AL_DBG_NDI );
+
+       p_context = (al_dev_open_context_t*)p_open_context;
+
+       /* Validate user parameters. */
+       if( cl_ioctl_in_size( h_ioctl ) != sizeof(uint64_t) )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate CQ handle */
+       h_cq = (ib_cq_handle_t)
+               al_hdl_ref( p_context->h_al, 
+                       *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_CQ );
+       if( !h_cq )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* flush IRP queues */
+       proxy_ndi_flush_ques( h_cq );
+
+       *p_ret_bytes = 0;
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+cl_status_t
+ndi_ioctl(
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t                             cl_status;
+       IO_STACK_LOCATION               *p_io_stack;
+       void                                    *p_context;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       p_io_stack = IoGetCurrentIrpStackLocation( h_ioctl );
+       p_context = p_io_stack->FileObject->FsContext;
+
+       if( !p_context )
+       {
+               AL_EXIT( AL_DBG_DEV );
+               return CL_INVALID_PARAMETER;
+       }
+
+       switch( cl_ioctl_ctl_code( h_ioctl ) )
+       {
+       case UAL_NDI_CREATE_CQ:
+               cl_status = __ndi_create_cq( p_context, h_ioctl, p_ret_bytes );
+               break;
+       case UAL_NDI_NOTIFY_CQ:
+               cl_status = __ndi_notify_cq( p_context, h_ioctl, p_ret_bytes );
+               break;
+       case UAL_NDI_CANCEL_CQ:
+               cl_status = __ndi_cancel_cq( p_context, h_ioctl, p_ret_bytes );
+               break;
+       default:
+               cl_status = CL_INVALID_PARAMETER;
+               break;
+       }
+
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
diff --git a/branches/Ndi/core/al/kernel/al_proxy_ndi.h b/branches/Ndi/core/al/kernel/al_proxy_ndi.h
new file mode 100644 (file)
index 0000000..8d5cd03
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+ * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id: al_proxy.h 33 2005-07-11 19:51:17Z ftillier $
+ */
+
+/*
+ * Abstract:
+ *     This header file defines data structures for the kernel-mode NDI support 
+ *
+ * Environment:
+ *     Kernel .
+ */
+
+
+#ifndef _ALPROXY_NDI_H_
+#define _ALPROXY_NDI_H_
+
+#ifdef CL_KERNEL
+
+#include "complib/cl_ioctl_osd.h"
+#include "al_cq.h"
+
+/* functions from al_proxy_verbs.c */
+ib_api_status_t
+cpyin_umvbuf(
+       IN              ci_umv_buf_t    *p_src,
+               OUT     ci_umv_buf_t    **pp_dst );
+
+ib_api_status_t
+cpyout_umvbuf(
+       IN              ci_umv_buf_t    *p_dest,
+       IN              ci_umv_buf_t    *p_src);
+
+void
+free_umvbuf(
+       IN                              ci_umv_buf_t                            *p_umv_buf );
+
+/* functions from al_proxy_ndi.c */
+
+void
+proxy_ndi_flush_ques(
+       IN                              ib_cq_handle_t                          h_cq );
+
+
+#endif
+
+
+#endif
+
+
+
index 5bf7db8fa87da49ee33c3945f4994f01a906d976..6dbaeab3ba8e2342a7afc1c1c5bcbf8fa2049792 100644 (file)
@@ -72,7 +72,6 @@ extern al_mgr_t                               *gp_al_mgr;
  * It is assumed that the p_buf does not have any embedded user-mode pointers\r
  */\r
 \r
-static\r
 ib_api_status_t\r
 cpyin_umvbuf(\r
        IN              ci_umv_buf_t    *p_src,\r
@@ -140,7 +139,6 @@ cpyin_umvbuf(
  * user process context may not be valid\r
  *\r
  */\r
-static\r
 ib_api_status_t\r
 cpyout_umvbuf(\r
        IN              ci_umv_buf_t    *p_dest,\r
@@ -173,7 +171,7 @@ cpyout_umvbuf(
 }\r
 \r
 \r
-static void\r
+void\r
 free_umvbuf(\r
        IN                              ci_umv_buf_t                            *p_umv_buf )\r
 {\r
index c006a6239dbbdfbd3970c8566179358bb07c4a10..0536477340062fa2b841b1ccf195a18c508cba24 100644 (file)
@@ -3399,4 +3399,50 @@ typedef struct _ual_dereg_pnp_ioctl
 *      h_pnp\r
 *              Handle to the PnP registration to deregister.\r
 *****/\r
+\r
+typedef enum _ND_CQ_NOTIFY_TYPE\r
+{\r
+       NdCqNotifyErrors = 0,\r
+       NdCqNotifyAny,\r
+       NdCqNotifySolicited,\r
+\r
+       NdCqNotifyCount\r
+       \r
+} ND_CQ_NOTIFY_TYPE;\r
+\r
+/****s* User-mode Access Layer/ual_ndi_notify_cq_ioctl_cmd_in_t\r
+* NAME\r
+*      ual_ndi_notify_cq_ioctl_cmd_in_t\r
+*\r
+* DESCRIPTION\r
+*      IOCTL structure containing the input parameters for requesting\r
+*      notification of the next event on NDI CQ.\r
+*\r
+* SYNOPSIS\r
+*/\r
+typedef struct _ual_ndi_notify_cq_ioctl_cmd_in\r
+{\r
+       uint64_t                                        h_cq;\r
+       ND_CQ_NOTIFY_TYPE                       notify_type;\r
+\r
+}      ual_ndi_notify_cq_ioctl_cmd_in_t;\r
+/*\r
+* NOTES\r
+*      This is an asynchronous IOCTL.\r
+*\r
+*      The output parameters are a ual_rearm_pnp_ioctl_out_t.\r
+*\r
+* FIELDS\r
+*      in.h_cq\r
+*              A handle to the CQ to modify.\r
+*\r
+*      in.notify_type\r
+*              Type of notification, requested.\r
+*\r
+*****/\r
+\r
+\r
+\r
+\r
+\r
 #endif /* __IB_UAL_IOCTL_H__ */\r