[IPoIB] Add support for address translation
authorftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 6 Dec 2005 21:41:40 +0000 (21:41 +0000)
committerftillier <ftillier@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 6 Dec 2005 21:41:40 +0000 (21:41 +0000)
Based on patch submitted by Tzachi Dar (tzachid@mellanox.co.il)

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@195 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

16 files changed:
inc/iba/ib_at_ioctl.h [new file with mode: 0644]
tests/dirs
tests/ibat/dirs [new file with mode: 0644]
tests/ibat/user/PrintIp.c [new file with mode: 0644]
tests/ibat/user/SOURCES [new file with mode: 0644]
tests/ibat/user/makefile [new file with mode: 0644]
ulp/ipoib/kernel/SOURCES
ulp/ipoib/kernel/ipoib_adapter.c
ulp/ipoib/kernel/ipoib_adapter.h
ulp/ipoib/kernel/ipoib_debug.h
ulp/ipoib/kernel/ipoib_driver.c
ulp/ipoib/kernel/ipoib_driver.h
ulp/ipoib/kernel/ipoib_ibat.c [new file with mode: 0644]
ulp/ipoib/kernel/ipoib_ibat.h [new file with mode: 0644]
ulp/ipoib/kernel/ipoib_port.c
ulp/ipoib/kernel/ipoib_port.h

diff --git a/inc/iba/ib_at_ioctl.h b/inc/iba/ib_at_ioctl.h
new file mode 100644 (file)
index 0000000..47e2f13
--- /dev/null
@@ -0,0 +1,133 @@
+/*\r
+* Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
+* Copyright (c) 2005 SilverStorm Technologies.  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
+/* This file is shared between user- and kernel-mode */\r
+\r
+#include <iba/ib_types.h>\r
+\r
+\r
+#ifndef        _IB_AT_IOCTL_H_\r
+#define        _IB_AT_IOCTL_H_\r
+\r
+\r
+#define        IBAT_IOCTL_VERSION              2\r
+\r
+#define        IBAT_MAC_LEN                    6\r
+\r
+\r
+#define IOCTL_IBAT( n )                \\r
+       CTL_CODE( FILE_DEVICE_UNKNOWN, (0x800 + n), \\r
+               METHOD_BUFFERED, FILE_READ_ACCESS )\r
+\r
+/** This IRP is used to return all available CAs ports number\r
+ * and port guid */\r
+#define        IOCTL_IBAT_PORTS        IOCTL_IBAT( 1 )\r
+\r
+typedef struct _IBAT_PORT_RECORD\r
+{\r
+       UINT64                          CaGuid;\r
+       UINT64                          PortGuid;\r
+} IBAT_PORT_RECORD;\r
+\r
+typedef struct _IOCTL_IBAT_PORTS_IN\r
+{\r
+       ULONG                           Version;\r
+\r
+} IOCTL_IBAT_PORTS_IN;\r
+\r
+typedef struct _IOCTL_IBAT_PORTS_OUT\r
+{\r
+       /** Total size, of the output buffer needed if the\r
+        * suplied buffer wasn't enough */\r
+       ULONG                           Size;\r
+       LONG                            NumPorts;\r
+       IBAT_PORT_RECORD        Ports[1];\r
+\r
+} IOCTL_IBAT_PORTS_OUT;\r
+\r
+\r
+/** This IRP is used to return all the ip addresses that\r
+ * are assigned to a port */\r
+#define        IOCTL_IBAT_IP_ADDRESSES         IOCTL_IBAT( 2 )\r
+\r
+typedef struct _IOCTL_IBAT_IP_ADDRESSES_IN\r
+{\r
+       ULONG                           Version;\r
+       /** The guid of the port that we are querying for.  May be\r
+        * zero if querying for IP addresses of all ports. */\r
+       UINT64                          PortGuid;\r
+\r
+} IOCTL_IBAT_IP_ADDRESSES_IN;\r
+\r
+typedef struct _IP_ADDRESS\r
+{\r
+       /** Might only be 4 or 6 */\r
+       CHAR                            IpVersion;\r
+       /** Sized to support both IPv4 and IPv6 */\r
+       UCHAR                           Address[16];\r
+\r
+} IP_ADDRESS;\r
+\r
+typedef struct _IOCTL_IBAT_IP_ADDRESSES_OUT\r
+{\r
+       /** Total size of the output buffer needed if the\r
+        * suplied buffer wasn't enough */\r
+       ULONG                           Size;\r
+       LONG                            AddressCount;\r
+       IP_ADDRESS                      Address[1];\r
+\r
+} IOCTL_IBAT_IP_ADDRESSES_OUT;\r
+\r
+\r
+/** This IRP is used to convert a remote MAC addresses to a remote GID */\r
+#define        IOCTL_IBAT_MAC_TO_GID IOCTL_IBAT( 3 )\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_GID_IN\r
+{\r
+       ULONG                           Version;\r
+       UINT64                          PortGuid;\r
+       UCHAR                           DestMac[IBAT_MAC_LEN];\r
+\r
+} IOCTL_IBAT_MAC_TO_GID_IN;\r
+\r
+typedef struct _IOCTL_IBAT_MAC_TO_GID_OUT\r
+{\r
+       ib_gid_t                        DestGid;\r
+\r
+} IOCTL_IBAT_MAC_TO_GID_OUT;\r
+\r
+\r
+#define        IBAT_DEV_NAME   L"\\Device\\ibat"\r
+#define        IBAT_DOS_DEV_NAME L"\\DosDevices\\Global\\ibat"\r
+#define        IBAT_WIN32_NAME L"\\\\.\\ibat"\r
+\r
+#endif /* _IB_AT_IOCTL_H_ */\r
index a9d217f..fc792b6 100644 (file)
@@ -2,4 +2,5 @@ DIRS=\
        alts    \\r
        cmtest  \\r
        wsd             \\r
