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

Tzachi Dar tzachid at mellanox.co.il
Mon Dec 5 13:59:03 PST 2005


Hi Fab, 

I have looked at the code that you have sent and things look great.

Thanks for the good job. 

Please check-in the patch. (Please also check-in the test program).

Thanks again
Tzachi

>-----Original Message-----
>From: Fab Tillier [mailto:ftillier at silverstorm.com] 
>Sent: Saturday, December 03, 2005 3:14 AM
>To: Tzachi Dar; openib-windows at openib.org
>Cc: Gilad Shainer
>Subject: RE: [Openib-windows] RE: Anything new about the IPOIB 
>arp check-in?
>
>
>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_ */
>



More information about the ofw mailing list