[Openib-windows] RE: Anything new about the IPOIB arp check-in?
Fab Tillier
ftillier at silverstorm.com
Wed Nov 30 22:50:10 PST 2005
Here's the code for getting the local port GUIDs and assigned IP addresses.
It's changed slightly from what you had in that it will return partial results
if the output buffer isn't large enough. I've also eliminated the copy of the
input parameters as most of the cases didn't require it. Other than that, the
functionality is as you had it though the code is restructured somewhat.
Let me know if you see any issues or not. I should be able to have the other
two IOCTLs implemented tomorrow, and will test and hopefully get a patch out for
review by the end of the week before committing.
Thanks!
- Fab
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 += 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(IB_ADDRESS) );
cl_memcpy( &pOut->Address[pOut->AddressCount].Address[12],
pAddr->address, IPV4_ADDR_SIZE );
pOut->AddressCount++;
}
cl_obj_lock( &pAdapter->obj );
}
pOut->Size = sizeof(IOCTL_IBAT_IP_ADDRESSES_OUT);
if( --nIps )
pOut->Size += sizeof(IP_ADDRESS) * nIps;
KeReleaseInStackQueuedSpinLock( &hdl );
return STATUS_SUCCESS;
}
More information about the ofw
mailing list