+       ibat    \\r
        limits\r
diff --git a/tests/ibat/dirs b/tests/ibat/dirs
new file mode 100644 (file)
index 0000000..389156f
--- /dev/null
@@ -0,0 +1,2 @@
+DIRS=\\r
+       user\r
diff --git a/tests/ibat/user/PrintIp.c b/tests/ibat/user/PrintIp.c
new file mode 100644 (file)
index 0000000..8fc1c44
--- /dev/null
@@ -0,0 +1,253 @@
+/*\r
+* Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
+* Copyright (c) 2005 SilverStorm Technologies.  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 <windows.h>\r
+#include <devioctl.h>\r
+#include <stdio.h>\r
+#include <Iphlpapi.h>\r
+#include "iba\ib_types.h"\r
+#include <iba\ib_at_ioctl.h>\r
+\r
+\r
+// Print all ips that are related to infiniband on this computer\r
+int print_ips()\r
+{\r
+       HANDLE hKernelLib;\r
+       HRESULT hr = S_OK;\r
+       char temp [1000];\r
+       char temp1 [1000];\r
+       IOCTL_IBAT_PORTS_IN ipoib_ports_in;\r
+       IOCTL_IBAT_PORTS_OUT *p_ipoib_ports_out;\r
+       IBAT_PORT_RECORD *ports_records;\r
+\r
+       IOCTL_IBAT_IP_ADDRESSES_IN addresses_in;\r
+       IOCTL_IBAT_IP_ADDRESSES_OUT *addresses_out;\r
+       IP_ADDRESS       *ip_addreses;\r
+\r
+       BOOL ret;\r
+       int i,j;\r
+       DWORD BytesReturned = 0;\r
+\r
+       printf("Adapters that are known to the ipoib modules are:\n\n");\r
+\r
+       hKernelLib =\r
+               CreateFileW(\r
+               IBAT_WIN32_NAME,\r
+               GENERIC_READ | GENERIC_WRITE,\r
+               FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none\r
+               NULL,                               // no security\r
+               OPEN_EXISTING,\r
+               FILE_ATTRIBUTE_NORMAL,\r
+               NULL                                // no template\r
+               );\r
+\r
+       if (hKernelLib == INVALID_HANDLE_VALUE) {\r
+               hr = HRESULT_FROM_WIN32(GetLastError());\r
+               printf("failed to open the kernel device hr=0x%x\n", hr);\r
+               return 1;\r
+       }\r
+\r
+       ipoib_ports_in.Version = IBAT_IOCTL_VERSION;\r
+\r
+       p_ipoib_ports_out = (IOCTL_IBAT_PORTS_OUT *)temp;\r
+\r
+       ret = DeviceIoControl(\r
+               hKernelLib,\r
+               IOCTL_IBAT_PORTS,\r
+               &ipoib_ports_in,\r
+               sizeof(ipoib_ports_in),\r
+               p_ipoib_ports_out,\r
+               sizeof(temp),\r
+               &BytesReturned,\r
+               NULL\r
+               );\r
+\r
+       if (ret == 0) {\r
+               hr = HRESULT_FROM_WIN32(GetLastError());\r
+               printf("DeviceIoControl failed for IOCTL_IBAT_PORTS hr=0x%x\n", hr);\r
+               return 1;\r
+       }\r
+       if (p_ipoib_ports_out->Size > sizeof(temp)) {\r
+               printf("Data truncated, please call again with a buffer of %d bytes", p_ipoib_ports_out->Size);\r
+       }\r
+\r
+       ports_records = p_ipoib_ports_out->Ports;\r
+       printf("Number of devices %d\n", p_ipoib_ports_out->NumPorts);\r
+       for (i = 0 ; i < p_ipoib_ports_out->NumPorts; i++)\r
+       {\r
+               printf("%d: ca guid = 0x%I64x port guid=0x%I64x\n", i, CL_NTOH64(ports_records[i].CaGuid), CL_NTOH64(ports_records[i].PortGuid));\r
+\r
+               // print the ip adresses of this port\r
+               addresses_in.Version = IBAT_IOCTL_VERSION;\r
+               addresses_in.PortGuid = ports_records[i].PortGuid;\r
+\r
+               addresses_out = (IOCTL_IBAT_IP_ADDRESSES_OUT *)temp1;\r
+\r
+               ret = DeviceIoControl(\r
+                       hKernelLib,\r
+                       IOCTL_IBAT_IP_ADDRESSES,\r
+                       &addresses_in,\r
+                       sizeof(addresses_in),\r
+                       addresses_out,\r
+                       sizeof(temp1),\r
+                       &BytesReturned,\r
+                       NULL\r
+                       );\r
+\r
+               if (ret == 0)\r
+               {\r
+                       hr = HRESULT_FROM_WIN32(GetLastError());\r
+                       printf("DeviceIoControl failed for IOCTL_IBAT_IP_ADDRESSES hr=0x%x\n", hr);\r
+                       return 1;\r
+               }\r
+               if (addresses_out->Size > sizeof(temp1) )\r
+               {\r
+                       printf("Data truncated, please call again with a buffer of %d bytes", p_ipoib_ports_out->Size);\r
+                       return 1;\r
+               }\r
+\r
+               printf("   found %d ips:", addresses_out->AddressCount);\r
+               ip_addreses = addresses_out->Address;\r
+               for (j = 0; j < addresses_out->AddressCount; j++)\r
+               {\r
+                       printf("    %d.%d.%d.%d   ",\r
+                               ip_addreses[j].Address[12],\r
+                               ip_addreses[j].Address[13],\r
+                               ip_addreses[j].Address[14],\r
+                               ip_addreses[j].Address[15]);\r
+               }\r
+               printf("\n");\r
+       }\r
+\r
+       return 0;\r
+};\r
+\r
+void print_usage(char *argv[])\r
+{\r
+       printf("This program is used to print ip adapters and their addresses or to do arp\n");\r
+       printf("Usage is: %s <print_ips> \n",argv[0]);\r
+       printf("or %s <remoteip> <ip>  (for example %s remoteip 1.2.3.4)\n", argv[0],argv[0]);\r
+}\r
+\r
+int remote_ip(char *remote_ip)\r
+{\r
+       HANDLE hKernelLib;\r
+       HRESULT hr = S_OK;\r
+       IPAddr ip;\r
+       char *pIp = (char *)&ip;\r
+       int b1,b2,b3,b4;\r
+       DWORD  ret;\r
+       IOCTL_IBAT_MAC_TO_GID_IN mac;\r
+       IOCTL_IBAT_MAC_TO_GID_OUT gid;\r
+       DWORD BytesReturned = 0;\r
+\r
+       ULONG pMacAddr[2], PhyAddrLen ;\r
+       unsigned char *pMac = (unsigned char *)&pMacAddr;\r
+       PhyAddrLen = sizeof(pMacAddr);\r
+\r
+       hKernelLib =\r
+               CreateFileW(\r
+               IBAT_WIN32_NAME,\r
+               GENERIC_READ | GENERIC_WRITE,\r
+               FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode none\r
+               NULL,                               // no security\r
+               OPEN_EXISTING,\r
+               FILE_ATTRIBUTE_NORMAL,\r
+               NULL                                // no template\r
+               );\r
+\r
+       if (hKernelLib == INVALID_HANDLE_VALUE)\r
+       {\r
+               hr = HRESULT_FROM_WIN32(GetLastError());\r
+               printf("failed to open the kernel device hr=0x%x\n", hr);\r
+               return 1;\r
+       }\r
+\r
+       sscanf(remote_ip, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);\r
+       printf("Calling arp for addresses %d.%d.%d.%d\n", b1, b2, b3, b4);\r
+\r
+       pIp[0] = (char)b1;\r
+       pIp[1] = (char)b2;\r
+       pIp[2] = (char)b3;\r
+       pIp[3] = (char)b4;\r
+\r
+       ret = SendARP(ip ,0 ,pMacAddr, &PhyAddrLen );\r
+       if (ret != NO_ERROR)\r
+       {\r
+               printf("Error in SendARP");\r
+               return 1;\r
+       }\r
+\r
+       printf("Mac of the remote addresses is %x-%x-%x-%x-%x-%x\n",\r
+               pMac[0], pMac[1], pMac[2], pMac[3], pMac[4], pMac[5] );\r
+\r
+       // query for the gid\r
+       memcpy(mac.DestMac, pMac, 6);\r
+\r
+       ret = DeviceIoControl(\r
+               hKernelLib,\r
+               IOCTL_IBAT_MAC_TO_GID,\r
+               &mac,\r
+               sizeof(mac),\r
+               &gid,\r
+               sizeof(gid),\r
+               &BytesReturned,\r
+               NULL );\r
+\r
+       if (ret == 0)\r
+       {\r
+               hr = HRESULT_FROM_WIN32(GetLastError());\r
+               printf("DeviceIoControl failed for IOCTL_IBAT_IP_ADDRESSES hr=0x%x\n", hr);\r
+       }\r
+\r
+       printf("lid of remote ip is = 0x%I64x : 0x%I64x\n", CL_NTOH64(gid.DestGid.unicast.prefix), CL_NTOH64(gid.DestGid.unicast.interface_id));\r
+\r
+       return 0;\r
+}\r
+\r
+\r
+int __cdecl main(int argc, char *argv[])\r
+{\r
+       if (argc < 2) {\r
+               print_usage(argv);\r
+               return 1;\r
+       }\r
+       if (!strcmp(argv[1], "print_ips")) {\r
+               return print_ips();\r
+       }\r
+       if (!strcmp(argv[1], "remoteip")) {\r
+               return remote_ip(argv[2]);\r
+       }\r
+       print_usage(argv);\r
+       return 1;\r
+}\r
diff --git a/tests/ibat/user/SOURCES b/tests/ibat/user/SOURCES
new file mode 100644 (file)
index 0000000..b50428b
--- /dev/null
@@ -0,0 +1,18 @@
+TARGETNAME=PrintIP\r
+TARGETPATH=..\..\..\bin\user\obj$(BUILD_ALT_DIR)\r
+TARGETTYPE=PROGRAM\r
+UMTYPE=console\r
+USE_CRTDLL=1\r
+\r
+SOURCES=\\r
+       PrintIp.c\r
+\r
+TARGETLIBS=\\r
+       $(SDK_LIB_PATH)\ws2_32.lib \\r
+       $(SDK_LIB_PATH)\Iphlpapi.lib\r
+\r
+MSC_WARNING_LEVEL= /W4\r
+\r
+INCLUDES=..\..\..\inc;\\r
+       ..\..\..\inc\user;\\r
+       $(PLATFORM_SDK_PATH)\include;\r
diff --git a/tests/ibat/user/makefile b/tests/ibat/user/makefile
new file mode 100644 (file)
index 0000000..9c985f5
--- /dev/null
@@ -0,0 +1,7 @@
+#\r
+# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source\r
+# file to this component.  This file merely indirects to the real make file\r
+# that is shared by all the driver components of the Windows NT DDK\r
+#\r
+\r
+!INCLUDE $(NTMAKEENV)\makefile.def\r
index a7f370d..dda2142 100644 (file)
@@ -6,7 +6,8 @@ SOURCES= ipoib.rc \
                ipoib_driver.c \\r
                ipoib_adapter.c \\r
                ipoib_endpoint.c \\r
-               ipoib_port.c\r
+               ipoib_port.c \\r
+               ipoib_ibat.c\r
 \r
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;\r
 \r
index b183747..f7c811c 100644 (file)
@@ -190,7 +190,7 @@ ipoib_create_adapter(
        }\r
 \r
        KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
-       InsertHeadList( &g_ipoib.adapter_list, &p_adapter->entry );\r
+       cl_qlist_insert_tail( &g_ipoib.adapter_list, &p_adapter->entry );\r
        KeReleaseInStackQueuedSpinLock( &hdl );\r
 \r
        status = adapter_init( p_adapter );\r
@@ -243,7 +243,6 @@ ipoib_destroy_adapter(
        cl_mutex_acquire( &p_adapter->mutex );\r
        cl_obj_lock( &p_adapter->obj );\r
        p_adapter->state = IB_PNP_PORT_REMOVE;\r
-       cl_obj_unlock( &p_adapter->obj );\r
 \r
        /*\r
         * Clear the pointer to the port object since the object destruction\r
@@ -252,6 +251,8 @@ ipoib_destroy_adapter(
         */\r
        p_adapter->p_port = NULL;\r
 \r
