[Openib-windows] RE: Anything new about the IPOIB arp check-in?

Fab Tillier ftillier at silverstorm.com
Fri Dec 2 17:14:18 PST 2005


Hi Tzachi,

I've finished the implementation.  I removed the IP to local GUID lookup as it
is inefficient.  WSD implements it by looking the IP address up in a red/black
tree, while IPoIB would have to do a linear search through each instance's IP
array.

Attached is a patch that provides the address translation implementation along
with your test program.  I have tested that it works, but would appreciate a
code review.

Please take a look and let me know if you see any issues.  I'll check this in
when I get your approval.

Note that a lot of the IPoIB files have changed as I had to fix a race condition
accessing the adapter's port object while it was destroyed.

Thanks,

- Fab

Index: ulp/ipoib/kernel/ipoib_ibat.c
===================================================================
--- ulp/ipoib/kernel/ipoib_ibat.c   (revision 0)
+++ ulp/ipoib/kernel/ipoib_ibat.c   (revision 0)
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+
+#include "ipoib_driver.h"
+#include "ipoib_adapter.h"
+#include "ipoib_port.h"
+#include "ipoib_debug.h"
+#include <iba/ib_at_ioctl.h>
+
+
+static NTSTATUS
+__ipoib_create(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp );
+
+static NTSTATUS
+__ipoib_cleanup(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp );
+
+static NTSTATUS
+__ipoib_close(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp );
+
+static NTSTATUS
+__ipoib_dispatch(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp );
+
+
+static NTSTATUS
+__ibat_get_ports(
+   IN              IRP                         *pIrp,
+   IN              IO_STACK_LOCATION           *pIoStack )
+{
+   IOCTL_IBAT_PORTS_IN     *pIn;
+   IOCTL_IBAT_PORTS_OUT    *pOut;
+   KLOCK_QUEUE_HANDLE      hdl;
+   cl_list_item_t          *pItem;
+   ipoib_adapter_t         *pAdapter;
+   LONG                    nPorts;
+
+   IPOIB_ENTER(IPOIB_DBG_IOCTL);
+
+   if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
+       sizeof(IOCTL_IBAT_PORTS_IN) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+   
+   if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <
+       sizeof(IOCTL_IBAT_PORTS_OUT) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   pIn = pIrp->AssociatedIrp.SystemBuffer;
+   pOut = pIrp->AssociatedIrp.SystemBuffer;
+
+   if( pIn->Version != IBAT_IOCTL_VERSION )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
+   nPorts = (LONG)cl_qlist_count( &g_ipoib.adapter_list );
+   switch( nPorts )
+   {
+   case 0:
+       cl_memclr( pOut->Ports, sizeof(pOut->Ports) );
+       /* Fall through */
+   case 1:
+       pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT);
+       break;
+
+   default:
+       pOut->Size = sizeof(IOCTL_IBAT_PORTS_OUT) + 
+           (sizeof(IBAT_PORT_RECORD) * (nPorts - 1));
+       break;
+   }
+
+   pIrp->IoStatus.Information = pOut->Size;
+
+   if( pOut->Size > pIoStack->Parameters.DeviceIoControl.OutputBufferLength )
+   {
+       nPorts = 1 +
+           (pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
+           sizeof(IOCTL_IBAT_PORTS_OUT)) / sizeof(IBAT_PORT_RECORD);
+
+       pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_PORTS_OUT) +
+           ((nPorts - 1) * sizeof(IBAT_PORT_RECORD));
+   }
+
+   pOut->NumPorts = 0;
+   pItem = cl_qlist_head( &g_ipoib.adapter_list );
+   while( pOut->NumPorts != nPorts )
+   {
+       pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
+       pOut->Ports[pOut->NumPorts].CaGuid = pAdapter->guids.ca_guid;
+       pOut->Ports[pOut->NumPorts].PortGuid = pAdapter->guids.port_guid;
+       pOut->NumPorts++;
+
+       pItem = cl_qlist_next( pItem );
+   }
+
+   KeReleaseInStackQueuedSpinLock( &hdl );
+   return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+__ibat_get_ips(
+   IN              IRP                         *pIrp,
+   IN              IO_STACK_LOCATION           *pIoStack )
+{
+   IOCTL_IBAT_IP_ADDRESSES_IN  *pIn;
+   IOCTL_IBAT_IP_ADDRESSES_OUT *pOut;
+   KLOCK_QUEUE_HANDLE          hdl;
+   cl_list_item_t              *pItem;
+   ipoib_adapter_t             *pAdapter;
+   LONG                        nIps, maxIps;
+   size_t                      idx;
+   net_address_item_t          *pAddr;
+   UINT64                      PortGuid;
+
+   IPOIB_ENTER(IPOIB_DBG_IOCTL);
+
+   if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
+       sizeof(IOCTL_IBAT_IP_ADDRESSES_IN) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+   
+   if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength <
+       sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   pIn = pIrp->AssociatedIrp.SystemBuffer;
+   pOut = pIrp->AssociatedIrp.SystemBuffer;
+
+   if( pIn->Version != IBAT_IOCTL_VERSION )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   PortGuid = pIn->PortGuid;
+
+   nIps = 0;
+   pOut->AddressCount = 0;
+   maxIps = 1 +
+       ((pIoStack->Parameters.DeviceIoControl.OutputBufferLength -
+       sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT)) / sizeof(IP_ADDRESS));
+
+   KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
+   for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
+       pItem != cl_qlist_end( &g_ipoib.adapter_list );
+       pItem = cl_qlist_next( pItem ) )
+   {
+       pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
+       if( PortGuid && pAdapter->guids.port_guid != PortGuid )
+           continue;
+
+       cl_obj_lock( &pAdapter->obj );
+       nIps += (LONG)cl_vector_get_size( &pAdapter->ip_vector );
+
+       for( idx = 0;
+           idx < cl_vector_get_size( &pAdapter->ip_vector );
+           idx++ )
+       {
+           if( pOut->AddressCount == maxIps )
+               break;
+
+           pAddr = (net_address_item_t*)
+               cl_vector_get_ptr( &pAdapter->ip_vector, idx );
+
+           pOut->Address[pOut->AddressCount].IpVersion = 4;
+           cl_memclr( &pOut->Address[pOut->AddressCount].Address,
+               sizeof(IP_ADDRESS) );
+           cl_memcpy( &pOut->Address[pOut->AddressCount].Address[12],
+               pAddr->address.as_bytes, IPV4_ADDR_SIZE );
+
+           pOut->AddressCount++;
+       }
+       cl_obj_unlock( &pAdapter->obj );
+   }
+
+   pOut->Size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
+   if( --nIps )
+       pOut->Size += sizeof(IP_ADDRESS) * nIps;
+
+   pIrp->IoStatus.Information = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
+   if( --maxIps < nIps )
+       pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * maxIps);
+   else
+       pIrp->IoStatus.Information += (sizeof(IP_ADDRESS) * nIps);
+
+   KeReleaseInStackQueuedSpinLock( &hdl );
+   return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+__ibat_mac_to_gid(
+   IN              IRP                         *pIrp,
+   IN              IO_STACK_LOCATION           *pIoStack )
+{
+   NTSTATUS                    status = STATUS_INVALID_PARAMETER;
+   IOCTL_IBAT_MAC_TO_GID_IN    *pIn;
+   IOCTL_IBAT_MAC_TO_GID_OUT   *pOut;
+   KLOCK_QUEUE_HANDLE          hdl;
+   cl_list_item_t              *pItem;
+   ipoib_adapter_t             *pAdapter;
+
+   IPOIB_ENTER(IPOIB_DBG_IOCTL);
+
+   if( pIoStack->Parameters.DeviceIoControl.InputBufferLength !=
+       sizeof(IOCTL_IBAT_PORTS_IN) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid input buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+   
+   if( pIoStack->Parameters.DeviceIoControl.OutputBufferLength !=
+       sizeof(IOCTL_IBAT_PORTS_OUT) )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid output buffer size.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   pIn = pIrp->AssociatedIrp.SystemBuffer;
+   pOut = pIrp->AssociatedIrp.SystemBuffer;
+
+   if( pIn->Version != IBAT_IOCTL_VERSION )
+   {
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ERROR, ("Invalid version.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
+
+   for( pItem = cl_qlist_head( &g_ipoib.adapter_list );
+       pItem != cl_qlist_end( &g_ipoib.adapter_list );
+       pItem = cl_qlist_next( pItem ) )
+   {
+       pAdapter = CONTAINING_RECORD( pItem, ipoib_adapter_t, entry );
+       if( pIn->PortGuid != pAdapter->guids.port_guid )
+           continue;
+
+       /* Found the port - lookup the MAC. */
+       cl_obj_lock( &pAdapter->obj );
+       if( pAdapter->p_port )
+       {
+           status = ipoib_mac_to_gid(
+               pAdapter->p_port, *(mac_addr_t*)pIn->DestMac, &pOut->DestGid );
+           if( NT_SUCCESS( status ) )
+           {
+               pIrp->IoStatus.Information =
+                   sizeof(IOCTL_IBAT_MAC_TO_GID_OUT);
+           }
+       }
+       cl_obj_unlock( &pAdapter->obj );
+       break;
+   }
+
+   KeReleaseInStackQueuedSpinLock( &hdl );
+
+   return status;
+}
+
+
+void
+ipoib_ref_ibat()
+{
+   NDIS_STATUS         status;
+   NDIS_STRING         DeviceName;
+   NDIS_STRING         DeviceLinkUnicodeString;
+   PDRIVER_DISPATCH    DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
+   DEVICE_OBJECT       *p_dev_obj;
+
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   if( InterlockedIncrement( &g_ipoib.ibat_ref ) == 1 )
+   {
+       NdisInitUnicodeString( &DeviceName, IBAT_DEV_NAME );
+       NdisInitUnicodeString( &DeviceLinkUnicodeString, IBAT_DOS_DEV_NAME );
+
+       NdisZeroMemory( DispatchTable, sizeof(DispatchTable) );
+
+       DispatchTable[IRP_MJ_CREATE] = __ipoib_create;
+       DispatchTable[IRP_MJ_CLEANUP] = __ipoib_cleanup;
+       DispatchTable[IRP_MJ_CLOSE] = __ipoib_close;
+       DispatchTable[IRP_MJ_DEVICE_CONTROL] = __ipoib_dispatch;
+       DispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] = __ipoib_dispatch;
+
+       status = NdisMRegisterDevice( g_ipoib.h_ndis_wrapper,
+           &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0],
+           &p_dev_obj, &g_ipoib.h_ibat_dev );
+       if( status != NDIS_STATUS_SUCCESS )
+       {
+           IPOIB_TRACE( IPOIB_DBG_ERROR, 
+               ("NdisMRegisterDevice failed with status of %d\n", status) );
+       }
+   }
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+}
+
+
+void
+ipoib_deref_ibat()
+{
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   if( InterlockedDecrement( &g_ipoib.ibat_ref ) )
+   {
+       IPOIB_EXIT( IPOIB_DBG_IOCTL );
+       return;
+   }
+
+   if( g_ipoib.h_ibat_dev )
+   {
+       NdisMDeregisterDevice( g_ipoib.h_ibat_dev );
+       g_ipoib.h_ibat_dev = NULL;
+   }
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+}
+
+
+static NTSTATUS
+__ipoib_create(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp )
+{
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   UNREFERENCED_PARAMETER( pDevObj );
+
+   ipoib_ref_ibat();
+
+   pIrp->IoStatus.Status = STATUS_SUCCESS;
+   pIrp->IoStatus.Information = 0;
+   IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+   return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+__ipoib_cleanup(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp )
+{
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   UNREFERENCED_PARAMETER( pDevObj );
+
+   ipoib_deref_ibat();
+
+   pIrp->IoStatus.Status = STATUS_SUCCESS;
+   pIrp->IoStatus.Information = 0;
+   IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+   return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+__ipoib_close(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp )
+{
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   UNREFERENCED_PARAMETER( pDevObj );
+
+   pIrp->IoStatus.Status = STATUS_SUCCESS;
+   pIrp->IoStatus.Information = 0;
+   IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+   return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+__ipoib_dispatch(
+   IN              DEVICE_OBJECT* const        pDevObj,
+   IN              IRP* const                  pIrp )
+{
+   IO_STACK_LOCATION   *pIoStack;
+   NTSTATUS            status = STATUS_SUCCESS;
+
+   IPOIB_ENTER( IPOIB_DBG_IOCTL );
+
+   UNREFERENCED_PARAMETER( pDevObj );
+
+   pIoStack = IoGetCurrentIrpStackLocation( pIrp );
+
+   pIrp->IoStatus.Information = 0;
+
+   switch( pIoStack->Parameters.DeviceIoControl.IoControlCode )
+   {
+   case IOCTL_IBAT_PORTS:
+       IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_PORTS recieved\n") );
+       status = __ibat_get_ports( pIrp, pIoStack );
+       break;
+
+   case IOCTL_IBAT_IP_ADDRESSES:
+       IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_IP_ADDRESSES recieved\n" ));
+       status = __ibat_get_ips( pIrp, pIoStack );
+       break;
+
+   case IOCTL_IBAT_MAC_TO_GID:
+       IPOIB_TRACE( IPOIB_DBG_IOCTL, ("IOCTL_IBAT_MAC_TO_GID recieved\n" ));
+       status = __ibat_mac_to_gid( pIrp, pIoStack );
+       break;
+
+   default:
+       IPOIB_TRACE( IPOIB_DBG_WARN, ("unknow IOCTL code = 0x%x\n",
+           pIoStack->Parameters.DeviceIoControl.IoControlCode) );
+       status = STATUS_INVALID_PARAMETER;
+   }
+
+   pIrp->IoStatus.Status = status;
+   IoCompleteRequest( pIrp, IO_NO_INCREMENT );
+
+   IPOIB_EXIT( IPOIB_DBG_IOCTL );
+   return status;
+}
+
Index: ulp/ipoib/kernel/ipoib_adapter.c
===================================================================
--- ulp/ipoib/kernel/ipoib_adapter.c    (revision 193)
+++ ulp/ipoib/kernel/ipoib_adapter.c    (working copy)
@@ -190,7 +190,7 @@
    }
 
    KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-   InsertHeadList( &g_ipoib.adapter_list, &p_adapter->entry );
+   cl_qlist_insert_tail( &g_ipoib.adapter_list, &p_adapter->entry );
    KeReleaseInStackQueuedSpinLock( &hdl );
 
    status = adapter_init( p_adapter );
@@ -243,7 +243,6 @@
    cl_mutex_acquire( &p_adapter->mutex );
    cl_obj_lock( &p_adapter->obj );
    p_adapter->state = IB_PNP_PORT_REMOVE;
-   cl_obj_unlock( &p_adapter->obj );
 
    /*
     * Clear the pointer to the port object since the object destruction
@@ -252,6 +251,8 @@
     */
    p_adapter->p_port = NULL;
 
+   cl_obj_unlock( &p_adapter->obj );
+
    cl_mutex_release( &p_adapter->mutex );
 
    cl_obj_destroy( &p_adapter->obj );
@@ -429,8 +430,8 @@
    }
 
    KeAcquireInStackQueuedSpinLock( &g_ipoib.lock, &hdl );
-   ASSERT( !IsListEmpty( &g_ipoib.adapter_list ) );
-   RemoveEntryList( &p_adapter->entry );
+   ASSERT( cl_qlist_count( &g_ipoib.adapter_list ) );
+   cl_qlist_remove_item( &g_ipoib.adapter_list, &p_adapter->entry );
    KeReleaseInStackQueuedSpinLock( &hdl );
 
    IPOIB_EXIT( IPOIB_DBG_INIT );
@@ -476,6 +477,7 @@
 {
    ib_api_status_t     status;
    ipoib_adapter_t     *p_adapter;
+   ipoib_port_t        *p_port;
    ib_pnp_event_t      old_state;
 
    IPOIB_ENTER( IPOIB_DBG_PNP );
@@ -527,17 +529,20 @@
        p_adapter->state = IB_PNP_PORT_ADD;
        cl_obj_unlock( &p_adapter->obj );
        status = ipoib_create_port( p_adapter,
-           (ib_pnp_port_rec_t*)p_pnp_rec, &p_adapter->p_port );
+           (ib_pnp_port_rec_t*)p_pnp_rec, &p_port );
+       cl_obj_lock( &p_adapter->obj );
        if( status != IB_SUCCESS )
        {
-           cl_obj_lock( &p_adapter->obj );
            p_adapter->state = old_state;
            cl_obj_unlock( &p_adapter->obj );
            p_adapter->hung = TRUE;
            break;
        }
 
-       p_pnp_rec->context = p_adapter->p_port;
+       p_pnp_rec->context = p_port;
+
+       p_adapter->p_port = p_port;
+       cl_obj_unlock( &p_adapter->obj );
        break;
 
    case IB_PNP_PORT_REMOVE:
@@ -546,9 +551,10 @@
 
        cl_obj_lock( &p_adapter->obj );
        p_adapter->state = IB_PNP_PORT_REMOVE;
+       p_port = p_adapter->p_port;
+       p_adapter->p_port = NULL;
        cl_obj_unlock( &p_adapter->obj );
-       ipoib_port_destroy( p_adapter->p_port );
-       p_adapter->p_port = NULL;
+       ipoib_port_destroy( p_port );
        p_pnp_rec->context = NULL;
        status = IB_SUCCESS;
        break;
@@ -732,6 +738,7 @@
    IN              void*                       context )
 {
    ipoib_adapter_t*    p_adapter;
+   ipoib_port_t*       p_port;
    ib_api_status_t     status;
    ib_pnp_event_t      state;
 
@@ -751,14 +758,14 @@
 
    state = p_adapter->state;
 
+   /* Destroy the current port instance if it still exists. */
+   p_port = p_adapter->p_port;
+   p_adapter->p_port = NULL;
    cl_obj_unlock( &p_adapter->obj );
 
-   /* Destroy the current port instance if it still exists. */
-   if( p_adapter->p_port )
-   {
-       ipoib_port_destroy( p_adapter->p_port );
-       p_adapter->p_port = NULL;
-   }
+   if( p_port )
+       ipoib_port_destroy( p_port );
+
    /* Complete any pending OIDs. */
    ipoib_resume_oids( p_adapter );
 
Index: ulp/ipoib/kernel/SOURCES
===================================================================
--- ulp/ipoib/kernel/SOURCES    (revision 193)
+++ ulp/ipoib/kernel/SOURCES    (working copy)
@@ -6,7 +6,8 @@
        ipoib_driver.c \
        ipoib_adapter.c \
        ipoib_endpoint.c \
-       ipoib_port.c
+       ipoib_port.c \
+       ipoib_ibat.c
 
 INCLUDES=..;..\..\..\inc;..\..\..\inc\kernel;
 
Index: ulp/ipoib/kernel/ipoib_ibat.h
===================================================================
--- ulp/ipoib/kernel/ipoib_ibat.h   (revision 0)
+++ ulp/ipoib/kernel/ipoib_ibat.h   (revision 0)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
+ * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+ *
+ * This software is available to you under the OpenIB.org BSD license
+ * below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * $Id$
+ */
+
+
+#ifndef _IPOIB_IBAT_H_
+#define _IPOIB_IBAT_H_
+
+
+void
+ipoib_ref_ibat();
+
+void
+ipoib_deref_ibat();
+
+
+#endif /* _IPOIB_IBAT_H_ */
Index: ulp/ipoib/kernel/ipoib_port.c
===================================================================
--- ulp/ipoib/kernel/ipoib_port.c   (revision 193)
+++ ulp/ipoib/kernel/ipoib_port.c   (working copy)
@@ -521,7 +521,7 @@
 
    CL_ASSERT( p_port );
    CL_ASSERT( p_port->p_adapter );
-   CL_ASSERT( p_port->p_adapter->p_port == p_port );
+   CL_ASSERT( !p_port->p_adapter->p_port );
 
    cl_obj_destroy( &p_port->obj );
 
@@ -3897,7 +3897,41 @@
 }
 
 
-static inline NDIS_STATUS
+NTSTATUS
+ipoib_mac_to_gid(
+   IN              ipoib_port_t* const         p_port,
+   IN      const   mac_addr_t                  mac,
+       OUT         ib_gid_t*                   p_gid )
+{
+   ipoib_endpt_t* p_endpt;
+   cl_map_item_t   *p_item;
+   uint64_t        key = 0;
+
+   IPOIB_ENTER( IPOIB_DBG_ENDPT );
+
+   cl_memcpy( &key, &mac, sizeof(mac_addr_t) );
+
+   cl_obj_lock( &p_port->obj );
+
+   p_item = cl_qmap_get( &p_port->endpt_mgr.mac_endpts, key );
+   if( p_item == cl_qmap_end( &p_port->endpt_mgr.mac_endpts ) )
+   {
+       cl_obj_unlock( &p_port->obj );
+       IPOIB_TRACE_EXIT( IPOIB_DBG_ENDPT, ("Failed endpoint lookup.\n") );
+       return STATUS_INVALID_PARAMETER;
+   }
+
+   p_endpt = PARENT_STRUCT( p_item, ipoib_endpt_t, mac_item );
+   *p_gid = p_endpt->dgid;
+
+   cl_obj_unlock( &p_port->obj );
+
+   IPOIB_EXIT( IPOIB_DBG_ENDPT );
+   return STATUS_SUCCESS;
+}
+
+
+NDIS_STATUS
 __endpt_mgr_ref(
    IN              ipoib_port_t* const         p_port,
    IN      const   mac_addr_t                  mac,
Index: ulp/ipoib/kernel/ipoib_adapter.h
===================================================================
--- ulp/ipoib/kernel/ipoib_adapter.h    (revision 193)
+++ ulp/ipoib/kernel/ipoib_adapter.h    (working copy)
@@ -130,7 +130,7 @@
    NDIS_HANDLE             h_adapter;
    ipoib_ifc_data_t        guids;
 
-   LIST_ENTRY              entry;
+   cl_list_item_t          entry;
 
    ib_al_handle_t          h_al;
    ib_pnp_handle_t         h_pnp;
Index: ulp/ipoib/kernel/ipoib_port.h
===================================================================
--- ulp/ipoib/kernel/ipoib_port.h   (revision 193)
+++ ulp/ipoib/kernel/ipoib_port.h   (working copy)
@@ -584,5 +584,10 @@
 ipoib_port_resume(
    IN              ipoib_port_t* const         p_port );
 
+NTSTATUS
+ipoib_mac_to_gid(
+   IN              ipoib_port_t* const         p_port,
+   IN      const   mac_addr_t                  mac,
+       OUT         ib_gid_t*                   p_gid );
 
 #endif /* _IPOIB_PORT_H_ */
Index: ulp/ipoib/kernel/ipoib_driver.c
===================================================================
--- ulp/ipoib/kernel/ipoib_driver.c (revision 193)
+++ ulp/ipoib/kernel/ipoib_driver.c (working copy)
@@ -33,6 +33,7 @@
 #include "ipoib_driver.h"
 #include "ipoib_debug.h"
 #include "ipoib_port.h"
+#include "ipoib_ibat.h"
 #include <complib/cl_bus_ifc.h>
 #include <complib/cl_init.h>
 #include <initguid.h>
@@ -266,9 +267,10 @@
    __ipoib_read_registry(p_registry_path);
    
    KeInitializeSpinLock( &g_ipoib.lock );
-   InitializeListHead( &g_ipoib.adapter_list );
+   cl_qlist_init( &g_ipoib.adapter_list );
 
-   NdisMInitializeWrapper( &ndis_handle, p_drv_obj, p_registry_path, NULL );
+   NdisMInitializeWrapper(
+       &g_ipoib.h_ndis_wrapper, p_drv_obj, p_registry_path, NULL );
 
    memset(&characteristics, 0, sizeof(characteristics));
    characteristics.MajorNdisVersion        = MAJOR_NDIS_VERSION;
@@ -289,19 +291,18 @@
 #endif
 
    status = NdisMRegisterMiniport(
-       ndis_handle, &characteristics, sizeof(characteristics) );
+       g_ipoib.h_ndis_wrapper, &characteristics, sizeof(characteristics) );
    if( status != NDIS_STATUS_SUCCESS )
    {
        IPOIB_TRACE( IPOIB_DBG_ERROR, 
            ("NdisMRegisterMiniport failed with status of %d\n", status) );
-       NdisTerminateWrapper( ndis_handle, NULL );
+       NdisTerminateWrapper( g_ipoib.h_ndis_wrapper, NULL );
        CL_DEINIT;
+       return status;
    }
-   else
-   {
-       NdisMRegisterUnloadHandler( ndis_handle, ipoib_unload );
-   }
 
+   NdisMRegisterUnloadHandler( g_ipoib.h_ndis_wrapper, ipoib_unload );
+
    IPOIB_EXIT( IPOIB_DBG_INIT );
    return status;
 }
