]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
[IBAL] added new IOCTLs GET_CID and REQ_CM
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 9 Oct 2007 18:46:56 +0000 (18:46 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 9 Oct 2007 18:46:56 +0000 (18:46 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1@851 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

17 files changed:
branches/Ndi/core/al/al_cq.c
branches/Ndi/core/al/al_cq.h
branches/Ndi/core/al/al_dev.h
branches/Ndi/core/al/al_qp.c
branches/Ndi/core/al/al_qp.h
branches/Ndi/core/al/kernel/SOURCES
branches/Ndi/core/al/kernel/al_cm_cep.c
branches/Ndi/core/al/kernel/al_cm_rdma.h
branches/Ndi/core/al/kernel/al_ndi_cm.c [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_ndi_cm.h [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_ndi_cq.c [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_ndi_cq.h [new file with mode: 0644]
branches/Ndi/core/al/kernel/al_proxy_ndi.c
branches/Ndi/core/al/kernel/al_proxy_ndi.h
branches/Ndi/inc/iba/ib_al_ioctl.h
branches/Ndi/inc/iba/ib_types.h
branches/Ndi/inc/user/iba/ib_uvp.h

index a1933f3d894b8a3a40618966f38a14e4c2cec623..d297d2e876022d94a23856a20ed25f0f7b1c6925 100644 (file)
@@ -99,8 +99,7 @@ create_cq(
        }\r
 \r
 #ifdef CL_KERNEL\r
-       /* cancel pending IRPS for NDI type CQ */\r
-       if( !NT_SUCCESS( proxy_ndi_cq_init( h_cq ) ) )\r
+       if( !NT_SUCCESS( ndi_cq_init( h_cq ) ) )\r
        {\r
                free_cq( &h_cq->obj );\r
                return IB_ERROR;\r
@@ -223,7 +222,7 @@ destroying_cq(
 \r
 #ifdef CL_KERNEL\r
        /* cancel pending IRPS for NDI type CQ */\r
-       proxy_ndi_flush_ques( h_cq );\r
+       ndi_cq_flush_ques( h_cq );\r
 #endif\r
 \r
 }\r
index 0a3302876c99b185acee32a9d1f044c7228ee50a..d3e6c52ff00215eb8a2ddfb82ea923701770c1ce 100644 (file)
@@ -64,12 +64,12 @@ typedef ib_api_status_t
 \r
 typedef struct _ib_cq  ib_cq_t;\r
 \r
-typedef struct _ndi_io_csq\r
+typedef struct _ndi_cq_csq\r
 {\r
        IO_CSQ                                          csq;\r
        ib_cq_t*                                        h_cq;\r
        LIST_ENTRY                                      que;\r
-} ndi_io_csq_t;\r
+} ndi_cq_csq_t;\r
 \r
 #endif\r
 \r
@@ -107,8 +107,8 @@ typedef struct _ib_cq
 \r
        /* NDI CQ fields */\r
 #ifdef CL_KERNEL\r
-       ndi_io_csq_t                            compl;\r
-       ndi_io_csq_t                            error;\r
+       ndi_cq_csq_t                            compl;\r
+       ndi_cq_csq_t                            error;\r
 #endif\r
 \r
 }      ib_cq_t;\r
index 5529c0506f4759bd49caac0633c0cd16df305365..eab5ada54e8239504640f835cbd41b9bce2505df 100644 (file)
@@ -383,6 +383,10 @@ typedef enum _al_ndi_ops
        ual_ndi_create_cq_ioctl_cmd,\r
        ual_ndi_notify_cq_ioctl_cmd,\r
        ual_ndi_cancel_cq_ioctl_cmd,\r
+       ual_ndi_get_cid_ioctl_cmd,\r
+       ual_ndi_req_cm_ioctl_cmd,\r
+       ual_ndi_rep_cm_ioctl_cmd,\r
+       ual_ndi_rtu_cm_ioctl_cmd,\r
 \r
        al_ndi_maxops\r
 \r
@@ -398,6 +402,10 @@ typedef enum _al_ndi_ops
 #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
+#define UAL_NDI_GET_CID                        IOCTL_CODE(ALDEV_KEY, ual_ndi_get_cid_ioctl_cmd)\r
+#define UAL_NDI_REQ_CM                 IOCTL_CODE(ALDEV_KEY, ual_ndi_req_cm_ioctl_cmd)\r
+#define UAL_NDI_REP_CM                 IOCTL_CODE(ALDEV_KEY, ual_ndi_rep_cm_ioctl_cmd)\r
+#define UAL_NDI_RTU_CM                 IOCTL_CODE(ALDEV_KEY, ual_ndi_rtu_cm_ioctl_cmd)\r
 \r
 /*\r
  * Various Opration Allowable on the System Helper\r
index 69aa89b4862277db5188d0a9da35862a96552d08..36e5f8a0ed293191f6ea593ad67ba250f717f4d8 100644 (file)
@@ -61,6 +61,7 @@
 #include "al_verbs.h"\r
 \r
 #include "ib_common.h"\r
+#include "kernel\al_proxy_ndi.h"\r
 \r
 \r
 #define UNBOUND_PORT_GUID              0\r
@@ -325,6 +326,10 @@ create_qp(
                        break;\r
                }\r
                status = init_conn_qp( (al_conn_qp_t*)h_qp, h_pd, p_qp_create, p_umv_buf );\r
+#ifdef CL_KERNEL\r
+               if( NT_SUCCESS( status ) )\r
+                       status = ndi_qp_init( h_qp );\r
+#endif\r
                break;\r
 \r
        case IB_QPT_UNRELIABLE_DGRM:\r
@@ -1123,6 +1128,9 @@ destroying_qp(
                                deref_al_obj( &h_qp->obj );\r
                        }\r
                }\r
+#ifdef CL_KERNEL\r
+               ndi_qp_deinit( h_qp );\r
+#endif\r
 \r
                /* Fall through. */\r
        case IB_QPT_UNRELIABLE_DGRM:\r
index 8b18d580b358303d82392ac7d264c89330a5ecb3..4c94dbb03f308dcf3ad7de530ae2fd70df80ac1c 100644 (file)
@@ -44,6 +44,7 @@
 #include "al_mcast.h"\r
 #ifdef CL_KERNEL\r
 #include "al_smi.h"\r
+#include "al_ndi_cm.h"\r
 #endif /* CL_KERNEL */\r
 \r
 \r
@@ -137,7 +138,7 @@ typedef struct _ib_qp
        cl_obj_rel_t                            recv_cq_rel;\r
        cl_obj_rel_t                            send_cq_rel;\r
 \r
-       ib_srq_handle_t                 h_srq;\r
+       ib_srq_handle_t                         h_srq;\r
        cl_obj_rel_t                            srq_rel;\r
 \r
        ib_pfn_event_cb_t                       pfn_event_cb;\r
@@ -152,6 +153,10 @@ typedef struct _ib_qp
        ib_pfn_init_dgrm_svc_t          pfn_init_dgrm_svc;\r
        ib_pfn_join_mcast_t                     pfn_join_mcast;\r
 \r
+#ifdef CL_KERNEL\r
+       ndi_qp_csq_t                            *p_irp_que;\r
+#endif\r
+\r
 }      ib_qp_t;\r
 \r
 \r
index b36e48f55997ac00fb9c916cadd873c9d7b16f84..6d682e3bb461a10e4f8fedd51eef17dd8c86f891 100644 (file)
@@ -30,6 +30,8 @@ SOURCES= ibal.rc                      \
        al_proxy_subnet.c               \\r
        al_proxy_verbs.c                \\r
        al_proxy_ndi.c                  \\r
+       al_ndi_cq.c                             \\r
+       al_ndi_cm.c                             \\r
        al_sa_req.c                             \\r
        al_smi.c                                \\r
        ..\al.c                                 \\r
index d4417683d4c3150997df086cb022e97337e2ca0c..c1b7bde77561c29c999fbe6547e81eddb5e7e39a 100644 (file)
@@ -1628,10 +1628,9 @@ __dreq_handler(
                if( status != IB_SUCCESS )\r
                        break;\r
 \r
-               status = __format_drep( p_cep, NULL, 0, (mad_cm_drep_t*)p_mad->p_mad_buf );\r
-               if( status != IB_SUCCESS )\r
-                       break;\r
-\r
+               p_mad->p_mad_buf->attr_id = CM_DREP_ATTR_ID;\r
+               /* __format_drep returns always SUCCESS while no private data */\r
+               __format_drep( p_cep, NULL, 0, (mad_cm_drep_t*)p_mad->p_mad_buf );\r
                __cep_send_mad( p_port_cep, p_mad );\r
                break;\r
 \r
@@ -3907,7 +3906,8 @@ __cleanup_cep(
        case CEP_STATE_LISTEN:\r
                /* Remove from listen map. */\r
                cl_rbmap_remove_item( &gp_cep_mgr->listen_map, &p_cep->listen_item );\r
-               if( !p_cep->p_cmp_buf )\r
+\r
+               if( p_cep->p_cmp_buf )\r
                {\r
                        cl_free( p_cep->p_cmp_buf );\r
                        p_cep->p_cmp_buf = NULL;\r
index 953e0c5f538787c91f8e1c33647c2879607309a0..9d88c1cf76a9a8ec334b4b8462b82df8a6893230 100644 (file)
@@ -47,7 +47,5 @@ typedef struct _cm_rdma_req
 }      PACK_SUFFIX cm_rdma_req_t;
 
 #define IB_REQ_CM_RDMA_SID_PREFIX              0x0000000001000000
-#define IB_REQ_CM_RDMA_SID_IP_PROT     252             /* a voluntary value */
-#define IB_REQ_CM_RDMA_SID_BASE                (IB_REQ_CM_RDMA_SID_PREFIX + (IB_REQ_CM_RDMA_SID_IP_PROT<<16))
 
 #endif
diff --git a/branches/Ndi/core/al/kernel/al_ndi_cm.c b/branches/Ndi/core/al/kernel/al_ndi_cm.c
new file mode 100644 (file)
index 0000000..5586e64
--- /dev/null
@@ -0,0 +1,910 @@
+/*
+ * 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_ndi_cm.tmh"
+#endif
+
+#include "al_dev.h"
+/* Get the internal definitions of apis for the proxy */
+#include "al_ca.h"
+#include "ib_common.h"
+#include "al_qp.h"
+#include "al_cm_rdma.h"
+#include "al_cm_conn.h"
+#include "al_cm_cep.h"
+#include "al_ndi_cm.h"
+
+uint32_t               g_sa_timeout = 500;
+uint32_t               g_sa_retries = 4;
+uint8_t                        g_qp_retries = QP_ATTRIB_RETRY_COUNT;
+uint8_t                        g_pkt_life_modifier = 0;
+uint8_t                        g_max_cm_retries = CM_RETRIES;
+
+/*******************************************************************
+ *
+ * CSQ
+ *
+ ******************************************************************/
+
+static VOID __ndi_insert_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_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_qp_csq_t *p_ndi_csq = (ndi_qp_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_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;
+       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;
+       UNUSED_PARAM( Irql );
+
+       AL_ENTER( AL_DBG_NDI );
+       cl_spinlock_acquire( &h_qp->obj.lock );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static VOID __ndi_release_lock(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      KIRQL                                                                   Irql
+       )
+{
+       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;
+       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;
+       UNUSED_PARAM( Irql );
+
+       AL_ENTER( AL_DBG_NDI );
+       cl_spinlock_release( &h_qp->obj.lock );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static VOID __ndi_complete_cancelled_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;
+       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       if ( (p_ndi_csq->state == NDI_CM_CONNECTING_REQ_SENT) )
+       {
+               /* Cleanup from issuing CM REQ. */
+               net32_t cid;
+
+               ref_al_obj( &h_qp->obj );
+               cid = cl_atomic_xchg( &((al_conn_qp_t*)h_qp)->cid, AL_INVALID_CID );
+               if( cid == AL_INVALID_CID || al_destroy_cep( qp_get_al( h_qp ), cid, deref_al_obj ) != IB_SUCCESS )
+               {
+                       deref_al_obj( &h_qp->obj );
+               }
+       }
+
+       if ( (p_ndi_csq->state == NDI_CM_CONNECTING_ATS_SENT) || (p_ndi_csq->state == NDI_CM_CONNECTING_QPR_SENT) )
+       {
+               /* Cleanup from issuing the query.will be performed in callbacks and then ioctl will be completed */
+               p_ndi_csq->irp_cancelled = TRUE;
+               goto exit;
+       }
+
+       cl_ioctl_complete( Irp, CL_CANCELED, 0 );
+       deref_al_obj( &h_qp->obj );
+exit:  
+       AL_EXIT( AL_DBG_NDI );
+}
+
+/* flush a queue of pending requests */
+
+#pragma warning(disable:4706)
+static inline void __ndi_flush_que(
+       IN      ndi_qp_csq_t*                                                   p_ndi_csq,
+       IN      NTSTATUS                                                                completion_code
+       )
+{
+       PIRP Irp;
+       while( Irp = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL ) )
+       {
+               cl_ioctl_complete( Irp, completion_code, 0 );
+               deref_al_obj( &p_ndi_csq->h_qp->obj );
+       }
+}
+#pragma warning(default:4706)
+
+void
+ndi_qp_flush_ques(
+       IN      ib_qp_handle_t                                                  h_qp
+       )
+{
+       AL_ENTER( AL_DBG_NDI );
+       __ndi_flush_que( h_qp->p_irp_que, STATUS_CANCELLED );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+
+
+NTSTATUS
+ndi_qp_init(
+       IN                              ib_qp_handle_t                          h_qp )
+{
+
+       NTSTATUS status;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       h_qp->p_irp_que = (ndi_qp_csq_t*)cl_zalloc(sizeof(ndi_qp_csq_t));
+       if (!h_qp->p_irp_que)
+       {
+               status = STATUS_NO_MEMORY;
+               goto exit;
+       }
+
+       status = IoCsqInitialize( &h_qp->p_irp_que->csq, 
+               __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_qp->p_irp_que->que );
+       h_qp->p_irp_que->h_qp = h_qp;
+       h_qp->p_irp_que->h_query = NULL;
+       h_qp->p_irp_que->state = NDI_CM_IDLE;
+       status = STATUS_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return status;
+}
+
+void
+ndi_qp_deinit(
+       IN              ib_qp_handle_t                                  h_qp )
+{
+       if (h_qp->p_irp_que)
+       {
+               /* cancel pending IRPS for NDI type CQ */
+               ndi_qp_flush_ques( h_qp );
+
+               /* free NDI context */
+               cl_free( h_qp->p_irp_que );
+               h_qp->p_irp_que = NULL;
+       }
+}
+
+
+/*******************************************************************
+ *
+ * Helpers
+ *
+ ******************************************************************/
+
+static char * State2String(ndi_cm_state_t state) 
+{
+       switch (state) 
+       {
+               case NDI_CM_IDLE                                        : return "NDI_CM_IDLE";
+               case NDI_CM_CONNECTING_ATS_SENT         : return "NDI_CM_CONNECTING_ATS_SENT";
+               case NDI_CM_CONNECTING_QPR_SENT         : return "NDI_CM_CONNECTING_QPR_SENT";
+               case NDI_CM_CONNECTING_REQ_SENT         : return "NDI_CM_CONNECTING_REQ_SENT";
+               case NDI_CM_CONNECTING_REP_RCVD         : return "NDI_CM_CONNECTING_REP_RCVD";
+               case NDI_CM_CONNECTING_REJ_RCVD         : return "NDI_CM_CONNECTING_REJ_RCVD";
+               case NDI_CM_CONNECTING_RTU_SENT         : return "NDI_CM_CONNECTING_RTU_SENT";
+               case NDI_CM_CONNECTED                           : return "NDI_CM_CONNECTED";
+               case NDI_CM_BOUND                                       : return "NDI_CM_BOUND";
+               case NDI_CM_LISTENING                           : return "NDI_CM_LISTENING";
+               case NDI_CM_REP_SENT                            : return "NDI_CM_REP_SENT";
+               case NDI_CM_CONNECTED_DREP_SENT         : return "NDI_CM_CONNECTED_DREP_SENT";
+               case NDI_CM_CONNECTED_DREQ_SENT         : return "NDI_CM_CONNECTED_DREQ_SENT";
+               default : 
+                       ASSERT(FALSE);
+       }
+       return "Unknown state";
+}
+
+
+
+/*******************************************************************
+ *
+ * REQ CM request
+ *
+ ******************************************************************/
+
+
+/*
+ * A user-specified callback that is invoked after receiving a connection
+ * request reply message (REP).
+ */
+
+static void
+__ndi_proc_rep(
+       IN                              ib_cm_handle_t* const           p_cm,
+       IN                              mad_cm_rep_t* const                     p_rep )
+{
+       NTSTATUS status;
+       cl_ioctl_handle_t h_ioctl;
+       ndi_rep_rec_t *p_rep_rec = &p_cm->h_qp->p_irp_que->mad_info.rep;
+       ndi_qp_csq_t *p_ndi_csq = p_cm->h_qp->p_irp_que;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       AL_PRINT(TRACE_LEVEL_INFORMATION ,AL_DBG_NDI ,("h_qp = 0x%p\n", p_cm->h_qp));
+
+       /* fill the rec data */
+       memcpy( p_rep_rec->pdata, p_rep->pdata, sizeof(p_rep_rec->pdata) );
+
+       if ( p_ndi_csq->state  != NDI_CM_CONNECTING_REQ_SENT) 
+       {
+               // This is not the state that we waited for, not much that we can do
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, 
+                       ("Not the expected state %s\n", State2String( p_ndi_csq->state )));
+               ASSERT(FALSE);
+               goto exit;
+       }
+
+       p_ndi_csq->state = NDI_CM_CONNECTING_REP_RCVD;
+       status = STATUS_SUCCESS;
+
+       h_ioctl = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL );
+       if (!h_ioctl)
+               goto exit;
+       cl_ioctl_complete( h_ioctl, status, 0 );
+       deref_al_obj( &p_cm->h_qp->obj );
+exit:  
+       AL_EXIT( AL_DBG_NDI );
+}
+
+/*
+ * A user-specified callback that is invoked after receiving a connection
+ * rejection message (REJ).
+ */
+       
+       
+void
+__ndi_proc_rej(
+       IN              const   ib_cm_handle_t* const           p_cm,
+       IN              const   mad_cm_rej_t* const             p_rej )
+{
+       net32_t cid;
+       NTSTATUS status;
+       cl_ioctl_handle_t h_ioctl;
+       ndi_rej_rec_t *p_rej_rec;
+       ndi_qp_csq_t *p_ndi_csq;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       if( !p_cm->h_qp )
+               goto exit;
+       p_rej_rec = &p_cm->h_qp->p_irp_que->mad_info.rej;
+       p_ndi_csq = p_cm->h_qp->p_irp_que;
+
+       /* fill the rej data */
+       memcpy( p_rej_rec->pdata, p_rej->pdata, sizeof(p_rej_rec->pdata));
+
+       AL_PRINT(TRACE_LEVEL_INFORMATION, AL_DBG_NDI, 
+               ("h_qp %p connect reject, reason=%d\n", p_cm->h_qp, cl_ntoh16(p_rej->reason) ) );
+
+       //TODO: do we need to do it here ? Can we do it from DISPATCH_LEVEL ? 
+       ref_al_obj( &p_cm->h_qp->obj );
+       cid = cl_atomic_xchg( &((al_conn_qp_t*)p_cm->h_qp)->cid, AL_INVALID_CID );
+       CL_ASSERT( cid == p_cm->cid || cid == AL_INVALID_CID );
+       if( cid == AL_INVALID_CID ||
+               al_destroy_cep( p_cm->h_al, cid, deref_al_obj ) != IB_SUCCESS )
+       {
+               deref_al_obj( &p_cm->h_qp->obj );
+       }
+
+       if ( p_ndi_csq->state  != NDI_CM_CONNECTING_REQ_SENT) 
+       {
+               // This is not the state that we waited for, not much that we can
+               // do. (This might happen in shutdown)
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, 
+                       ("Not the expected state %s\n", State2String( p_ndi_csq->state )));
+               ASSERT(FALSE);
+               goto exit;
+       }
+
+       p_ndi_csq->state = NDI_CM_CONNECTING_REJ_RCVD;
+       status = (p_rej->reason == IB_REJ_TIMEOUT) ? STATUS_TIMEOUT : STATUS_CONNECTION_REFUSED;
+
+       h_ioctl = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL );
+       if (!h_ioctl)
+               goto exit;
+       cl_ioctl_complete( h_ioctl, status, 0 );
+       deref_al_obj( &p_cm->h_qp->obj );
+exit:  
+       AL_EXIT( AL_DBG_NDI );
+}
+
+
+
+static void
+__ndi_proc_conn(
+       IN                              ib_cm_handle_t* const           p_cm,
+       IN                              ib_mad_t* const                         p_mad )
+{
+       AL_ENTER( AL_DBG_CM );
+
+       /* Success indicates a receive. */
+       switch( p_mad->attr_id )
+       {
+       case CM_REP_ATTR_ID:
+               CL_ASSERT( ((al_conn_qp_t*)p_cm->h_qp)->cid == (int32_t)p_cm->cid ||
+                       ((al_conn_qp_t*)p_cm->h_qp)->cid == AL_INVALID_CID );
+               __ndi_proc_rep( p_cm, (mad_cm_rep_t*)p_mad );
+               break;
+       
+       case CM_REJ_ATTR_ID:
+               __ndi_proc_rej( p_cm, (mad_cm_rej_t*)p_mad );
+               break;
+
+#if 0
+       case CM_REQ_ATTR_ID:
+               CL_ASSERT( ((al_conn_qp_t*)p_cm->h_qp)->cid == (int32_t)p_cm->cid ||
+                       ((al_conn_qp_t*)p_cm->h_qp)->cid == AL_INVALID_CID );
+               __proc_peer_req( p_cm, (mad_cm_req_t*)p_mad );
+               break;
+
+       case CM_RTU_ATTR_ID:
+               CL_ASSERT( ((al_conn_qp_t*)p_cm->h_qp)->cid == (int32_t)p_cm->cid ||
+                       ((al_conn_qp_t*)p_cm->h_qp)->cid == AL_INVALID_CID );
+               __proc_rtu( p_cm, (mad_cm_rtu_t*)p_mad );
+               break;
+
+       case CM_DREQ_ATTR_ID:
+               CL_ASSERT( ((al_conn_qp_t*)p_cm->h_qp)->cid == (int32_t)p_cm->cid ||
+                       ((al_conn_qp_t*)p_cm->h_qp)->cid == AL_INVALID_CID );
+               __proc_dreq( p_cm, (mad_cm_dreq_t*)p_mad );
+               break;
+
+       case CM_DREP_ATTR_ID:
+               CL_ASSERT( ((al_conn_qp_t*)p_cm->h_qp)->cid == (int32_t)p_cm->cid ||
+                       ((al_conn_qp_t*)p_cm->h_qp)->cid == AL_INVALID_CID );
+               __proc_drep( p_cm, (mad_cm_drep_t*)p_mad );
+               break;
+#endif         
+
+       default:
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+                       ("Invalid CM recv MAD attribute ID %d.\n", p_mad->attr_id) );
+       }
+
+       AL_EXIT( AL_DBG_CM );
+}
+
+static void
+__ndi_cm_handler(
+       IN              const   ib_al_handle_t                          h_al,
+       IN              const   net32_t                                         cid )
+{
+       ib_api_status_t         status;
+       void* __ptr64           context;
+       net32_t                         new_cid;
+       ib_mad_element_t        *p_mad;
+       ib_cm_handle_t          h_cm;
+
+       AL_ENTER( AL_DBG_CM );
+
+       for( status = al_cep_poll( h_al, cid, &context, &new_cid, &p_mad );
+               status == IB_SUCCESS;
+               status = al_cep_poll( h_al, cid, &context, &new_cid, &p_mad ) )
+       {
+#if 0  
+               /* Something to do - WOOT!!! */
+               if( new_cid != AL_INVALID_CID )
+               {
+                       __proc_listen( (al_listen_t* __ptr64)context,
+                               new_cid, ib_get_mad_buf( p_mad ) );
+               }
+               else if( p_mad->status != IB_SUCCESS )
+               {
+                       /* Context is a QP handle, and a sent MAD timed out. */
+                       __proc_failed_send(
+                               (ib_qp_handle_t)context, ib_get_mad_buf( p_mad ) );
+               }
+               else
+#endif                 
+               {
+                       h_cm.h_al = h_al;
+                       h_cm.cid = cid;
+                       h_cm.h_qp = (ib_qp_handle_t)context;
+                       __ndi_proc_conn( &h_cm, ib_get_mad_buf( p_mad ) );
+               }
+               ib_put_mad( p_mad );
+       }
+}
+
+static void
+__ndi_fill_cm_req(
+       IN              ib_qp_handle_t  const                           h_qp,
+       IN              ual_ndi_req_cm_ioctl_in_t                       *p_req,
+       IN              ib_path_rec_t                                           *p_path_rec,
+       IN              ib_cm_req_t                                                     *p_cm_req)
+{
+       cm_rdma_req_t *p_rdma = (cm_rdma_req_t*)p_req->pdata;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       memset( p_cm_req, 0, sizeof(ib_cm_req_t) );
+
+       p_cm_req->svc_id = IB_REQ_CM_RDMA_SID_PREFIX | (p_req->prot << 16) | p_req->dst_port;
+       p_cm_req->max_cm_retries = g_max_cm_retries;
+       p_cm_req->p_primary_path = p_path_rec;  
+
+       p_cm_req->p_req_pdata = (uint8_t *)p_rdma;
+       p_cm_req->req_length = sizeof(cm_rdma_req_t);
+
+       p_cm_req->qp_type = IB_QPT_RELIABLE_CONN;
+       p_cm_req->h_qp = h_qp;
+       p_cm_req->resp_res = QP_ATTRIB_RESPONDER_RESOURCES;
+       p_cm_req->init_depth = QP_ATTRIB_INITIATOR_DEPTH;
+
+       p_cm_req->remote_resp_timeout =
+               ib_path_rec_pkt_life( p_path_rec ) + CM_REMOTE_TIMEOUT;
+       if( p_cm_req->remote_resp_timeout > 0x1F )
+               p_cm_req->remote_resp_timeout = 0x1F;
+       else if( p_cm_req->remote_resp_timeout < CM_MIN_REMOTE_TIMEOUT )
+               p_cm_req->remote_resp_timeout = CM_MIN_REMOTE_TIMEOUT;
+
+       p_cm_req->flow_ctrl = TRUE;     /* HCAs must support end-to-end flow control. */
+
+       p_cm_req->local_resp_timeout =
+               ib_path_rec_pkt_life( p_path_rec ) + CM_LOCAL_TIMEOUT;
+       if( p_cm_req->local_resp_timeout > 0x1F )
+               p_cm_req->local_resp_timeout = 0x1F;
+       else if( p_cm_req->local_resp_timeout < CM_MIN_LOCAL_TIMEOUT )
+               p_cm_req->local_resp_timeout = CM_MIN_LOCAL_TIMEOUT;
+
+       p_cm_req->rnr_nak_timeout = QP_ATTRIB_RNR_NAK_TIMEOUT;
+       p_cm_req->rnr_retry_cnt = QP_ATTRIB_RNR_RETRY;
+       p_cm_req->retry_cnt = g_qp_retries;
+       p_cm_req->p_alt_path = NULL;
+
+       AL_EXIT( AL_DBG_NDI );
+}
+
+static void AL_API
+__ndi_pr_query_cb(
+                                       ib_query_rec_t                          *p_query_rec )
+{
+       ib_api_status_t status;
+       cl_ioctl_handle_t h_ioctl;
+       ib_cm_req_t cm_req;
+       uint8_t pkt_life;
+       ib_qp_mod_t qp_mod;
+       ib_path_rec_t *p_path_rec = ib_get_query_path_rec( p_query_rec->p_result_mad, 0 );
+       ual_ndi_req_cm_ioctl_in_t *p_req = (ual_ndi_req_cm_ioctl_in_t* __ptr64)p_query_rec->query_context;
+       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_req->h_qp;
+       net32_t cid;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,
+               ("status is %d, count is %d\n", p_query_rec->status,
+               p_query_rec->result_cnt) );
+
+       h_ioctl = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+       if (!h_ioctl)
+               goto exit;
+
+       if ( h_qp->p_irp_que->irp_cancelled )
+               goto err_irp_complete;
+               
+       if( p_query_rec->status != IB_SUCCESS || !p_query_rec->result_cnt )
+               goto err_irp_complete;
+
+       /* Path Record has been received ! */
+
+       /* fix packet life */
+       CL_ASSERT( p_path_rec );
+       pkt_life = ib_path_rec_pkt_life( p_path_rec ) + g_pkt_life_modifier;
+       if( pkt_life > 0x1F )
+               pkt_life = 0x1F;
+
+       p_path_rec->pkt_life &= IB_PATH_REC_SELECTOR_MASK;
+       p_path_rec->pkt_life |= pkt_life;
+
+       /* Copy the path record */
+       h_qp->p_irp_que->path_rec = *p_path_rec;
+
+       /* Get a CEP and bind it to the QP. */
+       status = al_create_cep( qp_get_al( h_qp ), __ndi_cm_handler, h_qp, &cid );
+       if( status != IB_SUCCESS )
+       {
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+                       ("al_create_cep returned %s.\n", ib_get_err_str( status )) );
+               goto err_irp_complete;
+       }
+
+       /* Format ib_cm_req_t structure */
+       __ndi_fill_cm_req( h_qp, p_req, p_path_rec, &cm_req );
+
+       /* prepare CEP for connection */
+       status = al_cep_pre_req( qp_get_al( h_qp ),
+               ((al_conn_qp_t*)h_qp)->cid, &cm_req, &qp_mod );
+       if( status != IB_SUCCESS )
+       {
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+                       ("al_cep_pre_req returned %s.\n", ib_get_err_str( status )) );
+               goto err_cep_destroy;
+       }
+
+       /* insert IRP in the queue */
+       h_qp->p_irp_que->state = NDI_CM_CONNECTING_REQ_SENT;
+       IoCsqInsertIrp( &h_qp->p_irp_que->csq, h_ioctl, NULL );
+
+       /* send CM REQ */
+       status = al_cep_send_req( qp_get_al( h_qp ), cid );
+       if( status != IB_SUCCESS )
+               goto err_irp_remove;
+
+       /* SUCCESS ! */
+       goto exit;
+
+err_irp_remove:
+       h_ioctl = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+
+err_cep_destroy:
+       al_destroy_cep( qp_get_al( h_qp ), cid, NULL );
+       
+err_irp_complete:
+       cl_ioctl_complete( h_ioctl, STATUS_HOST_UNREACHABLE, 0 );
+       deref_al_obj( &h_qp->obj );
+
+exit:  
+       if( p_query_rec->p_result_mad )
+               ib_put_mad( p_query_rec->p_result_mad );
+
+       AL_EXIT( AL_DBG_NDI );
+}
+
+
+
+/* Synchronously query the SA for a GUID. Return 0 on success. */
+cl_status_t
+__ndi_pr_query(
+       IN              cl_ioctl_handle_t                                       h_ioctl,
+       IN              ib_query_rec_t                                          *p_query_rec )
+{
+       cl_status_t cl_status;
+       ib_service_record_t *service_record;
+       ib_gid_pair_t user_query;
+       ib_query_handle_t query_handle;
+       ib_query_req_t query_req;
+       ib_api_status_t status;
+       ib_net64_t dest_port_guid;
+       ual_ndi_req_cm_ioctl_in_t *p_req = (ual_ndi_req_cm_ioctl_in_t* __ptr64)p_query_rec->query_context;
+       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_req->h_qp;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       service_record = ib_get_query_svc_rec( p_query_rec->p_result_mad, 0 );
+       dest_port_guid = ib_gid_get_guid( &service_record->service_gid );
+
+       CL_ASSERT( service_record != NULL );
+
+       query_req.query_type = IB_QUERY_PATH_REC_BY_GIDS;
+       query_req.p_query_input = &user_query;
+       query_req.port_guid = p_req->guid;
+       query_req.timeout_ms = g_sa_timeout;
+       query_req.retry_cnt = g_sa_retries;
+       query_req.flags = 0;    /* IB_FLAGS_SYNC */
+       query_req.query_context = p_req;
+       query_req.pfn_query_cb = __ndi_pr_query_cb;
+
+       ib_gid_set_default( &user_query.src_gid, p_req->guid );
+       ib_gid_set_default( &user_query.dest_gid, dest_port_guid );
+
+       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_ERROR,
+               ("Query for path from %I64x to %I64x\n",
+               p_req->guid, dest_port_guid) );
+
+       /* insert IRP in the queue */
+       h_qp->p_irp_que->state = NDI_CM_CONNECTING_QPR_SENT;
+       IoCsqInsertIrp( &h_qp->p_irp_que->csq, h_ioctl, NULL );
+
+       status = ib_query( qp_get_al( h_qp ), &query_req, &query_handle );
+
+       if( status != IB_SUCCESS )
+       {
+               h_qp->p_irp_que->state = NDI_CM_IDLE;   
+               IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );
+               cl_status = CL_ERROR;
+               goto exit;
+       }
+
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+
+static void AL_API
+__ndi_ats_query_cb(
+       IN                              ib_query_rec_t                          *p_query_rec )
+{
+       cl_ioctl_handle_t h_ioctl;
+       cl_status_t cl_status;
+       ual_ndi_req_cm_ioctl_in_t *p_req = (ual_ndi_req_cm_ioctl_in_t* __ptr64)p_query_rec->query_context;
+       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_req->h_qp;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,
+               ("status is %d, count is %d\n", p_query_rec->status,
+               p_query_rec->result_cnt) );
+
+       h_ioctl = IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+       if (!h_ioctl)
+               goto exit;
+
+       if ( h_qp->p_irp_que->irp_cancelled )
+               goto err_irp_complete;
+               
+       if( p_query_rec->status != IB_SUCCESS || !p_query_rec->result_cnt )
+               goto err_irp_complete;
+
+       cl_status = __ndi_pr_query( h_ioctl, p_query_rec );
+       if (cl_status != CL_SUCCESS)
+               goto err_irp_complete;
+
+       /* SUCCESS */
+       goto exit;
+
+err_irp_complete:
+       cl_ioctl_complete( h_ioctl, STATUS_HOST_UNREACHABLE, 0 );
+       deref_al_obj( &h_qp->obj );
+
+exit:  
+       if( p_query_rec->p_result_mad )
+               ib_put_mad( p_query_rec->p_result_mad );
+
+       AL_EXIT( AL_DBG_NDI );
+}
+
+/* Synchronously query the SA for a GUID. Return 0 on success. */
+cl_status_t
+__ndi_ats_query(
+       IN              ib_qp_handle_t  const                           h_qp,
+       IN              cl_ioctl_handle_t                                       h_ioctl,
+       IN              ual_ndi_req_cm_ioctl_in_t                       *p_req )
+{
+       ib_user_query_t user_query;
+       ib_service_record_t service_record;
+       ib_query_req_t query_req;
+       ib_api_status_t status;
+       cl_status_t cl_status;
+       cm_rdma_req_t *p_rdma = (cm_rdma_req_t*)p_req->pdata;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       query_req.query_type = IB_QUERY_USER_DEFINED;
+       query_req.p_query_input = &user_query;
+       query_req.port_guid = p_req->guid;
+       query_req.timeout_ms = g_sa_timeout;
+       query_req.retry_cnt = g_sa_retries;
+       query_req.flags = 0;    /* IB_FLAGS_SYNC */
+       query_req.query_context = p_req;
+       query_req.pfn_query_cb = __ndi_ats_query_cb;
+
+       /* TODO: which method one is correct? */
+       user_query.method = IB_MAD_METHOD_GETTABLE;
+       //user_query.method = IB_MAD_METHOD_GET;
+       user_query.attr_id = IB_MAD_ATTR_SERVICE_RECORD;
+       user_query.attr_size = sizeof(ib_service_record_t);
+       user_query.comp_mask =
+               IB_SR_COMPMASK_SPKEY |
+               IB_SR_COMPMASK_SLEASE |
+               IB_SR_COMPMASK_SNAME |
+               IB_SR_COMPMASK_SDATA8_12 |
+               IB_SR_COMPMASK_SDATA8_13 | IB_SR_COMPMASK_SDATA8_14 | IB_SR_COMPMASK_SDATA8_15;
+
+       user_query.p_attr = &service_record;
+
+       memset( &service_record, 0, sizeof(service_record) );
+       service_record.service_pkey = cl_hton16( IB_DEFAULT_PKEY );
+       service_record.service_data8[12] = (uint8_t) (p_rdma->dst_ip_addr[4] >> 0);
+       service_record.service_data8[13] = (uint8_t) (p_rdma->dst_ip_addr[4] >> 8);
+       service_record.service_data8[14] = (uint8_t) (p_rdma->dst_ip_addr[4] >> 16);
+       service_record.service_data8[15] = (uint8_t) (p_rdma->dst_ip_addr[4] >> 24);
+       service_record.service_lease = 0xFFFFFFFF;
+       strcpy( (void*)service_record.service_name, ATS_NAME );
+
+       /* insert IRP in the queue */
+       ref_al_obj( &h_qp->obj );
+       h_qp->p_irp_que->state = NDI_CM_CONNECTING_ATS_SENT;
+       IoCsqInsertIrp( &h_qp->p_irp_que->csq, h_ioctl, NULL );
+
+       /* query SA */
+       status = ib_query( qp_get_al( h_qp ), &query_req, &h_qp->p_irp_que->h_query );
+       if( status != IB_SUCCESS )
+       {
+               h_qp->p_irp_que->state = NDI_CM_IDLE;   
+               IoCsqRemoveNextIrp( &h_qp->p_irp_que->csq, NULL );
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );
+               cl_status = CL_ERROR;
+               goto exit;
+       }
+
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+cl_status_t
+ndi_req_cm(
+       IN              ib_qp_handle_t  const                           h_qp,
+       IN              cl_ioctl_handle_t                                       h_ioctl,
+       IN              ual_ndi_req_cm_ioctl_in_t                       *p_req
+       )
+{
+       cl_status_t cl_status;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       /* check outstanding request */
+       __ndi_acquire_lock( &h_qp->p_irp_que->csq, NULL);
+       if (!__ndi_peek_next_irp( &h_qp->p_irp_que->csq, NULL, NULL ))
+       {
+               cl_status = STATUS_CONNECTION_ACTIVE;
+               __ndi_release_lock( &h_qp->p_irp_que->csq, 0 );
+               goto exit;
+       }
+       __ndi_release_lock( &h_qp->p_irp_que->csq, 0 );
+
+       /* send ATS request */
+       cl_status = __ndi_ats_query( h_qp, h_ioctl, p_req );
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+
+/*******************************************************************
+ *
+ * REP CM request
+ *
+ ******************************************************************/
+
+
+cl_status_t
+ndi_rep_cm(
+       IN              ib_qp_handle_t  const                           h_qp,
+       IN              net32_t                 const                           cid,
+       IN              cl_ioctl_handle_t                                       h_ioctl,
+       IN              ual_ndi_rep_cm_ioctl_in_t                       *p_ndi_rep_cm
+       )
+{
+       cl_status_t cl_status = STATUS_SUCCESS;
+
+       UNUSED_PARAM(h_qp);
+       UNUSED_PARAM(cid);
+       UNUSED_PARAM(h_ioctl);
+       UNUSED_PARAM(p_ndi_rep_cm);
+       
+       AL_ENTER( AL_DBG_NDI );
+
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+
+
diff --git a/branches/Ndi/core/al/kernel/al_ndi_cm.h b/branches/Ndi/core/al/kernel/al_ndi_cm.h
new file mode 100644 (file)
index 0000000..5a478ea
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * 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 _AL_NDI_CM_H_
+#define _AL_NDI_CM_H_
+
+#include "complib/cl_ioctl_osd.h"
+
+/* QP creation parameters */
+#define QP_ATTRIB_RESPONDER_RESOURCES  4
+#define QP_ATTRIB_INITIATOR_DEPTH              4
+#define QP_ATTRIB_RETRY_COUNT                  6
+#define QP_ATTRIB_RNR_RETRY                            7
+#define QP_ATTRIB_RNR_NAK_TIMEOUT              8 /* 16 ms */
+
+#define QP_ATTRIB_SQ_DEPTH                             16
+
+/* CM timeouts */
+#define CM_MIN_LOCAL_TIMEOUT   (18)
+#define CM_LOCAL_TIMEOUT               (1)
+#define CM_MIN_REMOTE_TIMEOUT  (18)
+#define CM_REMOTE_TIMEOUT              (2)
+#define CM_RETRIES 4
+
+typedef enum _ndi_cm_state 
+{
+       NDI_CM_IDLE,
+       NDI_CM_CONNECTING_ATS_SENT, // ATS = Address Translation Service
+       NDI_CM_CONNECTING_QPR_SENT, // QPR = Query path record
+       NDI_CM_CONNECTING_REQ_SENT,
+       NDI_CM_CONNECTING_REP_RCVD,
+       NDI_CM_CONNECTING_REJ_RCVD,
+       NDI_CM_CONNECTING_RTU_SENT,
+       NDI_CM_CONNECTED,
+       NDI_CM_BOUND,
+       NDI_CM_LISTENING,
+       NDI_CM_REP_SENT,
+       NDI_CM_CONNECTED_DREP_SENT,
+       NDI_CM_CONNECTED_DREQ_SENT,
+} ndi_cm_state_t;
+
+typedef struct _ib_qp  ib_qp_t;
+
+typedef struct _ndi_rep_rec
+{
+       uint8_t                                         pdata[IB_REP_CM_RDMA_PDATA_SIZE];
+}      ndi_rep_rec_t;
+
+typedef struct _ndi_rej_rec
+{
+       uint8_t                                         pdata[IB_REP_CM_RDMA_PDATA_SIZE];
+}      ndi_rej_rec_t;
+
+#pragma warning(disable:4201)
+typedef struct _ndi_mad_info
+{
+       union
+       {
+               ndi_rep_rec_t   rep;
+               ndi_rej_rec_t   rej;
+       };
+} ndi_mad_info_t;
+#pragma warning(default:4201)
+       
+typedef struct _ndi_qp_csq
+{
+       IO_CSQ                                          csq;
+       ib_qp_t*                                        h_qp;
+       ib_query_handle_t                       h_query;
+       ib_path_rec_t                           path_rec;
+       LIST_ENTRY                                      que;
+       ndi_cm_state_t                          state;
+       boolean_t                                       shutdown_called;
+       boolean_t                                       close_called;
+       boolean_t                                       disconnect_sent;
+       boolean_t                                       irp_cancelled;
+       ndi_mad_info_t                          mad_info;
+       uint32_t                                        resv;
+} ndi_qp_csq_t;
+
+
+cl_status_t
+ndi_req_cm(
+       IN              ib_qp_handle_t  const                   h_qp,
+       IN              cl_ioctl_handle_t                               h_ioctl,
+       IN              ual_ndi_req_cm_ioctl_in_t               *p_req
+       );
+
+cl_status_t
+ndi_rep_cm(
+       IN              ib_qp_handle_t  const                   h_qp,
+       IN              net32_t                 const                   cid,
+       IN              cl_ioctl_handle_t                               h_ioctl,
+       IN              ual_ndi_rep_cm_ioctl_in_t               *p_ndi_rep_cm
+       );
+
+void
+ndi_qp_flush_ques(
+       IN                              ib_qp_handle_t                          h_qp );
+
+       
+NTSTATUS
+ndi_qp_init(
+       IN              ib_qp_handle_t                                  h_qp );
+
+void
+ndi_qp_deinit(
+       IN              ib_qp_handle_t                                  h_qp );
+
+#endif
+
diff --git a/branches/Ndi/core/al/kernel/al_ndi_cq.c b/branches/Ndi/core/al/kernel/al_ndi_cq.c
new file mode 100644 (file)
index 0000000..b4ef65b
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * 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_ndi_cq.tmh"
+#endif
+
+#include "al_dev.h"
+/* Get the internal definitions of apis for the proxy */
+#include "al_ca.h"
+#include "al_cq.h"
+#include "ib_common.h"
+
+/*******************************************************************
+ *
+ * Helpers
+ *
+ ******************************************************************/
+
+#pragma warning(disable:4706)
+static inline void __ndi_flush_que(
+       IN      ndi_cq_csq_t*                                                   p_ndi_csq,
+       IN      NTSTATUS                                                                completion_code
+       )
+{
+       PIRP Irp;
+       while( Irp = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL ) )
+       {
+               cl_ioctl_complete( Irp, completion_code, 0 );
+               deref_al_obj( &p_ndi_csq->h_cq->obj );
+       }
+}
+#pragma warning(default:4706)
+
+/*******************************************************************
+ *
+ * Callbacks
+ *
+ ******************************************************************/
+
+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->compl, STATUS_SUCCESS );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+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->compl, STATUS_INTERNAL_ERROR );
+       __ndi_flush_que( &h_cq->error, STATUS_INTERNAL_ERROR );
+       AL_EXIT( AL_DBG_NDI );
+}
+
+/*******************************************************************
+ *
+ * Public routines
+ *
+ ******************************************************************/
+
+/* flush a queue of pending requests */
+void
+ndi_cq_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->compl, STATUS_CANCELLED );
+               __ndi_flush_que( &h_cq->error, STATUS_CANCELLED );
+       }
+       AL_EXIT( AL_DBG_NDI );
+}
+
+
+/*******************************************************************
+ *
+ * CSQ
+ *
+ ******************************************************************/
+
+static VOID __ndi_insert_irp(
+       IN      PIO_CSQ                                                                 Csq,
+       IN      PIRP                                                                    Irp
+       )
+{
+       ndi_cq_csq_t *p_ndi_csq = (ndi_cq_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_cq_csq_t *p_ndi_csq = (ndi_cq_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_cq_csq_t *p_ndi_csq = (ndi_cq_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_cq_csq_t *p_ndi_csq = (ndi_cq_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_cq_csq_t *p_ndi_csq = (ndi_cq_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 );
+}
+
+NTSTATUS
+ndi_cq_init(
+       IN                              ib_cq_handle_t                          h_cq )
+{
+
+       NTSTATUS status;
+
+       AL_ENTER( AL_DBG_NDI );
+
+       status = IoCsqInitialize( &h_cq->compl.csq, 
+               __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( &h_cq->error.csq, 
+               __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;
+}
+
+
+
diff --git a/branches/Ndi/core/al/kernel/al_ndi_cq.h b/branches/Ndi/core/al/kernel/al_ndi_cq.h
new file mode 100644 (file)
index 0000000..466722d
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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 _AL_NDI_CQ_H_
+#define _AL_NDI_CQ_H_
+
+void
+ndi_cq_flush_ques(
+       IN                              ib_cq_handle_t                          h_cq );
+
+NTSTATUS
+ndi_cq_init(
+       IN                              ib_cq_handle_t                          h_cq );
+
+void 
+ndi_cq_compl_cb(
+       IN              const   ib_cq_handle_t                          h_cq,
+       IN                              void                                            *cq_context );
+
+void 
+ndi_cq_error_cb(
+       IN                              ib_async_event_rec_t            *p_err_rec );
+
+#endif
index 6af10b0584a1e09f33c56cc984a982e7a4360b7f..86f4226ec190cb35ffea968769227b8e508ddb85 100644 (file)
@@ -35,7 +35,9 @@
 #include <iba/ib_al.h>
 #include <iba/ib_al_ioctl.h>
 #include "al.h"
+#include "al_qp.h"
 #include "al_debug.h"
+#include "al_cm_cep.h"
 
 #if defined(EVENT_TRACING)
 #ifdef offsetof
 #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      ndi_io_csq_t*                                                   p_ndi_csq,
-       IN      NTSTATUS                                                                completion_code
-       )
-{
-       PIRP Irp;
-       while( Irp = IoCsqRemoveNextIrp( &p_ndi_csq->csq, NULL ) )
-       {
-               cl_ioctl_complete( Irp, completion_code, 0 );
-               deref_al_obj( &p_ndi_csq->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->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->compl, STATUS_INTERNAL_ERROR );
-       __ndi_flush_que( &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->compl, STATUS_CANCELLED );
-               __ndi_flush_que( &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 );
-}
-
-NTSTATUS
-proxy_ndi_cq_init(
-       IN                              ib_cq_handle_t                          h_cq )
-{
-
-       NTSTATUS status;
-
-       AL_ENTER( AL_DBG_NDI );
-
-       status = IoCsqInitialize( &h_cq->compl.csq, 
-               __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( &h_cq->error.csq, 
-               __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;
-}
-
+#include "al_ndi_cm.h"
+#include "al_cm_rdma.h"
 
 /*******************************************************************
  *
@@ -305,15 +80,15 @@ __ndi_create_cq(
        ib_api_status_t                 status;
        ib_pfn_event_cb_t               pfn_ev;
 
-       AL_ENTER( AL_DBG_CQ );
+       AL_ENTER( AL_DBG_NDI );
 
        /* 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;
+               status = CL_INVALID_PARAMETER;
+               goto exit;
        }
 
        /* Validate CA handle */
@@ -328,9 +103,9 @@ __ndi_create_cq(
        cq_create.size = p_ioctl->in.size;
 
        /* Override with proxy's cq callback */
-       cq_create.pfn_comp_cb = __ndi_cq_compl_cb;
+       cq_create.pfn_comp_cb = ndi_cq_compl_cb;
        cq_create.h_wait_obj = NULL;
-       pfn_ev = __ndi_cq_error_cb;
+       pfn_ev = ndi_cq_error_cb;
 
        status = cpyin_umvbuf( &p_ioctl->in.umv_buf, &p_umv_buf );
        if( status != IB_SUCCESS )
@@ -371,7 +146,8 @@ proxy_create_cq_err1:
        p_ioctl->out.status = status;
        *p_ret_bytes = sizeof(p_ioctl->out);
 
-       AL_EXIT( AL_DBG_CQ );
+exit:
+       AL_EXIT( AL_DBG_NDI );
        return CL_SUCCESS;
 }
 
@@ -383,17 +159,17 @@ __ndi_notify_cq(
                OUT     size_t                                  *p_ret_bytes )
 {
        cl_status_t cl_status;
-       ual_ndi_notify_cq_ioctl_cmd_in_t *p_ioctl;
+       ual_ndi_notify_cq_ioctl_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 );
+       p_ioctl = (ual_ndi_notify_cq_ioctl_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) )
+       if( cl_ioctl_in_size( h_ioctl ) != sizeof(ual_ndi_notify_cq_ioctl_in_t) )
        {
                cl_status = CL_INVALID_PARAMETER;
                goto exit;
@@ -462,9 +238,247 @@ __ndi_cancel_cq(
        }
 
        /* flush IRP queues */
-       proxy_ndi_flush_ques( h_cq );
+       ndi_cq_flush_ques( h_cq );
+
+       *p_ret_bytes = 0;
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+
+static cl_status_t
+__ndi_get_cid(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ib_qp_handle_t h_qp;
+       al_dev_open_context_t *p_context;
+       uint32_t cid;
+       
+       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_ioctl_out_size( h_ioctl ) != sizeof(atomic32_t) )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate CQ handle */
+       h_qp = (ib_qp_handle_t)
+               al_hdl_ref( p_context->h_al, 
+                       *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_QP );
+       if( !h_qp )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Check QP type */
+       if( h_qp->type != IB_QPT_RELIABLE_CONN )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* get CID */
+       cid = (uint32_t)((al_conn_qp_t*)h_qp)->cid;
+       if( cid == AL_INVALID_CID )
+       {
+               cl_status = CL_INVALID_STATE;
+               goto exit;
+       }
+
+       /* return CID */
+       *(uint32_t*)cl_ioctl_out_buf( h_ioctl ) = cid;
+
+       *p_ret_bytes = sizeof(uint32_t);
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
 
+
+static cl_status_t
+__ndi_req_cm(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ib_qp_handle_t h_qp;
+       al_dev_open_context_t *p_context;
+       ual_ndi_req_cm_ioctl_in_t *p_req = 
+               (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );
+       
+       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(ual_ndi_req_cm_ioctl_in_t) + p_req->pdata_size))
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate CQ handle */
+       h_qp = (ib_qp_handle_t)
+               al_hdl_ref( p_context->h_al, 
+                       *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_QP );
+       if( !h_qp )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Check QP type */
+       if( h_qp->type != IB_QPT_RELIABLE_CONN )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+       p_req->h_qp = (uint64_t)h_qp;
+
+       /* perform the ioctl */
+       cl_status = ndi_req_cm( h_qp, h_ioctl, p_req );
+       if (cl_status != CL_SUCCESS)
+               goto exit;
+
+       cl_status = CL_PENDING;
        *p_ret_bytes = 0;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+static cl_status_t
+__ndi_rep_cm(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ib_qp_handle_t h_qp;
+       al_dev_open_context_t *p_context;
+       ual_ndi_rep_cm_ioctl_in_t * p_ndi_rep_cm;
+       net32_t cid;
+       ual_ndi_rep_cm_ioctl_in_t *p_rep = 
+               (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );
+
+       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(ual_ndi_req_cm_ioctl_in_t) + p_rep->pdata_size)) ||
+               (p_rep->pdata_size < sizeof(cm_rdma_req_t)) ||
+               cl_ioctl_out_size( h_ioctl ) != sizeof(atomic32_t) )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Get and validate QP handle */
+       p_ndi_rep_cm = (ual_ndi_rep_cm_ioctl_in_t *)cl_ioctl_in_buf( h_ioctl );
+       h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_ndi_rep_cm->h_qp, AL_OBJ_TYPE_H_QP );
+
+       if( !h_qp )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       if( h_qp->type != IB_QPT_RELIABLE_CONN )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Get and validate CID */
+       cid = p_ndi_rep_cm->cid;
+
+       /* perform the ioctls */
+       cl_status = ndi_rep_cm( h_qp, cid, h_ioctl, p_ndi_rep_cm );
+       if( cl_status != CL_SUCCESS )
+               goto exit;
+       
+       /* return QP state */
+       *(uint32_t*)cl_ioctl_out_buf( h_ioctl ) = p_ndi_rep_cm->qp_state;
+
+       *p_ret_bytes = sizeof(uint32_t);
+       cl_status = CL_SUCCESS;
+
+exit:
+       AL_EXIT( AL_DBG_NDI );
+       return cl_status;
+}
+
+
+static cl_status_t
+__ndi_rtu_cm(
+       IN              void                                    *p_open_context,
+       IN              cl_ioctl_handle_t               h_ioctl,
+               OUT     size_t                                  *p_ret_bytes )
+{
+       cl_status_t cl_status;
+       ib_qp_handle_t h_qp;
+       al_dev_open_context_t *p_context;
+       atomic32_t cid;
+       
+       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_ioctl_out_size( h_ioctl ) != sizeof(atomic32_t) )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Validate CQ handle */
+       h_qp = (ib_qp_handle_t)
+               al_hdl_ref( p_context->h_al, 
+                       *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_QP );
+       if( !h_qp )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* Check QP type */
+       if( h_qp->type != IB_QPT_RELIABLE_CONN )
+       {
+               cl_status = CL_INVALID_PARAMETER;
+               goto exit;
+       }
+
+       /* get CID */
+       cid = ((al_conn_qp_t*)h_qp)->cid;
+       if( cid == AL_INVALID_CID )
+       {
+               cl_status = CL_INVALID_STATE;
+               goto exit;
+       }
+
+       /* return CID */
+       *(atomic32_t*)cl_ioctl_out_buf( h_ioctl ) = cid;
+
+       *p_ret_bytes = sizeof(atomic32_t);
        cl_status = CL_SUCCESS;
 
 exit:
@@ -503,6 +517,18 @@ ndi_ioctl(
        case UAL_NDI_CANCEL_CQ:
                cl_status = __ndi_cancel_cq( p_context, h_ioctl, p_ret_bytes );
                break;
+       case UAL_NDI_GET_CID:
+               cl_status = __ndi_get_cid( p_context, h_ioctl, p_ret_bytes );
+               break;
+       case UAL_NDI_REQ_CM:
+               cl_status = __ndi_req_cm( p_context, h_ioctl, p_ret_bytes );
+               break;
+       case UAL_NDI_REP_CM:
+               cl_status = __ndi_rep_cm( p_context, h_ioctl, p_ret_bytes );
+               break;
+       case UAL_NDI_RTU_CM:
+               cl_status = __ndi_rtu_cm( p_context, h_ioctl, p_ret_bytes );
+               break;
        default:
                cl_status = CL_INVALID_PARAMETER;
                break;
index 16d11d9c22a9bb201a038ecbf0e3902f835bb868..d1089d9d2b890d1e2c480bb3ef4fdf164752d313 100644 (file)
@@ -46,6 +46,9 @@
 
 #include "complib/cl_ioctl_osd.h"
 #include "al_cq.h"
+#include "al_ndi_cq.h"
+#include "al_qp.h"
+#include "al_ndi_cm.h"
 
 /* functions from al_proxy_verbs.c */
 ib_api_status_t
@@ -62,15 +65,6 @@ 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 );
-
-NTSTATUS
-proxy_ndi_cq_init(
-       IN                              ib_cq_handle_t                          h_cq );
 
 #endif
 
index 0536477340062fa2b841b1ccf195a18c508cba24..cba000d3b0190cc115c07962589a33b9f4dde195 100644 (file)
@@ -3410,9 +3410,9 @@ typedef enum _ND_CQ_NOTIFY_TYPE
        \r
 } ND_CQ_NOTIFY_TYPE;\r
 \r
-/****s* User-mode Access Layer/ual_ndi_notify_cq_ioctl_cmd_in_t\r
+/****s* User-mode Access Layer/ual_ndi_notify_cq_ioctl_in_t\r
 * NAME\r
-*      ual_ndi_notify_cq_ioctl_cmd_in_t\r
+*      ual_ndi_notify_cq_ioctl_in_t\r
 *\r
 * DESCRIPTION\r
 *      IOCTL structure containing the input parameters for requesting\r
@@ -3420,27 +3420,157 @@ typedef enum _ND_CQ_NOTIFY_TYPE
 *\r
 * SYNOPSIS\r
 */\r
-typedef struct _ual_ndi_notify_cq_ioctl_cmd_in\r
+typedef struct _ual_ndi_notify_cq_ioctl_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
+}      ual_ndi_notify_cq_ioctl_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
+*      h_cq\r
 *              A handle to the CQ to modify.\r
 *\r
-*      in.notify_type\r
+*      notify_type\r
 *              Type of notification, requested.\r
 *\r
 *****/\r
 \r
+/****s* User-mode Access Layer/ual_ndi_req_cm_ioctl_in_t\r
+* NAME\r
+*      ual_ndi_req_cm_ioctl_in_t\r
+*\r
+* DESCRIPTION\r
+*      IOCTL structure containing the input parameters \r
+*      sending CM REQ .\r
+*\r
+* SYNOPSIS\r
+*/\r
+#pragma warning( disable : 4200)\r
+typedef struct _ual_ndi_req_cm_ioctl_in\r
+{\r
+       uint64_t                                        h_qp;\r
+       net64_t                                         guid;\r
+       uint16_t                                        dst_port;\r
+       uint8_t                                         prot;\r
+       uint8_t                                         reserve[5];\r
+       uint32_t                                        pdata_size;\r
+       uint8_t                                         pdata[0];\r
+\r
+}      ual_ndi_req_cm_ioctl_in_t;\r
+#pragma warning( default  : 4200)\r
+/*\r
+* NOTES\r
+*      The output parameter is the new QP state (RTS).\r
+*\r
+* FIELDS\r
+*      h_qp\r
+*              A handle to the QP to modify.\r
+*\r
+*      guid\r
+*              Local port GUID to which to bind to.\r
+*\r
+*      dst_port\r
+*              Destination port number.\r
+*\r
+*      prot\r
+*              Protocol.\r
+*\r
+*      pdata_size\r
+*              The size of following private RDMA CM data\r
+*\r
+*****/\r
+\r
+/****s* User-mode Access Layer/ual_ndi_rep_cm_ioctl_in_t\r
+* NAME\r
+*      ual_ndi_rep_cm_ioctl_in_t\r
+*\r
+* DESCRIPTION\r
+*      IOCTL structure containing the input parameters \r
+*      sending CM RTU response .\r
+*\r
+* SYNOPSIS\r
+*/\r
+#pragma warning( disable : 4200)\r
+typedef struct _ual_ndi_rep_cm_ioctl_in\r
+{\r
+       uint64_t                                        h_qp;\r
+       net32_t                                         cid;\r
+       uint32_t                                        qp_state;\r
+       uint8_t                                         init_depth;\r
+       uint8_t                                         resp_res;\r
+       uint8_t                                         reserve[2];\r
+       uint32_t                                        pdata_size;\r
+       uint8_t                                         pdata[0];\r
+\r
+}      ual_ndi_rep_cm_ioctl_in_t;\r
+#pragma warning( default  : 4200)\r
+/*\r
+* NOTES\r
+*      The output parameter is the new QP state (RTS).\r
+*\r
+* FIELDS\r
+*      h_qp\r
+*              A handle to the QP to modify.\r
+*\r
+*      cid\r
+*              Connection ID.\r
+*\r
+*      qp_state\r
+*              UVP QP state, that is  to be set in case of success.\r
+*\r
+*      init_depth\r
+*              The maximum number of outstanding RDMA read/atomic operations.\r
+*\r
+*      resp_res\r
+*              The maximum number of RDMA read/atomic operations from the recipient.\r
+*\r
+*      pdata_size\r
+*              The size of following private data\r
+*\r
+*****/\r
+\r
+/****s* User-mode Access Layer/ual_ndi_rtu_cm_ioctl_in_t\r
+* NAME\r
+*      ual_ndi_rtu_cm_ioctl_in_t\r
+*\r
+* DESCRIPTION\r
+*      IOCTL structure containing the input parameters \r
+*      sending CM RTU response .\r
+*\r
+* SYNOPSIS\r
+*/\r
+#pragma warning( disable : 4200)\r
+typedef struct _ual_ndi_rtu_cm_ioctl_in\r
+{\r
+       uint64_t                                        h_qp;\r
+       uint32_t                                        qp_state;\r
+       uint8_t                                         init_depth;\r
+       uint8_t                                         resp_res;\r
+\r
+}      ual_ndi_rtu_cm_ioctl_in_t;\r
+#pragma warning( default  : 4200)\r
+/*\r
+* NOTES\r
+*      The output parameter is the new QP state (RTS).\r
+*\r
+* FIELDS\r
+*      h_qp\r
+*              A handle to the QP to modify.\r
+*\r
+*      qp_state\r
+*              UVP QP state, that is  to be set in case of success.\r
+*\r
+*      init_depth\r
+*              The maximum number of outstanding RDMA read/atomic operations.\r
+*\r
+*      resp_res\r
+*              The maximum number of RDMA read/atomic operations from the recipient.\r
+*\r
+*****/\r
 \r
 \r
 \r
index 2442e3b5d7d48122406c0cc78b429750dd25e5ad..0288f6a1fa99d0805cff5cf8fe057b0d21126985 100644 (file)
@@ -8395,6 +8395,7 @@ typedef struct _ib_ioc_info
  *     Defines the size of user available data in communication management MADs\r
  */\r
 #define IB_REQ_CM_RDMA_PDATA_SIZE                      56\r
+#define IB_REP_CM_RDMA_PDATA_SIZE                      148\r
 #define IB_REQ_PDATA_SIZE                                      92\r
 #define IB_MRA_PDATA_SIZE                                      222\r
 #define IB_REJ_PDATA_SIZE                                      148\r
index 33be7520a204d9131ecb2a7075db1a94e5777fea..590205826abcfb9002e7b8cc9af62ecd648c7226 100644 (file)
@@ -1891,6 +1891,45 @@ typedef void
 *\r
 ********/\r
 \r
+/****f* user-mode Verbs/uvp_post_destroy_qp_t\r
+* NAME\r
+*      uvp_pre_get_qp_state_t -- Get QP state location and size.\r
+*\r
+* SYNOPSIS\r
+*/\r
+\r
+typedef void\r
+(AL_API *uvp_pre_get_qp_state_t) (\r
+       IN              const   ib_qp_handle_t                          h_uvp_qp,\r
+       OUT                             uint32_t**                                      pp_qp_state,\r
+       OUT                             uint32_t*                                       p_size\r
+       );\r
+\r
+/*\r
+* DESCRIPTION\r
+*      uvp_pre_get_qp_state_t() is implemented by vendor. \r
+*      UAL invokes this pre-ioctl routine to enable KAL to change QP state\r
+*      It is used after quick QP modify operation.\r
+*      There is no uvp_post_get_qp_state_t function.\r
+*\r
+* PARAMETERS\r
+*      h_uvp_qp\r
+*              [in] Vendor's Handle to the qp (in user-mode library)\r
+*              that needs to be destroyed.\r
+*      pp_qp_state\r
+*              [out] pointer to QP state internal variable;\r
+*      p_size\r
+*              [out] pointer to the size of QP state internal variable;\r
+*\r
+* RETURN VALUE\r
+*\r
+* PORTABILITY\r
+*      User mode.\r
+*\r
+* SEE ALSO\r
+*\r
+********/\r
+\r
 /********/\r
 \r
 /****f* user-mode Verbs/uvp_pre_create_cq\r
@@ -3194,6 +3233,8 @@ typedef struct _uvp_interface
         */\r
        uint32_t                                        version;\r
 \r
+       /* Version 1.00 APIs */\r
+\r
        /*\r
         * HCA Access Verbs\r
         */\r
@@ -3323,6 +3364,9 @@ typedef struct _uvp_interface
        uvp_pre_detach_mcast            pre_detach_mcast;\r
        uvp_post_detach_mcast           post_detach_mcast;\r
 \r
+       /* Version 1.01 APIs */\r
+       uvp_pre_get_qp_state_t          pre_get_qp_state;\r
+       \r
 } uvp_interface_t;\r
 \r
 /********/\r