[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