]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
winverbs branch: update to trunk SVN 2100
authorshefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 15 Apr 2009 23:54:42 +0000 (23:54 +0000)
committershefty <shefty@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Wed, 15 Apr 2009 23:54:42 +0000 (23:54 +0000)
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
git-svn-id: svn://openib.tc.cornell.edu/gen1@2101 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

64 files changed:
branches/winverbs/WinOF/BuildRelease.bat
branches/winverbs/WinOF/WIX/README.txt
branches/winverbs/WinOF/WIX/README_release.txt
branches/winverbs/WinOF/WIX/Release_notes.htm
branches/winverbs/WinOF/WIX/build-OFA-dist.bat
branches/winverbs/WinOF/WIX/common/WinOF_cfg.inc
branches/winverbs/WinOF/WIX/win7/ia64/wof.wxs
branches/winverbs/WinOF/WIX/win7/signDrivers.bat
branches/winverbs/WinOF/WIX/win7/x64/wof.wxs
branches/winverbs/WinOF/WIX/win7/x86/wof.wxs
branches/winverbs/WinOF/WIX/wlh/ia64/wof.wxs
branches/winverbs/WinOF/WIX/wlh/signDrivers.bat
branches/winverbs/WinOF/WIX/wlh/x64/wof.wxs
branches/winverbs/WinOF/WIX/wlh/x86/wof.wxs
branches/winverbs/WinOF/WIX/wnet/signDrivers.bat
branches/winverbs/WinOF/WIX/wxp/signDrivers.bat
branches/winverbs/core/al/al_cm_cep.h
branches/winverbs/core/al/al_dev.h
branches/winverbs/core/al/al_qp.c
branches/winverbs/core/al/al_qp.h
branches/winverbs/core/al/kernel/al_cm_cep.c
branches/winverbs/core/al/kernel/al_ndi_cm.c
branches/winverbs/core/al/kernel/al_ndi_cm.h
branches/winverbs/core/al/kernel/al_proxy_cep.c
branches/winverbs/core/al/kernel/al_proxy_ndi.c
branches/winverbs/core/al/user/ual_cm_cep.c
branches/winverbs/core/bus/kernel/bus_pnp.c
branches/winverbs/core/winmad/kernel/makefile.inc
branches/winverbs/hw/mlx4/kernel/bus/drv/makefile.inc
branches/winverbs/hw/mlx4/kernel/bus/drv/mlx4_bus.inx
branches/winverbs/hw/mlx4/kernel/bus/drv/sources
branches/winverbs/hw/mlx4/kernel/bus/net/catas.c
branches/winverbs/hw/mlx4/kernel/hca/SOURCES
branches/winverbs/hw/mlx4/kernel/hca/drv.c
branches/winverbs/hw/mlx4/kernel/hca/makefile.inc
branches/winverbs/hw/mlx4/kernel/hca/mlx4_hca.inx
branches/winverbs/hw/mthca/kernel/SOURCES
branches/winverbs/hw/mthca/kernel/hca_pnp.c
branches/winverbs/hw/mthca/kernel/makefile.inc
branches/winverbs/hw/mthca/kernel/mthca.inx
branches/winverbs/inc/iba/ib_al_ioctl.h
branches/winverbs/inc/mod_ver.def
branches/winverbs/ulp/dapl2/test/dapltest/scripts/dt-cli.bat
branches/winverbs/ulp/dapl2/test/dapltest/scripts/dt-svr.bat
branches/winverbs/ulp/nd/user/NdAdapter.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdAdapter.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdConnector.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdConnector.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdCq.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdCq.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdEndpoint.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdEndpoint.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdListen.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdListen.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdMr.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdMr.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdMw.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdMw.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdProv.cpp [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdProv.def [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdProv.h [new file with mode: 0644]
branches/winverbs/ulp/nd/user/NdProv.rc [new file with mode: 0644]
branches/winverbs/ulp/nd/user/makefile
branches/winverbs/ulp/nd/user/nddebug.h [new file with mode: 0644]

index cddf164e32e1572bc848695081c33d3254dd2da1..21c13e1014dc68c64de271be3ac7e33dc9662ba4 100644 (file)
@@ -27,13 +27,17 @@ if "%1" == "all" goto OK
 if "%1" == "allnoforce" goto OK\r
 if "%1" == "allf" (\r
     if "%2" == "" goto usage\r
-       goto OK\r
+    if exist "%2" goto OK\r
+       echo %0 Err - path .\%2 does not exist?\r
+       exit /B 1\r
 )\r
 if "%1" == "compile" goto OK\r
 if "%1" == "compilenoforce" goto OK\r
 if "%1" == "compf" (\r
     if "%2" == "" goto usage\r
-    goto OK\r
+    if exist "%2" goto OK\r
+       echo %0 Err - path .\%2 does not exist?\r
+       exit /B 1\r
 )\r
 if "%1" == "makebin" goto OK\r
 if "%1" == "msi" goto OK\r
@@ -156,7 +160,7 @@ rem Use this WDK
 \r
 if "%WIN7%" == "yes" (\r
        rem Windows 7 WDK\r
-       set _DDK_VER=7053.0.winmain.090226-1910\r
+       set _DDK_VER=7068.0.0\r
        set _COIN_VER=01009\r
 ) else (\r
        rem Server 2008 WDK & WdfCoInstaller version\r
@@ -558,4 +562,3 @@ echo %0:   Started  %STIME%
 echo %0:   Finished %TIME%\r
 \r
 endlocal\r
-@echo on\r
index 2aef487a9d36d0f166f0611aab518f5e1ca8358f..300578754ebb79d05e8a07d6216e19183a0c9216 100644 (file)
@@ -1,4 +1,4 @@
-[11-13-08]\r
+[04-10-09]\r
 \r
 How to generate a Windows OpenFabrics Release (WinOF) using the WIX 2.0 open\r
 source installer tool set ( http://sourceforge.net/projects/wix/ ).\r
@@ -10,11 +10,12 @@ WIX References:
        WIX Introduction http://wix.sourceforge.net/manual-wix2/wix_index.htm   \r
 \r
 \r
-WinOF Revisions:\r
-  1.0  based on svn.614\r
+WinOF Revisions: (based on)\r
+  1.0  svn.614\r
   1.0.1        svn.864\r
   1.1  svn.1177\r
   2.0  svn.1763\r
+  2.0.2        svn.1975\r
 \r
 \r
 \r
@@ -24,15 +25,15 @@ Creating a binary release tree
 As of WinOF 2.0 release [Aug'08] the build environment has been switched over to\r
 Microsoft's WDK (Windows Driver Kit) version 6001.180001.\r
 \r
-See gen1\trunk\BuildRelease.bat file to generate a Wix installer (.msi file) containing\r
-signed driver files.\r
+See gen1\trunk\WinOF\BuildRelease.bat file to generate a Wix installer (.msi\r
+file) containing signed driver files.\r
 The OS flavor WLH\ - Vista/Server 2008[LongHorn], WNET\ - Server 2003+XP64\r
-and XP\ (x86 only) bin folders will be populated with the correct folder structure such that\r
-a WIX installer (.msi) files can be generated; either cd into OS\arch dir and\r
-run buildmsi.bat or use BuildRelease.bat from trunk\ folder.\r
+and XP\ (x86 only) bin\ folders will be populated with the correct folder\r
+structure such that a WIX installer (.msi) files can be generated; either\r
+cd into OS\arch dir and run buildmsi.bat or use WinOF\BuildRelease.bat.\r
 \r
 Warning - buildrelease.bat is not generic, some asembly required as the folder\r
-structure is assumed.\r
+structure is assumed; see SVN to set build SVN (aka OPENIB_REV).\r
 \r
 BuildRelease.bat will by default deposit 7 .msi files in\r
 '%SystemRoot%\temp\WinOF_OS_arch.msi'.\r
@@ -46,42 +47,46 @@ contents of WIX\bin\ yourself from a WDK/SDK build window which can run
      cd to trunk; build /wg from a WDK OS and arch specific command window; all\r
      are required by etc\makebin.bat.\r
 \r
-  2) cd trunk\etc; execute 'makebin src-dir dest-dir OS-flavor' for each OS flavor:\r
-     wnet, wlh and wxp.\r
+  2) from trunk: execute 'etc\makebin %CD% dest-dir OS-flavor' for each OS\r
+     flavor: wnet, wlh and wxp.\r
      Say your svn repository is at C:\open-ib\, then to populate the WIX bin\r
      folder for Server 2008 binaries from a command window:\r
-        makebin C:\open-ib\gen1\trunk C:\open-ib\gen1\branches\WinOF\Wix\WLH\bin WLH\r
-\r
-With the arrival of Windows Server 2008 & Vista (WLH - Windows LongHorn) driver signing\r
-is a requirement. The WIX\sign-all-drivers.bat script will create a .cat file for each\r
-driver .inf located. The generation of the .cat file is driven from the corresponding\r
-.cdf file (.inf + .cdf + all files listed in .cdf + inf2cat.exe & signtool.exe result\r
-in a .cat file).\r
-\r
-A SW publisher's digital-ID certificate is required in order for WinOF installers to\r
-be created. A test certificate can be generated for local use, requires overhead during\r
-installation ('bcdedit -set testsigning on', reboot & local certificate store updates).\r
-The MS prescribed procedure is to obtain a SW publisher's certificate from VeriSign or\r
-other agency; if your company is producing SW drivers for SVR2008/Vista, then you will\r
-likely have access to a cert file.\r
+        makebin C:\open-ib\gen1\trunk C:\open-ib\gen1\WinOF\Wix\WLH\bin WLH\r
+\r
+With the arrival of Windows Server 2008 & Vista (WLH - Windows LongHorn) driver\r
+signing is a requirement. The WIX\sign-all-drivers.bat script will create a .cat\r
+file for each driver .inf located. The generation of the .cat file is driven\r
+from the corresponding driver.inf file via inf2cat.exe creating the .cat file\r
+and signtool.exe signing the .cat and .sys files.\r
+\r
+A SW publisher's digital-ID certificate is required in order for WinOF\r
+installers to be created. A test certificate can be generated for local use,\r
+requires overhead during installation ('bcdedit -set testsigning on', reboot &\r
+local certificate store updates).\r
+The MS prescribed procedure is to obtain a SW publisher's certificate from\r
+VeriSign or other CA agency; if your company is producing SW drivers for\r
+SVR2008/Vista, then you will likely have access to a cert file.\r
 The OFA will be purchasing a certificate for WinOF publication.\r
-Scripts for signing drivers assume the .cer file will be resident in '...WinOF\Wix\*.cer'.\r
-see trunk\buildrelease.bat for an example of how to invoke driver\r
-signing; 'WIX\sign-all-drivers.bat'.\r
-Also see the Microsoft 'Kernel Mode Code Signing' document 'KMCS_Walkthrough.doc'; goggle\r
-for current URL.\r
+Scripts for signing drivers assume the MS cross-certification .cer file will be\r
+resident in 'trunk\WinOF\Wix\*.cer'; your company Cert must be placed in the\r
+local cert store under the default personal 'My' store. \r
+see trunk\winof\buildrelease.bat for an example of how to invoke driver\r
+signing or 'WIX\sign-all-drivers.bat'.\r
+Also see the Microsoft 'Kernel Mode Code Signing' document\r
+'KMCS_Walkthrough.doc'; goggle for current URL.\r
 \r
 \r
 Creating a WIX tool set\r
 -------------------------\r
 \r
 Download the WIX v2 (stable) tool set (http://sourceforge.net/projects/wix/)\r
-to \91WInOF\WIX\WIX_tools\\92.\r
+to \91WinOF\WIX\WIX_tools\\92.\r
 Unzip the archive to a folder within 'WIX_tools\' as this folder represents the\r
 version of the tool set.\r
 Something like unzip wix-2.0.5325.0-binaries.zip into wix-2.0.5325.0-binaries\.\r
 You would now have the following structure:\r
        WinOF\WIX\WIX_tools\wix-2.0.5325.0-binaries\{candle.exe, light.exe,...}\r
+Point being Trunk\WinOF\buildRelease.bat needs the path to the WIX tool set.\r
 \r
 \r
 \r
@@ -93,59 +98,68 @@ Update Release_notes.htm file.
         The file 'Release_notes.htm' represents the next to be released\r
         WinOF version, as reflected by is Release ID.\r
 \r
-       Release ID number (e.g., 1.0)\r
+       Release ID number (e.g., 1.0, point releases are 1.0.x)\r
 \r
        New features\r
 \r
        Know issues\r
 \r
-Update the trunk\doc\Manual.htm file for new features.\r
+Update the trunk\docs\Manual.htm file for new features.\r
 \r
 \r
 BUILDING a .msi installer image file\r
 ------------------------------------\r
 \r
 Easy way:\r
- place certificate file (.cer) in WIX\ folder; 'My Personal' cert store needs to be updated.\r
+ place MS cross certificate file (.cer) in WIX\ folder; 'My' cert store needs\r
+ to contain your company cert file; WinOF\BuildRelease.bat needs the name of\r
+ your company cert file; OFA case 'OpenFabrics Alliance'.\r
+ .\r
  cd trunk\\r
  From a standard DOS cmd window, not a WDK cmd window, say \r
-   buildrelease clean\r
-   buildrelease all            # .msi file created in %windir%\temp\*.msi\r
 \r
-   buildrelease makebin - assumes trunk\bin\* built, populates WIX\{wlh,wnet,wxp}\bin folders.\r
+   buildrelease all            # .msi files created in %windir%\temp\*.msi\r
+\r
+   buildrelease makebin - assumes trunk\bin\* built,\r
+                          populates WIX\{wlh,wnet,wxp}\bin folders.\r
+   buildrelease sign - sign driver files & exit, assumes makebin has been run.\r
    buildrelease msi - signs & creates installers assuming makebin has been run.\r
-   buildrelease wix - just creates .msi installers - assumes all bin\ folders populated.\r
+   buildrelease wix - creates .msi installers - assumes all bin\ folders\r
+                      populated and drivers signed.\r
 \r
 CPU specific builds\r
 \r
-CD to the WIX OS-flavor and architecture specific directory.  'nmake.exe' needs to be\r
-in your command window search path. Build three arch specific installers\r
+CD to the WIX OS-flavor and architecture specific directory. 'nmake.exe' needs\r
+to be in your command window search path. Build three arch specific installers\r
 (.msi files) for WLH and WNET; WXP is x86 only. \r
 \r
 WARNING:\r
-   assupmtion: .\bin is populated correctly from makebin.bat or BuildRelease.bat makebin.\r
+   assupmtion: .\bin is populated correctly from makebin.bat or\r
+   'BuildRelease makebin'.\r
 \r
-cd gen1\branches\WinOF\WIX\wlh\x86 & nmake\r
+cd gen1\trunk\WinOF\WIX\wlh\x86 & nmake\r
        Results in a .\WOF_wlh_x86.msi installer image.\r
 \r
-cd gen1\branches\WinOF\WIX\wlh\x64 & nmake\r
+cd gen1\trunk\WinOF\WIX\wlh\x64 & nmake\r
        Results in a WOF_wlh_x64.msi installer image.\r
 \r
-cd gen1\branches\WinOF\WIX\wlh\ia64 & nmake\r
+cd gen1\trunk\WinOF\WIX\wlh\ia64 & nmake\r
        Results in a WOF_wlh_ia64.msi installer image.\r
 \r
 \r
-DEBUG\r
------\r
+DEBUG Installation\r
+------------------\r
 Create a log file for a given .msi installation:\r
 \r
   msiexec /I "WOF_x86.msi" /Lv \temp\msi.log\r
 \r
-  Also see %windir%\inf\setupapi.dev.log on Svr08 & Vista for driver load logging.\r
+  Also see %windir%\inf\setupapi.dev.log on Svr08 & Vista for driver load\r
+  logging.\r
 \r
 Command line way to set an interface's IP address, netmask, no gateway:\r
 \r
-  netsh interface ip set address "Local Area Connection 3" static 10.10.4.200 255.255.255.0\r
+  netsh interface ip set \\r
+         address "Local Area Connection 3" static 10.10.4.200 255.255.255.0\r
   netsh interface ip show address "Local Area Connection 3"\r
 \r
 \r
index 2ae77a5b6092ad970a42b5014cb5c00acae2c06e..adf1d8994bc804c5c18c93f99f371a65ad72aef6 100644 (file)
@@ -10,7 +10,7 @@ WinOF 2.1 Summary Changes
 1) The WinOF 2.1 release is based on openib-windows source svn revision\r
    (branches\WOF2-1 svn.xxxx).\r
 \r
-   Last WinOF release (2.0.1) based on svn 1932.\r
+   Last WinOF release (2.0.1) based on svn.1932.\r
 \r
 2) Bug fixes in\r
 \r
@@ -25,10 +25,23 @@ WinOF 2.1 Summary Changes
 \r
 3) New Functionality\r
 \r
-  A) Connected mode IPoIB ensures higher performance IPoIB transfers in\r
+  - OFED Compatibility layers allow for easy porting of OFED applications\r
+    into the WinOF environment.\r
+        libibverbs - OFED verbs API library.\r
+        libmad - InfiniBand MAD (Management Datagram) library.\r
+        libumad - IB MAD exported user-mode interface library.\r
+        librdmacm - OFED RDMA CM (Comunications Manager).\r
+\r
+  - OFED fabric diagnostic utilities are available.\r
+       ibstat - display HCA information.\r
+       ibnetdiscover - generate a fabric topology.\r
+       portinfo - display InfiniBand port specific information.\r
+       saquery - SA (Subnet Administrator) query test.\r
+\r
+  - Connected mode IPoIB ensures higher performance IPoIB transfers in\r
      addition to OFED (Linux) IPoIB compatibility.\r
 \r
-  B) Windows Server 2008/Vista WinOF installs now utilize Windows Plug-n-Play\r
+  - Windows Server 2008/Vista WinOF installs now utilize Windows Plug-n-Play\r
      (PNP) to install the correct HCA driver(s). Selection of a specific HCA\r
      device type is no longer required for Server 2008/Vista/HPC.\r
 \r
@@ -54,7 +67,7 @@ WinOF 2.1 Summary Changes
          start/wait msiexec /X WinOF_wlh_x64.msi /passive\r
 \r
 \r
-  C) Server 2008-HPC install support has been enhanced to provide a no-drivers\r
+  - Server 2008-HPC install support has been enhanced to provide a no-drivers\r
      installed mode. Device driver '.inf' files are not processed during the\r
      WinOF install.\r
      The base assumption is that a WDM node provisioning template will install\r
@@ -77,26 +90,15 @@ WinOF 2.1 Summary Changes
         unattended uninstall with auto-reboot:\r
           start/wait msiexec /X WOF.msi /passive\r
 \r
-  D) SRP and VNIC drivers are command line selectable:\r
+  - SRP and VNIC drivers are command line selectable:\r
         start/wait msiexec /I WOF.msi /passive SRP=1\r
         start/wait msiexec /I WOF.msi /passive VNIC=1\r
 \r
-  E) Subnet Management started as a local Windows Service from a command line:\r
+  - Subnet Management started as a local Windows Service from a command line:\r
         start/wait msiexec /I WOF.msi /passive OSMS=1\r
 \r
-  F) HCA drivers load WinVerbs and WinMad filter drivers by default.\r
+  - HCA drivers load WinVerbs and WinMad filter drivers by default.\r
 \r
-  G) OFED Compatibility layers allow for easy porting of OFED applications\r
-     into the WinOF environment.\r
-        libibverbs - OFED verbs API library.\r
-        libmad - InfiniBand MAD (Management Datagram) library.\r
-        libumad - IB MAD exported user-mode interface library.\r
-\r
-  H) OFED fabric diagnostic utilities are available.\r
-       ibstat - display HCA information.\r
-       ibnetdiscover - generate a fabric topology.\r
-       portinfo - display InfiniBand port specific information.\r
-       saquery - SA (Subnet Administrator) query test.\r
 \r
 \r
 Note on Vista installs Only:\r
index 0b9cdd1dbb96b72706d4493038807279048d8557..c8ceb7d1f1f5c7554c579d4aad13e7dbd61d7879 100644 (file)
@@ -92,7 +92,7 @@ src=openfabrics.gif></h1>
 <h1 align=center style='text-align:center'><a name="1.1_Release_Notes">2.1 Release Notes</a></h1>\r
 \r
 <h3 align=center style='text-align:center'>\r
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%m/%d/%Y" startspan -->03/09/2009<!--webbot bot="Timestamp" endspan i-checksum="12644" --></h3>\r
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%m/%d/%Y" startspan -->04/10/2009<!--webbot bot="Timestamp" endspan i-checksum="12510" --></h3>\r
 \r
 <div class=MsoNormal align=center style='text-align:center'>\r
 \r
@@ -255,6 +255,14 @@ supported devices below</span></font></li>
        Server 2008</span></font></p>\r
        </li>\r
        <li>\r
+       <p style='margin-left:.5in;text-indent:-.25in'><font face="Arial">Windows \r
+       Server 2008 R2</font></p>\r
+       </li>\r
+       <li>\r
+       <p style='margin-left:.5in;text-indent:-.25in'><font face="Arial">Windows 7 \r
+       (Server/Ultimate/Professional)</font></p>\r
+       </li>\r
+       <li>\r
        <p style='margin-left:.5in;text-indent:-.25in'><font face="Arial"><span dir="LTR">Vista</span></font></p>\r
        </li>\r
        <li>\r
@@ -612,17 +620,20 @@ system</font></p>
 <p><a href="#1.1_Release_Notes"><font color="#000000">&lt;Return-to-Top&gt;</font></a></p>\r
 <p>&nbsp;</p>\r
 <h3><u><a name="Server_2008_HPC_Install_Notes">Server 2008 HPC Install Notes</a></u></h3>\r
-<p><font face="Arial">Device drivers in WinOF 2.0 and later releases, are Digitally \r
-signed although they are not WHQL'ed (Windows Quality Hardware Labs) certified. The lack \r
-of WHQL certification impacts unattended installs by requiring the user to \r
-'accept' \r
-installation of the non-WHQL'ed driver the first time a compute node is \r
-installing WinOF drivers via the WinOF .msi installer.&nbsp; Additionally the non-WHQL \r
+<p><font face="Arial">Device drivers in WinOF 2.0 and later releases are Digitally \r
+signed by the OpenFabrics Alliance, although they are not WHQL'ed (Windows Quality Hardware Labs) certified. \r
+The WinOF source code is used&nbsp; by hardware vendors to achieve WHQL \r
+certification. This lack \r
+of WinOF WHQL certification impacts unattended installs by requiring the user to \r
+'accept' installation of non-WHQL'ed drivers the 'first' time a compute node \r
+installs WinOF drivers via the WinOF .msi installer.&nbsp;<br>\r
+Additionally the non-WHQL \r
 driver notifier box has a \r
-checkbox which allows establishing a trust for software from the publisher \r
-'OpenFabrics Alliance'. Checking this box allows future WinOF driver installs to proceed \r
-without user intervention as you have indicated to Windows that you trust non-WHQL \r
-drivers from the Openfabrics Alliance software publisher.</font></p>\r
+checkbox which allows establishing a <b><i>trust</i></b> for software from the publisher \r
+'OpenFabrics Alliance'. Checking the 'Trust Software from the OpenFabrics \r
+Alliance publisher'&nbsp; box allows future WinOF driver installs to proceed \r
+without user intervention as you have indicated to Windows that you trust non-WHQL'ed \r
+drivers from the OpenFabrics Alliance software publisher.</font></p>\r
 <p><font face="Arial">***** Warning *****<br>\r
 WinOF .msi installs on compute nodes the first time require human input to 'accept' \r
 installation of non-WHQL'ed drivers along with establishing a trust for the SW \r
@@ -631,17 +642,21 @@ If one attempts an unattended WinOF .msi install using 'clusrun.bat msiexec /i
 WinOF.....msi /quiet', the install will \r
 silently hang waiting for user input.<br>\r
 First time unattended WinOF .msi installs need mouse input to complete.&nbsp; \r
-Once the SW publisher trust has been established, future unattended WinOF .msi \r
+Once the Openfabrics Alliance SW publisher trust has been established, future unattended WinOF .msi \r
 installs procees without human input.</font></p>\r
 <p><font face="Arial">Be aware: if a node is reimaged (same or different template applied) the \r
 established trust of OpenFabric Alliance is destroyed, thus the non-WHQL driver \r
-notifier box and ensuing human input is again required on the first WinOF .msi \r
+notifier box and muse-click&nbsp; input is again required on the first WinOF .msi \r
 install</font></p>\r
 <h4><u>Windows Deployment Manager usage for HPC compute node provisioning</u></h4>\r
-<p><font face="Arial">Microsoft has chosen the WDM to provision HPC \r
-cluster compute nodes. WinOF now supports an administrative install mode which \r
-is a method to extract the WinOF installed files without actually installing them, \r
-thus making WinOF driver files accessible for WDM provisioning.</font></p>\r
+<p><font face="Arial">Microsoft has chosen WDM to provision HPC \r
+cluster compute nodes; see&nbsp;\r
+<a href="http://technet.microsoft.com/en-us/library/dd391826.aspx">Microsoft HPC \r
+installs</a> for details.</font></p>\r
+<p><font face="Arial">In support of the new Microsoft WDM HPC cluster \r
+provisioning process, WinOF now supports an administrative install mode which is \r
+a method to extract WinOF files to the local filesystem without actually installing them; \r
+thus making WinOF driver files accessible to WDM provisioning. </font></p>\r
 <p><font face="Arial">msiexec /A WinOF_2-0_wlh_x64.msi TARGETDIR=dev:\path-to-extracted-files</font></p>\r
 <p><font face="Arial">example:&nbsp; msiexec /A WinOF_2-1_wlh_x64.msi TARGETDIR=%TEMP%&nbsp;&nbsp; \r
 (note: TARGETDIR is case sensitive)</font></p>\r
@@ -659,7 +674,7 @@ QLogic VNIC (Virtual Ethernet controller over InfiniBand)</font></p>
 <h4><u>WinOF device driver-less installs:</u></h4>\r
 <p><font face="Arial">Normally WinOF device driver files are installed by processing the driver '.inf' \r
 files. To install the WinOF package by selecting install features without \r
-installing any device drivers [HCA, IPoIB, ND, WSD, SRP or VNIC] (assumded \r
+installing any device drivers [HCA, IPoIB, ND, WSD, SRP or VNIC] (assumed \r
 reliance on WDM to install drivers) can be accomplished with the following \r
 command:</font></p>\r
 <p><font face="Arial">start/wait msiexec /i WinOF_2-0-1_wlh_x64.msi NODRV=1</font></p>\r
index 6464e477513e5d75d5e70499a255cefd928f15ba..939a85a68cb27b02cba01b00784ddaa88c287756 100644 (file)
@@ -1,8 +1,10 @@
 @echo off\r
 setlocal\r
-rem\r
-rem create a ZIP file of a WinOF distribution, such that the zip file is pushed to the\r
-rem OFA WinOF download site, unzipped for distribution.\r
+\r
+rem TabStop=4\r
+\r
+rem Mfg. a ZIP file of a WinOF distribution, such that the zip file can be\r
+rem pushed to the OFA WinOF download site and unzipped for distribution.\r
 \r
 rem populate arch specific distribution folders, zip'em, populate symbols \r
 rem folder and zip the entire package for transmission to OFA download website.\r
@@ -20,6 +22,14 @@ rem  example build-OFA-dist 1-1 %windir%\temp
 rem    # if target_path is null then default %SystemRoot%\temp\v%1\r
 rem     # otherwise %2\v%1\r
 \r
+rem cmd.exe /V:on (delayed environment variable expansion) is required!\r
+set F=on\r
+set F=off\r
+if not "!F!" == "off" (\r
+   echo Err: cmd.exe /V:on [delayed environment variable expansion] Required!\r
+   exit /B 1\r
+)\r
+\r
 if "%1" == "" (\r
   echo "Missing release ID, example %0 1-1"\r
   echo "usage: %0 release_ID {target_path, default: %SystemRoot%\temp}\r
@@ -57,15 +67,23 @@ if not exist %SYMST% (
     exit /B 1 \r
 )\r
 \r
-FOR %%s IN ( wxp wlh wnet ) DO (\r
+FOR %%s IN ( win7 wxp wlh wnet ) DO (\r
+    if exist %CD%\%%s\bin\Misc\Manual.htm (\r
+               set OSF=%%s !OSF!\r
+       )\r
+)\r
+echo Packaging installers for !OSF!\r
 \r
+if "!OSF!" == "" (\r
+    echo "Missing components?"\r
+    echo "Must execute from gen1\branches\WinOF\WIX -- and --"\r
+    echo "  .\win7,wnet,wxp,wlh\bin\ must be populated."\r
+    echo "  run gen1\trunk\buildRelease.bat -or- gen1\trunk\etc\makebin"\r
+    exit /B 1\r
+)\r
+\r
+FOR %%s IN ( !OSF! ) DO (\r
        echo Building %%s installers.\r
-    if not exist %CD%\%%s\bin\Misc\Manual.htm (\r
-        echo "Must execute from gen1\branches\WinOF\WIX -- and --"\r
-        echo "  .\wnet,wxp,wlh\bin\ must be populated."\r
-        echo "  run gen1\trunk\buildRelease.bat -or- gen1\trunk\etc\makebin"\r
-        exit /B 1\r
-    )\r
 \r
     rem create target structure\r
        mkdir %MSI_DST%\%%s\r
@@ -207,6 +225,7 @@ pushd v%ID%
 rename wlh Server_2008-Vista-HPC\r
 rename wnet Server_2003-XP64\r
 rename wxp XP32\r
+if exist win7  rename win7 Windows7\r
 popd\r
 \r
 IF EXIST %ZIP%  del /F/Q %ZIP%\r
index eff7df1a12367cf05b87ffd40583e315845bbd8e..75d998420d79d3ac2dfe3ae20c86e027ca945f8c 100644 (file)
@@ -1,7 +1,7 @@
 \r
 <Include>\r
 \r
-       <?define WOFREL="v2.1 (RC0)" ?>\r
+       <?define WOFREL="v2.1 (pre-RC0)" ?>\r
 \r
        <?define WOFRELNUM=2.1.0 ?>\r
 \r
index a6decfdb1460b17820238315aed95dd662039ab7..986308f94ba22d570416372c0fff88789b37341e 100644 (file)
@@ -37,8 +37,8 @@
         <![CDATA[VersionNT64]]>\r
     </Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 to install.">\r
-         <![CDATA[(VersionNT=600)]]>\r
+    <Condition Message="[ProductName] requires Windows 7 or Server 2008 R2 to install.">\r
+         <![CDATA[(VersionNT=601)]]>\r
     </Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
index bdd57de44a31ffe12c2892ba6931320cca23755a..8cb87228e7047c87071d4b79b4cb90e4580f8dc5 100644 (file)
@@ -8,7 +8,7 @@ rem   signDrivers CrossCertFilename CertStoreName path-2-drivers {noTimeStamp}
 rem            CrossCertFilename - fully qualified path\filename of cross cert.\r
 rem            CertStoreName - name of certificate in 'MY' Cert store (certmgr).\r
 \r
-rem example: signDrivers %CD%\cse1CCFilename My bin\hca\r
+rem example: signDrivers %CD%\Cross-Cert SWPublisher bin\hca\r
 \r
 rem cmd.exe /V:on (delayed environment variable expansion) is required!\r
 set F=on\r
@@ -59,7 +59,7 @@ rem make sure signtool is accessible in our path
 path > jnk.txt\r
 findstr /c:"SelfSign" jnk.txt > jnk1.txt\r
 if %errorlevel% EQU 1 (\r
-    path "%PATH%;C:\WinDDK\6001.18001\bin\SelfSign"\r
+    path "%PATH%;C:\WinDDK\xxx\bin\SelfSign"\r
 )\r
 if exist jnk1.txt  del /Q /F jnk1.txt\r
 if exist jnk.txt  del /Q /F jnk.txt\r
@@ -85,25 +85,21 @@ for %%d in (amd64 x86 ia64) do (
             if exist %%f del /F /Q %%f\r
         )\r
 \r
-rem temp hack until inf2cat support /OS WIN7_xxx\r
-               if "%%d" == "amd64" set OEA=Server2008_X64\r
-               if "%%d" == "x86"   set OEA=Server2008_X86\r
-               if "%%d" == "ia64"  set OEA=Server2008_IA64\r
+               rem set OS type for inf2cat\r
+               if "%%d" == "x86"   set OEA=7_X86\r
+               if "%%d" == "amd64" set OEA=7_X64,Server2008R2_X64\r
+               if "%%d" == "ia64"  set OEA=Server2008R2_IA64\r
 \r
-rem            if "%%d" == "amd64" set OEA=%OE%_X64,Vista_X64\r
-rem            if "%%d" == "x86"   set OEA=%OE%_X86,Vista_X86\r
-rem            if "%%d" == "ia64"  set OEA=%OE%_IA64\r
-\r
-        echo %0 - Generating %%d .cat files for !OEA!\r
-        inf2cat /driver:%CD%\%%d /os:!OEA!\r
+        echo %0 [%OE%] Generating %%d .cat files for !OEA!\r
+        inf2cat /driver:!CD! /os:!OEA!\r
         if ERRORLEVEL 1 (\r
             echo %CD% inf2cat failed\r
             exit /B 1\r
         )\r
-        echo %0 - Signing %%d .cat files\r
+        echo %0 [%OE%] Signing %%d .cat files\r
         for %%f in ( *.cat ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -118,10 +114,10 @@ rem               if "%%d" == "ia64"  set OEA=%OE%_IA64
                        echo +\r
         )\r
 \r
-        echo %0 - Signing %%d .sys files\r
+        echo %0 [%OE%] Signing %%d .sys files\r
         for %%f in ( *.sys ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -136,12 +132,12 @@ rem               if "%%d" == "ia64"  set OEA=%OE%_IA64
                        echo +\r
         )\r
 \r
-        echo %0 - Verify %%d .cat + .sys files\r
+        echo %0 [%OE%] Verify %%d .cat + .sys files\r
         for %%f in ( *.sys ) do (\r
                        set D=%%f\r
                        set C=!D:sys=cat!\r
                        if exist !C! (\r
-                               echo %0 - Verify %%d\!C! %%d\%%f\r
+                               echo %0 [%OE%] Verify %%d\!C! %%d\%%f\r
                                signtool verify /q /kp /c !C! %%f\r
                                if ERRORLEVEL 1 (\r
                                        echo %0 signtool verify /kp /c !C! %%f failed?\r
@@ -159,5 +155,6 @@ rem         if "%%d" == "ia64"  set OEA=%OE%_IA64
     )\r
 )\r
 \r
+echo %0 [%OE%] Finished: %0 %1 %2\r
+echo +\r
 endlocal\r
-echo %0 - Finished: %0 %1 %2 %OE% \r
index f4a51162b676ee7dbba44f37bfd1d96e1419d77a..14b3909a30548c5dc646a39a17d1ffbc365bdde8 100644 (file)
@@ -37,8 +37,8 @@
         <![CDATA[Msix64]]>\r
     </Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
-         <![CDATA[(VersionNT=600)]]>\r
+    <Condition Message="[ProductName] requires Windows 7 or Server 2008 R2 to install.">\r
+         <![CDATA[(VersionNT=601)]]>\r
     </Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
index a859b15febc5c028e6b32b77fbe6c6dc2a935df6..a4d1297f0a0bae324fe86f676d48757d07044191 100644 (file)
@@ -32,8 +32,8 @@
     <Condition Message="This package can be installed on x86 systems only">\r
      <![CDATA[(Not Intel64) And (Not Msix64)]]></Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
-     <![CDATA[(VersionNT=600)]]></Condition>\r
+    <Condition Message="[ProductName] requires Windows 7 or Server 2008 R2 to install.">\r
+     <![CDATA[(VersionNT=601)]]></Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
 \r
index e82dbc5c3c950f836d51bdc775060fceb4daebe0..a18a044b454ec9df6b614cdb6055289ec8a114a5 100644 (file)
@@ -37,8 +37,9 @@
         <![CDATA[VersionNT64]]>\r
     </Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 to install.">\r
-         <![CDATA[(VersionNT=600)]]>\r
+    <Condition\r
+      Message="[ProductName] requires Windows Server 2008 to install.">\r
+      <![CDATA[(VersionNT=600 OR VersionNT=601)]]>\r
     </Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
         Display="expand" Level="2" ConfigurableDirectory="INSTALLDIR"\r
         AllowAdvertise="no" InstallDefault="local" Absent="allow">\r
         <ComponentRef Id="cNetworkDirect" />\r
-        <Condition Level="201"> IPOIB_EXISTS </Condition> \r
+        <Condition Level="201"> IPOIB_EXISTS </Condition>\r
     </Feature>\r
 -->\r
     <Feature Id="fOSMS" Title="OpenSM Service Started" Level="5"\r
     </Feature>\r
 \r
     <Feature Id="fSRP" Title="SRP" Level="5" Description="SCSI over RDMA"\r
-         Display="expand" ConfigurableDirectory="INSTALLDIR"\r
-         AllowAdvertise='no' InstallDefault='local' Absent='allow'>\r
+        Display="expand" ConfigurableDirectory="INSTALLDIR"\r
+        AllowAdvertise="no" InstallDefault="local" Absent="allow">\r
       <ComponentRef Id="cSRP_driver_installed" />\r
     </Feature>\r
 \r
index d95efb6c8b36248a6effe6e11a28e7d328d1ef66..8927b3b20d8592f4f72dcc91b283d647a3e716cb 100644 (file)
@@ -8,7 +8,7 @@ rem   signDrivers CrossCertFilename CertStoreName path-2-drivers {noTimeStamp}
 rem            CrossCertFilename - fully qualified path\filename of cross cert.\r
 rem            CertStoreName - name of certificate in 'MY' Cert store (certmgr).\r
 \r
-rem example: signDrivers %CD%\cse1CStore TestCert bin\hca\r
+rem example: signDrivers %CD%\Cross-Cert SWPublisher bin\hca\r
 \r
 rem cmd.exe /V:on (delayed environment variable expansion) is required!\r
 set F=on\r
@@ -59,7 +59,7 @@ rem make sure signtool is accessible in our path
 path > jnk.txt\r
 findstr /c:"SelfSign" jnk.txt > jnk1.txt\r
 if %errorlevel% EQU 1 (\r
-    path "%PATH%;C:\WinDDK\6001.18001\bin\SelfSign"\r
+    path "%PATH%;C:\WinDDK\xxx\bin\SelfSign"\r
 )\r
 if exist jnk1.txt  del /Q /F jnk1.txt\r
 if exist jnk.txt  del /Q /F jnk.txt\r
@@ -89,16 +89,16 @@ for %%d in (amd64 x86 ia64) do (
                if "%%d" == "x86"   set OEA=%OE%_X86,Vista_X86\r
                if "%%d" == "ia64"  set OEA=%OE%_IA64\r
 \r
-        echo %0 - Generating %%d .cat files for !OEA!\r
-        inf2cat /driver:%CD%\%%d /os:!OEA!\r
+        echo %0 [%OE%] Generating %%d .cat files for !OEA!\r
+        inf2cat /driver:!CD! /os:!OEA!\r
         if ERRORLEVEL 1 (\r
             echo %CD% inf2cat failed\r
             exit /B 1\r
         )\r
-        echo %0 - Signing %%d .cat files\r
+        echo %0 [%OE%] Signing %%d .cat files\r
         for %%f in ( *.cat ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -113,10 +113,10 @@ for %%d in (amd64 x86 ia64) do (
                        echo +\r
         )\r
 \r
-        echo %0 - Signing %%d .sys files\r
+        echo %0 [%OE%] Signing %%d .sys files\r
         for %%f in ( *.sys ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -131,12 +131,12 @@ for %%d in (amd64 x86 ia64) do (
                        echo +\r
         )\r
 \r
-        echo %0 - Verify %%d .cat + .sys files\r
+        echo %0 [%OE%] Verify %%d .cat + .sys files\r
         for %%f in ( *.sys ) do (\r
                        set D=%%f\r
                        set C=!D:sys=cat!\r
                        if exist !C! (\r
-                               echo %0 - Verify %%d\!C! %%d\%%f\r
+                               echo %0 [%OE%] Verify %%d\!C! %%d\%%f\r
                                signtool verify /q /kp /c !C! %%f\r
                                if ERRORLEVEL 1 (\r
                                        echo %0 signtool verify /kp /c !C! %%f failed?\r
@@ -154,5 +154,6 @@ for %%d in (amd64 x86 ia64) do (
     )\r
 )\r
 \r
+echo %0 [%OE%] Finished: %0 %1 %2\r
+echo +\r
 endlocal\r
-echo %0 - Finished: %0 %1 %2 %OE% \r
index 562238d7726bcf6e8228d8b45ccbd038b48c425f..5d735bb85a6cc9b96bbfbf303a954f945cb9f4f7 100644 (file)
@@ -37,8 +37,9 @@
         <![CDATA[Msix64]]>\r
     </Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
-         <![CDATA[(VersionNT=600)]]>\r
+    <Condition\r
+      Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
+      <![CDATA[(VersionNT=600 OR VersionNT=601)]]>\r
     </Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
     </Feature>\r
 \r
     <Feature Id="fWSD" Title="WSD" Description="Winsock Direct Enabled"\r
-            Display="expand" Level="1" ConfigurableDirectory="INSTALLDIR"\r
-         AllowAdvertise='no' InstallDefault='local' Absent='allow'>\r
+           Display="expand" Level="1" ConfigurableDirectory="INSTALLDIR"\r
+        AllowAdvertise='no' InstallDefault='local' Absent='allow'>\r
       <!-- skip WSD on Windows XP, IPoIB is required for WSD. -->\r
       <Condition Level="200"><![CDATA[VersionNT=501]]></Condition>\r
       <Condition Level="201"> IPOIB_EXISTS </Condition>\r
     </Feature>\r
 \r
     <Feature Id="fSRP" Title="SRP" Level="5" Description="SCSI over RDMA"\r
-         Display="expand" ConfigurableDirectory="INSTALLDIR"\r
-         AllowAdvertise='no' InstallDefault='local' Absent='allow'>\r
+        Display="expand" ConfigurableDirectory="INSTALLDIR"\r
+        AllowAdvertise="no" InstallDefault="local" Absent="allow">\r
       <ComponentRef Id="cSRP_driver_installed" />\r
     </Feature>\r
 \r
index e7990176bb9745589d7f5b6b7e7eaff235a34900..7dcceedb06333ea4a2624427f981b421f35b8052 100644 (file)
     </Condition>\r
 \r
     <Condition Message="This package can be installed on x86 systems only">\r
-     <![CDATA[(Not Intel64) And (Not Msix64)]]></Condition>\r
+     <![CDATA[(Not Intel64) And (Not Msix64)]]>\r
+    </Condition>\r
 \r
-    <Condition Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
-     <![CDATA[(VersionNT=600)]]></Condition>\r
+    <Condition\r
+      Message="[ProductName] requires Windows Server 2008 or Vista to install.">\r
+      <![CDATA[(VersionNT=600 OR VersionNT=601)]]>\r
+    </Condition>\r
 \r
     <?include ..\..\common\requirements.inc ?>\r
 \r
         Description="Internet Protocols over InfiniBand" Display="expand"\r
         ConfigurableDirectory="INSTALLDIR" AllowAdvertise="no"\r
         InstallDefault="local" Absent="allow">\r
-        <ComponentRef Id="IPoIB" />\r
+      <ComponentRef Id="IPoIB" />\r
     </Feature>\r
 \r
     <Feature Id="fWSD" Title="WSD" Description="Winsock Direct Enabled"\r
         Description="Open Subnet Management started as a local Windows Service"\r
         Display="expand" ConfigurableDirectory="INSTALLDIR" AllowAdvertise="no"\r
         InstallDefault="local" Absent="allow">\r
-        <ComponentRef Id="OpenSM_Service_enabled" />\r
+      <ComponentRef Id="OpenSM_Service_enabled" />\r
     </Feature>\r
 \r
     <Feature Id="fDAPL" Title="DAPL" Description="DAT+DAPL over InfiniBand"\r
     </Feature>\r
 \r
     <Feature Id="fSRP" Title="SRP" Level="5" Description="SCSI over RDMA"\r
-        Display="expand" ConfigurableDirectory="INSTALLDIR" AllowAdvertise="no"\r
-        InstallDefault="local" Absent="allow">\r
+        Display="expand" ConfigurableDirectory="INSTALLDIR"\r
+        AllowAdvertise="no" InstallDefault="local" Absent="allow">\r
         <!-- skip SRP on 32-bit Windows XP -->\r
         <Condition Level="0">\r
           <![CDATA[VersionNT=501 AND (Not Intel64 AND Not Msix64)]]>\r
         </Condition>\r
-        <ComponentRef Id="cSRP_driver_installed" />\r
+      <ComponentRef Id="cSRP_driver_installed" />\r
     </Feature>\r
 \r
     <Feature Id="fVNIC" Title="QLogic-VNIC"\r
index c8665fc2943adb8776bef7d3660f202b5762b127..13b00cf70b3018562253b6cf64d0a99f68714a1c 100644 (file)
@@ -8,7 +8,7 @@ rem   signDrivers CrossCertFilename CertStoreName path-2-drivers {noTimeStamp}
 rem            CrossCertFilename - fully qualified path\filename of cross cert.\r
 rem            CertStoreName - name of certificate in 'MY' Cert store (certmgr).\r
 \r
-rem example: signDrivers %CD%\cse1CStore TestCert bin\hca\r
+rem example: signDrivers %CD%\Cross-Cert SWPublisher bin\hca\r
 \r
 rem cmd.exe /V:on (delayed environment variable expansion) is required!\r
 set F=on\r
@@ -59,7 +59,7 @@ rem make sure signtool is accessible in our path
 path > jnk.txt\r
 findstr /c:"SelfSign" jnk.txt > jnk1.txt\r
 if %errorlevel% EQU 1 (\r
-    path "%PATH%;C:\WinDDK\6001.18001\bin\SelfSign"\r
+    path "%PATH%;C:\WinDDK\xxx\bin\SelfSign"\r
 )\r
 if exist jnk1.txt  del /Q /F jnk1.txt\r
 if exist jnk.txt  del /Q /F jnk.txt\r
@@ -89,16 +89,16 @@ for %%d in (amd64 x86 ia64) do (
                if "%%d" == "x86"   set OEA=%OE%_X86\r
                if "%%d" == "ia64"  set OEA=%OE%_IA64\r
 \r
-        echo %0 - Generating %%d .cat files for !OEA!\r
-        inf2cat /driver:%CD%\%%d /os:!OEA!\r
+        echo %0 [%OE%] Generating %%d .cat files for !OEA!\r
+        inf2cat /driver:!CD! /os:!OEA!\r
         if ERRORLEVEL 1 (\r
             echo %CD% inf2cat failed\r
             exit /B 1\r
         )\r
-        echo %0 - Signing %%d .cat files\r
+        echo %0 [%OE%] Signing %%d .cat files\r
         for %%f in ( *.cat ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -113,10 +113,10 @@ for %%d in (amd64 x86 ia64) do (
                        echo +\r
         )\r
 \r
-        echo %0 - Signing %%d .sys files\r
+        echo %0 [%OE%] Signing %%d .sys files\r
         for %%f in ( *.sys ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -131,12 +131,12 @@ for %%d in (amd64 x86 ia64) do (
                        echo +\r
         )\r
 \r
-        echo %0 - Verify %%d .cat + .sys files\r
+        echo %0 [%OE%] Verify %%d .cat + .sys files\r
         for %%f in ( *.sys ) do (\r
                        set D=%%f\r
                        set C=!D:sys=cat!\r
                        if exist !C! (\r
-                               echo %0 - Verify %%d\!C! %%d\%%f\r
+                               echo %0 [%OE%] Verify %%d\!C! %%d\%%f\r
                                signtool verify /q /kp /c !C! %%f\r
                                if ERRORLEVEL 1 (\r
                                        echo %0 signtool verify /kp /c !C! %%f failed?\r
@@ -154,5 +154,6 @@ for %%d in (amd64 x86 ia64) do (
     )\r
 )\r
 \r
+echo %0 [%OE%] Finished: %0 %1 %2\r
+echo +\r
 endlocal\r
-echo %0 - Finished: %0 %1 %2 %OE% \r
index 933650f926a6c8c15842174cc9cf2d00a659ae2a..3311a0beca10136c152db535cdcd700150b8bb03 100644 (file)
@@ -8,7 +8,7 @@ rem   signDrivers CrossCertFilename CertStoreName path-2-drivers {noTimeStamp}
 rem            CrossCertFilename - fully qualified path\filename of cross cert.\r
 rem            CertStoreName - name of certificate in 'MY' Cert store (certmgr).\r
 \r
-rem example: signDrivers %CD%\cse1CStore TestCert bin\hca\r
+rem example: signDrivers %CD%\Cross-Cert SWPublisher bin\hca\r
 \r
 rem cmd.exe /V:on (delayed environment variable expansion) is required!\r
 set F=on\r
@@ -59,7 +59,7 @@ rem make sure signtool is accessible in our path
 path > jnk.txt\r
 findstr /c:"SelfSign" jnk.txt > jnk1.txt\r
 if %errorlevel% EQU 1 (\r
-    path "%PATH%;C:\WinDDK\6001.18001\bin\SelfSign"\r
+    path "%PATH%;C:\WinDDK\xxx\bin\SelfSign"\r
 )\r
 if exist jnk1.txt  del /Q /F jnk1.txt\r
 if exist jnk.txt  del /Q /F jnk.txt\r
@@ -70,7 +70,7 @@ if ERRORLEVEL 1 (
     echo %0 - missing relative path %3\r
     exit /B 1\r
 )\r
-echo cwd %CD%\r
+echo cwd !CD!\r
 \r
 rem Sign drivers only for x86 architecture\r
 \r
@@ -89,16 +89,16 @@ for %%d in ( x86 ) do (
 rem     if "%%d" == "amd64" set OEA=%OE%_X64\r
 rem            if "%%d" == "ia64"  set OEA=%OE%_IA64\r
 \r
-        echo %0 - Generating %%d .cat files for !OEA!\r
-        inf2cat /driver:%CD%\%%d /os:!OEA!\r
+        echo %0 [%OE%] Generating %%d .cat files for !OEA!\r
+        inf2cat /driver:!CD! /os:!OEA!\r
         if ERRORLEVEL 1 (\r
             echo %CD% inf2cat failed\r
             exit /B 1\r
         )\r
-        echo %0 - Signing %%d .cat files\r
+        echo %0 [%OE%] Signing %%d .cat files\r
         for %%f in ( *.cat ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -113,10 +113,10 @@ rem               if "%%d" == "ia64"  set OEA=%OE%_IA64
                        echo +\r
         )\r
 \r
-        echo %0 - Signing %%d .sys files\r
+        echo %0 [%OE%] Signing %%d .sys files\r
         for %%f in ( *.sys ) do (\r
-            echo %0 - Signing %%d\%%f\r
-            signtool sign /ac %1 /n %2 %TS% %DU% %%f\r
+            echo %0 [%OE%] Signing %%d\%%f\r
+            signtool sign /ac %1 /s "My" /n %2 %TS% %DU% %%f\r
             if ERRORLEVEL 1 (\r
                 echo %0 signtool sign %%f failed?\r
                 echo %0    file %CD%\%%f\r
@@ -131,12 +131,12 @@ rem               if "%%d" == "ia64"  set OEA=%OE%_IA64
                        echo +\r
         )\r
 \r
-        echo %0 - Verify %%d .cat + .sys files\r
+        echo %0 [%OE%] Verify %%d .cat + .sys files\r
         for %%f in ( *.sys ) do (\r
                        set D=%%f\r
                        set C=!D:sys=cat!\r
                        if exist !C! (\r
-                               echo %0 - Verify %%d\!C! %%d\%%f\r
+                               echo %0 [%OE%] Verify %%d\!C! %%d\%%f\r
                                signtool verify /q /kp /c !C! %%f\r
                                if ERRORLEVEL 1 (\r
                                        echo %0 signtool verify /kp /c !C! %%f failed?\r
@@ -154,5 +154,6 @@ rem         if "%%d" == "ia64"  set OEA=%OE%_IA64
     )\r
 )\r
 \r
+echo %0 [%OE%] Finished: %0 %1 %2\r
+echo +\r
 endlocal\r
-echo %0 - Finished: %0 %1 %2 %OE% \r
index 5d2d369f49c5ba08908e1cc0d0a85ad0af96e889..07a838b15d7404bb8f21de891a04b28627b7da5d 100644 (file)
@@ -116,7 +116,7 @@ kal_cep_alloc(
        IN                              ib_al_handle_t                          h_al,\r
        IN      OUT                     net32_t* const                          p_cid );\r
 \r
-void\r
+ib_api_status_t\r
 kal_cep_config(\r
        IN                              ib_al_handle_t                          h_al,\r
        IN                              net32_t                                         cid,\r
@@ -184,18 +184,6 @@ kal_cep_pre_rep(
        IN                              uint8_t                                         rnr_nak_timeout,\r
        IN      OUT                     ib_qp_mod_t* const                      p_init OPTIONAL );\r
 \r
-ib_api_status_t\r
-kal_cep_config_pre_rep_copy_cid(\r
-       IN                              ib_al_handle_t                          h_al,\r
-       IN                              net32_t                                         cid,\r
-       IN                              al_pfn_cep_cb_t                         pfn_cb,\r
-       IN                              void*                                           context,\r
-       IN                              ib_pfn_destroy_cb_t                     pfn_destroy_cb,\r
-       IN              const   iba_cm_rep* const                       p_cm_rep,\r
-       IN                              uint8_t                                         rnr_nak_timeout,\r
-       IN      OUT                     net32_t* const                          p_cid,\r
-               OUT                     ib_qp_mod_t* const                      p_init );\r
-\r
 void\r
 kal_cep_destroy(\r
        IN                              ib_al_handle_t                          h_al,\r
@@ -337,13 +325,6 @@ al_cep_queue_irp(
        IN                              net32_t                                         cid,\r
        IN                              IRP* const                                      p_irp );\r
 \r
-NTSTATUS\r
-al_cep_get_cid(\r
-       IN              ib_al_handle_t                                          h_al,\r
-       IN              net32_t                 const                           cid,\r
-       IN              PIRP                                                            h_ioctl\r
-       );\r
-\r
 NTSTATUS\r
 al_cep_get_pdata(\r
        IN                              ib_al_handle_t                          h_al,\r
@@ -353,6 +334,12 @@ al_cep_get_pdata(
        IN      OUT                     uint8_t                                         *p_psize,\r
                OUT                     uint8_t*                                        pdata );\r
 \r
+void*\r
+kal_cep_get_context(\r
+       IN                              ib_al_handle_t                          h_al,\r
+       IN                              net32_t                                         cid,\r
+       IN                              al_pfn_cep_cb_t                         pfn_cb,\r
+       IN                              ib_pfn_destroy_cb_t                     pfn_addref );\r
 #endif /* CL_KERNEL */\r
 \r
 \r
index 212dada0e8461c51e804cbe90d4db525078b7688..6d26e34f1d55b4852e0f1af4e3068e2f552d7061 100644 (file)
@@ -55,7 +55,7 @@
 #define AL_DEVICE_NAME L"\\Device\\ibal"\r
 #define        ALDEV_KEY               (0x3B)  /* Matches FILE_DEVICE_INFINIBAND from wdm.h */\r
 \r
-#define AL_IOCTL_VERSION                       (11)\r
+#define AL_IOCTL_VERSION                       (12)\r
 \r
 /* max number of devices with non-default pkey */\r
 #define        MAX_NUM_PKEY    16\r
@@ -353,7 +353,6 @@ typedef enum _ual_cep_ops
        ual_cep_get_timewait,\r
        ual_cep_get_event,\r
        ual_cep_poll,\r
-       ual_cep_get_req_cid,\r
        ual_cep_get_pdata,\r
 \r
        al_cep_maxops\r
@@ -408,6 +407,9 @@ typedef enum _al_ndi_ops
        ual_ndi_dreq_cm_ioctl_cmd,\r
     ual_ndi_noop,\r
     ual_ndi_notify_dreq_cmd,\r
+       ual_ndi_cancel_cm_irps,\r
+       ual_ndi_listen_cm_cmd,\r
+       ual_ndi_get_req_cm_cmd,\r
 \r
        al_ndi_maxops\r
 \r
@@ -440,6 +442,9 @@ typedef enum _al_ioc_device_config
 #define UAL_NDI_DREQ_CM                        IOCTL_CODE(ALDEV_KEY, ual_ndi_dreq_cm_ioctl_cmd)\r
 #define UAL_NDI_NOOP            IOCTL_CODE(ALDEV_KEY, ual_ndi_noop)\r
 #define UAL_NDI_NOTIFY_DREQ     IOCTL_CODE(ALDEV_KEY, ual_ndi_notify_dreq_cmd)\r
+#define UAL_NDI_CANCEL_CM_IRPS IOCTL_CODE(ALDEV_KEY, ual_ndi_cancel_cm_irps)\r
+#define UAL_NDI_LISTEN_CM              IOCTL_CODE(ALDEV_KEY, ual_ndi_listen_cm_cmd)\r
+#define UAL_NDI_GET_REQ_CM             IOCTL_CODE(ALDEV_KEY, ual_ndi_get_req_cm_cmd)\r
 \r
 /*\r
  * Various Operation Allowable on the System Helper\r
@@ -541,7 +546,6 @@ typedef enum _al_ioc_device_config
 #define UAL_CEP_GET_TIMEWAIT   IOCTL_CODE(ALDEV_KEY, ual_cep_get_timewait)\r
 #define UAL_CEP_GET_EVENT      IOCTL_CODE(ALDEV_KEY, ual_cep_get_event)\r
 #define UAL_CEP_POLL           IOCTL_CODE(ALDEV_KEY, ual_cep_poll)\r
-#define UAL_CEP_GET_REQ_CID    IOCTL_CODE(ALDEV_KEY, ual_cep_get_req_cid)\r
 #define UAL_CEP_GET_PDATA      IOCTL_CODE(ALDEV_KEY, ual_cep_get_pdata)\r
 \r
 \r
index 05c99d545210b22e4ddfb1d99e3d38102a03ae3d..a3313011c06bae0d9e84b938bffc25e81edceef2 100644 (file)
@@ -327,10 +327,6 @@ 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( status == IB_SUCCESS && !NT_SUCCESS( ndi_qp_init(h_qp) ) )\r
-                       status = IB_ERROR;\r
-#endif\r
                break;\r
 \r
        case IB_QPT_UNRELIABLE_DGRM:\r
@@ -1117,9 +1113,6 @@ destroying_qp(
        case IB_QPT_RELIABLE_CONN:\r
        case IB_QPT_UNRELIABLE_CONN:\r
                al_destroy_cep( h_qp->obj.h_al, &((al_conn_qp_t*)h_qp)->cid, FALSE );\r
-#ifdef CL_KERNEL\r
-               ndi_qp_destroy( h_qp );\r
-#endif\r
 \r
                /* Fall through. */\r
        case IB_QPT_UNRELIABLE_DGRM:\r
@@ -1237,10 +1230,6 @@ free_qp(
        CL_ASSERT( p_obj );\r
        h_qp = PARENT_STRUCT( p_obj, ib_qp_t, obj );\r
 \r
-#ifdef CL_KERNEL\r
-       ndi_qp_free( h_qp );\r
-#endif\r
-\r
        destroy_al_obj( p_obj );\r
        cl_free( h_qp );\r
 }\r
index b8847849ba35f25c0278090577839b17e2c50bcb..f2deaf46543ada68619646f1606eb00483eb584c 100644 (file)
@@ -135,10 +135,6 @@ typedef struct _ib_qp
                IN              const   ib_qp_handle_t                          h_qp,\r
                IN              const   ib_mcast_req_t* const           p_mcast_req );\r
 \r
-#ifdef CL_KERNEL\r
-       ndi_qp_csq_t                            *p_irp_queue;\r
-#endif\r
-\r
 }      ib_qp_t;\r
 \r
 \r
index 9ed239bb1b48c67b80634a19ba94de711415535a..9e9c4221bb7be67b7b44416ba197e4da84e043d9 100644 (file)
@@ -370,9 +370,6 @@ typedef struct _al_kcep
         * NDI stuff - TODO: manage above core kernel CM code\r
         */\r
 \r
-       /* IRP list head */\r
-       LIST_ENTRY                                      irp_que;\r
-\r
        /* private data of REQ, REP, REJ CM requests */ \r
        uint8_t                                         psize;\r
        uint8_t                                         pdata[IB_REP_PDATA_SIZE];\r
@@ -3382,24 +3379,6 @@ create_cep_mgr(
 * CEP manager API\r
 ******************************************************************************/\r
 \r
-static inline void \r
-__complete_ndi_irp(\r
-       IN                              PIRP                                            p_irp,\r
-       IN                              ib_mad_element_t*                       p_mad )\r
-{\r
-       net32_t* p_new_cid = (net32_t*)cl_ioctl_out_buf( p_irp );\r
-       kcep_t* p_cep = (kcep_t*)p_mad->send_context1;\r
-\r
-       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_CM,\r
-               ("Completing al_cep_get_cid IRP with CID = %d\n", p_cep->cid) );\r
-\r
-       *p_new_cid = p_cep->cid;\r
-       p_irp->IoStatus.Information = sizeof(uint32_t);\r
-       p_irp->IoStatus.Status = STATUS_SUCCESS;\r
-       IoCompleteRequest( p_irp, IO_NETWORK_INCREMENT );\r
-       ib_put_mad( p_mad );\r
-}\r
-\r
 \r
 /* Called with the CEP and CEP manager locks held */\r
 static ib_api_status_t\r
@@ -3422,8 +3401,6 @@ __cep_queue_mad(
        if ( p_cep->state == CEP_STATE_LISTEN &&\r
                (p_cep->sid & ~0x0ffffffI64) == IB_REQ_CM_RDMA_SID_PREFIX )\r
        { /* Try to complete pending IRP, if any */\r
-               PIRP p_irp;\r
-               PLIST_ENTRY p_list_entry;\r
                mad_cm_req_t* p_req = (mad_cm_req_t*)ib_get_mad_buf( p_mad );\r
                ib_cm_rdma_req_t *p_rdma_req = (ib_cm_rdma_req_t *)p_req->pdata;\r
 \r
@@ -3437,24 +3414,6 @@ __cep_queue_mad(
                                p_rdma_req->maj_min_ver, p_rdma_req->ipv ) );\r
                        return IB_UNSUPPORTED;\r
                }\r
-               \r
-               /* get a pending IRP */\r
-               if ( !IsListEmpty( &p_cep->irp_que ) )\r
-               {\r
-                       // get IRP\r
-                       p_list_entry = RemoveHeadList( &p_cep->irp_que );\r
-                       p_irp = (PIRP)CONTAINING_RECORD( p_list_entry, IRP, Tail.Overlay.ListEntry );\r
-\r
-                       // complete GetConnectionReq IRP\r
-#pragma warning(push, 3)\r
-                       IoSetCancelRoutine( p_irp, NULL );\r
-#pragma warning(pop)\r
-\r
-                       __complete_ndi_irp( p_irp, p_mad );\r
-\r
-                       AL_EXIT( AL_DBG_CM );\r
-                       return IB_PENDING;\r
-               }\r
        }\r
 \r
        /* Queue this MAD for processing. */\r
@@ -3628,8 +3587,6 @@ __create_cep()
 \r
        p_cep->p_cid->p_cep = p_cep;\r
 \r
-       InitializeListHead( &p_cep->irp_que );\r
-\r
        ref_al_obj( &gp_cep_mgr->obj );\r
 \r
        AL_EXIT( AL_DBG_CM );\r
@@ -3682,7 +3639,7 @@ kal_cep_alloc(
        return IB_SUCCESS;\r
 }\r
 \r
-void\r
+ib_api_status_t\r
 kal_cep_config(\r
        IN                              ib_al_handle_t                          h_al,\r
        IN                              net32_t                                         cid,\r
@@ -3695,13 +3652,18 @@ kal_cep_config(
 \r
        KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl );\r
        p_cep = __lookup_cep( h_al, cid );\r
-       CL_ASSERT( p_cep );\r
+       if( p_cep == NULL )\r
+       {\r
+               KeReleaseInStackQueuedSpinLock( &hdl );\r
+               return IB_INVALID_HANDLE;\r
+       }\r
 \r
        p_cep->pfn_cb = pfn_cb;\r
        p_cep->context = context;\r
        p_cep->pfn_destroy_cb = pfn_destroy_cb;\r
 \r
        KeReleaseInStackQueuedSpinLock( &hdl );\r
+       return IB_SUCCESS;\r
 }\r
 \r
 static inline void\r
@@ -4128,7 +4090,7 @@ al_create_cep(
        status = kal_cep_alloc(h_al, p_cid);\r
        if ( status == IB_SUCCESS )\r
        {\r
-               kal_cep_config(h_al, *p_cid, pfn_cb, context, pfn_destroy_cb);\r
+               status = kal_cep_config(h_al, *p_cid, pfn_cb, context, pfn_destroy_cb);\r
        }\r
 \r
        AL_EXIT( AL_DBG_CM );\r
@@ -4174,28 +4136,6 @@ al_destroy_cep(
        context = p_cep->context;\r
        pfn_destroy_cb = p_cep->pfn_destroy_cb;\r
 \r
-       /* Cancel any queued IRP */\r
-       __cep_complete_irp( p_cep, STATUS_CANCELLED, IO_NO_INCREMENT );\r
-\r
-    while( !IsListEmpty( &p_cep->irp_que ) )\r
-    {\r
-        LIST_ENTRY* p_list_entry;\r
-        IRP* p_irp;\r
-\r
-        // get IRP\r
-        p_list_entry = RemoveHeadList( &p_cep->irp_que );\r
-        p_irp = (PIRP)CONTAINING_RECORD( p_list_entry, IRP, Tail.Overlay.ListEntry );\r
-\r
-        // complete GetConnectionReq IRP\r
-#pragma warning(push, 3)\r
-        IoSetCancelRoutine( p_irp, NULL );\r
-#pragma warning(pop)\r
-\r
-        p_irp->IoStatus.Information = 0;\r
-        p_irp->IoStatus.Status = STATUS_CANCELLED;\r
-        IoCompleteRequest( p_irp, IO_NETWORK_INCREMENT );\r
-    }\r
-\r
        __unbind_cep( p_cep );\r
        ref_cnt = __cleanup_cep( p_cep );\r
     if( reusable )\r
@@ -5103,55 +5043,6 @@ out:
 }\r
 \r
 \r
-ib_api_status_t\r
-kal_cep_config_pre_rep_copy_cid(\r
-       IN                              ib_al_handle_t                          h_al,\r
-       IN                              net32_t                                         cid,\r
-       IN                              al_pfn_cep_cb_t                         pfn_cb,\r
-       IN                              void*                                           context,\r
-       IN                              ib_pfn_destroy_cb_t                     pfn_destroy_cb,\r
-       IN              const   iba_cm_rep* const                       p_cm_rep,\r
-       IN                              uint8_t                                         rnr_nak_timeout,\r
-       IN      OUT                     net32_t* const                          p_cid,\r
-               OUT                     ib_qp_mod_t* const                      p_init )\r
-{\r
-       kcep_t                          *p_cep;\r
-       KLOCK_QUEUE_HANDLE      hdl;\r
-       ib_api_status_t         status;\r
-\r
-       CL_ASSERT( h_al );\r
-       CL_ASSERT( p_cm_rep );\r
-       CL_ASSERT( p_init );\r
-\r
-       KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl );\r
-       if (*p_cid != AL_INVALID_CID)\r
-       {\r
-               status = IB_RESOURCE_BUSY;\r
-               goto out;\r
-       }\r
-\r
-       p_cep = __lookup_cep( h_al, cid );\r
-       if (!p_cep )\r
-       {\r
-               status = IB_INVALID_HANDLE;\r
-               goto out;\r
-       }\r
-\r
-       status = __al_cep_pre_rep( p_cep, p_cm_rep, rnr_nak_timeout, p_init );\r
-       if ( status == IB_SUCCESS )\r
-       {\r
-               p_cep->pfn_cb = pfn_cb;\r
-               p_cep->context = context;\r
-               p_cep->pfn_destroy_cb = pfn_destroy_cb;\r
-               *p_cid = cid;\r
-       }\r
-\r
-out:\r
-       KeReleaseInStackQueuedSpinLock( &hdl );\r
-       return status;\r
-}\r
-\r
-\r
 ib_api_status_t\r
 kal_cep_pre_rep(\r
        IN                              ib_al_handle_t                          h_al,\r
@@ -6700,60 +6591,6 @@ __cep_cancel_ndi_irp(
        AL_EXIT( AL_DBG_CM );\r
 }\r
 \r
-NTSTATUS\r
-al_cep_get_cid(\r
-       IN              ib_al_handle_t                                          h_al,\r
-       IN              net32_t                 const                           cid,\r
-       IN              PIRP                                                            p_irp\r
-       )\r
-{\r
-       kcep_t *p_cep;\r
-       NTSTATUS nt_status;\r
-       KLOCK_QUEUE_HANDLE hdl;\r
-       ib_mad_element_t* p_mad = NULL;\r
-\r
-       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_CM, ("[ CID = %d\n", cid) );\r
-       KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl );\r
-\r
-       p_cep = __lookup_cep( h_al, cid );\r
-       if( !p_cep )\r
-       {\r
-               p_irp->IoStatus.Information = 0;\r
-               p_irp->IoStatus.Status = STATUS_INVALID_PARAMETER;\r
-               IoCompleteRequest( p_irp, IO_NETWORK_INCREMENT );\r
-               nt_status = STATUS_EVENT_DONE;\r
-               goto exit;\r
-       }\r
-\r
-       if( !p_cep->p_mad_head )\r
-       { /* no pending MADs - queue the IRP */ \r
-               p_cep->signalled = FALSE;\r
-               InsertTailList( &p_cep->irp_que, &p_irp->Tail.Overlay.ListEntry );\r
-               p_irp->Tail.Overlay.DriverContext[0] = (void*)(size_t)cid;\r
-               p_irp->Tail.Overlay.DriverContext[1] = (void*)h_al;\r
-#pragma warning(push, 3)\r
-               IoSetCancelRoutine( p_irp, __cep_cancel_ndi_irp );\r
-#pragma warning(pop)\r
-               IoMarkIrpPending( p_irp );\r
-               nt_status = STATUS_PENDING;\r
-               goto exit;\r
-       }\r
-\r
-       /* Set the MAD. */\r
-       p_mad = p_cep->p_mad_head;\r
-       p_cep->p_mad_head = p_mad->p_next;\r
-       p_mad->p_next = NULL;\r
-\r
-       /* complete the IRP */\r
-       __complete_ndi_irp( p_irp, p_mad );\r
-       nt_status = STATUS_EVENT_DONE;\r
-       \r
-exit:\r
-       KeReleaseInStackQueuedSpinLock( &hdl );\r
-       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_CM, ("] returned %08x\n", nt_status) );\r
-       return nt_status;\r
-}\r
-\r
 \r
 NTSTATUS\r
 al_cep_get_pdata(\r
@@ -6801,3 +6638,57 @@ al_cep_get_pdata(
        AL_EXIT( AL_DBG_CM );\r
        return STATUS_SUCCESS;\r
 }\r
+\r
+\r
+/*\r
+ * This function is designed to support moving the NetorkDirect IRP queue to the CEP\r
+ * without performing major surgery on the CEP manager.\r
+ *\r
+ * It retrieves the context associated with a CEP, using the pfn_addref function\r
+ * to prevent the context from being destroyed after it is returned.\r
+ *\r
+ * It returns NULL if there is no context, requiring contexts to be pointers.\r
+ */\r
+void*\r
+kal_cep_get_context(\r
+       IN                              ib_al_handle_t                          h_al,\r
+       IN                              net32_t                                         cid,\r
+       IN                              al_pfn_cep_cb_t                         pfn_cb,\r
+       IN                              ib_pfn_destroy_cb_t                     pfn_addref )\r
+{\r
+       kcep_t                          *p_cep;\r
+       void*                           context = NULL;\r
+       KLOCK_QUEUE_HANDLE      hdl;\r
+\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_CM, ("[ CID = %d\n", cid) );\r
+\r
+       CL_ASSERT( h_al );\r
+       CL_ASSERT( pfn_addref );\r
+\r
+       KeAcquireInStackQueuedSpinLock( &gp_cep_mgr->lock, &hdl );\r
+       p_cep = __lookup_cep( h_al, cid );\r
+       if( !p_cep )\r
+       {\r
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
+                       ("CEP not found for cid %d, h_al %p\n", cid, h_al ));\r
+               goto out;\r
+       }\r
+\r
+       if( p_cep->pfn_cb != pfn_cb )\r
+       {\r
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                       ("CEP callback mismatch for cid %d, h_al %p\n", cid, h_al ));\r
+               goto out;\r
+       }\r
+\r
+       context = p_cep->context;\r
+       if( context != NULL )\r
+       {\r
+               pfn_addref( context );\r
+       }\r
+\r
+out:\r
+       KeReleaseInStackQueuedSpinLock( &hdl );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_CM, ("] returning %p\n", context) );\r
+       return context;\r
+}\r
index 4638e07a7ef65e618c7178c78aacf424f7515dc5..8f3c95c170201d507ee19c434a7b61a2334654c9 100644 (file)
@@ -81,7 +81,7 @@ __ndi_send_req(
 \r
 NTSTATUS\r
 __ndi_send_rep(\r
-       IN              ib_qp_handle_t                                          h_qp,\r
+       IN              nd_csq_t                                                        *p_csq,\r
        IN              PIRP                                                            p_irp\r
        );\r
 \r
@@ -90,11 +90,18 @@ __ndi_send_dreq(
        IN              IRP*                                                            p_irp\r
        );\r
 \r
+NTSTATUS\r
+__ndi_get_req(\r
+       IN              nd_csq_t                                                        *p_csq,\r
+       IN              IRP*                                                            p_irp\r
+       );\r
+\r
 static void\r
 __ndi_queue_drep(\r
        IN                              IRP                                                     *p_irp\r
        );\r
 \r
+\r
 /*******************************************************************\r
  *\r
  * Helpers\r
@@ -123,12 +130,12 @@ static char * State2String(ndi_cm_state_t state)
 \r
 static inline void\r
 __ndi_complete_irp(\r
-       IN      ib_qp_handle_t                                                  h_qp,\r
+       IN      nd_csq_t*                                                               p_csq,\r
        IN      PIRP                                                                    p_irp,\r
        IN      NTSTATUS                                                                status\r
        )\r
 {\r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("[ CID = %d\n", p_csq->cid) );\r
 \r
        CL_ASSERT( p_irp );\r
        CL_ASSERT( p_irp->Tail.Overlay.DriverContext[1] == NULL );\r
@@ -144,7 +151,7 @@ __ndi_complete_irp(
                p_irp->IoStatus.Information = 0;\r
                IoCompleteRequest( p_irp, 0 );\r
        }\r
-       deref_al_obj( &h_qp->obj ); /* Release IRP reference */\r
+       nd_csq_release( p_csq ); /* Release IRP reference */\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
@@ -159,23 +166,28 @@ __ndi_complete_irp(
  */\r
 static void\r
 __cep_timewait_qp(\r
-       IN              const   ib_qp_handle_t                          h_qp )\r
+       IN                              nd_csq_t                                        *p_csq )\r
 {\r
        uint64_t                        timewait = 0;\r
+       ib_qp_handle_t          h_qp;\r
        ib_qp_mod_t                     qp_mod;\r
        ib_api_status_t         status;\r
 \r
        AL_ENTER( AL_DBG_CM );\r
 \r
-       CL_ASSERT( h_qp );\r
+       CL_ASSERT( p_csq != NULL );\r
 \r
        /*\r
         * The CM should have set the proper timewait time-out value.  Reset\r
         * the QP and let it enter the timewait state.\r
         */\r
-       if( al_cep_get_timewait( h_qp->obj.h_al,\r
-               ((al_conn_qp_t*)h_qp)->cid, &timewait ) == IB_SUCCESS )\r
+       if( al_cep_get_timewait( p_csq->h_al, p_csq->cid, &timewait ) == IB_SUCCESS )\r
        {\r
+               h_qp = CONTAINING_RECORD(\r
+                       al_hdl_ref( p_csq->h_al, p_csq->h_qp, AL_OBJ_TYPE_H_QP ),\r
+                       ib_qp_t,\r
+                       obj );\r
+\r
                /* Special checks on the QP state for error handling - see above. */\r
                if( !h_qp || !AL_OBJ_IS_TYPE( h_qp, AL_OBJ_TYPE_H_QP ) ||\r
                        ( (h_qp->obj.state != CL_INITIALIZED) && \r
@@ -192,16 +204,16 @@ __cep_timewait_qp(
                status = h_qp->pfn_modify_qp( h_qp, &qp_mod, NULL );\r
                if( status != IB_SUCCESS )\r
                {\r
-                       AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                       AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
                                ("pfn_modify_qp to IB_QPS_ERROR returned %s\n",\r
                                ib_get_err_str( status )) );\r
-                       return;\r
                }\r
-\r
-#ifdef CL_KERNEL\r
-               /* Store the timestamp after which the QP exits timewait. */\r
-               h_qp->timewait = cl_get_time_stamp() + timewait;\r
-#endif /* CL_KERNEL */\r
+               else\r
+               {\r
+                       /* Store the timestamp after which the QP exits timewait. */\r
+                       h_qp->timewait = cl_get_time_stamp() + timewait;\r
+               }\r
+               deref_al_obj( &h_qp->obj );\r
        }\r
 \r
        AL_EXIT( AL_DBG_CM );\r
@@ -209,22 +221,39 @@ __cep_timewait_qp(
 \r
 static ib_api_status_t\r
 __ndi_qp2rts(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              nd_csq_t*                                                       p_csq,\r
        IN              PIRP                                                            p_irp\r
        )\r
 {\r
        ib_api_status_t status;\r
+       ib_qp_handle_t h_qp;\r
        ib_qp_mod_t qp_mod;\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("[ CID = %d\n", p_csq->cid) );\r
+\r
+       h_qp = CONTAINING_RECORD(\r
+               al_hdl_ref( p_csq->h_al, p_csq->h_qp, AL_OBJ_TYPE_H_QP ),\r
+               ib_qp_t,\r
+               obj );\r
+       if( h_qp == NULL )\r
+       {\r
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                       ("Bad QP %I64d\n", p_csq->h_qp) );\r
+               status = IB_INVALID_HANDLE;\r
+               goto err;\r
+       }\r
+\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("QP %p state %d\n", h_qp, h_qp->state) );\r
 \r
        /* fill required qp attributes */\r
-       status = al_cep_get_rtr_attr( qp_get_al( h_qp ), \r
-               ((al_conn_qp_t*)h_qp)->cid, &qp_mod );\r
+       status = al_cep_get_rtr_attr( p_csq->h_al, p_csq->cid, &qp_mod );\r
        if ( status != IB_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("al_cep_get_rtr_attr returned %s\n", ib_get_err_str( status )) );\r
+                       ("al_cep_get_rtr_attr for CID %d returned %s\n",\r
+                       p_csq->cid, ib_get_err_str( status )) );\r
                goto exit;\r
        }\r
 \r
@@ -234,17 +263,18 @@ __ndi_qp2rts(
        if ( status != IB_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("ndi_modify_qp to RTR returned %s.\n", ib_get_err_str(status) ) );\r
+                       ("ndi_modify_qp %p from %d to RTR returned %s.\n",\r
+                       h_qp, h_qp->state, ib_get_err_str(status) ) );\r
                goto exit;\r
        }\r
 \r
        /* fill required qp attributes */\r
-       status = al_cep_get_rts_attr( qp_get_al( h_qp ), \r
-               ((al_conn_qp_t*)h_qp)->cid, &qp_mod );\r
+       status = al_cep_get_rts_attr( p_csq->h_al, p_csq->cid, &qp_mod );\r
        if ( status != IB_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("al_cep_get_rts_attr returned %s\n", ib_get_err_str( status )) );\r
+                       ("al_cep_get_rts_attr for CID %d returned %s\n",\r
+                       p_csq->cid, ib_get_err_str( status )) );\r
                goto exit;\r
        }\r
 \r
@@ -254,10 +284,13 @@ __ndi_qp2rts(
        if ( status != IB_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("ndi_modify_qp to RTS returned %s.\n", ib_get_err_str(status) ) );\r
+                       ("ndi_modify_qp %p from %d to RTS returned %s.\n",\r
+                       h_qp, h_qp->state, ib_get_err_str(status) ) );\r
        }\r
 \r
 exit:\r
+       deref_al_obj( &h_qp->obj );\r
+err:\r
        AL_EXIT( AL_DBG_NDI );\r
        return status;\r
 }\r
@@ -277,11 +310,15 @@ static NTSTATUS __ndi_insert_irp_ex(
        )\r
 {\r
        NTSTATUS status;\r
-       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)pCsq;\r
+       nd_csq_t *p_ndi_csq = CONTAINING_RECORD( pCsq, nd_csq_t, csq );\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("[ CID = %d\n", p_ndi_csq->cid) );\r
        switch( (ULONG_PTR)Context )\r
        {\r
+       case NDI_CM_LISTEN:\r
+               status = __ndi_get_req( p_ndi_csq, pIrp );\r
+               break;\r
+\r
        case NDI_CM_CONNECTING_QPR_SENT:\r
                status = __ndi_pr_query( pIrp );\r
                break;\r
@@ -290,24 +327,38 @@ static NTSTATUS __ndi_insert_irp_ex(
                status = __ndi_send_req( pIrp );\r
                break;\r
 \r
-       case NDI_CM_CONNECTING_REP_SENT:\r
-               status = __ndi_send_rep( p_ndi_csq->h_qp, pIrp );\r
-               break;\r
-\r
        case NDI_CM_DISCONNECTING:\r
                status = __ndi_send_dreq( pIrp );\r
                break;\r
 \r
+       case NDI_CM_CONNECTED_DREQ_RCVD:\r
+               if( p_ndi_csq->state == NDI_CM_LISTEN )\r
+               {\r
+                       AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_NDI,\r
+                               ("] Invalid state (%d).\n", p_ndi_csq->state) );\r
+                       return STATUS_INVALID_DEVICE_REQUEST;\r
+               }\r
+\r
+               /*\r
+                * Overwrite the context so that the state change\r
+                * below turns into a noop.\r
+                */\r
+               Context = (VOID*)(ULONG_PTR)p_ndi_csq->state;\r
+               status = STATUS_PENDING;\r
+               break;\r
+\r
        default:\r
                status = STATUS_INVALID_DEVICE_REQUEST;\r
                ASSERT( FALSE );\r
        }\r
 \r
-       if( status == STATUS_SUCCESS )\r
+       ASSERT( status == STATUS_PENDING || !NT_SUCCESS( status ) );\r
+       if( NT_SUCCESS( status ) )\r
        {\r
+               AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("] Queueing IRP\n") );\r
                p_ndi_csq->state = (ndi_cm_state_t)(ULONG_PTR)Context;\r
                InsertTailList( &p_ndi_csq->queue, &pIrp->Tail.Overlay.ListEntry );\r
-               ref_al_obj( &p_ndi_csq->h_qp->obj ); /* Take IRP reference. */\r
+               nd_csq_ref( p_ndi_csq ); /* Take IRP reference. */\r
        }\r
        AL_EXIT( AL_DBG_NDI );\r
        return status;\r
@@ -334,7 +385,7 @@ static PIRP __ndi_peek_next_irp(
        PIRP nextIrp = NULL;\r
        PLIST_ENTRY nextEntry;\r
        PLIST_ENTRY listHead;\r
-       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;\r
+       nd_csq_t *p_ndi_csq = (nd_csq_t*)Csq;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
@@ -380,16 +431,12 @@ static PIRP __ndi_peek_next_irp(
 \r
 static VOID __ndi_acquire_lock(\r
        IN      PIO_CSQ                                                                 Csq,\r
-       OUT     PKIRQL                                                                  Irql\r
+       OUT     PKIRQL                                                                  pIrql\r
        )\r
 {\r
-       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;\r
-       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;\r
-       UNUSED_PARAM( Irql );\r
+       nd_csq_t *p_ndi_csq = (nd_csq_t*)Csq;\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
-       cl_spinlock_acquire( &h_qp->obj.lock );\r
-       AL_EXIT( AL_DBG_NDI );\r
+       KeAcquireSpinLock( &p_ndi_csq->lock, pIrql );\r
 }\r
 \r
 static VOID __ndi_release_lock(\r
@@ -397,13 +444,9 @@ static VOID __ndi_release_lock(
        IN      KIRQL                                                                   Irql\r
        )\r
 {\r
-       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;\r
-       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;\r
-       UNUSED_PARAM( Irql );\r
+       nd_csq_t *p_ndi_csq = (nd_csq_t*)Csq;\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
-       cl_spinlock_release( &h_qp->obj.lock );\r
-       AL_EXIT( AL_DBG_NDI );\r
+       KeReleaseSpinLock( &p_ndi_csq->lock, Irql );\r
 }\r
 \r
 static VOID __ndi_complete_cancelled_irp(\r
@@ -411,8 +454,7 @@ static VOID __ndi_complete_cancelled_irp(
        IN      PIRP                                                                    p_irp\r
        )\r
 {\r
-       ndi_qp_csq_t *p_ndi_csq = (ndi_qp_csq_t*)Csq;\r
-       ib_qp_handle_t h_qp = p_ndi_csq->h_qp;\r
+       nd_csq_t *p_ndi_csq = (nd_csq_t*)Csq;\r
        KIRQL irql;\r
        ib_query_handle_t h_query;\r
 \r
@@ -427,14 +469,11 @@ static VOID __ndi_complete_cancelled_irp(
                 * SA callback by the CSQ lock.\r
                 */\r
 #pragma warning( disable:4305 )\r
-               h_query = InterlockedExchangePointer( &h_qp->p_irp_queue->h_query, NULL );\r
+               h_query = InterlockedExchangePointer( &p_ndi_csq->h_query, NULL );\r
 #pragma warning( default:4305 )\r
                if( h_query != NULL )\r
                        al_cancel_sa_req( &h_query->sa_req );\r
 \r
-               /* Always try to destroy the CEP.  The CEP manager handles invalid CIDs. */\r
-               al_destroy_cep( qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
-\r
                if( p_ndi_csq->state != NDI_CM_INVALID )\r
                        p_ndi_csq->state = NDI_CM_IDLE;\r
 \r
@@ -443,7 +482,8 @@ static VOID __ndi_complete_cancelled_irp(
                __fallthrough;\r
 \r
        case UAL_NDI_NOTIFY_DREQ:\r
-               __ndi_complete_irp( h_qp, p_irp, STATUS_CANCELLED );\r
+       case UAL_NDI_GET_REQ_CM:\r
+               __ndi_complete_irp( p_ndi_csq, p_irp, STATUS_CANCELLED );\r
                break;\r
 \r
        case UAL_NDI_DREQ_CM:\r
@@ -457,138 +497,158 @@ static VOID __ndi_complete_cancelled_irp(
 \r
 \r
 NTSTATUS\r
-ndi_qp_init(\r
-       IN                              ib_qp_handle_t                          h_qp )\r
+nd_csq_init(\r
+       IN                              ib_al_handle_t                          h_al,\r
+       IN                              net32_t                                         cid,\r
+       IN                              uint64_t                                        h_qp,\r
+               OUT                     nd_csq_t                                        **pp_csq )\r
 {\r
-\r
+       nd_csq_t *p_nd_csq;\r
        NTSTATUS status;\r
+       ib_api_status_t ib_status;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       if ( h_qp->type != IB_QPT_RELIABLE_CONN )\r
-       {\r
-               AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                       ("Only RC QP type is supported \n"));\r
-               status = STATUS_SUCCESS;\r
-               goto exit;\r
-       }\r
-       \r
-       h_qp->p_irp_queue = (ndi_qp_csq_t*)cl_zalloc(sizeof(ndi_qp_csq_t));\r
-       if (!h_qp->p_irp_queue)\r
+       p_nd_csq = (nd_csq_t*)cl_zalloc( sizeof(*p_nd_csq) );\r
+       if( p_nd_csq == NULL )\r
        {\r
                status = STATUS_NO_MEMORY;\r
                goto exit;\r
        }\r
 \r
-       status = IoCsqInitializeEx( &h_qp->p_irp_queue->csq, \r
+       KeInitializeSpinLock( &p_nd_csq->lock );\r
+       InitializeListHead( &p_nd_csq->queue );\r
+       p_nd_csq->h_al = h_al;\r
+       p_nd_csq->h_qp = h_qp;\r
+       p_nd_csq->h_query = NULL;\r
+       p_nd_csq->state = NDI_CM_IDLE;\r
+       p_nd_csq->cid = cid;\r
+\r
+       status = IoCsqInitializeEx( &p_nd_csq->csq, \r
                __ndi_insert_irp_ex, __ndi_remove_irp,\r
                __ndi_peek_next_irp, __ndi_acquire_lock,\r
                __ndi_release_lock, __ndi_complete_cancelled_irp );\r
        if ( !NT_SUCCESS( status ) )\r
+       {\r
+               cl_free( p_nd_csq );\r
                goto exit;\r
+       }\r
 \r
-       InitializeListHead( &h_qp->p_irp_queue->queue );\r
-       h_qp->p_irp_queue->h_qp = h_qp;\r
-       h_qp->p_irp_queue->h_query = NULL;\r
-       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
+       /*\r
+        * One reference for the CEP, one for the caller (so that if the CEP\r
+        * gets destroyed we don't blow up.)\r
+        */\r
+       p_nd_csq->ref_cnt = 2;\r
+\r
+       ib_status = kal_cep_config(\r
+               h_al, cid, nd_cm_handler, p_nd_csq, nd_csq_release );\r
+\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               status = STATUS_UNSUCCESSFUL;\r
+               cl_free( p_nd_csq );\r
+               goto exit;\r
+       }\r
+\r
+       *pp_csq = p_nd_csq;\r
        status = STATUS_SUCCESS;\r
 \r
-AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-       ("Creating h_qp %#I64x, uhdl %#I64x \n", \r
-       (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl ) );\r
+       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
+               ("Creating CSQ %p, uhdl %#I64x \n", p_nd_csq, h_qp) );\r
 \r
 exit:\r
        AL_EXIT( AL_DBG_NDI );\r
        return status;\r
 }\r
 \r
-#pragma warning(disable:4706)\r
+\r
 void\r
-ndi_qp_destroy(\r
-       IN              ib_qp_handle_t                                  h_qp )\r
+ndi_cancel_cm_irps(\r
+       IN                              nd_csq_t                                        *p_nd_csq )\r
 {\r
-       KIRQL irql;\r
        PIRP Irp;\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("[ CSQ %p (CID = %d)\n", \r
+               p_nd_csq, p_nd_csq->cid ) );\r
 \r
-       if (h_qp->type == IB_QPT_RELIABLE_CONN && h_qp->p_irp_queue)\r
+       /* cancel pending IRPS for NDI type CQ */\r
+       AL_ENTER( AL_DBG_NDI );\r
+       for( Irp = IoCsqRemoveNextIrp( &p_nd_csq->csq, NULL );\r
+               Irp != NULL;\r
+               Irp = IoCsqRemoveNextIrp( &p_nd_csq->csq, NULL ) )\r
        {\r
-               AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                       ("Destroying h_qp %#I64x, uhdl %#I64x, cid %d\n", \r
-                       (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, ((al_conn_qp_t*)h_qp)->cid ) );\r
+               __ndi_complete_cancelled_irp( &p_nd_csq->csq, Irp );\r
+       }\r
+       for( Irp = IoCsqRemoveNextIrp( &p_nd_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_NOTIFY_DREQ );\r
+               Irp != NULL;\r
+               Irp = IoCsqRemoveNextIrp( &p_nd_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_NOTIFY_DREQ ) )\r
+       {\r
+               __ndi_complete_cancelled_irp( &p_nd_csq->csq, Irp );\r
+       }\r
 \r
-               /* Move the state before flushing, so that all new IRPs fail to queue. */\r
-               __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-               h_qp->p_irp_queue->state = NDI_CM_INVALID;\r
-               __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       AL_EXIT( AL_DBG_NDI );\r
+}\r
 \r
-               /* cancel pending IRPS for NDI type CQ */\r
-               AL_ENTER( AL_DBG_NDI );\r
-               while( Irp = IoCsqRemoveNextIrp( &h_qp->p_irp_queue->csq, NULL ) )\r
-               {\r
-                       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI, \r
-                               ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n", \r
-                               (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );\r
 \r
-                       __ndi_complete_cancelled_irp( &h_qp->p_irp_queue->csq, Irp );\r
-               }\r
-               while( Irp = IoCsqRemoveNextIrp(\r
-                       &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_NOTIFY_DREQ ) )\r
-               {\r
-                       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI, \r
-                               ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n", \r
-                               (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );\r
+void\r
+nd_csq_destroy(\r
+       IN                              nd_csq_t                                        *p_nd_csq )\r
+{\r
+       KIRQL irql;\r
 \r
-                       __ndi_complete_cancelled_irp( &h_qp->p_irp_queue->csq, Irp );\r
-               }\r
-               AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI, \r
-                       ("h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n", \r
-                       (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );\r
-       }\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("[ CSQ %p (CID = %d)\n", \r
+               p_nd_csq, p_nd_csq->cid ) );\r
+\r
+       /* Move the state before flushing, so that all new IRPs fail to queue. */\r
+       __ndi_acquire_lock( &p_nd_csq->csq, &irql );\r
+       p_nd_csq->state = NDI_CM_INVALID;\r
+       __ndi_release_lock( &p_nd_csq->csq, irql );\r
+\r
+       /* cancel pending IRPS */\r
+       ndi_cancel_cm_irps( p_nd_csq );\r
+\r
+       cl_free( p_nd_csq );\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
-#pragma warning(default:4706)\r
 \r
 \r
 void\r
-ndi_qp_free(\r
-       IN              ib_qp_handle_t                                  h_qp )\r
+nd_csq_ref( nd_csq_t* p_csq )\r
 {\r
-       AL_ENTER( AL_DBG_NDI );\r
+       InterlockedIncrement( &p_csq->ref_cnt );\r
+}\r
 \r
-       if (h_qp->type == IB_QPT_RELIABLE_CONN && h_qp->p_irp_queue)\r
+\r
+void\r
+nd_csq_release( nd_csq_t* p_csq )\r
+{\r
+       if( InterlockedDecrement( &p_csq->ref_cnt ) == 0 )\r
        {\r
-               /* free NDI context */\r
-               cl_free( h_qp->p_irp_queue );\r
-               h_qp->p_irp_queue = NULL;\r
+               nd_csq_destroy( p_csq );\r
        }\r
-\r
-       AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
 \r
 static inline void\r
-__ndi_complete_req_irp(\r
-       IN      ib_qp_handle_t                                                  h_qp,\r
-       IN      NTSTATUS                                                                code\r
-       )\r
+__ndi_timeout_req_irp(\r
+       __in nd_csq_t* p_csq )\r
 {\r
        PIRP Irp;\r
        KIRQL irql;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
-       Irp = IoCsqRemoveNextIrp( &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
-       if ( Irp )\r
+       Irp = IoCsqRemoveNextIrp( &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
+       if( Irp )\r
        {\r
-               __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-               if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-               __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
-               __ndi_complete_irp( h_qp, Irp, code );\r
+               __ndi_acquire_lock( &p_csq->csq, &irql );\r
+               if( p_csq->state != NDI_CM_INVALID )\r
+                       p_csq->state = NDI_CM_IDLE;\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
+               __ndi_complete_irp( p_csq, Irp, STATUS_TIMEOUT );\r
        }\r
-       al_destroy_cep( qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
@@ -600,38 +660,41 @@ __ndi_complete_req_irp(
 \r
 static void\r
 __ndi_notify_dreq(\r
-       IN                              ib_qp_handle_t const            h_qp )\r
+       __in nd_csq_t* p_csq )\r
 {\r
-       IRP *p_irp = IoCsqRemoveNextIrp(\r
-               &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_NOTIFY_DREQ );\r
-\r
-       if( p_irp )\r
+       IRP *p_irp;\r
+       do\r
        {\r
-               __ndi_complete_irp( h_qp, p_irp, STATUS_SUCCESS );\r
-       }\r
+               p_irp = IoCsqRemoveNextIrp(\r
+                       &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_NOTIFY_DREQ );\r
+\r
+               if( p_irp )\r
+               {\r
+                       __ndi_complete_irp( p_csq, p_irp, STATUS_SUCCESS );\r
+               }\r
+\r
+       } while ( p_irp );\r
 }\r
 \r
 \r
 static void\r
 __ndi_proc_dreq(\r
-       IN                              ib_qp_handle_t const            h_qp )\r
+       IN                              nd_csq_t                                        *p_csq)\r
 {\r
        IRP *p_irp;\r
        KIRQL irql;\r
-       ndi_cm_state_t old_state;\r
 \r
-       __ndi_notify_dreq( h_qp );\r
+       __ndi_notify_dreq( p_csq );\r
 \r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       old_state = h_qp->p_irp_queue->state;\r
-       if( old_state == NDI_CM_CONNECTED )\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       if( p_csq->state == NDI_CM_CONNECTED )\r
        {\r
-               h_qp->p_irp_queue->state = NDI_CM_CONNECTED_DREQ_RCVD;\r
+               p_csq->state = NDI_CM_CONNECTED_DREQ_RCVD;\r
        }\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
        p_irp = IoCsqRemoveNextIrp(\r
-               &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_DREQ_CM );\r
+               &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_DREQ_CM );\r
        if( p_irp != NULL )\r
        {\r
                __ndi_queue_drep( p_irp );\r
@@ -645,7 +708,7 @@ __ndi_proc_dreq(
  */\r
 static void\r
 __ndi_proc_rej(\r
-       IN                              ib_qp_handle_t const            h_qp,\r
+       IN                              nd_csq_t*                                       p_csq,\r
        IN              const   mad_cm_rej_t* const                     p_rej )\r
 {\r
        KIRQL irql;\r
@@ -654,73 +717,135 @@ __ndi_proc_rej(
        AL_ENTER( AL_DBG_NDI );\r
 \r
        AL_PRINT(TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
-               ("p_rej %p, h_qp %#I64x, uhdl %#I64x, connect reject, reason=%hd\n", \r
-               p_rej, (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, cl_ntoh16(p_rej->reason) ) );\r
+               ("p_rej %p, CID=%d, uhdl %#I64x, connect reject, reason=%hd\n", \r
+               p_rej, p_csq->cid, p_csq->h_qp, cl_ntoh16(p_rej->reason) ) );\r
 \r
-       p_irp = IoCsqRemoveNextIrp( &h_qp->p_irp_queue->csq, NULL );\r
-       __ndi_notify_dreq( h_qp );\r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
+       p_irp = IoCsqRemoveNextIrp( &p_csq->csq, NULL );\r
+       __ndi_notify_dreq( p_csq );\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
        if( p_irp != NULL )\r
        {\r
                switch( cl_ioctl_ctl_code( p_irp ) )\r
                {\r
                case UAL_NDI_REQ_CM:\r
-                       if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                               h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-                       if( p_rej->reason == IB_REJ_TIMEOUT )\r
-                               __ndi_complete_irp( h_qp, p_irp, STATUS_TIMEOUT );\r
+                       if( p_csq->state != NDI_CM_INVALID )\r
+                               p_csq->state = NDI_CM_IDLE;\r
+                       if( p_rej->reason == IB_REJ_USER_DEFINED )\r
+                               __ndi_complete_irp( p_csq, p_irp, STATUS_CONNECTION_REFUSED );\r
                        else\r
-                               __ndi_complete_irp( h_qp, p_irp, STATUS_CONNECTION_REFUSED );\r
+                               __ndi_complete_irp( p_csq, p_irp, STATUS_TIMEOUT );\r
 \r
-                       al_destroy_cep(\r
-                               qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
+                       /* We leave the CEP active so that the private data can be retrieved. */\r
                        break;\r
 \r
                case UAL_NDI_DREQ_CM:\r
                        __ndi_queue_drep( p_irp );\r
                        break;\r
+\r
+               case UAL_NDI_NOTIFY_DREQ:\r
+                       __ndi_complete_irp( p_csq, p_irp, STATUS_CONNECTION_ABORTED );\r
+                       break;\r
+\r
+               default:\r
+                       ASSERT( cl_ioctl_ctl_code( p_irp ) == UAL_NDI_REQ_CM ||\r
+                               cl_ioctl_ctl_code( p_irp ) == UAL_NDI_DREQ_CM ||\r
+                               cl_ioctl_ctl_code( p_irp ) == UAL_NDI_NOTIFY_DREQ );\r
                }\r
        }\r
-       else if( h_qp->p_irp_queue->state == NDI_CM_CONNECTED )\r
+       else if( p_csq->state == NDI_CM_CONNECTED || p_csq->state == NDI_CM_CONNECTING_REQ_RCVD )\r
        {\r
-               if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                       h_qp->p_irp_queue->state = NDI_CM_CONNECTED_DREQ_RCVD;\r
+               p_csq->state = NDI_CM_CONNECTED_DREQ_RCVD;\r
        }\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
 \r
+static void\r
+__ndi_proc_req(\r
+       IN                              nd_csq_t*                                       p_csq,\r
+       IN                              net32_t                                         new_cid,\r
+       IN                              ib_mad_element_t                        *p_mad )\r
+{\r
+       IRP* p_irp;\r
+       KIRQL irql;\r
+       NTSTATUS status;\r
+       nd_csq_t* p_new_csq;\r
+\r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,("CID = %d\n", p_csq->cid));\r
+\r
+       status = nd_csq_init( p_csq->h_al, new_cid, 0, &p_new_csq );\r
+       if( status != STATUS_SUCCESS )\r
+       {\r
+               // Ignore the request.\r
+               kal_cep_destroy( p_csq->h_al, new_cid, STATUS_NO_MORE_ENTRIES );\r
+               ib_put_mad( p_mad );\r
+               return;\r
+       }\r
+\r
+       __ndi_acquire_lock( &p_new_csq->csq, &irql );\r
+       p_new_csq->state = NDI_CM_CONNECTING_REQ_RCVD;\r
+       __ndi_release_lock( &p_new_csq->csq, irql );\r
+       nd_csq_release( p_new_csq );\r
+\r
+       p_irp = IoCsqRemoveNextIrp( &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_GET_REQ_CM );\r
+       if( p_irp == NULL )\r
+       {\r
+               p_mad->send_context1 = (VOID*)(ULONG_PTR)new_cid;\r
+               __ndi_acquire_lock( &p_csq->csq, &irql );\r
+               if( p_csq->p_mad_head == NULL )\r
+               {\r
+                       p_csq->p_mad_head = p_mad;\r
+               }\r
+               else\r
+               {\r
+                       p_csq->p_mad_tail->p_next = p_mad;\r
+               }\r
+               p_csq->p_mad_tail = p_mad;\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
+       }\r
+       else\r
+       {\r
+               *(net32_t*)cl_ioctl_out_buf( p_irp ) = new_cid;\r
+               __ndi_complete_irp( p_csq, p_irp, STATUS_SUCCESS );\r
+               ib_put_mad( p_mad );\r
+       }\r
+\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return;\r
+}\r
+\r
+\r
 static void\r
 __ndi_proc_rep(\r
-       IN                              ib_qp_handle_t const            h_qp,\r
-       IN                              net32_t                                         cid )\r
+       IN                              nd_csq_t*                                       p_csq )\r
 {\r
-       ndi_qp_csq_t *p_ndi_csq = h_qp->p_irp_queue;\r
        IRP* p_irp;\r
        KIRQL irql;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,("h_qp = 0x%p\n", h_qp));\r
+       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI ,("CID = %d\n", p_csq->cid));\r
 \r
-       p_irp = IoCsqRemoveNextIrp( &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
-       __ndi_acquire_lock( &p_ndi_csq->csq, &irql );\r
+       p_irp = IoCsqRemoveNextIrp( &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
        if( p_irp == NULL )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
-                       ("Not the expected state %s\n", State2String( p_ndi_csq->state )));\r
-               CL_ASSERT( IsListEmpty( &h_qp->p_irp_queue->queue ) );\r
-               al_cep_rej( qp_get_al( h_qp ), cid, IB_REJ_INVALID_COMM_INSTANCE, NULL, 0, NULL, 0 );\r
+                       ("Not the expected state %s\n", State2String( p_csq->state )));\r
+               CL_ASSERT( IsListEmpty( &p_csq->queue ) );\r
+               al_cep_rej( p_csq->h_al, p_csq->cid, IB_REJ_INVALID_COMM_INSTANCE, NULL, 0, NULL, 0 );\r
        }\r
        else\r
        {\r
-               p_ndi_csq->state = NDI_CM_CONNECTING_REP_RCVD;\r
+               p_csq->state = NDI_CM_CONNECTING_REP_RCVD;\r
 \r
-               __ndi_complete_irp( h_qp, p_irp, STATUS_SUCCESS );\r
+               __ndi_complete_irp( p_csq, p_irp, STATUS_SUCCESS );\r
        }\r
-       __ndi_release_lock( &p_ndi_csq->csq, irql );\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
        return;\r
@@ -732,7 +857,8 @@ __ndi_do_drep(
        IN                              DEVICE_OBJECT*                          p_dev_obj,\r
        IN                              PIRP                                            p_irp )\r
 {\r
-       ib_qp_handle_t h_qp = p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t* p_csq = p_irp->Tail.Overlay.DriverContext[0];\r
+       ib_qp_handle_t h_qp;\r
        ib_qp_mod_t qp_mod;\r
        ib_api_status_t status;\r
        uint64_t timewait_us;\r
@@ -746,11 +872,8 @@ __ndi_do_drep(
        CL_ASSERT( p_irp->Tail.Overlay.DriverContext[1] );\r
        IoFreeWorkItem( p_irp->Tail.Overlay.DriverContext[1] );\r
        p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-       deref_al_obj( &h_qp->obj ); /* Release work item reference. */\r
-\r
-       status = al_cep_get_timewait( qp_get_al( h_qp ), \r
-               ((al_conn_qp_t*)h_qp)->cid, &timewait_us );\r
 \r
+       status = al_cep_get_timewait( p_csq->h_al, p_csq->cid, &timewait_us );\r
        if (status != IB_SUCCESS)\r
        {\r
                nt_status = STATUS_CONNECTION_INVALID;\r
@@ -758,31 +881,44 @@ __ndi_do_drep(
        }\r
 \r
        /* Store the timestamp after which the QP exits timewait. */\r
-       h_qp->timewait = cl_get_time_stamp() + timewait_us;\r
+       h_qp = CONTAINING_RECORD(\r
+               al_hdl_ref( p_csq->h_al, p_csq->h_qp, AL_OBJ_TYPE_H_QP ),\r
+               ib_qp_t,\r
+               obj );\r
+       if( h_qp != NULL )\r
+       {\r
+               h_qp->timewait = cl_get_time_stamp() + timewait_us;\r
+       }\r
 \r
-       al_destroy_cep( qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
+       /* Send the DREP. */\r
+       al_cep_drep( p_csq->h_al, p_csq->cid, NULL, 0 );\r
 \r
        /* bring QP to error state */\r
-       cl_memclr( &qp_mod, sizeof(qp_mod) );\r
-       qp_mod.req_state = IB_QPS_ERROR;\r
-       \r
-       status = ndi_modify_qp( h_qp, &qp_mod, \r
-               cl_ioctl_out_size( p_irp ), cl_ioctl_out_buf( p_irp ) );\r
-       if ( status != IB_SUCCESS )\r
+       if( h_qp != NULL )\r
        {\r
-               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("ndi_modify_qp to ERROR returned %s.\n", ib_get_err_str(status) ) );\r
+               cl_memclr( &qp_mod, sizeof(qp_mod) );\r
+               qp_mod.req_state = IB_QPS_ERROR;\r
+               \r
+               status = ndi_modify_qp( h_qp, &qp_mod, \r
+                       cl_ioctl_out_size( p_irp ), cl_ioctl_out_buf( p_irp ) );\r
+               if ( status != IB_SUCCESS )\r
+               {\r
+                       AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                               ("ndi_modify_qp to ERROR returned %s.\n", ib_get_err_str(status) ) );\r
+               }\r
+               deref_al_obj( &h_qp->obj );\r
        }\r
 \r
        nt_status = ib_to_ntstatus( status );\r
 \r
 exit:\r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-               h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       if( p_csq->state != NDI_CM_INVALID )\r
+               p_csq->state = NDI_CM_IDLE;\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
-       __ndi_complete_irp( h_qp, p_irp, nt_status );\r
+       __ndi_complete_irp( p_csq, p_irp, nt_status );\r
+       nd_csq_release( p_csq ); /* Release work item reference. */\r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
@@ -799,16 +935,17 @@ __ndi_queue_drep(
 \r
 static void\r
 __ndi_proc_drep(\r
-       IN                              ib_qp_handle_t const            h_qp )\r
+       IN                              nd_csq_t*                                       p_csq )\r
 {\r
        IRP* p_irp;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
        p_irp = IoCsqRemoveNextIrp(\r
-               &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_DREQ_CM );\r
+               &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_DREQ_CM );\r
        if( p_irp != NULL )\r
        {\r
+               CL_ASSERT( p_irp->Tail.Overlay.DriverContext[0] == p_csq );\r
                __ndi_queue_drep( p_irp );\r
        }\r
 \r
@@ -816,8 +953,8 @@ __ndi_proc_drep(
 }\r
 \r
 \r
-static void\r
-__ndi_cm_handler(\r
+void\r
+nd_cm_handler(\r
        IN              const   ib_al_handle_t                          h_al,\r
        IN              const   net32_t                                         cid )\r
 {\r
@@ -829,8 +966,11 @@ __ndi_cm_handler(
 \r
        while( al_cep_poll( h_al, cid, &context, &new_cid, &p_mad_el ) == IB_SUCCESS )\r
        {\r
-               ib_mad_t*p_mad = ib_get_mad_buf( p_mad_el );\r
-               ib_qp_handle_t h_qp = (ib_qp_handle_t)context;\r
+               ib_mad_t* p_mad = ib_get_mad_buf( p_mad_el );\r
+               nd_csq_t* p_csq = (nd_csq_t*)context;\r
+\r
+               CL_ASSERT( p_csq != NULL );\r
+               CL_ASSERT( p_csq->cid == cid );\r
 \r
                if( p_mad_el->status != IB_SUCCESS )\r
                {\r
@@ -838,28 +978,28 @@ __ndi_cm_handler(
                        {\r
                        case CM_REQ_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("REQ timeouted for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               __ndi_complete_req_irp( h_qp, STATUS_TIMEOUT );\r
+                                       ("REQ timed out for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_timeout_req_irp( p_csq );\r
                                break;\r
 \r
                        case CM_REP_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("REP timeouted for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
+                                       ("REP timed out for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
                                break;\r
 \r
                        case CM_DREQ_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("DREQ timeouted for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               __ndi_proc_drep( h_qp );\r
+                                       ("DREQ timed out for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_drep( p_csq );\r
                                break;\r
 \r
                        default:\r
                                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
                                        ("Unhandled failed MAD attr ID %d for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       p_mad->attr_id, cid, h_al, h_qp, new_cid ) );\r
+                                       p_mad->attr_id, cid, h_al, p_csq, new_cid ) );\r
                                break;\r
                        }\r
                }\r
@@ -867,50 +1007,51 @@ __ndi_cm_handler(
                {\r
                        switch( p_mad->attr_id )\r
                        {\r
+                       case CM_REQ_ATTR_ID:\r
+                               AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
+                                       ("REQ received for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_req( p_csq, new_cid, p_mad_el );\r
+                               continue;\r
+\r
                        case CM_REP_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("REP received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               CL_ASSERT( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid || \r
-                                       ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID ||\r
-                                       ((al_conn_qp_t*)h_qp)->cid == AL_RESERVED_CID );\r
-                               __ndi_proc_rep( h_qp, cid );\r
+                                       ("REP received for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_rep( p_csq );\r
                                break;\r
                        \r
                        case CM_REJ_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("REJ received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               __ndi_proc_rej( h_qp, (mad_cm_rej_t*)p_mad );\r
+                                       ("REJ received for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_rej( p_csq, (mad_cm_rej_t*)p_mad );\r
                                break;\r
                \r
                        case CM_DREQ_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("DREQ received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               CL_ASSERT( ((al_conn_qp_t*)h_qp)->cid == (int32_t)cid || \r
-                               ((al_conn_qp_t*)h_qp)->cid == AL_INVALID_CID ||\r
-                               ((al_conn_qp_t*)h_qp)->cid == AL_RESERVED_CID );\r
-                               __ndi_proc_dreq( h_qp );\r
+                                       ("DREQ received for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_dreq( p_csq );\r
                                break;\r
 \r
                        case CM_DREP_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("DREP received for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       cid, h_al, h_qp, new_cid ) );\r
-                               __ndi_proc_drep( h_qp );\r
+                                       ("DREP received for CEP with cid %d, h_al %p, context %p.\n", \r
+                                       cid, h_al, p_csq ) );\r
+                               __ndi_proc_drep( p_csq );\r
                                break;\r
 \r
                        case CM_RTU_ATTR_ID:\r
                                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-                                       ("RTU received for CEP with cid %d, h_al %p, context %p, new_cid %d.\n",\r
-                                       cid, h_al, h_qp, new_cid ) );\r
+                                       ("RTU received for CEP with cid %d, h_al %p, context %p.\n",\r
+                                       cid, h_al, p_csq ) );\r
                                break;\r
 \r
                        default:\r
                                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
                                        ("Unhandled MAD attr ID %d for CEP with cid %d, h_al %p, context %p, new_cid %d .\n", \r
-                                       p_mad->attr_id, cid, h_al, h_qp, new_cid ) );\r
+                                       p_mad->attr_id, cid, h_al, p_csq, new_cid ) );\r
                        }\r
                }\r
 \r
@@ -922,24 +1063,26 @@ __ndi_cm_handler(
 \r
 static void\r
 __ndi_fill_cm_req(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              net32_t                                                         qpn,\r
        IN              ual_ndi_req_cm_ioctl_in_t                       *p_req,\r
        IN              ib_path_rec_t                                           *p_path_rec,\r
-               OUT     ib_cm_req_t                                                     *p_cm_req)\r
+               OUT     iba_cm_req                                                      *p_cm_req)\r
 {\r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       memset( p_cm_req, 0, sizeof(ib_cm_req_t) );\r
+       memset( p_cm_req, 0, sizeof(*p_cm_req) );\r
 \r
-       p_cm_req->svc_id = IB_REQ_CM_RDMA_SID_PREFIX | (p_req->prot << 16) | p_req->dst_port;\r
-       p_cm_req->max_cm_retries = g_max_cm_retries;\r
-       p_cm_req->p_primary_path = p_path_rec;  \r
-\r
-       p_cm_req->p_req_pdata = (uint8_t *)&p_req->pdata;\r
-       p_cm_req->req_length = sizeof(p_req->pdata);\r
+       p_cm_req->service_id = IB_REQ_CM_RDMA_SID_PREFIX | (p_req->prot << 16) | p_req->dst_port;\r
+       p_cm_req->p_primary_path = p_path_rec;\r
 \r
+       p_cm_req->qpn = qpn;\r
        p_cm_req->qp_type = IB_QPT_RELIABLE_CONN;\r
-       p_cm_req->h_qp = h_qp;\r
+       p_cm_req->starting_psn = qpn;\r
+\r
+       p_cm_req->p_pdata = (uint8_t *)&p_req->pdata;\r
+       p_cm_req->pdata_len = sizeof(p_req->pdata);\r
+\r
+       p_cm_req->max_cm_retries = g_max_cm_retries;\r
        p_cm_req->resp_res = p_req->resp_res;\r
        p_cm_req->init_depth = p_req->init_depth;\r
 \r
@@ -959,10 +1102,8 @@ __ndi_fill_cm_req(
        else if( p_cm_req->local_resp_timeout < CM_MIN_LOCAL_TIMEOUT )\r
                p_cm_req->local_resp_timeout = CM_MIN_LOCAL_TIMEOUT;\r
 \r
-       p_cm_req->rnr_nak_timeout = QP_ATTRIB_RNR_NAK_TIMEOUT;\r
        p_cm_req->rnr_retry_cnt = QP_ATTRIB_RNR_RETRY;\r
        p_cm_req->retry_cnt = g_qp_retries;\r
-       p_cm_req->p_alt_path = NULL;\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
@@ -974,58 +1115,47 @@ __ndi_send_req(
        )\r
 {\r
        ib_api_status_t status;\r
-       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t* p_csq = (nd_csq_t*)p_irp->Tail.Overlay.DriverContext[0];\r
        ib_path_rec_t *p_path_rec = p_irp->Tail.Overlay.DriverContext[1];\r
        ual_ndi_req_cm_ioctl_in_t *p_req = \r
                (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
        NTSTATUS nt_status;\r
-       ib_cm_req_t cm_req;\r
-       ib_qp_mod_t qp_mod;\r
-       al_conn_qp_t *p_qp;\r
+       ib_qp_handle_t h_qp;\r
+       iba_cm_req cm_req;\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("[ CID = %d, h_al %p, context %p\n",\r
+               p_req->cid, p_csq->h_al, p_csq) );\r
 \r
        p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
 \r
-       if( h_qp->p_irp_queue->state != NDI_CM_CONNECTING_QPR_SENT &&\r
-               h_qp->p_irp_queue->state != NDI_CM_IDLE )\r
+       if( p_csq->state != NDI_CM_CONNECTING_QPR_SENT &&\r
+               p_csq->state != NDI_CM_IDLE )\r
        {\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("Unexpected state: %d\n", h_qp->p_irp_queue->state) );\r
+                       ("Unexpected state: %d\n", p_csq->state) );\r
                return STATUS_CONNECTION_ACTIVE;\r
        }\r
 \r
-       /* Get a CEP and bind it to the QP. */\r
-       p_qp = (al_conn_qp_t*)h_qp;\r
-       cl_spinlock_acquire( &h_qp->obj.lock );\r
-       if( h_qp->obj.state != CL_DESTROYING && p_qp->cid == AL_INVALID_CID )\r
+       h_qp = CONTAINING_RECORD(\r
+               al_hdl_ref( p_csq->h_al, p_req->h_qp, AL_OBJ_TYPE_H_QP ),\r
+               ib_qp_t,\r
+               obj );\r
+       if( !h_qp )\r
        {\r
-               status = al_create_cep( qp_get_al( h_qp ), __ndi_cm_handler,\r
-                                                               &h_qp->obj, deref_al_obj, &p_qp->cid );\r
-       }\r
-       else \r
-       {\r
-               status = IB_RESOURCE_BUSY;\r
-       }\r
-       cl_spinlock_release( &h_qp->obj.lock );\r
-       if( status != IB_SUCCESS )\r
-       {\r
-               h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
+               /* The QP was valid when the IOCTL first came in... */\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("al_create_cep returned %s.\n", ib_get_err_str( status )) );\r
-               return ib_to_ntstatus( status );\r
+                       ("Invalid QP: %I64d\n", p_req->h_qp) );\r
+               return STATUS_CONNECTION_ABORTED;\r
        }\r
-       AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
-               ("Created Active CEP with cid %d, h_al %p, context %p\n",\r
-               p_qp->cid, qp_get_al( h_qp ), h_qp ) );\r
-\r
-       ref_al_obj( &h_qp->obj ); /* Take CEP reference. */\r
 \r
        /* Format ib_cm_req_t structure */\r
-       __ndi_fill_cm_req( h_qp, p_req, p_path_rec, &cm_req );\r
+       __ndi_fill_cm_req( h_qp->num, p_req, p_path_rec, &cm_req );\r
+       deref_al_obj( &h_qp->obj );\r
 \r
        /* prepare CEP for connection */\r
-       status = al_cep_pre_req( qp_get_al( h_qp ), p_qp->cid, &cm_req, &qp_mod );\r
+       status = kal_cep_pre_req(\r
+               p_csq->h_al, p_csq->cid, &cm_req, QP_ATTRIB_RNR_NAK_TIMEOUT, NULL );\r
        if( status != STATUS_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
@@ -1034,7 +1164,7 @@ __ndi_send_req(
        }\r
 \r
        /* send CM REQ */\r
-       status = al_cep_send_req( qp_get_al( h_qp ), p_qp->cid );\r
+       status = al_cep_send_req( p_csq->h_al, p_csq->cid );\r
        if( status != IB_SUCCESS )\r
        {\r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
@@ -1044,11 +1174,9 @@ __ndi_send_req(
 \r
        /* SUCCESS ! */\r
        AL_EXIT( AL_DBG_NDI );\r
-       return STATUS_SUCCESS;\r
+       return STATUS_PENDING;\r
 \r
 error:\r
-       al_destroy_cep( qp_get_al( h_qp ), &p_qp->cid, TRUE );\r
-       \r
        switch( status )\r
        {\r
        case IB_INVALID_HANDLE:\r
@@ -1063,7 +1191,7 @@ error:
                nt_status = ib_to_ntstatus( status );\r
        }\r
 \r
-       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
+       p_csq->state = NDI_CM_IDLE;\r
        AL_EXIT( AL_DBG_NDI );\r
        return nt_status;\r
 }\r
@@ -1076,7 +1204,7 @@ __ndi_pr_query_cb(
        cl_ioctl_handle_t p_irp;\r
        uint8_t pkt_life;\r
        ib_path_rec_t *p_path_rec;\r
-       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_query_rec->query_context;\r
+       nd_csq_t* p_csq = (nd_csq_t*)p_query_rec->query_context;\r
        NTSTATUS status;\r
        KIRQL irql;\r
 \r
@@ -1086,22 +1214,22 @@ __ndi_pr_query_cb(
                ("status is %d, count is %d, context %p\n", p_query_rec->status,\r
                p_query_rec->result_cnt, p_query_rec->query_context) );\r
 \r
-       p_irp = IoCsqRemoveNextIrp( &h_qp->p_irp_queue->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
+       p_irp = IoCsqRemoveNextIrp( &p_csq->csq, (VOID*)(ULONG_PTR)UAL_NDI_REQ_CM );\r
        if( p_irp == NULL )\r
        {\r
                goto exit;\r
        }\r
 \r
 #pragma warning( disable:4305 )\r
-       InterlockedExchangePointer( &h_qp->p_irp_queue->h_query, NULL );\r
+       InterlockedExchangePointer( &p_csq->h_query, NULL );\r
 #pragma warning( default:4305 )\r
 \r
        if( p_query_rec->status != IB_SUCCESS || p_query_rec->result_cnt == 0 )\r
        {\r
-               __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-               if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-               __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+               __ndi_acquire_lock( &p_csq->csq, &irql );\r
+               if( p_csq->state != NDI_CM_INVALID )\r
+                       p_csq->state = NDI_CM_IDLE;\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
                switch( p_query_rec->status )\r
                {\r
                case IB_TIMEOUT:\r
@@ -1129,7 +1257,7 @@ __ndi_pr_query_cb(
                        status = STATUS_HOST_UNREACHABLE;\r
                        break;\r
                }\r
-               __ndi_complete_irp( h_qp, p_irp, status );\r
+               __ndi_complete_irp( p_csq, p_irp, status );\r
                goto exit;\r
        }\r
 \r
@@ -1148,15 +1276,15 @@ __ndi_pr_query_cb(
        p_irp->Tail.Overlay.DriverContext[1] = p_path_rec;\r
 \r
        status = IoCsqInsertIrpEx(\r
-               &h_qp->p_irp_queue->csq,\r
+               &p_csq->csq,\r
                p_irp,\r
                NULL,\r
                (VOID*)(ULONG_PTR)NDI_CM_CONNECTING_REQ_SENT\r
                );\r
-       if( status != STATUS_SUCCESS )\r
+       if( !NT_SUCCESS( status ) )\r
        {\r
                p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-               __ndi_complete_irp( h_qp, p_irp, status );\r
+               __ndi_complete_irp( p_csq, p_irp, status );\r
        }\r
        else\r
        {\r
@@ -1164,14 +1292,14 @@ __ndi_pr_query_cb(
                 * Release the previous reference because IoCsqInsertIrpEx\r
                 * took a new one.\r
                 */\r
-               deref_al_obj( &h_qp->obj ); /* Release IRP reference. */\r
+               nd_csq_release( p_csq ); /* Release IRP reference. */\r
        }\r
 \r
 exit:\r
        if( p_query_rec->p_result_mad )\r
                ib_put_mad( p_query_rec->p_result_mad );\r
 \r
-       deref_al_obj( &h_qp->obj );     /* release path query reference */\r
+       nd_csq_release( p_csq );        /* release path query reference */\r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
@@ -1190,16 +1318,16 @@ __ndi_pr_query(
        ib_api_status_t status;\r
        ual_ndi_req_cm_ioctl_in_t *p_req = \r
                (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
-       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t* p_csq = (nd_csq_t*)p_irp->Tail.Overlay.DriverContext[0];\r
     ib_gid_pair_t gids;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       if ( h_qp->p_irp_queue->state != NDI_CM_IDLE )\r
+       if ( p_csq->state != NDI_CM_IDLE )\r
        {\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
-                       ("STATUS_CONNECTION_ACTIVE: h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",\r
-                       (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );\r
+                       ("STATUS_CONNECTION_ACTIVE: CID=%d, uhdl %#I64x, ref_cnt %d\n",\r
+                       p_csq->cid, p_csq->h_qp, p_csq->ref_cnt ) );\r
                return STATUS_CONNECTION_ACTIVE;\r
        }\r
 \r
@@ -1212,41 +1340,50 @@ __ndi_pr_query(
        query_req.timeout_ms = g_sa_timeout;\r
        query_req.retry_cnt = g_sa_retries;\r
        query_req.flags = 0;    /* IB_FLAGS_SYNC */\r
-       query_req.query_context = h_qp;\r
+       query_req.query_context = p_csq;\r
        query_req.pfn_query_cb = __ndi_pr_query_cb;\r
 \r
        AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
                ("Query for path from %I64x to %I64x\n",\r
                p_req->guid, ib_gid_get_guid( &p_req->path.dgid )) );\r
 \r
-       ref_al_obj( &h_qp->obj );               /* take path query reference */\r
-       status = ib_query( qp_get_al( h_qp ), &query_req, &h_qp->p_irp_queue->h_query );\r
+       nd_csq_ref( p_csq );            /* take path query reference */\r
+       status = ib_query( p_csq->h_al, &query_req, &p_csq->h_query );\r
        if( status != IB_SUCCESS )\r
        {\r
-               h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
+               p_csq->state = NDI_CM_IDLE;\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, ("ib_query failed (%d)\n", status) );\r
-               deref_al_obj( &h_qp->obj );     /* release path query reference */\r
+               nd_csq_release( p_csq );        /* release path query reference */\r
                return ib_to_ntstatus( status );\r
        }\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
-       return STATUS_SUCCESS;\r
+       return STATUS_PENDING;\r
 }\r
 \r
 \r
 NTSTATUS\r
 ndi_req_cm(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              ib_al_handle_t                                          h_al,\r
        IN              IRP                                                                     *p_irp\r
        )\r
 {\r
        NTSTATUS status;\r
+       nd_csq_t* p_csq;\r
        ual_ndi_req_cm_ioctl_in_t *p_req = \r
                (ual_ndi_req_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       p_irp->Tail.Overlay.DriverContext[0] = (ib_qp_t*)h_qp;\r
+       p_csq = kal_cep_get_context( h_al, p_req->cid, nd_cm_handler, nd_csq_ref );\r
+       if( p_csq == NULL )\r
+       {\r
+               status = nd_csq_init( h_al, p_req->cid, p_req->h_qp, &p_csq );\r
+               if( status != STATUS_SUCCESS )\r
+                       goto err;\r
+       }\r
+\r
+       p_irp->Tail.Overlay.DriverContext[0] = p_csq;\r
 \r
     if( p_req->path.dlid != 0 )\r
     {\r
@@ -1260,7 +1397,7 @@ ndi_req_cm(
 \r
            p_irp->Tail.Overlay.DriverContext[1] = &p_req->path;\r
            status = IoCsqInsertIrpEx(\r
-                   &h_qp->p_irp_queue->csq,\r
+                   &p_csq->csq,\r
                    p_irp,\r
                    NULL,\r
                    (VOID*)(ULONG_PTR)NDI_CM_CONNECTING_REQ_SENT\r
@@ -1269,15 +1406,15 @@ ndi_req_cm(
     else\r
     {\r
            status = IoCsqInsertIrpEx(\r
-                   &h_qp->p_irp_queue->csq,\r
+                   &p_csq->csq,\r
                    p_irp,\r
                    NULL,\r
                    (VOID*)(ULONG_PTR)NDI_CM_CONNECTING_QPR_SENT\r
                    );\r
     }\r
-       if( status == STATUS_SUCCESS )\r
-               status = STATUS_PENDING;\r
 \r
+       nd_csq_release( p_csq );\r
+err:\r
        AL_EXIT( AL_DBG_NDI );\r
        return status;\r
 }\r
@@ -1295,7 +1432,7 @@ __ndi_do_rtu(
        IN                              PIRP                                            p_irp )\r
 {\r
        ib_api_status_t status;\r
-       ib_qp_handle_t h_qp = p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t* p_csq = p_irp->Tail.Overlay.DriverContext[0];\r
        KIRQL irql;\r
        NTSTATUS nt_status;\r
 \r
@@ -1308,67 +1445,67 @@ __ndi_do_rtu(
        {\r
                IoFreeWorkItem( p_irp->Tail.Overlay.DriverContext[1] );\r
                p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-               deref_al_obj( &h_qp->obj ); /* Release work item reference. */\r
+               nd_csq_release( p_csq ); /* Release work item reference. */\r
        }\r
 \r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       if( h_qp->p_irp_queue->state != NDI_CM_CONNECTING_REP_RCVD )\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       if( p_csq->state != NDI_CM_CONNECTING_REP_RCVD )\r
        {\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
                nt_status = STATUS_CONNECTION_ABORTED;\r
                goto exit;\r
        }\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
        /* change the QP state to RTS */\r
-       status = __ndi_qp2rts( h_qp, p_irp );\r
-\r
+       status = __ndi_qp2rts( p_csq, p_irp );\r
        if ( status != IB_SUCCESS )\r
        {\r
                goto err;\r
        }\r
        \r
        /* send RTU */\r
-       status = al_cep_rtu( qp_get_al( h_qp ), ((al_conn_qp_t*)h_qp)->cid, NULL, 0 );\r
+       status = al_cep_rtu( p_csq->h_al, p_csq->cid, NULL, 0 );\r
        if( status != IB_SUCCESS )\r
        {\r
 err:\r
-               /* Reject and abort the connection. */\r
-               al_cep_rej(\r
-                       qp_get_al( h_qp ), ((al_conn_qp_t*)h_qp)->cid, \r
-                       IB_REJ_INSUF_QP, NULL, 0, NULL, 0 );\r
-\r
-               __cep_timewait_qp( h_qp );\r
+               /*\r
+                * Reject the connection.  Note that we don't free the CEP since the\r
+                * usermode INDConnector object references it, and the CEP will be\r
+                * freed when that object is freed.\r
+                */\r
+               al_cep_rej( p_csq->h_al, p_csq->cid, IB_REJ_INSUF_QP, NULL, 0, NULL, 0 );\r
 \r
-               al_destroy_cep( qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
+               __cep_timewait_qp( p_csq );\r
 \r
                AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
                        ("al_cep_rtu returned %s.\n", ib_get_err_str( status )) );\r
 \r
-               __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-               if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-               __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+               __ndi_acquire_lock( &p_csq->csq, &irql );\r
+               if( p_csq->state != NDI_CM_INVALID )\r
+                       p_csq->state = NDI_CM_IDLE;\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
 \r
                nt_status = STATUS_CONNECTION_ABORTED;\r
                goto exit;\r
        }\r
 \r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       if( h_qp->p_irp_queue->state == NDI_CM_CONNECTING_REP_RCVD )\r
-               h_qp->p_irp_queue->state = NDI_CM_CONNECTED;\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       if( p_csq->state == NDI_CM_CONNECTING_REP_RCVD )\r
+               p_csq->state = NDI_CM_CONNECTED;\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
        nt_status = STATUS_SUCCESS;\r
 \r
 exit:\r
-       __ndi_complete_irp( h_qp, p_irp, nt_status );\r
+       __ndi_complete_irp( p_csq, p_irp, nt_status );\r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
 \r
 cl_status_t\r
 ndi_rtu_cm(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              nd_csq_t                                                        *p_csq,\r
        IN              PIRP                                                            p_irp\r
        )\r
 {\r
@@ -1376,16 +1513,16 @@ ndi_rtu_cm(
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       p_irp->Tail.Overlay.DriverContext[0] = h_qp;\r
+       p_irp->Tail.Overlay.DriverContext[0] = p_csq;\r
+       nd_csq_ref( p_csq ); /* Take IRP reference. */\r
        p_io_stack = IoGetCurrentIrpStackLocation( p_irp );\r
        p_irp->Tail.Overlay.DriverContext[1] = IoAllocateWorkItem( p_io_stack->DeviceObject );\r
-       ref_al_obj( &h_qp->obj ); /* Take IRP reference. */\r
 \r
        IoMarkIrpPending( p_irp );\r
        if ( p_irp->Tail.Overlay.DriverContext[1] )\r
        { /* asyncronous performing */\r
                /* take a ref to prevent QP destroy before calling work item */\r
-               ref_al_obj( &h_qp->obj ); /* Take work item reference. */\r
+               nd_csq_ref( p_csq ); /* Take work item reference. */\r
                IoQueueWorkItem( p_irp->Tail.Overlay.DriverContext[1],\r
                        __ndi_do_rtu, DelayedWorkQueue, p_irp );\r
        }\r
@@ -1410,73 +1547,75 @@ __ndi_do_rep(
        IN                              DEVICE_OBJECT*                          p_dev_obj,\r
        IN              PIRP                                                            p_irp )\r
 {\r
-       ib_qp_handle_t h_qp = p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t* p_csq = p_irp->Tail.Overlay.DriverContext[0];\r
        ib_api_status_t status;\r
-       ual_ndi_rep_cm_ioctl_in_t *p_rep;\r
        KIRQL irql;\r
        NTSTATUS nt_status;\r
 \r
        UNUSED_PARAM(p_dev_obj);\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("[ CID = %d\n", p_csq->cid) );\r
 \r
        /* free the work item if any */\r
        CL_ASSERT( p_irp->Tail.Overlay.DriverContext[1] != NULL );\r
        IoFreeWorkItem( p_irp->Tail.Overlay.DriverContext[1] );\r
        p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-       deref_al_obj( &h_qp->obj ); /* Release work item reference. */\r
-\r
-       p_rep = (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
 \r
        /* change the QP state to RTS */\r
-       status = __ndi_qp2rts( h_qp, p_irp );\r
+       status = __ndi_qp2rts( p_csq, p_irp );\r
        if ( status != IB_SUCCESS )\r
        {\r
                goto err;\r
        }\r
        \r
        /* send REP */\r
-       status = al_cep_send_rep ( qp_get_al( h_qp ), p_rep->cid );\r
+       status = al_cep_send_rep ( p_csq->h_al, p_csq->cid );\r
        if( status != IB_SUCCESS )\r
        {\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
                        ("al_cep_send_rep returned %s\n", ib_get_err_str(status)) );\r
 err:\r
-               /* Reject and abort the connection. */\r
-               al_cep_rej( qp_get_al( h_qp ), p_rep->cid, IB_REJ_INSUF_QP, NULL, 0, NULL, 0 );\r
+               /*\r
+                * Reject the connection.  Note that we don't free the CEP since the\r
+                * usermode INDConnector object references it, and the CEP will be\r
+                * freed when that object is freed.\r
+                */\r
+               al_cep_rej( p_csq->h_al, p_csq->cid, IB_REJ_INSUF_QP, NULL, 0, NULL, 0 );\r
 \r
                /* transit QP to error state */\r
-               __cep_timewait_qp( h_qp );\r
-\r
-               al_destroy_cep( qp_get_al( h_qp ), &((al_conn_qp_t*)h_qp)->cid, TRUE );\r
+               __cep_timewait_qp( p_csq );\r
 \r
                AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
                        ("al_cep_rtu returned %s.\n", ib_get_err_str( status )) );\r
-               __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-               if( h_qp->p_irp_queue->state != NDI_CM_INVALID )\r
-                       h_qp->p_irp_queue->state = NDI_CM_IDLE;\r
-               __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
-               if (status == IB_INVALID_STATE)\r
+               __ndi_acquire_lock( &p_csq->csq, &irql );\r
+               if( p_csq->state != NDI_CM_INVALID )\r
+                       p_csq->state = NDI_CM_IDLE;\r
+               __ndi_release_lock( &p_csq->csq, irql );\r
+               if (status == IB_INVALID_STATE )\r
                        nt_status = STATUS_CONNECTION_ABORTED;\r
+               /* The HCA driver will return IB_INVALID_PARAMETER if the QP is in the wrong state. */\r
+               else if( status == IB_INVALID_HANDLE || status == IB_INVALID_PARAMETER )\r
+                       nt_status = STATUS_CANCELLED;\r
                else\r
-                       nt_status =STATUS_INSUFFICIENT_RESOURCES;\r
+                       nt_status = STATUS_INSUFFICIENT_RESOURCES;\r
                goto exit;\r
        }\r
 \r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       if( h_qp->p_irp_queue->state == NDI_CM_CONNECTING_REP_SENT )\r
-               h_qp->p_irp_queue->state = NDI_CM_CONNECTED;\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       if( p_csq->state == NDI_CM_CONNECTING_REP_SENT )\r
+               p_csq->state = NDI_CM_CONNECTED;\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
        nt_status = STATUS_SUCCESS;\r
 \r
 exit:\r
-       __ndi_complete_irp( h_qp, p_irp, nt_status );\r
+       __ndi_complete_irp( p_csq, p_irp, nt_status );\r
+       nd_csq_release( p_csq ); /* Release work item reference. */\r
        AL_EXIT( AL_DBG_NDI );\r
 }\r
 \r
 static void\r
 __ndi_fill_cm_rep(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              net32_t                                                         qpn,\r
        IN              ual_ndi_rep_cm_ioctl_in_t                       *p_rep,\r
                OUT     iba_cm_rep                                                      *p_cm_rep)\r
 {\r
@@ -1487,7 +1626,7 @@ __ndi_fill_cm_rep(
        p_cm_rep->p_pdata = p_rep->pdata;\r
        p_cm_rep->pdata_len = sizeof(p_rep->pdata);\r
 \r
-       p_cm_rep->qpn = h_qp->num;\r
+       p_cm_rep->qpn = qpn;\r
 \r
        p_cm_rep->init_depth = p_rep->init_depth;\r
        p_cm_rep->failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;\r
@@ -1500,20 +1639,29 @@ __ndi_fill_cm_rep(
 \r
 NTSTATUS\r
 __ndi_send_rep(\r
-       IN              ib_qp_handle_t                                          h_qp,\r
+       IN              nd_csq_t                                                        *p_csq,\r
        IN              PIRP                                                            p_irp )\r
 {\r
        IO_STACK_LOCATION       *p_io_stack;\r
+       ib_qp_handle_t h_qp;\r
        iba_cm_rep cm_rep;\r
-       ib_qp_mod_t qp_mod;\r
        ib_api_status_t status;\r
        ual_ndi_rep_cm_ioctl_in_t *p_rep = \r
                (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
 \r
-       AL_ENTER( AL_DBG_NDI );\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("[ CID = %d\n", p_csq->cid) );\r
 \r
-       if( h_qp->p_irp_queue->state != NDI_CM_IDLE )\r
+       switch( p_csq->state )\r
        {\r
+       case NDI_CM_CONNECTING_REQ_RCVD:\r
+               break;\r
+\r
+       case NDI_CM_CONNECTED_DREQ_RCVD:\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return STATUS_CONNECTION_ABORTED;\r
+\r
+       default:\r
                AL_EXIT( AL_DBG_NDI );\r
                return STATUS_CONNECTION_ACTIVE;\r
        }\r
@@ -1525,26 +1673,36 @@ __ndi_send_rep(
                AL_EXIT( AL_DBG_NDI );\r
                return STATUS_NO_MEMORY;\r
        }\r
-       ref_al_obj( &h_qp->obj ); /* Take work item reference. */\r
+       nd_csq_ref( p_csq ); /* Take work item reference. */\r
 \r
-       /* Format ib_cm_req_t structure */\r
-       __ndi_fill_cm_rep( h_qp, p_rep, &cm_rep );\r
+       h_qp = CONTAINING_RECORD(\r
+               al_hdl_ref( p_csq->h_al, p_csq->h_qp, AL_OBJ_TYPE_H_QP ),\r
+               ib_qp_t,\r
+               obj );\r
+       if( !h_qp )\r
+       {\r
+               /* The QP was valid when the IOCTL first came in... */\r
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                       ("Invalid QP: %I64d\n", p_rep->h_qp) );\r
+               status = IB_INVALID_HANDLE;\r
+               goto err;\r
+       }\r
 \r
-       ref_al_obj( &h_qp->obj ); /* Take CEP reference. */\r
+       /* Format ib_cm_req_t structure */\r
+       __ndi_fill_cm_rep( h_qp->num, p_rep, &cm_rep );\r
+       deref_al_obj( &h_qp->obj );\r
 \r
        /* prepare Passive CEP for connection */\r
-       status = kal_cep_config_pre_rep_copy_cid(\r
-               qp_get_al( h_qp ), p_rep->cid, __ndi_cm_handler, &h_qp->obj, deref_al_obj,\r
-               &cm_rep, QP_ATTRIB_RNR_NAK_TIMEOUT, &((al_conn_qp_t*)h_qp)->cid, &qp_mod);\r
+       status = kal_cep_pre_rep(\r
+               p_csq->h_al, p_csq->cid, &cm_rep, QP_ATTRIB_RNR_NAK_TIMEOUT, NULL );\r
        if( status != IB_SUCCESS )\r
        {\r
+               AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                       ("kal_cep_pre_rep returned %s.\n", ib_get_err_str( status )) );\r
+err:\r
                IoFreeWorkItem( p_irp->Tail.Overlay.DriverContext[1] );\r
                p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-               deref_al_obj( &h_qp->obj ); /* Release work item reference. */\r
-               al_destroy_cep( qp_get_al( h_qp ), &p_rep->cid, FALSE );\r
-               deref_al_obj( &h_qp->obj ); /* Release CEP reference. */\r
-               AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
-                       ("kal_cep_config_pre_rep_copy_cid returned %s.\n", ib_get_err_str( status )) );\r
+               nd_csq_release( p_csq ); /* Release work item reference. */\r
                switch (status)\r
                {\r
                        case IB_INVALID_HANDLE:\r
@@ -1560,7 +1718,7 @@ __ndi_send_rep(
 \r
        AL_PRINT( TRACE_LEVEL_INFORMATION, AL_DBG_NDI,\r
                ("Prepared Passive CEP with cid %d, h_al %p, context %p\n",\r
-               p_rep->cid, qp_get_al( h_qp ), h_qp ) );\r
+               p_csq->cid, p_csq->h_al, h_qp ) );\r
 \r
        /*\r
         * transfer work to a worker thread so that QP transitions can be done\r
@@ -1570,39 +1728,52 @@ __ndi_send_rep(
                __ndi_do_rep, DelayedWorkQueue, p_irp );\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
-       return STATUS_SUCCESS;\r
+       return STATUS_PENDING;\r
 }\r
 \r
 \r
 NTSTATUS\r
 ndi_rep_cm(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              ib_al_handle_t                                          h_al,\r
        IN              PIRP                                                            p_irp\r
        )\r
 {\r
        NTSTATUS status;\r
+       nd_csq_t* p_csq;\r
+       ual_ndi_rep_cm_ioctl_in_t *p_rep = \r
+               (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( p_irp );\r
        KIRQL irql;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       p_irp->Tail.Overlay.DriverContext[0] = h_qp;\r
+       p_csq = kal_cep_get_context( h_al, p_rep->cid, nd_cm_handler, nd_csq_ref );\r
+       if( p_csq == NULL )\r
+       {\r
+               status = STATUS_CONNECTION_ABORTED;\r
+               goto err;\r
+       }\r
 \r
-       __ndi_acquire_lock( &h_qp->p_irp_queue->csq, &irql );\r
-       status = __ndi_send_rep( h_qp, p_irp );\r
-       if( status == STATUS_SUCCESS )\r
+       p_csq->h_qp = p_rep->h_qp;\r
+\r
+       p_irp->Tail.Overlay.DriverContext[0] = p_csq;\r
+\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       status = __ndi_send_rep( p_csq, p_irp );\r
+       if( status == STATUS_PENDING )\r
        {\r
                /*\r
                 * We're going to keep the IRP dangling for a bit - take a reference\r
                 * on the QP until it completes.\r
                 */\r
-               ref_al_obj( &h_qp->obj ); /* Take IRP reference. */\r
-               h_qp->p_irp_queue->state = NDI_CM_CONNECTING_REP_SENT;\r
+               nd_csq_ref( p_csq ); /* Take IRP reference. */\r
+               p_csq->state = NDI_CM_CONNECTING_REP_SENT;\r
                IoMarkIrpPending( p_irp );\r
-               status = STATUS_PENDING;\r
        }\r
-       __ndi_release_lock( &h_qp->p_irp_queue->csq, irql );\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
 \r
-       AL_EXIT( AL_DBG_NDI );\r
+       nd_csq_release( p_csq );\r
+err:\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("] returning %08x\n", status) );\r
        return status;\r
 }\r
 \r
@@ -1620,19 +1791,19 @@ __ndi_send_dreq(
        IN              IRP*                                                            p_irp\r
        )\r
 {\r
-       ib_qp_handle_t h_qp = (ib_qp_handle_t)p_irp->Tail.Overlay.DriverContext[0];\r
+       nd_csq_t *p_csq = (nd_csq_t*)p_irp->Tail.Overlay.DriverContext[0];\r
        IO_STACK_LOCATION       *p_io_stack;\r
        ib_api_status_t status;\r
        NTSTATUS nt_status;\r
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       if ( h_qp->p_irp_queue->state != NDI_CM_CONNECTED &&\r
-               h_qp->p_irp_queue->state != NDI_CM_CONNECTED_DREQ_RCVD )\r
+       if ( p_csq->state != NDI_CM_CONNECTED &&\r
+               p_csq->state != NDI_CM_CONNECTED_DREQ_RCVD )\r
        {\r
                AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
-                       ("STATUS_CONNECTION_ACTIVE: h_qp %#I64x, uhdl %#I64x, ref_cnt %d\n",\r
-                       (uint64_t)(ULONG_PTR)h_qp, h_qp->obj.hdl, h_qp->obj.ref_cnt ) );\r
+                       ("STATUS_CONNECTION_ACTIVE: CID = %d, uhdl %#I64x, ref_cnt %d\n",\r
+                       p_csq->cid, p_csq->h_qp, p_csq->ref_cnt ) );\r
                return STATUS_CONNECTION_INVALID;\r
        }\r
 \r
@@ -1648,24 +1819,26 @@ __ndi_send_dreq(
                AL_EXIT( AL_DBG_NDI );\r
                return STATUS_NO_MEMORY;\r
        }\r
-       ref_al_obj( &h_qp->obj ); /* Take work item reference. */\r
+       nd_csq_ref( p_csq ); /* Take work item reference. */\r
 \r
-       status = al_cep_dreq( qp_get_al( h_qp ), ((al_conn_qp_t*)h_qp)->cid, NULL, 0 );\r
+       status = al_cep_dreq( p_csq->h_al, p_csq->cid, NULL, 0 );\r
        switch( status )\r
        {\r
        case IB_INVALID_STATE:\r
-               /* We might have just received a DREQ, so try sending a DREP. */\r
-               __ndi_queue_drep( p_irp );\r
-               IoMarkIrpPending( p_irp );\r
                /*\r
                 * We're going to keep the IRP dangling for a bit - take a reference\r
-                * on the QP until it completes.\r
+                * on the CSQ until it completes.\r
                 */\r
-               ref_al_obj( &h_qp->obj ); /* Take IRP reference. */\r
+               nd_csq_ref( p_csq ); /* Take IRP reference. */\r
+               /* We might have just received a DREQ, so try sending a DREP. */\r
+               IoMarkIrpPending( p_irp );\r
+               __ndi_queue_drep( p_irp );\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return STATUS_INVALID_DEVICE_STATE;\r
 \r
        case IB_SUCCESS:\r
                AL_EXIT( AL_DBG_NDI );\r
-               return( ib_to_ntstatus( status ) );\r
+               return STATUS_PENDING;\r
 \r
        case IB_INVALID_HANDLE:\r
                nt_status = STATUS_CONNECTION_INVALID;\r
@@ -1675,7 +1848,7 @@ __ndi_send_dreq(
        }\r
        IoFreeWorkItem( p_irp->Tail.Overlay.DriverContext[1] );\r
        p_irp->Tail.Overlay.DriverContext[1] = NULL;\r
-       deref_al_obj( &h_qp->obj ); /* Release work item reference. */\r
+       nd_csq_release( p_csq ); /* Release work item reference. */\r
        AL_EXIT( AL_DBG_NDI );\r
        return nt_status;\r
 }\r
@@ -1683,7 +1856,7 @@ __ndi_send_dreq(
 \r
 NTSTATUS\r
 ndi_dreq_cm(\r
-       IN              ib_qp_handle_t  const                           h_qp,\r
+       IN              nd_csq_t*                                                       p_csq,\r
        IN              PIRP                                                            p_irp\r
        )\r
 {\r
@@ -1691,10 +1864,10 @@ ndi_dreq_cm(
 \r
        AL_ENTER( AL_DBG_NDI );\r
 \r
-       p_irp->Tail.Overlay.DriverContext[0] = h_qp;\r
+       p_irp->Tail.Overlay.DriverContext[0] = p_csq;\r
 \r
        status = IoCsqInsertIrpEx(\r
-               &h_qp->p_irp_queue->csq,\r
+               &p_csq->csq,\r
                p_irp,\r
                NULL,\r
                (VOID*)(ULONG_PTR)NDI_CM_DISCONNECTING\r
@@ -1706,10 +1879,136 @@ ndi_dreq_cm(
         * The IRP should never be queued if the work item is queued, so \r
         * we trap the special error code for INVALID_STATE.\r
         */\r
-       if( status == STATUS_SUCCESS || status == STATUS_INVALID_DEVICE_STATE )\r
+       if( status == STATUS_INVALID_DEVICE_STATE )\r
                status = STATUS_PENDING;\r
 \r
        AL_EXIT( AL_DBG_NDI );\r
        return status;\r
 }\r
 \r
+\r
+NTSTATUS\r
+ndi_listen_cm(\r
+       IN              ib_al_handle_t                                  h_al,\r
+       IN              ib_cep_listen_t                                 *p_listen,\r
+               OUT     net32_t                                                 *p_cid,\r
+               OUT     size_t                                                  *p_ret_bytes\r
+       )\r
+{\r
+       NTSTATUS status;\r
+       net32_t cid;\r
+       ib_api_status_t ib_status;\r
+       nd_csq_t *p_csq;\r
+       KIRQL irql;\r
+\r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       ib_status = al_create_cep( h_al, NULL, NULL, NULL, &cid );\r
+       if( ib_status != IB_SUCCESS )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return ib_to_ntstatus( ib_status );\r
+       }\r
+\r
+       status = nd_csq_init( h_al, cid, 0, &p_csq );\r
+       if( status != STATUS_SUCCESS )\r
+       {\r
+               kal_cep_destroy( h_al, cid, STATUS_SUCCESS );\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return status;\r
+       }\r
+\r
+       __ndi_acquire_lock( &p_csq->csq, &irql );\r
+       p_csq->state = NDI_CM_LISTEN;\r
+       __ndi_release_lock( &p_csq->csq, irql );\r
+\r
+       if( (p_listen->svc_id & 0xFFFF) == 0 )\r
+       {\r
+               p_listen->svc_id |= (USHORT)cid | (USHORT)(cid >> 16);\r
+       }\r
+\r
+       ib_status = al_cep_listen( h_al, cid, p_listen );\r
+       if( ib_status == IB_SUCCESS )\r
+       {\r
+               *p_cid = cid;\r
+               *p_ret_bytes = sizeof(*p_cid);\r
+       }\r
+\r
+       nd_csq_release( p_csq );\r
+       status = ib_to_ntstatus( ib_status );\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return status;\r
+}\r
+\r
+\r
+NTSTATUS\r
+__ndi_get_req(\r
+       IN              nd_csq_t                                                        *p_csq,\r
+       IN              IRP*                                                            p_irp\r
+       )\r
+{\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("[ CID = %d\n", p_csq->cid) );\r
+\r
+       if( p_csq->state != NDI_CM_LISTEN )\r
+       {\r
+               AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_NDI,\r
+                       ("] Invalid state (%d).\n", p_csq->state) );\r
+               return STATUS_INVALID_DEVICE_REQUEST;\r
+       }\r
+\r
+       /* Check the MAD list. */\r
+       if( p_csq->p_mad_head != NULL )\r
+       {\r
+               ib_mad_element_t* p_mad = p_csq->p_mad_head;\r
+               net32_t cid = (net32_t)(ULONG_PTR)p_mad->send_context1;\r
+               p_csq->p_mad_head = p_mad->p_next;\r
+               p_mad->p_next = NULL;\r
+\r
+               *(net32_t*)cl_ioctl_out_buf( p_irp ) = cid;\r
+               p_irp->IoStatus.Information = sizeof(net32_t);\r
+               p_irp->IoStatus.Status = STATUS_SUCCESS;\r
+               IoMarkIrpPending( p_irp );\r
+               IoCompleteRequest( p_irp, IO_NETWORK_INCREMENT );\r
+               ib_put_mad( p_mad );\r
+               AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("] Returned new CID = %d\n", cid) );\r
+               return STATUS_INVALID_DEVICE_STATE;\r
+       }\r
+\r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI, ("] Queueing IRP\n") );\r
+       return STATUS_PENDING;\r
+}\r
+\r
+\r
+NTSTATUS\r
+ndi_get_req_cm(\r
+       IN              nd_csq_t                                                *p_csq,\r
+       IN              PIRP                                                    p_irp\r
+       )\r
+{\r
+       NTSTATUS status;\r
+\r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       status = IoCsqInsertIrpEx(\r
+               &p_csq->csq,\r
+               p_irp,\r
+               NULL,\r
+               (VOID*)(ULONG_PTR)NDI_CM_LISTEN\r
+               );\r
+\r
+       /*\r
+        * __ndi_get_req will return STATUS_INVALID_DEVICE_STATE to prevent the IRP\r
+        * from being inserted into the CSQ because the IRP was immediately completed.\r
+        * In this case, we need to return STATUS_PENDING.\r
+        */\r
+       if( status == STATUS_INVALID_DEVICE_STATE )\r
+       {\r
+               status = STATUS_PENDING;\r
+       }\r
+\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return status;\r
+}\r
+\r
+\r
+\r
index 029f7697692296d68ee5532626e2958d3227da59..554e39782457a6a66d3074e0a41df2305be03674 100644 (file)
 typedef enum _ndi_cm_state \r
 {\r
        NDI_CM_IDLE,\r
+       NDI_CM_LISTEN,\r
        NDI_CM_CONNECTING_QPR_SENT, // QPR = Query path record\r
        NDI_CM_CONNECTING_REQ_SENT,\r
+       NDI_CM_CONNECTING_REQ_RCVD,\r
        NDI_CM_CONNECTING_REP_SENT,\r
        NDI_CM_CONNECTING_REP_RCVD,\r
        NDI_CM_CONNECTED,\r
@@ -77,16 +79,27 @@ typedef enum _ndi_cm_state
 \r
 typedef struct _ib_qp  ib_qp_t;\r
 \r
-typedef struct _ndi_qp_csq\r
+typedef struct _nd_csq\r
 {\r
        IO_CSQ                                          csq;\r
        LIST_ENTRY                                      queue;\r
-       ib_qp_t*                                        h_qp;\r
-       ib_query_handle_t                       h_query;\r
+       ib_al_handle_t                          h_al;\r
+       union {\r
+               uint64_t                                h_qp;\r
+               ib_mad_element_t                *p_mad_head;\r
+       };\r
+       union {\r
+               ib_query_handle_t               h_query;\r
+               ib_mad_element_t                *p_mad_tail;\r
+       };\r
+       net32_t                                         cid;\r
        ndi_cm_state_t                          state;\r
        PIO_WORKITEM                            p_workitem;\r
+       volatile LONG                           ref_cnt;\r
+       KSPIN_LOCK                                      lock;\r
+\r
+} nd_csq_t;\r
 \r
-} ndi_qp_csq_t;\r
 \r
 ib_api_status_t\r
 ndi_modify_qp(\r
@@ -95,41 +108,59 @@ ndi_modify_qp(
        IN              const   uint32_t                                        buf_size,\r
        IN                              uint8_t* const                          p_outbuf);\r
 \r
+void\r
+nd_csq_ref( nd_csq_t* p_csq );\r
+\r
+void\r
+nd_csq_release( nd_csq_t* p_csq );\r
+\r
+void\r
+nd_cm_handler(\r
+       IN              const   ib_al_handle_t                          h_al,\r
+       IN              const   net32_t                                         cid );\r
+\r
 NTSTATUS\r
 ndi_req_cm(\r
-       IN              ib_qp_handle_t  const                   h_qp,\r
-       IN              cl_ioctl_handle_t                               h_ioctl\r
+       IN              ib_al_handle_t                                  h_al,\r
+       IN              PIRP                                                    p_irp\r
        );\r
 \r
 NTSTATUS\r
 ndi_rep_cm(\r
-       IN              ib_qp_handle_t  const                   h_qp,\r
+       IN              ib_al_handle_t                                  h_al,\r
        IN              PIRP                                                    p_irp\r
        );\r
 \r
 cl_status_t\r
 ndi_rtu_cm(\r
-       IN              ib_qp_handle_t  const                   h_qp,\r
+       IN              nd_csq_t                                                *p_csq,\r
        IN              PIRP                                                    p_irp\r
        );\r
 \r
 NTSTATUS\r
 ndi_dreq_cm(\r
-       IN              ib_qp_handle_t  const                   h_qp,\r
+       IN              nd_csq_t                                                *p_csq,\r
        IN              PIRP                                                    p_irp\r
        );\r
-       \r
-NTSTATUS\r
-ndi_qp_init(\r
-       IN              ib_qp_handle_t                                  h_qp );\r
 \r
 void\r
-ndi_qp_destroy(\r
-       IN              ib_qp_handle_t                                  h_qp );\r
+ndi_cancel_cm_irps(\r
+       IN              nd_csq_t                                                *p_csq\r
+       );\r
 \r
-void\r
-ndi_qp_free(\r
-       IN              ib_qp_handle_t                                  h_qp );\r
+NTSTATUS\r
+ndi_listen_cm(\r
+       IN              ib_al_handle_t                                  h_al,\r
+       IN              ib_cep_listen_t                                 *p_listen,\r
+               OUT     net32_t                                                 *p_cid,\r
+               OUT     size_t                                                  *p_ret_bytes\r
+       );\r
+\r
+NTSTATUS\r
+ndi_get_req_cm(\r
+       IN              nd_csq_t                                                *p_csq,\r
+       IN              PIRP                                                    p_irp\r
+       );\r
 \r
 #endif\r
 \r
index 2b174ee4311642ddc90099f87b62dee4cd748e61..86b39c9cb734004f3494cea4fa4230b2ca1c248a 100644 (file)
@@ -53,7 +53,6 @@ proxy_create_cep(
                OUT     size_t                                  *p_ret_bytes )\r
 {\r
        al_dev_open_context_t           *p_context;\r
-       void*                                           user_context;\r
        ual_create_cep_ioctl_t          *p_ioctl;\r
 \r
        AL_ENTER( AL_DBG_CM );\r
@@ -62,19 +61,13 @@ proxy_create_cep(
        p_ioctl = (ual_create_cep_ioctl_t*)cl_ioctl_out_buf( h_ioctl );\r
 \r
        /* Validate user parameters. */\r
-       if( cl_ioctl_in_size( h_ioctl ) != sizeof(uint64_t) ||\r
-               cl_ioctl_out_size( h_ioctl ) != sizeof(ual_create_cep_ioctl_t) )\r
+       if( cl_ioctl_out_size( h_ioctl ) != sizeof(ual_create_cep_ioctl_t) )\r
        {\r
                AL_EXIT( AL_DBG_CM );\r
                return CL_INVALID_PARAMETER;\r
        }\r
-\r
-       user_context = *(void**)cl_ioctl_in_buf( h_ioctl );\r
-\r
        /* We use IRPs as notification mechanism so the callback is NULL. */\r
-       p_ioctl->cid = AL_INVALID_CID;\r
-       p_ioctl->status = al_create_cep( p_context->h_al, NULL,\r
-               user_context, NULL, &p_ioctl->cid );\r
+       p_ioctl->status = kal_cep_alloc( p_context->h_al, &p_ioctl->cid );\r
 \r
        *p_ret_bytes = sizeof(ual_create_cep_ioctl_t);\r
 \r
@@ -862,37 +855,6 @@ proxy_cep_get_event(
 }\r
 \r
 \r
-static cl_status_t\r
-proxy_cep_get_req_cid(\r
-       IN              void                                    *p_open_context,\r
-       IN              cl_ioctl_handle_t               h_ioctl,\r
-               OUT     size_t                                  *p_ret_bytes )\r
-{\r
-       cl_status_t cl_status;\r
-       al_dev_open_context_t *p_context;\r
-       UNUSED_PARAM(p_ret_bytes);\r
-       \r
-       AL_ENTER( AL_DBG_CM );\r
-\r
-       p_context = (al_dev_open_context_t*)p_open_context;\r
-\r
-       /* Validate user parameters. */\r
-       if( cl_ioctl_in_size( h_ioctl ) != sizeof(uint32_t) ||\r
-               cl_ioctl_out_size( h_ioctl ) != sizeof(uint32_t) )\r
-       {\r
-               AL_EXIT( AL_DBG_CM );\r
-               return CL_INVALID_PARAMETER;\r
-       }\r
-\r
-       /* get CID */\r
-       cl_status = al_cep_get_cid( p_context->h_al, \r
-               *(uint32_t*)cl_ioctl_in_buf( h_ioctl ), h_ioctl );\r
-\r
-       AL_EXIT( AL_DBG_CM );\r
-       return cl_status;\r
-}\r
-\r
-\r
 \r
 static cl_status_t\r
 proxy_cep_get_pdata(\r
@@ -902,8 +864,8 @@ proxy_cep_get_pdata(
 {\r
        al_dev_open_context_t           *p_context;\r
        ual_cep_get_pdata_ioctl_t       *p_ioctl;\r
-       al_conn_qp_t                            *p_qp;\r
        NTSTATUS                    status;\r
+       net32_t                                         cid;\r
 \r
        AL_ENTER( AL_DBG_CM );\r
 \r
@@ -922,23 +884,9 @@ proxy_cep_get_pdata(
                return CL_INVALID_PARAMETER;\r
        }\r
 \r
-       if ( p_ioctl->in.h_qp )\r
-       {\r
-               /* Get the kernel QP handle. */\r
-               p_qp = (al_conn_qp_t*)al_hdl_ref(\r
-                       p_context->h_al, p_ioctl->in.h_qp, AL_OBJ_TYPE_H_QP );\r
-               if( !p_qp )\r
-               {\r
-                       AL_PRINT_EXIT( TRACE_LEVEL_ERROR, AL_DBG_ERROR, \r
-                               ("Invalid QP handle\n"));\r
-                       return CL_CONNECTION_INVALID;\r
-               }\r
-               p_ioctl->in.cid = p_qp->cid;\r
-               deref_al_obj( &p_qp->qp.obj );\r
-       }\r
-\r
+       cid = p_ioctl->in.cid;\r
        p_ioctl->out.pdata_len = sizeof(p_ioctl->out.pdata);\r
-       status = al_cep_get_pdata( p_context->h_al, p_ioctl->in.cid,\r
+       status = al_cep_get_pdata( p_context->h_al, cid,\r
         &p_ioctl->out.init_depth, &p_ioctl->out.resp_res,\r
                (uint8_t*)&p_ioctl->out.pdata_len, p_ioctl->out.pdata );\r
 \r
@@ -953,6 +901,7 @@ proxy_cep_get_pdata(
        return status;\r
 }\r
 \r
+\r
 cl_status_t cep_ioctl(\r
        IN              cl_ioctl_handle_t               h_ioctl,\r
                OUT     size_t                                  *p_ret_bytes )\r
@@ -1036,9 +985,6 @@ cl_status_t cep_ioctl(
        case UAL_CEP_POLL:\r
                cl_status = proxy_cep_poll( p_context, h_ioctl, p_ret_bytes );\r
                break;\r
-       case UAL_CEP_GET_REQ_CID:\r
-               cl_status = proxy_cep_get_req_cid( p_context, h_ioctl, p_ret_bytes );\r
-               break;\r
        case UAL_CEP_GET_PDATA:\r
                cl_status = proxy_cep_get_pdata( p_context, h_ioctl, p_ret_bytes );\r
                break;\r
index 3da4dbb7fd1b71ebef71a8424a77d644d4bb8650..9d16ceb22cb7cda42119595ffaae28733955b8ca 100644 (file)
 #include "al_proxy_ndi.h"\r
 #include "al_ndi_cm.h"\r
 \r
+#if WINVER <= 0x501\r
+#include "csq.h"\r
+#endif\r
+\r
 /*******************************************************************\r
  *\r
  * IOCTLS\r
@@ -322,7 +326,7 @@ __ndi_req_cm(
        p_context = (al_dev_open_context_t*)p_open_context;\r
 \r
        /* Validate user parameters. */\r
-       if( cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_req_cm_ioctl_in_t))\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_req_cm_ioctl_in_t) )\r
        {\r
                cl_status = CL_INVALID_PARAMETER;\r
                goto exit;\r
@@ -351,7 +355,7 @@ __ndi_req_cm(
        }\r
 \r
        /* perform the ioctl */\r
-       cl_status = ndi_req_cm( h_qp, h_ioctl );\r
+       cl_status = ndi_req_cm( p_context->h_al, h_ioctl );\r
 \r
 err:\r
        deref_al_obj( &h_qp->obj );\r
@@ -370,7 +374,6 @@ __ndi_rep_cm(
        cl_status_t cl_status;\r
        ib_qp_handle_t h_qp = NULL;\r
        al_dev_open_context_t *p_context;\r
-       net32_t cid;\r
        ual_ndi_rep_cm_ioctl_in_t *p_rep = \r
                (ual_ndi_rep_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
        UNUSED_PARAM(p_ret_bytes);\r
@@ -386,6 +389,9 @@ __ndi_rep_cm(
                goto exit;\r
        }\r
 \r
+       AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+               ("CID = %d\n", p_rep->cid) );\r
+\r
        /* Get and validate QP handle */\r
        h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_rep->h_qp, AL_OBJ_TYPE_H_QP );\r
        if( !h_qp )\r
@@ -406,12 +412,9 @@ __ndi_rep_cm(
                cl_status = CL_INVALID_PARAMETER;\r
                goto err;\r
        }\r
-       \r
-       /* Get and validate CID */\r
-       cid = p_rep->cid;\r
 \r
        /* perform the ioctls */\r
-       cl_status = ndi_rep_cm( h_qp, h_ioctl );\r
+       cl_status = ndi_rep_cm( p_context->h_al, h_ioctl );\r
 \r
 err:\r
        deref_al_obj( &h_qp->obj );\r
@@ -455,7 +458,6 @@ __ndi_rej_cm(
                goto exit;\r
        }\r
 \r
-       al_destroy_cep( p_context->h_al, &p_rej->cid, FALSE );\r
        ntstatus = STATUS_SUCCESS;\r
 \r
 exit:\r
@@ -470,10 +472,8 @@ __ndi_rtu_cm(
                OUT     size_t                                  *p_ret_bytes )\r
 {\r
        cl_status_t cl_status;\r
-       ib_qp_handle_t h_qp = NULL;\r
+       nd_csq_t* p_csq;\r
        al_dev_open_context_t *p_context;\r
-       ual_ndi_rtu_cm_ioctl_in_t *p_rtu = \r
-               (ual_ndi_rtu_cm_ioctl_in_t*)cl_ioctl_in_buf( h_ioctl );\r
 \r
        UNUSED_PARAM(p_ret_bytes);\r
        \r
@@ -482,32 +482,28 @@ __ndi_rtu_cm(
        p_context = (al_dev_open_context_t*)p_open_context;\r
 \r
        /* Validate user parameters. */\r
-       if( cl_ioctl_in_size( h_ioctl ) < sizeof(ual_ndi_rtu_cm_ioctl_in_t))\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
        {\r
                cl_status = CL_INVALID_PARAMETER;\r
                goto exit;\r
        }\r
 \r
-       /* Validate QP handle */\r
-       h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, p_rtu->h_qp, AL_OBJ_TYPE_H_QP );\r
-       if( !h_qp )\r
+       p_csq = kal_cep_get_context(\r
+               p_context->h_al,\r
+               *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
+               nd_cm_handler,\r
+               nd_csq_ref\r
+               );\r
+       if( p_csq == NULL )\r
        {\r
                cl_status = CL_INVALID_HANDLE;\r
                goto exit;\r
        }\r
 \r
-       /* Check QP type */\r
-       if( h_qp->type != IB_QPT_RELIABLE_CONN )\r
-       {\r
-               cl_status = CL_INVALID_HANDLE;\r
-               goto err;\r
-       }\r
-\r
        /* perform the ioctl */\r
-       cl_status = ndi_rtu_cm( h_qp, h_ioctl );\r
+       cl_status = ndi_rtu_cm( p_csq, h_ioctl );\r
 \r
-err:\r
-       deref_al_obj( &h_qp->obj );\r
+       nd_csq_release( p_csq );\r
 \r
 exit:\r
        AL_EXIT( AL_DBG_NDI );\r
@@ -521,7 +517,7 @@ __ndi_dreq_cm(
                OUT     size_t                                  *p_ret_bytes )\r
 {\r
        cl_status_t cl_status;\r
-       ib_qp_handle_t h_qp = NULL;\r
+       nd_csq_t *p_csq;\r
        al_dev_open_context_t *p_context;\r
 \r
        UNUSED_PARAM(p_ret_bytes);\r
@@ -531,37 +527,206 @@ __ndi_dreq_cm(
        p_context = (al_dev_open_context_t*)p_open_context;\r
 \r
        /* Validate user parameters. */\r
-       if( cl_ioctl_in_size( h_ioctl ) < sizeof(uint64_t))\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
        {\r
                cl_status = CL_INVALID_PARAMETER;\r
                goto exit;\r
        }\r
 \r
-       /* Validate QP handle */\r
-       h_qp = (ib_qp_handle_t)al_hdl_ref( p_context->h_al, \r
-               *(uint64_t*)cl_ioctl_in_buf( h_ioctl ), AL_OBJ_TYPE_H_QP );\r
-       if( !h_qp )\r
+       /* Validate CID */\r
+       p_csq = (nd_csq_t*)kal_cep_get_context(\r
+               p_context->h_al,\r
+               *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
+               nd_cm_handler,\r
+               nd_csq_ref\r
+               );\r
+\r
+       if( p_csq == NULL )\r
        {\r
                cl_status = CL_CONNECTION_INVALID;\r
                goto exit;\r
        }\r
 \r
-       /* Check QP type */\r
-       if( h_qp->type != IB_QPT_RELIABLE_CONN )\r
+       /* perform the ioctl */\r
+       cl_status = ndi_dreq_cm( p_csq, h_ioctl );\r
+\r
+       nd_csq_release( p_csq );\r
+\r
+exit:\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return cl_status;\r
+}\r
+\r
+static NTSTATUS\r
+__ndi_notify_dreq_cm(\r
+       IN              void                                    *p_open_context,\r
+       IN              cl_ioctl_handle_t               h_ioctl,\r
+               OUT     size_t                                  *p_ret_bytes )\r
+{\r
+       NTSTATUS status;\r
+       nd_csq_t *p_csq;\r
+       al_dev_open_context_t *p_context;\r
+\r
+       UNUSED_PARAM(p_ret_bytes);\r
+       \r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       p_context = (al_dev_open_context_t*)p_open_context;\r
+\r
+       /* Validate user parameters. */\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
        {\r
-               cl_status = CL_CONNECTION_INVALID;\r
-               goto err;\r
+               status = STATUS_INVALID_PARAMETER;\r
+               goto exit;\r
+       }\r
+\r
+       /* Validate CID */\r
+       p_csq = (nd_csq_t*)kal_cep_get_context(\r
+               p_context->h_al,\r
+               *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
+               nd_cm_handler,\r
+               nd_csq_ref\r
+               );\r
+\r
+       if( p_csq == NULL )\r
+       {\r
+               status = STATUS_CONNECTION_INVALID;\r
+               goto exit;\r
        }\r
 \r
        /* perform the ioctl */\r
-       cl_status = ndi_dreq_cm( h_qp, h_ioctl );\r
+       status = IoCsqInsertIrpEx(\r
+               &p_csq->csq,\r
+               h_ioctl,\r
+               NULL,\r
+               (VOID*)(ULONG_PTR)NDI_CM_CONNECTED_DREQ_RCVD\r
+               );\r
 \r
-err:\r
-       deref_al_obj( &h_qp->obj );\r
+       nd_csq_release( p_csq );\r
 \r
 exit:\r
        AL_EXIT( AL_DBG_NDI );\r
-       return cl_status;\r
+       return status;\r
+}\r
+\r
+static cl_status_t\r
+__ndi_cancel_cm_irps(\r
+       IN              void                                    *p_open_context,\r
+       IN              cl_ioctl_handle_t               h_ioctl,\r
+               OUT     size_t                                  *p_ret_bytes )\r
+{\r
+       nd_csq_t *p_csq;\r
+       al_dev_open_context_t *p_context;\r
+\r
+       UNUSED_PARAM(p_ret_bytes);\r
+       \r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       p_context = (al_dev_open_context_t*)p_open_context;\r
+\r
+       /* Validate user parameters. */\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(net32_t) )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       /* Validate CID */\r
+       p_csq = (nd_csq_t*)kal_cep_get_context(\r
+               p_context->h_al,\r
+               *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
+               nd_cm_handler,\r
+               nd_csq_ref\r
+               );\r
+\r
+       if( p_csq == NULL )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return STATUS_UNSUCCESSFUL;\r
+       }\r
+\r
+       /* perform the ioctl */\r
+       ndi_cancel_cm_irps( p_csq );\r
+       nd_csq_release( p_csq );\r
+\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+static cl_status_t\r
+__ndi_listen_cm(\r
+       IN              void                                    *p_open_context,\r
+       IN              cl_ioctl_handle_t               h_ioctl,\r
+               OUT     size_t                                  *p_ret_bytes )\r
+{\r
+       al_dev_open_context_t *p_context;\r
+       ual_cep_listen_ioctl_t *p_listen = \r
+               (ual_cep_listen_ioctl_t*)cl_ioctl_in_buf( h_ioctl );\r
+       net32_t* p_cid =\r
+               (net32_t*)cl_ioctl_out_buf( h_ioctl );\r
+\r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       p_context = (al_dev_open_context_t*)p_open_context;\r
+\r
+       /* Validate user parameters. */\r
+       if( cl_ioctl_in_size( h_ioctl ) < sizeof(*p_listen) ||\r
+               cl_ioctl_out_size( h_ioctl ) != sizeof(*p_cid) )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return CL_INVALID_PARAMETER;\r
+       }\r
+\r
+       /* Set the private data compare buffer to our kernel copy. */\r
+       if( p_listen->cep_listen.p_cmp_buf )\r
+               p_listen->cep_listen.p_cmp_buf = p_listen->compare;\r
+\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return ndi_listen_cm( p_context->h_al, &p_listen->cep_listen, p_cid, p_ret_bytes );\r
+}\r
+\r
+static cl_status_t\r
+__ndi_get_req_cm(\r
+       IN              void                                    *p_open_context,\r
+       IN              cl_ioctl_handle_t               h_ioctl,\r
+               OUT     size_t                                  *p_ret_bytes )\r
+{\r
+       al_dev_open_context_t *p_context;\r
+       nd_csq_t *p_csq;\r
+       NTSTATUS status;\r
+\r
+       AL_ENTER( AL_DBG_NDI );\r
+\r
+       UNREFERENCED_PARAMETER( p_ret_bytes );\r
+\r
+       p_context = (al_dev_open_context_t*)p_open_context;\r
+\r
+       /* Validate user parameters. */\r
+       if( cl_ioctl_in_size( h_ioctl ) != sizeof(net32_t) ||\r
+               cl_ioctl_out_size( h_ioctl ) != sizeof(net32_t) )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return CL_INVALID_PARAMETER;\r
+       }\r
+\r
+       /* Validate CID */\r
+       p_csq = (nd_csq_t*)kal_cep_get_context(\r
+               p_context->h_al,\r
+               *(net32_t*)cl_ioctl_in_buf( h_ioctl ),\r
+               nd_cm_handler,\r
+               nd_csq_ref\r
+               );\r
+\r
+       if( p_csq == NULL )\r
+       {\r
+               AL_EXIT( AL_DBG_NDI );\r
+               return STATUS_UNSUCCESSFUL;\r
+       }\r
+\r
+       status = ndi_get_req_cm( p_csq, h_ioctl );\r
+       nd_csq_release( p_csq );\r
+       AL_EXIT( AL_DBG_NDI );\r
+       return status;\r
 }\r
 \r
 cl_status_t\r
@@ -621,9 +786,23 @@ ndi_ioctl(
             h_ioctl->IoStatus.Status = CL_SUCCESS;\r
         h_ioctl->IoStatus.Information = 0;\r
 \r
+               AL_PRINT( TRACE_LEVEL_VERBOSE, AL_DBG_NDI,\r
+                       ("UAL_NDI_NOOP completed with %08x\n", h_ioctl->IoStatus.Status) );\r
         IoCompleteRequest( h_ioctl, IO_NETWORK_INCREMENT );\r
         cl_status = CL_PENDING;\r
         break;\r
+       case UAL_NDI_NOTIFY_DREQ:\r
+               cl_status = __ndi_notify_dreq_cm( p_context, h_ioctl, p_ret_bytes );\r
+               break;\r
+       case UAL_NDI_CANCEL_CM_IRPS:\r
+               cl_status = __ndi_cancel_cm_irps( p_context, h_ioctl, p_ret_bytes );\r
+               break;\r
+       case UAL_NDI_LISTEN_CM:\r
+               cl_status = __ndi_listen_cm( p_context, h_ioctl, p_ret_bytes );\r
+               break;\r
+       case UAL_NDI_GET_REQ_CM:\r
+               cl_status = __ndi_get_req_cm( p_context, h_ioctl, p_ret_bytes );\r
+               break;\r
        default:\r
                cl_status = CL_INVALID_PARAMETER;\r
                break;\r
index 280c2b211cac371fba5fa2e2f20d03ecdf78fba7..cd1a0e67732e88eb647b9eaea9b9a7aa45c4a175 100644 (file)
@@ -272,9 +272,8 @@ __create_ucep(
        /* Create a kernel CEP only if we don't already have a CID. */\r
        if( cid == AL_INVALID_CID )\r
        {\r
-               uint64_t cep_context = (ULONG_PTR)context;\r
-               if( !DeviceIoControl( g_al_device, UAL_CREATE_CEP, &cep_context,\r
-                       sizeof(cep_context), &ioctl, sizeof(ioctl), &bytes_ret, NULL ) ||\r
+               if( !DeviceIoControl( g_al_device, UAL_CREATE_CEP, NULL,\r
+                       0, &ioctl, sizeof(ioctl), &bytes_ret, NULL ) ||\r
                        bytes_ret != sizeof(ioctl) )\r
                {\r
                        __destroy_ucep( p_cep );\r
index 661a120ceec6510c54cbd240368e759cd8bb2db8..162c4015848932d5d5cb4a29945626c370e1455d 100644 (file)
@@ -555,6 +555,12 @@ fdo_release_resources(
 \r
        //TODO: Fail outstanding I/O operations.\r
 \r
+       ib_status = ib_deregister_ca( p_ext->hca_ifc.Verbs.guid );\r
+       if( ib_status != IB_SUCCESS ) {\r
+               BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned %s.\n",\r
+                       ib_get_err_str(ib_status)) );\r
+       }\r
+\r
        if ( p_ext->p_port_mgr && p_bfi->p_port_mgr ) {\r
                cl_obj_destroy( &p_ext->p_port_mgr->obj );\r
                p_ext->p_port_mgr = NULL;\r
@@ -566,11 +572,6 @@ fdo_release_resources(
        }\r
 \r
        if (p_ext->hca_ifc_taken) {\r
-               ib_status = ib_deregister_ca( p_ext->hca_ifc.Verbs.guid );\r
-               if( ib_status != IB_SUCCESS ) {\r
-                       BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned %s.\n",\r
-                               ib_get_err_str(ib_status)) );\r
-               }\r
                p_ext->hca_ifc.InterfaceHeader.InterfaceDereference(\r
                        p_ext->hca_ifc.InterfaceHeader.Context);\r
        }\r
index 4986bef3bba03943b2b76a9b347239c11ab3efe0..017f962971ce267ee9028eff878eea3d4a5c2507 100644 (file)
@@ -2,6 +2,8 @@ _LNG=$(LANGUAGE)
 _INX=.\r
 STAMP=stampinf -f $@ -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\r
 \r
+!INCLUDE mod_ver.def\r
+\r
 $(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx \r
     copy $(_INX)\$(@B).inx $@\r
-    $(STAMP)\r
+    $(STAMP) -d * -v $(IB_MAJORVERSION).$(IB_MINORVERSION).$(IB_BUILDVERSION).$(OPENIB_REV)\r
index f2e12253d1eca10a6ae21348164b4d072f81201c..b23286df69328f5fc166dcf761d72b9d624f5ae7 100644 (file)
@@ -14,7 +14,7 @@ _LNG=$(LANGUAGE)
 _INX=.\r
 !ENDIF\r
 \r
-STAMP=stampinf -a $(_BUILDARCH)\r
+STAMP=stampinf -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\r
 \r
 !INCLUDE mod_ver.def\r
 \r
index 042991a96b1e62695d9a83af61320163dadeba57..4cfcb3554c8fa5319127f7c736c62356dd168cbd 100644 (file)
@@ -48,15 +48,15 @@ HKR,,SilentInstall,,1
 \r
 [SourceDisksFiles.x86]\r
 mlx4_bus.sys = 1,,\r
-wdfcoinstaller01007.dll = 1,,\r
+wdfcoinstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 [SourceDisksFiles.amd64]\r
 mlx4_bus.sys = 1,,\r
-wdfcoinstaller01007.dll = 1,,\r
+wdfcoinstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 [SourceDisksFiles.ia64]\r
 mlx4_bus.sys = 1,,\r
-wdfcoinstaller01007.dll = 1,,\r
+wdfcoinstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 ;*****************************************\r
 ; Mlx4Bus  Install Section\r
@@ -226,10 +226,10 @@ AddReg=Wdf_CoInstaller_AddReg
 CopyFiles=Wdf_CoInstaller_CopyFiles\r
 \r
 [Wdf_CoInstaller_AddReg]\r
-HKR,,CoInstallers32,0x00010000, "wdfcoinstaller01007.dll,WdfCoInstaller"\r
+HKR,,CoInstallers32,0x00010000, "wdfcoinstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"\r
 \r
 [Wdf_CoInstaller_CopyFiles]\r
-wdfcoinstaller01007.dll\r
+wdfcoinstaller$KMDFCOINSTALLERVERSION$.dll\r
 \r
 [MLX4BUS.DDInstall.ntx86.Wdf]\r
 KmdfService = mlx4_bus, mlx4_bus_wdfsect\r
@@ -241,7 +241,7 @@ KmdfService = mlx4_bus, mlx4_bus_wdfsect
 KmdfService = mlx4_bus, mlx4_bus_wdfsect\r
 \r
 [mlx4_bus_wdfsect]\r
-KmdfLibraryVersion = 1.7\r
+KmdfLibraryVersion = $KMDFVERSION$\r
 \r
 \r
 ;*****************************************\r
index 00644b69b896746c87db8cd698f76aa0a2439d57..c8eb3b0a05ed8af2db60d98333a0ab0335bed3f6 100644 (file)
@@ -2,13 +2,11 @@ TARGETNAME=mlx4_bus
 TARGETPATH=..\..\..\..\..\bin\kernel\obj$(BUILD_ALT_DIR)\r
 TARGETTYPE=DRIVER\r
 \r
-!if $(_NT_TOOLS_VERSION) != 0x700\r
 # WDK build only - transform .inx --> .inf adding date & version stamp.\r
 # see .\makefile.inc\r
 INF_NAME=$(TARGETNAME)\r
 INF_TARGET=..\..\..\..\..\bin\kernel\$(O)\$(INF_NAME).inf\r
 NTTARGETFILES=$(INF_TARGET)\r
-!endif\r
 \r
 !if $(FREEBUILD)\r
 ENABLE_EVENT_TRACING=1\r
@@ -27,9 +25,7 @@ PRECOMPILED_INCLUDE=precomp.h
 \r
 NTTARGETFILE0=mofcomp\r
 \r
-KMDF_VERSION=1\r
-\r
-KMDF_MINOR_VERSION=7\r
+KMDF_VERSION_MAJOR=1\r
 \r
 C_DEFINES=$(C_DEFINES) -DDRIVER -DDEPRECATE_DDK_FUNCTIONS -D__LITTLE_ENDIAN -DUSE_WDM_INTERRUPTS\r
 \r
index 0fe6011e8714314d896a6166c723be097d316b0e..6c78ac6e9e8a69011acee4eef3ab2060e733abd7 100644 (file)
@@ -345,7 +345,6 @@ int mlx4_reset_request( struct ib_event_handler *event_handler )
 {
        struct ib_device *ibdev;
        struct mlx4_dev *dev;
-       int err = 0;
 
        unsigned long flags;
 
@@ -359,6 +358,7 @@ int mlx4_reset_request( struct ib_event_handler *event_handler )
 
        spin_lock_irqsave(&ibdev->event_handler_lock, &flags);
 
+        
        // set device to RESET_PENDING mode
        if (!(dev->flags & (MLX4_FLAG_RESET_CLIENT | MLX4_FLAG_RESET_DRIVER))) {
                PIO_WORKITEM reset_work;
@@ -372,16 +372,16 @@ int mlx4_reset_request( struct ib_event_handler *event_handler )
                if (!reset_work) {
             spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
                        mlx4_err(dev, "mlx4_reset_request IoAllocateWorkItem failed, reset will not be propagated\n");
-                       err = -EFAULT;
-                       goto err_workitem;
+                       return -EFAULT;
                }
                event_handler->rsrv_ptr = reset_work;
                IoQueueWorkItem( reset_work, card_reset_wi, DelayedWorkQueue, event_handler );
        }
 
-err_workitem:
        spin_unlock_irqrestore(&ibdev->event_handler_lock, flags);
-       return err;
+
+
+       return 0;
 }
 
 int mlx4_reset_cb_register( struct ib_event_handler *event_handler )
index cb3caf72589bae73bca605968e46750e502484d6..f497a4888853bb6c73e7090d275506a4db07fda3 100644 (file)
@@ -2,13 +2,11 @@ TARGETNAME=mlx4_hca
 TARGETPATH=..\..\..\..\bin\kernel\obj$(BUILD_ALT_DIR)\r
 TARGETTYPE=DRIVER\r
 \r
-!if $(_NT_TOOLS_VERSION) != 0x700\r
 # WDK build only - transform .inx --> .inf adding date & version stamp.\r
 # see .\makefile.inc\r
 INF_NAME=$(TARGETNAME)\r
 INF_TARGET=..\..\..\..\bin\kernel\$(O)\$(INF_NAME).inf\r
 NTTARGETFILES=$(INF_TARGET)\r
-!endif\r
 \r
 !if $(FREEBUILD)\r
 ENABLE_EVENT_TRACING=1\r
@@ -40,7 +38,7 @@ PRECOMPILED_INCLUDE=precomp.h
 \r
 NTTARGETFILE0=mofcomp\r
 \r
-KMDF_VERSION=1\r
+KMDF_VERSION_MAJOR=1\r
 \r
 C_DEFINES=$(C_DEFINES) -DDRIVER -DDEPRECATE_DDK_FUNCTIONS -D__LITTLE_ENDIAN \r
 #-DUSE_WDM_FRAMEWORK \r
index cb4d757f7e676cad2a9bc8d72076e8cd3fd4b127..4af4c9eba9746f7a5fd1f83638ff550079217ac4 100644 (file)
@@ -1328,7 +1328,14 @@ hca_query_interface(
                &GUID_RDMA_INTERFACE_VERBS ) )\r
        {\r
                status = __query_ci_ifc( p_dev_obj, p_io_stack );\r
-               *p_action = IrpComplete;\r
+               if( !NT_SUCCESS( status ) )\r
+               {\r
+                       *p_action = IrpComplete;\r
+               }\r
+               else\r
+               {\r
+                       *p_action = IrpSkip;\r
+               }\r
        }\r
        else\r
        {\r
index b926e9590bbc5961fcf06c95bdad96c9afe78269..bdf9eb237b11e00f2561fca86e309b4b7fdfd59a 100644 (file)
@@ -14,7 +14,7 @@ _LNG=$(LANGUAGE)
 _INX=.\r
 !ENDIF\r
 \r
-STAMP=stampinf -a $(_BUILDARCH)\r
+STAMP=stampinf -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\r
 \r
 !INCLUDE mod_ver.def\r
 \r
index 046a70cc634cf070b17675e6441ea0c331b4943f..35f88fa3ac3405260c6b97af5c161f55e0a8752d 100644 (file)
@@ -61,7 +61,7 @@ HKR,,"UpperFilters",0x00010008,"WinMad"
 mlx4_hca.sys = 1,,\r
 mlx4u.dll = 1,,\r
 mlx4ud.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 ibal.dll=1,,\r
 ibald.dll=1,,\r
 complib.dll=1,,\r
@@ -80,7 +80,7 @@ mlx4u.dll = 1,,
 mlx4ud.dll = 1,,\r
 mlx4u32.dll = 1,,\r
 mlx4u32d.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 ibal.dll=1,,\r
 ibald.dll=1,,\r
 complib.dll=1,,\r
@@ -103,7 +103,7 @@ mlx4u.dll = 1,,
 mlx4ud.dll = 1,,\r
 mlx4u32.dll = 1,,\r
 mlx4u32d.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 ibal.dll=1,,\r
 ibald.dll=1,,\r
 complib.dll=1,,\r
@@ -408,10 +408,10 @@ AddReg=Wdf_CoInstaller_AddReg
 CopyFiles=Wdf_CoInstaller_CopyFiles\r
 \r
 [Wdf_CoInstaller_AddReg]\r
-HKR,,CoInstallers32,0x00010000, "WdfCoInstaller01007.dll,WdfCoInstaller"\r
+HKR,,CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"\r
 \r
 [Wdf_CoInstaller_CopyFiles]\r
-WdfCoInstaller01007.dll\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll\r
 \r
 [MLX4HCA.DDInstall.ntx86.Wdf]\r
 KmdfService = mlx4_hca,WvWdfSect\r
@@ -429,7 +429,7 @@ KmdfService = WinVerbs,WvWdfSect
 KmdfService = WinMad,WvWdfSect\r
 \r
 [WvWdfSect]\r
-KmdfLibraryVersion = 1.7\r
+KmdfLibraryVersion = $KMDFVERSION$\r
 \r
 \r
 ;*****************************************\r
index 5364cdbc39f829c10d052091f402fd1eae23bb87..f653d2289b626f9213dbe214e0f917ccd2c99b6a 100644 (file)
@@ -4,13 +4,13 @@ TARGETNAME=mthca
 TARGETPATH=$(TRUNK)\bin\kernel\obj$(BUILD_ALT_DIR)\r
 TARGETTYPE=DRIVER\r
 \r
-!if $(_NT_TOOLS_VERSION) != 0x700\r
+KMDF_VERSION_MAJOR=1\r
+\r
 # WDK build only - transform .inx --> .inf adding date & version stamp.\r
 # see .\makefile.inc\r
 INF_NAME=$(TARGETNAME)\r
 INF_TARGET=$(TRUNK)\bin\kernel\$(O)\$(INF_NAME).inf\r
 NTTARGETFILES=$(INF_TARGET)\r
-!endif\r
 \r
 !if $(FREEBUILD)\r
 ENABLE_EVENT_TRACING=1\r
index 054086a67ac05b4d783267ae96e8471f7a3ae49d..1488a749812dd569b2e7be2bc94bd1980e74caba 100644 (file)
@@ -912,7 +912,14 @@ hca_query_interface(
                &GUID_RDMA_INTERFACE_VERBS ) )\r
        {\r
                status = __query_ci_ifc( p_dev_obj, p_io_stack );\r
-               *p_action = IrpComplete;\r
+               if( !NT_SUCCESS( status ) )\r
+               {\r
+                       *p_action = IrpComplete;\r
+               }\r
+               else\r
+               {\r
+                       *p_action = IrpSkip;\r
+               }\r
        }\r
        else\r
        {\r
index 4f29f500780f2c5ff8dd40ca60e7f5f081fbdeea..3f3c0013ddf443f839ef23b7da5b64eb3d702405 100644 (file)
@@ -8,7 +8,7 @@ _LNG=$(LANGUAGE)
 _INX=.\r
 !ENDIF\r
 \r
-STAMP=stampinf -a $(_BUILDARCH)\r
+STAMP=stampinf -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR)\r
 \r
 !INCLUDE mod_ver.def\r
 \r
index bac2dd3d3a213a1f2b42d13738c98e501aed6648..14b64f5188806be61b630bfc34069c78e9bad30e 100644 (file)
@@ -65,7 +65,7 @@ winverbsd.dll = 1,,
 winmad.sys = 1,,\r
 winmad.dll = 1,,\r
 winmadd.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 \r
 [SourceDisksFiles.amd64]\r
@@ -89,7 +89,7 @@ winverbsd.dll = 1,,
 winmad.sys = 1,,\r
 winmad.dll = 1,,\r
 winmadd.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 [SourceDisksFiles.ia64]\r
 mthca.sys=1,,\r
@@ -112,7 +112,7 @@ winverbsd.dll = 1,,
 winmad.sys = 1,,\r
 winmad.dll = 1,,\r
 winmadd.dll = 1,,\r
-WdfCoInstaller01007.dll = 1,,\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll = 1,,\r
 \r
 [Manufacturer]\r
 %MTL% = HCA.DeviceSection,ntx86,ntamd64,ntia64\r
@@ -360,10 +360,10 @@ AddReg = Wdf_CoInstaller_AddReg
 CopyFiles = Wdf_CoInstaller_CopyFiles\r
 \r
 [Wdf_CoInstaller_AddReg]\r
-HKR,, CoInstallers32,0x00010000, "WdfCoInstaller01007.dll,WdfCoInstaller"\r
+HKR,, CoInstallers32,0x00010000, "WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll,WdfCoInstaller"\r
 \r
 [Wdf_CoInstaller_CopyFiles]\r
-WdfCoInstaller01007.dll\r
+WdfCoInstaller$KMDFCOINSTALLERVERSION$.dll\r
 \r
 [MTHCA.DDInstall.ntx86.Wdf]\r
 KmdfService = WinVerbs, WvWdfSect\r
@@ -378,7 +378,7 @@ KmdfService = WinVerbs, WvWdfSect
 KmdfService = WinMad, WvWdfSect\r
 \r
 [WvWdfSect]\r
-KmdfLibraryVersion = 1.7\r
+KmdfLibraryVersion = $KMDFVERSION$\r
 \r
 \r
 ; ============= Uninstall Section =============\r
index 0b425c1feba9bf4d98fe64a71b3c51b846710d8c..0884779fc1f366852222dd0407799fb00e27f521 100644 (file)
@@ -3089,7 +3089,6 @@ typedef union _ual_cep_get_pdata_ioctl
 {\r
        struct _ual_cep_get_pdata_ioctl_in\r
        {\r
-               uint64_t                                h_qp;\r
                net32_t                                 cid;\r
 \r
        }       in;\r
@@ -3106,9 +3105,6 @@ typedef union _ual_cep_get_pdata_ioctl
 }      ual_cep_get_pdata_ioctl_t;\r
 /*\r
 * FIELDS\r
-*      h_qp\r
-*              A handle to the QP to modify.\r
-*\r
 *      in.cid\r
 *              The CID for the target CEP.\r
 *\r
@@ -3483,6 +3479,7 @@ typedef struct _ual_ndi_req_cm_ioctl_in
     ib_path_rec_t               path;\r
        uint64_t                                        h_qp;\r
        net64_t                                         guid;\r
+       net32_t                                         cid;\r
        uint16_t                                        dst_port;\r
     uint8_t                     resp_res;\r
     uint8_t                     init_depth;\r
@@ -3493,7 +3490,7 @@ typedef struct _ual_ndi_req_cm_ioctl_in
 }      ual_ndi_req_cm_ioctl_in_t;\r
 /*\r
 * NOTES\r
-*      The output parameter is the new QP state (RTS).\r
+*      There is no output parameter.\r
 *\r
 * FIELDS\r
 *      h_qp\r
@@ -3502,6 +3499,9 @@ typedef struct _ual_ndi_req_cm_ioctl_in
 *      guid\r
 *              Local port GUID to which to bind to.\r
 *\r
+*      cid\r
+*              CID of the CEP to use for the connection request.\r
+*\r
 *      dst_port\r
 *              Destination port number.\r
 *\r
@@ -3603,38 +3603,6 @@ typedef struct _ual_ndi_rej_cm_ioctl_in
 *\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
-typedef struct _ual_ndi_rtu_cm_ioctl_in\r
-{\r
-       uint64_t                                        h_qp;\r
-\r
-}      ual_ndi_rtu_cm_ioctl_in_t;\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
-*      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
 /****s* User-mode Access Layer/ual_ndi_modify_qp_ioctl_in_t\r
 * NAME\r
 *      ual_ndi_modify_qp_ioctl_in_t\r
index b40572c3aebabd452b7cc8abce6695b8399df36c..1d4ff65ea7fa53aa46fcec65dc545d0b2f54af84 100644 (file)
@@ -11,7 +11,7 @@ IB_MAJORVERSION=2
 !ENDIF\r
 \r
 !IF !DEFINED(IB_MINORVERSION)\r
-IB_MINORVERSION=0\r
+IB_MINORVERSION=1\r
 !ENDIF\r
 \r
 # unused build version field\r
index 94cbaa1f9b2e66412804f2d7185d605cfea76a73..0314e50375c00aeea8ff6ff16df675fcaa3f4d11 100644 (file)
@@ -85,57 +85,74 @@ rem             client RW  4096 1    server RW  2048 4
 rem             server RR  1024 2    client RR  2048 2 \r
 rem             client SR  1024 3 -f server SR   256 3 -f\r
 \r
+if "%T%" == "bench" (\r
+    echo %T%: Threads[1] Endpoints[1] transactions[RW, RR, SR], 64K iterations\r
+       set STIME=!DATE! !TIME!\r
+    %DT% -T T -P -t 1 -w 1 -i 65536 -s %S% -D %D% client RW  4096 4 server RW  2048 4  server RR  4096 2 client RR 4096 2 client SR 1024 2 -f server SR 1024 2 -f\r
+       set ETIME=!DATE! !TIME!\r
+    goto xit\r
+)\r
+\r
 if "%T%" == "conn" (\r
 rem Connectivity test - client sends one buffer with one 4KB segments, one time.\r
 rem add '-d' for debug output.\r
     echo Simple Connectivity test\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -s %S% -D %D% -i 1 -t 1 -w 1 client SR 4096 server SR 4096\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "trans" (\r
     echo %T%: Transaction test - 8192 iterations, 1 thread, SR 4KB buffers\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -s %S% -D %D% -i 8192 -t 1 -w 1 client SR 4096 server SR 4096\r
-    echo Finished %T%: Transaction test - 8192 iterations, 1 thread, SR 4KB buffers\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "transm" (\r
     echo %T%: Multiple RW, RR, SR transactions, 4096 iterations\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -P -t 1 -w 1 -i 4096 -s %S% -D %D% client RW 4096 1 server RW 2048 4  server RR  1024 2 client RR 2048 2 client SR 1024 3 -f server SR 256 3 -f\r
-    echo Finished %T%: Multiple RW, RR, SR transactions, 4096 iterations\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "transt" (\r
     echo %T%: Threads[4] Transaction test - 4096 iterations, 1 thread, SR 4KB buffers\r
+       set STIME=!DATE! !TIME!\r
    %DT% -T T -s %S% -D %D% -i 4096 -t 4 -w 1 client SR 8192 3 server SR 8192 3\r
-    echo Finished %T%: Threads[4] Transaction test - 4096 iterations, 1 thread, SR 4KB buffers\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "transme" (\r
     echo %T%: 1 Thread Endpoints[4] transactions [RW, RR, SR], 4096 iterations\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -P -t 1 -w 4 -i 4096 -s %S% -D %D% client RW  4096 1 server RW  2048 4  server RR  1024 2 client RR 2048 2 client SR 1024 3 -f server SR 256 3 -f\r
-    echo Finished %T%: 1 Thread Endpoints[4] transactions [RW, RR, SR], 4096 iterations\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "transmet" (\r
     echo %T%: Threads[2] Endpoints[4] transactions[RW, RR, SR], 4096 iterations\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -P -t 2 -w 4 -i 4096 -s %S% -D %D% client RW  4096 1 server RW  2048 4  server RR  1024 2 client RR 2048 2 client SR 1024 3 -f server SR 256 3 -f\r
-    echo Finished %T%: Threads[2] Endpoints[4] transactions[RW, RR, SR], 4096 iterations\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "transmete" (\r
     echo %T%: Threads[4] Endpoints[4] transactions[RW, RR, SR], 8192 iterations\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -P -t 2 -w 4 -i 8192 -s %S% -D %D% client RW  4096 1 server RW  2048 4  server RR  1024 2 client RR 2048 2 client SR 1024 3 -f server SR 256 3 -f\r
-    echo Finished %T%: Threads[4] Endpoints[4] transactions[RW, RR, SR], 8192 iterations\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "EPA" (\r
+       set STIME=!DATE! !TIME!\r
     FOR /L %%j IN (2,1,5) DO (\r
         FOR /L %%i IN (1,1,5) DO (\r
              echo %T%: Multi: Threads[%%j] Endpoints[%%i] Send/Recv test - 4096 iterations, 3 8K segs\r
@@ -145,6 +162,7 @@ if "%T%" == "EPA" (
              timeout /T 3\r
         )\r
     )\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
@@ -152,15 +170,17 @@ if "%T%" == "EP" (
     set TH=4\r
     set EP=3\r
     echo %T%: Multi: Threads[!TH!] endpoints[!EP!] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -s %S% -D %D% -i 4096 -t !TH! -w !EP! client SR 8192 3 server SR 8192 3\r
-    echo %T%: Multi: Threads[!TH!] endpoints[!EP!] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "threads" (\r
     echo %T%: Multi Threaded[6] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -s %S% -D %D% -i 4096 -t 6 -w 1 client SR 8192 3 server SR 8192 3\r
-    echo Finished %T%: Multi Threaded[6] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
@@ -168,52 +188,63 @@ if "%T%" == "threadsm" (
     set TH=5\r
     set EP=3\r
     echo %T%: Multi: Threads[!TH!] endpoints[!EP!] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T T -s %S% -D %D% -i 4096 -t !TH! -w !EP! client SR 8192 3 server SR 8192 3\r
-    echo Finished %T%: Multi: Threads[!TH!] endpoints[!EP!] Send/Recv test - 4096 iterations, 3 8K segs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "perf" (\r
     rem echo Performance test\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P %DBG% -s %S% -D %D% -i 2048 RW 4096 2\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "rdma-read" (\r
     echo %T% 4 32K segs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P -s %S% -D %D% -i 4096 RR 32768 4\r
-    echo Finished %T% 4 32K segs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "rdma-write" (\r
     echo %T% 4 32K segs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P -s %S% -D %D% -i 4096 RW 32768 4\r
-    echo Finished %T% 4 32K segs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "bw" (\r
     echo bandwidth 4096 iterations of 2 65K mesgs\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P -s %S% -D %D% -i 4096 -p 16 -m p RW 65536 2 \r
-    echo Finished bandwidth 4096 iterations of 2 65K mesgs\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "latb" (\r
     echo latency test - block for completion events\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P -s %S% -D %D% -i 8192 -p 1 -m b RW 4 1\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "latp" (\r
     echo latency test - poll completion events\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T P -s %S% -D %D% -i 8192 -p 1 -m p RW 4 1\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "lim" (\r
     echo Resource limit tests\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T L -D %D% -w 8 -m 100 limit_ia\r
     %DT% -T L -D %D% -w 8 -m 100 limit_pz\r
     %DT% -T L -D %D% -w 8 -m 100 limit_evd\r
@@ -221,6 +252,7 @@ if "%T%" == "lim" (
     %DT% -T L -D %D% -w 8 -m 100 limit_psp\r
     %DT% -T L -D %D% -w 8 -m 100 limit_lmr\r
     %DT% -T L -D %D% -w 8 -m 15 limit_rpost\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
@@ -234,6 +266,7 @@ if "%T%" == "regression" (
     echo %T% testing in !LPS! Loops\r
     REM rdma-write, read, perf\r
     set RT=trans perf threads threadsm transm transt transme transmet transmete rdma-write rdma-read bw EP\r
+       set STIME=!DATE! !TIME!\r
     FOR /L %%i IN (1,1,!LPS!) DO (\r
        for %%r in ( !RT! ) do (\r
            echo loop %%i - start test %%r\r
@@ -249,6 +282,7 @@ if "%T%" == "regression" (
        echo Finished %T% loop %%i of !LPS!\r
        if %%i LSS !LPS!  timeout /T 8\r
     )\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
@@ -261,6 +295,7 @@ if "%T%" == "interop" (
     )\r
     echo %T% testing in !LPS! Loops\r
     REM test units from Nov-'07 OFA interop event\r
+       set STIME=!DATE! !TIME!\r
     FOR /L %%i IN (1,1,!LPS!) DO (\r
          echo %DT% -T T -s %S% -D %D% -i 4096 -t 1 -w 1 -R BE client SR 256 1 server SR 256 1\r
          %DT% -T T -s %S% -D %D% -i 4096 -t 1 -w 1 -R BE client SR 256 1 server SR 256 1\r
@@ -308,11 +343,14 @@ if "%T%" == "interop" (
          echo %%i %T% loops of !LPS! completed.\r
          if %%i LSS !LPS!  timeout /T 8\r
     )\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
 if "%T%" == "stop" (\r
+       set STIME=!DATE! !TIME!\r
     %DT% -T Q -s %S% -D %D%\r
+       set ETIME=!DATE! !TIME!\r
     goto xit\r
 )\r
 \r
@@ -341,5 +379,11 @@ echo    regression {loopCnt,default=%LPS%} - regression + stress.
 echo    interop {loopCnt,default=%LPS%} - 2007 OFA interoperability event tests.\r
 \r
 :xit\r
+if %ERRORLEVEL% EQU 0 (\r
+       echo +\r
+       echo %0 %*\r
+       echo    Start %STIME% \r
+       echo    End   %ETIME%\r
+)\r
 ENDLOCAL\r
 exit /B %ERRORLEVEL%\r
index cc2173e2bd86538a165f4b650879a59e1bbca1da..e68a71c73003763c3df63ef6b1b26899d9d08588 100644 (file)
@@ -1,68 +1,65 @@
-@echo off
-rem
-rem Sample DAPLtest server - usage: dt-svr [ -D [dbg-bit-mask] ]
-rem
-
-SETLOCAL
-
-rem set DAT_OVERRIDE=C:\DAT\dat.conf
-
-if EXIST "%ProgramFiles(x86)%" (
-    set PF="%ProgramFiles(x86)%\WinOF"
-) else (
-    set PF="%ProgramFiles%\WinOF"
-)
-
-rem Program name of dt-svr preferes dapl2test.exe, otherwise prefer dapltest.exe
-if "%0" == "dt-svr" (
-    if EXIST %PF%\dapl2test.exe (
-        set DT=dapl2test.exe
-        set DEV=ibnic0v2
-        goto OK
-    )
-)
-
-if EXIST %PF%\dapltest.exe (
-        set DT=dapltest.exe
-        set DEV=ibnic0
-        goto OK
-)
-echo Unable to find dapltest.exe or dapl2test.exe?
-exit /B
-
-:OK
-
-rem '-D' enables full debug output
-rem '-D hex-bit-mask' enables selective debug output - see manual.htm for details.
-if "%1" == "-D" (
-    if "%2" == "" (
-        set X=0xfffff
-    ) else (
-        set X=%2
-    )
-) else ( set X= )
-
-if not "%X%" == "" (
-    set DAT_OS_DBG_TYPE=%X%
-    set DAT_DBG_LEVEL=%X%
-    set DAT_DBG_TYPE=%X%
-    set DAPL_DBG_TYPE=%X%
-    set DAPL_DBG_LEVEL=%X%
-) else (
-    set DAT_DBG_TYPE=1
-)
-
-rem    start a dapltest server on the local node - server is waiting for
-rem    dapltest 'client' to issue dapltest commands (dt-cli.bat).
-rem    Client runs 'dt-cli IP-addr stop' to shutdown this dapltest server.
-
-echo %DT% -T S -d -D %DEV%
-
-%DT% -T S -D %DEV%
-
-echo %0 - %DT% server exit...
-
-ENDLOCAL
-
-@echo on
-exit /B
+@echo off\r
+rem\r
+rem Sample DAPLtest server - usage: dt-svr [ -D [dbg-bit-mask] ]\r
+rem\r
+SETLOCAL\r
+\r
+rem set DAT_OVERRIDE=C:\DAT\dat.conf\r
+\r
+if EXIST "%ProgramFiles(x86)%" (\r
+    set PF="%ProgramFiles(x86)%\WinOF"\r
+) else (\r
+    set PF="%ProgramFiles%\WinOF"\r
+)\r
+\r
+rem Program name of dt-svr preferes dapl2test.exe, otherwise prefer dapltest.exe\r
+if "%0" == "dt-svr" (\r
+    if EXIST %PF%\dapl2test.exe (\r
+        set DT=dapl2test.exe\r
+        set DEV=ibnic0v2\r
+        goto OK\r
+    )\r
+)\r
+\r
+if EXIST %PF%\dapltest.exe (\r
+        set DT=dapltest.exe\r
+        set DEV=ibnic0\r
+        goto OK\r
+)\r
+echo Unable to find dapltest.exe or dapl2test.exe?\r
+exit /B\r
+\r
+:OK\r
+\r
+rem '-D' enables full debug output\r
+rem '-D hex-bit-mask' enables selective debug output - see manual.htm for details.\r
+if "%1" == "-D" (\r
+    if "%2" == "" (\r
+        set X=0xfffff\r
+    ) else (\r
+        set X=%2\r
+    )\r
+) else ( set X= )\r
+\r
+if not "%X%" == "" (\r
+    set DAT_OS_DBG_TYPE=%X%\r
+    set DAT_DBG_LEVEL=%X%\r
+    set DAT_DBG_TYPE=%X%\r
+    set DAPL_DBG_TYPE=%X%\r
+    set DAPL_DBG_LEVEL=%X%\r
+) else (\r
+    set DAT_DBG_TYPE=1\r
+)\r
+\r
+rem    start a dapltest server on the local node - server is waiting for\r
+rem    dapltest 'client' to issue dapltest commands (dt-cli.bat).\r
+rem    Client runs 'dt-cli IP-addr stop' to shutdown this dapltest server.\r
+\r
+echo %DT% -T S -d -D %DEV%\r
+\r
+%DT% -T S -D %DEV%\r
+\r
+echo %0 - %DT% server exit...\r
+\r
+ENDLOCAL\r
+exit /B %ERRORLEVEL%\r
diff --git a/branches/winverbs/ulp/nd/user/NdAdapter.cpp b/branches/winverbs/ulp/nd/user/NdAdapter.cpp
new file mode 100644 (file)
index 0000000..a174d94
--- /dev/null
@@ -0,0 +1,950 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdCq.h"\r
+#include "NdAdapter.h"\r
+#include "NdMw.h"\r
+#include "NdEndpoint.h"\r
+#include "NdProv.h"\r
+#include "NdMr.h"\r
+#include "NdListen.h"\r
+#include "NdConnector.h"\r
+\r
+#include "al_dev.h"\r
+#pragma warning( push, 3 )\r
+#include "winternl.h"\r
+#pragma warning( pop )\r
+\r
+#include <assert.h>\r
+#include <limits.h>\r
+#include <strsafe.h>\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdAdapter.tmh"\r
+#endif\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// HPC Pack 2008 Beta 2 SPI\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+CAdapter::CAdapter(void) :\r
+    m_nRef( 1 ),\r
+    m_hSync( INVALID_HANDLE_VALUE ),\r
+    m_hAsync( INVALID_HANDLE_VALUE ),\r
+    m_hCa( 0 ),\r
+    m_hPd( 0 ),\r
+    m_uCa( NULL ),\r
+    m_uPd( NULL ),\r
+    m_pParent( NULL )\r
+{\r
+    m_Ifc.h_uvp_lib = NULL;\r
+}\r
+\r
+CAdapter::~CAdapter(void)\r
+{\r
+    if( m_hPd )\r
+        DeallocPd();\r
+\r
+    if( m_hCa )\r
+        CloseCa();\r
+\r
+    if( m_hSync != INVALID_HANDLE_VALUE )\r
+        CloseHandle( m_hSync );\r
+\r
+    if( m_hAsync != INVALID_HANDLE_VALUE )\r
+        CloseHandle( m_hAsync );\r
+\r
+    if( m_pParent )\r
+        m_pParent->Release();\r
+}\r
+\r
+HRESULT CAdapter::Initialize(\r
+    CProvider* pParent,\r
+    const struct sockaddr* pAddr,\r
+    const IBAT_PORT_RECORD* pPortRecord )\r
+{\r
+    m_pParent = pParent;\r
+    m_pParent->AddRef();\r
+\r
+    HRESULT hr = OpenFiles();\r
+    if( FAILED( hr ) )\r
+        return hr;\r
+\r
+    hr = OpenCa( pPortRecord->CaGuid );\r
+    if( FAILED( hr ) )\r
+        return hr;\r
+\r
+    hr = AllocPd();\r
+    if( FAILED( hr ) )\r
+        return hr;\r
+\r
+    m_PortNum = pPortRecord->PortNum;\r
+    m_PortGuid = pPortRecord->PortGuid;\r
+\r
+    switch( pAddr->sa_family )\r
+    {\r
+    case AF_INET:\r
+        RtlCopyMemory( &m_Addr.v4, pAddr, sizeof(m_Addr.v4) );\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("Local address: IP %#x, port %#hx\n", \r
+            cl_hton32(m_Addr.v4.sin_addr.S_un.S_addr), cl_hton16(m_Addr.v4.sin_port) ) );\r
+        break;\r
+    case AF_INET6:\r
+        RtlCopyMemory( &m_Addr.v6, pAddr, sizeof(m_Addr.v6) );\r
+        break;\r
+    default:\r
+        return ND_INVALID_ADDRESS;\r
+    }\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CAdapter::Create(\r
+    CProvider* pParent,\r
+    const struct sockaddr* pAddr,\r
+    const IBAT_PORT_RECORD* pPortRecord,\r
+    __out INDAdapter** ppAdapter\r
+    )\r
+{\r
+    CAdapter* pAdapter = new CAdapter();\r
+    if( pAdapter == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    HRESULT hr = pAdapter->Initialize( pParent, pAddr, pPortRecord );\r
+    if( FAILED( hr ) )\r
+    {\r
+        delete pAdapter;\r
+        return hr;\r
+    }\r
+\r
+    *ppAdapter = pAdapter;\r
+    return ND_SUCCESS;\r
+}\r
+\r
+// IUnknown overrides.\r
+HRESULT CAdapter::QueryInterface(\r
+    const IID &riid,\r
+    LPVOID FAR *ppvObj )\r
+{\r
+    if( IsEqualIID( riid, IID_IUnknown ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    if( IsEqualIID( riid, IID_INDAdapter ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    return E_NOINTERFACE;\r
+}\r
+\r
+ULONG CAdapter::AddRef(void)\r
+{\r
+    return InterlockedIncrement( &m_nRef );\r
+}\r
+\r
+ULONG CAdapter::Release(void)\r
+{\r
+    ULONG ref = InterlockedDecrement( &m_nRef );\r
+    if( ref == 0 )\r
+        delete this;\r
+\r
+    return ref;\r
+}\r
+\r
+// *** INDOverlapped methods ***\r
+HRESULT CAdapter::CancelOverlappedRequests(void)\r
+{\r
+    // Memory registration IOCTLs can't be cancelled.\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CAdapter::GetOverlappedResult(\r
+    __inout OVERLAPPED *pOverlapped,\r
+    __out SIZE_T *pNumberOfBytesTransferred,\r
+    __in BOOL bWait\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    *pNumberOfBytesTransferred = 0;\r
+    ::GetOverlappedResult(\r
+        m_hAsync,\r
+        pOverlapped,\r
+        (DWORD*)pNumberOfBytesTransferred,\r
+        bWait );\r
+    return (HRESULT)pOverlapped->Internal;\r
+}\r
+\r
+// INDAdapter overrides.\r
+HANDLE CAdapter::GetFileHandle(void)\r
+{\r
+    return m_hAsync;\r
+}\r
+\r
+HRESULT CAdapter::Query(\r
+    __in DWORD VersionRequested,\r
+    __out_bcount_part_opt(*pBufferSize, *pBufferSize) ND_ADAPTER_INFO* pInfo,\r
+    __inout_opt SIZE_T* pBufferSize\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( VersionRequested != 1 )\r
+        return ND_NOT_SUPPORTED;\r
+\r
+    if( *pBufferSize < sizeof(ND_ADAPTER_INFO1) )\r
+    {\r
+        *pBufferSize = sizeof(ND_ADAPTER_INFO1);\r
+        return ND_BUFFER_OVERFLOW;\r
+    }\r
+\r
+    ib_ca_attr_t* pAttr = NULL;\r
+    DWORD size = 0;\r
+    HRESULT hr = QueryCa( pAttr, &size );\r
+    if( hr != ND_BUFFER_OVERFLOW )\r
+        return hr;\r
+\r
+    pAttr = (ib_ca_attr_t*)HeapAlloc( GetProcessHeap(), 0, size );\r
+    if( !pAttr )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    hr = QueryCa( pAttr, &size );\r
+    if( FAILED( hr ) )\r
+    {\r
+        HeapFree( GetProcessHeap(), 0, pAttr );\r
+        return hr;\r
+    }\r
+\r
+    pInfo->MaxInboundSge = pAttr->max_sges;\r
+    pInfo->MaxInboundRequests = pAttr->max_wrs;\r
+    pInfo->MaxInboundLength = INT_MAX;\r
+    pInfo->MaxOutboundSge = pAttr->max_sges;\r
+    pInfo->MaxOutboundRequests = pAttr->max_wrs;\r
+    pInfo->MaxOutboundLength = INT_MAX;\r
+    pInfo->MaxInboundReadLimit = pAttr->max_qp_resp_res;\r
+    pInfo->MaxOutboundReadLimit = pAttr->max_qp_init_depth;\r
+    pInfo->MaxCqEntries = pAttr->max_cqes;\r
+#ifndef SIZE_MAX\r
+#ifdef _WIN64\r
+#define SIZE_MAX _UI64_MAX\r
+#else\r
+#define SIZE_MAX UINT_MAX\r
+#endif\r
+#endif\r
+    if( pAttr->init_region_size > SIZE_MAX )\r
+        pInfo->MaxRegistrationSize = SIZE_MAX;\r
+    else\r
+        pInfo->MaxRegistrationSize = (SIZE_T)pAttr->init_region_size;\r
+    pInfo->MaxWindowSize = pInfo->MaxRegistrationSize;\r
+    pInfo->LargeRequestThreshold = 16 * 1024;\r
+    pInfo->MaxCallerData = 56;\r
+    pInfo->MaxCalleeData = 148;\r
+    *pBufferSize = sizeof(ND_ADAPTER_INFO1);\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CAdapter::Control(\r
+    __in DWORD IoControlCode,\r
+    __in_bcount_opt(InBufferSize) const void* pInBuffer,\r
+    __in SIZE_T InBufferSize,\r
+    __out_bcount_opt(OutBufferSize) void* pOutBuffer,\r
+    __in SIZE_T OutBufferSize,\r
+    __out SIZE_T* pBytesReturned,\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    UNREFERENCED_PARAMETER( IoControlCode );\r
+    UNREFERENCED_PARAMETER( pInBuffer );\r
+    UNREFERENCED_PARAMETER( InBufferSize );\r
+    UNREFERENCED_PARAMETER( pOutBuffer );\r
+    UNREFERENCED_PARAMETER( OutBufferSize );\r
+    UNREFERENCED_PARAMETER( pBytesReturned );\r
+    UNREFERENCED_PARAMETER( pOverlapped );\r
+    \r
+    return ND_NOT_SUPPORTED;\r
+}\r
+\r
+HRESULT CAdapter::CreateCompletionQueue(\r
+    __in SIZE_T nEntries,\r
+    __deref_out INDCompletionQueue** ppCq\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    CCq* pCq = new CCq();\r
+    if( pCq == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    HRESULT hr = pCq->Initialize( this, nEntries );\r
+    if( FAILED(hr) )\r
+    {\r
+        delete pCq;\r
+        return hr;\r
+    }\r
+\r
+    *ppCq = pCq;\r
+    return S_OK;\r
+}\r
+\r
+\r
+HRESULT CAdapter::RegisterMemory(\r
+    __in_bcount(BufferSize) const void* pBuffer,\r
+    __in SIZE_T BufferSize,\r
+    __inout OVERLAPPED* pOverlapped,\r
+    __deref_out ND_MR_HANDLE* phMr\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    /* Get a MR tracking structure. */\r
+    CMr* pMr = new CMr();\r
+    if( pMr == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    pMr->pBase = (const char*)pBuffer;\r
+\r
+    if( BufferSize > ULONG_MAX )\r
+        return ND_INVALID_PARAMETER_2;\r
+    pMr->Length = (uint32_t)BufferSize;\r
+\r
+    /* Clear the mr_ioctl */\r
+    pMr->mr_ioctl.in.h_pd = m_hPd;\r
+    pMr->mr_ioctl.in.mem_create.vaddr_padding = (ULONG_PTR)pBuffer;\r
+    pMr->mr_ioctl.in.mem_create.length = BufferSize;\r
+    // No support for MWs yet, so simulate it.\r
+    pMr->mr_ioctl.in.mem_create.access_ctrl =\r
+        IB_AC_RDMA_READ | IB_AC_RDMA_WRITE | IB_AC_LOCAL_WRITE;\r
+\r
+    *phMr = (ND_MR_HANDLE)pMr;\r
+    //\r
+    // We must issue the IOCTL on the synchronous file handle.\r
+    // If the user bound the async file handle to an I/O completion port\r
+    // DeviceIoControl could succeed, but not return data, so the MR\r
+    // wouldn't be updated.\r
+    //\r
+    // We use a second IOCTL to complet the user's overlapped.\r
+    //\r
+    DWORD bytes_ret = 0;\r
+    BOOL ret = DeviceIoControl( m_hSync, UAL_REG_MR,\r
+        &pMr->mr_ioctl.in, sizeof(pMr->mr_ioctl.in),\r
+        &pMr->mr_ioctl.out, sizeof(pMr->mr_ioctl.out),\r
+        &bytes_ret, NULL );\r
+    if( !ret )\r
+    {\r
+        CL_ASSERT( GetLastError() != ERROR_IO_PENDING );\r
+\r
+        delete pMr;\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+    if( bytes_ret != sizeof(pMr->mr_ioctl.out) || \r
+        pMr->mr_ioctl.out.status != IB_SUCCESS )\r
+    {\r
+        delete pMr;\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+\r
+    //\r
+    // The registration succeeded.  Now issue the user's IOCTL.\r
+    //\r
+    pOverlapped->Internal = ND_PENDING;\r
+    HRESULT hr = NtDeviceIoControlFile(\r
+        m_hAsync,\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_NOOP,\r
+        NULL,\r
+        0,\r
+        NULL,\r
+        0 );\r
+\r
+    if( hr != ND_PENDING && hr != ND_SUCCESS )\r
+    {\r
+        delete pMr;\r
+        return hr;\r
+    }\r
+\r
+    AddRef();\r
+    return ND_SUCCESS;\r
+}\r
+\r
+HRESULT CAdapter::DeregisterMemory(\r
+    __in ND_MR_HANDLE hMr,\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    CMr* pMr = (CMr*)hMr;\r
+\r
+    //\r
+    // We must issue the IOCTL on the synchronous file handle.\r
+    // If the user bound the async file handle to an I/O completion port\r
+    // DeviceIoControl could succeed, but not return data, so the MR\r
+    // wouldn't be updated.\r
+    //\r
+    // We use a second IOCTL to complet the user's overlapped.\r
+    //\r
+    DWORD bytes_ret = 0;\r
+    BOOL ret = DeviceIoControl( m_hSync, UAL_DEREG_MR,\r
+        &pMr->mr_ioctl.out.h_mr, sizeof(pMr->mr_ioctl.out.h_mr),\r
+        &pMr->mr_ioctl.out.status, sizeof(pMr->mr_ioctl.out.status),\r
+        &bytes_ret, NULL );\r
+    if( !ret )\r
+    {\r
+        CL_ASSERT( GetLastError() != ERROR_IO_PENDING );\r
+        pMr->mr_ioctl.out.status = IB_ERROR;\r
+    }\r
+    if( bytes_ret != sizeof(pMr->mr_ioctl.out.status) )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    switch( pMr->mr_ioctl.out.status )\r
+    {\r
+    case IB_SUCCESS:\r
+        {\r
+        delete pMr;\r
+        Release();\r
+\r
+        //\r
+        // The deregistration succeeded.  Now issue the user's IOCTL.\r
+        //\r
+        pOverlapped->Internal = ND_PENDING;\r
+        HRESULT hr = NtDeviceIoControlFile(\r
+            m_hAsync,\r
+            pOverlapped->hEvent,\r
+            NULL,\r
+            (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+            (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+            UAL_NDI_NOOP,\r
+            NULL,\r
+            0,\r
+            NULL,\r
+            0 );\r
+        CL_ASSERT( SUCCEEDED( hr ) );\r
+        return hr;\r
+        }\r
+    case IB_RESOURCE_BUSY:\r
+        return ND_DEVICE_BUSY;\r
+\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CAdapter::CreateMemoryWindow(\r
+    __out ND_RESULT* pInvalidateResult,\r
+    __deref_out INDMemoryWindow** ppMw\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    CMw* pMw = new CMw();\r
+    if( pMw == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    HRESULT hr = pMw->Initialize( this, pInvalidateResult );\r
+    if( FAILED(hr) )\r
+    {\r
+        delete pMw;\r
+        return hr;\r
+    }\r
+\r
+    *ppMw = pMw;\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CAdapter::CreateConnector(\r
+    __deref_out INDConnector** ppConnector\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    return CConnector::Create( this, ppConnector );\r
+}\r
+\r
+HRESULT CAdapter::Listen(\r
+    __in SIZE_T Backlog,\r
+    __in INT Protocol,\r
+    __in USHORT Port,\r
+    __out_opt USHORT* pAssignedPort,\r
+    __deref_out INDListen** ppListen\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    return CListen::Create(\r
+        this,\r
+        Backlog,\r
+        Protocol,\r
+        Port,\r
+        pAssignedPort,\r
+        ppListen\r
+        );\r
+}\r
+\r
+HRESULT CAdapter::GetLocalAddress(\r
+    __out_bcount_part(*pAddressLength, *pAddressLength) struct sockaddr *pAddr,\r
+    __inout SIZE_T *pAddressLength )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    switch( m_Addr.v4.sin_family )\r
+    {\r
+    case AF_INET:\r
+        if( *pAddressLength < sizeof(struct sockaddr_in) )\r
+        {\r
+            *pAddressLength = sizeof(struct sockaddr_in);\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        *(struct sockaddr_in*)pAddr = m_Addr.v4;\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("Local address: IP %#x, port %#hx\n", \r
+            cl_hton32(m_Addr.v4.sin_addr.S_un.S_addr), cl_hton16(m_Addr.v4.sin_port) ) );\r
+        return S_OK;\r
+\r
+    case AF_INET6:\r
+        if( *pAddressLength < sizeof(struct sockaddr_in6) )\r
+        {\r
+            *pAddressLength = sizeof(struct sockaddr_in6);\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        *(struct sockaddr_in6*)pAddr = m_Addr.v6;\r
+        return S_OK;\r
+\r
+    default:\r
+        return ND_INVALID_ADDRESS;\r
+    }\r
+}\r
+\r
+HRESULT CAdapter::OpenFiles(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    /* First open the kernel device. */\r
+    CL_ASSERT( m_hSync == INVALID_HANDLE_VALUE );\r
+    m_hSync = CreateFile(\r
+        "\\\\.\\ibal",\r
+        GENERIC_READ | GENERIC_WRITE,\r
+        FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+        NULL,\r
+        OPEN_EXISTING,\r
+        0,\r
+        NULL\r
+        );\r
+    if( m_hSync == INVALID_HANDLE_VALUE )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    // Now issue the BIND IOCTL which associates us as a client.\r
+    ULONG ver = AL_IOCTL_VERSION;\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_BIND,\r
+        &ver,\r
+        sizeof(ver),\r
+        NULL,\r
+        0,\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+    if( fSuccess != TRUE )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    // Now create the async file.\r
+    m_hAsync = CreateFile(\r
+        "\\\\.\\ibal",\r
+        GENERIC_READ | GENERIC_WRITE,\r
+        FILE_SHARE_READ | FILE_SHARE_WRITE,\r
+        NULL,\r
+        OPEN_EXISTING,\r
+        FILE_FLAG_OVERLAPPED,\r
+        NULL\r
+        );\r
+    if( m_hAsync == INVALID_HANDLE_VALUE )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    /*\r
+     * Send an IOCTL down on the main file handle to bind this file\r
+     * handle with our proxy context.\r
+     */\r
+    UINT64 hFile = (ULONG_PTR)m_hAsync;\r
+    fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_BIND_ND,\r
+        &hFile,\r
+        sizeof(hFile),\r
+        NULL,\r
+        0,\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+    if( fSuccess != TRUE )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CAdapter::OpenCa(\r
+    __in UINT64 CaGuid )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    ual_get_uvp_name_ioctl_t   al_ioctl;\r
+\r
+    /* Initialize assuming no user-mode support */\r
+    cl_memclr( &al_ioctl, sizeof(al_ioctl) );\r
+    cl_memclr( &m_Ifc, sizeof(m_Ifc) );\r
+\r
+    /* init with the guid */\r
+    m_Ifc.guid = CaGuid;\r
+\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_GET_VENDOR_LIBCFG,\r
+        &CaGuid, sizeof(CaGuid),\r
+        &al_ioctl.out, sizeof(al_ioctl.out),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess != TRUE || BytesRet != sizeof(al_ioctl.out) )\r
+        return ND_INSUFFICIENT_RESOURCES;\r
+\r
+    if( !strlen( al_ioctl.out.uvp_lib_name ) )\r
+    {\r
+        /* Vendor does not implement user-mode library */\r
+        return ND_NOT_SUPPORTED;\r
+    }\r
+\r
+    /*\r
+     * The vendor supports a user-mode library\r
+     * open the library and get the interfaces supported\r
+     */\r
+#if DBG\r
+    HRESULT hr = StringCbCatA( al_ioctl.out.uvp_lib_name, 32, "d.dll" );\r
+#else\r
+    HRESULT hr = StringCbCatA( al_ioctl.out.uvp_lib_name, 32, ".dll" );\r
+#endif\r
+    if( FAILED( hr ) )\r
+        return ND_NOT_SUPPORTED;\r
+\r
+    m_Ifc.h_uvp_lib = LoadLibrary( al_ioctl.out.uvp_lib_name );\r
+    if( m_Ifc.h_uvp_lib == NULL )\r
+        return ND_NOT_SUPPORTED;\r
+\r
+    uvp_get_interface_t pfn_uvp_ifc = (uvp_get_interface_t)GetProcAddress(\r
+        m_Ifc.h_uvp_lib,\r
+        "uvp_get_interface"\r
+        );\r
+\r
+    if( pfn_uvp_ifc == NULL )\r
+        return ND_NOT_SUPPORTED;\r
+\r
+    /* Query the vendor-supported user-mode functions */\r
+    pfn_uvp_ifc( IID_UVP, &m_Ifc.user_verbs );\r
+\r
+    ual_open_ca_ioctl_t ca_ioctl;\r
+    cl_memclr( &ca_ioctl, sizeof(ca_ioctl) );\r
+\r
+    /* Pre call to the UVP library */\r
+    ib_api_status_t status = IB_ERROR;\r
+    if( m_Ifc.user_verbs.pre_open_ca )\r
+    {\r
+        status = m_Ifc.user_verbs.pre_open_ca(\r
+            CaGuid,\r
+            &ca_ioctl.in.umv_buf,\r
+            (ib_ca_handle_t*)(ULONG_PTR)&m_uCa\r
+            );\r
+        if( status != IB_SUCCESS )\r
+        {\r
+            CL_ASSERT( status != IB_VERBS_PROCESSING_DONE );\r
+            return ND_INSUFFICIENT_RESOURCES;\r
+        }\r
+    }\r
+\r
+    ca_ioctl.in.guid = CaGuid;\r
+    ca_ioctl.in.context = (ULONG_PTR)this;\r
+\r
+    fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_OPEN_CA,\r
+        &ca_ioctl.in,\r
+        sizeof(ca_ioctl.in),\r
+        &ca_ioctl.out,\r
+        sizeof(ca_ioctl.out),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess != TRUE || BytesRet != sizeof(ca_ioctl.out) )\r
+    {\r
+        status = IB_ERROR;\r
+    }\r
+    else\r
+    {\r
+        status = ca_ioctl.out.status;\r
+        m_hCa = ca_ioctl.out.h_ca;\r
+    }\r
+\r
+    /* Post uvp call */\r
+    if( m_Ifc.user_verbs.post_open_ca )\r
+    {\r
+        status = m_Ifc.user_verbs.post_open_ca(\r
+            CaGuid,\r
+            status,\r
+            (ib_ca_handle_t*)(ULONG_PTR)&m_uCa,\r
+            &ca_ioctl.out.umv_buf );\r
+    }\r
+\r
+    // TODO: Does the UVP need a query call to succeed?\r
+    // IBAL always does this internally.\r
+\r
+    return (status == IB_SUCCESS? S_OK : ND_INSUFFICIENT_RESOURCES );\r
+}\r
+\r
+HRESULT CAdapter::QueryCa(\r
+        __out_bcount(*pSize) ib_ca_attr_t* pAttr,\r
+        __inout DWORD* pSize )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    ual_query_ca_ioctl_t ca_ioctl;\r
+\r
+    cl_memclr( &ca_ioctl, sizeof(ca_ioctl) );\r
+\r
+    ca_ioctl.in.h_ca = m_hCa;\r
+    ca_ioctl.in.p_ca_attr = (ULONG_PTR)pAttr;\r
+    ca_ioctl.in.byte_cnt = *pSize;\r
+\r
+    /* Call the uvp pre call if the vendor library provided a valid ca handle */\r
+    ib_api_status_t status;\r
+    if( m_uCa && m_Ifc.user_verbs.pre_query_ca )\r
+    {\r
+        /* Pre call to the UVP library */\r
+        status = m_Ifc.user_verbs.pre_query_ca(\r
+            m_uCa, pAttr, *pSize, &ca_ioctl.in.umv_buf );\r
+        if( status != IB_SUCCESS )\r
+            return ND_UNSUCCESSFUL;\r
+    }\r
+\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_QUERY_CA,\r
+        &ca_ioctl.in,\r
+        sizeof(ca_ioctl.in),\r
+        &ca_ioctl.out,\r
+        sizeof(ca_ioctl.out),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+    if( fSuccess != TRUE || BytesRet != sizeof(ca_ioctl.out) )\r
+    {\r
+        status = IB_ERROR;\r
+    }\r
+    else\r
+    {\r
+        *pSize = ca_ioctl.out.byte_cnt;\r
+        status = ca_ioctl.out.status;\r
+    }\r
+\r
+    /* The attributes, if any, will be directly copied by proxy */\r
+    /* Post uvp call */\r
+    if( m_uCa && m_Ifc.user_verbs.post_query_ca )\r
+    {\r
+        m_Ifc.user_verbs.post_query_ca( m_uCa,\r
+            status, pAttr, ca_ioctl.out.byte_cnt, &ca_ioctl.out.umv_buf );\r
+    }\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_MEMORY:\r
+        return ND_BUFFER_OVERFLOW;\r
+    default:\r
+        return ND_INSUFFICIENT_RESOURCES;\r
+    }\r
+}\r
+\r
+void CAdapter::CloseCa(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    ib_api_status_t status;\r
+\r
+    /* Call the uvp pre call if the vendor library provided a valid ca handle */\r
+    if( m_uCa && m_Ifc.user_verbs.pre_close_ca )\r
+    {\r
+        /* Pre call to the UVP library */\r
+        status = m_Ifc.user_verbs.pre_close_ca( m_uCa );\r
+        if( status != IB_SUCCESS )\r
+            return;\r
+    }\r
+\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_CLOSE_CA,\r
+        &m_hCa,\r
+        sizeof(m_hCa),\r
+        &status,\r
+        sizeof(status),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess != TRUE || BytesRet != sizeof(status) )\r
+        status = IB_ERROR;\r
+\r
+    if( m_uCa && m_Ifc.user_verbs.post_close_ca )\r
+        m_Ifc.user_verbs.post_close_ca( m_uCa, status );\r
+\r
+    if( m_Ifc.h_uvp_lib )\r
+        FreeLibrary( m_Ifc.h_uvp_lib );\r
+\r
+    m_hCa = 0;\r
+}\r
+\r
+HRESULT CAdapter::AllocPd(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    /* Clear the pd_ioctl */\r
+    ual_alloc_pd_ioctl_t pd_ioctl;\r
+    cl_memclr( &pd_ioctl, sizeof(pd_ioctl) );\r
+\r
+    /* Pre call to the UVP library */\r
+    ib_api_status_t status;\r
+    if( m_uCa && m_Ifc.user_verbs.pre_allocate_pd )\r
+    {\r
+        status = m_Ifc.user_verbs.pre_allocate_pd(\r
+            m_uCa,\r
+            &pd_ioctl.in.umv_buf,\r
+            (ib_pd_handle_t*)(ULONG_PTR)&m_uPd\r
+            );\r
+        if( status != IB_SUCCESS )\r
+            return ND_INSUFFICIENT_RESOURCES;\r
+    }\r
+\r
+    pd_ioctl.in.h_ca = m_hCa;\r
+    pd_ioctl.in.type = IB_PDT_NORMAL;\r
+    pd_ioctl.in.context = (ULONG_PTR)this;\r
+\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_ALLOC_PD,\r
+        &pd_ioctl.in,\r
+        sizeof(pd_ioctl.in),\r
+        &pd_ioctl.out,\r
+        sizeof(pd_ioctl.out),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess != TRUE || BytesRet != sizeof(pd_ioctl.out) )\r
+    {\r
+        status = IB_ERROR;\r
+    }\r
+    else\r
+    {\r
+        status = pd_ioctl.out.status;\r
+        if( pd_ioctl.out.status == IB_SUCCESS )\r
+            m_hPd = pd_ioctl.out.h_pd;\r
+    }\r
+\r
+    /* Post uvp call */\r
+    if( m_uCa && m_Ifc.user_verbs.post_allocate_pd )\r
+    {\r
+        m_Ifc.user_verbs.post_allocate_pd(\r
+            m_uCa,\r
+            status,\r
+            (ib_pd_handle_t*)(ULONG_PTR)&m_uPd,\r
+            &pd_ioctl.out.umv_buf );\r
+    }\r
+\r
+    return (status == IB_SUCCESS? S_OK : ND_INSUFFICIENT_RESOURCES);\r
+}\r
+\r
+void CAdapter::DeallocPd(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    ib_api_status_t                    status;\r
+\r
+    /* Call the uvp pre call if the vendor library provided a valid ca handle */\r
+    if( m_uPd && m_Ifc.user_verbs.pre_deallocate_pd )\r
+    {\r
+        /* Pre call to the UVP library */\r
+        status = m_Ifc.user_verbs.pre_deallocate_pd( m_uPd );\r
+        if( status != IB_SUCCESS )\r
+            return;\r
+    }\r
+\r
+    DWORD BytesRet;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_hSync,\r
+        UAL_DEALLOC_PD,\r
+        &m_hPd,\r
+        sizeof(m_hPd),\r
+        &status,\r
+        sizeof(status),\r
+        &BytesRet,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess == FALSE || BytesRet != sizeof(status) )\r
+        status = IB_ERROR;\r
+\r
+    /* Call vendor's post_close ca */\r
+    if( m_uPd && m_Ifc.user_verbs.post_deallocate_pd )\r
+        m_Ifc.user_verbs.post_deallocate_pd( m_uPd, status );\r
+\r
+    m_hPd = 0;\r
+}\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdAdapter.h b/branches/winverbs/ulp/nd/user/NdAdapter.h
new file mode 100644 (file)
index 0000000..79b79e0
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "ndspi.h"\r
+#include "nddebug.h"\r
+#include <iba/ib_al.h>\r
+#include <iba/ib_at_ioctl.h>\r
+#include <ws2tcpip.h>\r
+#include "ual_ci_ca.h"\r
+\r
+#include "NdProv.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+class CCq;\r
+class CAddr;\r
+class CProvider;\r
+\r
+class CAdapter :\r
+    public INDAdapter\r
+{\r
+    friend class CCq;\r
+    friend class CEndpoint;\r
+    friend class CConnector;\r
+    friend class CMw;\r
+    friend class CMr;\r
+    friend class CListen;\r
+\r
+private:\r
+    CAdapter(void);\r
+    ~CAdapter(void);\r
+\r
+    HRESULT Initialize(\r
+        CProvider* pParent,\r
+        const struct sockaddr* pAddr,\r
+        const IBAT_PORT_RECORD* pPortRecord\r
+        );\r
+\r
+public:\r
+    static HRESULT Create(\r
+        CProvider* pParent,\r
+        const struct sockaddr* pAddr,\r
+        const IBAT_PORT_RECORD* pPortRecord,\r
+        __out INDAdapter** ppAdapter\r
+        );\r
+\r
+    // *** IUnknown methods ***\r
+    HRESULT STDMETHODCALLTYPE QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        );\r
+\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // *** INDOverlapped methods ***\r
+    HRESULT STDMETHODCALLTYPE CancelOverlappedRequests(void);\r
+\r
+    HRESULT STDMETHODCALLTYPE GetOverlappedResult(\r
+        __inout OVERLAPPED *pOverlapped,\r
+        __out SIZE_T *pNumberOfBytesTransferred,\r
+        __in BOOL bWait\r
+        );\r
+\r
+    // *** INDAdapter methods ***\r
+    HANDLE STDMETHODCALLTYPE GetFileHandle(void);\r
+\r
+    HRESULT STDMETHODCALLTYPE Query(\r
+        __in DWORD VersionRequested,\r
+        __out_bcount_part_opt(*pBufferSize, *pBufferSize) ND_ADAPTER_INFO* pInfo,\r
+        __inout_opt SIZE_T* pBufferSize\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Control(\r
+        __in DWORD IoControlCode,\r
+        __in_bcount_opt(InBufferSize) const void* pInBuffer,\r
+        __in SIZE_T InBufferSize,\r
+        __out_bcount_opt(OutBufferSize) void* pOutBuffer,\r
+        __in SIZE_T OutBufferSize,\r
+        __out SIZE_T* pBytesReturned,\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CreateCompletionQueue(\r
+        __in SIZE_T nEntries,\r
+        __deref_out INDCompletionQueue** ppCq\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE RegisterMemory(\r
+        __in_bcount(BufferSize) const void* pBuffer,\r
+        __in SIZE_T BufferSize,\r
+        __inout OVERLAPPED* pOverlapped,\r
+        __deref_out ND_MR_HANDLE* phMr\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CompleteRegisterMemory(\r
+        __in ND_MR_HANDLE hMr,\r
+        __in OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE DeregisterMemory(\r
+        __in ND_MR_HANDLE hMr,\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CompleteDeregisterMemory(\r
+        __in ND_MR_HANDLE hMr,\r
+        __in OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CreateMemoryWindow(\r
+        __out ND_RESULT* pInvalidateResult,\r
+        __deref_out INDMemoryWindow** ppMw\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CreateConnector(\r
+        __deref_out INDConnector** ppConnector\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Listen(\r
+        __in SIZE_T Backlog,\r
+        __in INT Protocol,\r
+        __in USHORT Port,\r
+        __out_opt USHORT* pAssignedPort,\r
+        __deref_out INDListen** ppListen\r
+        );\r
+\r
+    HRESULT GetLocalAddress(\r
+        __out_bcount_part(*pAddressLength, *pAddressLength) struct sockaddr* pAddr,\r
+        __inout SIZE_T *pAddressLength );\r
+\r
+private:\r
+    HRESULT OpenFiles(void);\r
+\r
+    HRESULT OpenCa(\r
+        __in UINT64 CaGuid\r
+        );\r
+\r
+    HRESULT QueryCa(\r
+        __out_bcount(*pSize) ib_ca_attr_t* pAttr,\r
+        __inout DWORD* pSize\r
+        );\r
+\r
+    void CloseCa(void);\r
+\r
+    HRESULT AllocPd(void);\r
+\r
+    void DeallocPd(void);\r
+\r
+protected:\r
+    volatile LONG m_nRef;\r
+\r
+    CProvider* m_pParent;\r
+    UINT64 m_PortGuid;\r
+    UINT8 m_PortNum;\r
+\r
+    HANDLE m_hSync;\r
+    HANDLE m_hAsync;\r
+\r
+    ual_ci_interface_t m_Ifc;\r
+    // Kernel IBAL handles.\r
+    uint64_t m_hCa;\r
+    uint64_t m_hPd;\r
+    // UVP handles.\r
+    ib_ca_handle_t m_uCa;\r
+    ib_pd_handle_t m_uPd;\r
+\r
+    union _addr\r
+    {\r
+        struct sockaddr unspec;\r
+        struct sockaddr_in v4;\r
+        struct sockaddr_in6 v6;\r
+\r
+    } m_Addr;\r
+};\r
+\r
+} // namespace
\ No newline at end of file
diff --git a/branches/winverbs/ulp/nd/user/NdConnector.cpp b/branches/winverbs/ulp/nd/user/NdConnector.cpp
new file mode 100644 (file)
index 0000000..3cb4aa2
--- /dev/null
@@ -0,0 +1,935 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdCq.h"\r
+#include "NdAdapter.h"\r
+#include "NdMw.h"\r
+#include "NdEndpoint.h"\r
+#include "NdProv.h"\r
+#include "NdMr.h"\r
+#include "NdListen.h"\r
+#include "NdConnector.h"\r
+\r
+#include "al_dev.h"\r
+#pragma warning( push, 3 )\r
+#include "winternl.h"\r
+#pragma warning( pop )\r
+#include "iba/ibat.h"\r
+\r
+#include <assert.h>\r
+#include <limits.h>\r
+#include <strsafe.h>\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdConnector.tmh"\r
+#endif\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+CConnector::CConnector(void) :\r
+    m_nRef( 1 ),\r
+    m_pParent( NULL ),\r
+    m_pEndpoint( NULL ),\r
+    m_Protocol( 0 ),\r
+    m_LocalPort( 0 ),\r
+    m_cid( 0 ),\r
+    m_fActive( false )\r
+{\r
+}\r
+\r
+CConnector::~CConnector(void)\r
+{\r
+    FreeCid();\r
+\r
+    if( m_pEndpoint )\r
+        m_pEndpoint->Release();\r
+\r
+    if( m_pParent )\r
+        m_pParent->Release();\r
+}\r
+\r
+void CConnector::FreeCid(void)\r
+{\r
+    if( m_cid != 0 )\r
+    {\r
+        DWORD bytes_ret;\r
+        DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_DESTROY_CEP,\r
+            &m_cid,\r
+            sizeof(m_cid),\r
+            NULL,\r
+            0,\r
+            &bytes_ret,\r
+            NULL );\r
+\r
+        m_cid = 0;\r
+    }\r
+}\r
+\r
+HRESULT CConnector::Create(\r
+    __in CAdapter* pParent,\r
+    __deref_out INDConnector** ppConnector\r
+    )\r
+{\r
+    CConnector* pConnector = new CConnector();\r
+    if( pConnector == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    pConnector->m_pParent = pParent;\r
+    pParent->AddRef();\r
+\r
+    *ppConnector = pConnector;\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CConnector::QueryInterface(\r
+    REFIID riid,\r
+    LPVOID FAR* ppvObj\r
+    )\r
+{\r
+    if( IsEqualIID( riid, IID_IUnknown ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    if( IsEqualIID( riid, IID_INDConnector ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    return E_NOINTERFACE;\r
+}\r
+\r
+ULONG CConnector::AddRef(void)\r
+{\r
+    return InterlockedIncrement( &m_nRef );\r
+}\r
+\r
+ULONG CConnector::Release(void)\r
+{\r
+    ULONG ref = InterlockedDecrement( &m_nRef );\r
+    if( ref == 0 )\r
+        delete this;\r
+\r
+    return ref;\r
+}\r
+\r
+// *** INDOverlapped methods ***\r
+HRESULT CConnector::CancelOverlappedRequests(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    DWORD bytes_ret;\r
+    BOOL ret = DeviceIoControl(\r
+        m_pParent->m_hSync,\r
+        UAL_NDI_CANCEL_CM_IRPS,\r
+        &m_cid,\r
+        sizeof(m_cid),\r
+        NULL,\r
+        0,\r
+        &bytes_ret,\r
+        NULL );\r
+\r
+    if( ret )\r
+        return S_OK;\r
+    else\r
+        return ND_UNSUCCESSFUL;\r
+}\r
+\r
+HRESULT CConnector::GetOverlappedResult(\r
+    __inout OVERLAPPED *pOverlapped,\r
+    __out SIZE_T *pNumberOfBytesTransferred,\r
+    __in BOOL bWait\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    *pNumberOfBytesTransferred = 0;\r
+    ::GetOverlappedResult(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped,\r
+        (DWORD*)pNumberOfBytesTransferred,\r
+        bWait );\r
+    return (HRESULT)pOverlapped->Internal;\r
+}\r
+\r
+HRESULT CConnector::CreateEndpoint(\r
+    __in INDCompletionQueue* pInboundCq,\r
+    __in INDCompletionQueue* pOutboundCq,\r
+    __in SIZE_T nInboundEntries,\r
+    __in SIZE_T nOutboundEntries,\r
+    __in SIZE_T nInboundSge,\r
+    __in SIZE_T nOutboundSge,\r
+    __in SIZE_T InboundReadLimit,\r
+    __in SIZE_T OutboundReadLimit,\r
+    __out_opt SIZE_T* pMaxInlineData,\r
+    __deref_out INDEndpoint** ppEndpoint\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    //\r
+    // Check that the verb provider supports user-mode operations.\r
+    // If not, a different class should be created.\r
+    //\r
+    if( m_pParent->m_Ifc.user_verbs.pre_create_qp == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_create_qp == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.nd_modify_qp == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.nd_get_qp_state == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.pre_destroy_qp == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_destroy_qp == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_send == NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_recv == NULL /*||\r
+        m_pParent->m_Ifc.user_verbs.bind_mw == NULL*/ )\r
+    {\r
+        return ND_NOT_SUPPORTED;\r
+    }\r
+\r
+    if( m_pEndpoint != NULL )\r
+        return ND_NOT_SUPPORTED;\r
+\r
+    HRESULT hr = CEndpoint::Create(\r
+        m_pParent,\r
+        static_cast<CCq*>(pInboundCq),\r
+        static_cast<CCq*>(pOutboundCq),\r
+        nInboundEntries,\r
+        nOutboundEntries,\r
+        nInboundSge,\r
+        nOutboundSge,\r
+        InboundReadLimit,\r
+        OutboundReadLimit,\r
+        pMaxInlineData,\r
+        (INDEndpoint**)&m_pEndpoint\r
+        );\r
+\r
+    if( SUCCEEDED( hr ) )\r
+    {\r
+        m_pEndpoint->AddRef();\r
+        *ppEndpoint = m_pEndpoint;\r
+    }\r
+\r
+    return hr;\r
+}\r
+\r
+//\r
+// Connects an endpoint to the specified destinaton address.\r
+//\r
+// Only basic checks on input data are performed in user-mode,\r
+// and request is handed to the kernel, where:\r
+//  1. the destination address is resolved to a destination GID\r
+//  2. the destination GID is used to get a path record\r
+//  3. the path record is used to issue a CM REQ\r
+//  4. a CM REP is received (or REJ or timeout).\r
+//  5. the request is completed.\r
+//\r
+HRESULT CConnector::Connect(\r
+    __inout INDEndpoint* pEndpoint,\r
+    __in_bcount(AddressLength) const struct sockaddr* pAddress,\r
+    __in SIZE_T AddressLength,\r
+    __in INT Protocol,\r
+    __in_opt USHORT LocalPort,\r
+    __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+    __in SIZE_T PrivateDataLength,\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( AddressLength < sizeof(struct sockaddr) )\r
+        return ND_INVALID_ADDRESS;\r
+\r
+    if( Protocol > UCHAR_MAX || Protocol < 0 )\r
+        return ND_INVALID_PARAMETER_4;\r
+\r
+    m_Protocol = (UINT8)Protocol;\r
+\r
+    //\r
+    // CM REQ supports 92 bytes of private data.  We expect to use IP\r
+    // addressing annex, which eats up 36 bytes, leaving us with 56.\r
+    //\r
+    if( PrivateDataLength > 56 )\r
+        return ND_BUFFER_OVERFLOW;\r
+\r
+    //\r
+    // Only support connecting the endpoint we created.\r
+    //\r
+    if( pEndpoint != m_pEndpoint )\r
+        return ND_INVALID_PARAMETER_1;\r
+\r
+    //\r
+    // Format the private data to match the RDMA CM annex spec as we\r
+    // check the address validity.\r
+    //\r
+    ual_ndi_req_cm_ioctl_in_t ioctl;\r
+    ioctl.pdata.maj_min_ver = 0;\r
+    if( LocalPort == 0 )\r
+    {\r
+        m_LocalPort = (USHORT)_byteswap_ulong( m_pEndpoint->m_Qpn );\r
+    }\r
+    else\r
+    {\r
+        m_LocalPort = LocalPort;\r
+    }\r
+    ioctl.pdata.src_port = _byteswap_ushort( m_LocalPort );\r
+\r
+    // Resolve the GIDs.\r
+   HRESULT hr = IBAT::Resolve(\r
+        &m_pParent->m_Addr.unspec,\r
+        pAddress,\r
+        (IBAT_PATH_BLOB*)&ioctl.path\r
+        );\r
+    if( FAILED( hr ) )\r
+    {\r
+        if( hr == E_PENDING )\r
+        {\r
+            //\r
+            // Complete the request with a timeout status.\r
+            //\r
+            pOverlapped->Internal = ND_PENDING;\r
+            hr = NtDeviceIoControlFile(\r
+                m_pParent->GetFileHandle(),\r
+                pOverlapped->hEvent,\r
+                NULL,\r
+                (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+                (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+                UAL_NDI_NOOP,\r
+                &hr,\r
+                sizeof(hr),\r
+                NULL,\r
+                0 );\r
+        }\r
+        return hr;\r
+    }\r
+\r
+    switch( ((struct sockaddr_in*)pAddress)->sin_family )\r
+    {\r
+    case AF_INET:\r
+        if( AddressLength != sizeof(struct sockaddr_in) )\r
+            return ND_INVALID_ADDRESS;\r
+\r
+        if( m_pParent->m_Addr.v4.sin_family != AF_INET )\r
+            return ND_INVALID_ADDRESS;\r
+\r
+        //\r
+        // Copy the destination address so we can satisfy a\r
+        // GetPeerAddress request.\r
+        //\r
+        m_PeerAddr.v4 = *(struct sockaddr_in*)pAddress;\r
+\r
+        ioctl.dst_port = m_PeerAddr.v4.sin_port;\r
+        ioctl.pdata.ipv = 0x40;\r
+\r
+        // Local address.\r
+        RtlZeroMemory( &ioctl.pdata.src_ip_addr, ATS_IPV4_OFFSET );\r
+        CopyMemory(\r
+            &ioctl.pdata.src_ip_addr[ATS_IPV4_OFFSET>>2],\r
+            (uint8_t*)&m_pParent->m_Addr.v4.sin_addr,\r
+            sizeof( m_pParent->m_Addr.v4.sin_addr )\r
+            );\r
+\r
+        // Destination address.\r
+        RtlZeroMemory( &ioctl.pdata.dst_ip_addr, ATS_IPV4_OFFSET );\r
+        CopyMemory(\r
+            &ioctl.pdata.dst_ip_addr[ATS_IPV4_OFFSET>>2],\r
+            (uint8_t*)&m_PeerAddr.v4.sin_addr,\r
+            sizeof( m_PeerAddr.v4.sin_addr )\r
+            );\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("local address: IP %#x, port %#hx, dest address: IP %#x, port %#hx\n", \r
+            cl_hton32(m_pParent->m_Addr.v4.sin_addr.S_un.S_addr), cl_hton16(m_pParent->m_Addr.v4.sin_port),\r
+            cl_hton32(m_PeerAddr.v4.sin_addr.S_un.S_addr), cl_hton16(m_PeerAddr.v4.sin_port) ) );\r
+        break;\r
+\r
+    case AF_INET6:\r
+        if( AddressLength != sizeof(struct sockaddr_in6) )\r
+            return ND_INVALID_ADDRESS;\r
+\r
+        //\r
+        // Copy the destination address so we can satisfy a\r
+        // GetPeerAddress request.\r
+        //\r
+        m_PeerAddr.v6 = *(struct sockaddr_in6*)pAddress;\r
+\r
+        ioctl.dst_port = m_PeerAddr.v6.sin6_port;\r
+        ioctl.pdata.ipv = 0x60;\r
+\r
+        // Local address.\r
+        CopyMemory(\r
+            ioctl.pdata.src_ip_addr,\r
+            m_pParent->m_Addr.v6.sin6_addr.u.Byte,\r
+            sizeof(ioctl.pdata.src_ip_addr)\r
+            );\r
+\r
+        // Destination address.\r
+        CopyMemory( ioctl.pdata.dst_ip_addr,\r
+            m_PeerAddr.v6.sin6_addr.u.Byte,\r
+            sizeof(ioctl.pdata.dst_ip_addr)\r
+            );\r
+        break;\r
+\r
+    default:\r
+        return ND_INVALID_ADDRESS;\r
+    }\r
+\r
+    // Copy the user's private data.\r
+    CopyMemory( ioctl.pdata.pdata, pPrivateData, PrivateDataLength );\r
+\r
+    //\r
+    // It's only valid to call Connect with a new or reused endpoint:\r
+    // the QP must be in the INIT state.\r
+    //\r
+    switch( m_pParent->m_Ifc.user_verbs.nd_get_qp_state( m_pEndpoint->m_uQp ) )\r
+    {\r
+    case IB_QPS_INIT:\r
+        break;\r
+\r
+    case IB_QPS_RTS:\r
+        return ND_CONNECTION_ACTIVE;\r
+\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+\r
+    //\r
+    // Create the CEP.  We do this so that we have a valid CID in user-mode\r
+    // in case the user calls CancelOverlappedRequests or releases the object.\r
+    //\r
+    UINT64 context = 0;\r
+    ual_create_cep_ioctl_t create;\r
+    DWORD bytes_ret;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_pParent->m_hSync,\r
+        UAL_CREATE_CEP,\r
+        &context,\r
+        sizeof(context),\r
+        &create,\r
+        sizeof(create),\r
+        &bytes_ret,\r
+        NULL\r
+        );\r
+    if( !fSuccess ||\r
+        bytes_ret != sizeof(create) ||\r
+        create.status != IB_SUCCESS )\r
+    {\r
+        return ND_INSUFFICIENT_RESOURCES;\r
+    }\r
+\r
+    m_cid = create.cid;\r
+\r
+    //\r
+    // Fill in the rest of the input buffer and send the request down\r
+    // to the kernel and let everything else be done there.\r
+    //\r
+    ioctl.h_qp = m_pEndpoint->m_hQp;\r
+    ioctl.guid = m_pParent->m_PortGuid;\r
+    ioctl.cid = m_cid;\r
+    ioctl.prot = m_Protocol;\r
+    ioctl.pdata_size = sizeof(ioctl.pdata);\r
+    ioctl.init_depth = m_pEndpoint->m_Ord;\r
+    ioctl.resp_res = m_pEndpoint->m_Ird;\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Connect QP %#I64x, QPn %#x, Guid %#I64x \n",\r
+        m_pEndpoint->m_hQp,\r
+        m_pEndpoint->m_Qpn,\r
+        m_pParent->m_PortGuid ) );\r
+\r
+    m_fActive = true;\r
+\r
+    pOverlapped->Internal = ND_PENDING;\r
+    hr = NtDeviceIoControlFile(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_REQ_CM,\r
+        &ioctl,\r
+        sizeof(ioctl),\r
+        NULL,\r
+        0 );\r
+\r
+    if( FAILED( hr ) )\r
+    {\r
+        FreeCid();\r
+        m_pEndpoint->Release();\r
+        m_pEndpoint = NULL;\r
+    }\r
+\r
+    return hr;\r
+}\r
+\r
+HRESULT CConnector::CompleteConnect(\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( !m_fActive )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    if( m_pEndpoint == NULL )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    //\r
+    // Get the UVP's buffer for modify operations.\r
+    //\r
+    void* pOutbuf;\r
+    DWORD szOutbuf;\r
+\r
+    m_pParent->m_Ifc.user_verbs.nd_modify_qp(\r
+        (const ib_qp_handle_t)m_pEndpoint->m_uQp,\r
+        &pOutbuf,\r
+        &szOutbuf\r
+        );\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("CompleteConnect QP %#I64x, QPn %#x\n", m_pEndpoint->m_hQp, m_pEndpoint->m_Qpn ) );\r
+\r
+    pOverlapped->Internal = ND_PENDING;\r
+    return NtDeviceIoControlFile(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_RTU_CM,\r
+        &m_cid,\r
+        sizeof(m_cid),\r
+        pOutbuf,\r
+        szOutbuf );\r
+}\r
+\r
+HRESULT CConnector::Accept(\r
+    __in INDEndpoint* pEndpoint,\r
+    __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+    __in SIZE_T PrivateDataLength,\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( PrivateDataLength > IB_REJ_PDATA_SIZE )\r
+        return ND_BUFFER_OVERFLOW;\r
+\r
+    //\r
+    // Only support connecting the endpoint we created.\r
+    //\r
+    if( pEndpoint != m_pEndpoint )\r
+        return ND_INVALID_PARAMETER_1;\r
+\r
+    //\r
+    // Get the UVP's buffer for modify operations.\r
+    //\r
+    void* pOutbuf;\r
+    DWORD szOutbuf;\r
+\r
+    m_pParent->m_Ifc.user_verbs.nd_modify_qp(\r
+        static_cast<CEndpoint*>(pEndpoint)->m_uQp,\r
+        &pOutbuf,\r
+        &szOutbuf\r
+        );\r
+\r
+    ual_ndi_rep_cm_ioctl_in_t ioctl;\r
+    ioctl.h_qp = m_pEndpoint->m_hQp;\r
+    ioctl.cid = m_cid;\r
+    ioctl.init_depth = m_pEndpoint->m_Ord;\r
+    ioctl.resp_res = m_pEndpoint->m_Ird;\r
+    ioctl.pdata_size = (uint8_t)PrivateDataLength;\r
+    CopyMemory( &ioctl.pdata, pPrivateData, PrivateDataLength );\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Accept QP %#I64x, cid %d \n", ioctl.h_qp, ioctl.cid ) );\r
+\r
+    pOverlapped->Internal = ND_PENDING;\r
+    HRESULT hr = NtDeviceIoControlFile(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_REP_CM,\r
+        &ioctl,\r
+        sizeof(ioctl),\r
+        pOutbuf,\r
+        szOutbuf );\r
+\r
+    if( FAILED( hr ) )\r
+    {\r
+        m_pEndpoint->Release();\r
+        m_pEndpoint = NULL;\r
+    }\r
+    return hr;\r
+}\r
+\r
+HRESULT CConnector::Reject(\r
+    __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+    __in SIZE_T PrivateDataLength\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( PrivateDataLength > IB_REJ_PDATA_SIZE )\r
+        return ND_BUFFER_OVERFLOW;\r
+\r
+    ual_ndi_rej_cm_ioctl_in_t ioctl;\r
+    ioctl.cid = m_cid;\r
+    ioctl.pdata_size = (uint8_t)PrivateDataLength;\r
+    if( pPrivateData != NULL )\r
+    {\r
+        CopyMemory( &ioctl.pdata, pPrivateData, PrivateDataLength );\r
+    }\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI, \r
+        ("Connection rejected with pdata_size %d, cid %d\n", \r
+        (int)PrivateDataLength, ioctl.cid ));\r
+\r
+    IO_STATUS_BLOCK IoStatus;\r
+    return NtDeviceIoControlFile(\r
+        m_pParent->m_hSync,\r
+        NULL,\r
+        NULL,\r
+        NULL,\r
+        &IoStatus,\r
+        UAL_NDI_REJ_CM,\r
+        &ioctl,\r
+        sizeof(ioctl),\r
+        NULL,\r
+        0 );\r
+}\r
+\r
+HRESULT CConnector::GetConnectionData(\r
+    __out_opt SIZE_T* pInboundReadLimit,\r
+    __out_opt SIZE_T* pOutboundReadLimit,\r
+    __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+    __inout SIZE_T* pPrivateDataLength\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    IO_STATUS_BLOCK IoStatus;\r
+    ual_cep_get_pdata_ioctl_t IoctlBuf;\r
+\r
+    IoctlBuf.in.cid = m_cid;\r
+    HRESULT hr = NtDeviceIoControlFile(\r
+        m_pParent->m_hSync,\r
+        NULL,\r
+        NULL,\r
+        NULL,\r
+        &IoStatus,\r
+        UAL_CEP_GET_PDATA,\r
+        &IoctlBuf,\r
+        sizeof(IoctlBuf.in),\r
+        &IoctlBuf,\r
+        sizeof(IoctlBuf.out) );\r
+\r
+    // UAL_CEP_GET_PDATA never returns pending.\r
+    if( FAILED( hr ) )\r
+        return hr;\r
+\r
+    // On the passive side, check that we got the REQ private data.\r
+    if( !m_fActive )\r
+    {\r
+        hr = GetPdataForPassive(\r
+            IoctlBuf.out.pdata,\r
+            IoctlBuf.out.pdata_len,\r
+            pPrivateData,\r
+            pPrivateDataLength\r
+            );\r
+    }\r
+    else\r
+    {\r
+        hr = GetPdataForActive(\r
+            IoctlBuf.out.pdata,\r
+            IoctlBuf.out.pdata_len,\r
+            pPrivateData,\r
+            pPrivateDataLength\r
+            );\r
+    }\r
+\r
+    if( FAILED( hr ) && hr != ND_BUFFER_OVERFLOW )\r
+        return hr;\r
+\r
+    if( pInboundReadLimit )\r
+    {\r
+        *pInboundReadLimit = IoctlBuf.out.resp_res;\r
+    }\r
+\r
+    if( pOutboundReadLimit )\r
+    {\r
+        *pOutboundReadLimit = IoctlBuf.out.init_depth;\r
+    }\r
+\r
+    return hr;\r
+}\r
+\r
+HRESULT CConnector::GetLocalAddress(\r
+    __out_bcount_part_opt(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+    __inout SIZE_T* pAddressLength\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( m_pEndpoint == NULL )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    ib_qp_state_t state =\r
+        m_pParent->m_Ifc.user_verbs.nd_get_qp_state( m_pEndpoint->m_uQp );\r
+    if( state != IB_QPS_RTS )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    HRESULT hr = m_pParent->GetLocalAddress( pAddress, pAddressLength );\r
+    if( FAILED(hr) )\r
+        return hr;\r
+\r
+    // V4 and V6 addresses have the port number in the same place.\r
+    ((struct sockaddr_in*)pAddress)->sin_port = m_LocalPort;\r
+#if DBG || defined(EVENT_TRACING)\r
+    struct sockaddr_in*pAddrV4 = (struct sockaddr_in*)pAddress;\r
+#endif        \r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Local address: IP %#x, port %#hx\n", \r
+        cl_hton32(pAddrV4->sin_addr.S_un.S_addr), cl_hton16(pAddrV4->sin_port) ) );\r
+\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CConnector::GetAddressFromPdata(\r
+    __out_bcount_part(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+    __inout SIZE_T* pAddressLength\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    IO_STATUS_BLOCK IoStatus;\r
+    ual_cep_get_pdata_ioctl_t IoctlBuf;\r
+\r
+    IoctlBuf.in.cid = m_cid;\r
+\r
+    HRESULT hr = NtDeviceIoControlFile(\r
+        m_pParent->m_hSync,\r
+        NULL,\r
+        NULL,\r
+        NULL,\r
+        &IoStatus,\r
+        UAL_CEP_GET_PDATA,\r
+        &IoctlBuf,\r
+        sizeof(IoctlBuf.in),\r
+        &IoctlBuf,\r
+        sizeof(IoctlBuf.out) );\r
+\r
+    // UAL_CEP_GET_PDATA never returns pending.\r
+    if( FAILED( hr ) )\r
+    {\r
+        CL_ASSERT( hr != ND_PENDING );\r
+        return hr;\r
+    }\r
+\r
+    if( IoctlBuf.out.pdata_len != IB_REQ_PDATA_SIZE )\r
+        return ND_CONNECTION_ABORTED;\r
+\r
+    ib_cm_rdma_req_t* pIpData = (ib_cm_rdma_req_t*)&IoctlBuf.out.pdata;\r
+    CL_ASSERT( pIpData->maj_min_ver == 0 );\r
+\r
+    SIZE_T len;\r
+    switch( pIpData->ipv )\r
+    {\r
+    case 0x40:\r
+        len = 4;\r
+        break;\r
+    case 0x60:\r
+        len = 16;\r
+        break;\r
+    default:\r
+        CL_ASSERT( pIpData->ipv == 0x40 || pIpData->ipv == 0x60 );\r
+        len = 0;\r
+        break;\r
+    }\r
+\r
+    if( len > *pAddressLength )\r
+    {\r
+        *pAddressLength = len;\r
+        return ND_BUFFER_OVERFLOW;\r
+    }\r
+\r
+    ((struct sockaddr_in*)pAddress)->sin_port =\r
+        _byteswap_ushort( pIpData->src_port );\r
+\r
+    switch( pIpData->ipv )\r
+    {\r
+    case 0x40:\r
+        ((struct sockaddr_in*)pAddress)->sin_family = AF_INET;\r
+        ((struct sockaddr_in*)pAddress)->sin_addr.s_addr = pIpData->src_ip_addr[3];\r
+        ZeroMemory( ((struct sockaddr_in*)pAddress)->sin_zero,\r
+            sizeof( ((struct sockaddr_in*)pAddress)->sin_zero ) );\r
+        break;\r
+\r
+    case 0x60:\r
+        ((struct sockaddr_in6*)pAddress)->sin6_family = AF_INET6;\r
+        ((struct sockaddr_in6*)pAddress)->sin6_flowinfo = 0;\r
+        RtlCopyMemory( (char*)((struct sockaddr_in6*)pAddress)->sin6_addr.s6_bytes,\r
+            (char *const)pIpData->src_ip_addr, sizeof(pIpData->src_ip_addr) );\r
+        ((struct sockaddr_in6*)pAddress)->sin6_scope_id = 0;\r
+        break;\r
+    }\r
+\r
+    *pAddressLength = len;\r
+    return hr;\r
+}\r
+\r
+HRESULT CConnector::GetPeerAddress(\r
+    __out_bcount_part_opt(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+    __inout SIZE_T* pAddressLength\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( !m_fActive )\r
+        return GetAddressFromPdata( pAddress, pAddressLength );\r
+\r
+    if( m_pEndpoint == NULL )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    ib_qp_state_t state =\r
+        m_pParent->m_Ifc.user_verbs.nd_get_qp_state( m_pEndpoint->m_uQp );\r
+    if( state != IB_QPS_RTS )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    switch( m_PeerAddr.v4.sin_family )\r
+    {\r
+    case AF_INET:\r
+        if( *pAddressLength < sizeof(struct sockaddr_in) )\r
+        {\r
+            *pAddressLength = sizeof(struct sockaddr_in);\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        *(struct sockaddr_in*)pAddress = m_PeerAddr.v4;\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("Peer address: IP %#x, port %#hx\n", \r
+            cl_hton32(m_PeerAddr.v4.sin_addr.S_un.S_addr), cl_hton16(m_PeerAddr.v4.sin_port) ) );\r
+        break;\r
+\r
+    case AF_INET6:\r
+        if( *pAddressLength < sizeof(struct sockaddr_in6) )\r
+        {\r
+            *pAddressLength = sizeof(struct sockaddr_in6);\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        *(struct sockaddr_in6*)pAddress = m_PeerAddr.v6;\r
+        break;\r
+\r
+    default:\r
+        return ND_CONNECTION_INVALID;\r
+    }\r
+\r
+    return S_OK;\r
+}\r
+\r
+HRESULT CConnector::NotifyDisconnect(\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    pOverlapped->Internal = ND_PENDING;\r
+    return NtDeviceIoControlFile(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_NOTIFY_DREQ,\r
+        &m_cid,\r
+        sizeof(m_cid),\r
+        NULL,\r
+        0 );\r
+}\r
+\r
+HRESULT CConnector::Disconnect(\r
+    __inout OVERLAPPED* pOverlapped\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( m_pEndpoint == NULL )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    ib_qp_state_t state =\r
+        m_pParent->m_Ifc.user_verbs.nd_get_qp_state( m_pEndpoint->m_uQp );\r
+    if( state != IB_QPS_RTS )\r
+        return ND_CONNECTION_INVALID;\r
+\r
+    //\r
+    // Get the UVP's buffer for modify operations.\r
+    //\r
+    void* pOutbuf;\r
+    DWORD szOutbuf;\r
+\r
+    m_pParent->m_Ifc.user_verbs.nd_modify_qp(\r
+        m_pEndpoint->m_uQp,\r
+        &pOutbuf,\r
+        &szOutbuf\r
+        );\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Disconnect QP %#I64x, QPn %#x\n", m_pEndpoint->m_hQp, m_pEndpoint->m_Qpn ) );\r
+\r
+    pOverlapped->Internal = ND_PENDING;\r
+    HRESULT hr = NtDeviceIoControlFile(\r
+        m_pParent->GetFileHandle(),\r
+        pOverlapped->hEvent,\r
+        NULL,\r
+        (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+        (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+        UAL_NDI_DREQ_CM,\r
+        &m_cid,\r
+        sizeof(m_cid),\r
+        pOutbuf,\r
+        szOutbuf );\r
+\r
+    if( SUCCEEDED( hr ) )\r
+    {\r
+        m_pEndpoint->Release();\r
+        m_pEndpoint = NULL;\r
+    }\r
+\r
+    return hr;\r
+}\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdConnector.h b/branches/winverbs/ulp/nd/user/NdConnector.h
new file mode 100644 (file)
index 0000000..6f701a9
--- /dev/null
@@ -0,0 +1,172 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "ndspi.h"\r
+#include "nddebug.h"\r
+#include <iba/ib_al.h>\r
+#include <iba/ib_at_ioctl.h>\r
+#include <ws2tcpip.h>\r
+#include "ual_ci_ca.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+class CConnector :\r
+    public INDConnector\r
+{\r
+    friend class CListen;\r
+\r
+private:\r
+    CConnector(void);\r
+    ~CConnector(void);\r
+    void FreeCid(void);\r
+\r
+public:\r
+    static HRESULT Create(\r
+        __in CAdapter* pParent,\r
+        __deref_out INDConnector** ppConnector\r
+        );\r
+\r
+    // *** IUnknown methods ***\r
+    HRESULT STDMETHODCALLTYPE QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        );\r
+\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // *** INDOverlapped methods ***\r
+    HRESULT STDMETHODCALLTYPE CancelOverlappedRequests(void);\r
+\r
+    HRESULT STDMETHODCALLTYPE GetOverlappedResult(\r
+        __inout OVERLAPPED *pOverlapped,\r
+        __out SIZE_T *pNumberOfBytesTransferred,\r
+        __in BOOL bWait\r
+        );\r
+\r
+    // *** INDConnector methods ***\r
+    HRESULT STDMETHODCALLTYPE CreateEndpoint(\r
+        __in INDCompletionQueue* pInboundCq,\r
+        __in INDCompletionQueue* pOutboundCq,\r
+        __in SIZE_T nInboundEntries,\r
+        __in SIZE_T nOutboundEntries,\r
+        __in SIZE_T nInboundSge,\r
+        __in SIZE_T nOutboundSge,\r
+        __in SIZE_T InboundReadLimit,\r
+        __in SIZE_T OutboundReadLimit,\r
+        __out_opt SIZE_T* pMaxInlineData,\r
+        __deref_out INDEndpoint** ppEndpoint\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Connect(\r
+        __in INDEndpoint* pEndpoint,\r
+        __in_bcount(AddressLength) const struct sockaddr* pAddress,\r
+        __in SIZE_T AddressLength,\r
+        __in INT Protocol,\r
+        __in_opt USHORT LocalPort,\r
+        __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+        __in SIZE_T PrivateDataLength,\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE CompleteConnect(\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Accept(\r
+        __in INDEndpoint* pEndpoint,\r
+        __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+        __in SIZE_T PrivateDataLength,\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Reject(\r
+        __in_bcount_opt(PrivateDataLength) const void* pPrivateData,\r
+        __in SIZE_T PrivateDataLength\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE GetConnectionData(\r
+        __out_opt SIZE_T* pInboundReadLimit,\r
+        __out_opt SIZE_T* pOutboundReadLimit,\r
+        __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+        __inout SIZE_T* pPrivateDataLength\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE GetLocalAddress(\r
+        __out_bcount_part_opt(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+        __inout SIZE_T* pAddressLength\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE GetPeerAddress(\r
+        __out_bcount_part_opt(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+        __inout SIZE_T* pAddressLength\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE NotifyDisconnect(\r
+        __inout_opt OVERLAPPED* pOverlapped\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Disconnect(\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+private:\r
+    HRESULT GetAddressFromPdata(\r
+        __out_bcount_part(*pAddressLength, *pAddressLength) struct sockaddr* pAddress,\r
+        __inout SIZE_T* pAddressLength\r
+        );\r
+\r
+protected:\r
+        volatile LONG m_nRef;\r
+\r
+        CAdapter* m_pParent;\r
+\r
+        CEndpoint* m_pEndpoint;\r
+\r
+        UINT8 m_Protocol;\r
+        USHORT m_LocalPort;\r
+        net32_t m_cid;\r
+        bool m_fActive;\r
+\r
+        union _addr\r
+        {\r
+            struct sockaddr_in v4;\r
+            struct sockaddr_in6 v6;\r
+\r
+        } m_PeerAddr;\r
+};\r
+\r
+}\r
diff --git a/branches/winverbs/ulp/nd/user/NdCq.cpp b/branches/winverbs/ulp/nd/user/NdCq.cpp
new file mode 100644 (file)
index 0000000..94c71c3
--- /dev/null
@@ -0,0 +1,487 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdCq.h"\r
+#include "NdAdapter.h"\r
+#include "al_cq.h"\r
+#include "al_dev.h"\r
+#include "al.h"\r
+#include "al_verbs.h"\r
+#pragma warning( push, 3 )\r
+#include "winternl.h"\r
+#pragma warning( pop )\r
+#include "limits.h"\r
+#include "nddebug.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdCq.tmh"\r
+#endif\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    CCq::CCq(void) :\r
+        m_nRef( 1 ),\r
+        m_pParent( NULL ),\r
+        m_hCq( 0 ),\r
+        m_uCq( NULL )\r
+    {\r
+    }\r
+\r
+    CCq::~CCq(void)\r
+    {\r
+        if( m_hCq )\r
+            CloseCq();\r
+\r
+        if( m_pParent )\r
+            m_pParent->Release();\r
+    }\r
+\r
+    HRESULT CCq::Initialize(\r
+        CAdapter* pParent,\r
+        SIZE_T nEntries )\r
+    {\r
+        if( nEntries > UINT_MAX )\r
+            return ND_INVALID_PARAMETER;\r
+\r
+        m_pParent = pParent;\r
+        pParent->AddRef();\r
+\r
+        return CreateCq( (UINT32)nEntries );\r
+    }\r
+\r
+    HRESULT CCq::QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        )\r
+    {\r
+        if( IsEqualIID( riid, IID_IUnknown ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        if( IsEqualIID( riid, IID_INDCompletionQueue ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    ULONG CCq::AddRef(void)\r
+    {\r
+        return InterlockedIncrement( &m_nRef );\r
+    }\r
+\r
+    ULONG CCq::Release(void)\r
+    {\r
+        ULONG ref = InterlockedDecrement( &m_nRef );\r
+        if( ref == 0 )\r
+            delete this;\r
+\r
+        return ref;\r
+    }\r
+\r
+    // *** INDOverlapped methods ***\r
+    HRESULT CCq::CancelOverlappedRequests(void)\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        DWORD BytesRet;\r
+        DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_NDI_CANCEL_CQ,\r
+            &m_hCq,\r
+            sizeof(m_hCq),\r
+            NULL,\r
+            0,\r
+            &BytesRet,\r
+            NULL\r
+            );\r
+\r
+        return S_OK;\r
+    }\r
+\r
+    HRESULT CCq::GetOverlappedResult(\r
+        __inout OVERLAPPED *pOverlapped,\r
+        __out SIZE_T *pNumberOfBytesTransferred,\r
+        __in BOOL bWait\r
+        )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        *pNumberOfBytesTransferred = 0;\r
+        ::GetOverlappedResult(\r
+            m_pParent->GetFileHandle(),\r
+            pOverlapped,\r
+            (DWORD*)pNumberOfBytesTransferred,\r
+            bWait );\r
+        ND_PRINT( TRACE_LEVEL_VERBOSE, ND_DBG_NDI,\r
+            ("==> %s, result %#x, bytes %d\n", __FUNCTION__, (int)pOverlapped->Internal, (int)*pNumberOfBytesTransferred ));\r
+        return (HRESULT)pOverlapped->Internal;\r
+    }\r
+\r
+    // *** INDCompletionQueue methods ***\r
+    HRESULT CCq::Resize(\r
+        __in SIZE_T nEntries\r
+        )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        if( nEntries > UINT_MAX )\r
+            return ND_INVALID_PARAMETER;\r
+\r
+        ib_api_status_t                        status;\r
+\r
+        /* Clear the IOCTL buffer */\r
+        ual_modify_cq_ioctl_t  cq_ioctl;\r
+        cl_memclr( &cq_ioctl, sizeof(cq_ioctl) );\r
+\r
+        /* Call the uvp pre call if the vendor library provided a valid ca handle */\r
+        if( m_uCq && m_pParent->m_Ifc.user_verbs.pre_resize_cq )\r
+        {\r
+            /* Pre call to the UVP library */\r
+            status = m_pParent->m_Ifc.user_verbs.pre_resize_cq(\r
+                m_uCq, (uint32_t*)&nEntries, &cq_ioctl.in.umv_buf );\r
+            if( status != IB_SUCCESS )\r
+                goto exit;\r
+        }\r
+\r
+        cq_ioctl.in.h_cq = m_hCq;\r
+        cq_ioctl.in.size = (DWORD)nEntries;\r
+\r
+        DWORD BytesRet;\r
+        BOOL fSuccess = DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_MODIFY_CQ,\r
+            &cq_ioctl.in,\r
+            sizeof(cq_ioctl.in),\r
+            &cq_ioctl.out,\r
+            sizeof(cq_ioctl.out),\r
+            &BytesRet,\r
+            NULL\r
+            );\r
+\r
+        if( fSuccess != TRUE || BytesRet != sizeof(cq_ioctl.out) )\r
+            status = IB_ERROR;\r
+        else\r
+            status = cq_ioctl.out.status;\r
+\r
+        /* Post uvp call */\r
+        if( m_uCq && m_pParent->m_Ifc.user_verbs.post_resize_cq )\r
+        {\r
+            m_pParent->m_Ifc.user_verbs.post_resize_cq(\r
+                m_uCq, status, cq_ioctl.out.size, &cq_ioctl.out.umv_buf );\r
+        }\r
+\r
+exit:\r
+        switch( status )\r
+        {\r
+        case IB_INVALID_CQ_SIZE:\r
+            return ND_INVALID_PARAMETER;\r
+\r
+        case IB_SUCCESS:\r
+            return S_OK;\r
+\r
+        case IB_INSUFFICIENT_RESOURCES:\r
+            return ND_INSUFFICIENT_RESOURCES;\r
+\r
+        default:\r
+            return ND_UNSUCCESSFUL;\r
+        }\r
+    }\r
+\r
+    HRESULT CCq::Notify(\r
+        __in DWORD Type,\r
+        __inout OVERLAPPED* pOverlapped\r
+        )\r
+    {\r
+//        ND_ENTER( ND_DBG_NDI );\r
+\r
+        ual_ndi_notify_cq_ioctl_in_t ioctl;\r
+        ioctl.h_cq = m_hCq;\r
+        ioctl.notify_comps = (boolean_t)Type;\r
+        pOverlapped->Internal = ND_PENDING;\r
+        HRESULT hr = NtDeviceIoControlFile(\r
+            m_pParent->GetFileHandle(),\r
+            pOverlapped->hEvent,\r
+            NULL,\r
+            (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+            (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+            UAL_NDI_NOTIFY_CQ,\r
+            &ioctl,\r
+            sizeof(ioctl),\r
+            NULL,\r
+            0 );\r
+\r
+        if( hr == ND_PENDING && Type != ND_CQ_NOTIFY_ERRORS )\r
+        {\r
+            m_pParent->m_Ifc.user_verbs.rearm_cq(\r
+                m_uCq,\r
+                (Type == ND_CQ_NOTIFY_SOLICITED) ? TRUE : FALSE\r
+                );\r
+            ND_PRINT( TRACE_LEVEL_VERBOSE, ND_DBG_NDI,\r
+                ("==> %s, rearming with Type %d\n", __FUNCTION__, Type));\r
+        }\r
+        else\r
+        {\r
+            ND_PRINT( TRACE_LEVEL_ERROR, ND_DBG_NDI,\r
+                ("==> %s failed: hr %#x, notify_type %d \n", __FUNCTION__, hr, Type ));\r
+        }\r
+        return hr;\r
+    }\r
+\r
+    SIZE_T CCq::GetResults(\r
+        __out_ecount(nResults) ND_RESULT* pResults[],\r
+        __in SIZE_T nResults\r
+        )\r
+    {\r
+#if DBG    \r
+        if (!(++g.c_cnt % 100000000))        //  || !(rcv_pkts % 1000) || !(snd_pkts % 1000)\r
+            ND_PRINT( TRACE_LEVEL_VERBOSE, ND_DBG_NDI,\r
+                ("==> %s, cnt %I64d, rcv: %I64d:%I64d:%I64d, snd %I64d:%I64d:%I64d\n", \r
+                __FUNCTION__, g.c_cnt, \r
+                g.c_rcv_pkts, g.c_rcv_bytes, g.c_rcv_pkts_err,\r
+                g.c_snd_pkts, g.c_snd_bytes, g.c_snd_pkts_err));\r
+#endif                \r
+        SIZE_T i = 0;\r
+\r
+        while( nResults-- )\r
+        {\r
+            ib_wc_t wc;\r
+            ib_wc_t* pWc = &wc;\r
+            ib_wc_t* pDoneWc;\r
+            wc.p_next = NULL;\r
+            ib_api_status_t status =\r
+                m_pParent->m_Ifc.user_verbs.poll_cq( m_uCq, &pWc, &pDoneWc );\r
+\r
+            if( status != IB_SUCCESS )\r
+                break;\r
+\r
+            pResults[i] = (ND_RESULT*)wc.wr_id;\r
+            if( wc.wc_type == IB_WC_RECV )\r
+                pResults[i]->BytesTransferred = wc.length;\r
+\r
+            if( wc.recv.conn.recv_opt & IB_RECV_OPT_IMMEDIATE )\r
+            {\r
+                // Emulated receive with invalidate - the immediate\r
+                // data holds the RKey that is supposed to be invalidated.\r
+\r
+                //TODO: We need the QP handle (or context) so we can force an\r
+                // error if we don't find a matching MW for the given RKEY.\r
+                // We also need to change the receive status in this case to\r
+                // ND_INVALIDATION_ERROR;\r
+            }\r
+\r
+            switch( wc.status )\r
+            {\r
+            case IB_WCS_SUCCESS:\r
+                pResults[i]->Status = ND_SUCCESS;\r
+                break;\r
+            case IB_WCS_LOCAL_LEN_ERR:\r
+                pResults[i]->Status = ND_LOCAL_LENGTH;\r
+                break;\r
+            case IB_WCS_LOCAL_OP_ERR:\r
+            case IB_WCS_LOCAL_ACCESS_ERR:\r
+            case IB_WCS_GENERAL_ERR:\r
+            default:\r
+                pResults[i]->Status = ND_INTERNAL_ERROR;\r
+                break;\r
+            case IB_WCS_LOCAL_PROTECTION_ERR:\r
+            case IB_WCS_MEM_WINDOW_BIND_ERR:\r
+                pResults[i]->Status = ND_ACCESS_VIOLATION;\r
+                break;\r
+            case IB_WCS_WR_FLUSHED_ERR:\r
+                pResults[i]->Status = ND_CANCELED;\r
+                break;\r
+            case IB_WCS_REM_INVALID_REQ_ERR:\r
+                pResults[i]->Status = ND_BUFFER_OVERFLOW;\r
+                break;\r
+            case IB_WCS_REM_ACCESS_ERR:\r
+            case IB_WCS_REM_OP_ERR:\r
+            case IB_WCS_BAD_RESP_ERR:\r
+                pResults[i]->Status = ND_REMOTE_ERROR;\r
+                break;\r
+            case IB_WCS_RNR_RETRY_ERR:\r
+            case IB_WCS_TIMEOUT_RETRY_ERR:\r
+                pResults[i]->Status = ND_TIMEOUT;\r
+                break;\r
+            }\r
+            i++;\r
+            // leo\r
+#if DBG\r
+            {\r
+                if (wc.wc_type == IB_WC_RECV)\r
+                {    \r
+                    if (!wc.status)\r
+                    {\r
+                        ++g.c_rcv_pkts;\r
+                        g.c_rcv_bytes += wc.length;\r
+                    }\r
+                    else\r
+                        ++g.c_rcv_pkts_err;\r
+                }\r
+                else\r
+                {    \r
+                    if (!wc.status)\r
+                    {\r
+                        ++g.c_snd_pkts;\r
+                        g.c_snd_bytes += wc.length;\r
+                    }\r
+                    else\r
+                        ++g.c_snd_pkts_err;\r
+                }\r
+            }\r
+#endif\r
+            continue;\r
+        }\r
+        return i;\r
+    }\r
+\r
+    HRESULT CCq::CreateCq(\r
+        __in UINT32 nEntries )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        /* Clear the IOCTL buffer */\r
+        ual_create_cq_ioctl_t cq_ioctl;\r
+        cl_memclr( &cq_ioctl, sizeof(cq_ioctl) );\r
+\r
+        /* Pre call to the UVP library */\r
+        ib_api_status_t status;\r
+        if( m_pParent->m_uCa && m_pParent->m_Ifc.user_verbs.pre_create_cq )\r
+        {\r
+            status = m_pParent->m_Ifc.user_verbs.pre_create_cq(\r
+                m_pParent->m_uCa,\r
+                &nEntries,\r
+                &cq_ioctl.in.umv_buf,\r
+                (ib_cq_handle_t*)(ULONG_PTR)&m_uCq\r
+                );\r
+            if( status != IB_SUCCESS )\r
+                goto done;\r
+        }\r
+\r
+        cq_ioctl.in.h_ca = m_pParent->m_hCa;\r
+        cq_ioctl.in.size = nEntries;\r
+        cq_ioctl.in.h_wait_obj = NULL;\r
+        cq_ioctl.in.context = (ULONG_PTR)this;\r
+        cq_ioctl.in.ev_notify = FALSE;\r
+\r
+        DWORD BytesRet;\r
+        BOOL fSuccess = DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_NDI_CREATE_CQ,\r
+            &cq_ioctl.in,\r
+            sizeof(cq_ioctl.in),\r
+            &cq_ioctl.out,\r
+            sizeof(cq_ioctl.out),\r
+            &BytesRet,\r
+            NULL\r
+            );\r
+\r
+        if( fSuccess != TRUE || BytesRet != sizeof(cq_ioctl.out) )\r
+            status = IB_ERROR;\r
+        else\r
+            status = cq_ioctl.out.status;\r
+\r
+        m_hCq = cq_ioctl.out.h_cq;\r
+\r
+        /* Post uvp call */\r
+        if( m_pParent->m_uCa && m_pParent->m_Ifc.user_verbs.post_create_cq )\r
+        {\r
+            m_pParent->m_Ifc.user_verbs.post_create_cq(\r
+                m_pParent->m_uCa,\r
+                status,\r
+                cq_ioctl.out.size,\r
+                (ib_cq_handle_t*)(ULONG_PTR)&m_uCq,\r
+                &cq_ioctl.out.umv_buf );\r
+        }\r
+\r
+done:\r
+        switch( status )\r
+        {\r
+        case IB_INVALID_CQ_SIZE:\r
+            return ND_INVALID_PARAMETER;\r
+\r
+        case IB_INSUFFICIENT_RESOURCES:\r
+            return ND_INSUFFICIENT_RESOURCES;\r
+\r
+        case IB_INSUFFICIENT_MEMORY:\r
+            return ND_NO_MEMORY;\r
+\r
+        case IB_SUCCESS:\r
+            return S_OK;\r
+\r
+        default:\r
+            return ND_UNSUCCESSFUL;\r
+        }\r
+    }\r
+\r
+    void CCq::CloseCq(void)\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        ib_api_status_t                        status;\r
+\r
+        if( m_uCq && m_pParent->m_Ifc.user_verbs.pre_destroy_cq )\r
+        {\r
+            /* Pre call to the UVP library */\r
+            status = m_pParent->m_Ifc.user_verbs.pre_destroy_cq( m_uCq );\r
+            if( status != IB_SUCCESS )\r
+                return;\r
+        }\r
+\r
+        DWORD BytesRet;\r
+        BOOL fSuccess = DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_DESTROY_CQ,\r
+            &m_hCq,\r
+            sizeof(m_hCq),\r
+            &status,\r
+            sizeof(status),\r
+            &BytesRet,\r
+            NULL\r
+            );\r
+\r
+        if( fSuccess != TRUE || BytesRet != sizeof(status) )\r
+            status = IB_ERROR;\r
+\r
+        if( m_uCq && m_pParent->m_Ifc.user_verbs.post_destroy_cq )\r
+            m_pParent->m_Ifc.user_verbs.post_destroy_cq( m_uCq, status );\r
+    }\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdCq.h b/branches/winverbs/ulp/nd/user/NdCq.h
new file mode 100644 (file)
index 0000000..f4bdb79
--- /dev/null
@@ -0,0 +1,113 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+#include "ndspi.h"\r
+#include <iba/ib_al.h>\r
+#include "al_cq.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+    class CAdapter;\r
+\r
+    class CCq :\r
+        public INDCompletionQueue\r
+    {\r
+        friend class CEndpoint;\r
+    public:\r
+        CCq(void);\r
+        ~CCq(void);\r
+\r
+        HRESULT Initialize(\r
+            CAdapter* pParent,\r
+            SIZE_T nEntries );\r
+\r
+        // *** IUnknown methods ***\r
+        HRESULT STDMETHODCALLTYPE QueryInterface(\r
+            REFIID riid,\r
+            LPVOID FAR* ppvObj\r
+            );\r
+\r
+        ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+        ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+        // *** INDOverlapped methods ***\r
+        HRESULT STDMETHODCALLTYPE CancelOverlappedRequests(void);\r
+\r
+        HRESULT STDMETHODCALLTYPE GetOverlappedResult(\r
+            __inout_opt OVERLAPPED *pOverlapped,\r
+            __out SIZE_T *pNumberOfBytesTransferred,\r
+            __in BOOL bWait\r
+            );\r
+\r
+        // *** INDCompletionQueue methods ***\r
+        HANDLE STDMETHODCALLTYPE GetAdapterFileHandle(void);\r
+\r
+        HRESULT STDMETHODCALLTYPE Close(void);\r
+\r
+        HRESULT STDMETHODCALLTYPE Resize(\r
+            __in SIZE_T nEntries\r
+            );\r
+\r
+        HRESULT STDMETHODCALLTYPE Notify(\r
+            __in DWORD Type,\r
+            __inout_opt OVERLAPPED* pOverlapped\r
+            );\r
+\r
+        SIZE_T STDMETHODCALLTYPE GetResults(\r
+            __out_ecount(nResults) ND_RESULT* pResults[],\r
+            __in SIZE_T nResults\r
+            );\r
+\r
+    private:\r
+        HRESULT CreateCq(\r
+            __in UINT32 nEntries );\r
+\r
+        HRESULT Complete(\r
+            __in HRESULT Status );\r
+\r
+        HRESULT ModifyCq(\r
+            __in SIZE_T nEntries );\r
+\r
+        void CloseCq(void);\r
+\r
+    private:\r
+        volatile LONG m_nRef;\r
+\r
+        CAdapter* m_pParent;\r
+\r
+        UINT64 m_hCq;\r
+        ib_cq_handle_t m_uCq;\r
+    };\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdEndpoint.cpp b/branches/winverbs/ulp/nd/user/NdEndpoint.cpp
new file mode 100644 (file)
index 0000000..3325477
--- /dev/null
@@ -0,0 +1,944 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdEndpoint.h"\r
+#include "NdCq.h"\r
+#include "NdAdapter.h"\r
+#include "NdMr.h"\r
+#include "NdListen.h"\r
+#include "limits.h"\r
+#include "al_dev.h"\r
+#pragma warning( push, 3 )\r
+#include "winternl.h"\r
+#pragma warning( pop )\r
+#include "nddebug.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdEndpoint.tmh"\r
+#endif\r
+\r
+#if DBG\r
+dbg_data g = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };\r
+#endif\r
+\r
+#ifndef SIZE_MAX\r
+#ifdef _WIN64\r
+#define SIZE_MAX _UI64_MAX\r
+#else\r
+#define SIZE_MAX UINT_MAX\r
+#endif\r
+#endif\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// HPC Pack 2008 Beta 2 SPI\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+\r
+CEndpoint::CEndpoint(void) :\r
+    m_nRef( 1 ),\r
+    m_pParent( NULL ),\r
+    m_hQp( 0 )\r
+{\r
+}\r
+\r
+CEndpoint::~CEndpoint(void)\r
+{\r
+    if( m_hQp )\r
+        DestroyQp();\r
+\r
+    if( m_pParent )\r
+        m_pParent->Release();\r
+}\r
+\r
+HRESULT CEndpoint::Initialize(\r
+    __in CAdapter* pParent,\r
+    __in CCq* pInboundCq,\r
+    __in CCq* pOutboundCq,\r
+    __in SIZE_T nInboundEntries,\r
+    __in SIZE_T nOutboundEntries,\r
+    __in SIZE_T nInboundSge,\r
+    __in SIZE_T nOutboundSge,\r
+    __in SIZE_T InboundReadLimit,\r
+    __in SIZE_T OutboundReadLimit,\r
+    __out_opt SIZE_T* pMaxInlineData\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( InboundReadLimit > UCHAR_MAX )\r
+        return ND_INVALID_PARAMETER_8;\r
+\r
+    if( OutboundReadLimit > UCHAR_MAX )\r
+        return ND_INVALID_PARAMETER_9;\r
+\r
+    m_pParent = pParent;\r
+    m_pParent->AddRef();\r
+\r
+    CL_ASSERT(\r
+        m_pParent->m_Ifc.user_verbs.pre_create_qp != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_create_qp != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.nd_modify_qp != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.nd_get_qp_state != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.pre_destroy_qp != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_destroy_qp != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_send != NULL ||\r
+        m_pParent->m_Ifc.user_verbs.post_recv != NULL /*||\r
+        m_pParent->m_Ifc.user_verbs.bind_mw != NULL*/ );\r
+\r
+    HRESULT hr = CreateQp(\r
+        pInboundCq,\r
+        pOutboundCq,\r
+        nInboundEntries,\r
+        nOutboundEntries,\r
+        nInboundSge,\r
+        nOutboundSge,\r
+        InboundReadLimit,\r
+        OutboundReadLimit );\r
+\r
+    if( FAILED( hr ) )\r
+        return hr;\r
+\r
+    m_Ird = (UINT8)InboundReadLimit;\r
+    m_Ord = (UINT8)OutboundReadLimit;\r
+\r
+    // Move the QP to the INIT state so users can post receives.\r
+    hr = ModifyQp( IB_QPS_INIT );\r
+    if( FAILED( hr ) )\r
+        DestroyQp();\r
+\r
+    if( SUCCEEDED( hr ) && pMaxInlineData != NULL )\r
+    {\r
+        // Worst case.\r
+        *pMaxInlineData = nOutboundSge * 12;\r
+    }\r
+\r
+    return hr;\r
+}\r
+\r
+HRESULT CEndpoint::Create(\r
+    __in CAdapter* pParent,\r
+    __in CCq* pInboundCq,\r
+    __in CCq* pOutboundCq,\r
+    __in SIZE_T nInboundEntries,\r
+    __in SIZE_T nOutboundEntries,\r
+    __in SIZE_T nInboundSge,\r
+    __in SIZE_T nOutboundSge,\r
+    __in SIZE_T InboundReadLimit,\r
+    __in SIZE_T OutboundReadLimit,\r
+    __out_opt SIZE_T* pMaxInlineData,\r
+    __out INDEndpoint** ppEndpoint\r
+    )\r
+{\r
+    CEndpoint* pEp = new CEndpoint();\r
+    if( pEp == NULL )\r
+        return ND_NO_MEMORY;\r
+\r
+    HRESULT hr = pEp->Initialize(\r
+        pParent,\r
+        pInboundCq,\r
+        pOutboundCq,\r
+        nInboundEntries,\r
+        nOutboundEntries,\r
+        nInboundSge,\r
+        nOutboundSge,\r
+        InboundReadLimit,\r
+        OutboundReadLimit,\r
+        pMaxInlineData\r
+        );\r
+\r
+    if( FAILED( hr ) )\r
+    {\r
+        pEp->Release();\r
+        return hr;\r
+    }\r
+\r
+    *ppEndpoint = pEp;\r
+    return ND_SUCCESS;\r
+}\r
+\r
+HRESULT CEndpoint::QueryInterface(\r
+    REFIID riid,\r
+    LPVOID FAR* ppvObj\r
+    )\r
+{\r
+    if( IsEqualIID( riid, IID_IUnknown ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    if( IsEqualIID( riid, IID_INDEndpoint ) )\r
+    {\r
+        *ppvObj = this;\r
+        return S_OK;\r
+    }\r
+\r
+    return E_NOINTERFACE;\r
+}\r
+\r
+ULONG CEndpoint::AddRef(void)\r
+{\r
+    return InterlockedIncrement( &m_nRef );\r
+}\r
+\r
+ULONG CEndpoint::Release(void)\r
+{\r
+    ULONG ref = InterlockedDecrement( &m_nRef );\r
+    if( ref == 0 )\r
+        delete this;\r
+\r
+    return ref;\r
+}\r
+\r
+// *** INDEndpoint methods ***\r
+HRESULT CEndpoint::Flush(void)\r
+{\r
+    return ModifyQp( IB_QPS_ERROR );\r
+}\r
+\r
+void CEndpoint::StartRequestBatch(void)\r
+{\r
+    return;\r
+}\r
+\r
+void CEndpoint::SubmitRequestBatch(void)\r
+{\r
+    return;\r
+}\r
+\r
+HRESULT CEndpoint::Send(\r
+    __out ND_RESULT* pResult,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+    ib_send_wr_t wr;\r
+    ib_local_ds_t* pDs;\r
+    ib_local_ds_t ds[4];\r
+\r
+    if( nSge > UINT_MAX )\r
+        return ND_DATA_OVERRUN;\r
+    else if( nSge <= 4 )\r
+        pDs = ds;\r
+    else\r
+    {\r
+        pDs = new ib_local_ds_t[nSge];\r
+        if( !pDs )\r
+            return ND_NO_MEMORY;\r
+    }\r
+\r
+    pResult->BytesTransferred = 0;\r
+    for( SIZE_T i = 0; i < nSge; i++ )\r
+    {\r
+        pDs[i].vaddr = (ULONG_PTR)pSgl[i].pAddr;\r
+        if( pSgl[i].Length > UINT_MAX )\r
+        {\r
+            if( nSge > 4 )\r
+                delete[] pDs;\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        pDs[i].length = (uint32_t)pSgl[i].Length;\r
+        pDs[i].lkey = ((CMr*)pSgl[i].hMr)->mr_ioctl.out.lkey;\r
+\r
+        // Send completions don't include the length.  It's going to\r
+        // be all or nothing, so store it now and we can reset if the\r
+        // request fails.\r
+        pResult->BytesTransferred += pSgl[i].Length;\r
+    }\r
+\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.wr_type = WR_SEND;\r
+    wr.send_opt = 0;\r
+    if( !(Flags & ND_OP_FLAG_SILENT_SUCCESS) )\r
+        wr.send_opt |= IB_SEND_OPT_SIGNALED;\r
+    if( Flags & ND_OP_FLAG_READ_FENCE )\r
+        wr.send_opt |= IB_SEND_OPT_FENCE;\r
+    if( Flags & ND_OP_FLAG_SEND_AND_SOLICIT_EVENT )\r
+        wr.send_opt |= IB_SEND_OPT_SOLICITED;\r
+    wr.num_ds = (uint32_t)nSge;\r
+    wr.ds_array = pDs;\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_send( m_uQp, &wr, NULL );\r
+    if( nSge > 4 )\r
+        delete[] pDs;\r
+\r
+    // leo\r
+    CL_ASSERT( nSge || pSgl == NULL );\r
+#if DBG\r
+    if (!status )\r
+    {\r
+        if (pSgl)\r
+        {\r
+            ++g.snd_pkts;\r
+            g.snd_bytes += pSgl[0].Length;\r
+        }\r
+        else\r
+            ++g.snd_pkts_zero;\r
+    }\r
+    else\r
+        ++g.snd_pkts_err;\r
+#endif\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_MAX_SGE:\r
+        return ND_DATA_OVERRUN;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::SendAndInvalidate(\r
+    __out ND_RESULT* pResult,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge,\r
+    __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    ib_send_wr_t wr;\r
+    ib_local_ds_t* pDs;\r
+\r
+    if( nSge > UINT_MAX )\r
+        return ND_DATA_OVERRUN;\r
+\r
+    pDs = new ib_local_ds_t[nSge];\r
+    if( !pDs )\r
+        return ND_NO_MEMORY;\r
+\r
+    pResult->BytesTransferred = 0;\r
+    for( SIZE_T i = 0; i < nSge; i++ )\r
+    {\r
+        pDs[i].vaddr = (ULONG_PTR)pSgl[i].pAddr;\r
+        if( pSgl[i].Length > UINT_MAX )\r
+        {\r
+            delete[] pDs;\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        pDs[i].length = (uint32_t)pSgl[i].Length;\r
+        pDs[i].lkey = ((CMr*)pSgl[i].hMr)->mr_ioctl.out.lkey;\r
+\r
+        // Send completions don't include the length.  It's going to\r
+        // be all or nothing, so store it now and we can reset if the\r
+        // request fails.\r
+        pResult->BytesTransferred += pSgl[i].Length;\r
+    }\r
+\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.wr_type = WR_SEND;\r
+    // We simulate invalidate operations (since we simulate MW use).  We\r
+    // put the RKey in the immediate data, the recipient will do the\r
+    // lookup of the MW based on that (as they would with a regular\r
+    // invalidate request).\r
+    wr.send_opt = IB_SEND_OPT_IMMEDIATE;\r
+    if( !(Flags & ND_OP_FLAG_SILENT_SUCCESS) )\r
+        wr.send_opt |= IB_SEND_OPT_SIGNALED;\r
+    if( Flags & ND_OP_FLAG_READ_FENCE )\r
+        wr.send_opt |= IB_SEND_OPT_FENCE;\r
+    if( Flags & ND_OP_FLAG_SEND_AND_SOLICIT_EVENT )\r
+        wr.send_opt |= IB_SEND_OPT_SOLICITED;\r
+    wr.num_ds = (uint32_t)nSge;\r
+    wr.ds_array = pDs;\r
+    // Put the RKey in the immeditate data.\r
+    wr.immediate_data = pRemoteMwDescriptor->Token;\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_send( m_uQp, &wr, NULL );\r
+    delete[] pDs;\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_MAX_SGE:\r
+        return ND_DATA_OVERRUN;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::Receive(\r
+    __out ND_RESULT* pResult,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge\r
+    )\r
+{\r
+#if DBG    \r
+    if (!(++g.rcv_cnt % 1000))\r
+        ND_PRINT( TRACE_LEVEL_VERBOSE, ND_DBG_NDI,\r
+            ("==> %s, cnt %I64d, rcv %I64d:%I64d:%I64d:%I64d\n",\r
+            __FUNCTION__, g.rcv_cnt, g.rcv_pkts, g.rcv_bytes, g.rcv_pkts_err, g.rcv_pkts_zero ));\r
+#endif\r
+    ib_recv_wr_t wr;\r
+    ib_local_ds_t* pDs;\r
+    ib_local_ds_t ds[4];\r
+\r
+    if( nSge > UINT_MAX )\r
+        return ND_DATA_OVERRUN;\r
+    else if( nSge <= 4 )\r
+        pDs = ds;\r
+    else\r
+    {\r
+        pDs = new ib_local_ds_t[nSge];\r
+        if( !pDs )\r
+            return ND_NO_MEMORY;\r
+    }\r
+\r
+    for( SIZE_T i = 0; i < nSge; i++ )\r
+    {\r
+        pDs[i].vaddr = (ULONG_PTR)pSgl[i].pAddr;\r
+        if( pSgl[i].Length > UINT_MAX )\r
+        {\r
+            if( nSge > 4 )\r
+                delete[] pDs;\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        pDs[i].length = (uint32_t)pSgl[i].Length;\r
+        pDs[i].lkey = ((CMr*)pSgl[i].hMr)->mr_ioctl.out.lkey;\r
+    }\r
+\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.num_ds = (uint32_t)nSge;\r
+    wr.ds_array = pDs;\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_recv( m_uQp, &wr, NULL );\r
+\r
+    if( nSge > 4 )\r
+        delete[] pDs;\r
+\r
+    // leo\r
+    CL_ASSERT( nSge || pSgl == NULL );\r
+#if DBG\r
+    if (!status)\r
+    {\r
+        if (pSgl)\r
+        {\r
+            ++g.rcv_pkts;\r
+            g.rcv_bytes += pSgl[0].Length;\r
+        }\r
+        else\r
+            ++g.rcv_pkts_zero;\r
+    }\r
+    else\r
+        ++g.rcv_pkts_err;\r
+#endif\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_MAX_SGE:\r
+        return ND_DATA_OVERRUN;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::Bind(\r
+    __out ND_RESULT* pResult,\r
+    __in ND_MR_HANDLE hMr,\r
+    __in INDMemoryWindow* pMw,\r
+    __in_bcount(BufferSize) const void* pBuffer,\r
+    __in SIZE_T BufferSize,\r
+    __in DWORD Flags,\r
+    __out ND_MW_DESCRIPTOR* pMwDescriptor\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    UNREFERENCED_PARAMETER( pMw );\r
+    UNREFERENCED_PARAMETER( Flags );\r
+\r
+    CMr* pMr = ((CMr*)hMr);\r
+\r
+    if( pBuffer < pMr->pBase ||\r
+        pBuffer > pMr->pBase + pMr->Length )\r
+    {\r
+        return ND_INVALID_PARAMETER_4;\r
+    }\r
+\r
+    if( ((const char*)pBuffer + BufferSize) > (pMr->pBase + pMr->Length) )\r
+    {\r
+        return ND_INVALID_PARAMETER_5;\r
+    }\r
+\r
+    // Ok, this here is a workaround since the Mellanox HCA driver doesn't\r
+    // support MWs.  This should be pushed into the HCA driver.\r
+    pMwDescriptor->Base = _byteswap_uint64( (UINT64)(ULONG_PTR)pBuffer );\r
+    pMwDescriptor->Length = _byteswap_uint64( BufferSize );\r
+    pMwDescriptor->Token = pMr->mr_ioctl.out.rkey;\r
+\r
+    // Zero-byte RDMA write.  Could also be a no-op on the send queue\r
+    // which would be better, but requires changing the HCA driver.\r
+    ib_send_wr_t wr;\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.wr_type = WR_RDMA_WRITE;\r
+    wr.send_opt = IB_SEND_OPT_SIGNALED;\r
+    wr.num_ds = 0;\r
+    wr.ds_array = NULL;\r
+\r
+    wr.remote_ops.vaddr = 0;\r
+    wr.remote_ops.rkey = 0;\r
+\r
+    pResult->BytesTransferred = 0;\r
+\r
+    // TODO: Track the MW by rkey, so we can unbind it.\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_send( m_uQp, &wr, NULL );\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::Invalidate(\r
+    __out ND_RESULT* pResult,\r
+    __in INDMemoryWindow* pMw,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    UNREFERENCED_PARAMETER( pMw );\r
+    UNREFERENCED_PARAMETER( Flags );\r
+\r
+    // Zero-byte RDMA write.  Could also be a no-op on the send queue\r
+    // which would be better, but requires changing the HCA driver.\r
+    ib_send_wr_t wr;\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.wr_type = WR_RDMA_WRITE;\r
+    wr.send_opt = IB_SEND_OPT_SIGNALED;\r
+    wr.num_ds = 0;\r
+    wr.ds_array = NULL;\r
+\r
+    wr.remote_ops.vaddr = 0;\r
+    wr.remote_ops.rkey = 0;\r
+\r
+    pResult->BytesTransferred = 0;\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_send( m_uQp, &wr, NULL );\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        // TODO: Stop trackign MW\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::Rdma(\r
+    __out ND_RESULT* pResult,\r
+    __in ib_wr_type_t Type,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge,\r
+    __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+    __in ULONGLONG Offset,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+//        ND_ENTER( ND_DBG_NDI );\r
+\r
+    ib_send_wr_t wr;\r
+    ib_local_ds_t* pDs;\r
+    ib_local_ds_t ds[4];\r
+\r
+    if( nSge > UINT_MAX )\r
+        return ND_DATA_OVERRUN;\r
+    else if( nSge <= 4 )\r
+        pDs = ds;\r
+    else\r
+    {\r
+        pDs = new ib_local_ds_t[nSge];\r
+        if( !pDs )\r
+            return ND_NO_MEMORY;\r
+    }\r
+\r
+    pResult->BytesTransferred = 0;\r
+    for( SIZE_T i = 0; i < nSge; i++ )\r
+    {\r
+        pDs[i].vaddr = (ULONG_PTR)pSgl[i].pAddr;\r
+        if( pSgl[i].Length > UINT_MAX )\r
+        {\r
+            if( nSge > 4 )\r
+                delete[] pDs;\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+        pDs[i].length = (uint32_t)pSgl[i].Length;\r
+        pDs[i].lkey = ((CMr*)pSgl[i].hMr)->mr_ioctl.out.lkey;\r
+\r
+        //TODO: temporary - a workaround of test bug\r
+        //leo\r
+        if( (int)pSgl[i].Length < 0 )\r
+        {\r
+            pDs[i].length = 0 - (int)pSgl[i].Length;\r
+#if DBG                \r
+            ND_PRINT( TRACE_LEVEL_VERBOSE, ND_DBG_NDI,\r
+                ("nSge %d, i %d, Length %#x\n", nSge, i, pSgl[i].Length ));\r
+            if( nSge > 4 )\r
+                delete[] pDs;\r
+            return ND_BUFFER_OVERFLOW;\r
+#endif                \r
+        }\r
+\r
+        // Send completions don't include the length.  It's going to\r
+        // be all or nothing, so store it now and we can reset if the\r
+        // request fails.\r
+        pResult->BytesTransferred += pSgl[i].Length;\r
+    }\r
+\r
+    wr.p_next = NULL;\r
+    wr.wr_id = (ULONG_PTR)pResult;\r
+    wr.wr_type = Type;\r
+    wr.send_opt = 0;\r
+    if( !(Flags & ND_OP_FLAG_SILENT_SUCCESS) )\r
+        wr.send_opt |= IB_SEND_OPT_SIGNALED;\r
+    if( Flags & ND_OP_FLAG_READ_FENCE )\r
+        wr.send_opt |= IB_SEND_OPT_FENCE;\r
+    wr.num_ds = (uint32_t)nSge;\r
+    wr.ds_array = pDs;\r
+\r
+    UINT64 vaddr = _byteswap_uint64( pRemoteMwDescriptor->Base );\r
+    vaddr += Offset;\r
+    wr.remote_ops.vaddr = vaddr;\r
+    wr.remote_ops.rkey = pRemoteMwDescriptor->Token;\r
+\r
+    ib_api_status_t status =\r
+        m_pParent->m_Ifc.user_verbs.post_send( m_uQp, &wr, NULL );\r
+\r
+    if( nSge > 4 )\r
+        delete[] pDs;\r
+\r
+    switch( status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return S_OK;\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return ND_NO_MORE_ENTRIES;\r
+    case IB_INVALID_MAX_SGE:\r
+        return ND_DATA_OVERRUN;\r
+    case IB_INVALID_QP_STATE:\r
+        return ND_CONNECTION_INVALID;\r
+    default:\r
+        return ND_UNSUCCESSFUL;\r
+    }\r
+}\r
+\r
+HRESULT CEndpoint::Read(\r
+    __out ND_RESULT* pResult,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge,\r
+    __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+    __in ULONGLONG Offset,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+//        ND_ENTER( ND_DBG_NDI );\r
+\r
+    return Rdma( pResult, WR_RDMA_READ, pSgl, nSge,\r
+        pRemoteMwDescriptor, Offset, Flags );\r
+}\r
+\r
+HRESULT CEndpoint::Write(\r
+    __out ND_RESULT* pResult,\r
+    __in_ecount(nSge) const ND_SGE* pSgl,\r
+    __in SIZE_T nSge,\r
+    __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+    __in ULONGLONG Offset,\r
+    __in DWORD Flags\r
+    )\r
+{\r
+//        ND_ENTER( ND_DBG_NDI );\r
+\r
+    return Rdma( pResult, WR_RDMA_WRITE, pSgl, nSge,\r
+        pRemoteMwDescriptor, Offset, Flags );\r
+}\r
+\r
+HRESULT CEndpoint::CreateQp(\r
+    __in CCq* pInboundCq,\r
+    __in CCq* pOutboundCq,\r
+    __in SIZE_T nInboundEntries,\r
+    __in SIZE_T nOutboundEntries,\r
+    __in SIZE_T nInboundSge,\r
+    __in SIZE_T nOutboundSge,\r
+    __in SIZE_T InboundReadLimit,\r
+    __in SIZE_T OutboundReadLimit\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( nInboundEntries > UINT_MAX )\r
+        return ND_INVALID_PARAMETER_4;\r
+    if( nOutboundEntries > UINT_MAX )\r
+        return ND_INVALID_PARAMETER_5;\r
+    if( nInboundSge > UINT_MAX )\r
+        return ND_INVALID_PARAMETER_6;\r
+    if( nOutboundSge > UINT_MAX )\r
+        return ND_INVALID_PARAMETER_7;\r
+    if( InboundReadLimit > UCHAR_MAX )\r
+        return ND_INVALID_PARAMETER_9;\r
+    if( OutboundReadLimit > UCHAR_MAX )\r
+        return ND_INVALID_PARAMETER_10;\r
+\r
+    /* Setup the qp_ioctl */\r
+    ual_create_qp_ioctl_t qp_ioctl;\r
+    cl_memclr( &qp_ioctl, sizeof(qp_ioctl) );\r
+\r
+    qp_ioctl.in.qp_create.qp_type = IB_QPT_RELIABLE_CONN;\r
+    qp_ioctl.in.qp_create.sq_depth = (uint32_t)nOutboundEntries;\r
+    qp_ioctl.in.qp_create.rq_depth = (uint32_t)nInboundEntries;\r
+    qp_ioctl.in.qp_create.sq_sge = (uint32_t)nOutboundSge;\r
+    qp_ioctl.in.qp_create.rq_sge = (uint32_t)nInboundSge;\r
+    qp_ioctl.in.qp_create.h_srq = NULL;\r
+    qp_ioctl.in.qp_create.sq_signaled = FALSE;\r
+\r
+    /* Pre call to the UVP library */\r
+    CL_ASSERT( m_pParent->m_Ifc.user_verbs.pre_create_qp );\r
+    qp_ioctl.in.qp_create.h_sq_cq = pOutboundCq->m_uCq;\r
+    qp_ioctl.in.qp_create.h_rq_cq = pInboundCq->m_uCq;\r
+    ib_api_status_t status = m_pParent->m_Ifc.user_verbs.pre_create_qp(\r
+        m_pParent->m_uPd,\r
+        &qp_ioctl.in.qp_create,\r
+        &qp_ioctl.in.umv_buf,\r
+        (ib_qp_handle_t*)(ULONG_PTR)&m_uQp\r
+        );\r
+    if( status != IB_SUCCESS )\r
+        return ND_INSUFFICIENT_RESOURCES;\r
+\r
+    /*\r
+    * Convert the handles to KAL handles once again starting\r
+    * from the input qp attribute\r
+    */\r
+    qp_ioctl.in.h_pd = m_pParent->m_hPd;\r
+    qp_ioctl.in.qp_create.h_sq_cq = (ib_cq_handle_t)pOutboundCq->m_hCq;\r
+    qp_ioctl.in.qp_create.h_rq_cq = (ib_cq_handle_t)pInboundCq->m_hCq;\r
+    qp_ioctl.in.context = (ULONG_PTR)this;\r
+    qp_ioctl.in.ev_notify = FALSE;\r
+\r
+    DWORD bytes_ret;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_pParent->m_hSync,\r
+        UAL_CREATE_QP,\r
+        &qp_ioctl.in,\r
+        sizeof(qp_ioctl.in),\r
+        &qp_ioctl.out,\r
+        sizeof(qp_ioctl.out),\r
+        &bytes_ret,\r
+        NULL );\r
+\r
+    if( fSuccess != TRUE || bytes_ret != sizeof(qp_ioctl.out) )\r
+        qp_ioctl.out.status = IB_ERROR;\r
+\r
+    /* Post uvp call */\r
+    CL_ASSERT( m_pParent->m_Ifc.user_verbs.post_create_qp );\r
+    m_pParent->m_Ifc.user_verbs.post_create_qp(\r
+        m_pParent->m_uPd,\r
+        qp_ioctl.out.status,\r
+        (ib_qp_handle_t*)(ULONG_PTR)&m_uQp,\r
+        &qp_ioctl.out.umv_buf\r
+        );\r
+\r
+\r
+    switch( qp_ioctl.out.status )\r
+    {\r
+    case IB_SUCCESS:\r
+        m_hQp = qp_ioctl.out.h_qp;\r
+        m_Qpn = qp_ioctl.out.attr.num;\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("Created QP %#I64x, QPn %#x, pd %#I64x, context %p \n", \r
+            m_hQp, m_Qpn, m_pParent->m_hPd, this ) );\r
+        return S_OK;\r
+\r
+    case IB_INVALID_MAX_WRS:\r
+        if( nInboundEntries > nOutboundEntries )\r
+            return ND_INVALID_PARAMETER_4;\r
+        else\r
+            return ND_INVALID_PARAMETER_5;\r
+\r
+    case IB_INVALID_MAX_SGE:\r
+        if( nInboundSge > nOutboundSge )\r
+            return ND_INVALID_PARAMETER_6;\r
+        else\r
+            return ND_INVALID_PARAMETER_7;\r
+\r
+    case IB_INSUFFICIENT_MEMORY:\r
+        return ND_NO_MEMORY;\r
+\r
+    default:\r
+        return ND_INSUFFICIENT_RESOURCES;\r
+    }\r
+}\r
+\r
+void CEndpoint::DestroyQp()\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    /* Call the uvp pre call if the vendor library provided a valid QP handle */\r
+    CL_ASSERT( m_pParent->m_Ifc.user_verbs.pre_destroy_qp );\r
+    m_pParent->m_Ifc.user_verbs.pre_destroy_qp( m_uQp );\r
+\r
+    ual_destroy_qp_ioctl_t qp_ioctl;\r
+    cl_memclr( &qp_ioctl, sizeof(qp_ioctl) );\r
+    qp_ioctl.in.h_qp = m_hQp;\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Destroy QP %I64x\n", m_hQp) );\r
+\r
+    DWORD bytes_ret;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_pParent->m_hSync,\r
+        UAL_DESTROY_QP,\r
+        &qp_ioctl.in,\r
+        sizeof(qp_ioctl.in),\r
+        &qp_ioctl.out,\r
+        sizeof(qp_ioctl.out),\r
+        &bytes_ret,\r
+        NULL\r
+        );\r
+\r
+    if( fSuccess != TRUE || bytes_ret != sizeof(qp_ioctl.out) )\r
+        qp_ioctl.out.status = IB_ERROR;\r
+\r
+    ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+        ("Destroyed QP %#I64x, QPn %#x, pd %#I64x, context %p \n", \r
+        m_hQp, m_Qpn, m_pParent->m_hPd, this ) );\r
+        \r
+    /* Call vendor's post_destroy_qp */\r
+    CL_ASSERT( m_pParent->m_Ifc.user_verbs.post_destroy_qp );\r
+    m_pParent->m_Ifc.user_verbs.post_destroy_qp(\r
+        m_uQp,\r
+        qp_ioctl.out.status\r
+        );\r
+    m_hQp = NULL;\r
+}\r
+\r
+HRESULT CEndpoint::ModifyQp(\r
+    __in ib_qp_state_t NewState )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    /* Setup the qp_ioctl */\r
+    ual_ndi_modify_qp_ioctl_in_t qp_ioctl;\r
+    cl_memclr( &qp_ioctl, sizeof(qp_ioctl) );\r
+\r
+    switch( NewState )\r
+    {\r
+    case IB_QPS_INIT:\r
+        qp_ioctl.qp_mod.state.init.primary_port = m_pParent->m_PortNum;\r
+        qp_ioctl.qp_mod.state.init.qkey = 0;\r
+        qp_ioctl.qp_mod.state.init.pkey_index = 0;\r
+        qp_ioctl.qp_mod.state.init.access_ctrl =\r
+            IB_AC_LOCAL_WRITE | IB_AC_RDMA_READ | IB_AC_RDMA_WRITE;\r
+\r
+        // Fall through.\r
+    case IB_QPS_RESET:\r
+    case IB_QPS_ERROR:\r
+        qp_ioctl.qp_mod.req_state = NewState;\r
+    }\r
+\r
+    /* Call the uvp ND modify verb */\r
+    CL_ASSERT( m_pParent->m_Ifc.user_verbs.nd_modify_qp );\r
+    void* pOutbuf;\r
+    DWORD szOutbuf;\r
+\r
+    m_pParent->m_Ifc.user_verbs.nd_modify_qp(\r
+        m_uQp,\r
+        &pOutbuf,\r
+        &szOutbuf\r
+        );\r
+\r
+    qp_ioctl.h_qp = m_hQp;\r
+\r
+    DWORD bytes_ret;\r
+    BOOL fSuccess = DeviceIoControl(\r
+        m_pParent->m_hSync,\r
+        UAL_NDI_MODIFY_QP,\r
+        &qp_ioctl,\r
+        sizeof(qp_ioctl),\r
+        pOutbuf,\r
+        szOutbuf,\r
+        &bytes_ret,\r
+        NULL );\r
+\r
+    if( fSuccess != TRUE )\r
+        return ND_UNSUCCESSFUL;\r
+\r
+    return S_OK;\r
+}\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdEndpoint.h b/branches/winverbs/ulp/nd/user/NdEndpoint.h
new file mode 100644 (file)
index 0000000..f47a6c3
--- /dev/null
@@ -0,0 +1,202 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+#include "ndspi.h"\r
+#include <iba/ib_al.h>\r
+#include <ws2tcpip.h>\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// HPC Pack 2008 Beta 2 SPI\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+class CAdapter;\r
+class CCq;\r
+\r
+class CEndpoint :\r
+    public INDEndpoint\r
+{\r
+    friend class CConnector;\r
+\r
+private:\r
+    CEndpoint(void);\r
+    ~CEndpoint(void);\r
+\r
+    HRESULT Initialize(\r
+        __in CAdapter* pParent,\r
+        __in CCq* pInboundCq,\r
+        __in CCq* pOutboundCq,\r
+        __in SIZE_T nInboundEntries,\r
+        __in SIZE_T nOutboundEntries,\r
+        __in SIZE_T nInboundSge,\r
+        __in SIZE_T nOutboundSge,\r
+        __in SIZE_T InboundReadLimit,\r
+        __in SIZE_T OutboundReadLimit,\r
+        __out_opt SIZE_T* pMaxInlineData\r
+        );\r
+\r
+public:\r
+    static HRESULT Create(\r
+        __in CAdapter* pParent,\r
+        __in CCq* pInboundCq,\r
+        __in CCq* pOutboundCq,\r
+        __in SIZE_T nInboundEntries,\r
+        __in SIZE_T nOutboundEntries,\r
+        __in SIZE_T nInboundSge,\r
+        __in SIZE_T nOutboundSge,\r
+        __in SIZE_T InboundReadLimit,\r
+        __in SIZE_T OutboundReadLimit,\r
+        __out_opt SIZE_T* pMaxInlineData,\r
+        __out INDEndpoint** ppEndpoint\r
+        );\r
+\r
+    // *** IUnknown methods ***\r
+    HRESULT STDMETHODCALLTYPE QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        );\r
+\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // *** INDEndpoint methods ***\r
+    HRESULT STDMETHODCALLTYPE Flush(void);\r
+\r
+    void STDMETHODCALLTYPE StartRequestBatch(void);\r
+\r
+    void STDMETHODCALLTYPE SubmitRequestBatch(void);\r
+\r
+    HRESULT STDMETHODCALLTYPE Send(\r
+        __out ND_RESULT* pResult,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge,\r
+        __in DWORD Flags\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE SendAndInvalidate(\r
+        __out ND_RESULT* pResult,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge,\r
+        __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+        __in DWORD Flags\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Receive(\r
+        __out ND_RESULT* pResult,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Bind(\r
+        __out ND_RESULT* pResult,\r
+        __in ND_MR_HANDLE hMr,\r
+        __in INDMemoryWindow* pMw,\r
+        __in_bcount(BufferSize) const void* pBuffer,\r
+        __in SIZE_T BufferSize,\r
+        __in DWORD Flags,\r
+        __out ND_MW_DESCRIPTOR* pMwDescriptor\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Invalidate(\r
+        __out ND_RESULT* pResult,\r
+        __in INDMemoryWindow* pMw,\r
+        __in DWORD Flags\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Read(\r
+        __out ND_RESULT* pResult,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge,\r
+        __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+        __in ULONGLONG Offset,\r
+        __in DWORD Flags\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE Write(\r
+        __out ND_RESULT* pResult,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge,\r
+        __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+        __in ULONGLONG Offset,\r
+        __in DWORD Flags\r
+        );\r
+\r
+private:\r
+    HRESULT Rdma(\r
+        __out ND_RESULT* pResult,\r
+        __in ib_wr_type_t Type,\r
+        __in_ecount(nSge) const ND_SGE* pSgl,\r
+        __in SIZE_T nSge,\r
+        __in const ND_MW_DESCRIPTOR* pRemoteMwDescriptor,\r
+        __in ULONGLONG Offset,\r
+        __in DWORD Flags\r
+        );\r
+\r
+    HRESULT CreateQp(\r
+        __in CCq* pInboundCq,\r
+        __in CCq* pOutboundCq,\r
+        __in SIZE_T nInboundEntries,\r
+        __in SIZE_T nOutboundEntries,\r
+        __in SIZE_T nInboundSge,\r
+        __in SIZE_T nOutboundSge,\r
+        __in SIZE_T InboundReadLimit,\r
+        __in SIZE_T OutboundReadLimit\r
+        );\r
+\r
+    void DestroyQp();\r
+\r
+    HRESULT ModifyQp(\r
+        __in ib_qp_state_t NewState\r
+        );\r
+\r
+protected:\r
+    volatile LONG m_nRef;\r
+\r
+    CAdapter* m_pParent;\r
+\r
+    uint64_t m_hQp;\r
+    ib_qp_handle_t m_uQp;\r
+\r
+    net32_t m_Qpn;\r
+\r
+    UINT8 m_Ird;\r
+    UINT8 m_Ord;\r
+};\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdListen.cpp b/branches/winverbs/ulp/nd/user/NdListen.cpp
new file mode 100644 (file)
index 0000000..82f0111
--- /dev/null
@@ -0,0 +1,385 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdListen.h"\r
+#include "NdAdapter.h"\r
+#include "NdEndpoint.h"\r
+#include "NdConnector.h"\r
+#include "al_dev.h"\r
+#pragma warning( push, 3 )\r
+#include "winternl.h"\r
+#pragma warning( pop )\r
+#include <complib/cl_byteswap.h>\r
+#include <limits.h>\r
+#include "nddebug.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdListen.tmh"\r
+#endif\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+HRESULT GetPdataForPassive(\r
+    __in UINT8* pSrc,\r
+    __in SIZE_T SrcLength,\r
+    __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+    __inout SIZE_T* pPrivateDataLength\r
+    )\r
+{\r
+    if( SrcLength != IB_REQ_PDATA_SIZE )\r
+    {\r
+        ND_PRINT( TRACE_LEVEL_ERROR, ND_DBG_NDI, \r
+            ("Connection aborted: incorrect pdata_len %d \n", (int)SrcLength ));\r
+        return ND_CONNECTION_ABORTED;\r
+    }\r
+\r
+    if( pPrivateDataLength == NULL )\r
+        return S_OK;\r
+\r
+    ib_cm_rdma_req_t* pIpData = (ib_cm_rdma_req_t*)pSrc;\r
+    CL_ASSERT( pIpData->maj_min_ver == 0 );\r
+    CL_ASSERT( pIpData->ipv == 0x40 || pIpData->ipv == 0x60 );\r
+\r
+    if( *pPrivateDataLength == 0 )\r
+    {\r
+        *pPrivateDataLength = sizeof(pIpData->pdata);\r
+        return ND_BUFFER_OVERFLOW;\r
+    }\r
+\r
+    CopyMemory(\r
+        pPrivateData,\r
+        pIpData->pdata,\r
+        min( *pPrivateDataLength, sizeof(pIpData->pdata) )\r
+        );\r
+\r
+    HRESULT hr;\r
+    if( *pPrivateDataLength < sizeof(pIpData->pdata) )\r
+    {\r
+        hr = ND_BUFFER_OVERFLOW;\r
+    }\r
+    else\r
+    {\r
+        hr = S_OK;\r
+    }\r
+\r
+    *pPrivateDataLength = sizeof(pIpData->pdata);\r
+    return hr;\r
+}\r
+\r
+HRESULT GetPdataForActive(\r
+    __in UINT8* pSrc,\r
+    __in SIZE_T SrcLength,\r
+    __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+    __inout SIZE_T* pPrivateDataLength\r
+    )\r
+{\r
+    if( pPrivateDataLength == NULL )\r
+        return S_OK;\r
+\r
+    if( *pPrivateDataLength == 0 )\r
+    {\r
+        *pPrivateDataLength = SrcLength;\r
+        return ND_BUFFER_OVERFLOW;\r
+    }\r
+\r
+    CopyMemory(\r
+        pPrivateData,\r
+        pSrc,\r
+        min( *pPrivateDataLength, SrcLength ) );\r
+\r
+    HRESULT hr;\r
+    if( *pPrivateDataLength < IB_REJ_PDATA_SIZE )\r
+    {\r
+        hr = ND_BUFFER_OVERFLOW;\r
+    }\r
+    else\r
+    {\r
+        hr = S_OK;\r
+    }\r
+\r
+    *pPrivateDataLength = SrcLength;\r
+    return hr;\r
+}\r
+\r
+    CListen::CListen(void) :\r
+        m_nRef( 1 ),\r
+        m_pParent( NULL ),\r
+        m_cid( 0 )\r
+    {\r
+    }\r
+\r
+    CListen::~CListen(void)\r
+    {\r
+        if( m_cid != 0 )\r
+        {\r
+            DWORD bytes_ret;\r
+            DeviceIoControl(\r
+                m_pParent->m_hSync,\r
+                UAL_DESTROY_CEP,\r
+                &m_cid,\r
+                sizeof(m_cid),\r
+                NULL,\r
+                0,\r
+                &bytes_ret,\r
+                NULL );\r
+        }\r
+\r
+        if( m_pParent )\r
+            m_pParent->Release();\r
+    }\r
+\r
+    HRESULT CListen::Initialize(\r
+        __in CAdapter* pParent,\r
+        __in SIZE_T Backlog,\r
+        __in INT Protocol,\r
+        __in USHORT Port,\r
+        __out_opt USHORT* pAssignedPort\r
+        )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        m_pParent = pParent;\r
+        m_pParent->AddRef();\r
+\r
+        UNREFERENCED_PARAMETER( Backlog );\r
+\r
+        if( Port == 0 && pAssignedPort == NULL )\r
+            return ND_INVALID_PARAMETER_MIX;\r
+\r
+        //\r
+        // IP Addressing Annex only supports a single byte for protocol.\r
+        //\r
+        if( Protocol > UCHAR_MAX || Protocol < 0 )\r
+            return ND_INVALID_PARAMETER_3;\r
+\r
+        ual_cep_listen_ioctl_t listen;\r
+        listen.cid = 0;\r
+\r
+        listen.cep_listen.svc_id = \r
+            0x0000000001000000 | Protocol << 16 | Port;\r
+\r
+        listen.cep_listen.port_guid = m_pParent->m_PortGuid;\r
+\r
+        switch( m_pParent->m_Addr.v4.sin_family )\r
+        {\r
+        case AF_INET:\r
+            ZeroMemory( listen.compare, ATS_IPV4_OFFSET );\r
+            CopyMemory( &listen.compare[ATS_IPV4_OFFSET],\r
+                (uint8_t*)&m_pParent->m_Addr.v4.sin_addr,\r
+                sizeof(m_pParent->m_Addr.v4.sin_addr) );\r
+            ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+                ("Listen for: IP %#x, port %#hx\n", \r
+                cl_hton32(m_pParent->m_Addr.v4.sin_addr.S_un.S_addr), cl_hton16(m_pParent->m_Addr.v4.sin_port) ) );\r
+            break;\r
+        case AF_INET6:\r
+            CopyMemory( listen.compare,\r
+                (uint8_t*)&m_pParent->m_Addr.v6.sin6_addr,\r
+                sizeof(m_pParent->m_Addr.v6.sin6_addr) );\r
+            break;\r
+        }\r
+        listen.cep_listen.p_cmp_buf = listen.compare;\r
+        listen.cep_listen.cmp_len = 16;\r
+        listen.cep_listen.cmp_offset = FIELD_OFFSET( ib_cm_rdma_req_t, dst_ip_addr );\r
+\r
+        IO_STATUS_BLOCK IoStatus;\r
+        IoStatus.Status = NtDeviceIoControlFile(\r
+            m_pParent->m_hSync,\r
+            NULL,\r
+            NULL,\r
+            NULL,\r
+            &IoStatus,\r
+            UAL_NDI_LISTEN_CM,\r
+            &listen,\r
+            sizeof(listen),\r
+            &m_cid,\r
+            sizeof(m_cid) );\r
+\r
+        switch( IoStatus.Status )\r
+        {\r
+        case ND_SUCCESS:\r
+            ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+                ("Listen for: Guid %#I64x, sid %#I64x\n", \r
+                m_pParent->m_PortGuid, listen.cep_listen.svc_id ) );\r
+            break;\r
+\r
+        case IB_INVALID_SETTING:\r
+            return ND_ADDRESS_ALREADY_EXISTS;\r
+\r
+        default:\r
+            return IoStatus.Status;\r
+        }\r
+\r
+        ND_PRINT( TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("Created listen CEP with cid %d \n", m_cid ) );\r
+\r
+        // TODO: Come up with something better for port number.\r
+        if( Port == 0 )\r
+            Port = (USHORT)m_cid | (USHORT)(m_cid >> 16);\r
+\r
+        if( pAssignedPort )\r
+            *pAssignedPort = Port;\r
+\r
+        m_Protocol = (UINT8)Protocol;\r
+        return S_OK;\r
+    }\r
+\r
+    HRESULT CListen::Create(\r
+        __in CAdapter* pParent,\r
+        __in SIZE_T Backlog,\r
+        __in INT Protocol,\r
+        __in USHORT Port,\r
+        __out_opt USHORT* pAssignedPort,\r
+        __deref_out INDListen** ppListen\r
+        )\r
+    {\r
+        CListen* pListen = new CListen();\r
+        if( pListen == NULL )\r
+            return ND_NO_MEMORY;\r
+\r
+        HRESULT hr = pListen->Initialize(\r
+            pParent,\r
+            Backlog,\r
+            Protocol,\r
+            Port,\r
+            pAssignedPort );\r
+        if( FAILED( hr ) )\r
+        {\r
+            delete pListen;\r
+            return hr;\r
+        }\r
+\r
+        *ppListen = pListen;\r
+        return S_OK;\r
+    }\r
+\r
+    // *** IUnknown methods ***\r
+    HRESULT CListen::QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        )\r
+    {\r
+        if( IsEqualIID( riid, IID_IUnknown ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        if( IsEqualIID( riid, IID_INDListen ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    ULONG CListen::AddRef(void)\r
+    {\r
+        return InterlockedIncrement( &m_nRef );\r
+    }\r
+\r
+    ULONG CListen::Release(void)\r
+    {\r
+        ULONG ref = InterlockedDecrement( &m_nRef );\r
+        if( ref == 0 )\r
+            delete this;\r
+\r
+        return ref;\r
+    }\r
+\r
+    // *** INDOverlapped methods ***\r
+    HRESULT CListen::CancelOverlappedRequests(void)\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        DWORD bytes_ret;\r
+        BOOL ret = DeviceIoControl(\r
+            m_pParent->m_hSync,\r
+            UAL_NDI_CANCEL_CM_IRPS,\r
+            &m_cid,\r
+            sizeof(m_cid),\r
+            NULL,\r
+            0,\r
+            &bytes_ret,\r
+            NULL );\r
+\r
+        if( ret )\r
+            return S_OK;\r
+        else\r
+            return ND_UNSUCCESSFUL;\r
+    }\r
+\r
+    HRESULT CListen::GetOverlappedResult(\r
+        __inout OVERLAPPED *pOverlapped,\r
+        __out SIZE_T *pNumberOfBytesTransferred,\r
+        __in BOOL bWait\r
+        )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        *pNumberOfBytesTransferred = 0;\r
+        ::GetOverlappedResult(\r
+            m_pParent->GetFileHandle(),\r
+            pOverlapped,\r
+            (DWORD*)pNumberOfBytesTransferred,\r
+            bWait );\r
+        return (HRESULT)pOverlapped->Internal;\r
+    }\r
+\r
+    // *** INDListen methods ***\r
+    HRESULT CListen::GetConnectionRequest(\r
+        __inout INDConnector* pConnector,\r
+        __inout OVERLAPPED* pOverlapped\r
+        )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        static_cast<CConnector*>(pConnector)->m_Protocol = m_Protocol;\r
+\r
+        pOverlapped->Internal = ND_PENDING;\r
+        return NtDeviceIoControlFile(\r
+            m_pParent->GetFileHandle(),\r
+            pOverlapped->hEvent,\r
+            NULL,\r
+            (ULONG_PTR)pOverlapped->hEvent & 1 ? NULL : pOverlapped,\r
+            (IO_STATUS_BLOCK*)&pOverlapped->Internal,\r
+            UAL_NDI_GET_REQ_CM,\r
+            &m_cid,\r
+            sizeof(m_cid),\r
+            &static_cast<CConnector*>(pConnector)->m_cid,\r
+            sizeof(static_cast<CConnector*>(pConnector)->m_cid) );\r
+    }\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdListen.h b/branches/winverbs/ulp/nd/user/NdListen.h
new file mode 100644 (file)
index 0000000..3372fbf
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+#include "ndspi.h"\r
+#include <iba/ib_al.h>\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+HRESULT GetPdataForPassive(\r
+    __in UINT8* pSrc,\r
+    __in SIZE_T SrcLength,\r
+    __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+    __inout SIZE_T* pPrivateDataLength\r
+    );\r
+\r
+HRESULT GetPdataForActive(\r
+    __in UINT8* pSrc,\r
+    __in SIZE_T SrcLength,\r
+    __out_bcount_part_opt(*pPrivateDataLength, *pPrivateDataLength) void* pPrivateData,\r
+    __inout SIZE_T* pPrivateDataLength\r
+    );\r
+\r
+class CAdapter;\r
+\r
+class CListen :\r
+    public INDListen\r
+{\r
+private:\r
+    CListen(void);\r
+    ~CListen(void);\r
+\r
+    HRESULT Initialize(\r
+        __in CAdapter* pParent,\r
+        __in SIZE_T Backlog,\r
+        __in INT Protocol,\r
+        __in USHORT Port,\r
+        __out_opt USHORT* pAssignedPort\r
+        );\r
+\r
+public:\r
+    static HRESULT Create(\r
+        __in CAdapter* pParent,\r
+        __in SIZE_T Backlog,\r
+        __in INT Protocol,\r
+        __in USHORT Port,\r
+        __out_opt USHORT* pAssignedPort,\r
+        __deref_out INDListen** ppListen\r
+        );\r
+\r
+    // *** IUnknown methods ***\r
+    HRESULT STDMETHODCALLTYPE QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        );\r
+\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // *** INDOverlapped methods ***\r
+    HRESULT STDMETHODCALLTYPE CancelOverlappedRequests(void);\r
+\r
+    HRESULT STDMETHODCALLTYPE GetOverlappedResult(\r
+        __inout OVERLAPPED *pOverlapped,\r
+        __out SIZE_T *pNumberOfBytesTransferred,\r
+        __in BOOL bWait\r
+        );\r
+\r
+    // *** INDListen methods ***\r
+    HRESULT STDMETHODCALLTYPE GetConnectionRequest(\r
+        __inout INDConnector* pConnector,\r
+        __inout OVERLAPPED* pOverlapped\r
+        );\r
+\r
+private:\r
+    volatile LONG m_nRef;\r
+\r
+    CAdapter* m_pParent;\r
+\r
+    UINT8 m_Protocol;\r
+    net32_t m_cid;\r
+};\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdMr.cpp b/branches/winverbs/ulp/nd/user/NdMr.cpp
new file mode 100644 (file)
index 0000000..2216e63
--- /dev/null
@@ -0,0 +1,48 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include <initguid.h>\r
+#include "ndspi.h"\r
+#include "NdMr.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    CMr::CMr(void)\r
+    {\r
+    }\r
+\r
+    CMr::~CMr(void)\r
+    {\r
+    }\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdMr.h b/branches/winverbs/ulp/nd/user/NdMr.h
new file mode 100644 (file)
index 0000000..c0eb405
--- /dev/null
@@ -0,0 +1,57 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+\r
+#include "iba/ib_al_ioctl.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    class CMr\r
+    {\r
+        friend class CAdapter;\r
+        friend class CEndpoint;\r
+\r
+        friend class CAdapter_Beta1;\r
+        friend class CEndpoint_Beta1;\r
+    public:\r
+        CMr(void);\r
+        ~CMr(void);\r
+\r
+    protected:\r
+        const char* pBase;\r
+        uint32_t Length;\r
+        ual_reg_mem_ioctl_t mr_ioctl;\r
+    };\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdMw.cpp b/branches/winverbs/ulp/nd/user/NdMw.cpp
new file mode 100644 (file)
index 0000000..cc10eb0
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include "NdMw.h"\r
+#include "NdAdapter.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdMw.tmh"\r
+#endif\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    CMw::CMw(void) :\r
+        m_nRef( 1 ),\r
+        m_pParent( NULL )\r
+    {\r
+    }\r
+\r
+    CMw::~CMw(void)\r
+    {\r
+        if( m_pParent )\r
+            m_pParent->Release();\r
+    }\r
+\r
+    HRESULT CMw::Initialize(\r
+        CAdapter* pParent,\r
+        ND_RESULT* pInvalidateResult\r
+        )\r
+    {\r
+        m_pParent = pParent;\r
+        m_pParent->AddRef();\r
+\r
+        m_pInvalidateResult = pInvalidateResult;\r
+        return S_OK;\r
+    }\r
+\r
+    HRESULT CMw::QueryInterface(\r
+        REFIID riid,\r
+        LPVOID FAR* ppvObj\r
+        )\r
+    {\r
+        if( IsEqualIID( riid, IID_IUnknown ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        if( IsEqualIID( riid, IID_INDMemoryWindow ) )\r
+        {\r
+            *ppvObj = this;\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    ULONG CMw::AddRef(void)\r
+    {\r
+        return InterlockedIncrement( &m_nRef );\r
+    }\r
+\r
+    ULONG CMw::Release(void)\r
+    {\r
+        ULONG ref = InterlockedDecrement( &m_nRef );\r
+        if( ref == 0 )\r
+            delete this;\r
+\r
+        return ref;\r
+    }\r
+\r
+    HRESULT CMw::Close(void)\r
+    {\r
+        Release();\r
+        return S_OK;\r
+    }\r
+\r
+} // namespace\r
diff --git a/branches/winverbs/ulp/nd/user/NdMw.h b/branches/winverbs/ulp/nd/user/NdMw.h
new file mode 100644 (file)
index 0000000..c3589c5
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+#include "ndspi.h"\r
+\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    class CAdapter;\r
+\r
+    class CMw :\r
+        public INDMemoryWindow\r
+    {\r
+    public:\r
+        CMw(void);\r
+        ~CMw(void);\r
+\r
+        HRESULT Initialize(\r
+            CAdapter* pParent,\r
+            ND_RESULT* pInvalidateResult );\r
+\r
+        // *** IUnknown methods ***\r
+        HRESULT STDMETHODCALLTYPE QueryInterface(\r
+            REFIID riid,\r
+            LPVOID FAR* ppvObj\r
+            );\r
+\r
+        ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+        ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+        // *** INDMemoryWindow methods ***\r
+        HRESULT STDMETHODCALLTYPE Close(void);\r
+\r
+        //operator ND_RESULT*(){ return m_pInvalidateResult; };\r
+\r
+    private:\r
+        volatile LONG m_nRef;\r
+\r
+        CAdapter* m_pParent;\r
+\r
+        ND_RESULT* m_pInvalidateResult;\r
+    };\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// HPC Pack 2008 Beta 1 SPI\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+    class CAdapter_Beta1;\r
+\r
+    class CMw_Beta1 :\r
+        public INDMemoryWindow\r
+    {\r
+    public:\r
+        CMw_Beta1(void);\r
+        ~CMw_Beta1(void);\r
+\r
+        HRESULT Initialize(\r
+            CAdapter_Beta1* pParent,\r
+            ND_RESULT* pInvalidateResult );\r
+\r
+        // *** IUnknown methods ***\r
+        HRESULT STDMETHODCALLTYPE QueryInterface(\r
+            REFIID riid,\r
+            LPVOID FAR* ppvObj\r
+            );\r
+\r
+        ULONG STDMETHODCALLTYPE AddRef(void);\r
+\r
+        ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+        // *** INDMemoryWindow methods ***\r
+        HRESULT STDMETHODCALLTYPE Close(void);\r
+\r
+        //operator ND_RESULT*(){ return m_pInvalidateResult; };\r
+\r
+    private:\r
+        volatile LONG m_nRef;\r
+\r
+        CAdapter_Beta1* m_pParent;\r
+\r
+        ND_RESULT* m_pInvalidateResult;\r
+    };\r
+\r
+} // namespace
\ No newline at end of file
diff --git a/branches/winverbs/ulp/nd/user/NdProv.cpp b/branches/winverbs/ulp/nd/user/NdProv.cpp
new file mode 100644 (file)
index 0000000..e242877
--- /dev/null
@@ -0,0 +1,561 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#include <tchar.h>\r
+#include <ndspi.h>\r
+#include <iba/ib_at_ioctl.h>\r
+#include <complib/cl_types.h>\r
+#include <complib/cl_ioctl.h>\r
+#pragma warning( push, 3 )\r
+#include <unknwn.h>\r
+#include <assert.h>\r
+#include <ws2tcpip.h>\r
+#include <winioctl.h>\r
+#include <limits.h>\r
+#include <ws2spi.h>\r
+#pragma warning( pop )\r
+#include "ndprov.h"\r
+#include "ndadapter.h"\r
+\r
+#if defined(EVENT_TRACING)\r
+#ifdef offsetof\r
+#undef offsetof\r
+#endif\r
+#include "NdProv.tmh"\r
+#endif\r
+\r
+#include "nddebug.h"\r
+\r
+uint32_t g_nd_dbg_level = TRACE_LEVEL_ERROR;\r
+/* WPP doesn't want here literals! */\r
+uint32_t g_nd_dbg_flags = 0x80000001; /* ND_DBG_ERROR | ND_DBG_NDI; */\r
+\r
+namespace NetworkDirect\r
+{\r
+\r
+    static LONG gnRef = 0;\r
+\r
+    CProvider::CProvider() :\r
+        m_nRef( 1 )\r
+    {\r
+        InterlockedIncrement( &gnRef );\r
+    }\r
+\r
+    CProvider::~CProvider()\r
+    {\r
+        InterlockedDecrement( &gnRef );\r
+    }\r
+\r
+    HRESULT CProvider::QueryInterface(\r
+        const IID &riid,\r
+        void **ppObject )\r
+    {\r
+        if( IsEqualIID( riid, IID_IUnknown ) )\r
+        {\r
+            *ppObject = this;\r
+            return S_OK;\r
+        }\r
+\r
+        if( IsEqualIID( riid, IID_INDProvider ) )\r
+        {\r
+            *ppObject = this;\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    ULONG CProvider::AddRef()\r
+    {\r
+        return InterlockedIncrement( &m_nRef );\r
+    }\r
+\r
+    ULONG CProvider::Release()\r
+    {\r
+        ULONG ref = InterlockedDecrement( &m_nRef );\r
+        if( ref == 0 )\r
+            delete this;\r
+\r
+        return ref;\r
+    }\r
+\r
+    HRESULT CProvider::QueryAddressList(\r
+            __out_bcount_part_opt(*pBufferSize, *pBufferSize) SOCKET_ADDRESS_LIST* pAddressList,\r
+            __inout SIZE_T* pBufferSize )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        HANDLE hIbatDev = CreateFileW( IBAT_WIN32_NAME,\r
+            MAXIMUM_ALLOWED, 0, NULL,\r
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
+        if( hIbatDev == INVALID_HANDLE_VALUE )\r
+            return ND_NO_MEMORY;\r
+\r
+        IOCTL_IBAT_IP_ADDRESSES_IN addrIn;\r
+\r
+        addrIn.Version = IBAT_IOCTL_VERSION;\r
+        addrIn.PortGuid = 0;\r
+\r
+        DWORD size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);\r
+        IOCTL_IBAT_IP_ADDRESSES_OUT *pAddrOut;\r
+        do\r
+        {\r
+            pAddrOut = (IOCTL_IBAT_IP_ADDRESSES_OUT*)HeapAlloc(\r
+                GetProcessHeap(),\r
+                0,\r
+                size );\r
+            if( !pAddrOut )\r
+            {\r
+                //AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                //    ("Failed to allocate output buffer.\n") );\r
+                return ND_NO_MEMORY;\r
+            }\r
+\r
+            if( !DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_ADDRESSES,\r
+                &addrIn, sizeof(addrIn), pAddrOut, size, &size, NULL ) )\r
+            {\r
+                HeapFree( GetProcessHeap(), 0, pAddrOut );\r
+                //AL_PRINT( TRACE_LEVEL_ERROR, AL_DBG_ERROR,\r
+                //    ("IOCTL_IBAT_IP_ADDRESSES failed (%x).\n", GetLastError()) );\r
+                return ND_UNSUCCESSFUL;\r
+            }\r
+\r
+            if( pAddrOut->Size > size )\r
+            {\r
+                size = pAddrOut->Size;\r
+                HeapFree( GetProcessHeap(), 0, pAddrOut );\r
+                pAddrOut = NULL;\r
+            }\r
+\r
+        } while( !pAddrOut );\r
+\r
+        CloseHandle( hIbatDev );\r
+\r
+        //\r
+        // Note: the required size computed is a few bytes larger than necessary, \r
+        // but that keeps the code clean.\r
+        //\r
+        SIZE_T size_req = sizeof(SOCKET_ADDRESS_LIST);\r
+\r
+        switch( pAddrOut->AddressCount )\r
+        {\r
+        case 0:\r
+            break;\r
+\r
+        default:\r
+            size_req += (pAddrOut->AddressCount - 1) *\r
+                (sizeof(SOCKET_ADDRESS) + sizeof(SOCKADDR));\r
+            /* Fall through. */\r
+            __fallthrough;\r
+\r
+        case 1:\r
+            /* Add the space for the first address. */\r
+            size_req += sizeof(SOCKADDR);\r
+            break;\r
+        }\r
+\r
+        if( size_req > *pBufferSize )\r
+        {\r
+            HeapFree( GetProcessHeap(), 0, pAddrOut );\r
+            *pBufferSize = size_req;\r
+            return ND_BUFFER_OVERFLOW;\r
+        }\r
+\r
+        ZeroMemory( pAddressList, *pBufferSize );\r
+\r
+        /* We store the array of addresses after the last address pointer:\r
+        *      iAddressCount\r
+        *      Address[0]; <-- points to sockaddr[0]\r
+        *      Address[1]; <-- points to sockaddr[1]\r
+        *      ...\r
+        *      Address[n-1]; <-- points to sockaddr[n-1]\r
+        *      sockaddr[0];\r
+        *      sockaddr[1];\r
+        *      ...\r
+        *      sockaddr[n-1]\r
+        */\r
+        BYTE* pBuf = (BYTE*)(&(pAddressList->Address[pAddrOut->AddressCount]));\r
+        *pBufferSize = size_req;\r
+\r
+        pAddressList->iAddressCount = 0;\r
+        for( LONG i = 0; i < pAddrOut->AddressCount; i++ )\r
+        {\r
+            pAddressList->Address[pAddressList->iAddressCount].lpSockaddr =\r
+                (LPSOCKADDR)pBuf;\r
+\r
+            switch( pAddrOut->Address[i].IpVersion )\r
+            {\r
+            case 4:\r
+                {\r
+                    struct sockaddr_in* pAddr4 = ((struct sockaddr_in*)pBuf);\r
+                    pAddr4->sin_family = AF_INET;\r
+                    pAddr4->sin_addr.s_addr =\r
+                        *((u_long*)&pAddrOut->Address[i].Address[12]);\r
+                    pAddressList->Address[pAddressList->iAddressCount].iSockaddrLength =\r
+                        sizeof(struct sockaddr_in);\r
+                }\r
+                break;\r
+\r
+            case 6:\r
+                {\r
+                    struct sockaddr_in6* pAddr6 = ((struct sockaddr_in6*)pBuf);\r
+                    pAddr6->sin6_family = AF_INET6;\r
+                    CopyMemory(\r
+                        &pAddr6->sin6_addr,\r
+                        pAddrOut->Address[i].Address,\r
+                        sizeof(pAddr6->sin6_addr) );\r
+                    pAddressList->Address[pAddressList->iAddressCount].iSockaddrLength =\r
+                        sizeof(struct sockaddr_in6);\r
+                }\r
+                break;\r
+\r
+            default:\r
+                continue;\r
+            }\r
+\r
+            pBuf += pAddressList->Address[pAddressList->iAddressCount++].iSockaddrLength;\r
+        }\r
+\r
+        HeapFree( GetProcessHeap(), 0, pAddrOut );\r
+\r
+        return S_OK;\r
+    }\r
+\r
+    HRESULT CProvider::OpenAdapter(\r
+            __in_bcount(AddressLength) const struct sockaddr* pAddress,\r
+            __in SIZE_T AddressLength,\r
+            __deref_out INDAdapter** ppAdapter )\r
+    {\r
+        ND_ENTER( ND_DBG_NDI );\r
+\r
+        if( AddressLength < sizeof(struct sockaddr) )\r
+            return ND_INVALID_ADDRESS;\r
+\r
+        IOCTL_IBAT_IP_TO_PORT_IN in;\r
+        in.Version = IBAT_IOCTL_VERSION;\r
+\r
+        switch( pAddress->sa_family )\r
+        {\r
+        case AF_INET:\r
+            if( AddressLength < sizeof(struct sockaddr_in) )\r
+                return ND_INVALID_ADDRESS;\r
+            in.Address.IpVersion = 4;\r
+            RtlCopyMemory(\r
+                &in.Address.Address[12],\r
+                &((struct sockaddr_in*)pAddress)->sin_addr,\r
+                sizeof( ((struct sockaddr_in*)pAddress)->sin_addr ) );\r
+            break;\r
+\r
+        case AF_INET6:\r
+            if( AddressLength < sizeof(struct sockaddr_in6) )\r
+                return ND_INVALID_ADDRESS;\r
+            in.Address.IpVersion = 6;\r
+            RtlCopyMemory(\r
+                in.Address.Address,\r
+                &((struct sockaddr_in6*)pAddress)->sin6_addr,\r
+                sizeof(in.Address.Address) );\r
+            break;\r
+\r
+        default:\r
+            return ND_INVALID_ADDRESS;\r
+        }\r
+\r
+        HANDLE hIbatDev = CreateFileW( IBAT_WIN32_NAME,\r
+            MAXIMUM_ALLOWED, 0, NULL,\r
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );\r
+        if( hIbatDev == INVALID_HANDLE_VALUE )\r
+            return ND_NO_MEMORY;\r
+\r
+        IBAT_PORT_RECORD out;\r
+        DWORD size;\r
+        BOOL fSuccess = DeviceIoControl( hIbatDev, IOCTL_IBAT_IP_TO_PORT,\r
+            &in, sizeof(in), &out, sizeof(out), &size, NULL );\r
+        \r
+        CloseHandle( hIbatDev );\r
+        if( !fSuccess || size == 0 )\r
+            return ND_INVALID_ADDRESS;\r
+\r
+        return CAdapter::Create( this, pAddress, &out, ppAdapter );\r
+    }\r
+\r
+    CClassFactory::CClassFactory(void) :\r
+        m_nRef( 1 )\r
+    {\r
+        InterlockedIncrement( &gnRef );\r
+    }\r
+\r
+    CClassFactory::~CClassFactory(void)\r
+    {\r
+        InterlockedDecrement( &gnRef );\r
+    }\r
+\r
+    HRESULT CClassFactory::QueryInterface(\r
+        REFIID riid,\r
+        void** ppObject )\r
+    {\r
+        if( IsEqualIID( riid, IID_IUnknown ) )\r
+        {\r
+            *ppObject = this;\r
+            return S_OK;\r
+        }\r
+        if( IsEqualIID( riid, IID_IClassFactory ) )\r
+        {\r
+            *ppObject = this;\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    ULONG CClassFactory::AddRef()\r
+    {\r
+        return InterlockedIncrement( &m_nRef );\r
+    }\r
+\r
+    ULONG CClassFactory::Release()\r
+    {\r
+        ULONG ref = InterlockedDecrement( &m_nRef );\r
+        if( ref == 0 )\r
+            delete this;\r
+\r
+        return ref;\r
+    }\r
+\r
+    HRESULT CClassFactory::CreateInstance(\r
+        IUnknown* pUnkOuter,\r
+        REFIID riid,\r
+        void** ppObject )\r
+    {\r
+        if( pUnkOuter != NULL )\r
+            return CLASS_E_NOAGGREGATION;\r
+\r
+        if( IsEqualIID( riid, IID_INDProvider ) )\r
+        {\r
+            *ppObject = new CProvider();\r
+            if( !*ppObject )\r
+                return E_OUTOFMEMORY;\r
+\r
+            return S_OK;\r
+        }\r
+\r
+        return E_NOINTERFACE;\r
+    }\r
+\r
+    HRESULT CClassFactory::LockServer( BOOL fLock )\r
+    { \r
+        UNREFERENCED_PARAMETER( fLock );\r
+        return S_OK;\r
+    }\r
+\r
+} // namespace\r
+\r
+void* __cdecl operator new(\r
+    size_t count\r
+    )\r
+{\r
+    return HeapAlloc( GetProcessHeap(), 0, count );\r
+}\r
+\r
+\r
+void __cdecl operator delete(\r
+    void* object\r
+    )\r
+{\r
+    HeapFree( GetProcessHeap(), 0, object );\r
+}\r
+\r
+extern "C" {\r
+STDAPI DllGetClassObject(\r
+    REFCLSID rclsid,\r
+    REFIID riid,\r
+    LPVOID * ppv\r
+    )\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    UNREFERENCED_PARAMETER( rclsid );\r
+\r
+    if( IsEqualIID( riid, IID_IClassFactory ) )\r
+    {\r
+        NetworkDirect::CClassFactory* pFactory = new NetworkDirect::CClassFactory();\r
+        if( pFactory == NULL )\r
+            return E_OUTOFMEMORY;\r
+\r
+        *ppv = pFactory;\r
+        return S_OK;\r
+    }\r
+\r
+    return E_NOINTERFACE;\r
+}\r
+\r
+STDAPI DllCanUnloadNow(void)\r
+{\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    if( InterlockedCompareExchange( &NetworkDirect::gnRef, 0, 0 ) != 0 )\r
+        return S_FALSE;\r
+\r
+    return S_OK;\r
+}\r
+\r
+int\r
+WSPAPI\r
+WSPStartup(\r
+    IN WORD wVersionRequested,\r
+    OUT LPWSPDATA lpWSPData,\r
+    IN LPWSAPROTOCOL_INFOW lpProtocolInfo,\r
+    IN WSPUPCALLTABLE UpcallTable,\r
+    OUT LPWSPPROC_TABLE lpProcTable\r
+    )\r
+{\r
+    UNREFERENCED_PARAMETER( wVersionRequested );\r
+    UNREFERENCED_PARAMETER( lpWSPData );\r
+    UNREFERENCED_PARAMETER( lpProtocolInfo );\r
+    UNREFERENCED_PARAMETER( UpcallTable );\r
+    UNREFERENCED_PARAMETER( lpProcTable );\r
+    return WSASYSNOTREADY;\r
+}\r
+\r
+static BOOL\r
+_DllMain(\r
+    IN                HINSTANCE                    hinstDll,\r
+    IN                DWORD                        dwReason,\r
+    IN                LPVOID                        lpvReserved )\r
+{\r
+\r
+    ND_ENTER( ND_DBG_NDI );\r
+\r
+    UNUSED_PARAM( hinstDll );\r
+    UNUSED_PARAM( lpvReserved );\r
+\r
+    switch( dwReason )\r
+    {\r
+    case DLL_PROCESS_ATTACH:\r
+\r
+\r
+#if defined(EVENT_TRACING)\r
+#if DBG\r
+        WPP_INIT_TRACING(L"ibndprov.dll");\r
+#else\r
+        WPP_INIT_TRACING(L"ibndprov.dll");\r
+#endif\r
+#endif\r
+\r
+\r
+#if !defined(EVENT_TRACING)\r
+#if DBG \r
+        TCHAR    env_var[16];\r
+        DWORD    i;\r
+\r
+        i = GetEnvironmentVariable( "IBNDPROV_DBG_LEVEL", env_var, sizeof(env_var) );\r
+        if( i && i <= 16 )\r
+        {\r
+            g_nd_dbg_level = _tcstoul( env_var, NULL, 16 );\r
+        }\r
+\r
+        i = GetEnvironmentVariable( "IBNDPROV_DBG_FLAGS", env_var, sizeof(env_var) );\r
+        if( i && i <= 16 )\r
+        {\r
+            g_nd_dbg_flags = _tcstoul( env_var, NULL, 16 );\r
+        }\r
+\r
+        if( g_nd_dbg_flags & ND_DBG_ERR )\r
+            g_nd_dbg_flags |= CL_DBG_ERROR;\r
+\r
+        ND_PRINT( TRACE_LEVEL_ERROR, ND_DBG_ERR ,\r
+            ("(pcs %#x) IbNdProv: Debug print: level:%d, flags 0x%x\n",\r
+            GetCurrentProcessId(), g_nd_dbg_level ,g_nd_dbg_flags) );\r
+\r
+#endif\r
+#endif\r
+\r
+        ND_PRINT(TRACE_LEVEL_INFORMATION, ND_DBG_NDI, ("DllMain: DLL_PROCESS_ATTACH\n") );\r
+        break;\r
+\r
+    case DLL_PROCESS_DETACH:\r
+        ND_PRINT(TRACE_LEVEL_INFORMATION, ND_DBG_NDI,\r
+            ("DllMain: DLL_PROCESS_DETACH, ref count %d\n", NetworkDirect::gnRef) );\r
+\r
+#if defined(EVENT_TRACING)\r
+        WPP_CLEANUP();\r
+#endif\r
+        break;\r
+    }\r
+\r
+    ND_EXIT( ND_DBG_NDI );\r
+\r
+    return TRUE;\r
+}\r
+\r
+\r
+extern BOOL APIENTRY\r
+_DllMainCRTStartupForGS(\r
+    IN                HINSTANCE                    h_module,\r
+    IN                DWORD                        ul_reason_for_call, \r
+    IN                LPVOID                        lp_reserved );\r
+\r
+\r
+BOOL APIENTRY\r
+DllMain(\r
+    IN                HINSTANCE                    h_module,\r
+    IN                DWORD                        ul_reason_for_call, \r
+    IN                LPVOID                        lp_reserved )\r
+{\r
+    switch( ul_reason_for_call )\r
+    {\r
+    case DLL_PROCESS_ATTACH:\r
+        if( !_DllMainCRTStartupForGS(\r
+            h_module, ul_reason_for_call, lp_reserved ) )\r
+        {\r
+            return FALSE;\r
+        }\r
+\r
+        return _DllMain( h_module, ul_reason_for_call, lp_reserved );\r
+\r
+    case DLL_THREAD_ATTACH:\r
+        ND_PRINT(TRACE_LEVEL_INFORMATION, ND_DBG_NDI, ("DllMain: DLL_THREAD_ATTACH\n") );\r
+        break;\r
+\r
+    case DLL_THREAD_DETACH:\r
+        ND_PRINT(TRACE_LEVEL_INFORMATION, ND_DBG_NDI, ("DllMain: DLL_THREAD_DETACH\n") );\r
+        break;\r
+\r
+    case DLL_PROCESS_DETACH:\r
+        _DllMain( h_module, ul_reason_for_call, lp_reserved );\r
+\r
+        return _DllMainCRTStartupForGS(\r
+            h_module, ul_reason_for_call, lp_reserved );\r
+    }\r
+    return TRUE;\r
+}\r
+\r
+}   // extern "C"\r
+\r
diff --git a/branches/winverbs/ulp/nd/user/NdProv.def b/branches/winverbs/ulp/nd/user/NdProv.def
new file mode 100644 (file)
index 0000000..f2fb99c
--- /dev/null
@@ -0,0 +1,6 @@
+LIBRARY                IbNdProv.dll\r
+\r
+EXPORTS\r
+       DllGetClassObject       private\r
+       WSPStartup                      \r
+       DllCanUnloadNow private
\ No newline at end of file
diff --git a/branches/winverbs/ulp/nd/user/NdProv.h b/branches/winverbs/ulp/nd/user/NdProv.h
new file mode 100644 (file)
index 0000000..21de4a7
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+#include <iba/ib_at_ioctl.h>\r
+\r
+#ifdef __cplusplus\r
+namespace NetworkDirect\r
+{\r
+\r
+\r
+///////////////////////////////////////////////////////////////////////////////\r
+//\r
+// HPC Pack 2008 Beta 2 SPI\r
+//\r
+///////////////////////////////////////////////////////////////////////////////\r
+\r
+class CProvider :\r
+    public INDProvider\r
+{\r
+    friend class CClassFactory;\r
+\r
+public:\r
+    CProvider(void);\r
+    ~CProvider(void);\r
+\r
+    // IUnknown Methods\r
+    HRESULT STDMETHODCALLTYPE QueryInterface(\r
+        REFIID riid,\r
+        void** ppObject\r
+        );\r
+\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // INDProvider Methods\r
+    HRESULT STDMETHODCALLTYPE QueryAddressList(\r
+        __out_bcount_part_opt(*pBufferSize, *pBufferSize) SOCKET_ADDRESS_LIST* pAddressList,\r
+        __inout SIZE_T* pBufferSize\r
+        );\r
+\r
+    HRESULT STDMETHODCALLTYPE OpenAdapter(\r
+        __in_bcount(AddressLength) const struct sockaddr* pAddress,\r
+        __in SIZE_T AddressLength,\r
+        __deref_out INDAdapter** ppAdapter\r
+        );\r
+\r
+private:\r
+    volatile LONG m_nRef;\r
+};\r
+\r
+\r
+class CClassFactory : public IClassFactory\r
+{\r
+public:\r
+    CClassFactory(void);\r
+    ~CClassFactory(void);\r
+\r
+    // IUnknown Methods.\r
+    HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, void** ppObject );\r
+    ULONG STDMETHODCALLTYPE AddRef(void);\r
+    ULONG STDMETHODCALLTYPE Release(void);\r
+\r
+    // IClassFactory Methods.\r
+    HRESULT STDMETHODCALLTYPE CreateInstance( IUnknown* pUnkOuter, REFIID riid, void** ppObject );\r
+    HRESULT STDMETHODCALLTYPE LockServer( BOOL fLock );\r
+\r
+private:\r
+    volatile LONG m_nRef;\r
+};\r
+\r
+} // namespace\r
+\r
+void* __cdecl operator new(\r
+    size_t count\r
+    );\r
+\r
+void __cdecl operator delete(\r
+    void* object\r
+    );\r
+\r
+#endif // __cplusplus\r
diff --git a/branches/winverbs/ulp/nd/user/NdProv.rc b/branches/winverbs/ulp/nd/user/NdProv.rc
new file mode 100644 (file)
index 0000000..6f5908b
--- /dev/null
@@ -0,0 +1,49 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id$\r
+ */\r
+\r
+\r
+#include <oib_ver.h>\r
+\r
+#define VER_FILETYPE                           VFT_DLL\r
+#define VER_FILESUBTYPE                                VFT2_UNKNOWN\r
+\r
+#ifdef _DEBUG_\r
+#define VER_FILEDESCRIPTION_STR                "OpenFabrics Network Direct Provider (Debug)"\r
+#define VER_INTERNALNAME_STR           "ibndprov.dll"\r
+#define VER_ORIGINALFILENAME_STR       "ibndprov.dll"\r
+#else\r
+#define VER_FILEDESCRIPTION_STR                "OpenFabrics Network Direct Provider"\r
+#define VER_INTERNALNAME_STR           "ibndprov.dll"\r
+#define VER_ORIGINALFILENAME_STR       "ibndprov.dll"\r
+#endif\r
+\r
+#include <common.ver>\r
+\r
index d366266945b386587873448924a86ec7d732aea6..45f67c42b0b60572ca805c52cf133af9bc96e67d 100644 (file)
@@ -3,4 +3,6 @@
 # file to this component.  This file merely indirects to the real make file\r
 # that is shared by all the driver components of the OpenIB Windows project.\r
 #\r
+\r
+DDK_BLOCK_ON_IA64=1\r
 !INCLUDE ..\..\..\inc\openib.def\r
diff --git a/branches/winverbs/ulp/nd/user/nddebug.h b/branches/winverbs/ulp/nd/user/nddebug.h
new file mode 100644 (file)
index 0000000..ab5607b
--- /dev/null
@@ -0,0 +1,160 @@
+/*\r
+ * Copyright (c) 2008 Microsoft Corporation.  All rights reserved.\r
+ *\r
+ * This software is available to you under the OpenIB.org BSD license\r
+ * below:\r
+ *\r
+ *     Redistribution and use in source and binary forms, with or\r
+ *     without modification, are permitted provided that the following\r
+ *     conditions are met:\r
+ *\r
+ *      - Redistributions of source code must retain the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer.\r
+ *\r
+ *      - Redistributions in binary form must reproduce the above\r
+ *        copyright notice, this list of conditions and the following\r
+ *        disclaimer in the documentation and/or other materials\r
+ *        provided with the distribution.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+ * SOFTWARE.\r
+ *\r
+ * $Id:$\r
+ */\r
+\r
+#pragma once\r
+\r
+#ifdef __MODULE__\r
+#undef __MODULE__\r
+#endif\r
+#define __MODULE__     "[ND]"\r
+\r
+\r
+#include <complib/cl_debug.h>\r
+\r
+extern uint32_t                        g_nd_dbg_level;\r
+extern uint32_t                        g_nd_dbg_flags;\r
+\r
+#if defined(EVENT_TRACING)\r
+//\r
+// Software Tracing Definitions \r
+//\r
+\r
+\r
+#define WPP_CONTROL_GUIDS \\r
+       WPP_DEFINE_CONTROL_GUID(NDCtlGuid1,(1463B4CE,7A66,47a4,ABDB,09EE7AD9E698),  \\r
+       WPP_DEFINE_BIT( ND_DBG_ERROR)\\r
+       WPP_DEFINE_BIT( ND_DBG_NDI))\r
+       \r
+\r
+\r
+#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level  >= lvl)\r
+#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags)\r
+#define WPP_FLAG_ENABLED(flags)(WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level  >= TRACE_LEVEL_VERBOSE)\r
+#define WPP_FLAG_LOGGER(flags) WPP_LEVEL_LOGGER(flags)\r
+\r
+\r
+// begin_wpp config\r
+// ND_ENTER( FLAG );\r
+// ND_EXIT( FLAG );\r
+// USEPREFIX(ND_PRINT, "%!STDPREFIX! [ND] :%!FUNC!() :");\r
+// USESUFFIX(ND_ENTER, " [ND] :%!FUNC!():[");\r
+// USESUFFIX(ND_EXIT, " [ND] :%!FUNC!():]");\r
+// end_wpp\r
+\r
+\r
+\r
+#else\r
+\r
+#include <wmistr.h>\r
+#include <evntrace.h>\r
+\r
+/*\r
+ * Debug macros\r
+ */\r
+\r
+\r
+/* Debug message source */\r
+#define ND_DBG_ERR     (1 << 0)\r
+#define ND_DBG_NDI     (1 << 1)\r
+\r
+#define ND_DBG_ERROR   (CL_DBG_ERROR | ND_DBG_ERR)\r
+\r
+#if DBG\r
+\r
+// assignment of _level_ is need to to overcome warning C4127\r
+#define ND_PRINT( _level_,_flag_,_msg_)  \\r
+       { \\r
+               if( g_nd_dbg_level >= (_level_) ) \\r
+                       CL_TRACE( _flag_, g_nd_dbg_flags, _msg_ ); \\r
+       }\r
+\r
+\r
+#define ND_PRINT_EXIT( _level_,_flag_,_msg_) \\r
+       { \\r
+               if( g_nd_dbg_level >= (_level_) ) \\r
+                       CL_TRACE( _flag_, g_nd_dbg_flags, _msg_ );\\r
+               ND_EXIT( _flag_ );\\r
+       }\r
+\r
+#define ND_ENTER( _flag_) \\r
+       { \\r
+               if( g_nd_dbg_level >= TRACE_LEVEL_VERBOSE ) \\r
+                       CL_ENTER( _flag_, g_nd_dbg_flags ); \\r
+       }\r
+\r
+#define ND_EXIT( _flag_)\\r
+       { \\r
+               if( g_nd_dbg_level >= TRACE_LEVEL_VERBOSE ) \\r
+                       CL_EXIT( _flag_, g_nd_dbg_flags ); \\r
+       }\r
+\r
+\r
+#else\r
+\r
+#define ND_PRINT( lvl, flags, msg)\r
+\r
+#define ND_PRINT_EXIT( _level_,_flag_,_msg_)\r
+\r
+#define ND_ENTER( _flag_)\r
+\r
+#define ND_EXIT( _flag_)\r
+\r
+\r
+#endif\r
+\r
+#endif //EVENT_TRACING\r
+\r
+\r
+#if DBG\r
+struct dbg_data\r
+{      \r
+       int64_t rcv_cnt;\r
+       int64_t rcv_pkts;\r
+       int64_t rcv_bytes;\r
+       int64_t rcv_pkts_err;\r
+       int64_t rcv_pkts_zero;\r
+       int64_t snd_cnt;\r
+       int64_t snd_pkts;\r
+       int64_t snd_bytes;\r
+       int64_t snd_pkts_err;\r
+       int64_t snd_pkts_zero;\r
+       int64_t c_cnt;\r
+       int64_t c_rcv_pkts;\r
+       int64_t c_rcv_bytes;\r
+       int64_t c_rcv_pkts_err;\r
+       int64_t c_snd_pkts;\r
+       int64_t c_snd_bytes;\r
+       int64_t c_snd_pkts_err;\r
+};\r
+\r
+extern dbg_data g;\r
+\r
+#endif\r