[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