+       cl_obj_unlock( &p_adapter->obj );\r
+\r
        cl_mutex_release( &p_adapter->mutex );\r
 \r
        cl_obj_destroy( &p_adapter->obj );\r
@@ -429,8 +430,8 @@ __adapter_destroying(
        }\r
 \r
        KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
-       ASSERT( !IsListEmpty( &g_ipoib.adapter_list ) );\r
-       RemoveEntryList( &p_adapter->entry );\r
+       ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );\r
+       cl_qlist_remove_item( &g_ipoib.adapter_list, &p_adapter->entry );\r
        KeReleaseInStackQueuedSpinLock( &hdl );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
@@ -476,6 +477,7 @@ __ipoib_pnp_cb(
 {\r
        ib_api_status_t         status;\r
        ipoib_adapter_t         *p_adapter;\r
+       ipoib_port_t            *p_port;\r
        ib_pnp_event_t          old_state;\r
 \r
        IPOIB_ENTER( IPOIB_DBG_PNP );\r
@@ -527,17 +529,20 @@ __ipoib_pnp_cb(
                p_adapter->state = IB_PNP_PORT_ADD;\r
                cl_obj_unlock( &p_adapter->obj );\r
                status = ipoib_create_port( p_adapter,\r
-                       (ib_pnp_port_rec_t*)p_pnp_rec, &p_adapter->p_port );\r
+                       (ib_pnp_port_rec_t*)p_pnp_rec, &p_port );\r
+               cl_obj_lock( &p_adapter->obj );\r
                if( status != IB_SUCCESS )\r
                {\r
-                       cl_obj_lock( &p_adapter->obj );\r
                        p_adapter->state = old_state;\r
                        cl_obj_unlock( &p_adapter->obj );\r
                        p_adapter->hung = TRUE;\r
                        break;\r
                }\r
 \r
-               p_pnp_rec->context = p_adapter->p_port;\r
+               p_pnp_rec->context = p_port;\r
+\r
+               p_adapter->p_port = p_port;\r
+               cl_obj_unlock( &p_adapter->obj );\r
                break;\r
 \r
        case IB_PNP_PORT_REMOVE:\r
@@ -546,9 +551,10 @@ __ipoib_pnp_cb(
 \r
                cl_obj_lock( &p_adapter->obj );\r
                p_adapter->state = IB_PNP_PORT_REMOVE;\r
-               cl_obj_unlock( &p_adapter->obj );\r
-               ipoib_port_destroy( p_adapter->p_port );\r
+               p_port = p_adapter->p_port;\r
                p_adapter->p_port = NULL;\r
+               cl_obj_unlock( &p_adapter->obj );\r
+               ipoib_port_destroy( p_port );\r
                p_pnp_rec->context = NULL;\r
                status = IB_SUCCESS;\r
                break;\r
@@ -732,6 +738,7 @@ __ipoib_pnp_dereg(
        IN                              void*                                           context )\r
 {\r
        ipoib_adapter_t*        p_adapter;\r
+       ipoib_port_t*           p_port;\r
        ib_api_status_t         status;\r
        ib_pnp_event_t          state;\r
 \r
@@ -751,14 +758,14 @@ __ipoib_pnp_dereg(
 \r
        state = p_adapter->state;\r
 \r
+       /* Destroy the current port instance if it still exists. */\r
+       p_port = p_adapter->p_port;\r
+       p_adapter->p_port = NULL;\r
        cl_obj_unlock( &p_adapter->obj );\r
 \r
-       /* Destroy the current port instance if it still exists. */\r
-       if( p_adapter->p_port )\r
-       {\r
-               ipoib_port_destroy( p_adapter->p_port );\r
-               p_adapter->p_port = NULL;\r
-       }\r
+       if( p_port )\r
+               ipoib_port_destroy( p_port );\r
+\r
        /* Complete any pending OIDs. */\r
        ipoib_resume_oids( p_adapter );\r
 \r
index ba67e24..dbd891c 100644 (file)
@@ -130,7 +130,7 @@ typedef struct _ipoib_adapter
        NDIS_HANDLE                             h_adapter;\r
        ipoib_ifc_data_t                guids;\r
 \r
-       LIST_ENTRY                              entry;\r
+       cl_list_item_t                  entry;\r
 \r
        ib_al_handle_t                  h_al;\r
        ib_pnp_handle_t                 h_pnp;\r
index a96cd69..7b58334 100644 (file)
@@ -59,6 +59,7 @@ extern uint32_t               g_ipoib_dbg_lvl;
 #define IPOIB_DBG_MCAST        (1 << 7)\r
 #define IPOIB_DBG_ALLOC        (1 << 8)\r
 #define IPOIB_DBG_OID  (1 << 9)\r
+#define IPOIB_DBG_IOCTL        (1 << 10)\r
 \r
 #define IPOIB_DBG_FUNC (1 << 28)       /* For function entry/exit */\r
 #define IPOIB_DBG_INFO (1 << 29)       /* For verbose information */\r
index c1451f8..7322a3b 100644 (file)
@@ -33,6 +33,7 @@
 #include "ipoib_driver.h"\r
 #include "ipoib_debug.h"\r
 #include "ipoib_port.h"\r
+#include "ipoib_ibat.h"\r
 #include <complib/cl_bus_ifc.h>\r
 #include <complib/cl_init.h>\r
 #include <initguid.h>\r
@@ -266,9 +267,10 @@ DriverEntry(
        __ipoib_read_registry(p_registry_path);\r
        \r
        KeInitializeSpinLock( &g_ipoib.lock );\r
-       InitializeListHead( &g_ipoib.adapter_list );\r
+       cl_qlist_init( &g_ipoib.adapter_list );\r
 \r
-       NdisMInitializeWrapper( &ndis_handle, p_drv_obj, p_registry_path, NULL );\r
+       NdisMInitializeWrapper(\r
+               &g_ipoib.h_ndis_wrapper, p_drv_obj, p_registry_path, NULL );\r
 \r
        memset(&characteristics, 0, sizeof(characteristics));\r
        characteristics.MajorNdisVersion                = MAJOR_NDIS_VERSION;\r
@@ -289,18 +291,17 @@ DriverEntry(
 #endif\r
 \r
        status = NdisMRegisterMiniport(\r
-               ndis_handle, &characteristics, sizeof(characteristics) );\r
+               g_ipoib.h_ndis_wrapper, &characteristics, sizeof(characteristics) );\r
        if( status != NDIS_STATUS_SUCCESS )\r
        {\r
                IPOIB_TRACE( IPOIB_DBG_ERROR, \r
                        ("NdisMRegisterMiniport failed with status of %d\n", status) );\r
-               NdisTerminateWrapper( ndis_handle, NULL );\r
+               NdisTerminateWrapper( g_ipoib.h_ndis_wrapper, NULL );\r
                CL_DEINIT;\r
+               return status;\r
        }\r
-       else\r
-       {\r
-               NdisMRegisterUnloadHandler( ndis_handle, ipoib_unload );\r
-       }\r
+\r
+       NdisMRegisterUnloadHandler( g_ipoib.h_ndis_wrapper, ipoib_unload );\r
 \r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
        return status;\r
@@ -643,6 +644,8 @@ ipoib_initialize(
                return NDIS_STATUS_FAILURE;\r
        }\r
 \r
+       ipoib_ref_ibat();\r
+\r
        IPOIB_EXIT( IPOIB_DBG_INIT );\r
        return status;\r
 }\r
@@ -661,6 +664,8 @@ ipoib_halt(
 \r
        IPOIB_ENTER( IPOIB_DBG_INIT );\r
 \r
+       ipoib_deref_ibat();\r
+\r
        CL_ASSERT( adapter_context );\r
        p_adapter = (ipoib_adapter_t*)adapter_context;\r
 \r
@@ -2244,7 +2249,7 @@ __ipoib_dereg_addrs(
        for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )\r
        {\r
                p_addr_item = (net_address_item_t*)\r
-                       cl_vector_get_ptr(  &p_adapter->ip_vector, idx );\r
+                       cl_vector_get_ptr( &p_adapter->ip_vector, idx );\r
 \r
                if( !p_addr_item->p_reg )\r
                        continue;\r
index 94bea71..0d42d59 100644 (file)
 typedef struct _ipoib_globals\r
 {\r
        KSPIN_LOCK              lock;\r
-       LIST_ENTRY              adapter_list;\r
+       cl_qlist_t              adapter_list;\r
        cl_qlist_t              bundle_list;\r
 \r
        atomic32_t              laa_idx;\r
 \r
+       NDIS_HANDLE             h_ndis_wrapper;\r
+       NDIS_HANDLE             h_ibat_dev;\r
+       volatile LONG   ibat_ref;\r
+\r
 }      ipoib_globals_t;\r
 /*\r
 * FIELDS\r
@@ -83,6 +87,9 @@ typedef struct _ipoib_globals
 *\r
 *      laa_idx\r
 *              Global counter for generating LAA MACs\r
+*\r
+*      h_ibat_dev\r
+*              Device handle returned by NdisMRegisterDevice.\r
 *********/\r
 \r
 extern ipoib_globals_t g_ipoib;\r
diff --git a/ulp/ipoib/kernel/ipoib_ibat.c b/ulp/ipoib/kernel/ipoib_ibat.c
new file mode 100644 (file)
index 0000000..0b47206
--- /dev/null
@@ -0,0 +1,472 @@
+/*\r
+ * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
+ * Copyright (c) 2005 SilverStorm Technologies.  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 "ipoib_driver.h"\r
+#include "ipoib_adapter.h"\r
+#include "ipoib_port.h"\r
+#include "ipoib_debug.h"\r
+#include <iba/ib_at_ioctl.h>\r
+\r
+\r
+static NTSTATUS\r
+__ipoib_create(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp );\r
+\r
+static NTSTATUS\r
+__ipoib_cleanup(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp );\r
+\r
+static NTSTATUS\r
+__ipoib_close(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp );\r
+\r
+static NTSTATUS\r
+__ipoib_dispatch(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp );\r
+\r
+\r
+static NTSTATUS\r
+__ibat_get_ports(\r
+       IN                              IRP                                                     *pIrp,\r
+       IN                              IO_STACK_LOCATION                       *pIoStack )\r
+{\r
+       IOCTL_IBAT_PORTS_IN             *pIn;\r
+       IOCTL_IBAT_PORTS_OUT    *pOut;\r
+       KLOCK_QUEUE_HANDLE              hdl;\r
+       cl_list_item_t                  *pItem;\r
+       ipoib_adapter_t                 *pAdapter;\r
+       LONG                                    nPorts;\r
+\r
+       IPOIB_ENTER(IPOIB_DBG_IOCTL);\r
+\r
+       if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=\r
+               sizeof(IOCTL_IBAT_PORTS_IN) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+       \r
+       if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <\r
+               sizeof(IOCTL_IBAT_PORTS_OUT) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       pIn = pIrp->AssociatedIrp.SystemBuffer;\r
+       pOut = pIrp->AssociatedIrp.SystemBuffer;\r
+\r
+       if( pIn->Version != IBAT_IOCTL_VERSION )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+       nPorts = (LONG)cl_qlist_count( &g_ipoib.adapter_list );\r
+       switch( nPorts )\r
+       {\r
+       case 0:\r
+               cl_memclr( pOut->Ports, sizeof(pOut->Ports) );\r
+               /* Fall through */\r
+       case 1:\r
+               pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT);\r
+               break;\r
+\r
+       default:\r
+               pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT) + \r
+                       (sizeof(IBAT_PORT_RECORD) * (nPorts - 1));\r
+               break;\r
+       }\r
+\r
+       pIrp->IoStatus.Information = pOut->Size;\r
+\r
+       if( pOut->Size > pIoStack->Parameters.DeviceIoControl.OutputBufferLength )\r
+       {\r
+               nPorts = 1 +\r
+                       (pIoStack->Parameters.DeviceIoControl.OutputBufferLength -\r
+                       sizeof(IOCTL_IBAT_PORTS_OUT)) / sizeof(IBAT_PORT_RECORD);\r
+\r
+               pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_PORTS_OUT) +\r
+                       ((nPorts - 1) * sizeof(IBAT_PORT_RECORD));\r
+       }\r
+\r
+       pOut->NumPorts = 0;\r
+       pItem = cl_qlist_head( &g_ipoib.adapter_list );\r
+       while( pOut->NumPorts != nPorts )\r
+       {\r
+               pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );\r
+               pOut->Ports[pOut->NumPorts].CaGuid = pAdapter->guids.ca_guid;\r
+               pOut->Ports[pOut->NumPorts].PortGuid = pAdapter->guids.port_guid;\r
+               pOut->NumPorts++;\r
+\r
+               pItem = cl_qlist_next( pItem );\r
+       }\r
+\r
+       KeReleaseInStackQueuedSpinLock( &hdl );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ibat_get_ips(\r
+       IN                              IRP                                                     *pIrp,\r
+       IN                              IO_STACK_LOCATION                       *pIoStack )\r
+{\r
+       IOCTL_IBAT_IP_ADDRESSES_IN      *pIn;\r
+       IOCTL_IBAT_IP_ADDRESSES_OUT     *pOut;\r
+       KLOCK_QUEUE_HANDLE                      hdl;\r
+       cl_list_item_t                          *pItem;\r
+       ipoib_adapter_t                         *pAdapter;\r
+       LONG                                            nIps, maxIps;\r
+       size_t                                          idx;\r
+       net_address_item_t                      *pAddr;\r
+       UINT64                                          PortGuid;\r
+\r
+       IPOIB_ENTER(IPOIB_DBG_IOCTL);\r
+\r
+       if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=\r
+               sizeof(IOCTL_IBAT_IP_ADDRESSES_IN) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+       \r
+       if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <\r
+               sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       pIn = pIrp->AssociatedIrp.SystemBuffer;\r
+       pOut = pIrp->AssociatedIrp.SystemBuffer;\r
+\r
+       if( pIn->Version != IBAT_IOCTL_VERSION )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       PortGuid = pIn->PortGuid;\r
+\r
+       nIps = 0;\r
+       pOut->AddressCount = 0;\r
+       maxIps = 1 +\r
+               ((pIoStack->Parameters.DeviceIoControl.OutputBufferLength -\r
+               sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT)) / sizeof(IP_ADDRESS));\r
+\r
+       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+       for( pItem = cl_qlist_head( &g_ipoib.adapter_list );\r
+               pItem != cl_qlist_end( &g_ipoib.adapter_list );\r
+               pItem = cl_qlist_next( pItem ) )\r
+       {\r
+               pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );\r
+               if( PortGuid && pAdapter->guids.port_guid != PortGuid )\r
+                       continue;\r
+\r
+               cl_obj_lock( &pAdapter->obj );\r
+               nIps += (LONG)cl_vector_get_size( &pAdapter->ip_vector );\r
+\r
+               for( idx = 0;\r
+                       idx < cl_vector_get_size( &pAdapter->ip_vector );\r
+                       idx++ )\r
+               {\r
+                       if( pOut->AddressCount == maxIps )\r
+                               break;\r
+\r
+                       pAddr = (net_address_item_t*)\r
+                               cl_vector_get_ptr( &pAdapter->ip_vector, idx );\r
+\r
+                       pOut->Address[pOut->AddressCount].IpVersion = 4;\r
+                       cl_memclr( &pOut->Address[pOut->AddressCount].Address,\r
+                               sizeof(IP_ADDRESS) );\r
+                       cl_memcpy( &pOut->Address[pOut->AddressCount].Address[12],\r
+                               pAddr->address.as_bytes, IPV4_ADDR_SIZE );\r
+\r
+                       pOut->AddressCount++;\r
+               }\r
+               cl_obj_unlock( &pAdapter->obj );\r
+       }\r
+\r
+       pOut->Size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);\r
+       if( --nIps )\r
+               pOut->Size += sizeof(IP_ADDRESS) * nIps;\r
+\r
+       pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);\r
+       if( --maxIps < nIps )\r
+               pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * maxIps);\r
+       else\r
+               pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * nIps);\r
+\r
+       KeReleaseInStackQueuedSpinLock( &hdl );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ibat_mac_to_gid(\r
+       IN                              IRP                                                     *pIrp,\r
+       IN                              IO_STACK_LOCATION                       *pIoStack )\r
+{\r
+       NTSTATUS                                        status = STATUS_INVALID_PARAMETER;\r
+       IOCTL_IBAT_MAC_TO_GID_IN        *pIn;\r
+       IOCTL_IBAT_MAC_TO_GID_OUT       *pOut;\r
+       KLOCK_QUEUE_HANDLE                      hdl;\r
+       cl_list_item_t                          *pItem;\r
+       ipoib_adapter_t                         *pAdapter;\r
+\r
+       IPOIB_ENTER(IPOIB_DBG_IOCTL);\r
+\r
+       if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=\r
+               sizeof(IOCTL_IBAT_PORTS_IN) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+       \r
+       if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=\r
+               sizeof(IOCTL_IBAT_PORTS_OUT) )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       pIn = pIrp->AssociatedIrp.SystemBuffer;\r
+       pOut = pIrp->AssociatedIrp.SystemBuffer;\r
+\r
+       if( pIn->Version != IBAT_IOCTL_VERSION )\r
+       {\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );\r
+\r
+       for( pItem = cl_qlist_head( &g_ipoib.adapter_list );\r
+               pItem != cl_qlist_end( &g_ipoib.adapter_list );\r
+               pItem = cl_qlist_next( pItem ) )\r
+       {\r
+               pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );\r
+               if( pIn->PortGuid != pAdapter->guids.port_guid )\r
+                       continue;\r
+\r
+               /* Found the port - lookup the MAC. */\r
+               cl_obj_lock( &pAdapter->obj );\r
+               if( pAdapter->p_port )\r
+               {\r
+                       status = ipoib_mac_to_gid(\r
+                               pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->DestGid );\r
+                       if( NT_SUCCESS( status ) )\r
+                       {\r
+                               pIrp->IoStatus.Information =\r
+                                       sizeof(IOCTL_IBAT_MAC_TO_GID_OUT);\r
+                       }\r
+               }\r
+               cl_obj_unlock( &pAdapter->obj );\r
+               break;\r
+       }\r
+\r
+       KeReleaseInStackQueuedSpinLock( &hdl );\r
+\r
+       return status;\r
+}\r
+\r
+\r
+void\r
+ipoib_ref_ibat()\r
+{\r
+       NDIS_STATUS                     status;\r
+       NDIS_STRING                     DeviceName;\r
+       NDIS_STRING                     DeviceLinkUnicodeString;\r
+       PDRIVER_DISPATCH        DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];\r
+       DEVICE_OBJECT           *p_dev_obj;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       if( InterlockedIncrement( &g_ipoib.ibat_ref ) == 1 )\r
+       {\r
+               NdisInitUnicodeString( &DeviceName, IBAT_DEV_NAME );\r
+               NdisInitUnicodeString( &DeviceLinkUnicodeString, IBAT_DOS_DEV_NAME );\r
+\r
+               NdisZeroMemory( DispatchTable, sizeof(DispatchTable) );\r
+\r
+               DispatchTable[IRP_MJ_CREATE] = __ipoib_create;\r
+               DispatchTable[IRP_MJ_CLEANUP] = __ipoib_cleanup;\r
+               DispatchTable[IRP_MJ_CLOSE] = __ipoib_close;\r
+               DispatchTable[IRP_MJ_DEVICE_CONTROL] = __ipoib_dispatch;\r
+               DispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] = __ipoib_dispatch;\r
+\r
+               status = NdisMRegisterDevice( g_ipoib.h_ndis_wrapper,\r
+                       &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0],\r
+                       &p_dev_obj, &g_ipoib.h_ibat_dev );\r
+               if( status != NDIS_STATUS_SUCCESS )\r
+               {\r
+                       IPOIB_TRACE( IPOIB_DBG_ERROR, \r
+                               ("NdisMRegisterDevice failed with status of %d\n", status) );\r
+               }\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+}\r
+\r
+\r
+void\r
+ipoib_deref_ibat()\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       if( InterlockedDecrement( &g_ipoib.ibat_ref ) )\r
+       {\r
+               IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+               return;\r
+       }\r
+\r
+       if( g_ipoib.h_ibat_dev )\r
+       {\r
+               NdisMDeregisterDevice( g_ipoib.h_ibat_dev );\r
+               g_ipoib.h_ibat_dev = NULL;\r
+       }\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ipoib_create(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       UNREFERENCED_PARAMETER( pDevObj );\r
+\r
+       ipoib_ref_ibat();\r
+\r
+       pIrp->IoStatus.Status = STATUS_SUCCESS;\r
+       pIrp->IoStatus.Information = 0;\r
+       IoCompleteRequest( pIrp, IO_NO_INCREMENT );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ipoib_cleanup(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       UNREFERENCED_PARAMETER( pDevObj );\r
+\r
+       ipoib_deref_ibat();\r
+\r
+       pIrp->IoStatus.Status = STATUS_SUCCESS;\r
+       pIrp->IoStatus.Information = 0;\r
+       IoCompleteRequest( pIrp, IO_NO_INCREMENT );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ipoib_close(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp )\r
+{\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       UNREFERENCED_PARAMETER( pDevObj );\r
+\r
+       pIrp->IoStatus.Status = STATUS_SUCCESS;\r
+       pIrp->IoStatus.Information = 0;\r
+       IoCompleteRequest( pIrp, IO_NO_INCREMENT );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+static NTSTATUS\r
+__ipoib_dispatch(\r
+       IN                              DEVICE_OBJECT* const            pDevObj,\r
+       IN                              IRP* const                                      pIrp )\r
+{\r
+       IO_STACK_LOCATION       *pIoStack;\r
+       NTSTATUS                        status = STATUS_SUCCESS;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_IOCTL );\r
+\r
+       UNREFERENCED_PARAMETER( pDevObj );\r
+\r
+       pIoStack = IoGetCurrentIrpStackLocation( pIrp );\r
+\r
+       pIrp->IoStatus.Information = 0;\r
+\r
+       switch( pIoStack->Parameters.DeviceIoControl.IoControlCode )\r
+       {\r
+       case IOCTL_IBAT_PORTS:\r
+               IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_PORTS recieved\n") );\r
+               status = __ibat_get_ports( pIrp, pIoStack );\r
+               break;\r
+\r
+       case IOCTL_IBAT_IP_ADDRESSES:\r
+               IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_IP_ADDRESSES recieved\n" ));\r
+               status = __ibat_get_ips( pIrp, pIoStack );\r
+               break;\r
+\r
+       case IOCTL_IBAT_MAC_TO_GID:\r
+               IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_MAC_TO_GID recieved\n" ));\r
+               status = __ibat_mac_to_gid( pIrp, pIoStack );\r
+               break;\r
+\r
+       default:\r
+               IPOIB_TRACE( IPOIB_DBG_WARN, ("unknow IOCTL code = 0x%x\n",\r
+                       pIoStack->Parameters.DeviceIoControl.IoControlCode) );\r
+               status = STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       pIrp->IoStatus.Status = status;\r
+       IoCompleteRequest( pIrp, IO_NO_INCREMENT );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );\r
+       return status;\r
+}\r
+\r
diff --git a/ulp/ipoib/kernel/ipoib_ibat.h b/ulp/ipoib/kernel/ipoib_ibat.h
new file mode 100644 (file)
index 0000000..83d0195
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.\r
+ * Copyright (c) 2005 SilverStorm Technologies.  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
+#ifndef _IPOIB_IBAT_H_\r
+#define _IPOIB_IBAT_H_\r
+\r
+\r
+void\r
+ipoib_ref_ibat();\r
+\r
+void\r
+ipoib_deref_ibat();\r
+\r
+\r
+#endif /* _IPOIB_IBAT_H_ */\r
index 9ab1a41..62abcea 100644 (file)
@@ -521,7 +521,7 @@ ipoib_port_destroy(
 \r
        CL_ASSERT( p_port );\r
        CL_ASSERT( p_port->p_adapter );\r
-       CL_ASSERT( p_port->p_adapter->p_port == p_port );\r
+       CL_ASSERT( !p_port->p_adapter->p_port );\r
 \r
        cl_obj_destroy( &p_port->obj );\r
 \r
@@ -3897,6 +3897,40 @@ __endpt_mgr_remove(
 }\r
 \r
 \r
+NTSTATUS\r
+ipoib_mac_to_gid(\r
+       IN                              ipoib_port_t* const                     p_port,\r
+       IN              const   mac_addr_t                                      mac,\r
+               OUT                     ib_gid_t*                                       p_gid )\r
+{\r
+       ipoib_endpt_t* p_endpt;\r
+       cl_map_item_t   *p_item;\r
+       uint64_t                key = 0;\r
+\r
+       IPOIB_ENTER( IPOIB_DBG_ENDPT );\r
+\r
+       cl_memcpy( &key, &mac, sizeof(mac_addr_t) );\r
+\r
+       cl_obj_lock( &p_port->obj );\r
+\r
+       p_item = cl_qmap_get( &p_port->endpt_mgr.mac_endpts, key );\r
+       if( p_item == cl_qmap_end( &p_port->endpt_mgr.mac_endpts ) )\r
+       {\r
+               cl_obj_unlock( &p_port->obj );\r
+               IPOIB_TRACE_EXIT( IPOIB_DBG_ENDPT, ("Failed endpoint lookup.\n") );\r
+               return STATUS_INVALID_PARAMETER;\r
+       }\r
+\r
+       p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, mac_item );\r
+       *p_gid = p_endpt->dgid;\r
+\r
+       cl_obj_unlock( &p_port->obj );\r
+\r
+       IPOIB_EXIT( IPOIB_DBG_ENDPT );\r
+       return STATUS_SUCCESS;\r
+}\r
+\r
+\r
 static inline NDIS_STATUS\r
 __endpt_mgr_ref(\r
        IN                              ipoib_port_t* const                     p_port,\r
index 7c12292..8d78ce6 100644 (file)
@@ -584,5 +584,10 @@ void
 ipoib_port_resume(\r
        IN                              ipoib_port_t* const                     p_port );\r
 \r
+NTSTATUS\r
+ipoib_mac_to_gid(\r
+       IN                              ipoib_port_t* const                     p_port,\r
+       IN              const   mac_addr_t                                      mac,\r
+               OUT                     ib_gid_t*                                       p_gid );\r
 \r
 #endif /* _IPOIB_PORT_H_ */\r