[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