@@ -643,6 +644,8 @@
        return NDIS_STATUS_FAILURE;
    }
 
+   ipoib_ref_ibat();
+
    IPOIB_EXIT( IPOIB_DBG_INIT );
    return status;
 }
@@ -661,6 +664,8 @@
 
    IPOIB_ENTER( IPOIB_DBG_INIT );
 
+   ipoib_deref_ibat();
+
    CL_ASSERT( adapter_context );
    p_adapter = (ipoib_adapter_t*)adapter_context;
 
@@ -2244,7 +2249,7 @@
    for( idx = 0; idx < cl_vector_get_size( &p_adapter->ip_vector); idx++ )
    {
        p_addr_item = (net_address_item_t*)
-           cl_vector_get_ptr(  &p_adapter->ip_vector, idx );
+           cl_vector_get_ptr( &p_adapter->ip_vector, idx );
 
        if( !p_addr_item->p_reg )
            continue;
Index: ulp/ipoib/kernel/ipoib_debug.h
===================================================================
--- ulp/ipoib/kernel/ipoib_debug.h  (revision 193)
+++ ulp/ipoib/kernel/ipoib_debug.h  (working copy)
@@ -59,6 +59,7 @@
 #define IPOIB_DBG_MCAST    (1 << 7)
 #define IPOIB_DBG_ALLOC    (1 << 8)
 #define IPOIB_DBG_OID  (1 << 9)
+#define IPOIB_DBG_IOCTL    (1 << 10)
 
 #define IPOIB_DBG_FUNC (1 << 28)   /* For function entry/exit */
 #define IPOIB_DBG_INFO (1 << 29)   /* For verbose information */
Index: ulp/ipoib/kernel/ipoib_driver.h
===================================================================
--- ulp/ipoib/kernel/ipoib_driver.h (revision 193)
+++ ulp/ipoib/kernel/ipoib_driver.h (working copy)
@@ -64,11 +64,15 @@
 typedef struct _ipoib_globals
 {
    KSPIN_LOCK      lock;
-   LIST_ENTRY      adapter_list;
+   cl_qlist_t      adapter_list;
    cl_qlist_t      bundle_list;
 
    atomic32_t      laa_idx;
 
+   NDIS_HANDLE     h_ndis_wrapper;
+   NDIS_HANDLE     h_ibat_dev;
+   volatile LONG   ibat_ref;
+
 }  ipoib_globals_t;
 /*
 * FIELDS
@@ -83,6 +87,9 @@
 *
 *  laa_idx
 *      Global counter for generating LAA MACs
+*
+*  h_ibat_dev
+*      Device handle returned by NdisMRegisterDevice.
 *********/
 
 extern ipoib_globals_t g_ipoib;
Index: tests/dirs
===================================================================
--- tests/dirs  (revision 193)
+++ tests/dirs  (working copy)
@@ -1,5 +1,6 @@
 DIRS=\
    alts    \
    cmtest  \
    wsd     \
+   ipoib   \
    limits
Index: inc/iba/ib_at_ioctl.h
===================================================================
--- inc/iba/ib_at_ioctl.h   (revision 0)
+++ inc/iba/ib_at_ioctl.h   (revision 0)
@@ -0,0 +1,133 @@
+/*
+* Copyright (c) 2005 Mellanox Technologies.  All rights reserved.
+* Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.
+*
+* This software is available to you under the OpenIB.org BSD license
+* below:
+*
+*     Redistribution and use in source and binary forms, with or
+*     without modification, are permitted provided that the following
+*     conditions are met:
+*
+*      - Redistributions of source code must retain the above
+*        copyright notice, this list of conditions and the following
+*        disclaimer.
+*
+*      - Redistributions in binary form must reproduce the above
+*        copyright notice, this list of conditions and the following
+*        disclaimer in the documentation and/or other materials
+*        provided with the distribution.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* $Id$
+*/
+
+/* This file is shared between user- and kernel-mode */
+
+#include <iba/ib_types.h>
+
+
+#ifndef    _IB_AT_IOCTL_H_
+#define    _IB_AT_IOCTL_H_
+
+
+#define    IBAT_IOCTL_VERSION      2
+
+#define    IBAT_MAC_LEN            6
+
+
+#define IOCTL_IBAT( n )        \
+   CTL_CODE( FILE_DEVICE_UNKNOWN, (0x800 + n), \
+       METHOD_BUFFERED, FILE_READ_ACCESS )
+
+/** This IRP is used to return all available CAs ports number
+ * and port guid */
+#define    IOCTL_IBAT_PORTS    IOCTL_IBAT( 1 )
+
+typedef struct _IBAT_PORT_RECORD
+{
+   UINT64              CaGuid;
+   UINT64              PortGuid;
+} IBAT_PORT_RECORD;
+
+typedef struct _IOCTL_IBAT_PORTS_IN
+{
+   ULONG               Version;
+
+} IOCTL_IBAT_PORTS_IN;
+
+typedef struct _IOCTL_IBAT_PORTS_OUT
+{
+   /** Total size, of the output buffer needed if the
+    * suplied buffer wasn't enough */
+   ULONG               Size;
+   LONG                NumPorts;
+   IBAT_PORT_RECORD    Ports[1];
+
+} IOCTL_IBAT_PORTS_OUT;
+
+
+/** This IRP is used to return all the ip addresses that
+ * are assigned to a port */
+#define    IOCTL_IBAT_IP_ADDRESSES     IOCTL_IBAT( 2 )
+
+typedef struct _IOCTL_IBAT_IP_ADDRESSES_IN
+{
+   ULONG               Version;
+   /** The guid of the port that we are querying for.  May be
+    * zero if querying for IP addresses of all ports. */
+   UINT64              PortGuid;
+
+} IOCTL_IBAT_IP_ADDRESSES_IN;
+
+typedef struct _IP_ADDRESS
+{
+   /** Might only be 4 or 6 */
+   CHAR                IpVersion;
+   /** Sized to support both IPv4 and IPv6 */
+   UCHAR               Address[16];
+
+} IP_ADDRESS;
+
+typedef struct _IOCTL_IBAT_IP_ADDRESSES_OUT
+{
+   /** Total size of the output buffer needed if the
+    * suplied buffer wasn't enough */
+   ULONG               Size;
+   LONG                AddressCount;
+   IP_ADDRESS          Address[1];
+
+} IOCTL_IBAT_IP_ADDRESSES_OUT;
+
+
+/** This IRP is used to convert a remote MAC addresses to a remote GID */
+#define    IOCTL_IBAT_MAC_TO_GID IOCTL_IBAT( 3 )
+
+typedef struct _IOCTL_IBAT_MAC_TO_GID_IN
+{
+   ULONG               Version;
+   UINT64              PortGuid;
+   UCHAR               DestMac[IBAT_MAC_LEN];
+
+} IOCTL_IBAT_MAC_TO_GID_IN;
+
+typedef struct _IOCTL_IBAT_MAC_TO_GID_OUT
+{
+   ib_gid_t            DestGid;
+
+} IOCTL_IBAT_MAC_TO_GID_OUT;
+
+
+#define    IBAT_DEV_NAME   L"\\Device\\ibat"
+#define    IBAT_DOS_DEV_NAME L"\\DosDevices\\Global\\ibat"
+#define    IBAT_WIN32_NAME L"\\\\.\\ibat"
+
+#endif /* _IB_AT_IOCTL_H_ */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ibat.patch
Type: application/octet-stream
Size: 27399 bytes
Desc: not available
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20051202/a6b2a4e6/attachment.obj>


More information about the ofw mailing list