From c7f8be49194eea50d21cbc0419422b7c8aa6cfd9 Mon Sep 17 00:00:00 2001 From: tzachid Date: Wed, 25 Jan 2006 08:54:42 +0000 Subject: [PATCH] git-svn-id: svn://openib.tc.cornell.edu/gen1@215 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- trunk/ulp/sdp/dirs | 4 - trunk/ulp/sdp/include/RefCount.h | 67 - trunk/ulp/sdp/include/SdpShared.h | 157 -- trunk/ulp/sdp/kernel/Precompile.h | 60 - trunk/ulp/sdp/kernel/SOURCES | 52 - trunk/ulp/sdp/kernel/SdpArp.cpp | 477 ---- trunk/ulp/sdp/kernel/SdpArp.h | 115 - trunk/ulp/sdp/kernel/SdpBufferPool.cpp | 738 ------ trunk/ulp/sdp/kernel/SdpBufferPool.h | 333 --- trunk/ulp/sdp/kernel/SdpConnectionList.cpp | 218 -- trunk/ulp/sdp/kernel/SdpConnectionList.h | 80 - trunk/ulp/sdp/kernel/SdpDriver.cpp | 831 ------ trunk/ulp/sdp/kernel/SdpDriver.h | 121 - trunk/ulp/sdp/kernel/SdpGenUtils.cpp | 264 -- trunk/ulp/sdp/kernel/SdpGenUtils.h | 183 -- trunk/ulp/sdp/kernel/SdpLock.h | 351 --- trunk/ulp/sdp/kernel/SdpMsgs.h | 228 -- trunk/ulp/sdp/kernel/SdpRecvPool.cpp | 488 ---- trunk/ulp/sdp/kernel/SdpRecvPool.h | 135 - trunk/ulp/sdp/kernel/SdpSocket.cpp | 2730 -------------------- trunk/ulp/sdp/kernel/SdpSocket.h | 311 --- trunk/ulp/sdp/kernel/SdpTrace.cpp | 110 - trunk/ulp/sdp/kernel/SdpTrace.h | 96 - trunk/ulp/sdp/kernel/SdpUserFile.cpp | 269 -- trunk/ulp/sdp/kernel/SdpUserFile.h | 79 - trunk/ulp/sdp/kernel/makefile | 7 - trunk/ulp/sdp/kernel/sdp.rc | 47 - trunk/ulp/sdp/tests/basic/BasicConnect.cpp | 492 ---- trunk/ulp/sdp/tests/basic/SdpConnect.cpp | 585 ----- trunk/ulp/sdp/tests/basic/makefile | 7 - trunk/ulp/sdp/tests/basic/sources | 91 - trunk/ulp/sdp/tests/dirs | 3 - trunk/ulp/sdp/todo | 53 - 33 files changed, 9782 deletions(-) delete mode 100644 trunk/ulp/sdp/dirs delete mode 100644 trunk/ulp/sdp/include/RefCount.h delete mode 100644 trunk/ulp/sdp/include/SdpShared.h delete mode 100644 trunk/ulp/sdp/kernel/Precompile.h delete mode 100644 trunk/ulp/sdp/kernel/SOURCES delete mode 100644 trunk/ulp/sdp/kernel/SdpArp.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpArp.h delete mode 100644 trunk/ulp/sdp/kernel/SdpBufferPool.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpBufferPool.h delete mode 100644 trunk/ulp/sdp/kernel/SdpConnectionList.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpConnectionList.h delete mode 100644 trunk/ulp/sdp/kernel/SdpDriver.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpDriver.h delete mode 100644 trunk/ulp/sdp/kernel/SdpGenUtils.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpGenUtils.h delete mode 100644 trunk/ulp/sdp/kernel/SdpLock.h delete mode 100644 trunk/ulp/sdp/kernel/SdpMsgs.h delete mode 100644 trunk/ulp/sdp/kernel/SdpRecvPool.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpRecvPool.h delete mode 100644 trunk/ulp/sdp/kernel/SdpSocket.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpSocket.h delete mode 100644 trunk/ulp/sdp/kernel/SdpTrace.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpTrace.h delete mode 100644 trunk/ulp/sdp/kernel/SdpUserFile.cpp delete mode 100644 trunk/ulp/sdp/kernel/SdpUserFile.h delete mode 100644 trunk/ulp/sdp/kernel/makefile delete mode 100644 trunk/ulp/sdp/kernel/sdp.rc delete mode 100644 trunk/ulp/sdp/tests/basic/BasicConnect.cpp delete mode 100644 trunk/ulp/sdp/tests/basic/SdpConnect.cpp delete mode 100644 trunk/ulp/sdp/tests/basic/makefile delete mode 100644 trunk/ulp/sdp/tests/basic/sources delete mode 100644 trunk/ulp/sdp/tests/dirs delete mode 100644 trunk/ulp/sdp/todo diff --git a/trunk/ulp/sdp/dirs b/trunk/ulp/sdp/dirs deleted file mode 100644 index 68ee2bdb..00000000 --- a/trunk/ulp/sdp/dirs +++ /dev/null @@ -1,4 +0,0 @@ -dirs = \ -kernel \ -tests \ - diff --git a/trunk/ulp/sdp/include/RefCount.h b/trunk/ulp/sdp/include/RefCount.h deleted file mode 100644 index 76c4e68f..00000000 --- a/trunk/ulp/sdp/include/RefCount.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -/* - This file includes two classes: One is used as a full refcount implmentation. - - The second class is only the ref count interface. It should be used by abstract - classes. - -*/ - - -class RefCountImpl { -public : - - RefCountImpl() { - m_ref = 1; - } - - ULONG AddRef(void) { - ASSERT(m_ref > 0); - LONG result = InterlockedIncrement(&m_ref); - return (ULONG)result; - } - - ULONG Release(void) { - ASSERT(m_ref > 0); - LONG result = InterlockedDecrement(&m_ref); - if ( result == 0 ) { - delete this; - } - return (ULONG)result; - } - - virtual ~RefCountImpl() {}; -private : - long m_ref; -}; diff --git a/trunk/ulp/sdp/include/SdpShared.h b/trunk/ulp/sdp/include/SdpShared.h deleted file mode 100644 index 317ddef5..00000000 --- a/trunk/ulp/sdp/include/SdpShared.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef _SDP_SHARED_H -#define _SDP_SHARED_H - -#define ProviderName L"SdpDriver" - -#define SDP_DEVICE_NAME L"\\Device\\"ProviderName -#define SDP_LINK_NAME L"\\DosDevices\\Global\\"ProviderName -#define SDP_WIN32_NAME L"\\\\.\\"ProviderName - -// Define the IOCTL codes that will be used for sending the requests down - -#define IOCTL_WSP_SOCKET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_CONNECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_SEND CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_RECV CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_BIND CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_LISTEN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_ACCEPT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_GET_XXX_NAME CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_CLOSE_SOCKET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_USER_THREAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_BUFFERED ,FILE_ANY_ACCESS) - - -// Data structures that are used for connect -struct WspSocketIn { - ULONG dwFlags; -}; - -struct WspSocketOut { - int Errno; - VOID *pSocket; -}; - -const int MAC_ADDR_SIZE = 6; -typedef char MAC_ADDR[MAC_ADDR_SIZE] ; - -struct WspConnectIn { - VOID *pSocket; - ULONG SrcIP; - MAC_ADDR DestMac; - ULONG DestIP; - USHORT DestPort; -}; - -struct WspConnectOut { - int Errno; -}; - -struct WspSendIn { - VOID *pSocket; - CHAR *pData; - ULONG BufferSize; - ULONG dwFlags; -}; - -struct WspSendOut { - ULONG NumberOfBytesSent; - int Errno; -}; - -struct WspRecvIn { - VOID *pSocket; - CHAR *pData; - ULONG BufferSize; - ULONG dwFlags; -}; - -struct WspRecvOut { - ULONG NumberOfBytesRecieved; - int Errno; - ULONG dwFlags; -}; - -struct WspBindIn { - VOID *pSocket; - ULONG IP; - USHORT Port; -}; - -struct WspBindOut { - int Errno; -}; - -struct WspListenIn { - VOID *pSocket; - int backlog; -}; - -struct WspListenOut { - int Errno; -}; - -struct WspAcceptIn { - VOID *pSocket; -}; - -struct WspAcceptOut { - int Errno; - VOID *pAccaptedSocket; - ULONG IP; - USHORT Port; -}; - -struct WspGetSockXXIn { - VOID *pSocket; - bool LocaleAddress; // Tells if this is used as GetSockName or GetPeerName -}; - -struct WspGetSockXXOut { - int Errno; - ULONG IP; - USHORT Port; -}; - -struct WspSocketCloseIn { - VOID *pSocket; -}; - -struct WspSocketCloseOut { - int Errno; -}; - - - -#endif //_SDP_SHARED_H diff --git a/trunk/ulp/sdp/kernel/Precompile.h b/trunk/ulp/sdp/kernel/Precompile.h deleted file mode 100644 index f4d07077..00000000 --- a/trunk/ulp/sdp/kernel/Precompile.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef _SDP_PRECOMP_ -#define _SDP_PRECOMP_ -extern "C" { -#include -} - -// External classes declrations -class SdpSocket; -class SdpArp; - -#include "ib_al.h" -#include "..\..\..\inc\iba\ib_at_ioctl.h" -#include "sdpMsgs.h" -#include "SdpGenUtils.h" -#include "SdpTrace.h" -#include "sdpLock.h" -#include "RefCount.h" -#include "SdpBufferPool.h" -#include "SdpUserFile.h" -#include "sdpdriver.h" -#include "SdpShared.h" -#include "SdpRecvPool.h" -#include "SdpConnectionList.h" -#include "SdpSocket.h" -#include "SdpArp.h" - - -#endif // _SDP_PRECOMP_ diff --git a/trunk/ulp/sdp/kernel/SOURCES b/trunk/ulp/sdp/kernel/SOURCES deleted file mode 100644 index 59cceaf0..00000000 --- a/trunk/ulp/sdp/kernel/SOURCES +++ /dev/null @@ -1,52 +0,0 @@ -TARGETNAME=Sdp -TARGETPATH=..\..\..\bin\kernel\obj$(BUILD_ALT_DIR) -TARGETTYPE=DRIVER - -ENABLE_EVENT_TRACING=1 - -SOURCES= Sdp.rc \ - SdpDriver.cpp \ - SdpUserFile.cpp \ - SdpGenUtils.cpp \ - SdpSocket.cpp \ - SdpArp.cpp \ - SdpBufferPool.cpp \ - SdpRecvPool.cpp \ - SdpConnectionList.cpp \ - SdpTrace.cpp - - -INCLUDES=..\include;\ - ..\..\..\inc;\ - ..\..\..\inc\kernel;\ - ..\..\..\inc\iba - -C_DEFINES=$(C_DEFINES) -DNDIS_WDM=1 \ - -DDEPRECATE_DDK_FUNCTIONS - -TARGETLIBS= \ - $(TARGETPATH)\*\complib.lib \ - $(TARGETPATH)\*\ibal.lib \ - -!if !defined(DDK_TARGET_OS) || "$(DDK_TARGET_OS)"=="Win2K" -# -# The driver is built in the Win2K build environment -# - use the library version of safe strings -# -TARGETLIBS= $(TARGETLIBS) $(DDK_LIB_PATH)\ntstrsafe.lib -!endif - -!IFDEF ENABLE_EVENT_TRACING - -C_DEFINES = $(C_DEFINES) -DEVENT_TRACING - -RUN_WPP= $(SOURCES) -km -dll -ext: .c .cpp .h .C .CPP .H\ - -preserveext:.cpp .h\ - -func:SDP_PRINT(LEVEL,FLAGS,MSG,...) -!ENDIF - -MSC_WARNING_LEVEL= /W3 - -PRECOMPILED_INCLUDE=Precompile.h -PRECOMPILED_PCH=Precompile.pch -PRECOMPILED_CXX=1 diff --git a/trunk/ulp/sdp/kernel/SdpArp.cpp b/trunk/ulp/sdp/kernel/SdpArp.cpp deleted file mode 100644 index 87ab2288..00000000 --- a/trunk/ulp/sdp/kernel/SdpArp.cpp +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "precompile.h" - -#pragma warning(disable: 4244 ) - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpArp.tmh" -#endif - - - -NTSTATUS -SdpArp::Init(PDRIVER_OBJECT DriverObject) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"Entering"); - - NTSTATUS rc = STATUS_SUCCESS; - UNICODE_STRING DevName1; - IO_STATUS_BLOCK ioStatus; - m_DeviceObject = NULL; - - OBJECT_ATTRIBUTES objectAttributes; - - RtlInitUnicodeString( &DevName1, IBAT_DEV_NAME ); - - InitializeObjectAttributes( &objectAttributes, - &DevName1, - OBJ_KERNEL_HANDLE, - (HANDLE) NULL, - (PSECURITY_DESCRIPTOR) NULL ); - - // Try to open the IPOIB device object - // - // The reason for using ZwOpenFile instead of IoGetDeviceObjectPointer - // is to keep the handle around because the NDISPROT makes an assumption - // that there is no I/O requests between Cleanup and Close requests. - // - rc = ZwOpenFile( &m_FileHandle, - STANDARD_RIGHTS_ALL, - &objectAttributes, - &ioStatus, - 0, - FILE_NON_DIRECTORY_FILE ); - if (!NT_SUCCESS( rc )) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"ZwOpenFile failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - // - // obtain a pointer to the device object for the handle. - // - rc = ObReferenceObjectByHandle(m_FileHandle, - THREAD_ALL_ACCESS, - *IoFileObjectType, - KernelMode, - (PVOID *) &m_FileObject, - NULL ); - if (!NT_SUCCESS( rc )) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"ObReferenceObjectByHandle failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - // This is what we are looking for - m_DeviceObject = IoGetRelatedDeviceObject(m_FileObject); - -Cleanup: - if (!NT_SUCCESS( rc )) { - if (m_FileHandle) { - ZwClose(m_FileHandle); - m_FileHandle = NULL; - } - if (m_FileObject) { - ObDereferenceObject(m_FileObject); - m_FileObject = NULL; - } - } - return rc; - -} - -VOID -SdpArp::Shutdown() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = %p\n", this); - if (m_FileHandle) { - ZwClose(m_FileHandle); - m_FileHandle = NULL; - } - if (m_FileObject) { - ObDereferenceObject(m_FileObject); - m_FileObject = NULL; - } - m_DeviceObject = NULL; // Not valid any more -} - - -NTSTATUS -SdpArp::SourcePortGidFromIP( - IN ULONG SourceAddr, - OUT ib_net64_t *SrcPortGuid, - OUT ib_net64_t *SrcCaGuid - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "IP = %d.%d.%d.%d\n", - (SourceAddr & 0xff000000) >> 24, - (SourceAddr & 0xff0000) >> 16, - (SourceAddr & 0xff00) >> 8 , - SourceAddr & 0xff); - NTSTATUS rc = STATUS_SUCCESS; - KEVENT event; - PIRP irp; - IO_STATUS_BLOCK ioStatus; - char temp [1000]; // BUGBUG: Handle the case of more IPs - - IOCTL_IBAT_PORTS_IN ipoib_ports_in; - IOCTL_IBAT_PORTS_OUT *pipoib_ports_out; - IBAT_PORT_RECORD *ports_records; - - ipoib_ports_in.Version = IBAT_IOCTL_VERSION; - - pipoib_ports_out = (IOCTL_IBAT_PORTS_OUT *)temp; - - ASSERT(m_DeviceObject != NULL); - - KeInitializeEvent(&event, NotificationEvent, FALSE); - irp = IoBuildDeviceIoControlRequest( - IOCTL_IBAT_PORTS , - m_DeviceObject, - &ipoib_ports_in, - sizeof ipoib_ports_in, - pipoib_ports_out, - sizeof temp, - TRUE, - &event, - &ioStatus - ); - - if(NULL == irp) { - rc = STATUS_INSUFFICIENT_RESOURCES; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoBuildDeviceIoControlRequest failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - rc = IoCallDriver(m_DeviceObject, irp); - if(STATUS_PENDING == rc) { - KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); - } - else { - ioStatus.Status = rc; - } - - if(!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoCallDriver failed rc = 0x%x\n", rc ); - goto Cleanup; - } - if (pipoib_ports_out->Size > sizeof temp) { - // The number of bytes that we have allocated wasn't enough - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"pipoib_ports_out.Size = %d\n", pipoib_ports_out->Size ); - rc = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - // BUGBUG: We should try again, with a bigger buffer - } - - rc = SourcePortGidFromPorts(SourceAddr, pipoib_ports_out, SrcPortGuid, SrcCaGuid); - if(!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"SourcePortGidFromPorts failed rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - return rc; -} - -NTSTATUS -SdpArp::SourcePortGidFromPorts( - IN ULONG SourceAddr, - IN IOCTL_IBAT_PORTS_OUT *pPorts, - OUT ib_net64_t *SrcPortGuid, - OUT ib_net64_t *SrcCaGuid - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"Entered\n"); - NTSTATUS rc = STATUS_SUCCESS; - KEVENT event; - PIRP irp; - IO_STATUS_BLOCK ioStatus; - - int i = 0, j = 0; - - IOCTL_IBAT_IP_ADDRESSES_IN addresses_in; - IOCTL_IBAT_IP_ADDRESSES_OUT *addresses_out; - char temp[1000]; - addresses_out = (IOCTL_IBAT_IP_ADDRESSES_OUT *)temp; - - addresses_in.Version = IBAT_IOCTL_VERSION; - - for (i = 0 ; i < pPorts->NumPorts; i++) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "%d: ca guid = 0x%I64x port guid=0x%I64x\n", - i, CL_NTOH64(pPorts->Ports[i].CaGuid), CL_NTOH64(pPorts->Ports[i].PortGuid)); - - // Do a quary to find out if this is the correct port - ASSERT(m_DeviceObject != NULL); - - addresses_in.PortGuid = pPorts->Ports[i].PortGuid; - - KeInitializeEvent(&event, NotificationEvent, FALSE); - irp = IoBuildDeviceIoControlRequest( - IOCTL_IBAT_IP_ADDRESSES , - m_DeviceObject, - &addresses_in, - sizeof addresses_in, - addresses_out, - sizeof temp, - TRUE, - &event, - &ioStatus - ); - - if(NULL == irp) { - rc = STATUS_INSUFFICIENT_RESOURCES; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoBuildDeviceIoControlRequest failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - rc = IoCallDriver(m_DeviceObject, irp); - if(STATUS_PENDING == rc) { - KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); - } - else { - ioStatus.Status = rc; - } - - if(!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoCallDriver failed rc = 0x%x\n", rc ); - goto Cleanup; - } - if (addresses_out->Size > sizeof temp) { - // The number of bytes that we have allocated wasn't enough - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"addresses_out.Size = %d\n", addresses_out->Size ); - rc = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - // BUGBUG: We should try again, with a bigger buffer - } - - - // We now have the addreses, we can check if this is what we need - for (j = 0 ; j < addresses_out->AddressCount; j++) { - ULONG *pIp; - ASSERT(addresses_out->Address[j].IpVersion == 4); - pIp = (ULONG *) (&addresses_out->Address[j].Address[12]); - if (*pIp == CL_NTOH32(SourceAddr)) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_ARP, - "Found the IP: ca guid = 0x%I64x port guid=0x%I64x\n", - CL_NTOH64(pPorts->Ports[i].CaGuid), CL_NTOH64(pPorts->Ports[i].PortGuid)); - ASSERT(rc == STATUS_SUCCESS); - *SrcPortGuid = pPorts->Ports[i].PortGuid; - *SrcCaGuid = pPorts->Ports[i].CaGuid; - goto Cleanup; - } - - } - - } - // If we have reached here the data was not found - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_ARP, - "HCA not found for ip=%d.%d.%d.%d\n", - (SourceAddr & 0xff000000) >> 24, - (SourceAddr & 0xff0000) >> 16, - (SourceAddr & 0xff00) >> 8 , - SourceAddr & 0xff - ); - rc = STATUS_NOT_FOUND; - -Cleanup: - return rc; - -} - - -NTSTATUS -SdpArp::DestPortGidFromMac( - IN ib_net64_t SrcPortGuid, - IN MAC_ADDR DestMac, - OUT ib_gid_t *pDestPortGid) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"MAC = ????\n"); - NTSTATUS rc = STATUS_SUCCESS; - - KEVENT event; - PIRP irp; - IO_STATUS_BLOCK ioStatus; - - IOCTL_IBAT_MAC_TO_GID_IN ipoib_mac2gid_in; - IOCTL_IBAT_MAC_TO_GID_OUT ipoib_mac2gid_out; - - C_ASSERT(MAC_ADDR_SIZE == sizeof (ipoib_mac2gid_in.DestMac)); - ipoib_mac2gid_in.Version = IBAT_IOCTL_VERSION; - ipoib_mac2gid_in.PortGuid = SrcPortGuid; - memcpy(ipoib_mac2gid_in.DestMac, DestMac, MAC_ADDR_SIZE); - - - - ASSERT(m_DeviceObject != NULL); - - KeInitializeEvent(&event, NotificationEvent, FALSE); - irp = IoBuildDeviceIoControlRequest( - IOCTL_IBAT_MAC_TO_GID , - m_DeviceObject, - &ipoib_mac2gid_in, - sizeof ipoib_mac2gid_in, - &ipoib_mac2gid_out, - sizeof ipoib_mac2gid_out, - TRUE, - &event, - &ioStatus - ); - - if(NULL == irp) { - rc = STATUS_INSUFFICIENT_RESOURCES; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoBuildDeviceIoControlRequest failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - rc = IoCallDriver(m_DeviceObject, irp); - if(STATUS_PENDING == rc) { - KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); - } - else { - ioStatus.Status = rc; - } - - if(!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"IoCallDriver failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - *pDestPortGid = ipoib_mac2gid_out.DestGid; -Cleanup: - return rc; -} - -NTSTATUS -SdpArp::QueryPathRecord( - IN ib_net64_t SrcPortGuid, - IN ib_gid_t DestPortGid, - OUT ib_path_rec_t *path_rec ) -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_gid_pair_t user_query; - struct query_pr_context query_context; - ib_query_handle_t query_handle; - ib_query_req_t query_req; - ib_api_status_t ib_status; - - query_req.query_type = IB_QUERY_PATH_REC_BY_GIDS; - query_req.p_query_input = &user_query; - query_req.port_guid = SrcPortGuid; - query_req.timeout_ms = 500; - query_req.retry_cnt = 4; - query_req.flags = IB_FLAGS_SYNC; - query_req.query_context = &query_context; - query_req.pfn_query_cb = SdpArp::query_pr_callback; - - ib_gid_set_default( &user_query.src_gid, SrcPortGuid ); - - user_query.dest_gid = DestPortGid; - - query_context.path_rec = path_rec; - - SDP_PRINT( TRACE_LEVEL_INFORMATION, SDP_ARP, "Query for path from %I64x to %I64x\n", - SrcPortGuid, DestPortGid.unicast.interface_id); - - ib_status = ib_query( g_pSdpDriver->m_al_handle, &query_req, &query_handle ); - - if ( ib_status != IB_SUCCESS) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"ib_query failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - if( query_context.status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_ARP,"query_context.status failed ib_status = 0x%d\n", query_context.status ); - rc = IB2Status(query_context.status); - goto Cleanup; - } - -// BUGBUG: This code was in the orginanl function. We have to decide -// if we want to keep it. -#if 0 - if( (port->hca->dev_id == 0x5A44) && - (ib_path_rec_mtu( path_rec ) > IB_MTU_1024) ) - { - /* Local endpoint is Tavor - cap MTU to 1K for extra bandwidth. */ - path_rec->mtu &= IB_PATH_REC_SELECTOR_MASK; - path_rec->mtu |= IB_MTU_1024; - } -#endif - -Cleanup: - return rc; -} - -void AL_API -SdpArp::query_pr_callback( - IN ib_query_rec_t *p_query_rec) -{ - query_pr_context * __ptr64 query_context = - (query_pr_context * __ptr64)p_query_rec->query_context; - - - ib_api_status_t status; - - SDP_PRINT( TRACE_LEVEL_INFORMATION, SDP_ARP,"query_pr_callback status is %d irql=%d\n", p_query_rec->status, KeGetCurrentIrql()); - - query_context->status = p_query_rec->status; - - if( p_query_rec->status == IB_SUCCESS ){ - ib_path_rec_t *path_rec; - - path_rec = ib_get_query_path_rec(p_query_rec->p_result_mad, 0 ); - - ASSERT( path_rec ); - - /* Copy the path record */ - *query_context->path_rec = *path_rec; - } - - if( p_query_rec->status == IB_SUCCESS || p_query_rec->status == IB_REMOTE_ERROR ) - { - status = ib_put_mad( p_query_rec->p_result_mad ); - - ASSERT(status == IB_SUCCESS); - if( status != IB_SUCCESS ) - { - SDP_PRINT( TRACE_LEVEL_ERROR, SDP_ARP,"ib_put_mad failed "); - } - } else { - // When do we free this mad ??? - ASSERT(p_query_rec->p_result_mad == NULL); - } - -} - diff --git a/trunk/ulp/sdp/kernel/SdpArp.h b/trunk/ulp/sdp/kernel/SdpArp.h deleted file mode 100644 index ec7e0b2f..00000000 --- a/trunk/ulp/sdp/kernel/SdpArp.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -class SdpArp { - /* - Look at the routing table of the machine and see which port - to use for outbound traffic - */ - -public: - - SdpArp() { - m_DeviceObject = NULL; - m_FileObject = NULL; - m_FileHandle = NULL; - - } - - struct query_pr_context - { - ib_api_status_t status; - ib_path_rec_t *path_rec; - }; - - NTSTATUS Init(PDRIVER_OBJECT DriverObject); - - VOID Shutdown(); - - NTSTATUS GetPort( - IN ULONG SourceAddr, - OUT USHORT *SrcPort - ) - { - // If the port is 0, choose your own free port. - // If the port is not 0 check if this port is already in use - *SrcPort = 5050; // BUGBUG: Complete this mechanism - return STATUS_SUCCESS; - - } - - NTSTATUS SourcePortGidFromIP( - IN ULONG SourceAddr, - OUT ib_net64_t *SrcPortGuid, - OUT ib_net64_t *SrcCaGuid - ); - NTSTATUS DestPortGidFromMac( - IN ib_net64_t SrcPortGuid, - IN MAC_ADDR DestMac, - OUT ib_gid_t *pDestPortGid); - -/* -Synchronously query the SA for a GUID. (started from wsd - query_pr) -*/ -/* - * Get a path record from a GUID - */ - - NTSTATUS - QueryPathRecord( - IN ib_net64_t SrcPortGuid, - IN ib_gid_t DestPortGid, - OUT ib_path_rec_t *path_rec - ); - - static void AL_API - query_pr_callback( - IN ib_query_rec_t *p_query_rec); - - private : - PDEVICE_OBJECT m_DeviceObject; - PFILE_OBJECT m_FileObject; - HANDLE m_FileHandle; - - - - NTSTATUS - SourcePortGidFromPorts( - IN ULONG SourceAddr, - IN IOCTL_IBAT_PORTS_OUT *pPorts, - OUT ib_net64_t *SrcPortGuid, - OUT ib_net64_t *SrcCaGuid - ); - - -}; - diff --git a/trunk/ulp/sdp/kernel/SdpBufferPool.cpp b/trunk/ulp/sdp/kernel/SdpBufferPool.cpp deleted file mode 100644 index b554f1cc..00000000 --- a/trunk/ulp/sdp/kernel/SdpBufferPool.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - - -#include "preCompile.h" - -#pragma warning(disable: 4244 ) - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpBufferPool.tmh" -#endif - - - - -//static -NTSTATUS -BufferDescriptor::AllocateBuffer(BufferDescriptor ** ppBufferDescriptor, int BufferSize, int Tag) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"\n"); - NTSTATUS rc = STATUS_SUCCESS; - BufferDescriptor *pBufferDescriptor = NULL; - - // Allocate the buffer descriptor - pBufferDescriptor = - (BufferDescriptor *) - ExAllocatePoolWithTag( - NonPagedPool , - sizeof BufferDescriptor, - Tag - ); - - if (pBufferDescriptor == NULL) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"ExAllocatePoolWithTag failed \n"); - rc = STATUS_NO_MEMORY; - goto Cleanup; - } - - // Allocate the buffer itself (from continious memory) - PHYSICAL_ADDRESS mem; - mem.HighPart = 0xffffffff; - mem.LowPart = 0xffffffff; - pBufferDescriptor->pBuffer = MmAllocateContiguousMemory(BufferSize, mem); - - if (pBufferDescriptor->pBuffer == NULL) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"ExAllocatePoolWithTag failed BufferSize = %d irql=%d\n",BufferSize, KeGetCurrentIrql()); - rc = STATUS_NO_MEMORY; - goto Cleanup; - } - - pBufferDescriptor->BufferSize = BufferSize; - pBufferDescriptor->Reset(); - -Cleanup: - if (!NT_SUCCESS(rc)) { - if (pBufferDescriptor != NULL) { - if (pBufferDescriptor->pBuffer != NULL) { - MmFreeContiguousMemory(pBufferDescriptor->pBuffer); - } - ExFreePoolWithTag(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); - pBufferDescriptor = NULL; - } - } - *ppBufferDescriptor = pBufferDescriptor; - return rc; - -} - -//static -VOID -BufferDescriptor::DeAllocateBuffer(BufferDescriptor *pBufferDescriptor, int Tag) -{ - MmFreeContiguousMemory(pBufferDescriptor->pBuffer); - ExFreePoolWithTag(pBufferDescriptor, Tag); - -} - -/* - Currently the implmentation of shutdown should allow it to work, even without - init being called -*/ -BufferPool::BufferPool() -{ - m_SendSeq = 0; - m_AdvtSeq = 0; - m_CurrentlySentBuffers = 0; - m_CurrentlyAllocated = 0; - m_PostCreditsWhenCan = false; - m_CreditsCurrentlyPosted = false; - m_CreditdBufferDescriptor = NULL; - m_pSdpSocket = NULL; - - - m_NumberOfBytesSent = 0; - m_NumberOfBytesSentAndAcked = 0; - -} - -NTSTATUS -BufferPool::Init( - int MaxBuffers, - int MaxConcurrentSends, - int MaxMessageSize, - ib_pd_handle_t pd, - ib_qp_handle_t qp, - net32_t lkey, - SdpSocket *pSdpSocket - - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"this = 0x%p \n",this); - m_MaxBuffers = MaxBuffers; - m_MaxConcurrentSends = MaxConcurrentSends; - m_MaxMessageSize = MaxMessageSize; - ASSERT(pd != NULL); - m_pd = pd; - ASSERT(qp != NULL); - m_qp = qp; - ASSERT(lkey != NULL); - m_lkey = lkey; - m_pSdpSocket = pSdpSocket; - m_CallBackPending = false; - - - - return STATUS_SUCCESS; -} - -/* - This function is being called by a thread that wants to do a send in order - to have a buffer that he can copy the data to. - FirstBuffer tells if this is the first buffer that he wants. - If it is true, this means that no other request will be handled before - this client will indicate that he has finished queing his data. - If an event is returned this means that the caller has to wait on the - event before the request will be staisfied. - - This function is being called under a lock - -*/ -NTSTATUS -BufferPool::GetBuffer( - BufferDescriptor **ppBufferDescriptor - ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p \n",this); - AssertLocked(); - - NTSTATUS rc = STATUS_SUCCESS; - *ppBufferDescriptor = NULL; - - if (m_FreePackets.Size() > 0) { - LIST_ENTRY *item = m_FreePackets.RemoveHeadList(); - *ppBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - goto Cleanup; - } else if (m_CurrentlyAllocated < m_MaxBuffers) { - // we need to alocate a new buffer - rc = BufferDescriptor::AllocateBuffer(ppBufferDescriptor, m_MaxMessageSize, SEND_BUFFERS_ALLOCATION_TAG); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL, "AllocateBuffer failed rc = 0x%x\n", rc ); - ASSERT(*ppBufferDescriptor == NULL); - goto Cleanup; - } - m_CurrentlyAllocated++; - goto Cleanup; - } - // No buffers available, we return NULL - ASSERT(*ppBufferDescriptor == NULL); - -Cleanup: - return rc; -} - -/* -Send the buffers if possibale, if not possibale ,adds them to the -queue -*/ - -NTSTATUS -BufferPool::AddBufferToQueuedList(BufferDescriptor *pBufferDescriptor) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p pBufferDescriptor = 0x%p\n",this, - pBufferDescriptor); - AssertLocked(); - - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(pBufferDescriptor->GetFlags() == 0 || - pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE); - - // Assert that we are not sending an empty buffer - if (pBufferDescriptor->DataSize == 0) { - msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *) pBufferDescriptor->pBuffer; - ASSERT(pHeader->mid == SDP_MID_DISCONNECT ); - } - - m_QueuedPackets.InsertTailList(&pBufferDescriptor->BuffersList); - rc = SendBuffersIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"SendBuffersIfCan failed rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - return rc; - -} - -/* - called when a send packet has finished. -*/ - -NTSTATUS -BufferPool::ReturnBuffer(BufferDescriptor *pBufferDescriptor) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p buffer=0x%p\n",this, pBufferDescriptor); - AssertLocked(); - bool CreditUpdate = false; - bool DissconnectMessage = false; - NTSTATUS rc = STATUS_SUCCESS; - -#if DBG - if (m_CurrentlySentBuffers == 1) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_PERFORMANCE, "Currently no packets are bing sent \n"); - } -#endif - ASSERT( pBufferDescriptor->GetFlags() == CREDIT_UPDATE || - pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE || - pBufferDescriptor->GetFlags() == 0); - - CreditUpdate = (pBufferDescriptor->GetFlags() == CREDIT_UPDATE); - DissconnectMessage = (pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE); - if (CreditUpdate) { - // This is a credit update packet, need to act accordingly - ASSERT(m_CreditdBufferDescriptor == NULL); - ASSERT(m_CreditsCurrentlyPosted == true); - m_CreditdBufferDescriptor = pBufferDescriptor; - m_CreditsCurrentlyPosted = false; - - if (m_PostCreditsWhenCan == true) { - m_PostCreditsWhenCan = false; - rc = PostCredits(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"PostCredits failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - } else { - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - // We have to ask for another thread to do the job, as - // we might be in a DPC context - - // Ask for a new callback only in the following conditions: - // 1) There is no request on the way AND - // 2) There is a buffer that can be used AND - // 3) We have enough free space to complete a packet - // 4) We have gone under some threshold -// TODO: 4 above, didn't seem to have a real influance, so it is not in -// the code now. It should be testsed in the future. - if (!m_CallBackPending && (m_UserPackets.Size() > 0)) { - // Now testing 3,4 - - LIST_ENTRY *item = m_UserPackets.Head(); - IRP * pIrp = CONTAINING_RECORD(item, IRP ,Tail.Overlay.ListEntry); - - if ((RemainingToCopy(pIrp) < m_MaxMessageSize * m_FreePackets.Size())) { - rc = m_pSdpSocket->RequestCallBack(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL, "PostCredits failed rc = 0x%x\n", rc ); - goto Cleanup; - } - m_CallBackPending = true; - } - } - - if (DissconnectMessage) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"We have recieved a DissconnectMessage complition\n" ); - m_pSdpSocket->DisconectSentEvent(); - } - } - /* - We allow buffers to be sent here since it is possible that the - socket is already closed, and the user thread is not present. - */ - rc = SendBuffersIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL, "SendBuffersIfCan failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - -Cleanup: - ASSERT(m_CurrentlySentBuffers != 0); - m_CurrentlySentBuffers--; - - - return rc; -} - -NTSTATUS -BufferPool::AddToUserBuffers( - bool *pCopied, - bool ForceCopy, - char *pData, - uint32_t BufferSize, - uint32_t Coppied, - IRP* pIrp - ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p m_UserPackets.Size() = %d \n",this, m_UserPackets.Size()); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - - if ((m_UserPackets.Size() == 0) && (ForceCopy == false) ){ - *pCopied = false; - goto Cleanup; - } - - // We have to queue this IRP (following logic from sample) - ASSERT(pData != NULL); - SetBufferSize(pIrp, BufferSize); - SetUserBuffer(pIrp, pData); - SetCoppied(pIrp,Coppied); - SetSocket(pIrp,m_pSdpSocket); - - - IoMarkIrpPending(pIrp); - m_UserPackets.InsertTailList(&pIrp->Tail.Overlay.ListEntry); - *pCopied = true; - // We mark the IRP as pending - pIrp->IoStatus.Status = STATUS_PENDING; - rc = STATUS_PENDING; - -Cleanup: - - -#if 0 -The above code should be activated if we want to allow returning offsetof -the user mode thread as fast as possible. - if (m_CallBackPending == false) { - NTSTATUS rc1 = m_pSdpSocket->RequestCallBack(); - if (!NT_SUCCESS(rc1)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL, "RequestCallBack failed rc = 0x%x\n", rc ); - ASSERT(FALSE); - } - m_CallBackPending = true; - } -#endif - - ASSERT(rc == STATUS_PENDING || rc == STATUS_SUCCESS); - return rc; -} - - -NTSTATUS -BufferPool::UsersThreadCallBack() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p \n",this); - AssertLocked(); - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - IRP *pIrp = NULL; - LIST_ENTRY *item; - - NTSTATUS rc = STATUS_SUCCESS, rc1; - BufferDescriptor *pBufferDescriptor = NULL; - ASSERT(m_CallBackPending == true); - ASSERT(m_UserPackets.Size() > 0 ); - - m_CallBackPending = false; - - while (m_UserPackets.Size() > 0) { - rc = GetBuffer(&pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "GetBuffer failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - if (pBufferDescriptor == NULL) { - // We don't have a new buffer any more, we just - // wait for a new packet to be freed - ASSERT(rc == STATUS_SUCCESS); - goto Cleanup; - } - - item = m_UserPackets.Head(); - - pIrp = CONTAINING_RECORD(item, IRP ,Tail.Overlay.ListEntry); - - // copy the data from the user mode to the buffers - ULONG CopySize = pBufferDescriptor->BufferSize - sizeof msg_hdr_bsdh; - CopySize = min(CopySize, RemainingToCopy(pIrp)); - - rc = pBufferDescriptor->WriteData((CHAR *)GetUserBuffer(pIrp) + GetCoppied(pIrp), CopySize); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "pBufferDescriptor->WriteData failed rc = 0x%x\n", rc ); - // free the buffer that you have - rc1 = ReturnBuffer(pBufferDescriptor); - ASSERT(NT_SUCCESS(rc1)); - goto Cleanup; - } - // Update the user buffer - SetCoppied(pIrp, GetCoppied(pIrp) + CopySize); - - // send the data to the buffer - pBufferDescriptor->SetMid(SDP_MID_DATA); - rc = AddBufferToQueuedList(pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "AddBufferToQueuedList failed rc = 0x%x\n", rc ); - // free the buffer that you have - rc1 = ReturnBuffer(pBufferDescriptor); - ASSERT(NT_SUCCESS(rc1)); - goto Cleanup; - } - - if (RemainingToCopy(pIrp) == 0) { - // We have finished with this users packet, we should - // compleate the IRP - - WspSendOut *pWspSendOut = (WspSendOut *) pIrp->AssociatedIrp.SystemBuffer; - m_UserPackets.RemoveHeadList(); - - pIrp->IoStatus.Status = STATUS_SUCCESS; - pIrp->IoStatus.Information = sizeof (WspSendOut); - pWspSendOut->Errno = 0; - pWspSendOut->NumberOfBytesSent = GetBufferSize(pIrp); - IoCompleteRequest(pIrp, IO_NETWORK_INCREMENT); - - } - } - -Cleanup: - - return rc; -} - - -/* - This function goes over the list of packets that we can send, and sends - them. It is called under the lock, and might be called also from a DPC - context. - -*/ -NTSTATUS -BufferPool::SendBuffersIfCan() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p \n",this); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - -// Check if such code should be here ???? what if we have packets ???? - if (m_PostCreditsWhenCan == true) { - m_PostCreditsWhenCan = false; - rc = PostCredits(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"PostCredits failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - - while ((m_QueuedPackets.Size() > 0) && - (m_CurrentlySentBuffers < m_MaxConcurrentSends) && - (m_rRecvBuf > 2)) { - // we can now send the next buffer - LIST_ENTRY *item = m_QueuedPackets.RemoveHeadList(); - BufferDescriptor *pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - rc = SendBuffer(pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"SendBuffer failed rc = 0x%x\n", rc ); - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - goto Cleanup; - } - } - -Cleanup: - return rc; - -} - - -/* This function is called when the user mode has called close socket - If a client is waiting on recieve we free him, he should get an - error on his callback. *** The caller probably has a bug - as one - can't race a closesocket *** -*/ - -VOID -BufferPool::CloseSocket() -{ - LIST_ENTRY *item = NULL; - IRP *pIrp = NULL; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL, "this = 0x%p \n",this); - AssertLocked(); - // All IRP's that were not compleated, will be compleated as cancelled - while (m_UserPackets.Size() > 0 ) { - item = m_UserPackets.RemoveHeadList(); - pIrp = CONTAINING_RECORD(item, IRP ,Tail.Overlay.ListEntry); - pIrp->IoStatus.Status = STATUS_CANCELLED; - pIrp->IoStatus.Information = 0; - IoCompleteRequest (pIrp, IO_NO_INCREMENT); - } -} - - - -/* - This function is being called from under the lock and is the last one to be called. - It frees all resources - -*/ -VOID -BufferPool::ShutDown() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"this = 0x%p \n",this); - - //AssertLocked(); - BufferDescriptor *pBufferDescriptor = NULL; - LIST_ENTRY *item = NULL; - IRP *pIrp = NULL; - - while (m_FreePackets.Size() > 0 ) { - item = m_FreePackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); - } - - while (m_QueuedPackets.Size() > 0 ) { - item = m_QueuedPackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); - } - - while (m_UserPackets.Size() > 0 ) { - item = m_UserPackets.RemoveHeadList(); - pIrp = CONTAINING_RECORD(item, IRP ,Tail.Overlay.ListEntry); - pIrp->IoStatus.Status = STATUS_CANCELLED; - pIrp->IoStatus.Information = 0; - IoCompleteRequest (pIrp, IO_NO_INCREMENT); - } - - if(m_CreditdBufferDescriptor != NULL) { - BufferDescriptor::DeAllocateBuffer(m_CreditdBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); - m_CreditdBufferDescriptor = NULL; - } - -} - -NTSTATUS -BufferPool::SendBuffer(BufferDescriptor *pBufferDescriptor) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p \n",this); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - - msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *) pBufferDescriptor->pBuffer; - - pHeader->recv_bufs = m_pSdpSocket->m_RecvBufferPool.GetCurrentlyPostedRecievedBuffers(); - pHeader->size = pBufferDescriptor->DataSize + sizeof msg_hdr_bsdh; - pHeader->seq_num = GetAndIncreaseSendSeq(); - pHeader->seq_ack = m_pSdpSocket->m_RecvBufferPool.GetRecvSeq(); - m_AdvtSeq = pHeader->seq_ack;// Currently only for debug - pHeader->flags = SDP_MSG_FLAG_NON_FLAG; - - /* - * endian swap - */ - sdp_msg_swap_bsdh(pHeader); - - ib_send_wr_t send_wr; - - send_wr.p_next = NULL; - send_wr.wr_id = (uintn_t)pBufferDescriptor; - send_wr.wr_type = WR_SEND; - send_wr.send_opt = IB_SEND_OPT_SIGNALED;//socket_info->send_opt; - - pBufferDescriptor->ds_array.length = pBufferDescriptor->DataSize + sizeof msg_hdr_bsdh; - pBufferDescriptor->ds_array.vaddr = MmGetPhysicalAddress( pBufferDescriptor->pBuffer ).QuadPart; - pBufferDescriptor->ds_array.lkey = m_lkey; - - send_wr.num_ds = 1; - send_wr.ds_array = &pBufferDescriptor->ds_array; - - - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_CREDITS, "Sending buffer pHeader->recv_bufs = %d pHeader->seq_ack = %d\n", CL_NTOH16(pHeader->recv_bufs), - CL_NTOH32(pHeader->seq_ack)); - - - ib_api_status_t ib_status = ib_post_send(m_qp, &send_wr, NULL); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"ib_post_send failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - m_NumberOfBytesSent++; - //????? Should we clear the post credits here ???????? - m_CurrentlySentBuffers ++; - m_rRecvBuf--; - m_pSdpSocket->m_RecvBufferPool.UpdateLocaleAdvertisedBuffers(); - -Cleanup: - return rc; -} - -NTSTATUS -BufferPool::PostCredits() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p \n",this); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - - // TODO: If we currently have buffers with data that we should post, and we - // have enough credits then we shouldn't do anything. data will be sent when - // the time comes. - - if (m_CreditsCurrentlyPosted) { - // We will have to send them once we can - m_PostCreditsWhenCan = true; - goto Cleanup; - } - - if (m_pSdpSocket->GetState() != SS_CONNECTED) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL, "this = 0x%p - Not sending credits," - " because state = %s \n",this, SdpSocket::SS2String(m_pSdpSocket->GetState() )); - // We will have to send them once we can - m_PostCreditsWhenCan = true; - goto Cleanup; - } - - // Post the credit - if (m_CreditdBufferDescriptor == NULL) { - - rc = BufferDescriptor::AllocateBuffer( - &m_CreditdBufferDescriptor, - sizeof msg_hdr_bsdh, - SEND_BUFFERS_ALLOCATION_TAG - ); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"AllocateBuffer failed rc = 0x%x\n", rc ); - ASSERT(m_CreditdBufferDescriptor == NULL); - goto Cleanup; - } - m_CreditdBufferDescriptor->SetFlags(CREDIT_UPDATE); - } - ASSERT(m_CreditdBufferDescriptor->GetFlags() == CREDIT_UPDATE); - - ASSERT(m_CreditdBufferDescriptor->DataSize == 0); - - m_CreditdBufferDescriptor->SetMid(SDP_MID_DATA); - rc = SendBuffer(m_CreditdBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"SendBuffer failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - m_CreditsCurrentlyPosted = true; - m_CreditdBufferDescriptor = NULL; - -Cleanup: - return rc; - -} - -NTSTATUS BufferPool::PostDisConn() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"this = 0x%p \n",this); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - BufferDescriptor *pBufferDescriptor = NULL; - - rc = BufferDescriptor::AllocateBuffer( - &pBufferDescriptor, - sizeof msg_hdr_bsdh, - SEND_BUFFERS_ALLOCATION_TAG - ); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"AllocateBuffer failed rc = 0x%x\n", rc ); - ASSERT(m_CreditdBufferDescriptor == NULL); - goto Cleanup; - } - - pBufferDescriptor->SetFlags(DISCONNECT_MESSAGE); - - ASSERT(pBufferDescriptor->DataSize == 0); - - pBufferDescriptor->SetMid(SDP_MID_DISCONNECT); - rc = AddBufferToQueuedList(pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"AddBufferToQueuedList failed rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - return rc; - -} - - -VOID -BufferPool::AssertLocked() { -#if DBG - if (m_pSdpSocket) { - m_pSdpSocket->AssertLocked(); - } -#endif -} - - diff --git a/trunk/ulp/sdp/kernel/SdpBufferPool.h b/trunk/ulp/sdp/kernel/SdpBufferPool.h deleted file mode 100644 index ac7108e7..00000000 --- a/trunk/ulp/sdp/kernel/SdpBufferPool.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef H_SDP_BUFFER_POOL_H -#define H_SDP_BUFFER_POOL_H - -// This is simply a wrapper to the LIST_ENTRY class that allows -// easier work with this list -class LinkedList { - -public: - LinkedList() { - size = 0; - InitializeListHead(&m_Data); - } - - int Size() {return size;} - - LIST_ENTRY *RemoveHeadList() { - LIST_ENTRY *pTemp; - ASSERT(size > 0); - ASSERT(!IsListEmpty(&m_Data)); - pTemp = ::RemoveHeadList(&m_Data); - size--; - return pTemp; - } - - VOID InsertTailList (LIST_ENTRY *Item) { - ::InsertTailList(&m_Data, Item); - size++; - } - - LIST_ENTRY *Head() { - ASSERT(size > 0); - ASSERT(!IsListEmpty(&m_Data)); - return m_Data.Flink; - - } - - VOID RemoveEntryList(LIST_ENTRY *Item) { - ASSERT(size > 0); - ASSERT(!IsListEmpty(&m_Data)); -#if DBG - // Verify that this item is indeed in the list - LIST_ENTRY *current = m_Data.Flink; - while (current != Item) { - if (current == & m_Data) { - ASSERT(FALSE); - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"Object is not in the list\n"); - } - current = current->Flink; - } - -#endif - ::RemoveEntryList(Item); - size--; - } - -private: - int size; - LIST_ENTRY m_Data; -}; - - -// The defenition of the function that we use to report back errors -typedef void (* SendErrorCB )(NTSTATUS Error, VOID *Context); - -// The flags that are being used to give more information about the BufferDescriptors -const uint8_t CREDIT_UPDATE = 1; -const uint8_t DISCONNECT_MESSAGE = 2; - - -// Each buffer starts with msg_hdr_bsdh and is followed by the actual data -class BufferDescriptor { -public: - // copies the data from the user to a buffer (to be used for send only) - NTSTATUS WriteData(char *pData, uint32_t Size) { - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(Size <= BufferSize - sizeof msg_hdr_bsdh); - char *pStart = (char *) pBuffer + sizeof msg_hdr_bsdh; - rc = CopyFromUser(pStart, pData, Size); - if (!NT_SUCCESS(rc)) { - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"CopyFromUser failed rc = 0x%x\n", rc ); - goto Cleanup; - } - DataSize = Size; - Cleanup: - return rc; - } - - // copies data from the buffer to a user suplied buffer - // to be used for recieve only - NTSTATUS CopyToUser(char *pData, uint32_t Size) { - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(DataSize >= Size); - char *pStart = (char *) pBuffer + DataStart; - rc = ::CopyToUser(pData, pStart, Size); - if (!NT_SUCCESS(rc)) { - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"CopyToUser failed rc = 0x%x\n", rc ); - goto Cleanup; - } - DataStart += Size; - DataSize -= Size; - Cleanup: - return rc; - } - VOID Reset() { - DataSize = 0; - DataStart = 0; - Flags = 0; - } - - VOID SetFlags(uint8_t flags) { Flags = flags; } - uint8_t GetFlags() { return Flags; } - - VOID SetMid(uint8_t Mid) { - msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *) pBuffer; - pHeader->mid = Mid; - } - - // Each buffer starts with bsdh_hdr structure - VOID *pBuffer; // A pointer to the actual place that we put the data - uint32_t BufferSize; // The total size of the buffer (size that we have allocated) - uint32_t DataSize; // The size of the data - uint32_t DataStart; // The place in which the data starts (used for recieve packets) - LIST_ENTRY BuffersList; // The place to hold the list of the buffers - uint8_t Flags; // A field that tells if there is anything special in this descriptor - - ib_local_ds_t ds_array; // Used for sending the buffer - - static NTSTATUS AllocateBuffer(BufferDescriptor ** ppBufferDescriptor, int BufferSize, int Tag); - - static VOID DeAllocateBuffer(BufferDescriptor *pBufferDescriptor, int Tag); - - -}; - - -// We will define 4 pointers to store send data for the IRP: -// This will have to change one day() -// The users data - -inline VOID SetUserBuffer(IRP *pIrp, VOID * p) { - pIrp->Tail.Overlay.DriverContext[0] = (VOID *)p; -} -inline VOID* GetUserBuffer(IRP *pIrp) { - return (pIrp->Tail.Overlay.DriverContext[0]); -} - -inline VOID SetBufferSize(IRP *pIrp, uint32_t i) { - pIrp->Tail.Overlay.DriverContext[1] = (VOID *)(UINT_PTR)i; -} -inline uint32_t GetBufferSize(IRP *pIrp) { - return (uint32_t)(UINT_PTR) (pIrp->Tail.Overlay.DriverContext[1]); -} - -inline VOID SetCoppied(IRP *pIrp, uint32_t i) { - pIrp->Tail.Overlay.DriverContext[2] = (VOID *)(UINT_PTR)i; - ASSERT(i <= GetBufferSize(pIrp)); -} -inline uint32_t GetCoppied(IRP *pIrp) { - return (uint32_t)(UINT_PTR) (pIrp->Tail.Overlay.DriverContext[2]); -} - -/* - BUGBUG: - As I intend to change this in any case, - I will not use Referance count on the socket - here. -*/ // ??????????????????? -inline void SetSocket(IRP *pIrp, SdpSocket *pSdpSocket) { - pIrp->Tail.Overlay.DriverContext[3] = pSdpSocket; -} - -inline SdpSocket *GetSocket(IRP *pIrp) { - return (SdpSocket *)pIrp->Tail.Overlay.DriverContext[3]; -} - -inline uint32_t RemainingToCopy(IRP *pIrp) { - uint32_t Coppied = GetCoppied(pIrp); - uint32_t BufferSize = GetBufferSize(pIrp); - ASSERT(BufferSize >= Coppied); - return BufferSize - Coppied; -} - -class BufferPool { - -public: - - BufferPool(); - - NTSTATUS Init( - int MaxBuffers, - int MaxConcurrentSends, - int MaxMessageSize, - ib_pd_handle_t pd, - ib_qp_handle_t qp, - net32_t lkey, - SdpSocket *pSdpSocket - ); - - NTSTATUS GetBuffer( - BufferDescriptor ** ppBufferDescriptor - ); - - NTSTATUS AddBufferToQueuedList(BufferDescriptor *pBufferDescriptor); - - NTSTATUS ReturnBuffer(BufferDescriptor *pBufferDescriptor); - - NTSTATUS AddToUserBuffers(bool *pCopied, bool ForceCopy,char *pData, uint32_t BufferSize, uint32_t Coppied, IRP* pIrp); - - VOID RemoveFromUserBuffers(PIRP pIrp) { - m_UserPackets.RemoveEntryList(&pIrp->Tail.Overlay.ListEntry); - } - - NTSTATUS UsersThreadCallBack(); - - NTSTATUS SendBuffersIfCan(); - - VOID CloseSocket(); - - VOID ShutDown(); - - uint32_t GetSendSeq() {return m_SendSeq;} - uint32_t GetAndIncreaseSendSeq() {return ++m_SendSeq;} - uint32_t GetAdvtSeq() {return m_AdvtSeq;} - - VOID SetRemoteRecvBuf (uint16_t rRecvBuf) { - if (m_rRecvBuf == 2) { - //SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"m_rRecvBuf = %d, it is being set to %d seqnum = %d\n", m_rRecvBuf, rRecvBuf, m_SendSeq); - } - ASSERT(rRecvBuf < 1000); - m_rRecvBuf = rRecvBuf; - } - - NTSTATUS PostCredits(); - - NTSTATUS PostDisConn(); - -private: - - NTSTATUS SendBuffer(BufferDescriptor *pBufferDescriptor); - - // Global data about this connection - uint32_t m_MaxBuffers; // The maximum number of buffers that we allow for this QP (to be allocated) - uint32_t m_MaxConcurrentSends; // The total numbers of sends that are allowd for the QP - uint32_t m_MaxMessageSize; // The maximum buffer size that we allow - - uint32_t m_CurrentlySentBuffers; // Number of buffers that we have sent, and didn't get an ack yet - uint32_t m_CurrentlyAllocated; // The number of buffers that we have allocated - - LinkedList m_FreePackets; // This packets are free and might be used - LinkedList m_QueuedPackets; // This packets were filled with data and should be sent - - -//????? - public: - LinkedList m_UserPackets; // This is a list of user packets that we should send - - - -private: //????????? - - // IBAL constants from the main socket structure - // TODO: Should they stay here and be used like this ? - ib_pd_handle_t m_pd; - ib_qp_handle_t m_qp; - net32_t m_lkey; - - // A list of events that the users has to wait on. ???? currently only one - - uint32_t m_SendSeq; //sequence number of last message sent (send_seq in linux) - uint32_t m_AdvtSeq; // sequence number of last message acknowledged (advt_seq in linux) - uint16_t m_rRecvBuf; // number of recv buffers remote currently has (r_recv_bf in linux) - - SdpSocket *m_pSdpSocket; - - /* - Following two flags are responsible for sending the credits to the - remote side. - Since we are not allowed to send more than one more credit at a time, - we have to remember if a credit is being sent, and if one is, we have - to delay the send of the next credit to the time that the previous - credit was sent - */ - bool m_PostCreditsWhenCan; - bool m_CreditsCurrentlyPosted; - BufferDescriptor *m_CreditdBufferDescriptor; - bool m_CallBackPending; // Set to true if we have requesetd a callback from - // the users thread - - // TODO: The two counters bellow are for debug only. move them to be - // declared as such -public: - uint32_t m_NumberOfBytesSent; - uint32_t m_NumberOfBytesSentAndAcked; - - -VOID AssertLocked(); - -}; - -#endif // H_SDP_BUFFER_POOL_H - diff --git a/trunk/ulp/sdp/kernel/SdpConnectionList.cpp b/trunk/ulp/sdp/kernel/SdpConnectionList.cpp deleted file mode 100644 index c4df3662..00000000 --- a/trunk/ulp/sdp/kernel/SdpConnectionList.cpp +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "Precompile.h" - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpConnectionList.tmh" -#endif - - -VOID -ConnectionList::Init(SdpSocket *pSdpSocket) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - m_pSdpSocket = pSdpSocket; - m_ClientWaiting = false; - KeInitializeEvent(&m_WaitForConnection, NotificationEvent , FALSE ); -} - - -/* This function is called when the user mode has called close socket - If a client is waiting on recieve we free him, he should get an - error on his callback. *** The caller probably has a bug - as one - can't race a closesocket *** -*/ - -VOID -ConnectionList::CloseSocket() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL, "this = 0x%p m_WaitingClients = %s\n",this, - m_ClientWaiting ? "true" : "false"); - AssertLocked(); - - if (m_ClientWaiting) { - KeSetEvent( &m_WaitForConnection, IO_NO_INCREMENT, FALSE ); - m_ClientWaiting = false; - } - // The next time our client will try to get data, he will get - // the error -} - - -VOID ConnectionList::Shutdown() -{ - //?????AssertLocked(); - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - // Go over both lists, and shutdown all their objects - LIST_ENTRY *item = NULL; - SdpSocket *pSocket = NULL; - - while (m_ReplySentConnections.Size() > 0) { - item = m_ReplySentConnections.RemoveHeadList(); - pSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList); - pSocket->Shutdown(); - pSocket->Release(); - } - ASSERT(m_ReplySentConnections.Size() == 0); - - while (m_ReadyConnections.Size() > 0) { - item = m_ReadyConnections.RemoveHeadList(); - pSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList); - pSocket->Shutdown(); - pSocket->Release(); - } - ASSERT(m_ReadyConnections.Size() == 0); - -} - -bool -ConnectionList::IsFull() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - AssertLocked(); - int CurrentConnections = - m_ReplySentConnections.Size() + m_ReadyConnections.Size(); - return CurrentConnections >= m_BackLog; -} - -NTSTATUS -ConnectionList::AddConnectionToReplySent(SdpSocket *pNewSocket) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - AssertLocked(); - m_ReplySentConnections.InsertTailList(&pNewSocket->m_ListeningSocketList); - pNewSocket->AddRef(); - return 0; -} - -// Go over the list of connections and verify that such a connection -// exists -NTSTATUS -ConnectionList::VerifyConnictionInReplySent(SdpSocket *pNewSocket) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - AssertLocked(); - SdpSocket *pSocket = NULL; -#if DBG - LIST_ENTRY *item = m_ReplySentConnections.Head(); - for (int i = 0 ; i < m_ReplySentConnections.Size(); i++) { - pSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList); - if (pSocket == pNewSocket) { - // We have found what we were looking for - return STATUS_SUCCESS; - } - item = item->Flink; - } - // Not found, return error - ASSERT(FALSE); - return STATUS_UNEXPECTED_IO_ERROR; -#else - return STATUS_SUCCESS; - -#endif // DBG - -} - -VOID -ConnectionList::MoveConnectionFromReplyToReady(SdpSocket *pNewSocket) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - AssertLocked(); - pNewSocket->AssertLocked(); - // just take it out from one list and put it in the other - // This must be done through the list, in order to make sure - // that the list size is being kept correctly - m_ReplySentConnections.RemoveEntryList(&pNewSocket->m_ListeningSocketList); - m_ReadyConnections.InsertTailList(&pNewSocket->m_ListeningSocketList); -} - -VOID -ConnectionList::FreeWaitingIfCan() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - AssertLocked(); - if (m_ClientWaiting) { - ASSERT(m_ReadyConnections.Size() > 0); - KeSetEvent( &m_WaitForConnection, IO_NO_INCREMENT, FALSE ); - m_ClientWaiting = false; - } -} - -NTSTATUS -ConnectionList::AcceptAReadyConnection( - SdpSocket **ppNewSocket, - KEVENT **ppEvent - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_CONNECTION_LIST,"this = 0x%p \n", this); - - ASSERT(*ppEvent == NULL); - ASSERT(*ppNewSocket == NULL); - LIST_ENTRY *item = NULL; - - if (m_ClientWaiting) { - ASSERT(m_ClientWaiting == false); - // This is very likely caused because of two threads that are calling - // accept (not supported currently) - //?????? print ????? - return STATUS_UNEXPECTED_IO_ERROR; - } - if (m_ReadyConnections.Size() > 0) { - // We have a connection to return - // TODO: This connection might be in a bad state. What should we do - item = m_ReadyConnections.RemoveHeadList(); - *ppNewSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList); - // There is no change of the referance count, since we are taking - // the socket from the list, but we are also giving it to someone else - return STATUS_SUCCESS; - } - - // We don't have a ready socket to return, the caller will have - // to wait - KeClearEvent(&m_WaitForConnection); - m_ClientWaiting = true; - *ppEvent = &m_WaitForConnection; - return STATUS_SUCCESS; -} - - -VOID -ConnectionList::AssertLocked() { -#if DBG - m_pSdpSocket->AssertLocked(); -#endif -} - diff --git a/trunk/ulp/sdp/kernel/SdpConnectionList.h b/trunk/ulp/sdp/kernel/SdpConnectionList.h deleted file mode 100644 index 516922d2..00000000 --- a/trunk/ulp/sdp/kernel/SdpConnectionList.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef H_SDP_CONNECTION_LIST_H -#define H_SDP_CONNECTION_LIST_H - -// All functions here (including shutdown, should be called with -// the lock taken) - -class ConnectionList { - -public: - VOID Init(SdpSocket *pSdpSocket); - - VOID CloseSocket(); - - VOID Shutdown(); - - bool IsFull(); - VOID SetBackLog(int BackLog) { - m_BackLog = BackLog; - }; - NTSTATUS AddConnectionToReplySent(SdpSocket *pNewSocket); - - // Go over the list of connections and verify that such a connection - // exists - NTSTATUS VerifyConnictionInReplySent(SdpSocket *pNewSocket); - - VOID MoveConnectionFromReplyToReady(SdpSocket *pNewSocket); - - VOID FreeWaitingIfCan(); - - NTSTATUS AcceptAReadyConnection( - SdpSocket **ppNewSocket, - KEVENT **ppEvent - ); - -private: - - VOID AssertLocked(); - - SdpSocket *m_pSdpSocket; // No refcount as we are part of this socket - - int m_BackLog; - LinkedList m_ReplySentConnections; - LinkedList m_ReadyConnections; - KEVENT m_WaitForConnection; - bool m_ClientWaiting; - -}; -#endif //H_SDP_CONNECTION_LIST_H diff --git a/trunk/ulp/sdp/kernel/SdpDriver.cpp b/trunk/ulp/sdp/kernel/SdpDriver.cpp deleted file mode 100644 index 050676c0..00000000 --- a/trunk/ulp/sdp/kernel/SdpDriver.cpp +++ /dev/null @@ -1,831 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar -#include "Precompile.h" - - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpDriver.tmh" -#endif - - - -SdpDriver *g_pSdpDriver = NULL; - -FAST_IO_DISPATCH FastIoDispatch = -{ - FIELD_OFFSET(FAST_IO_DISPATCH, FastIoDeviceControl), - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - SdpDriver::FastDispatch -}; - - -VOID DriverUnload ( - IN PDRIVER_OBJECT pDriverObject - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"called pDriverObject = 0x%p\n", pDriverObject ); - ib_api_status_t ib_status; - - g_pSdpDriver->Shutdown(); - - - ib_status = ib_close_al(g_pSdpDriver->m_al_handle); - g_pSdpDriver->m_al_handle = NULL; - ASSERT( ib_status == IB_SUCCESS); -#if defined(EVENT_TRACING) - WPP_CLEANUP(pDriverObject); -#endif - UNICODE_STRING LinkName; - - RtlInitUnicodeString( &LinkName, SDP_LINK_NAME ); - IoDeleteSymbolicLink(&LinkName); - - IoDeleteDevice( g_pSdpDriver->GetDeviceObject()); - g_pSdpDriver = NULL; -} - - - -extern "C" NTSTATUS DriverEntry ( - IN PDRIVER_OBJECT pDriverObject, - IN PUNICODE_STRING pRegistryPath ) -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_api_status_t ib_status; - PDEVICE_OBJECT pDevObj; - SdpDriver *pSdpDriver; - bool DeviceCreated = false; - bool LinkCreated = false; - UNICODE_STRING DevName1, LinkName; - int i; -#if defined(EVENT_TRACING) - WPP_INIT_TRACING(pDriverObject, pRegistryPath); -#endif - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"called\n" ); - - // fill the device functions - pDriverObject->DriverUnload = DriverUnload; - pDriverObject->FastIoDispatch = NULL; - pDriverObject->DriverStartIo = NULL; - for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { - pDriverObject->MajorFunction[i] = SdpDriver::Dispatch; - } - - // Create the device that will be used for comunication with the user mode - // Now create the device - - RtlInitUnicodeString( &DevName1, SDP_DEVICE_NAME ); - RtlInitUnicodeString( &LinkName, SDP_LINK_NAME ); - - - // BUGBUG: Should we crearte a secure device object - rc = IoCreateDevice( pDriverObject, - sizeof(SdpDriver), - &DevName1, - FILE_DEVICE_UNKNOWN, - 0, - FALSE, - &pDevObj ); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"IoCreateDevice failed rc = 0x%x\n", rc ); - goto Cleanup; - } - DeviceCreated = true; - - pSdpDriver = new (pDevObj->DeviceExtension) SdpDriver; - rc = pSdpDriver->Init(pDevObj, pDriverObject); - - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpDriver->Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - - // Create a Win32-accessible device object - rc = IoCreateSymbolicLink( - &LinkName, - &DevName1 - ); - - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"IoCreateSymbolicLink failed rc = 0x%x\n", rc ); - goto Cleanup; - } - LinkCreated = true; -#pragma warning( push ) -#pragma warning(disable: 4244 ) - ib_status = ib_open_al(&pSdpDriver->m_al_handle); -#pragma warning( pop ) - if ( ib_status != IB_SUCCESS) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"ib_open_al failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - -Cleanup: - if (!NT_SUCCESS(rc)) { - if (LinkCreated) { - IoDeleteSymbolicLink(&LinkName); - - } - if ( DeviceCreated ) { - IoDeleteDevice(pDevObj); - } - } - g_pSdpDriver = pSdpDriver; - - return rc; - -} - -// TODO: Make sure that this function is used correctly, and that -// parameters are being checked well. -BOOLEAN SdpDriver::FastDispatch( - PFILE_OBJECT pFileObject, - BOOLEAN Wait, - PVOID pInputBuffer, - ULONG nInputBufferLength, - PVOID pOutputBuffer, - ULONG nOutputBufferLength, - ULONG IoControlCode, - PIO_STATUS_BLOCK IoStatus, - PDEVICE_OBJECT pDeviceObject - ) -{ - NTSTATUS rc; - ULONG nSize = 0; - ASSERT(FALSE); // Don't just use this function without modifications - - UNREFERENCED_PARAMETER(pDeviceObject); - - UNREFERENCED_PARAMETER(Wait); - - // IOCTLs are allowed only for user mode processes - if (UserMode != ExGetPreviousMode()) { - return (BOOLEAN)FALSE; - } - - __try { - if (pInputBuffer || nInputBufferLength) { - ProbeForRead(pInputBuffer, nInputBufferLength, sizeof(UCHAR)); - } - } __except(EXCEPTION_EXECUTE_HANDLER) { //??? what should I do - ASSERT(FALSE); - pInputBuffer = NULL; - nInputBufferLength = 0; - } - - __try { - if (pOutputBuffer || nOutputBufferLength) { - ProbeForWrite(pOutputBuffer, nOutputBufferLength, sizeof(UCHAR)); - } - } __except(EXCEPTION_EXECUTE_HANDLER) { - ASSERT(FALSE); - pOutputBuffer = NULL; - nOutputBufferLength = 0; - } - - IO_STACK_LOCATION isl; - isl.FileObject = pFileObject; - - // Dispatch the request - rc = g_pSdpDriver->DispatchDeviceIoControl( - NULL, - NULL, - &isl, - pInputBuffer, - nInputBufferLength, - pOutputBuffer, - nOutputBufferLength, - IoControlCode, - nSize - ); - - if (rc != STATUS_PENDING) { - IoStatus->Information = nSize; - IoStatus->Status = rc; - } - - return ((rc == STATUS_PENDING) ? (BOOLEAN)FALSE : (BOOLEAN)TRUE); -} - - - -NTSTATUS SdpDriver::Dispatch( - IN PDEVICE_OBJECT pDeviceObject, - IN PIRP pIrp - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - PIO_STACK_LOCATION pIrpSp; - pIrp->IoStatus.Status = STATUS_SUCCESS; - pIrp->IoStatus.Information = 0; - PVOID pInputBuffer = NULL; - PVOID pOutputBuffer = NULL; - ULONG OutputDataSize = 0; - int Method; - SdpUserFile *pSdpUserFile = NULL; - - pIrpSp = IoGetCurrentIrpStackLocation(pIrp); - - switch (pIrpSp->MajorFunction) { - - case IRP_MJ_CREATE: { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER, "IRP_MJ_CREATE pIrpSp->FileObject = 0x%p\n", - pIrpSp->FileObject ); - pSdpUserFile = new SdpUserFile; - if (pSdpUserFile == NULL) { - rc = STATUS_NO_MEMORY; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"new SdpUserFile failed rc = 0x%x\n", rc ); - goto Cleanup; - } - rc = pSdpUserFile->Init(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpUserFile->Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - // Everything went well, and windows is still using this object. - // As a result we want to make sure that this object will not be - // freed - pIrpSp->FileObject->FsContext = pSdpUserFile; - pSdpUserFile = NULL; - - - break; - } - case IRP_MJ_CLEANUP: { - // All IRPs that were associated with this device should be cleaned - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IRP_MJ_CLEANUP pIrpSp->FileObject = 0x%p\n", - pIrpSp->FileObject ); - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - // The object is being shutdown, and it's cleaning should - // be started - pSdpUserFile->Shutdown(); - // The file object is still holding referance to the object, - // so we set the pointer to NULL - pSdpUserFile = NULL; - - break; - - } - - case IRP_MJ_CLOSE: { - // Receipt of this request indicates that the last handle of the file object - // that is associated with the target device object has been closed and - //released. All outstanding I/O requests have been completed or canceled. - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER, "IRP_MJ_CLOSE pIrpSp->FileObject = 0x%p\n", - pIrpSp->FileObject); - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - // Nothing to do, the referance count will be removed once - // we leave the function - break; - } - case IRP_MJ_DEVICE_CONTROL: { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IRP_MJ_DEVICE_CONTROL pIrpSp->FileObject = 0x%p\n", - pIrpSp->FileObject); - - // IOCTLs are allowed only for user mode processes - if (UserMode != pIrp->RequestorMode) { - rc = STATUS_ACCESS_DENIED; - break; - } - - // Handle the mode of the request and get it's params - Method = pIrpSp->Parameters.DeviceIoControl.IoControlCode & 0x3; - switch (Method) { - case METHOD_BUFFERED: { - pInputBuffer = pOutputBuffer = - pIrp->AssociatedIrp.SystemBuffer; - break; - } - - case METHOD_IN_DIRECT: - case METHOD_OUT_DIRECT: { - pInputBuffer = pIrp->AssociatedIrp.SystemBuffer; - if (pIrp->MdlAddress && - pIrpSp->Parameters.DeviceIoControl.OutputBufferLength) { - if (NULL == (pOutputBuffer = - MmGetSystemAddressForMdlSafe(pIrp->MdlAddress, LowPagePriority))) { - rc = STATUS_INSUFFICIENT_RESOURCES; - goto Cleanup; - } - } - break; - } - - case METHOD_NEITHER: { - pInputBuffer = - pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - pOutputBuffer = pIrp->UserBuffer; - break; - } - } - - // If 'METHOD_NEITHER' probe the buffer - if (METHOD_NEITHER == Method) { - - __try { - - if (pInputBuffer) { - ProbeForRead( - pInputBuffer, - pIrpSp->Parameters.DeviceIoControl.InputBufferLength, - sizeof(UCHAR) - ); - } - if (pOutputBuffer) { - ProbeForWrite( - pOutputBuffer, - pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, - sizeof(UCHAR) - ); - } - - } __except(EXCEPTION_EXECUTE_HANDLER) { - rc = STATUS_ACCESS_VIOLATION; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"IRP_MJ_DEVICE_CONTROL Access " - "violition when trying to read/write data\n"); - - ASSERT(FALSE); - goto Cleanup; - } - } - - - // Handle the request itself - rc = g_pSdpDriver->DispatchDeviceIoControl( - pIrpSp->FileObject, - pIrp, - pIrpSp, - pInputBuffer, - pIrpSp->Parameters.DeviceIoControl.InputBufferLength, - pOutputBuffer, - pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, - pIrpSp->Parameters.DeviceIoControl.IoControlCode, - OutputDataSize - ); - - break; - - } - } - -Cleanup: - if (rc != STATUS_PENDING) { - pIrp->IoStatus.Status = rc; - pIrp->IoStatus.Information = OutputDataSize; - IoCompleteRequest(pIrp, IO_NO_INCREMENT); - } - if (pSdpUserFile) { - pSdpUserFile->Release(); - } - return rc; -} - -// A macro to verify input/output params length -#define VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, InStruct, OutStruct) \ -if ((InputBufferLength < sizeof (InStruct)) || \ - (OutputBufferLength < sizeof (OutStruct))) { \ - /*SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER, "DispatchDeviceIoControl bad buffer sizes\n" ); */ \ - ASSERT(FALSE); \ - rc = STATUS_ACCESS_VIOLATION; \ - goto Cleanup; \ -} - -NTSTATUS -SdpDriver::Init(PDEVICE_OBJECT pDevObj, PDRIVER_OBJECT DriverObject) -{ - NTSTATUS rc = STATUS_SUCCESS; - m_pDevObj = pDevObj; - m_pSdpArp = new SdpArp; - if (m_pSdpArp == NULL) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"new SdpArp failed \n"); - rc = STATUS_NO_MEMORY; - goto Cleanup; - } - rc = m_pSdpArp->Init(DriverObject); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"m_pSdpArp->Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - ExInitializeFastMutex(&m_ThreadsMutex); - -Cleanup: - if (!NT_SUCCESS(rc)) { - if (m_pSdpArp) { - m_pSdpArp->Shutdown(); - delete m_pSdpArp; - } - } - return rc; -} - -VOID -SdpDriver::Shutdown() -{ - m_pSdpArp->Shutdown(); - WaitForAllThreadsToDie(); - -} - -NTSTATUS -SdpDriver::DispatchDeviceIoControl( - IN PFILE_OBJECT pDeviceObject, - IN PIRP pIrp, - IN PIO_STACK_LOCATION pIrpSp, - IN PVOID pInputBuffer, - IN ULONG InputBufferLength, - IN PVOID pOutputBuffer, - IN ULONG OutputBufferLength, - IN ULONG IoControlCode, - OUT ULONG &OutputDataSize - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - SdpUserFile *pSdpUserFile = NULL; - SdpSocket *pSdpSocket = NULL; - SdpSocket *pAcceptedSdpSocket = NULL; - - switch (IoControlCode) { - case IOCTL_WSP_SOCKET : - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_SOCKET recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspSocketIn, WspSocketOut); - OutputDataSize = sizeof (WspSocketOut); - - WspSocketIn wspSocketIn = *(WspSocketIn *) pInputBuffer; - WspSocketOut *pWspSocketOut = (WspSocketOut *) pOutputBuffer; - - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = new SdpSocket; - if (pSdpSocket == NULL) { - rc = STATUS_NO_MEMORY; - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"new SdpSocket failed rc = 0x%x\n", rc ); - goto Cleanup; - } - rc = pSdpSocket->Init(&wspSocketIn, pWspSocketOut, pSdpUserFile); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - rc = pSdpUserFile->AddSocket(pSdpSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpUserFile->AddSocket failed rc = 0x%x\n", rc ); - pSdpSocket->Shutdown(); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_CONNECT : - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_CONNECT recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspConnectIn, WspConnectOut); - OutputDataSize = sizeof (WspConnectOut); - - // get the socket based on the users pointer - WspConnectIn wspConnectIn = *(WspConnectIn *) pInputBuffer; - WspConnectOut *pWspConnectOut = (WspConnectOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspConnectIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_CONNECT socket %p not found\n",wspConnectIn.pSocket); - // This is a well defined winsock error - pWspConnectOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPConnect(&wspConnectIn, pWspConnectOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPConnect failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_SEND : - { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_SEND recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspSendIn, WspSendOut); - OutputDataSize = sizeof (WspSendOut); - - // get the socket based on the users pointer - WspSendIn wspSendIn = *(WspSendIn *) pInputBuffer; - WspSendOut *pWspSendOut = (WspSendOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspSendIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_SEND socket %p not found\n",wspSendIn.pSocket); - // This is a well defined winsock error - pWspSendOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPSend(&wspSendIn, pWspSendOut, pIrp); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPSend failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_RECV : - { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_RECV recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspRecvIn, WspRecvOut); - OutputDataSize = sizeof (WspRecvOut); - - // get the socket based on the users pointer - WspRecvIn wspRecvIn = *(WspRecvIn *) pInputBuffer; - WspRecvOut *pWspRecvOut = (WspRecvOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspRecvIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_RECV socket %p not found\n",wspRecvIn.pSocket); - // This is a well defined winsock error - pWspRecvOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPRecv(&wspRecvIn, pWspRecvOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPRecv failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_BIND: - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_BIND recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspBindIn, WspBindOut); - OutputDataSize = sizeof (WspBindOut); - - // get the socket based on the users pointer - WspBindIn wspBindIn = *(WspBindIn *) pInputBuffer; - WspBindOut *pWspBindOut = (WspBindOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspBindIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_BIND socket %p not found\n", wspBindIn.pSocket); - // This is a well defined winsock error - pWspBindOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPBind(&wspBindIn, pWspBindOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPBind failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_LISTEN: - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_LISTEN recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspListenIn, WspListenOut); - OutputDataSize = sizeof (WspListenOut); - - // get the socket based on the users pointer - WspListenIn wspListenIn = *(WspListenIn *) pInputBuffer; - WspListenOut *pWspListenOut = (WspListenOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspListenIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_LISTEN socket %p not found\n",wspListenIn.pSocket); - // This is a well defined winsock error - pWspListenOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPListen(&wspListenIn, pWspListenOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPListen failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_ACCEPT: - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_ACCEPT recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspAcceptIn, WspAcceptOut); - OutputDataSize = sizeof (WspAcceptOut); - - // get the socket based on the users pointer - WspAcceptIn wspAcceptIn = *(WspAcceptIn *) pInputBuffer; - WspAcceptOut *pWspAcceptOut = (WspAcceptOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspAcceptIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_ACCEPT socket %p not found\n",wspAcceptIn.pSocket); - // This is a well defined winsock error - pWspAcceptOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPAccept(&wspAcceptIn, pWspAcceptOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPAccept failed rc = 0x%x\n", rc ); - goto Cleanup; - } - if (pWspAcceptOut->pAccaptedSocket != NULL) { - pAcceptedSdpSocket = (SdpSocket *) pWspAcceptOut->pAccaptedSocket; - rc = pSdpUserFile->AddSocket(pAcceptedSdpSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpUserFile->AddSocket failed rc = 0x%x\n", rc ); - pAcceptedSdpSocket->Shutdown(); - goto Cleanup; - } - } - } - break; - - case IOCTL_WSP_GET_XXX_NAME: - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_GET_XXX_NAME recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspGetSockXXIn, WspGetSockXXOut); - OutputDataSize = sizeof (WspGetSockXXOut); - - // get the socket based on the users pointer - WspGetSockXXIn wspGetSockXXin = *(WspGetSockXXIn *) pInputBuffer; - WspGetSockXXOut *pWspGetSockXXOut = (WspGetSockXXOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspGetSockXXin.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_GET_XXX_NAME socket %p not found\n", wspGetSockXXin.pSocket); - // This is a well defined winsock error - pWspGetSockXXOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPGetXXXName(&wspGetSockXXin, pWspGetSockXXOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPGetXXXName failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - case IOCTL_WSP_CLOSE_SOCKET : - { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"IOCTL_WSP_CLOSE_SOCKET recieved\n" ); - VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspSocketCloseIn, WspSocketCloseOut); - OutputDataSize = sizeof (WspSocketCloseOut); - - // get the socket based on the users pointer - WspSocketCloseIn wspSocketCloseIn = *(WspSocketCloseIn *) pInputBuffer; - WspSocketCloseOut *pWspSocketCloseOut = (WspSocketCloseOut *) pOutputBuffer; - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - pSdpSocket = pSdpUserFile->SocketByPointer(wspSocketCloseIn.pSocket); - if (pSdpSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER,"IOCTL_WSP_CLOSE_SOCKET socket %p not found\n",wspSocketCloseIn.pSocket); - // This is a well defined winsock error - pWspSocketCloseOut->Errno = WSAENOTSOCK; - goto Cleanup; - } - rc = pSdpSocket->WSPCloseSocket(&wspSocketCloseIn, pWspSocketCloseOut); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"pSdpSocket->WSPCloseSocket failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - break; - - case IOCTL_WSP_USER_THREAD : - { - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_DRIVER, "IOCTL_WSP_USER_THREAD recieved\n" ); - pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; - - /* Ignore Error = */ pSdpUserFile->UsersThread(); - } - break; - - default: - // This is an unrecgnized IOCTL - ASSERT(FALSE); - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_DRIVER,"unknow IOCTL code = 0x%x\n", IoControlCode ); - rc = STATUS_INVALID_PARAMETER; - goto Cleanup; - - - } -Cleanup: - if (pSdpSocket) { - pSdpSocket->Release(); - } - if (pAcceptedSdpSocket) { - pAcceptedSdpSocket->Release(); - } - - return rc; -} - -VOID -SdpDriver::AddThread(ThreadHandle *pThreadHandle) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"this = 0x%p\n", this ); - // Check if there is any next thread that can be removed from the queue - LARGE_INTEGER WaitTime; - WaitTime.QuadPart = 0; // Don't wait for them to die - - ExAcquireFastMutex(&m_ThreadsMutex); - - WaitForThreadsToDie(&WaitTime); - - // Add me to the list of threads that should be removed - m_ShutDownThreads.InsertTailList(&pThreadHandle->m_List); - ExReleaseFastMutex(&m_ThreadsMutex); - -} - -VOID -SdpDriver::WaitForAllThreadsToDie() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"this = 0x%p\n", this ); - - ExAcquireFastMutex(&m_ThreadsMutex); - // Timeout of null will cause a wait forever - WaitForThreadsToDie(NULL); - ExReleaseFastMutex(&m_ThreadsMutex); -} - - -// This function has to be called with the mutex held -VOID -SdpDriver::WaitForThreadsToDie(LARGE_INTEGER *pWaitTime) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"this = 0x%p\n", this ); - // Check if there is any next thread that can be removed from the queue - NTSTATUS rc = STATUS_SUCCESS; - - LIST_ENTRY *pNextItem; - ThreadHandle *pNextThreadHandle; - while (m_ShutDownThreads.Size() > 0) { - pNextItem = m_ShutDownThreads.Head(); - pNextThreadHandle = CONTAINING_RECORD(pNextItem, ThreadHandle, m_List); - - rc = MyKeWaitForSingleObject( - pNextThreadHandle->ThreadObject, - Executive, - KernelMode, - FALSE, - pWaitTime - ); - ASSERT((rc == STATUS_SUCCESS) || - (rc == STATUS_TIMEOUT)); - - if (rc == STATUS_TIMEOUT) { - // Nothing that we should do, the thread is not ready yet - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"this = 0x%p Former thread is not dead yet\n", this ); - break; - } - // SUCESS means that the thread is dead, we can remove it - // from the list - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_DRIVER,"this = 0x%p Former thread is already dead\n", this ); - - m_ShutDownThreads.RemoveHeadList(); - ObDereferenceObject(pNextThreadHandle->ThreadObject); - delete pNextThreadHandle; - - // We now continue and try to remove the next object - - } - -} - - diff --git a/trunk/ulp/sdp/kernel/SdpDriver.h b/trunk/ulp/sdp/kernel/SdpDriver.h deleted file mode 100644 index e1b23931..00000000 --- a/trunk/ulp/sdp/kernel/SdpDriver.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef H_SDP_DRIVER_H -#define H_SDP_DRIVER_H - -// This struct is being used to hold an object that we can wait on -// for threads to die. - -struct ThreadHandle { - // As this object has a simple life cycle I don't use refferance counting - // for it. This might have to change. - PVOID ThreadObject; - LIST_ENTRY m_List; -}; - - -class SdpDriver { -public: - SdpDriver() { - m_al_handle = NULL; - m_pDevObj = NULL; - m_pSdpArp = NULL; - } - - NTSTATUS Init(PDEVICE_OBJECT pDevObj, PDRIVER_OBJECT DriverObject); - - VOID Shutdown(); - - PDEVICE_OBJECT GetDeviceObject() { - return m_pDevObj; - } - - static - NTSTATUS Dispatch( - IN PDEVICE_OBJECT pDeviceObject, - IN PIRP pIrp - ); - - static - BOOLEAN FastDispatch( - PFILE_OBJECT pFileObject, - BOOLEAN Wait, - PVOID pInputBuffer, - ULONG nInputBufferLength, - PVOID pOutputBuffer, - ULONG nOutputBufferLength, - ULONG IoControlCode, - PIO_STATUS_BLOCK IoStatus, - PDEVICE_OBJECT pDeviceObject - ); - - - NTSTATUS DispatchDeviceIoControl( - IN PFILE_OBJECT pDeviceObject, - IN PIRP pIrp, - IN PIO_STACK_LOCATION pIrpSp, - IN PVOID pInputBuffer, - IN ULONG InputBufferLength, - IN PVOID pOutputBuffer, - IN ULONG OutputBufferLength, - IN ULONG IoControlCode, - OUT ULONG &OutputDataSize - ); - - // The following functions are being used so that the driver - // will wait for all the created threads to end - VOID AddThread(ThreadHandle *pThreadHandle); - - VOID WaitForAllThreadsToDie(); - -public: - ib_al_handle_t m_al_handle ; - SdpArp *m_pSdpArp; - - -private: - - VOID WaitForThreadsToDie(LARGE_INTEGER *pWWaitTime); - - - PDEVICE_OBJECT m_pDevObj; - - LinkedList m_ShutDownThreads; - - FAST_MUTEX m_ThreadsMutex; - -}; - -extern SdpDriver *g_pSdpDriver; - -#endif //H_SDP_DRIVER_H diff --git a/trunk/ulp/sdp/kernel/SdpGenUtils.cpp b/trunk/ulp/sdp/kernel/SdpGenUtils.cpp deleted file mode 100644 index db77ec45..00000000 --- a/trunk/ulp/sdp/kernel/SdpGenUtils.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "Precompile.h" - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpGenUtils.tmh" -#endif - -//#define DONT_COPY_DATA - -USHORT ntohs(USHORT in) -{ - return ((in & 0xff) << 8) | ((in & 0xff00) >> 8); -} - -NTSTATUS IB2Status (ib_api_status_t ib_status) -{ - if ( ib_status == IB_SUCCESS ) { - return STATUS_SUCCESS; - } if (( ib_status > IB_SUCCESS ) && (ib_status < IB_UNKNOWN_ERROR)) { -// -// Values are 32 bit values layed out as follows: -// -// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 -// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -// +---+-+-+-----------------------+-------------------------------+ -// |Sev|C|R| Facility | Code | -// +---+-+-+-----------------------+-------------------------------+ - - return 0xcc000000 | ib_status; - } - - - // Keep translating as the error pops - ASSERT(FALSE); - return STATUS_UNEXPECTED_IO_ERROR; - -} - -// BUGBUG: Understand how to reomove the 20 from the code. -// This function is a wrapper for the KeWaitForSingleObject that adds -// assertsions to the valuas returned by it -NTSTATUS - MyKeWaitForSingleObject( - IN PVOID Object, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL - ) -{ - NTSTATUS rc; - for (int i=0; i < 20; i++) { - rc = KeWaitForSingleObject( - Object, - WaitReason, - WaitMode, - Alertable, - Timeout - ); - if (!NT_SUCCESS(rc)) { - ASSERT(FALSE); - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"KeWaitForSingleObject failed rc = 0x%x\n", rc ); - // No meter what we do the program can't continue, let's crush it - int *i = NULL; - *i = 5; - } - ASSERT((rc == STATUS_SUCCESS ) || - (rc == STATUS_ALERTED ) || - (rc == STATUS_USER_APC ) || - (rc == STATUS_TIMEOUT )); // This are simply all the return code from DDK - - ASSERT( (Timeout != NULL ) || rc != STATUS_TIMEOUT); - if (rc != STATUS_USER_APC) { - break; - } else { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"KeWaitForSingleObject was stoped because of STATUS_USER_APC\n" ); - } - } - if (i == 20) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"!!!! KeWaitForSingleObject was Exhausted STATUS_USER_APC\n" ); - // This is probably fine if we are runnign for a user thread - ASSERT((WaitReason == UserRequest) && (WaitMode == UserMode)); - } - return rc; -} - -NTSTATUS -CopyFromUser( - IN void* const p_dest, - IN const void* const p_src, - IN const size_t count ) -{ - /* - * The memory copy must be done within a try/except block as the - * memory could be changing while the buffer is copied. - */ - __try - { - ProbeForRead( (void*)p_src, count, 1 ); -#ifdef DONT_COPY_DATA - if (count < 1000){ - RtlCopyMemory( p_dest, p_src, count ); - } -#else - RtlCopyMemory( p_dest, p_src, count ); -#endif - return STATUS_SUCCESS; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"copying memory from user failed\n"); - ASSERT(FALSE); - return STATUS_ACCESS_DENIED; - } -} - -NTSTATUS -CopyToUser( - IN void* const p_dest, - IN const void* const p_src, - IN const size_t count - ) -{ - /* - * The memory copy must be done within a try/except block as the - * memory could be changing while the buffer is copied. - */ - __try - { - ProbeForWrite( p_dest, count, 1 ); -#ifdef DONT_COPY_DATA - if (count < 1000){ - RtlCopyMemory( p_dest, p_src, count ); - } -#else - RtlCopyMemory( p_dest, p_src, count ); -#endif - return CL_SUCCESS; - } - __except(EXCEPTION_EXECUTE_HANDLER) - { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"copying memory from user failed\n"); - ASSERT(FALSE); - return STATUS_ACCESS_DENIED; - } -} - -VOID UpdateRc(NTSTATUS *rc, NTSTATUS rc1) -{ - // We want to keep the first errro - if (NT_SUCCESS(*rc)) { - *rc = rc1; - } -} - -int abs(int i){ - if (i > 0) return i; - return -i; -} - -LARGE_INTEGER TimeFromLong(ULONG HandredNanos) -{ - LARGE_INTEGER Timeout; - Timeout.HighPart = 0xffffffff; - Timeout.LowPart = 0xffffffff ^ HandredNanos; - return Timeout; -} - -NTSTATUS Sleep(ULONG HandredNanos) -{ - KEVENT Event; - NTSTATUS rc = STATUS_SUCCESS; - - KeInitializeEvent(&Event, NotificationEvent , FALSE ); - - LARGE_INTEGER Timeout = TimeFromLong(HandredNanos); - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"Before Sleep\n"); - rc = MyKeWaitForSingleObject( - &Event, - UserRequest, - UserMode, - FALSE, - &Timeout); - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"After Sleep rc = 0x%x\n", rc); - return rc; - -} - -/* Convert an IBAL error to a Winsock error. */ -int IbalToWsaError(const ib_api_status_t ib_status ) -{ - switch( ib_status ) - { - case IB_SUCCESS: - return 0; - - case IB_INVALID_QP_HANDLE: - return WSAENOTCONN; - - case IB_INVALID_PARAMETER: - return WSAEINVAL; - - case IB_INSUFFICIENT_RESOURCES: - return WSAENOBUFS; - - case IB_INVALID_WR_TYPE: - return WSAEINVAL; - - case IB_INVALID_QP_STATE: - return WSAENOTCONN; - - default: - return WSAEINVAL; - } -} - -void* __cdecl operator new(size_t n ) throw() { - return ExAllocatePoolWithTag(NonPagedPool , n, GLOBAL_ALLOCATION_TAG); -} - -void __cdecl operator delete(void* p) { - ExFreePoolWithTag(p, GLOBAL_ALLOCATION_TAG); -} - -void* __cdecl operator new(size_t n, void *addr ) throw() { - return addr; -} - - diff --git a/trunk/ulp/sdp/kernel/SdpGenUtils.h b/trunk/ulp/sdp/kernel/SdpGenUtils.h deleted file mode 100644 index 4b655fd6..00000000 --- a/trunk/ulp/sdp/kernel/SdpGenUtils.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef _SDP_GEN_UTILS_H -#define _SDP_GEN_UTILS_H - - - -#define GLOBAL_ALLOCATION_TAG ' pdS' -#define SEND_BUFFERS_ALLOCATION_TAG 'SpdS' -#define RECV_BUFFERS_ALLOCATION_TAG 'RpdS' - - -class CSpinLockWrapper { - KSPIN_LOCK &m_SpinLock; - KIRQL m_OldIrql; - -public: - - CSpinLockWrapper (KSPIN_LOCK &SpinLock) : m_SpinLock(SpinLock){ - // Spinlock must already be initialized -#if DBG - m_OldIrql = 0xff; -#endif - } - - void Lock() { - ASSERT(m_OldIrql == 0xff); - KeAcquireSpinLock(&m_SpinLock, &m_OldIrql); - } - - void Unlock() { - ASSERT(m_OldIrql != 0xff); - KeReleaseSpinLock(&m_SpinLock, m_OldIrql); -#if DBG - m_OldIrql = 0xff; -#endif - } - - ~CSpinLockWrapper() { - ASSERT(m_OldIrql == 0xff); - } - -}; - -NTSTATUS IB2Status (ib_api_status_t ib_status); - -USHORT nthos(USHORT in); - -NTSTATUS - MyKeWaitForSingleObject( - IN PVOID Object, - IN KWAIT_REASON WaitReason, - IN KPROCESSOR_MODE WaitMode, - IN BOOLEAN Alertable, - IN PLARGE_INTEGER Timeout OPTIONAL - ); - - -NTSTATUS -CopyFromUser( - IN void* const p_dest, - IN const void* const p_src, - IN const size_t count - ); - -NTSTATUS -CopyToUser( - IN void* const p_dest, - IN const void* const p_src, - IN const size_t count - ); - -VOID UpdateRc(NTSTATUS *rc, NTSTATUS rc1); - -int abs(int i); - -LARGE_INTEGER TimeFromLong(ULONG HandredNanos); - -NTSTATUS Sleep(ULONG HandredNanos); - -void* __cdecl operator new(size_t n, void *addr ) throw(); - -/* Convert an IBAL error to a Winsock error. */ -int IbalToWsaError(const ib_api_status_t ib_status ); - -#define INADDR_ANY (ULONG)0x00000000 -#define INADDR_LOOPBACK 0x7f000001 - -// This error codes are taken from winsock2.h (the file can not) -// be included from kernel mode - -/* - * All Windows Sockets error constants are biased by WSABASEERR from - * the "normal" - */ -#define WSABASEERR 10000 - -/* - * Windows Sockets definitions of regular Microsoft C error constants - */ -#define WSAEINTR (WSABASEERR+4) -#define WSAEBADF (WSABASEERR+9) -#define WSAEACCES (WSABASEERR+13) -#define WSAEFAULT (WSABASEERR+14) -#define WSAEINVAL (WSABASEERR+22) -#define WSAEMFILE (WSABASEERR+24) - -/* - * Windows Sockets definitions of regular Berkeley error constants - */ -#define WSAEWOULDBLOCK (WSABASEERR+35) -#define WSAEINPROGRESS (WSABASEERR+36) -#define WSAEALREADY (WSABASEERR+37) -#define WSAENOTSOCK (WSABASEERR+38) -#define WSAEDESTADDRREQ (WSABASEERR+39) -#define WSAEMSGSIZE (WSABASEERR+40) -#define WSAEPROTOTYPE (WSABASEERR+41) -#define WSAENOPROTOOPT (WSABASEERR+42) -#define WSAEPROTONOSUPPORT (WSABASEERR+43) -#define WSAESOCKTNOSUPPORT (WSABASEERR+44) -#define WSAEOPNOTSUPP (WSABASEERR+45) -#define WSAEPFNOSUPPORT (WSABASEERR+46) -#define WSAEAFNOSUPPORT (WSABASEERR+47) -#define WSAEADDRINUSE (WSABASEERR+48) -#define WSAEADDRNOTAVAIL (WSABASEERR+49) -#define WSAENETDOWN (WSABASEERR+50) -#define WSAENETUNREACH (WSABASEERR+51) -#define WSAENETRESET (WSABASEERR+52) -#define WSAECONNABORTED (WSABASEERR+53) -#define WSAECONNRESET (WSABASEERR+54) -#define WSAENOBUFS (WSABASEERR+55) -#define WSAEISCONN (WSABASEERR+56) -#define WSAENOTCONN (WSABASEERR+57) -#define WSAESHUTDOWN (WSABASEERR+58) -#define WSAETOOMANYREFS (WSABASEERR+59) -#define WSAETIMEDOUT (WSABASEERR+60) -#define WSAECONNREFUSED (WSABASEERR+61) -#define WSAELOOP (WSABASEERR+62) -#define WSAENAMETOOLONG (WSABASEERR+63) -#define WSAEHOSTDOWN (WSABASEERR+64) -#define WSAEHOSTUNREACH (WSABASEERR+65) -#define WSAENOTEMPTY (WSABASEERR+66) -#define WSAEPROCLIM (WSABASEERR+67) -#define WSAEUSERS (WSABASEERR+68) -#define WSAEDQUOT (WSABASEERR+69) -#define WSAESTALE (WSABASEERR+70) -#define WSAEREMOTE (WSABASEERR+71) - -// Used for IRP cancell -#define ERROR_OPERATION_ABORTED 995L -#define WSA_OPERATION_ABORTED (ERROR_OPERATION_ABORTED) - -#endif // _SDP_GEN_UTILS_H diff --git a/trunk/ulp/sdp/kernel/SdpLock.h b/trunk/ulp/sdp/kernel/SdpLock.h deleted file mode 100644 index 5637044b..00000000 --- a/trunk/ulp/sdp/kernel/SdpLock.h +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - - -#ifndef _SDP_LOCK_H -#define _SDP_LOCK_H - -/* -The goal of this lock is to be a user mode lock that will allow us to synchronize -both "user" operations at PASSIVE level as well as DPC's at DPC level. - -The main problem that we have is that we have many functions that we can only call at -passive level, and therefore can not be called under a spinlock. - -We might, however, receive notifications at DPC level. Example of such are send and -receive completions. As always, shutdown might appear at any time (at any level?). - -Bottom line of this is that the lock will be implemented as an event. DPC level -callers that will call us will only mark our state as send/received/shutdown arrived. - -Once one tries to take/free the lock from passive level, he will have to handle this -events first. - -Callers at DPC level, (send receive call backs) will only signal if the lock is taken -or do the actual job if it is not taken. - -There will therefore be a spinlock that will protect the event. - -*/ - - -// Still Need to make sure that all errors are handled when they should ?????? - -typedef NTSTATUS (* SendCBHandler )(SdpSocket *); -typedef NTSTATUS (* RecvCBHandler )(SdpSocket *); -typedef NTSTATUS (* CheckSocketStateFunction )(SdpSocket *); - - -const int SEND_CB_CALLED = 0x00000001; -const int RECV_CB_CALLED = 0x00000002; -const int ERROR_SIGNALLED = 0x00000004; - -const int DPC_FLAGS = SEND_CB_CALLED | RECV_CB_CALLED; -inline void ResetFlags(int &Flags) -{ - Flags &= (!(SEND_CB_CALLED | RECV_CB_CALLED)); -} - -inline void ResetDpcFlags(int &Flags) -{ - // Currently this function is just like the one above it. It will probably - // change in the future - Flags &= (!(DPC_FLAGS)); -} - -inline bool SomethingToHandle(int flags) -{ - if (flags & SEND_CB_CALLED) return true; - if (flags & RECV_CB_CALLED) return true; - - return false; -} - -class SdpLock { -public: - SdpLock() { - m_InUse = false; - m_flags = 0; - KeInitializeEvent(&m_Event, NotificationEvent , TRUE); - KeInitializeSpinLock(&m_SpinLock); - m_SendCBHandler = NULL; - m_RecvCBHandler = NULL; - m_NumberOfClientWaiting = 0; - } - - VOID Init( - SendCBHandler SendCB, - RecvCBHandler RecvCB, - CheckSocketStateFunction CheckSocketState, - SdpSocket *pSdpSocket ) - { - m_SendCBHandler = SendCB; - m_CheckSocketState = CheckSocketState; - m_RecvCBHandler = RecvCB; - m_pSdpSocket = pSdpSocket; - - } - - /* - Lock should handle recieve_cb/send_cb without user knowledge. - for shutdown, it should return false and not continue - - return value of false means that the lock can not be taken (eitheir - shutdown or STATUS_ALERTED, or some error has happend) - */ - bool Lock(bool Force = false) { - KIRQL OldIrql; - int OldFlags = 0; - NTSTATUS rc = STATUS_SUCCESS, rc1 = STATUS_SUCCESS; - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - bool Locked = false; - bool WaitedOnLock = false; - do { - KeAcquireSpinLock(&m_SpinLock, &OldIrql); - - if (m_InUse) { - // We have to release the spinlock and wait on the event - if (WaitedOnLock == false) { - m_NumberOfClientWaiting++; - WaitedOnLock = true; - } - KeReleaseSpinLock(&m_SpinLock, OldIrql); - rc = MyKeWaitForSingleObject(&m_Event, UserRequest, UserMode, false, NULL); - if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) { - //SDP_PRINT(TRACE_LEVEL_WARNING, SDP_LOCK,"MyKeWaitForSingleObject was alerted = 0x%x\n", rc ); - rc = STATUS_UNEXPECTED_IO_ERROR; - Locked = false; - goto Cleanup; - } - continue; - } - m_InUse = true; - KeClearEvent(&m_Event); - OldFlags = m_flags; - ResetFlags(m_flags); - if (WaitedOnLock) { - m_NumberOfClientWaiting--; - } - ASSERT(m_NumberOfClientWaiting >= 0); - KeReleaseSpinLock(&m_SpinLock, OldIrql); - rc = HandleFlags(OldFlags); - if(!NT_SUCCESS(rc)) { - //SDP_PRINT(SDP_ERR, SDP_LOCK, ("HandleFlags failed rc = 0x%x\n", rc )); - } - if ((Force == false) && - (!NT_SUCCESS(rc) || - (m_flags & ERROR_SIGNALLED) || - (!NT_SUCCESS(rc1 = m_CheckSocketState(m_pSdpSocket))) - )) { - // We have to signal the error to the calling side - if(!NT_SUCCESS(rc1)) { - //SDP_PRINT(SDP_ERR, SDP_LOCK, ("m_CheckSocketState failed rc1 = 0x%x\n", rc1 )); - } - Locked = false; - KeAcquireSpinLock(&m_SpinLock, &OldIrql); - m_InUse = false; - // Release whoever is waiting - KeSetEvent(&m_Event, IO_NO_INCREMENT, FALSE); - KeReleaseSpinLock(&m_SpinLock, OldIrql); - goto Cleanup; - } - // Exit the loop - - Locked = true; - goto Cleanup; - } while (true); - -Cleanup: - //SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_LOCK,"Lock is returing %s\n", Locked ? "true" : "false"); - return Locked; - } - - // This is the first stage in moving the lock to return rc (and later void) - NTSTATUS LockRc() { - if (Lock()) return STATUS_SUCCESS; - return STATUS_SHUTDOWN_IN_PROGRESS; - } - - /* - Frees the lock and handle any events that might happen there. - Please note that the lock is freed no metter what the error code is. - An error means that there was some error in the sockets. - */ - - //?????????? should this be ntstatus or bool ??????? - NTSTATUS Unlock() - { - KIRQL OldIrql; - int OldFlags = 0; - NTSTATUS rc = STATUS_SUCCESS; - - while (true) { - ASSERT(m_InUse); - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - KeAcquireSpinLock(&m_SpinLock, &OldIrql); - ASSERT(m_InUse); // Also with the lock taken - OldFlags = m_flags; - ResetFlags(m_flags); - if (!SomethingToHandle(OldFlags)) { - // We can safely quit the lock - m_InUse = false; - // Before we leave this function we check for errors / shutdown here - if (m_flags & ERROR_SIGNALLED) { - rc = STATUS_UNEXPECTED_IO_ERROR; - } else { - rc = m_CheckSocketState(m_pSdpSocket); - } - KeReleaseSpinLock(&m_SpinLock, OldIrql); - break; - } - KeReleaseSpinLock(&m_SpinLock, OldIrql); - ASSERT(SomethingToHandle(OldFlags)); - ASSERT(m_InUse); - rc = HandleFlags(OldFlags); - if (!NT_SUCCESS(rc)) { - // We have to signal the error to the calling side - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_LOCK,"HandleFlags failed rc = 0x%x\n", rc ); - ASSERT(m_flags & ERROR_SIGNALLED); - } - // At the time that we were handeling the flags, someone might have - // signaled something, so we have to try again - continue; - } - - // Release whoever is waiting - KeSetEvent(&m_Event, IO_NO_INCREMENT, FALSE); - - return rc; - } -/* - This function is being called at DPC level. It has some message of a call back. - to tell us. Once called, it will try to take the lock. If it succeeds, it will - do the actual work, if not it will only signal. Once it returns the lock is freed - again -*/ - - bool SignalCB(int flags) - { - KIRQL OldIrql; - int OldFlags = 0; - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - KeAcquireSpinLock(&m_SpinLock, &OldIrql); - if (m_InUse || (m_NumberOfClientWaiting > 0 ) ) { - m_flags |= flags; - KeReleaseSpinLock(&m_SpinLock, OldIrql); - return false; - } - while (true) { - m_InUse = true; - // In this lock, we only handle DPC events - OldFlags = (m_flags & DPC_FLAGS) | flags; - flags = 0; // No need to handle the same event any more - ResetDpcFlags(m_flags); - KeClearEvent(&m_Event); - KeReleaseSpinLock(&m_SpinLock, OldIrql); - rc = HandleFlags(OldFlags); - if (!NT_SUCCESS(rc)) { - // We have to signal the error to the calling side - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_LOCK,"HandleFlags failed rc = 0x%x\n", rc ); - ASSERT(m_flags & ERROR_SIGNALLED); - } - KeAcquireSpinLock(&m_SpinLock, &OldIrql); - if ((m_flags & DPC_FLAGS) == 0) { - // No flags to handle from the DPC layer - break; - } - } - - // Release whoever is waiting - m_InUse = false; - KeSetEvent(&m_Event, IO_NO_INCREMENT, FALSE); - KeReleaseSpinLock(&m_SpinLock, OldIrql); - - return true; - } - - /* - This function is responsible for handling the flags that we might get. - Currently it can be called from passive or DPC level, and handle only "DPC" events - */ - NTSTATUS HandleFlags(int flags) { - NTSTATUS rc = STATUS_SUCCESS; - AssertLocked(); - // Try to do this faster if nothing to do - if (flags == 0) { - return STATUS_SUCCESS; - } - if (flags & SEND_CB_CALLED) { - // We need to handle the send CB - rc = m_SendCBHandler(m_pSdpSocket); - if (!NT_SUCCESS(rc)) { - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"m_SendCBHandler failed rc = 0x%x\n", rc ); - m_flags |= ERROR_SIGNALLED; - // We continue from here since, there might be other things to handle, - // and this might be in a DPC context - } - } - if (flags & RECV_CB_CALLED) { - // We need to handle the send CB - rc = m_RecvCBHandler(m_pSdpSocket); - if (!NT_SUCCESS(rc)) { - //SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"m_RecvCBHandler failed rc = 0x%x\n", rc ); - m_flags |= ERROR_SIGNALLED; - // We continue from here since, there might be other things to handle, - // and this might be in a DPC context - } - } - return rc; - } - - VOID SignalError(NTSTATUS rc) { - m_flags |= ERROR_SIGNALLED; - } - - VOID AssertLocked() {ASSERT(m_InUse);} - - KEVENT m_Event; // the event for passive level threads - KSPIN_LOCK m_SpinLock; // The real guard of the lock - SendCBHandler m_SendCBHandler; - RecvCBHandler m_RecvCBHandler; - CheckSocketStateFunction m_CheckSocketState; - - - bool m_InUse; // Tells if this lock has any user - int m_flags; // call backs that were recieved - int m_NumberOfClientWaiting; // Number of clients that are waiting to be served - - SdpSocket *m_pSdpSocket;// The socket that this class depends on -}; - -#endif // _SDP_LOCK_H diff --git a/trunk/ulp/sdp/kernel/SdpMsgs.h b/trunk/ulp/sdp/kernel/SdpMsgs.h deleted file mode 100644 index a24d93d6..00000000 --- a/trunk/ulp/sdp/kernel/SdpMsgs.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -/* - This file holds the types that are used for SDP comunication - -*/ - -#ifndef H_SDP_MSGS_H -#define H_SDP_MSGS_H - - -#pragma pack(push) -#pragma pack(1) - - -/* - * Message Identifier Opcodes for BSDH - */ -/* Name Value Extended Header Payload */ -#define SDP_MID_HELLO 0x00 /* msg_hdr_hh */ -#define SDP_MID_HELLO_ACK 0x01 /* msg_hdr_hah */ -#define SDP_MID_DISCONNECT 0x02 /* */ -#define SDP_MID_ABORT_CONN 0x03 /* */ -#define SDP_MID_SEND_SM 0x04 /* */ -#define SDP_MID_RDMA_WR_COMP 0x05 /* msg_hdr_rwch */ -#define SDP_MID_RDMA_RD_COMP 0x06 /* msg_hdr_rrch */ -#define SDP_MID_MODE_CHANGE 0x07 /* msg_hdr_mch */ -#define SDP_MID_SRC_CANCEL 0x08 /* */ -#define SDP_MID_SNK_CANCEL 0x09 /* */ -#define SDP_MID_SNK_CANCEL_ACK 0x0A /* */ -#define SDP_MID_CH_RECV_BUF 0x0B /* msg_hdr_crbh */ -#define SDP_MID_CH_RECV_BUF_ACK 0x0C /* msg_hdr_crbah */ -#define SDP_MID_SUSPEND 0x0D /* msg_hdr_sch */ -#define SDP_MID_SUSPEND_ACK 0x0E /* */ -#define SDP_MID_SNK_AVAIL 0xFD /* msg_hdr_snkah */ -#define SDP_MID_SRC_AVAIL 0xFE /* msg_hdr_srcah */ -#define SDP_MID_DATA 0xFF /* */ -/* - * shift number for BSDH Flags. - */ -#define SDP_MSG_FLAG_NON_FLAG (0x0) /* no flag present */ -#define SDP_MSG_FLAG_OOB_PRES 0 /* out-of-band data present */ -#define SDP_MSG_FLAG_OOB_PEND 1 /* out-of-band data pending */ -#define SDP_MSG_FLAG_REQ_PIPE 2 /* request change to pipelined */ -/* - * message type masks - */ -#define SDP_MID_CTRL(mid) ((0xF0 & mid) ? 0 : 1) - - -/* - * Base Sockets Direct Header (header for all SDP messages) - */ -struct msg_hdr_bsdh { - uint8_t mid; /* message identifier opcode (SDP_MID_*) */ - uint8_t flags; /* flags as defined by SDP_MSG_FLAG_* */ - uint16_t recv_bufs; /* current number of posted private recv buffers */ - uint32_t size; /* length of msg, including header(s) and data */ - uint32_t seq_num; /* message sequence number */ - uint32_t seq_ack; /* last received message sequence number */ -};// __attribute__ ((packed)); /* struct msg_hdr_bsdh */ - -/* - * Hello Header constants (two 8-bit constants, no conversion needed) - */ -#ifdef _SDP_MS_APRIL_ERROR_COMPAT -this bug was probably solved -#define SDP_MSG_IPVER 0x04 /* (1: ipversion), (0: reserved) */ -#else -#define SDP_MSG_IPVER 0x40 /* (1: ipversion), (0: reserved) */ -#endif -#define SDP_MSG_VERSION 0x11 /* (1: major ), (0: minor ) */ - - -/* - * Hello Header (BSDH + HH are contained in private data of the CM REQ MAD - */ -struct msg_hdr_hh { - uint8_t version; /* 0-3: minor version (current spec; 0x1) - 4-7: major version (current spec; 0x1) */ - uint8_t ip_ver; /* 0-3: reserved - 4-7: ip version (0x4 = ipv4, 0x6 = ipv6) */ - uint8_t rsvd_1; /* reserved */ - uint8_t max_adv; /* max outstanding Zcopy advertisments (>0) */ - uint32_t r_rcv_size; /* requested size of each remote recv buffer */ - uint32_t l_rcv_size; /* initial size of each local receive buffer */ - uint16_t port; /* local port */ - uint16_t rsvd_2; /* reserved */ - - union { /* source IP address. */ - struct { - uint32_t addr3; /* ipv6 96-127 */ - uint32_t addr2; /* ipv6 64-95 */ - uint32_t addr1; /* ipv6 32-63 */ - uint32_t addr0; /* ipv6 0-31 */ - } ipv6; /* 128bit IPv6 address */ - struct { - uint32_t none2; /* unused 96-127 */ - uint32_t none1; /* unused 64-95 */ - uint32_t none0; /* unused 32-63 */ - uint32_t addr; /* ipv4 0-31 */ - } ipv4; /* 32bit IPv4 address */ - } src; - - union { /* destination IP address. */ - struct { - uint32_t addr3; /* ipv6 96-127 */ - uint32_t addr2; /* ipv6 64-95 */ - uint32_t addr1; /* ipv6 32-63 */ - uint32_t addr0; /* ipv6 0-31 */ - } ipv6; /* 128bit IPv6 address */ - struct { - uint32_t none2; /* unused 96-127 */ - uint32_t none1; /* unused 64-95 */ - uint32_t none0; /* unused 32-63 */ - uint32_t addr; /* ipv4 0-31 */ - } ipv4; /* 32bit IPv4 address */ - } dst; - - uint8_t rsvd_3[28]; /* reserved for future use, and zero'd */ -}; //__attribute__ ((packed)); /* struct msg_hdr_hh */ - -struct msg_hdr_hah { - uint8_t version; /* 0-3: minor version (current spec; 0x1) - 4-7: major version (current spec; 0x1) */ - uint16_t rsvd_1; /* reserved */ - uint8_t max_adv; /* max outstanding Zcopy advertisments (>0) */ - uint32_t l_rcv_size; /* initial size of each local receive buffer */ -#if 0 /* There is a bug in the 1.1 spec. REP message grew by 8 bytes. */ - __u8 rsvd_2[180]; /* reserved for future use, and zero'd (big) */ -#else - uint8_t rsvd_2[172]; /* reserved for future use, and zero'd (big) */ -#endif -}; //__attribute__ ((packed)); /* struct msg_hdr_hah */ - -struct sdp_msg_hello { - struct msg_hdr_bsdh bsdh; /* base sockets direct header */ - struct msg_hdr_hh hh; /* hello message header */ -} ;//__attribute__ ((packed)); /* struct sdp_msg_hello */ - -struct sdp_msg_hello_ack { - struct msg_hdr_bsdh bsdh; /* base sockets direct header */ - struct msg_hdr_hah hah; /* hello ack message header */ -};// __attribute__ ((packed)); /* struct sdp_msg_hello_ack */ - -static inline void sdp_msg_swap_bsdh(struct msg_hdr_bsdh *header) -{ - header->recv_bufs = CL_NTOH16(header->recv_bufs); - header->size = CL_NTOH32(header->size); - header->seq_num = CL_NTOH32(header->seq_num); - header->seq_ack = CL_NTOH32(header->seq_ack); -} - -static inline void sdp_msg_swap_hh(struct msg_hdr_hh *header) -{ - header->r_rcv_size = CL_NTOH32(header->r_rcv_size); - header->l_rcv_size = CL_NTOH32(header->l_rcv_size); - header->port = CL_NTOH16(header->port); - header->src.ipv6.addr0 = CL_NTOH32(header->src.ipv6.addr0); - header->src.ipv6.addr1 = CL_NTOH32(header->src.ipv6.addr1); - header->src.ipv6.addr2 = CL_NTOH32(header->src.ipv6.addr2); - header->src.ipv6.addr3 = CL_NTOH32(header->src.ipv6.addr3); - header->dst.ipv6.addr0 = CL_NTOH32(header->dst.ipv6.addr0); - header->dst.ipv6.addr1 = CL_NTOH32(header->dst.ipv6.addr1); - header->dst.ipv6.addr2 = CL_NTOH32(header->dst.ipv6.addr2); - header->dst.ipv6.addr3 = CL_NTOH32(header->dst.ipv6.addr3); -} - -/* - * sdp_msg_swap_hah - SDP header endian byte swapping - */ -static inline void sdp_msg_swap_hah(struct msg_hdr_hah *header) -{ - header->l_rcv_size = CL_NTOH32(header->l_rcv_size); -} - -#define BASE_LISTEN_ID (CL_CONST64(0x0000000000010000)) - -static inline ib_net64_t -get_service_id_for_port( - ib_net16_t ip_port) -{ - return CL_NTOH64( BASE_LISTEN_ID | ip_port ); -} - - -// CM timeouts - Used for creating the sockets -#define CM_MIN_LOCAL_TIMEOUT (18) -#define CM_LOCAL_TIMEOUT (1) -#define CM_MIN_REMOTE_TIMEOUT (18) -#define CM_REMOTE_TIMEOUT (2) -#define CM_RETRIES 4 - - -#pragma pack(pop) - -#endif H_SDP_MSGS_H - diff --git a/trunk/ulp/sdp/kernel/SdpRecvPool.cpp b/trunk/ulp/sdp/kernel/SdpRecvPool.cpp deleted file mode 100644 index edbacaaf..00000000 --- a/trunk/ulp/sdp/kernel/SdpRecvPool.cpp +++ /dev/null @@ -1,488 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "preCompile.h" - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpRecvPool.tmh" -#endif - - - -RecvPool::RecvPool() -{ - m_RecvSeq = 0; - m_ClientBeingServed = false; - m_CurrentlyPostedRecievedBuffers = 0; - m_CurrentlyAllocated = 0; - m_ClientWaiting = false; - m_DisConnRecieved = false; - m_LocaleAdvertisedBuffers = 0; - m_pSdpSocket = NULL; - m_NumberOfBuffersRecievedWithError = 0; - m_NumberOfBuffersRecievedSuccessfully = 0; -} - -NTSTATUS -RecvPool::Init( - int MaxBuffers, - int MaxConcurrentRecieves, - int MaxMessageSize, - ib_pd_handle_t pd, - ib_qp_handle_t qp, - net32_t lkey, - SdpSocket *pSdpSocket - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"this = 0x%p \n", m_pSdpSocket); - m_MaxBuffers = MaxBuffers; - m_MaxConcurrentRecieves = MaxConcurrentRecieves; - m_MaxMessageSize = MaxMessageSize; - KeInitializeEvent(&m_WaitingClients, NotificationEvent, FALSE); - ASSERT(pd != NULL); - m_pd = pd; - ASSERT(qp != NULL); - m_qp = qp; - ASSERT(lkey != NULL); - m_lkey = lkey; - m_pSdpSocket = pSdpSocket; - - // Allocate all the buffers as continues memory (better be done - // at passive level) - BufferDescriptor *pBufferDescriptor = NULL; - NTSTATUS rc = STATUS_SUCCESS; - - for (int i=0;i < MAX_RECV_PACKETS; i++) { - rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, RECV_BUFFERS_ALLOCATION_TAG); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"BufferDescriptor::AllocateBuffer failed rc=0x%x \n", rc); - goto Cleanup; - } - - m_CurrentlyAllocated++; - - pBufferDescriptor->Reset(); - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - } -Cleanup: - if (!NT_SUCCESS(rc)) { - LIST_ENTRY *item = NULL; - while (m_FreePackets.Size() > 0 ) { - item = m_FreePackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); - } - - } - - return rc; -} - -/* - A buffer was compleated and is being added to the queued list -*/ - -NTSTATUS -RecvPool::RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p pBufferDescriptor = 0x%p sucess = %s\n" - ,m_pSdpSocket, pBufferDescriptor, error ? "false" : "true"); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - - m_CurrentlyPostedRecievedBuffers--; - ASSERT(m_CurrentlyPostedRecievedBuffers >= 0); - - if (error) { - // Not much that we can do in this case (only return the packet) - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - m_NumberOfBuffersRecievedWithError++; - goto Cleanup; - } - ASSERT(m_NumberOfBuffersRecievedWithError == 0); - m_NumberOfBuffersRecievedSuccessfully++; - - // We have recieved a "RAW" buffer, we have to make sure that the buffer - // descriptor is OK. - msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *)pBufferDescriptor->pBuffer; - - ASSERT(pBufferDescriptor->DataStart == 0); - pBufferDescriptor->DataStart = sizeof (msg_hdr_bsdh); - pBufferDescriptor->DataSize = pHeader->size - sizeof msg_hdr_bsdh; - - m_RecvSeq = pHeader->seq_num; - - // Start processing the different messages: - // No metter what the message type is, we can update our credits - - uint16_t rRecvBuf = - pHeader->recv_bufs - - abs ( - (int)m_pSdpSocket->m_SendBufferPool.GetSendSeq()- - (int)pHeader->seq_ack); - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_CREDITS,"SetRemoteRecvBuf rRecvBuf = %d, pHeader->recv_bufs = %d, SendSeq = %d , pHeader->seq_ack = %d\n", - rRecvBuf, - pHeader->recv_bufs, - (int)m_pSdpSocket->m_SendBufferPool.GetSendSeq(), - (int)pHeader->seq_ack); - m_pSdpSocket->m_SendBufferPool.SetRemoteRecvBuf(rRecvBuf); - - // m_DisConnRecieved is the last "real" message that should be recieved - // we might still get credits update - ASSERT(m_DisConnRecieved == false || - (pHeader->mid == SDP_MID_DATA && pHeader->size == sizeof msg_hdr_bsdh)); // BUGBUG: do a real check here - - // ???? Handle more state changes here ???? - if (pHeader->mid != SDP_MID_DATA) { - if (pHeader->mid == SDP_MID_DISCONNECT) { - m_DisConnRecieved = true; - if (m_ClientWaiting) { - KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE ); - m_ClientWaiting = false; - } - } - // This is a message without data, we currently ignore it - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - } else { - - if(pHeader->size > sizeof msg_hdr_bsdh) { - m_FullPackets.InsertTailList(&pBufferDescriptor->BuffersList); - ASSERT(m_FullPackets.Size() <= m_MaxBuffers); - - // we need to notify the client that is waiting - if (m_ClientWaiting) { - KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE ); - m_ClientWaiting = false; - } - } else { - // This is an empty buffer - ASSERT(pHeader->size == sizeof msg_hdr_bsdh); - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - } - } - - // Check if we have to send more credits to the remote side - ASSERT(m_LocaleAdvertisedBuffers > 0); - m_LocaleAdvertisedBuffers--; - - ASSERT(m_CurrentlyPostedRecievedBuffers >= m_LocaleAdvertisedBuffers); - if (m_CurrentlyPostedRecievedBuffers - m_LocaleAdvertisedBuffers > - SDP_RECV_CREDIT_UPDATE) { - rc = m_pSdpSocket->m_SendBufferPool.PostCredits(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"m_SendBufferPool.PostCredits failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - - // Wake up the clients of the send (new credits were added) - rc = m_pSdpSocket->m_SendBufferPool.SendBuffersIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"SendBuffersIfCan failed rc = 0x%x\n", rc ); - goto Cleanup; - } - // We might be able to post a new recieve buffer now - ASSERT(m_CurrentlyPostedRecievedBuffers < m_MaxConcurrentRecieves); - rc = ReceiveIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"RecieveIfCan failed rc = 0x%x\n", rc ); - goto Cleanup; - } -Cleanup: - return rc; - -} - -/* - This function is being called by a thread that wants to do a recieve in order - to have a buffer with the data, that he can copy. - FirstBuffer tells if this is the first buffer that he wants. - If it is true, this means that no other request will be handled before - this client will indicate that he has finished recieving his data. - If an event is returned this means that the caller has to wait on the - event before the request will be staisfied. - - pData is the place that the data should be copied to. CopySize is the number of - requested bytes, while Copied is the number actually copied. - - This function is being called under the lock -*/ -NTSTATUS -RecvPool::GetData( - char *pData, - uint32_t CopySize, - uint32_t *Copied, - KEVENT **ppEvent, - bool FirstBuffer, - bool *pNoMoreData - ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p FirstBuffer = %s\n", m_pSdpSocket, - FirstBuffer ? "TRUE" : "FALSE"); - AssertLocked(); - bool BufferFreed = false; - *Copied = 0; - *pNoMoreData = false; - BufferDescriptor *pBufferDescriptor = NULL; - uint32_t OldDataSize = 0; - - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(*ppEvent == NULL); - - if (m_ClientBeingServed == true && (FirstBuffer != false)) { - // The request can not be staisfied right now. We need to hold it - // until our request is being freed - // BUGBUG: iMPLMENT: create event and put it in the queue. - // This might only happen when there are two threads calling us - ASSERT(FALSE); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if (FirstBuffer == true) { - m_ClientBeingServed = true; - } - - // Can we supply data to the user right now ? - while (*Copied < CopySize) { - if (m_FullPackets.Size()) { - // We have a buffer, we can use it to copy data to the user - LIST_ENTRY *item = m_FullPackets.Head(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - OldDataSize = pBufferDescriptor->DataSize; - if (OldDataSize > CopySize - *Copied) { - // we can only copy part of the buffer - ASSERT(CopySize > *Copied); - rc = pBufferDescriptor->CopyToUser(pData + *Copied, CopySize - *Copied); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"pBufferDescriptor->CopyToUser failed rc = 0x%x\n", rc ); - goto Cleanup; - } - *Copied += CopySize - *Copied; - - } else { - // We copy the entire buffer and remove it - rc = pBufferDescriptor->CopyToUser(pData + *Copied, OldDataSize); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"pBufferDescriptor->CopyToUser failed rc = 0x%x\n", rc ); - goto Cleanup; - } - *Copied += OldDataSize; - m_FullPackets.RemoveHeadList(); - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - BufferFreed = true; - } - - } else { - *pNoMoreData = true; - // If data was already supplied, then we shouldn't wait any more - if ((*Copied > 0) || - (FirstBuffer == false) || - m_DisConnRecieved) { - ASSERT(*ppEvent == NULL); - break; - } - // No buffers available, we have to wait - ASSERT(m_ClientWaiting == false); - KeClearEvent(&m_WaitingClients); - m_ClientWaiting = true; - *ppEvent = &m_WaitingClients; - break; - } - } - - // As data was copyed, it is possibale that we will be able to post more receives - if (BufferFreed) { - ReceiveIfCan(); - } - -Cleanup: - return rc; -} - -VOID -RecvPool::AllowOthersToGet() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p \n", m_pSdpSocket); - ASSERT(m_ClientBeingServed == true); - m_ClientBeingServed = false; - - // BUGBUG: this means that we should free the next waiter (Once we support more - // than one thread). -} - -NTSTATUS -RecvPool::ReceiveIfCan() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL, "this = 0x%p m_CurrentlyPostedRecievedBuffers = %d m_LocaleAdvertisedBuffers = %d\n", - m_pSdpSocket, m_CurrentlyPostedRecievedBuffers, m_LocaleAdvertisedBuffers); - AssertLocked(); - BufferDescriptor *pBufferDescriptor = NULL; - NTSTATUS rc = STATUS_SUCCESS; - uint16_t StartLocaleAdvertisedBuffers = m_LocaleAdvertisedBuffers; - - while (m_CurrentlyPostedRecievedBuffers < m_MaxConcurrentRecieves) { - // do we have a free packet ? - if (m_FreePackets.Size() > 0) { - // we can take a packet from the list - LIST_ENTRY *item = m_FreePackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - } else if (m_CurrentlyAllocated < m_MaxBuffers) { - // We can allocate more buffers - rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, RECV_BUFFERS_ALLOCATION_TAG); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"AllocateBuffer failed rc = 0x%x\n", rc ); - goto Cleanup; - } - m_CurrentlyAllocated++; - } else { - // Couldn't get any more free packets. - break; - } - pBufferDescriptor->Reset(); - - // we can now post the buffer for recieve - rc = PostReceiveBuffer(pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"PostReceiveBuffer failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - if (StartLocaleAdvertisedBuffers <= 2) { - // In this case we have (probably) posted some buffers. We have to notify the - // other side that he has more credits - rc = m_pSdpSocket->m_SendBufferPool.PostCredits(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"m_SendBufferPool.PostCredits failed rc = 0x%x\n", rc ); - goto Cleanup; - } - } - -Cleanup: - return rc; -} - -/* - Currently the implmentation of shutdown should allow it to work, even without - init being called -*/ - -VOID -RecvPool::ShutDown() -{ - // Lock is not taken here, but we should be gurantied that no - // one can be racing us in here - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL,"this = 0x%p \n", m_pSdpSocket); - BufferDescriptor *pBufferDescriptor = NULL; - LIST_ENTRY *item = NULL; - - while (m_FreePackets.Size() > 0 ) { - item = m_FreePackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); - } - - while (m_FullPackets.Size() > 0 ) { - item = m_FullPackets.RemoveHeadList(); - pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); - } -} - -/* This function is called when the user mode has called close socket - If a client is waiting on recieve we free him, he should get an - error on his callback. *** The caller probably has a bug - as one - can't race a closesocket *** -*/ - -VOID -RecvPool::CloseSocket() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_BUFFER_POOL, "this = 0x%p m_WaitingClients = %s waiting buffer = %d\n", - this, - m_ClientWaiting ? "true" : "false", - m_FullPackets.Size() - ); - AssertLocked(); - - if (m_ClientWaiting) { - KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE ); - m_ClientWaiting = false; - } - // The next time our client will try to get data, he will get - // the error -} - -NTSTATUS -RecvPool::PostReceiveBuffer(BufferDescriptor *pBufferDescriptor) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_BUFFER_POOL,"this = 0x%p \n", m_pSdpSocket); - AssertLocked(); - NTSTATUS rc = STATUS_SUCCESS; - - ib_recv_wr_t recv_wr; - recv_wr.p_next = NULL; - recv_wr.wr_id = (uintn_t)pBufferDescriptor; - recv_wr.num_ds = 1; - recv_wr.ds_array = &pBufferDescriptor->ds_array; - - pBufferDescriptor->ds_array.length = pBufferDescriptor->BufferSize; - pBufferDescriptor->ds_array.vaddr = MmGetPhysicalAddress( pBufferDescriptor->pBuffer ).QuadPart; - pBufferDescriptor->ds_array.lkey = m_lkey; - - ib_api_status_t ib_status = ib_post_recv(m_qp, &recv_wr, NULL); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_BUFFER_POOL,"ib_post_recv failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - m_CurrentlyPostedRecievedBuffers++; - -Cleanup: - return rc; - -} - -VOID -RecvPool::AssertLocked() -{ -#if DBG - if (m_pSdpSocket) { - m_pSdpSocket->AssertLocked(); - } -#endif -} - - diff --git a/trunk/ulp/sdp/kernel/SdpRecvPool.h b/trunk/ulp/sdp/kernel/SdpRecvPool.h deleted file mode 100644 index 40e0c44b..00000000 --- a/trunk/ulp/sdp/kernel/SdpRecvPool.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef H_SDP_RECV_POOL_H -#define H_SDP_RECV_POOL_H - -class RecvPool { - -public: - - RecvPool(); - - NTSTATUS Init( - int MaxBuffers, - int MaxConcurrentRecives, - int MaxMessageSize, - ib_pd_handle_t pd, - ib_qp_handle_t qp, - net32_t lkey, - SdpSocket *pSdpSocket - ); - - NTSTATUS GetData( - char *pData, - uint32_t CopySize, - uint32_t *Copied, - KEVENT **ppEvent, - bool FirstBuffer, - bool *pNoMoreData - ); - - VOID AllowOthersToGet(); - - NTSTATUS RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error); - - NTSTATUS ReceiveIfCan(); - - uint32_t GetRecvSeq() { return m_RecvSeq;} - - VOID CloseSocket(); - - VOID ShutDown(); - - uint16_t GetCurrentlyPostedRecievedBuffers() { - return m_CurrentlyPostedRecievedBuffers; - } - - void SetLocaleAdvertisedBuffers(uint16_t LocaleAdvertisedBuffers) { - m_LocaleAdvertisedBuffers = LocaleAdvertisedBuffers; - } - - void UpdateLocaleAdvertisedBuffers() { - m_LocaleAdvertisedBuffers = m_CurrentlyPostedRecievedBuffers; - } -private: - - NTSTATUS PostReceiveBuffer(BufferDescriptor *pBufferDescriptor); - - // Global data about this connection - int m_MaxBuffers; // The maximum number of buffers that we allow for this QP (to be allocated) - int m_MaxConcurrentRecieves; // The total numbers of recvs that are allowd for the QP - int m_MaxMessageSize; // The maximum buffer size that we allow for recieving - - uint16_t m_CurrentlyPostedRecievedBuffers; // Number of buffers that we have posted for recieve and didn't get an answer yet - uint16_t m_LocaleAdvertisedBuffers; // Number of buffers that we have advertised to the remote side (l_advt_bf in linux) - - int m_CurrentlyAllocated; // The number of buffers that we have already allocated - - bool m_ClientBeingServed; // true if we have already started giving buffers to a client - - LinkedList m_FreePackets; // This packets are free and might be used for recieving - LinkedList m_FullPackets; // This packets were filled with data and can be used by the user - - - // TODO: A queue of events for threads that are waiting for buffers. - - // IBAL constants from the main socket structure - // TODO: Should they stay here and be used like this ? - ib_pd_handle_t m_pd; - ib_qp_handle_t m_qp; - net32_t m_lkey; - - // A list of events that the users has to wait on. ???? currently only one - KEVENT m_WaitingClients; // switch to a linked list - bool m_ClientWaiting; - - uint32_t m_RecvSeq; // sequence number of last message received (recv_seq) - - SdpSocket *m_pSdpSocket; - - // This signals that the remote side will not be sending any data any more - bool m_DisConnRecieved; - - // TODO: The two counters bellow are for debug only. move them to be - // declared as such - public: - uint32_t m_NumberOfBuffersRecievedWithError; - uint32_t m_NumberOfBuffersRecievedSuccessfully; - - - VOID AssertLocked(); - -}; - -#endif // H_SDP_RECV_POOL_H - diff --git a/trunk/ulp/sdp/kernel/SdpSocket.cpp b/trunk/ulp/sdp/kernel/SdpSocket.cpp deleted file mode 100644 index 81f6328b..00000000 --- a/trunk/ulp/sdp/kernel/SdpSocket.cpp +++ /dev/null @@ -1,2730 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "Precompile.h" - -#pragma warning(disable: 4244 ) - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpSocket.tmh" -#endif - - -NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack); -NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello); -static NTSTATUS __send_cb2(SdpSocket * pSdpSocket); -static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket); -static NTSTATUS __accept_requests(SdpSocket * pSdpSocket); - -static void AL_API -cm_rej_callback(IN ib_cm_rej_rec_t *p_cm_rej_rec ) -{ - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"dispatch level = %d\n", KeGetCurrentIrql()); - // BUGBUG: This should be used to return error to the connecting side -} - -static void AL_API -cm_rep_callback( - IN ib_cm_rep_rec_t *p_cm_rep_rec ) -{ - SdpSocket *pSocket = (SdpSocket *) p_cm_rep_rec->qp_context; - pSocket->CmRepCallback(p_cm_rep_rec); -} - -static void AL_API -cm_mra_callback( - IN ib_cm_mra_rec_t *p_cm_mra_rec ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"cm_mra_callback called"); - ASSERT(FALSE); -} - -/* - * A user-specified callback that is invoked after receiving a load - * alternate path response message. - */ -static void AL_API -cm_apr_callback( - IN ib_cm_apr_rec_t *p_cm_apr_rec ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"cm_apr_callback called"); - ASSERT(FALSE); -} - -static void AL_API -cm_dreq_callback(IN ib_cm_dreq_rec_t *p_cm_dreq_rec ) -{ - SdpSocket *pSocket = (SdpSocket *) p_cm_dreq_rec->qp_context; - pSocket->CmDreqCallback(p_cm_dreq_rec); -} - -static void AL_API -cm_lap_callback( - IN ib_cm_lap_rec_t *p_cm_lap_rec ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"dispatch level = %d\n", KeGetCurrentIrql()); - ASSERT(FALSE); -} - -void -cm_rtu_callback( - IN ib_cm_rtu_rec_t *p_cm_rtu_rec ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"dispatch level = %d\n", KeGetCurrentIrql()); - // Note - Referance count is not increased here since this is a call - // back, and we are gurantied that shuting down ibal will only end - // after all callbacks are finished. - SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context; - SdpSocket *pListeningSocket = pSocket->m_pListeningSocket; - pListeningSocket->CmRtuCallback(p_cm_rtu_rec); - -} -/* - * A user-specified callback that is invoked after an error has occurred on - * a listen request. - */ -static void AL_API -listen_err_callback( - IN ib_listen_err_rec_t *p_listen_err_rec ) -{ - /* TODO ??????????????*/ - UNUSED_PARAM( p_listen_err_rec ); - ASSERT( 0 ); -} - -void CloseSocketThread(void *pContext) -{ - SdpSocket *pSocket = (SdpSocket *) pContext; - pSocket->CloseSocketThread(); - -} -static void AL_API -cm_req_callback( - IN ib_cm_req_rec_t *p_cm_req_rec ) -{ - // Pass the request to the approperiate socket - SdpSocket *pSocket = (SdpSocket *) p_cm_req_rec->context; - pSocket->CmReqCallback(p_cm_req_rec); -} - -SdpSocket::SdpSocket() -{ - m_CreationFlags = 0; - m_SrcPort = 0; - m_SrcIp = 0; - m_DstPort = 0; - m_DstIp = 0; - - m_SrcPortGuid = 0; - m_SrcCaGuid = 0; - m_ListenHandle = NULL; - - mh_Ca = NULL; - m_pd = NULL; - m_rcq = NULL; - m_scq = NULL; - m_qp = NULL; - m_mr = NULL; - - m_state = SS_IDLE; - m_pListeningSocket = NULL; - - m_CloseSocketCalled = false; - m_ShutdownCalled = false; - m_DisconnectConnectionRecieved = false; - m_pSdpUserFile = NULL; - InitializeListHead(&m_CallBackRequestList); - -} - -VOID SdpSocket::AssertLocked() -{ -#if DBG - m_Lock.AssertLocked(); -#endif -} - -NTSTATUS SdpSocket::Init( - WspSocketIn *pSocketInParam, - WspSocketOut *pSocketOutParam, - SdpUserFile *pSdpUserFile) -{ - NTSTATUS rc = STATUS_SUCCESS; - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - - m_CreationFlags = pSocketInParam->dwFlags; - - m_Lock.Init(__send_cb2, __recv_cb2, __accept_requests ,this); - pSocketOutParam->Errno = 0;// No error - pSocketOutParam->pSocket = this; // give the user a handle to the socket - KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE ); - KeInitializeEvent(&m_DisconectSentEvent, NotificationEvent , FALSE ); - - m_ConnectionList.Init(this); - - // We now allocate the needed structure for the close socket, so that - // we won't be in trouble after the thread was created - m_pCloseSocketThread = new ThreadHandle; - if (m_pCloseSocketThread == NULL) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to allocate new SocketThread this = 0x%p \n",this); - rc = STATUS_NO_MEMORY; - goto Cleanup; - } - - m_pSdpUserFile = pSdpUserFile; - m_pSdpUserFile->AddRef(); - - -Cleanup: - return rc; -} - - -NTSTATUS SdpSocket::AcceptRequests() -{ - // Check if our state allows us to handle send/recv/accept ... - if (m_ShutdownCalled) return STATUS_SHUTDOWN_IN_PROGRESS; - if (m_CloseSocketCalled) return STATUS_HANDLES_CLOSED; // Not the exact code - // But it seems relatively closest - return STATUS_SUCCESS; -} - -NTSTATUS SdpSocket::WSPSend( - WspSendIn *pWspSendIn, - WspSendOut *pWspSendOut, - IRP *pIrp - ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"this = 0x%p size = %d \n",this, pWspSendIn->BufferSize); - - NTSTATUS rc = STATUS_SUCCESS; - BufferDescriptor * pBufferDescriptor = NULL; - bool First = true; - ULONG Coppied = 0; - PRKEVENT pBuffersEvent = NULL; - bool BufferCopied; - NTSTATUS rc1; - - // For zero bytes send we currently don't do anything and return with status - // success - if (pWspSendIn->BufferSize == 0) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"this = 0x%p - zero size send \n",this); - goto Cleanup; - } - - if (!m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - - if ((m_state != SS_CONNECTED)) { - // We can not send now. - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"Can't send now, m_state = %s\n", - SS2String(m_state)); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - pWspSendOut->Errno = WSAENOTCONN; - - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - - // Check if there is already data in the queue, if yes we just - // increase the queue and leave. - - ASSERT(!m_CloseSocketCalled); - rc = m_SendBufferPool.AddToUserBuffers(&BufferCopied, false , pWspSendIn->pData, pWspSendIn->BufferSize,Coppied, pIrp); - ASSERT(rc == STATUS_PENDING || rc == STATUS_SUCCESS); - if (rc == STATUS_PENDING) { - ASSERT(BufferCopied); - // TODO: We already took the lock, and we are in the right context, - // We should probably do some work there - // Data was already copied to the buffer we are done. - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - // No need to complete the IRP, as it will be be deleted - // when all other IRPs will be - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "m_Lock.Unlock() failed rc = 0x%x\n", rc ); - goto Cleanup; - } - // This IRP will be pending (make sure to change this after the unlock) - rc = STATUS_PENDING; - - goto Cleanup; - } - - ASSERT(rc == STATUS_SUCCESS); - ASSERT(BufferCopied == false); - // We now try to copy the data to the internal buffers - - while (Coppied < pWspSendIn->BufferSize) { - - rc = m_SendBufferPool.GetBuffer(&pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_SendBufferPool.GetBuffer failed rc = 0x%x\n", rc ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - - if (pBufferDescriptor == NULL) { - // We don't have a new buffer any more, we store the remaining - // buffer and quit - rc = m_SendBufferPool.AddToUserBuffers( - &BufferCopied, - true , - pWspSendIn->pData, - pWspSendIn->BufferSize, - Coppied, - pIrp); - ASSERT(rc == STATUS_PENDING); - ASSERT(BufferCopied == true); - - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // No need to complete the IRP, as it will be be deleted - // when all other IRPs will be - goto Cleanup; - } - rc = STATUS_PENDING;// This IRP will be pending (make sure to change this after the unlock) - goto Cleanup; - } - // copy the data from the user mode to the buffers - ULONG CopySize = pBufferDescriptor->BufferSize - sizeof msg_hdr_bsdh; - CopySize = min(CopySize, pWspSendIn->BufferSize - Coppied); - - rc = pBufferDescriptor->WriteData(pWspSendIn->pData + Coppied, CopySize); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pBufferDescriptor->WriteData failed rc = 0x%x\n", rc ); - // free the buffer that you have - rc1 = m_SendBufferPool.ReturnBuffer(pBufferDescriptor); - ASSERT(NT_SUCCESS(rc1)); - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - Coppied += CopySize; - - // send the data to the buffer - pBufferDescriptor->SetMid(SDP_MID_DATA); - rc = m_SendBufferPool.AddBufferToQueuedList(pBufferDescriptor); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_SendBufferPool.AddBufferToQueuedList failed rc = 0x%x\n", rc ); - // free the buffer that you have - rc1 = m_SendBufferPool.ReturnBuffer(pBufferDescriptor); - ASSERT(NT_SUCCESS(rc1)); - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } - - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - -Cleanup: - if (NT_SUCCESS(rc) ) { - ASSERT((rc == STATUS_SUCCESS) || (rc == STATUS_PENDING)); - if (rc != STATUS_PENDING) { - pWspSendOut->Errno = 0; - ASSERT(pWspSendIn->BufferSize == Coppied); - pWspSendOut->NumberOfBytesSent = Coppied; - } - } else { - // Make sure that we have the error setted - Shutdown(); - ASSERT(pWspSendOut->Errno != 0); // BUGBUG: Need to make sure that this - if(pWspSendOut->Errno == 0) { - // Some default value - pWspSendOut->Errno = WSAENOBUFS; - } - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "this = 0x%p rc = 0x%x\n",this, rc); - // is indeed the case. - } - return rc; -} - -NTSTATUS -SdpSocket::WSPRecv( - WspRecvIn *pWspRecvIn, - WspRecvOut *pWspRecvOut - ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"this = 0x%p BufferSize = %d\n",this, pWspRecvIn->BufferSize); - - NTSTATUS rc = STATUS_SUCCESS; - bool First = true; - uint32_t Coppied = 0, ThisCopy = 0; - bool Locked = false; - PRKEVENT pBuffersEvent = NULL; - bool NoMoreData; - - if (pWspRecvIn->BufferSize == 0) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"this = 0x%p - zero size recv \n",this); - goto Cleanup; - } - - while (Coppied < pWspRecvIn->BufferSize) { - if ((Locked == false) && !m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - Locked = true; - ASSERT(pBuffersEvent == NULL); - - if ((m_state != SS_CONNECTED && m_state!= SS_CONNECTED_DREP_SENT ) ) { - // We can not recv now. - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "Can't recv now, m_state = %s this = %p\n", - SS2String(m_state), this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - pWspRecvOut->Errno = WSAENOTCONN; - - m_Lock.Unlock(); // Error ignored as this is already an error pass - Locked = false; - goto Cleanup; - } - - rc = m_RecvBufferPool.GetData( - pWspRecvIn->pData + Coppied, - pWspRecvIn->BufferSize - Coppied, - &ThisCopy, - &pBuffersEvent, - First, - &NoMoreData - ); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_RecvBufferPool.GetData failed rc = 0x%x\n", rc ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - Locked = false; - goto Cleanup; - } - Coppied += ThisCopy; - - if (NoMoreData && pBuffersEvent == NULL) { - // this means that there is nothing to copy, and we should return - ASSERT(pBuffersEvent == NULL); - break; - } - - First = false; - - if (pBuffersEvent != NULL) { - // We are told to wait on this event - ASSERT(Coppied < pWspRecvIn->BufferSize); - rc = m_Lock.Unlock(); - Locked = false; - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - - rc = MyKeWaitForSingleObject( - pBuffersEvent, - UserRequest, - UserMode, - FALSE, - NULL - ); - pBuffersEvent = NULL; - if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) { - // BUGBUG: Think what to do here, we should be able to stop the - // connect, and quit (probably shutdown should be enough) - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"MyKeWaitForSingleObject was alerted rc = 0x%x\n", rc ); - rc = STATUS_UNEXPECTED_IO_ERROR; - //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - Shutdown(); - goto Cleanup; - } - // try getting the buffer again - continue; - } - } - ASSERT(Locked == true); - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - - // This should happen only for good path anyway - m_RecvBufferPool.AllowOthersToGet(); -Cleanup: - if (NT_SUCCESS(rc) ) { - pWspRecvOut->Errno = 0; - ASSERT(pWspRecvIn->BufferSize >= Coppied); - pWspRecvOut->NumberOfBytesRecieved = Coppied; - } else { - // Make sure that we have the error setted - ASSERT(pWspRecvOut->Errno != 0); // BUGBUG: Need to make sure that this - pWspRecvOut->NumberOfBytesRecieved = 0; - // is indeed the case. - } - // Currently in any case, the flags are not being used: - pWspRecvOut->dwFlags = 0; - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"this = 0x%p returning %d bytes \n",this, pWspRecvOut->NumberOfBytesRecieved); - return rc; - -} - -NTSTATUS SdpSocket::WSPConnect( - WspConnectIn *pWspConnectIn, - WspConnectOut *pWspConnectOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_api_status_t ib_status; - ib_gid_t DestPortGid; - - ib_path_rec_t path_rec; - ULONG SrcIp = 0; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "this = 0x%p remote addresses ip=%d.%d.%d.%d:%d\n", - this, - (pWspConnectIn->DestIP & 0XFF000000) >> 24, - (pWspConnectIn->DestIP & 0XFF0000) >> 16, - (pWspConnectIn->DestIP & 0XFF00) >> 8, - (pWspConnectIn->DestIP & 0XFF), - pWspConnectIn->DestPort - ); - - if((pWspConnectIn->DestIP == 0) || - (pWspConnectIn->DestPort == 0) || - (pWspConnectIn->SrcIP == 0)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Invalid Addresses"); - pWspConnectOut->Errno = WSAEADDRNOTAVAIL; - goto Cleanup; - } - - // check socket state - m_Lock.Lock();//??? retval - if ((m_state != SS_IDLE)) { - // We can not connect in this state - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "Can't send now, m_state = %s\n", - SS2String(m_state)); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - pWspConnectOut->Errno = WSAENOTCONN; - - m_Lock.Unlock(); //?????retval - goto Cleanup; - - } - - // - // Arp: this means that based on the ARP protocol we should convert the - // IP address into gid. - // - if (m_SrcIp == 0) { - // No explicit bind was done, we use the default addresses - m_SrcIp = pWspConnectIn->SrcIP; - } - if (m_SrcIp == INADDR_LOOPBACK) { - // This is the loopback case, we use the dest IP in order to - // get the port - SrcIp = pWspConnectIn->DestIP; - } else { - SrcIp = m_SrcIp; - } - - // Now that we know the source IP we can decide about the src port - if (m_SrcPort == 0) { - rc = g_pSdpDriver->m_pSdpArp->GetPort(m_SrcIp, &m_SrcPort); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->GetPort failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } else { - // We need to connect to the global table of ports - - } - - rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(SrcIp, &m_SrcPortGuid, &m_SrcCaGuid); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - - rc = g_pSdpDriver->m_pSdpArp->DestPortGidFromMac(m_SrcPortGuid, pWspConnectIn->DestMac, &DestPortGid); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->DestPortGidFromIP failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - - // - // Next step is convert the gid to a path record - // - - // Since this is a function that might wait we do it without the lock - m_state = SS_CONNECTING_QPR_SENT; - m_Lock.Unlock(); //????? - - rc = g_pSdpDriver->m_pSdpArp->QueryPathRecord( m_SrcPortGuid, DestPortGid, &path_rec ); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->QueryPathRecord failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - goto Cleanup; - } - - - // Verify that we are in the correct state (just looking - without the lock) - if (m_state != SS_CONNECTING_QPR_SENT) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"wrong state after QueryPathRecord\n" ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - goto Cleanup; - } - - rc = CreateQp(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"CreateQp failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - goto Cleanup; - } - - // We need to prepare the hello mesage for the CM - sdp_msg_hello hello_msg; - CreateHelloHeader(&hello_msg, pWspConnectIn->DestIP); - // We can now update the number of buffers that we have - m_RecvBufferPool.SetLocaleAdvertisedBuffers(CL_NTOH16(hello_msg.bsdh.recv_bufs)); - - // Create the CM request - ib_cm_req_t cm_req; - CreateCmRequest(&cm_req, &hello_msg, &path_rec, pWspConnectIn->DestPort); - - // Create the event to wait on to the connection request to end: - KeInitializeEvent(&m_ConnectCmCompleteEvent, NotificationEvent , FALSE ); - - m_state = SS_CONNECTING_REQ_SENT; - - ib_status = ib_cm_req( &cm_req ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_req failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - goto Cleanup; - } - - rc = MyKeWaitForSingleObject( - &m_ConnectCmCompleteEvent, - UserRequest, - UserMode, - FALSE, - NULL); - - if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) { - // BUGBUG: Think what to do here, we should be able to stop the - // connect, and quit (probably shutdown should be enough) - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"MyKeWaitForSingleObject was alerted rc = 0x%x\n", rc ); - rc = STATUS_UNEXPECTED_IO_ERROR; - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - Shutdown(); - goto Cleanup; - } - - // - // We have recieved the REP, we send the RTU code - // - - m_state = SS_CONNECTING_REQ_SENT; - - rc = CmSendRTU(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"CmSendRTU failed rc = 0x%x\n", rc ); - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - goto Cleanup; - } - - // we should now complete the request - m_Lock.Lock(); //????? retval - if (m_state == SS_CONNECTED) { - pWspConnectOut->Errno = 0; - ASSERT(rc == STATUS_SUCCESS); - m_Lock.Unlock(); //????? retval - goto Cleanup; - } else { - // There probably was some error or some kind of shutdown, we - // need to return an error. - rc = STATUS_UNEXPECTED_IO_ERROR; - pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - -Cleanup: - // Make sure that success/failure is marked in both places - ASSERT(((pWspConnectOut->Errno == 0) && (NT_SUCCESS(rc))) | - ((pWspConnectOut->Errno != 0) && (!NT_SUCCESS(rc)))); - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"connect is returning %s this = 0x%p\n", - NT_SUCCESS(rc) ? "SUCCESS" : "FAILURE", this); - return rc; - -} - -NTSTATUS -SdpSocket::WSPBind( - WspBindIn *pWspBindIn, - WspBindOut *pWspBindOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "this = 0x%p bind address ip=%d.%d.%d.%d:%d\n", - this, - (pWspBindIn->IP & 0XFF000000) >> 24, - (pWspBindIn->IP & 0XFF0000) >> 16, - (pWspBindIn->IP & 0XFF00) >> 8, - (pWspBindIn->IP & 0XFF), - pWspBindIn->Port - ); - - if (!m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - - /* Verify the state of the socket */ - if( m_state != SS_IDLE) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "socket is in invalid state %s this = 0x%p \n", - SS2String(m_state),this ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - rc = STATUS_INVALID_DEVICE_STATE; - pWspBindOut->Errno = WSAEINVAL; - goto Cleanup; - } - - - /* Check if the ip address is assigned to one of our IBoIB HCA. */ - if( pWspBindIn->IP != INADDR_ANY ) - { - ASSERT(m_SrcCaGuid == NULL); - rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pWspBindIn->IP, &m_SrcPortGuid, &m_SrcCaGuid); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ); - pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } - else - { - m_SrcPortGuid = 0; - } - - if( pWspBindIn->IP != INADDR_ANY ) { - /* Time to allocate our IB QP */ - rc = CreateQp(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"CreateQp failed rc = 0x%x\n", rc ); - pWspBindOut->Errno = WSAENOBUFS; - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } - - // If the src port is 0, we need to allocate a port for the caller. - if (pWspBindIn->Port == 0) { - m_SrcPort = 0; - rc = g_pSdpDriver->m_pSdpArp->GetPort(pWspBindIn->IP, &m_SrcPort); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->GetPort failed rc = 0x%x\n", rc ); - pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } else { - // We have to allocate the needed port in the table??????? - - } - - // Everything went OK - m_SrcPort = pWspBindIn->Port; - m_SrcIp = pWspBindIn->IP; - - m_state = SS_BOUND; - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - -Cleanup: - if (NT_SUCCESS(rc) ) { - pWspBindOut->Errno = 0; - } else { - // Make sure that we have the error setted - ASSERT(pWspBindOut->Errno != 0); // BUGBUG: Need to make sure that this - // is indeed the case. - //??????????? Make sure that we clean this function on exit - } - return rc; - -} - -NTSTATUS SdpSocket::WSPListen( - WspListenIn *pWspListenIn, - WspListenOut *pWspListenOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_cm_listen_t param; - ib_api_status_t ib_status; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p \n",this); - if (!m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - - /* Verify the state of the socket */ - if( m_state != SS_BOUND) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "socket is in invalid state %s this = 0x%p \n", - SS2String(m_state),this); - m_Lock.Unlock(); // Error ignored as this is already an error pass - rc = STATUS_INVALID_DEVICE_STATE; - pWspListenOut->Errno = WSAEINVAL; - goto Cleanup; - } - - m_ConnectionList.SetBackLog(pWspListenIn->backlog); - - // Create the CM request - memset( ¶m, 0, sizeof(param) ); - - ASSERT(m_SrcPort != 0); - param.svc_id = get_service_id_for_port( m_SrcPort); - if( m_SrcPortGuid ) - { - /* The socket is bound to an IP address */ - param.ca_guid = m_SrcCaGuid; - param.port_guid = m_SrcPortGuid; - } - else - { - /* The socket is bound to INADDR_ANY */ - param.ca_guid = IB_ALL_CAS; - param.port_guid = IB_ALL_PORTS; - } - - param.lid = IB_ALL_LIDS; - - /* Currently no compare function ????? - param.p_compare_buffer = (uint8_t *) & socket_info->info.listen.listen_req_param; - param.compare_length = sizeof(struct listen_req_param); - param.compare_offset = offsetof(struct cm_req_params, listen_req_param); - */ - - param.pfn_cm_req_cb = cm_req_callback; - - param.qp_type = IB_QPT_RELIABLE_CONN; - - ASSERT(m_ListenHandle == NULL); - - ib_status = ib_cm_listen( - g_pSdpDriver->m_al_handle , - ¶m, - listen_err_callback, - this, - &m_ListenHandle - ); - - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_listen failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - pWspListenOut->Errno = IbalToWsaError( ib_status ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - - // SUCCESS - change the state - m_state = SS_LISTENING; - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - -Cleanup: - if (NT_SUCCESS(rc) ) { - pWspListenOut->Errno = 0; - } else { - // Make sure that we have the error setted - ASSERT(pWspListenOut->Errno != 0); // BUGBUG: Need to make sure that this - // is indeed the case. - } - return rc; -} - -NTSTATUS -SdpSocket::WSPAccept( - WspAcceptIn *pWspAcceptIn, - WspAcceptOut *pWspAcceptOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - bool Locked = false; - SdpSocket *pNewSocket = NULL; - PRKEVENT pAcceptEvent = NULL; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p \n",this); - - while (true) { - if ((Locked == false) && !m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - Locked = true; - ASSERT(pNewSocket == NULL); - - /* Verify the state of the socket */ - if( m_state != SS_LISTENING) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"socket is in invalid state %s this = 0x%p \n", - SS2String(m_state),this); - m_Lock.Unlock(); // Error ignored as this is already an error pass - Locked = false; - rc = STATUS_INVALID_DEVICE_STATE; - pWspAcceptOut->Errno = WSAEINVAL; - goto Cleanup; - } - - rc = m_ConnectionList.AcceptAReadyConnection(&pNewSocket, &pAcceptEvent); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_ConnectionList.AcceptAReadyConnection failed rc = 0x%x\n", rc ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - Locked = false; - goto Cleanup; - } - - if (pNewSocket != NULL) { - ASSERT(pAcceptEvent == NULL); - break; - } - - ASSERT(pAcceptEvent != NULL); - - // We are told to wait on this event - rc = m_Lock.Unlock(); - Locked = false; - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - - rc = MyKeWaitForSingleObject( - pAcceptEvent, - UserRequest, - UserMode, - FALSE, - NULL - ); - pAcceptEvent = NULL; - if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) { - // BUGBUG: Think what to do here, we should be able to stop the - // connect, and quit (probably shutdown should be enough) - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"MyKeWaitForSingleObject was alerted = 0x%x\n", rc ); - rc = STATUS_UNEXPECTED_IO_ERROR; - //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error - Shutdown(); - goto Cleanup; - } - // try getting the socket again - } - - // I want to copy this data before releasing the lock - ULONG IP = pNewSocket->m_DstIp; - USHORT Port = pNewSocket->m_DstPort; - - ASSERT(Locked == true); - rc = m_Lock.Unlock(); - Locked = false; - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - -Cleanup: - ASSERT(Locked == false); - if (NT_SUCCESS(rc) ) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p returning socket 0x%p \n",this, pNewSocket); - pWspAcceptOut->pAccaptedSocket = pNewSocket; - pWspAcceptOut->IP = IP; - pWspAcceptOut->Port = Port; - pWspAcceptOut->Errno = 0; - // We need to "register" this socket in the global list - - } else { - // Make sure that we have the error setted - ASSERT(pWspAcceptOut->Errno != 0); // BUGBUG: Need to make sure that this - ASSERT(pNewSocket == NULL); - pWspAcceptOut->pAccaptedSocket = NULL; - // is indeed the case. - } - // referance on pNewSocket is not currently released, since we are - // returning them to the next level - return rc; -} - -NTSTATUS -SdpSocket::WSPGetXXXName( - WspGetSockXXIn *pWspGetSockXXIn, - WspGetSockXXOut *pWspGetSockXXOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_api_status_t ib_status; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p \n",this); - rc = m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - pWspGetSockXXOut->Errno = WSAENETDOWN; - goto Cleanup; - } - pWspGetSockXXOut->Errno = 0; - if(pWspGetSockXXIn->LocaleAddress) { - // This is the WSPGetSockName - pWspGetSockXXOut->IP = m_SrcIp; - pWspGetSockXXOut->Port = m_SrcPort; - } else { - // This is the WSPGetPeerName - pWspGetSockXXOut->IP = m_DstIp; - pWspGetSockXXOut->Port = m_DstPort; - } - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - pWspGetSockXXOut->Errno = WSAENETDOWN; - goto Cleanup; - } - -Cleanup: - if (NT_SUCCESS(rc) ) { - pWspGetSockXXOut->Errno = 0; - } else { - // Make sure that we have the error setted - ASSERT(pWspGetSockXXOut->Errno != 0); - // is indeed the case. - } - return rc; - - -} - - - -/* - CloseSocket is probably one of the most complicated winsock APIs. - Our current implmentation will be the default implmentation always. - This means that the call is always non-blocking, and it is always gracefully. - As a result, the remote side should return 0 on it's last read, and we should - send a DisConn mesage. - - Well, gracefull or not, the other side is not gourantied to call recieve and - we can't wait for ever. As a result a timer will be created and after 40 - seconds, we close abortively. - - If a different thread is waiting on some event (read, send or accept), we will - stop the blocking operation, and complete that wait with error. - - A special case to handle, is a socket that was created and after a while - closed. In this case, there is nothing really to do, and we will use the - same thread to close the socket. - - In the case of an error, an abortive close will be done (using the CM). - - There will be the following flag, telling the state of the socket. - - 1) CloseSocket called. - - So basicly, on close, we will do the following: - 1) Stop all blocking operations (send, recieve, accept). (ofcourse, new ones - are not allowed anymore) - 2) Create the DisConn packet and send it. (if needed) - 3) Start the timer, and wait for all the sends to end. - 4) When ever a send is complited, we will check if this a shutdown in progress - and we can close the socket. - - The "real" work of closing the socket will be done by the Shutdown function, - that will be called either by the CloseSocket when the logic is finished. - -*/ - -NTSTATUS -SdpSocket::WSPCloseSocket( - WspSocketCloseIn *pWspSocketCloseIn, - WspSocketCloseOut *pWspSocketCloseOut - ) -{ - NTSTATUS rc = STATUS_SUCCESS; - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p state = %s \n",this, SS2String(m_state)); - OBJECT_ATTRIBUTES attr; - HANDLE ThreadHandle; - - if (!m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Failed to lock this = 0x%p \n",this); - rc = STATUS_SHUTDOWN_IN_PROGRESS; - goto Cleanup; - } - - /* Verify the state of the socket */ - if(m_state == SS_IDLE) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"socket is in idle state this = 0x%p \n", - this); - m_Lock.Unlock(); // Error ignored as this is already a Shutdown pass - Shutdown(); - pWspSocketCloseOut->Errno = 0; - goto Cleanup; - } - - // This will force that no more calls will be allowed - ASSERT(m_CloseSocketCalled == FALSE); // If this is not the case - // We shouldn't be able to take the lock - m_CloseSocketCalled = true; - - // notify to all "subclients" to free all waiting clients - // and also return cancell on all IRPs - m_RecvBufferPool.CloseSocket(); - m_SendBufferPool.CloseSocket(); - m_ConnectionList.CloseSocket(); - - if (m_state == SS_CONNECTED) { - // Need to send the DisConn message to the remote side and wait - rc = m_SendBufferPool.PostDisConn(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_SendBufferPool.PostDisConn failed rc = 0x%x\n", rc ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - goto Cleanup; - } - } else { - // Already set the event, so that the created thread won't have to wait - // for anything - KeSetEvent( &m_DisconectSentEvent, IO_NO_INCREMENT, FALSE ); - } - - // We will now create a thread that will be resposible for the - // destruction of this socket - AddRef(); - - /* Create a new thread, storing both the handle and thread id. */ - InitializeObjectAttributes( &attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL ); - - rc = PsCreateSystemThread( - &ThreadHandle, - THREAD_ALL_ACCESS, - &attr, - NULL, - NULL, - ::CloseSocketThread, - this - ); - - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"PsCreateSystemThread failed rc = 0x%x\n", rc ); - m_Lock.Unlock(); // Error ignored as this is already an error pass - // The thread wasn't created so we should remove the refferance - Release(); - goto Cleanup; - } - - ASSERT(m_pCloseSocketThread != NULL); - // Convert the thread into a handle - rc = ObReferenceObjectByHandle( - ThreadHandle, - THREAD_ALL_ACCESS, - NULL, - KernelMode, - &m_pCloseSocketThread->ThreadObject, - NULL - ); - ASSERT(rc == STATUS_SUCCESS); // According to MSDN, must succeed if I set the params - - rc = ZwClose(ThreadHandle); - ASSERT(NT_SUCCESS(rc)); // Should always succeed - - g_pSdpDriver->AddThread(m_pCloseSocketThread); - m_pCloseSocketThread = NULL; // Will be delated when the callback thread is deleted - - rc = m_Lock.Unlock(); - if (rc == STATUS_HANDLES_CLOSED) { - // shutdown in progress is fine since we have started the shutdown ... - rc = STATUS_SUCCESS; - } - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - goto Cleanup; - } - -Cleanup: - if (NT_SUCCESS(rc) ) { - pWspSocketCloseOut->Errno = 0; - } else { - // Make sure that we have the error setted - ASSERT(pWspSocketCloseOut->Errno != 0); // BUGBUG: Need to make sure that this - // is indeed the case. (also check if error was already signaled) - // In the current model, we call shutdown in any case (to kill the socket) - Shutdown(); - } - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "this = 0x%p returning Errno = %d\n", - this , pWspSocketCloseOut->Errno); - - - return rc; -} - -/* - This function is supposed to wait for the send to compleate - and then to kill the socket. - -*/ - - -VOID SdpSocket::DisconectSentEvent() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "this = 0x%p\n",this); - KeSetEvent( &m_DisconectSentEvent, IO_NO_INCREMENT, FALSE ); -} - -/* - This is the "CloseSocket" thread call back. - This thread waits WAIT_TO_SOCKET_SHUTDOWN seconds for tht send to complete - and then it kills the socket abortively. -*/ -VOID SdpSocket::CloseSocketThread() -{ - NTSTATUS rc = STATUS_SUCCESS; - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n",this); - - // wait for the last thread to end. - LARGE_INTEGER WaitTime; - - WaitTime = TimeFromLong(WAIT_TO_SOCKET_SHUTDOWN * 10 * 1000000); - rc = MyKeWaitForSingleObject( - &m_DisconectSentEvent, - Executive, - KernelMode, - FALSE, - &WaitTime - ); - - if (rc == STATUS_TIMEOUT) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Wait failed with time out\n"); - } - - ASSERT(NT_SUCCESS(rc)); - ASSERT(rc == STATUS_SUCCESS || rc == STATUS_TIMEOUT);// || rc == STATUS_USER_APC); //???????? what to do - - Shutdown(); - - // Everything done - the threads releases the last referance - // and kills itself - Release(); - PsTerminateSystemThread(STATUS_SUCCESS); - - // Do I get here ? - ASSERT(FALSE); - -} - -NTSTATUS SdpSocket::CmSendRTU() -{ - // This is only valid in connect. - // We might also be in shutdown, but nothing else currently - - ib_api_status_t ib_status; - NTSTATUS rc = STATUS_SUCCESS; - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p \n", this); - - if (m_state != SS_CONNECTING_REQ_SENT) { - // There was some error, we can release the waiting thread. - // The error will be handled there - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"this = 0x%p invalid state %s\n", this, SS2String(m_state)); - rc = STATUS_UNEXPECTED_IO_ERROR; - goto Cleanup; - } - - /* - * check Hello Header Ack, to determine if we want - * the connection. - */ - - rc = sdp_cm_hello_ack_check(&m_hello_ack); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"sdp_cm_hello_ack_check failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - int MaxMessageSize = min(m_hello_ack.hah.l_rcv_size, MAX_SEND_BUFFER_SIZE); - - rc = m_SendBufferPool.Init(MAX_SEND_PACKETS, SDP_QP_ATTRIB_SQ_DEPTH, MaxMessageSize, m_pd, m_qp, m_lkey, this); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_SendBufferPool.Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - rc = m_RecvBufferPool.Init(MAX_RECV_PACKETS, QP_ATTRIB_RQ_DEPTH, MaxMessageSize, m_pd, m_qp, m_lkey, this); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_RecvBufferPool.Init failed rc = 0x%x\n", rc ); - goto Cleanup; - } - m_SendBufferPool.SetRemoteRecvBuf(m_hello_ack.bsdh.recv_bufs); - -#if 0 - /* - * read remote information - */ - conn->send_size = hello_ack->hah.l_rcv_size; - conn->r_max_adv = hello_ack->hah.max_adv; - conn->r_recv_bf = hello_ack->bsdh.recv_bufs; - conn->recv_seq = hello_ack->bsdh.seq_num; - conn->advt_seq = hello_ack->bsdh.seq_num; - - conn->d_qpn = event->param.rep_rcvd.remote_qpn; - /* - * The maximum amount of data that can be sent to the remote - * peer is the smaller of the local and remote buffer sizes, - * minus the size of the message header. - */ - conn->send_size = min((u16)sdp_buff_pool_buff_size(), - (u16)conn->send_size) - SDP_MSG_HDR_SIZE; - -#endif - - ib_cm_rtu_t cm_rtu; - - memset( &cm_rtu, 0, sizeof(cm_rtu) ); - - cm_rtu.access_ctrl = IB_AC_RDMA_READ | IB_AC_RDMA_WRITE | IB_AC_LOCAL_WRITE; - -#if 0 // Do we want to keep it - // Bug in TAVOR - cm_rtu.sq_depth = QP_ATTRIB_SQ_DEPTH; - cm_rtu.rq_depth = QP_ATTRIB_RQ_DEPTH; -#endif - - cm_rtu.pfn_cm_apr_cb = cm_apr_callback; - cm_rtu.pfn_cm_dreq_cb = cm_dreq_callback; - - ib_status = ib_cm_rtu( m_cm_handle_t, &cm_rtu ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_rtu failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - // We are now connected - // How should this be locked ?? - m_state = SS_CONNECTED; - - // we now arm the CQs - ib_status = ib_rearm_cq(m_rcq, FALSE); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - ib_status = ib_rearm_cq(m_scq, FALSE); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - // We now start the recieve processing - - rc = m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - rc = m_RecvBufferPool.ReceiveIfCan(); //??? error - m_Lock.Unlock(); // error ???? - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_RecvBufferPool.ReceiveIfCan failed rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - return rc; -} - - -VOID SdpSocket::CmRepCallback(IN ib_cm_rep_rec_t *p_cm_rep_rec) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - - if (m_state != SS_CONNECTING_REQ_SENT) { - // This is not the state that we waited for, not much that we can - // do. (This might happen in shutdown) - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Not the expacted state %s\n", SS2String(m_state)); - ASSERT(FALSE); - return; - } - - // We need to store the params and signal the event - sdp_msg_hello_ack *hello_ack = (sdp_msg_hello_ack *)p_cm_rep_rec->p_rep_pdata; - m_hello_ack = *hello_ack; - m_cm_handle_t = p_cm_rep_rec->h_cm_rep; - - KeSetEvent(&m_ConnectCmCompleteEvent, IO_NO_INCREMENT, FALSE); -} - -VOID -SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - net64_t SrcCaGuid; - ib_net64_t SrcPortGuid; - ib_api_status_t ib_status; - SdpSocket *pNewSocket = NULL; - - sdp_msg_hello *msg_hello = (sdp_msg_hello *)p_cm_req_rec->p_req_pdata; - - rc = sdp_cm_hello_check(msg_hello); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"sdp_cm_hello_ack_check failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - // Take the lock and verify the state - rc = m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - if (m_state != SS_LISTENING) { - // This is not the state that we waited for, we drop the request - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Not the expacted state %s\n", SS2String(m_state)); - ASSERT(FALSE); - goto ErrorLocked; - } - - // Check that we haven't passed the backlog for this connection - if (m_ConnectionList.IsFull()) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"Dropping the connection, because of a backlog that is too small\n"); - goto ErrorLocked; - } - - // Create a new socket for this request - pNewSocket = new SdpSocket; - if (pNewSocket == NULL) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"new pNewSocket failed\n"); - goto ErrorLocked; - } - - // Code here is a little dirty to allow us to use the existing infrastructure - WspSocketIn SocketInParam; - WspSocketOut SocketOutParam; - SocketInParam.dwFlags = 0; - rc = pNewSocket->Init(&SocketInParam, &SocketOutParam, m_pSdpUserFile); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket.Init()"); - goto ErrorLocked; - } - ASSERT(SocketOutParam.Errno == 0); - ASSERT(SocketOutParam.pSocket == pNewSocket); - - // Connect the new socket to it's creator - ASSERT(pNewSocket->m_pListeningSocket == NULL); - pNewSocket->m_pListeningSocket = this; - pNewSocket->m_pListeningSocket->AddRef(); - - /* - * save hello parameters. - */ - pNewSocket->m_state = SS_REQ_RECV; //?????? do we really need this state????? - - pNewSocket->m_SrcIp = msg_hello->hh.dst.ipv4.addr; - ASSERT(m_SrcPort != 0); - pNewSocket->m_SrcPort = m_SrcPort; - pNewSocket->m_DstIp = msg_hello->hh.src.ipv4.addr; - pNewSocket->m_DstPort = msg_hello->hh.port; - - // Initiate parameters based on what we recieve from the remote side -// pNewSocket->send_size = msg_hello->hh.l_rcv_size; ??? MAX_Message_size when calling init on the buffers ??? -//??? pNewSocket->r_max_adv = msg_hello->hh.max_adv; ??????????? -//???? pNewSocket->r_recv_bf = msg_hello->bsdh.recv_bufs; <= m_pSdpSocket->m_SendBufferPool.SetRemoteRecvBuf(rRecvBuf); -//??? pNewSocket->recv_seq = msg_hello->bsdh.seq_num; -//??? pNewSocket->advt_seq = msg_hello->bsdh.seq_num; - - /* - * The maximum amount of data that can be sent to the remote - * peer is the smaller of the local and remote buffer sizes, - * minus the size of the message header. - */ -// conn->send_size = min((u16)sdp_buff_pool_buff_size(), -// (u16)conn->send_size) - SDP_MSG_HDR_SIZE; ?????????? - - // We will now allocate our QP. - - rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pNewSocket->m_SrcIp, &SrcPortGuid, &SrcCaGuid); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ); - goto ErrorLocked; - } - - if (pNewSocket->m_SrcCaGuid == 0) { - pNewSocket->m_SrcCaGuid = SrcCaGuid; - } else { - ASSERT(pNewSocket->m_SrcCaGuid == CL_NTOH64(p_cm_req_rec->primary_path.sgid.unicast.interface_id)); - } - - // MAke sure that the port that was recieved muches the one that we - // get based on the source IP. - if (SrcPortGuid != p_cm_req_rec->primary_path.sgid.unicast.interface_id) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Recieved guid is not what we have expected\n" ); - ASSERT(0); - goto ErrorLocked; - } - - rc = pNewSocket->CreateQp(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket.CreateQp()"); - goto ErrorLocked; - } - - // We will now call init on the sender and the reciever - int MaxMessageSize = min(msg_hello->hh.l_rcv_size, MAX_SEND_BUFFER_SIZE); - - rc = pNewSocket->m_SendBufferPool.Init(MAX_SEND_PACKETS, SDP_QP_ATTRIB_SQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_SendBufferPool.Init failed rc = 0x%x\n", rc ); - goto ErrorLocked; - } - - rc = pNewSocket->m_RecvBufferPool.Init(MAX_RECV_PACKETS, QP_ATTRIB_RQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_RecvBufferPool.Init failed rc = 0x%x\n", rc ); - goto ErrorLocked; - } - pNewSocket->m_SendBufferPool.SetRemoteRecvBuf(msg_hello->bsdh.recv_bufs); - - // It won't be used, but I want to make sure that there won't be - // problems later - pNewSocket->m_ConnectionList.Init(pNewSocket); - -#if 0 // ??????????????????????? - /* - * Save connect request info for QP modify in cm_accept(). - */ - conn->d_lid = event->param.req_rcvd.primary_path->dlid; - conn->s_lid = event->param.req_rcvd.primary_path->slid; - conn->d_qpn = event->param.req_rcvd.remote_qpn; - - conn->path_mtu = event->param.req_rcvd.primary_path->mtu; - /* - * inherit listener properties - */ - sdp_cm_listen_inherit(listen_conn, conn); - /* - * initiate a CM response message. - */ -#endif - - // - // Send the ib_cm_rep message to the remote side - // - ib_cm_rep_t cm_rep; - - memset( &cm_rep, 0, sizeof(cm_rep) ); - - cm_rep.qp_type = IB_QPT_RELIABLE_CONN; - cm_rep.h_qp = pNewSocket->m_qp; -// TODO: Add more cababilities once we start using RDMA -// cm_rep.access_ctrl = IB_AC_RDMA_READ | IB_AC_RDMA_WRITE | IB_AC_LOCAL_WRITE; - cm_rep.access_ctrl = IB_AC_LOCAL_WRITE; -#if 0 - // Bug in TAVOR - cm_rep.sq_depth = QP_ATTRIB_SQ_DEPTH; - cm_rep.rq_depth = QP_ATTRIB_RQ_DEPTH; -#endif - // We need to prepare the hello mesage for the CM - sdp_msg_hello_ack hello_ack_msg; - CreateHelloAckHeader(&hello_ack_msg); - - pNewSocket->m_RecvBufferPool.SetLocaleAdvertisedBuffers(CL_NTOH16(hello_ack_msg.bsdh.recv_bufs)); - - cm_rep.p_rep_pdata = (uint8_t *) &hello_ack_msg; - cm_rep.rep_length = sizeof(hello_ack_msg); - - cm_rep.init_depth = QP_ATTRIB_INITIATOR_DEPTH; - cm_rep.target_ack_delay = 10; - cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED; - cm_rep.flow_ctrl = p_cm_req_rec->flow_ctrl; - cm_rep.rnr_nak_timeout = QP_ATTRIB_RNR_NAK_TIMEOUT; - cm_rep.rnr_retry_cnt = p_cm_req_rec->rnr_retry_cnt; - cm_rep.pfn_cm_mra_cb = cm_mra_callback; - cm_rep.pfn_cm_rej_cb = cm_rej_callback; - cm_rep.pfn_cm_rtu_cb = cm_rtu_callback; - cm_rep.pfn_cm_lap_cb = cm_lap_callback; - cm_rep.pfn_cm_dreq_cb = cm_dreq_callback; - - ib_status = ib_cm_rep( p_cm_req_rec->h_cm_req, &cm_rep ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_rep failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto ErrorLocked; - } - - // Add this socket to the list of sockets ?????? should this also be done on errors ???? - rc = m_ConnectionList.AddConnectionToReplySent(pNewSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket.Init()"); - goto ErrorLocked; - } - - rc = pNewSocket->m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket.Init()"); - goto ErrorLocked; - } - - rc = pNewSocket->m_RecvBufferPool.ReceiveIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket.Init()"); - pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path - goto ErrorLocked; - } - - // we now arm the CQs (after that a call back might happen) - ib_status = ib_rearm_cq(pNewSocket->m_rcq, FALSE); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path - goto ErrorLocked; - } - - ib_status = ib_rearm_cq(pNewSocket->m_scq, FALSE); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto ErrorLocked; - } - - // Sucess - we can now release the lock and update our state - pNewSocket->m_state = SS_REP_SENT; - - rc = pNewSocket->m_Lock.Unlock(); // ???????? Error is ignored, since this is already an error path - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pNewSocket->m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - goto ErrorLocked; - } - - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - } - -Cleanup: - if (!NT_SUCCESS(rc)) { - // BUGBUG: We need to send a rej here - } - if (pNewSocket != NULL) { - pNewSocket->Release(); - } - return; - -ErrorLocked: - // Previous rc doesn't mater as this function is void - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - } - goto Cleanup; - -} - -VOID -SdpSocket::CmRtuCallback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec) -{ - NTSTATUS rc = STATUS_SUCCESS; - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - - SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context; - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p pSocket = 0x%p\n", this, pSocket); - - // In order to make our model more consistent we increase the refcount here. - // (This is not a must since this is a callback and we are gurantied that the last - // callback won't happen untill we free IBAL) - pSocket->AddRef(); - - - // Take the lock and verify the state - rc = m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - if (m_state != SS_LISTENING) { - // This is not the state that we waited for, we drop the request - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Not the expacted state %s\n", SS2String(m_state)); - ASSERT(FALSE); // Can this happen on shutdown ? - goto ErrorLocked; - } - - // First step is to verify that we have the new socket - rc = m_ConnectionList.VerifyConnictionInReplySent(pSocket); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_ConnectionList.GetConnection failed (got a call back on a not existing connection)"); - ASSERT(FALSE); - goto ErrorLocked; - } - - // Next step is to move the new socket to the SS_CONNECTED state - rc = pSocket->m_Lock.LockRc(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto ErrorLocked; - } - if (pSocket->m_state != SS_REP_SENT) { - ASSERT(pSocket->m_state == SS_REP_SENT); - // This is not the expected state (probably shutdown). - // we should signal an error also on the one that is waiting - pSocket->m_Lock.Unlock(); // Error is ignored since this is already - // an error path - pSocket->Shutdown(); - rc = STATUS_UNEXPECTED_IO_ERROR; - goto ErrorLocked; - } - - pSocket->m_state = SS_CONNECTED; - - m_ConnectionList.MoveConnectionFromReplyToReady(pSocket); - rc = pSocket->m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"pSocket->m_Lock.Lock failed rc = 0x%x\n", rc ); - goto ErrorLocked; - } - - // if needed we will free the one that is waiting - m_ConnectionList.FreeWaitingIfCan(); - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - - if (pSocket != NULL) { - pSocket->Release(); - } - - // Who should take care of the errors that were found here (if found)???????? - return; - -ErrorLocked: - // Previous rc doesn't mater as this function is void - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - } - goto Cleanup; - -} - -VOID -SdpSocket::CmDreqCallback(IN ib_cm_dreq_rec_t *p_cm_dreq_rec) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p, dispatch level = %d\n", this, KeGetCurrentIrql()); - ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); - NTSTATUS rc = STATUS_SUCCESS; - ib_cm_drep_t cm_drep; - ib_api_status_t ib_status; - bool Locked; - - - // Take the lock and verify the state - rc = m_Lock.LockRc(); - // BUGBUG: It seems that even when the lock fails we should send - // drep - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Lock failed rc = 0x%x\n", rc ); - goto Cleanup; - } - - if (m_state != SS_CONNECTED) { - // This is not the state that we waited for, we drop the request - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Not the expacted state %s\n", SS2String(m_state)); - ASSERT(FALSE); // Can this happen on shutdown ? - goto ErrorLocked; - } - - // We should send a DREP now - memset( &cm_drep, 0, sizeof(cm_drep) ); - - ib_status = ib_cm_drep( p_cm_dreq_rec->h_cm_dreq, &cm_drep ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_drep failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto ErrorLocked; - } - - // last step is to change our state (this will affect close socket for example) - m_state = SS_CONNECTED_DREP_SENT; - - // We should close the connection know ??????????/ - - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - } - - //??????? abortive close the connection - -Cleanup: - - // Who should take care of the errors that were found here (if found)???????? - return; - -ErrorLocked: - // Previous rc doesn't mater as this function is void - rc = m_Lock.Unlock(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_Lock.Unlock()"); - // BUGBUG: who is responsibale for the cleanup ??????? - } - goto Cleanup; - -} - - -VOID -SdpSocket::__recv_cb1( - IN const ib_cq_handle_t h_cq, - IN void *cq_context ) -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"__recv_cb1\n"); - - SdpSocket *pSocket = (SdpSocket *) cq_context; - pSocket->m_Lock.SignalCB(RECV_CB_CALLED); -} - -NTSTATUS -SdpSocket::recv_cb() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"this = 0x%p \n", this); - NTSTATUS rc = STATUS_SUCCESS, rc1 = STATUS_SUCCESS; - ib_api_status_t ib_status; - ib_wc_t *p_free, *p_wc1; - uint32_t pkt_cnt, recv_cnt = 0; - size_t i; - BufferDescriptor *pBufferDescriptor = NULL; - - for( i = 0; i < QP_ATTRIB_RQ_DEPTH; i++ ) - m_RecvComplitionWC[i].p_next = &m_RecvComplitionWC[i + 1]; - m_RecvComplitionWC[QP_ATTRIB_RQ_DEPTH - 1].p_next = NULL; - - do - { - /* If we get here, then the list of WCs is intact. */ - p_free = m_RecvComplitionWC; - - ib_status = ib_poll_cq( m_rcq, &p_free, &p_wc1 ); - if( (ib_status != IB_SUCCESS) && (ib_status != IB_NOT_FOUND) ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_poll_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - if (ib_status == IB_NOT_FOUND) { - // Nothing to do in this case - ASSERT(NT_SUCCESS(rc)); - goto Cleanup; - } - - ASSERT (ib_status == IB_SUCCESS); - ib_wc_t *p_wc; - for( p_wc = p_wc1; p_wc; p_wc = p_wc->p_next ) { - ASSERT( p_wc->status == IB_WCS_SUCCESS || p_wc->status == IB_WCS_WR_FLUSHED_ERR); // BUGBUG: Can there be other errors here ??? - if (p_wc->status == IB_WCS_WR_FLUSHED_ERR) { - // We have an error, but we still need to return the packet to the caller - pBufferDescriptor = (BufferDescriptor *)p_wc->wr_id; - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"p_wc->status == IB_WCS_WR_FLUSHED_ERR \n" ); - // we can not handle it, but we can and should return it to the pool of recieved buffers - rc1 = m_RecvBufferPool.RecievedBuffer(pBufferDescriptor, true); - ASSERT(rc1 == STATUS_SUCCESS); // return with error can not fail - UpdateRc(&rc, rc1); - continue; - } - if (p_wc->status == IB_WCS_SUCCESS) { - int len = p_wc->length; - pBufferDescriptor = (BufferDescriptor *)p_wc->wr_id; - ASSERT(len >= sizeof msg_hdr_bsdh); - if (len < sizeof msg_hdr_bsdh) { - // This is a message that is not big enough - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Recieved a message with a buffer that is too short len = %d\n", len ); - // we can not handle it, but we can and should return it to the pool of recieved buffers - rc1 = m_RecvBufferPool.RecievedBuffer(pBufferDescriptor, true); - ASSERT(rc1 == STATUS_SUCCESS); // return with error can not fail - UpdateRc(&rc, rc1); - continue; - } - - msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *)pBufferDescriptor->pBuffer; - sdp_msg_swap_bsdh(pHeader); - ASSERT(pHeader->size >= 0x10); - if (len != pHeader->size) { - // This is a message that is not formated well - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Recieved a message with a len != pHeader->size = %d : %d\n", len , pHeader->size ); - // we can not handle it, but we can and should return it to the pool of recieved buffers - rc1 = m_RecvBufferPool.RecievedBuffer(pBufferDescriptor, true); - ASSERT(rc1 == STATUS_SUCCESS); // return with error can not fail - UpdateRc(&rc, rc1); - continue; - } - // BUGBUG: currently we only handle this messages, we should handle - // them better ??????????? - ASSERT(pHeader->mid == 0xff || - pHeader->mid == 2 || - pHeader->mid == 7); - - rc1 = m_RecvBufferPool.RecievedBuffer(pBufferDescriptor, false); - if (!NT_SUCCESS(rc1)) { - // We have an error, but we should continue, or we will have a leak - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"m_RecvBufferPool.RecievedBuffer failed rc = 0x%x\n", rc1 ); - UpdateRc(&rc, rc1); - continue; - } - } - } - - } while( !p_free ); - - // Rearm after filtering -Cleanup: - if (NT_SUCCESS(rc)) { - ib_status = ib_rearm_cq(m_rcq, FALSE ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - // get out of this function - } - } - - return rc; - -} - - -// TODO: Clear the callback functions mess -void -SdpSocket::__send_cb1( - IN const ib_cq_handle_t h_cq, - IN void *cq_context ) -{ - SdpSocket *pSocket = (SdpSocket *) cq_context; - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"called this = 0x%p\n", pSocket ); - pSocket->m_Lock.SignalCB(SEND_CB_CALLED); -} - - -// This function is here so it's addresses can be taken -static NTSTATUS __send_cb2(SdpSocket * pSdpSocket) -{ - return pSdpSocket->send_cb(); -} - -// This function is here so it's addresses can be taken -static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket) -{ - return pSdpSocket->recv_cb(); -} - -static NTSTATUS __accept_requests(SdpSocket * pSdpSocket) -{ - return pSdpSocket->AcceptRequests(); -} - -NTSTATUS SdpSocket::send_cb() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET,"called this =0x%p\n", this); - NTSTATUS rc = STATUS_SUCCESS, rc1 = STATUS_SUCCESS, rc2 = STATUS_SUCCESS; - AssertLocked(); - ib_api_status_t ib_status; - ib_wc_t *p_wc, *p_free; - size_t i; - BufferDescriptor *pBufferDescriptor = NULL; - - for( i = 0; i < SDP_QP_ATTRIB_SQ_DEPTH; i++ ) { - m_SendComplitionWC[i].p_next = &m_SendComplitionWC[i + 1]; - } - m_SendComplitionWC[SDP_QP_ATTRIB_SQ_DEPTH - 1].p_next = NULL; - - do - { - p_free = m_SendComplitionWC; - ib_status = ib_poll_cq( m_scq, &p_free, &p_wc ); - ASSERT( ib_status == IB_SUCCESS || ib_status == IB_NOT_FOUND); - if (ib_status == IB_NOT_FOUND) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET,"ib_poll_cq returned IB_NOT_FOUND, this =0x%p\n", this); - break; - } - if (ib_status != IB_SUCCESS) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_poll_cq failed ib_status=%d, this =0x%p\n", ib_status,this); - ASSERT(ib_status == IB_INVALID_CQ_HANDLE || ib_status == IB_NOT_FOUND); - rc = IB2Status(ib_status); - goto Cleanup; - } - - while( p_wc ) - { - ASSERT( p_wc->wc_type == IB_WC_SEND ); - pBufferDescriptor = (BufferDescriptor*)(uintn_t)p_wc->wr_id; - m_SendBufferPool.m_NumberOfBytesSentAndAcked++; - - rc2 = m_SendBufferPool.ReturnBuffer(pBufferDescriptor); - UpdateRc(&rc1, rc2); // We remember the error here and continue to avoid leaks - switch( p_wc->status ) - { - case IB_WCS_SUCCESS: - // Nothing to do here - break; - - case IB_WCS_WR_FLUSHED_ERR: - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "Flushed send completion. this =0x%p\n", this); - // Intentainly fall down - default: - SDP_PRINT( TRACE_LEVEL_ERROR, SDP_SOCKET, "Send failed with %s\n", - ib_get_wc_status_str( p_wc->status )); - m_Lock.SignalError(IB2Status(ib_status)); - } - - p_wc = p_wc->p_next; - } - /* If we didn't use up every WC, break out. */ - } while( !p_free ); - if (!NT_SUCCESS(rc1)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "Error was detected on ReturnBuffer rc1 = 0x%x\n", rc1 ); - ASSERT(NT_SUCCESS(rc)); - rc = rc1; - goto Cleanup; - } - - /* Rearm the CQ. */ - ib_status = ib_rearm_cq(m_scq, FALSE ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "ib_rearm_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - /* Resume any sends awaiting resources. */ - rc = m_SendBufferPool.SendBuffersIfCan(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "m_SendBufferPool.Init SendBuffersIfCan rc = 0x%x\n", rc ); - goto Cleanup; - } - -Cleanup: - return rc; - -} - - -// BUGBUG: This code is based on __cq_event, find out what it realy does -static void -__cq_event1( - IN ib_async_event_rec_t *p_event_rec ) -{ - ASSERT(FALSE); - UNUSED_PARAM( p_event_rec ); - ASSERT( p_event_rec->context ); - /* Place holder for proper error handler. */ - ASSERT( p_event_rec->code == IB_AE_UNKNOWN ); -} - - -// Based on __qp_event - do we need it? -static void -__qp_event1( - IN ib_async_event_rec_t *p_event_rec ) -{ - UNUSED_PARAM( p_event_rec ); - ASSERT( p_event_rec->context ); - /* Place holder for proper error handler. */ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"Async QP event: %d\n", p_event_rec->code); - ASSERT( p_event_rec->code == IB_AE_UNKNOWN ); -} - - -// This currently works only for the connect -NTSTATUS SdpSocket::CreateQp() -{ - NTSTATUS rc = STATUS_SUCCESS; - ib_cq_create_t cq_create; - ib_qp_create_t qp_create; - ib_api_status_t ib_status; - ib_phys_create_t phys_create; - ib_phys_range_t phys_range; - uint64_t vaddr; - net32_t rkey; - - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - ASSERT(m_SrcCaGuid != 0); - /* Open the CA. */ - ib_status = ib_open_ca( - g_pSdpDriver->m_al_handle, - m_SrcCaGuid, - NULL, - this, - &mh_Ca - ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_open_ca failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - /* Allocate the PD. */ - ib_status = ib_alloc_pd( - mh_Ca, - IB_PDT_NORMAL, - this, - &m_pd - ); - - if( ib_status != IB_SUCCESS ) - { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_alloc_pd failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - /* Allocate receive CQ. */ - cq_create.size = QP_ATTRIB_RQ_DEPTH; - cq_create.pfn_comp_cb = __recv_cb1; - cq_create.h_wait_obj = NULL; - - ib_status = ib_create_cq( - mh_Ca, - &cq_create, - this, - __cq_event1, - &m_rcq - ); - - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_create_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - /* Allocate send CQ. */ - cq_create.size = SDP_QP_ATTRIB_SQ_DEPTH; - cq_create.pfn_comp_cb = SdpSocket::__send_cb1; - - ib_status = ib_create_cq( - mh_Ca, - &cq_create, - this, - __cq_event1, - &m_scq - ); - - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_create_cq failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - - /* Allocate the QP. */ - cl_memclr( &qp_create, sizeof(qp_create) ); - qp_create.qp_type = IB_QPT_RELIABLE_CONN; - qp_create.rq_depth = QP_ATTRIB_RQ_DEPTH; - qp_create.rq_sge = QP_ATTRIB_RQ_SGE; /* To support buffers spanning pages. */ - qp_create.h_rq_cq = m_rcq; - qp_create.sq_depth = SDP_QP_ATTRIB_SQ_DEPTH; - //TODO: Figure out the right number of SGE entries for sends. - qp_create.sq_sge = QP_ATTRIB_SQ_SGE; - qp_create.h_sq_cq = m_scq; - qp_create.sq_signaled = TRUE; - ib_status = ib_create_qp( m_pd, &qp_create, this, __qp_event1, &m_qp ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_create_qp failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } -#if DBG - /* Query the QP so we can get our QPN. */ - ib_qp_attr_t qp_attr; - ib_status = ib_query_qp( - m_qp, &qp_attr ); - if( ib_status != IB_SUCCESS ) - { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_query_qp failed ib_status = 0x%d\n", ib_status ); - // ignore the error, this is only needed for debug - } - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"QP number is %x\n", CL_NTOH32(qp_attr.num)); -#endif - - const net64_t MEM_REG_SIZE = 0xFFFFFFFFFFFFFFFF; - /* Register all of physical memory */ - phys_create.length = MEM_REG_SIZE; - phys_create.num_ranges = 1; - phys_create.range_array = &phys_range; - phys_create.buf_offset = 0; - phys_create.hca_page_size = PAGE_SIZE; - phys_create.access_ctrl = IB_AC_LOCAL_WRITE; - phys_range.base_addr = 0; - phys_range.size = MEM_REG_SIZE; - vaddr = 0; - ib_status = ib_reg_phys( - m_pd, - &phys_create, - &vaddr, - &m_lkey, - &rkey, - &m_mr ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_reg_phys failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - goto Cleanup; - } - -Cleanup: - // In the case of failure the mess will be cleaned on - // shutdown - // TODO: Need to make a beter cleanup here - return rc; - -} - -VOID SdpSocket::CreateHelloHeader( - sdp_msg_hello *hello_msg, - ULONG DestIp - - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - ASSERT(DestIp != 0); - ASSERT(m_SrcPort != 0); - ASSERT(m_SrcIp != 0); - - memset(hello_msg, 0, sizeof(struct sdp_msg_hello)); - hello_msg->bsdh.recv_bufs = QP_ATTRIB_RQ_DEPTH; //????conn->l_advt_bf; - hello_msg->bsdh.flags = SDP_MSG_FLAG_NON_FLAG; - hello_msg->bsdh.mid = SDP_MID_HELLO; - hello_msg->bsdh.size = sizeof(struct sdp_msg_hello); - hello_msg->bsdh.seq_num = m_SendBufferPool.GetAndIncreaseSendSeq();//conn->send_seq; ??? - hello_msg->bsdh.seq_ack = m_RecvBufferPool.GetRecvSeq();//conn->advt_seq; ??? - - hello_msg->hh.max_adv = QP_ATTRIB_RQ_DEPTH;// ??? conn->l_max_adv; - hello_msg->hh.ip_ver = SDP_MSG_IPVER; - hello_msg->hh.version = SDP_MSG_VERSION; - hello_msg->hh.r_rcv_size = MAX_RECV_BUFFER_SIZE;//???conn->recv_size; - hello_msg->hh.l_rcv_size = MAX_RECV_BUFFER_SIZE;//???conn->recv_size; - hello_msg->hh.port = m_SrcPort; - hello_msg->hh.src.ipv4.addr = m_SrcIp; - hello_msg->hh.dst.ipv4.addr = DestIp; - - /* - * endian swap - */ - sdp_msg_swap_bsdh(&hello_msg->bsdh); - sdp_msg_swap_hh(&hello_msg->hh); - -} - -VOID SdpSocket::CreateHelloAckHeader( - sdp_msg_hello_ack* hello_ack_msg - ) -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"called this = 0x%p\n", this); - - memset(hello_ack_msg, 0, sizeof(struct sdp_msg_hello_ack)); - hello_ack_msg->bsdh.recv_bufs = QP_ATTRIB_RQ_DEPTH; //????conn->l_advt_bf; - hello_ack_msg->bsdh.flags = SDP_MSG_FLAG_NON_FLAG; - hello_ack_msg->bsdh.mid = SDP_MID_HELLO_ACK; - hello_ack_msg->bsdh.size = sizeof(struct sdp_msg_hello_ack); - hello_ack_msg->bsdh.seq_num = m_SendBufferPool.GetAndIncreaseSendSeq();//conn->send_seq; ??? - hello_ack_msg->bsdh.seq_ack = m_RecvBufferPool.GetRecvSeq();//conn->advt_seq; ??? - - hello_ack_msg->hah.max_adv = QP_ATTRIB_RQ_DEPTH;// ??? conn->l_max_adv; - hello_ack_msg->hah.version = SDP_MSG_VERSION; - hello_ack_msg->hah.l_rcv_size = MAX_RECV_BUFFER_SIZE;//???conn->recv_size; - - /* - * endian swap - */ - sdp_msg_swap_bsdh(&hello_ack_msg->bsdh); - sdp_msg_swap_hah(&hello_ack_msg->hah); - - -} - - -VOID SdpSocket::CreateCmRequest( - ib_cm_req_t *cm_req, - sdp_msg_hello *hello_msg, - ib_path_rec_t *path_rec, - USHORT DestPort - ) -{ - - memset( cm_req, 0, sizeof(ib_cm_req_t) ); - cm_req->qp_type = IB_QPT_RELIABLE_CONN; - cm_req->h_qp = m_qp; - cm_req->p_primary_path = path_rec; - cm_req->p_alt_path = NULL; - cm_req->svc_id = get_service_id_for_port(DestPort ); - cm_req->p_req_pdata = (uint8_t *) hello_msg; - cm_req->req_length = sizeof(sdp_msg_hello); - - // Caution: From here we live the linux code, as it was in: gen2 - sdp_cm_path_complete - cm_req->max_cm_retries = CM_RETRIES; - cm_req->resp_res = 4;//???????? what are this??? QP_ATTRIB_RESPONDER_RESOURCES; - cm_req->init_depth = 4;//?????QP_ATTRIB_INITIATOR_DEPTH; - - cm_req->remote_resp_timeout = - ib_path_rec_pkt_life( path_rec ) + CM_REMOTE_TIMEOUT; - if( cm_req->remote_resp_timeout > 0x1F ) - cm_req->remote_resp_timeout = 0x1F; - else if( cm_req->remote_resp_timeout < CM_MIN_REMOTE_TIMEOUT ) - cm_req->remote_resp_timeout = CM_MIN_REMOTE_TIMEOUT; - - cm_req->flow_ctrl = TRUE; /* HCAs must support end-to-end flow control. */ - - cm_req->local_resp_timeout = - ib_path_rec_pkt_life( path_rec ) + CM_LOCAL_TIMEOUT; - if( cm_req->local_resp_timeout > 0x1F ) - cm_req->local_resp_timeout = 0x1F; - else if( cm_req->local_resp_timeout < CM_MIN_LOCAL_TIMEOUT ) - cm_req->local_resp_timeout = CM_MIN_LOCAL_TIMEOUT; - - cm_req->rnr_nak_timeout = 6;//???QP_ATTRIB_RNR_NAK_TIMEOUT; - cm_req->rnr_retry_cnt = 6;//????QP_ATTRIB_RNR_RETRY; - cm_req->retry_cnt = 6;//????QP_ATTRIB_RETRY_COUNT; - - cm_req->pfn_cm_req_cb = NULL; - cm_req->pfn_cm_mra_cb = cm_mra_callback; - cm_req->pfn_cm_rej_cb = cm_rej_callback; - cm_req->pfn_cm_rep_cb = cm_rep_callback; -} - - -VOID SdpSocket::UsersThreadCallBack(bool Send) -{ - NTSTATUS rc = STATUS_SUCCESS; - - if (!m_Lock.Lock()) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "Failed to lock this = 0x%p \n",this); - // Error is ignored, as it is a callback path, socket is already at an error state - goto Cleanup; - } - if (Send) { - InitializeListHead(&m_CallBackRequestList); - rc = m_SendBufferPool.UsersThreadCallBack(); - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "m_SendBufferPool.UsersThreadCallBack failed this = 0x%p, rc = 0x%x \n", - this, rc); - m_Lock.Unlock(); // Error is ignored, as this is already an error path - Shutdown(); - goto Cleanup; - } - - } - - rc = m_Lock.Unlock(); // Error is ignored, as it is a callback path - if (!NT_SUCCESS(rc)) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "m_Lock.Unlock failed this = 0x%p, rc = 0x%x \n", - this, rc); - Shutdown(); - goto Cleanup; - } - -Cleanup: - return; -} - -// static -VOID SdpSocket::ShutdownCB(VOID* pContext) -{ - SdpSocket *pSocket = (SdpSocket *) pContext; - KeSetEvent(&pSocket->m_ShutdownCompleteEvent, IO_NO_INCREMENT, FALSE);; - -} - -// This is just a wrapper for some operations that have to be done for the code bellow -// It will probably be converted to a macro -VOID WaitForShutdownEvent(KEVENT *ShutdownCompleteEvent) -{ - NTSTATUS rc = STATUS_SUCCESS; - - LARGE_INTEGER WaitTime; - // Why are we waiting with timeout? obviously we should wait forever - // and if this is the case, there is a bug *SOMEWHERE ELSE* - // Still I wait WAIT_TO_SOCKET_SHUTDOWN seconds and believe that the user - // will like me more If I do quit and let the application close - - WaitTime = TimeFromLong(WAIT_TO_SOCKET_SHUTDOWN * 10 * 1000000); - - rc = MyKeWaitForSingleObject( - ShutdownCompleteEvent, - Executive, - KernelMode, - FALSE, - &WaitTime - ); - - if (rc == STATUS_TIMEOUT) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"Wait failed with time out\n"); - ASSERT(FALSE); - } - - ASSERT(NT_SUCCESS(rc)); - ASSERT(rc == STATUS_SUCCESS || rc == STATUS_TIMEOUT);// || rc == STATUS_USER_APC); //???????? what to do - //???????? the wait fails - KeClearEvent(ShutdownCompleteEvent); -} - -/* - This function is called when the usercallback thread has detected - that the user thread is dead, or when we have a IRP_MJ_CLEANUP. - In this case, if CloseSocket was called, we don't do anything - (since there is alreadya thread that is garantied to close it) and on - all other cases, we close it abortively. -*/ - -VOID SdpSocket::DyingProcessDetected() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "called this = 0x%p\n", this); - m_Lock.Lock(true); //????? verify must succeed - if (m_CloseSocketCalled) { - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "this = 0x%p m_CloseSocketCalled, letting it finish his job\n", this); - m_Lock.Unlock(); // Error is ignored since this is already - // shutdown call - return; - } - m_Lock.Unlock(); // Error is ignored since this is already - // shutdown call - Shutdown(); -} - -VOID SdpSocket::Shutdown() -{ - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "called this = 0x%p\n", this); - - NTSTATUS rc = STATUS_SUCCESS; - ib_api_status_t ib_status; - ib_qp_mod_t qp_mod; - - if (m_ShutdownCalled) { - // Since this variable is always changing from false to true - // we can check it without the lock. Since there is no memory - // barier, this test is not true for multiple enviorments, but it - // still makes the shutodwn reentrent - return; - } - // now take the lock and test again - - m_Lock.Lock(true); //????? verify must succeed - if (m_ShutdownCalled) { - // Already handled - m_Lock.Unlock(); // Error is ignored since this is already - // shutdown call - return; - } - m_ShutdownCalled = true; - m_Lock.Unlock(); - - // - // Here we start a list of operations that once comlpeated, - // should force that no complition exists anymore - // Although we are not holding the lock, they will not be able to - // lock it. This means that they will try to take it and fail - - if (m_ListenHandle != NULL) { - ib_status = ib_cm_cancel( m_ListenHandle, ShutdownCB ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_cm_cancel failed ib_status = 0x%d\n", ib_status ); - rc = IB2Status(ib_status); - } else { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - m_ListenHandle = NULL; - } - } - - m_ConnectionList.Shutdown(); - - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"111111%p\n", this); - - if (m_qp != NULL) { - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"222222%p\n", this); - - cl_memclr( &qp_mod, sizeof(ib_qp_mod_t) ); - qp_mod.req_state = IB_QPS_ERROR; - ib_status = ib_modify_qp( m_qp, &qp_mod ); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_modify_qp failed ib_status = 0x%d\n", ib_status ); - ASSERT(FALSE); - // We are probably going to leak, but we have to continue - } - - ib_status = ib_destroy_qp(m_qp, ShutdownCB); - //m_qp = NULL; - if(ib_status == IB_SUCCESS) { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - } else { - ASSERT(ib_status == IB_SUCCESS); - // If this is not the case, then we could have probably being - // closing a different socket, which is very bad. - // To give things a chance to work without shutdown, I'll continue - } - } - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"333333%p\n", this); - - if (m_scq != NULL) { - ib_status = ib_destroy_cq(m_scq, ShutdownCB); - //???ASSERT(ib_status == IB_SUCCESS); - if(ib_status == IB_SUCCESS) { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - } - //?????m_scq = NULL; - } - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"444444%p\n", this); - - if (m_rcq != NULL) { - ib_status = ib_destroy_cq(m_rcq, ShutdownCB); - //???ASSERT(ib_status == IB_SUCCESS); - if(ib_status == IB_SUCCESS) { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - } - //??????m_rcq = NULL; - - } - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"555555%p\n", this); - if (m_pd != NULL) { - ib_status = ib_dealloc_pd(m_pd, ShutdownCB); - //???ASSERT(ib_status == IB_SUCCESS); - if(ib_status == IB_SUCCESS) { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - } - //?????m_pd = NULL; - - } - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"666666%p\n", this); - - if (mh_Ca != NULL) { - ib_status = ib_close_ca(mh_Ca, ShutdownCB); - //ASSERT(ib_status == IB_SUCCESS); - if(ib_status == IB_SUCCESS) { - WaitForShutdownEvent(&m_ShutdownCompleteEvent); - } - //?????mh_Ca = NULL; - - } - - // No compleations should exist any more - - if (m_pListeningSocket != NULL) { - m_pListeningSocket->Release(); - m_pListeningSocket = NULL; - } - - if (m_pCloseSocketThread != NULL) { - delete m_pCloseSocketThread; - m_pCloseSocketThread = NULL; - } - - // Now that all ibal operations have finished we can free the memory - m_SendBufferPool.ShutDown(); - m_RecvBufferPool.ShutDown(); - - if (m_pSdpUserFile != NULL) { - m_pSdpUserFile->RemoveSocket(this); - m_pSdpUserFile->Release(); - m_pSdpUserFile = NULL; - } - -/* - Memory reagion probably cleans when the other handles are closed - if (m_mr != NULL) { - ib_status = ib_dereg_mr(m_mr); - if( ib_status != IB_SUCCESS ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET,"ib_dereg_mr failed ib_status = 0x%d\n", ib_status ); - ASSERT( ib_status == IB_SUCCESS ); - } - m_mr = NULL; - } -*/ - -} - -/* - * sdp_cm_hello_ack_check - validate the hello ack header - */ -NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack) -{ - /* - * endian swap - */ - sdp_msg_swap_bsdh(&hello_ack->bsdh); - sdp_msg_swap_hah(&hello_ack->hah); - /* - * validation and consistency checks - */ - if (hello_ack->bsdh.size != sizeof(struct sdp_msg_hello_ack)) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello ack, size mismatch. (2) <%d:%d>", - hello_ack->bsdh.size, - sizeof(struct sdp_msg_hello_ack)); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if (SDP_MID_HELLO_ACK != hello_ack->bsdh.mid) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello ack, unexpected message. <%d>", - hello_ack->bsdh.mid); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if (hello_ack->hah.max_adv <= 0) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello ack, bad zcopy advertisment. <%d>", - hello_ack->hah.max_adv); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if ((0xF0 & hello_ack->hah.version) != (0xF0 & SDP_MSG_VERSION)) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello ack, version mismatch. <%d:%d>", - ((0xF0 & hello_ack->hah.version) >> 4), - ((0xF0 & SDP_MSG_VERSION) >> 4)); - return STATUS_UNEXPECTED_IO_ERROR; - } - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "Hello Ack BSDH <%04x:%02x:%02x:%08x:%08x:%08x>", - hello_ack->bsdh.recv_bufs, - hello_ack->bsdh.flags, - hello_ack->bsdh.mid, - hello_ack->bsdh.size, - hello_ack->bsdh.seq_num, - hello_ack->bsdh.seq_ack); - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "Hello Ack HAH <%02x:%02x:%08x", - hello_ack->hah.max_adv, - hello_ack->hah.version, - hello_ack->hah.l_rcv_size); - - return STATUS_SUCCESS; -} - -NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello) -{ - /* - * endian swap - */ - sdp_msg_swap_bsdh(&msg_hello->bsdh); - sdp_msg_swap_hh(&msg_hello->hh); - /* - * validation and consistency checks - */ - - if (msg_hello->bsdh.size != sizeof(struct sdp_msg_hello)) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello msg size mismatch. (2) <%d:%d>", - msg_hello->bsdh.size, - sizeof(struct sdp_msg_hello)); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if (SDP_MID_HELLO != msg_hello->bsdh.mid) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello msg unexpected ID. <%d>", - msg_hello->bsdh.mid); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if (msg_hello->hh.max_adv <= 0) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello msg, bad zcopy count <%d>", - msg_hello->hh.max_adv); - return STATUS_UNEXPECTED_IO_ERROR; - } - - if ((0xF0 & msg_hello->hh.version) != (0xF0 & SDP_MSG_VERSION)) { - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello msg, version mismatch. <%d:%d>", - ((0xF0 & msg_hello->hh.version) >> 4), - ((0xF0 & SDP_MSG_VERSION) >> 4)); - return STATUS_UNEXPECTED_IO_ERROR; - } -#ifdef _SDP_MS_APRIL_ERROR_COMPAT - if ((SDP_MSG_IPVER & 0x0F) != (msg_hello->hh.ip_ver & 0x0F)) -#else - if ((SDP_MSG_IPVER & 0xF0) != (msg_hello->hh.ip_ver & 0xF0)) { -#endif - SDP_PRINT(TRACE_LEVEL_WARNING, SDP_SOCKET, "hello msg, ip version mismatch. <%d:%d>", - msg_hello->hh.ip_ver, SDP_MSG_IPVER); - return STATUS_UNEXPECTED_IO_ERROR; - } - - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "Hello BSDH <%04x:%02x:%02x:%08x:%08x:%08x>", - msg_hello->bsdh.recv_bufs, - msg_hello->bsdh.flags, - msg_hello->bsdh.mid, - msg_hello->bsdh.size, - msg_hello->bsdh.seq_num, - msg_hello->bsdh.seq_ack); - SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET, "Hello HH <%02x:%02x:%02x:%08x:%08x:%04x:%08x:%08x>", - msg_hello->hh.max_adv, - msg_hello->hh.ip_ver, - msg_hello->hh.version, - msg_hello->hh.r_rcv_size, - msg_hello->hh.l_rcv_size, - msg_hello->hh.port, - msg_hello->hh.src.ipv4.addr, - msg_hello->hh.dst.ipv4.addr); - - return STATUS_SUCCESS; -} - diff --git a/trunk/ulp/sdp/kernel/SdpSocket.h b/trunk/ulp/sdp/kernel/SdpSocket.h deleted file mode 100644 index 2f477828..00000000 --- a/trunk/ulp/sdp/kernel/SdpSocket.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -/* -This class is being used to truck all the user objects that are being -created per user mode dll (each dll opens a handle to the driver once) - -It keeps a list of all the objects so we know when to remove them. - -*/ - -#ifndef _SDP_SOCKET_H -#define _SDP_SOCKET_H - - -const int MAX_SEND_BUFFER_SIZE = 1*4096; // This is the maximum send packet size - -const int MAX_RECV_BUFFER_SIZE = 1*4096; // This is the maximum send packet size -const int MAX_SEND_PACKETS = 200; // This is the maximum number of packets allocated per send -const int MAX_RECV_PACKETS = 200; // This is the maximum number of packets allocated per send - - -const short SDP_QP_ATTRIB_SQ_DEPTH = 64; -const short QP_ATTRIB_SQ_SGE = 1; /* Set based on inline data requirements */ -//#define QP_ATTRIB_RESPONDER_RESOURCES 4 -const short QP_ATTRIB_INITIATOR_DEPTH = 4; -//#define QP_ATTRIB_RETRY_COUNT 6 -//#define QP_ATTRIB_RNR_RETRY 6 -const short QP_ATTRIB_RNR_NAK_TIMEOUT = 6; - -const short WAIT_TO_SOCKET_SHUTDOWN = 40; // The time to wait for a socket to complete - // it's shutdown before we become brutal -/* - * TODO: During testing, the switch has been observed to post - * 12 receive buffers. It would be nice to know what the max is. - */ -const short QP_ATTRIB_RQ_DEPTH = 64;//64 -#define QP_ATTRIB_RQ_SGE 1 -const int SDP_RECV_CREDIT_UPDATE = 20; // send credit update to the remote - // side. - -/* Number of entries in a CQ */ -#define IB_CQ_SIZE (QP_ATTRIB_SQ_DEPTH + QP_ATTRIB_RQ_DEPTH + 1) - -enum SocketStates { - SS_IDLE, - SS_CONNECTING_QPR_SENT, // QPR = Query path record - SS_CONNECTING_REQ_SENT, - SS_CONNECTING_RTU_SENT, - SS_CONNECTED, - SS_BOUND, - SS_LISTENING, - SS_REQ_RECV, //???? not really used ???? - SS_REP_SENT, - SS_CONNECTED_DREP_SENT //??? not really used -}; - // Plesae note that shutdwon and close socket is being done - // through flags - -void cm_rtu_callback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec ); - - -class SdpSocket : public RefCountImpl { - - friend void cm_rtu_callback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec ); - friend class ConnectionList; - -private: - - SocketStates m_state; - - // This flags are being Initiated when the socket is being - // created - ULONG m_CreationFlags; - - USHORT m_SrcPort; - ULONG m_SrcIp; - - USHORT m_DstPort; - ULONG m_DstIp; - - SdpLock m_Lock; - - - // A handle to the ca that is being used (in connect) and its guid - ib_ca_handle_t mh_Ca; - net64_t m_SrcCaGuid; // The guid of the CA that is used - ib_net64_t m_SrcPortGuid; // The guid of the port that is used - ib_pd_handle_t m_pd; - ib_cq_handle_t m_rcq; - - ib_cq_handle_t m_scq; - - ib_qp_handle_t m_qp; - - ib_mr_handle_t m_mr; - - net32_t m_lkey; - - // This handle is used if this is a socket that is listening for new connections - ib_listen_handle_t m_ListenHandle; - - // If this socket was created fron a listening socket, this is a - // pointer to the "mother socket" - SdpSocket* m_pListeningSocket; - - // If this socket is in a listners list of socket, this is the place that is - // used for puting it in the list - LIST_ENTRY m_ListeningSocketList; - - - KEVENT m_ConnectCmCompleteEvent; - KEVENT m_ShutdownCompleteEvent; - KEVENT m_DisconectSentEvent; - - ib_wc_t m_SendComplitionWC[SDP_QP_ATTRIB_SQ_DEPTH]; - ib_wc_t m_RecvComplitionWC[QP_ATTRIB_RQ_DEPTH]; - - // The following three falgs are used to shutdown a socket - bool m_CloseSocketCalled; - bool m_ShutdownCalled; - bool m_DisconnectConnectionRecieved; - - ThreadHandle* m_pCloseSocketThread; - - SdpUserFile *m_pSdpUserFile; - - static VOID __send_cb1( - IN const ib_cq_handle_t h_cq, - IN void *cq_context ); - - static VOID __recv_cb1( - IN const ib_cq_handle_t h_cq, - IN void *cq_context ); - -public: - - BufferPool m_SendBufferPool; - RecvPool m_RecvBufferPool; - ConnectionList m_ConnectionList; - - LIST_ENTRY m_CallBackRequestList;// Used by the call back request thread to hold the request - - - SdpSocket(); - - ~SdpSocket() { - //SDP_PRINT(TRACE_LEVEL_INFORMATION, SDP_SOCKET,"this = 0x%p\n", this); - } - - NTSTATUS Init( - WspSocketIn *pSocketInParam, - WspSocketOut *pSocketOutParam, - SdpUserFile *pSdpUserFile - ); - - NTSTATUS WSPConnect( - WspConnectIn *pWspConnectIn, - WspConnectOut *pWspConnectOut - ); - - NTSTATUS WSPSend( - WspSendIn *pWspSendIn, - WspSendOut *pWspSendOut, - IRP *pIrp - ); - - NTSTATUS WSPRecv( - WspRecvIn *pWspRecvIn, - WspRecvOut *pWspRecvOut - ); - - NTSTATUS WSPBind( - WspBindIn *pWspBindIn, - WspBindOut *pWspBindOut - ); - - NTSTATUS WSPListen( - WspListenIn *pWspListenIn, - WspListenOut *pWspListenOut - ); - - NTSTATUS WSPAccept( - WspAcceptIn *pWspAcceptIn, - WspAcceptOut *pWspAcceptOut - ); - - NTSTATUS WSPGetXXXName( - WspGetSockXXIn *pWspGetSockXXIn, - WspGetSockXXOut *pWspGetSockXXOut - ); - - NTSTATUS WSPCloseSocket( - WspSocketCloseIn *pWspSocketCloseIn, - WspSocketCloseOut *pWspSocketCloseOut - ); - - VOID DyingProcessDetected(); - - VOID Shutdown(); - - static VOID ShutdownCB(VOID* pContext); - - NTSTATUS AcceptRequests(); - - NTSTATUS CreateQp(); - - NTSTATUS CmSendRTU(); - - VOID CreateHelloHeader( - sdp_msg_hello *hello_msg, - ULONG DestIp - ); - - VOID CreateHelloAckHeader( - sdp_msg_hello_ack* hello_ack_msg - ); - - VOID CreateCmRequest( - ib_cm_req_t *cm_req, - sdp_msg_hello *hello_msg, - ib_path_rec_t *path_rec, - USHORT DestPort - ); - - NTSTATUS RequestCallBack() { - AssertLocked(); - ASSERT(IsListEmpty(&m_CallBackRequestList)); - return m_pSdpUserFile->RequestCallBack(&m_CallBackRequestList); - } - - VOID UsersThreadCallBack(bool Send); - - VOID CmRepCallback(IN ib_cm_rep_rec_t *p_cm_rep_rec); - VOID CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec); - VOID CmRtuCallback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec); - VOID CmDreqCallback(IN ib_cm_dreq_rec_t *p_cm_dreq_rec); - - VOID CloseSocketThread(); - - VOID DisconectSentEvent(); - - SocketStates GetState() {return m_state;}; - - // Two varibales that are needed for passing REP data - struct sdp_msg_hello_ack m_hello_ack; - ib_cm_handle_t m_cm_handle_t; // BUGBUG: Check how this is used / locked - - NTSTATUS send_cb(); - NTSTATUS recv_cb(); - - // Used to allow the user file to remember us - LIST_ENTRY m_UserFileList; - - - - static char * SS2String(SocketStates state) { - switch (state) { - case SS_IDLE : return "SS_IDLE"; - case SS_CONNECTING_QPR_SENT : return "SS_CONNECTING_QPR_SENT"; - case SS_CONNECTING_REQ_SENT : return "SS_CONNECTING_REQ_SENT"; - case SS_CONNECTING_RTU_SENT : return "SS_CONNECTING_RTU_SENT"; - case SS_CONNECTED : return "SS_CONNECTED"; - case SS_BOUND : return "SS_BOUND"; - case SS_LISTENING : return "SS_LISTENING"; - case SS_REQ_RECV : return "SS_REQ_RECV"; - case SS_REP_SENT : return "SS_REP_SENT"; - case SS_CONNECTED_DREP_SENT : return "SS_CONNECTED_DREP_SENT"; - default : - ASSERT(FALSE); - - } - return "Unknown state"; - } - - - - VOID AssertLocked(); -}; - -#endif // _SDP_SOCKET_H - diff --git a/trunk/ulp/sdp/kernel/SdpTrace.cpp b/trunk/ulp/sdp/kernel/SdpTrace.cpp deleted file mode 100644 index 1fcbdf82..00000000 --- a/trunk/ulp/sdp/kernel/SdpTrace.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "Precompile.h" -#include -#include -#include - -#if !defined(EVENT_TRACING) - -const int g_SdpDbgLevel = SDP_WARN; -//const int g_SdpDbgLevel = SDP_TRACE; -//const int g_SdpDbgLevel = SDP_DEBUG; - - -#if DBG -//int g_SdpDbgLevel = TRACE_LEVEL_WARNING; -uint32_t g_SdpDbgLevel = TRACE_LEVEL_INFORMATION; -//int g_SdpDbgLevel = TRACE_LEVEL_VERBOSE; -uint32_t g_SdpDbgFlags= SDP_API; -#endif - -VOID -SDP_PRINT ( - IN ULONG lvl, - IN ULONG flags, - IN PCCHAR msg, - ... - ) - -/*++ - -Routine Description: - - Debug print for the sample driver. - -Arguments: - - DebugPrintLevel - print level between 0 and 3, with 3 the most verbose - -Return Value: - - None. - - --*/ - { -#if DBG -#define TEMP_BUFFER_SIZE 1024 - va_list list; - UCHAR debugMessageBuffer[TEMP_BUFFER_SIZE]; - NTSTATUS status; - - va_start(list, msg); - - if (msg) { - - // - // Using new safe string functions instead of _vsnprintf. This function takes - // care of NULL terminating if the message is longer than the buffer. - // - status = RtlStringCbVPrintfA(msg, sizeof(msg), - msg, list); - if(!NT_SUCCESS(status)) { - - KdPrint ((": RtlStringCbVPrintfA failed %x\n", status)); - return; - } - if ((lvl <= g_SdpDbgLevel && - ((flags & g_SdpDbgFlags) == flags))) { - KdPrint(("%s:",__FUNCTION__)); - if(lvl == TRACE_LEVEL_ERROR) KdPrint (("ERROR - ")); - KdPrint ((":%s", msg)); - } - } - va_end(list); - - return; -#endif -} - -#endif diff --git a/trunk/ulp/sdp/kernel/SdpTrace.h b/trunk/ulp/sdp/kernel/SdpTrace.h deleted file mode 100644 index ad1b1d96..00000000 --- a/trunk/ulp/sdp/kernel/SdpTrace.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#ifndef H_SDP_TRACE_H -#define H_SDP_TRACE_H -extern "C" { -#include -#include -} -#if defined(EVENT_TRACING) - -// -// Software Tracing Definitions -// -#define WPP_CONTROL_GUIDS \ - WPP_DEFINE_CONTROL_GUID(SdpCtlGuid,(2D4C03CC, E071, 48e2, BDBD, 526A0D69D6C9), \ - WPP_DEFINE_BIT( SDP_API) \ - WPP_DEFINE_BIT( SDP_CONNECT) \ - WPP_DEFINE_BIT( SDP_DRIVER) \ - WPP_DEFINE_BIT( SDP_SOCKET) \ - WPP_DEFINE_BIT( SDP_ARP) \ - WPP_DEFINE_BIT( SDP_BUFFER_POOL) \ - WPP_DEFINE_BIT( SDP_LOCK) \ - WPP_DEFINE_BIT( SDP_PERFORMANCE) \ - WPP_DEFINE_BIT( SDP_CONNECTION_LIST) \ - WPP_DEFINE_BIT( SDP_CREDITS)) - -#define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl) -#define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) WPP_LEVEL_LOGGER(flags) -#define WPP_FLAG_ENABLED(flags)(WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= TRACE_LEVEL_VERBOSE) -#define WPP_FLAG_LOGGER(flags) WPP_LEVEL_LOGGER(flags) - -// begin_wpp config -// SDP_ENTER(FLAG); -// SDP_EXIT(FLAG); -// USESUFFIX(SDP_ENTER, "%!FUNC!["); -// USESUFFIX(SDP_ENTER, "%!FUNC!]"); -// end_wpp - -#else - -// Debug toppics -#define SDP_API 0x000001 -#define SDP_CONNECT 0x000002 -#define SDP_DRIVER 0x000004 -#define SDP_SOCKET 0x000008 -#define SDP_ARP 0x000010 -#define SDP_BUFFER_POOL 0x000020 -#define SDP_LOCK 0x000040 -#define SDP_PERFORMANCE 0x000080 -#define SDP_CONNECTION_LIST 0x000100 -#define SDP_CREDITS 0x000200 - - - -VOID - SDP_PRINT( - IN ULONG lvl, - IN ULONG flags, - IN PCCHAR msg, - ...); - -#endif - - -#endif //H_SDP_TRACE_H - diff --git a/trunk/ulp/sdp/kernel/SdpUserFile.cpp b/trunk/ulp/sdp/kernel/SdpUserFile.cpp deleted file mode 100644 index 257d0e28..00000000 --- a/trunk/ulp/sdp/kernel/SdpUserFile.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -#include "Precompile.h" - - -#if defined(EVENT_TRACING) -#ifdef offsetof -#undef offsetof -#endif -#include "SdpUserFile.tmh" -#endif - -SdpUserFile::SdpUserFile() -{ - InitializeListHead(&m_SocketsList); - m_shutdown = false; - m_NumberOfUserThreads = 0; -} - -NTSTATUS SdpUserFile::Init() -{ - InitializeListHead(&m_SocketsList); - KeInitializeEvent(&m_UsersCallEvent, SynchronizationEvent , FALSE ); - m_shutdown = false; - KeInitializeSpinLock(&m_Lock); - return STATUS_SUCCESS; -} - -void SdpUserFile::Shutdown() -{ - SDP_PRINT(TRACE_LEVEL_VERBOSE, SDP_SOCKET, "Called this = 0x%p \n",this); - // go over the entire list, and release it's objects - CSpinLockWrapper Lock(m_Lock); - Lock.Lock(); - if (m_shutdown) { - // Nothing to do - Lock.Unlock(); - return; - } - m_shutdown = true; - - // Go over the list of callbacks that you have to make and remove - // them. - while (m_UsersCallList.Size() > 0) { - PLIST_ENTRY pTemp = m_UsersCallList.RemoveHeadList(); - SdpSocket * pSdpSocket = CONTAINING_RECORD(pTemp, SdpSocket , m_CallBackRequestList); - - // Don't call release with the lock being hold - Lock.Unlock(); - pSdpSocket->Release(); - // It seems that we shoule be protected by the m_shutdown - // flag, but will take the lock just in case - Lock.Lock(); - } - - while (!IsListEmpty(&m_SocketsList)) { - PLIST_ENTRY pTemp = RemoveHeadList(&m_SocketsList); - SdpSocket *pSdpSocket = CONTAINING_RECORD(pTemp, SdpSocket, m_UserFileList ); - - // Don't call release with the lock being hold - Lock.Unlock(); - // We currently call this both when the process is dead as well as - // when the device is closed - pSdpSocket->DyingProcessDetected(); - pSdpSocket->Release(); - // It seems that we shoule be protected by the m_shutdown - // flag, but will take the lock just in case - Lock.Lock(); - } - - Lock.Unlock(); - // Free the users thread - KePulseEvent(&m_UsersCallEvent,IO_NO_INCREMENT ,FALSE); -} - -NTSTATUS SdpUserFile::AddSocket(SdpSocket *pSdpSocket) -{ - CSpinLockWrapper Lock(m_Lock); - Lock.Lock(); - if (m_shutdown) { - Lock.Unlock(); - return STATUS_FILE_CLOSED; - } - InsertHeadList(&m_SocketsList, &pSdpSocket->m_UserFileList); - pSdpSocket->AddRef(); - - Lock.Unlock(); - return STATUS_SUCCESS; - -} - -VOID SdpUserFile::RemoveSocket(SdpSocket *pSdpSocket) -{ - CSpinLockWrapper Lock(m_Lock); - Lock.Lock(); - - // If shutodown is running, we don't do anything, weather this - // socket is out of the list already, or that it will soon be - // out - if (m_shutdown) { - Lock.Unlock(); - return ; - } - - RemoveEntryList(&pSdpSocket->m_UserFileList); - pSdpSocket->Release(); - - Lock.Unlock(); -} - - -SdpSocket *SdpUserFile::SocketByPointer(VOID *Socket) -{ - NTSTATUS rc = STATUS_SUCCESS; - SdpSocket *pSdpSocket = NULL; - PLIST_ENTRY pNext; - CSpinLockWrapper Lock(m_Lock); - Lock.Lock(); - if (m_shutdown) { - Lock.Unlock(); - return NULL; - } - - pNext = m_SocketsList.Flink; - while (pNext != &m_SocketsList) { - pSdpSocket = CONTAINING_RECORD(pNext, SdpSocket, m_UserFileList ); - if (pSdpSocket == Socket) { - // We have found the socket that we are looking for - break; - } - pNext = pNext->Flink; - } - if (pSdpSocket != Socket) { - // We have found something, but this is not the correct object - pSdpSocket = NULL; - } - if (pSdpSocket) { - pSdpSocket->AddRef(); - } - - Lock.Unlock(); - - return pSdpSocket; -} - -NTSTATUS -SdpUserFile::RequestCallBack(LIST_ENTRY *pList) -{ - NTSTATUS rc = STATUS_SUCCESS; - CSpinLockWrapper Lock(m_Lock); - SdpSocket *pSdpSocket = NULL; - - pSdpSocket = CONTAINING_RECORD(pList, SdpSocket , m_CallBackRequestList); - // Take the lock and add the wanted event - Lock.Lock(); - if (m_shutdown) { - Lock.Unlock(); - return STATUS_SHUTDOWN_IN_PROGRESS; - } - pSdpSocket->AddRef(); - - ASSERT(IsListEmpty(pList)); - m_UsersCallList.InsertTailList(pList); - - Lock.Unlock(); - // Make sure someone tries to read our objects - KeSetEvent(&m_UsersCallEvent,IO_NETWORK_INCREMENT ,FALSE); - return rc; - -} - -/* - This function is being called by a thread that reaches us from - the user, and is responisble for copying data from user buffers - to kernel memory. - - Only in the case of shutdown, the thread will exit. - Since we only do the cleanup of the SdpUserFile on IRP_MJ_CLOSE - there is no feer of working on a removed object. -*/ - -NTSTATUS -SdpUserFile::UsersThread() -{ - NTSTATUS rc = STATUS_SUCCESS; - CSpinLockWrapper Lock(m_Lock); - LIST_ENTRY *item = NULL; - SdpSocket *pSdpSocket = NULL; - bool ShutdownCalled = false; // This will only change from false - // to true - long NumberOfThreads = InterlockedIncrement(&m_NumberOfUserThreads); - if(NumberOfThreads != 1) { - // It seems that more than one uesr is here, don't let him - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "More than one user thread !!! \n"); - ASSERT(FALSE); - return STATUS_ACCESS_DENIED; - } - - int count = 0; - while (true) { - // Take the lock, and see the state: - Lock.Lock(); - ShutdownCalled = m_shutdown; - // Process all data that exists - if(m_UsersCallList.Size() > 0) { - item = m_UsersCallList.RemoveHeadList(); - pSdpSocket = CONTAINING_RECORD(item, SdpSocket , m_CallBackRequestList); - - Lock.Unlock(); - // Do the call back - if (!ShutdownCalled) { - pSdpSocket->UsersThreadCallBack(true); - } else { - //Currently, we don't call on shutdown. - } - - // Release everything - pSdpSocket->Release(); - continue; - } - if (ShutdownCalled) { - // Is there some other thread that is hidding ? Shouldn't happen - // but we can't trust the user - KePulseEvent(&m_UsersCallEvent,IO_NO_INCREMENT ,FALSE); - Lock.Unlock(); - return STATUS_SUCCESS; - } - // Wait for a new event to arrive - Lock.Unlock(); - rc = MyKeWaitForSingleObject(&m_UsersCallEvent, UserRequest, UserMode, TRUE, NULL); - - if (rc == STATUS_USER_APC ) { - SDP_PRINT(TRACE_LEVEL_ERROR, SDP_SOCKET, "Worker thread has recieved a user APC, shuting down the process \n"); - Shutdown(); - return STATUS_SUCCESS; - } - } - -} diff --git a/trunk/ulp/sdp/kernel/SdpUserFile.h b/trunk/ulp/sdp/kernel/SdpUserFile.h deleted file mode 100644 index 17263126..00000000 --- a/trunk/ulp/sdp/kernel/SdpUserFile.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox Technologies LTD. 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. - * - */ - -// Author: Tzachi Dar - -/* -This class is being used to truck all the user objects that are being -created per user mode dll (each dll opens a handle to the driver once) - -It keeps a list of all the objects so we know when to remove them. - -*/ - -#ifndef _SDP_USER_FILE_H -#define _SDP_USER_FILE_H - -class SdpUserFile : public RefCountImpl { -private: - KSPIN_LOCK m_Lock; - bool m_shutdown; - -// BUGBUG: Use something more effiecent for this storage - LIST_ENTRY m_SocketsList; - - LinkedList m_UsersCallList; // This list holds all the requests of users for callback - KEVENT m_UsersCallEvent; // The users thread waits on this event - - volatile long m_NumberOfUserThreads;// Make sure that there is only one user thread - -public: - - SdpUserFile(); - - NTSTATUS Init(); - VOID Shutdown(); - - SdpSocket *SocketByPointer(VOID *Socket); - - NTSTATUS AddSocket(SdpSocket *pSdpSocket); - - VOID RemoveSocket(SdpSocket *pSdpSocket); - -// VOID MoveSocketT(SdpSocket *pSdpSocket); - - NTSTATUS RequestCallBack(LIST_ENTRY *pList); - - NTSTATUS UsersThread(); - -}; - -#endif //_SDP_USER_FILE_H - diff --git a/trunk/ulp/sdp/kernel/makefile b/trunk/ulp/sdp/kernel/makefile deleted file mode 100644 index 128ed372..00000000 --- a/trunk/ulp/sdp/kernel/makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source -# file to this component. This file merely indirects to the real make file -# that is shared by all the driver components of the Windows NT DDK -# - -!INCLUDE ..\..\..\inc\openib.def diff --git a/trunk/ulp/sdp/kernel/sdp.rc b/trunk/ulp/sdp/kernel/sdp.rc deleted file mode 100644 index a9ef0d25..00000000 --- a/trunk/ulp/sdp/kernel/sdp.rc +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2005 Mellanox 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 - -#define VER_FILETYPE VFT_DRV -#define VER_FILESUBTYPE VFT2_UNKNOWN - -#if DBG -#define VER_FILEDESCRIPTION_STR "SDP over InfiniBand Driver (Debug)" -#else -#define VER_FILEDESCRIPTION_STR "SDP over InfiniBand Driver" -#endif - -#define VER_INTERNALNAME_STR "sdp.sys" -#define VER_ORIGINALFILENAME_STR "sdp.sys" - -#include diff --git a/trunk/ulp/sdp/tests/basic/BasicConnect.cpp b/trunk/ulp/sdp/tests/basic/BasicConnect.cpp deleted file mode 100644 index 9f5837a9..00000000 --- a/trunk/ulp/sdp/tests/basic/BasicConnect.cpp +++ /dev/null @@ -1,492 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static int result = 0; - - -// Notes: -// -// -- Maximum message size calculation: -// The maximum lenght of an IP message is 64K-1 (the length field in the IP header is 16 bits wide). -// The IP length field includes the IP header. -// Therefore, the maximum length of a UDP message payload is: -// 64K-1-20(IP header)-8(UDP header) = 65507 bytes - - -void printUsage(char *exeName){ - printf("usage of program is:\n"); - printf("%s <\"client\"> \nif contSize==0, then client will send numberOfMessages messages of 1,2,3,...numberOfMessages bytes\nif contSize!=0 then client will send numberOfMessages messages of contSize bytes\n",exeName); - printf("\n or\n\n"); - printf("%s \n\t", exeName); -} - -WSABUF* allocateBuffer(int len){ - WSABUF* buffer = new WSABUF[1]; - if (buffer == NULL) { - printf("Error in allocating memory for buffer\n"); - return NULL; - }else{ - buffer[0].len = len; - buffer[0].buf = new char [len]; - if (buffer[0].buf == NULL) { - printf("Error in allocating memory for buffer[0].buf\n"); - delete [] buffer; - return NULL; - }else{ - buffer[0].buf[0] = 0; - return buffer; - } - } -} - -void freeBuffer(WSABUF* buffer){ - delete [] buffer[0].buf; - delete [] buffer; -} - -SOCKET createSocket(){ - WSADATA wsaData; - int error = WSAStartup( MAKEWORD( 2, 2 ), &wsaData); - if (error) { - printf("Error in WSAStartup: winsock error=%d\n", WSAGetLastError()); - return INVALID_SOCKET; - } - SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); - if (socket == INVALID_SOCKET) { - printf("Error in WSASocket: winsock error=%d\n", WSAGetLastError()); - } - return socket; -} - -bool increaseSendBuffSize(SOCKET socket, int requestedBufferSize){ - int realSendBufferSize; - int error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char*)&requestedBufferSize, sizeof (int)); - if (error) { - printf("Error in setsockopt: winsock error=%d\n", WSAGetLastError()); - return FALSE; - } - int size = sizeof (int); - error = getsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char*)&realSendBufferSize, &size); - if (error) { - printf("Error in getsockopt: winsock error=%d\n", WSAGetLastError()); - return FALSE; - } - if (realSendBufferSize != requestedBufferSize) { - printf("Error: realSendBufferSize!=requestedBufferSize:\n \ - , realSendBufferSize = %d, requestedBufferSize=%d", - realSendBufferSize, requestedBufferSize); - return FALSE; - } - return TRUE; -} - -sockaddr addressFromString(char *address, USHORT port) - -{ - SOCKADDR_IN socket_address; - sockaddr *socket_address_ptr = (sockaddr*)&socket_address; - memset(&socket_address, 0, sizeof(socket_address)); - socket_address.sin_family = AF_INET; - socket_address.sin_port = htons(port); - int b1,b2,b3,b4; - sscanf(address, "%d.%d.%d.%d",&b1, &b2, &b3, &b4); - socket_address.sin_addr.S_un.S_un_b.s_b1 = (BYTE)b1; - socket_address.sin_addr.S_un.S_un_b.s_b2 = (BYTE)b2; - socket_address.sin_addr.S_un.S_un_b.s_b3 = (BYTE)b3; - socket_address.sin_addr.S_un.S_un_b.s_b4 = (BYTE)b4; - return *socket_address_ptr; -} - -void performancePrint(double size, DWORD startTime){ - DWORD mseconds = GetTickCount()-startTime; - if(mseconds!=0){ - printf("sent and received %f bytes/%d mseconds => %f MBPS\n", - size, mseconds, (size/mseconds)/1000.0); - }else{ - printf("sent and received %f bytes, in 0 mseconds\n", size); - } -} - -void clientDebugMessage(bool printEnable, int debugMessageNumber, double size, DWORD time){ - if(!printEnable){ - return; - } - switch(debugMessageNumber){ - case 1: - printf("sending %f bytes at time %d msec\n", size, time); - break; - case 2: - performancePrint(size, time); - break; - case 3: - printf("\n\n\nPerformance summary:\n"); - performancePrint(size, time); - break; - default: - break; - } -} - -// 0: normanl good receive -// 2: error -int myReceive( - SOCKET socket, - WSABUF* receiveBufferArray, - WSAOVERLAPPED* wsaoverlappedPtr, - DWORD* numOfRecvBytesPtr, - DWORD* flagsPtr, - int timeoutTime - ){ - - int recvStat = WSARecv( - socket, - receiveBufferArray, - 1, - numOfRecvBytesPtr, - flagsPtr, - NULL, - NULL - ); - if( (recvStat!= 0) ){ - printf("erroro\n"); - DWORD dwgle = WSAGetLastError(); - if (dwgle != WSA_IO_PENDING ) { - printf("Error in WSARecv: winsock error=%d\n", WSAGetLastError()); - return 2; - } - } - return 0; -} - - -#define SEND - -void client(char *IP, int Port, int numberOfMessages, int constSize) -{ - bool debug = FALSE; - SOCKET socket = INVALID_SOCKET; - sockaddr localSockAddr; - sockaddr destSockAddr; - WSABUF* sendBufferArray = NULL; - WSABUF* receiveBufferArray = NULL; - DWORD firstSendStartTime; - DWORD startTime; - DWORD flags = 0; - DWORD numOfSentBytes; - DWORD numOfRecvBytes; - double totalSentBytes = 0; - DWORD timeoutTime = 3000; //represents mseconds - DWORD totalWaitTime = 0; - int ret; - - - printf("client starting: ip=%s, port=%d, numberOfMessages=%d\n", IP, Port, numberOfMessages ); - - // open and connect the socket: - socket = createSocket(); - if(socket==INVALID_SOCKET) { - result = 1; - goto cleanup; - } - - destSockAddr = addressFromString (IP, (USHORT)Port); - if(WSAConnect(socket, &destSockAddr, sizeof(destSockAddr), NULL, NULL, NULL, NULL)!=0){ - printf("Error in WSAConnect: winsock error=%d\n", WSAGetLastError()); - result = 1; - goto cleanup; - } - - -#ifndef SEND - // Send the buffer sizes - char message[40]; - StringCbPrintf(message, sizeof message, "%d,%d,", constSize,numberOfMessages); - ret = send(socket, message, strlen (message), 0); - if (ret != strlen (message)) { - printf("Error in send winsock error=%d\n", WSAGetLastError()); - result = 1; - goto cleanup; - } -#endif - - // allocate send & receive buffers: - sendBufferArray = allocateBuffer(constSize); - if(sendBufferArray==NULL){ - result = 1; - goto cleanup; - } - receiveBufferArray = allocateBuffer(constSize); - if(receiveBufferArray==NULL){ - result = 1; - goto cleanup; - } - - firstSendStartTime = GetTickCount(); - // main client loop: - for(int i = 0; i < numberOfMessages; i++) { - int messageSize = constSize==0 ? i : constSize; - startTime = GetTickCount(); - clientDebugMessage(debug, 1, (double)messageSize, startTime); - sendBufferArray[0].len = messageSize; - if(i==numberOfMessages){ - sendBufferArray[0].buf[0] = 1; - } - - if (messageSize > 10 ) { - // Just put some data in here - int q; - for (q= 0; q< 8; q++ ) { - sendBufferArray[0].buf[q] = (char)q + 'A'; - } - } -#ifdef SEND - if(WSASend(socket, sendBufferArray, 1, &numOfSentBytes, 0, NULL, NULL) != 0) { - printf("Error in WSASend in messageSize=%d: winsock error=%d\n", messageSize, WSAGetLastError()); - result = 1; - goto cleanup; - } - if(numOfSentBytes!=messageSize) { - printf("numOfSentBytes!=messageSize\n"); - result = 1; - goto cleanup; - } -#else - DWORD Flags = 0; - if(WSARecv(socket, sendBufferArray, 1, &numOfSentBytes, &Flags, NULL, NULL) != 0) { - printf("Error in WSARecv in messageSize=%d: winsock error=%d\n", messageSize, WSAGetLastError()); - result = 1; - goto cleanup; - } - assert(numOfSentBytes == messageSize); // Make sure we have a complete buffer - if (numOfSentBytes > 4) { - //printf("Recieved %c%c%c%c\n", sendBufferArray->buf[0], sendBufferArray->buf[1], sendBufferArray->buf[2], sendBufferArray->buf[3] ); - } - //printf("i = %d Recieved %d bytes\n",i, numOfSentBytes); - -#endif -/* - int recvStatus = myReceive( - socket, - receiveBufferArray, - NULL, - &numOfRecvBytes, - &flags, - timeoutTime - ); - switch(recvStatus){ - case 0: - totalSentBytes+=messageSize; - if(numOfRecvBytes!=messageSize){ - printf("numOfRecvBytes(%d) != messageSize(%d)\n", numOfRecvBytes, messageSize); - result = 1; - goto cleanup; - } - clientDebugMessage(debug, 2, messageSize, startTime); - break; - case 2: - result = 1; - goto cleanup; - default: - printf("reached default in switch statement\n"); - result = 1; - goto cleanup; - } -*/ - } - - if(totalSentBytes!=0){ - clientDebugMessage(TRUE, 3, totalSentBytes, firstSendStartTime+totalWaitTime); - }else{ - printf("no bytes transferred\n"); - } - - cleanup: - if(socket!=INVALID_SOCKET){ - if(closesocket(socket)!=0){ - printf("closesocket error: error = %d\n", WSAGetLastError()); - } - } - WSACleanup(); - if(sendBufferArray!=NULL){ - freeBuffer(sendBufferArray); - } - if(receiveBufferArray!=NULL){ - freeBuffer(receiveBufferArray); - } -// printf("sleeping ...\n"); -// Sleep(1000); -} - -void serverDebugMessage(bool printEnable, int messageNumber, double size){ - if(!printEnable){ - return; - } - switch(messageNumber){ - case 1: - printf("-----------------------------------------------------------\n"); - printf(" received %f bytes at time %d\n", size, GetTickCount()); - break; - case 2: - printf("sent back %f bytes at time %d\n", size, GetTickCount()); - printf("-----------------------------------------------------------\n\n"); - break; - default: - break; - } -} - -void Server(int Port) -{ - SOCKET s; - WSADATA wsaData; - sockaddr saLocal, saFrom; - int i; - DWORD start, end, Flags = 0; - int NumberOfMessages = 1; - int MessageSize = 70000; - WSABUF wsb; - - - printf("Starting as Server port=%d, \n", Port ); - - int err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData); - if ( err != 0 ) { - printf("Error opening winsock err=%d", WSAGetLastError()); - goto cleanup; - } - - s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0 ); - if (s == INVALID_SOCKET) { - printf("Error creating socket winsock err=%d", WSAGetLastError()); - goto cleanup; - } - - int RecvBufferSize = 0* 1024, RealRecvBufferSize; - err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&RecvBufferSize, sizeof (int)); - if ( err != 0 ) { - printf("Error setsockopt failed err=%d", WSAGetLastError()); - goto cleanup; - } - int Size = sizeof (int); - err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&RealRecvBufferSize, &Size); - if ( err != 0 ) { - printf("Error setsockopt failed err=%d", WSAGetLastError()); - goto cleanup; - } - if (RealRecvBufferSize != RecvBufferSize) { - printf("Error: RealSendBufferSize = %d", RealRecvBufferSize); - goto cleanup; - } - - - DWORD dwBytesRecieved; - - // Bind the socket first - - SOCKADDR_IN *psa = (SOCKADDR_IN*)&saLocal; - memset(&saLocal, 0, sizeof(saLocal)); - psa->sin_family = AF_INET; - psa->sin_port = htons((USHORT)Port); - - err = bind(s, &saLocal, sizeof(saLocal)); - if ( err != 0 ) { - printf("Error bind winsock err=%d", WSAGetLastError()); - goto cleanup; - } - - err = listen(s, 10); - if ( err != 0 ) { - printf("Error on listen winsock err=%d", WSAGetLastError()); - goto cleanup; - } - - while (1) { - int addrLen = sizeof (saFrom); - SOCKET s1 = accept(s, &saFrom, &addrLen); - if (s1 == INVALID_SOCKET) { - printf("Error accept failed err=%d", WSAGetLastError()); - goto cleanup; - } - - - for (i =0; i < 1; i++) { - // Recieve the data - printf ("Calling recieve\n"); - - wsb.len = MessageSize; - wsb.buf = new char [MessageSize]; - if (wsb.buf == NULL ) { - printf("Error Allocating memory\n"); - goto cleanup; - } - - err = WSARecv( - s1, - &wsb, - 1, - &dwBytesRecieved, - &Flags, - NULL, - NULL - ); - if (err == SOCKET_ERROR) { - DWORD gle = WSAGetLastError(); - if (gle != WSA_IO_PENDING) { - - printf("Error WSARecv winsock err=%d", gle); - goto cleanup; - } - } - - // send a reply packet - - StringCbCopy(wsb.buf, wsb.len, "I'm a demo server");\ - wsb.len = strlen(wsb.buf); - err = WSASend( - s1, - &wsb, - 1, - &dwBytesRecieved, - Flags, - NULL, - NULL - ); - if (err == SOCKET_ERROR) { - DWORD gle = WSAGetLastError(); - if (gle != WSA_IO_PENDING) { - - printf("Error WSASend winsock err=%d", gle); - goto cleanup; - } - } - } - } - cleanup: - WSACleanup(); - -} - -__cdecl main (int argc, char *argv[]){ - if ((argc == 6) && !_stricmp(argv[1],"client") ) { - int port = atoi(argv[3]); - int numberOfMessages = atoi(argv[4]); - int constSize = atoi(argv[5]); - client(argv[2], port, numberOfMessages, constSize); - return result; - }else if((argc==3 ) && !_stricmp(argv[1],"server") ){ - int port = atoi(argv[2]); - Server(port); - return result; - }else{ - printUsage(argv[0]); - return 1; - } -} diff --git a/trunk/ulp/sdp/tests/basic/SdpConnect.cpp b/trunk/ulp/sdp/tests/basic/SdpConnect.cpp deleted file mode 100644 index b43f503a..00000000 --- a/trunk/ulp/sdp/tests/basic/SdpConnect.cpp +++ /dev/null @@ -1,585 +0,0 @@ - -#ifdef _WIN32 -#include -#include -#include -#include - -#define AF_INET_FAMILY PF_INET - -#define sleep(x) Sleep(1000 * (x)); -#define CloseSocket closesocket - -#define GetTimeMs() GetTickCount() -#else - -#define AF_INET_FAMILY 27 - -#include -#include -#include -#include -#include - -#define _stricmp strcasecmp -#define WSAGetLastError() errno -#define CloseSocket close - - -#endif -// Windows linux - -const int NumberOfThreads = 2; - -HANDLE g_ComplitionPort; -HANDLE g_pThreads[NumberOfThreads]; - -#define ASSERT assert - -struct sockaddr addressFromString(char *address, int port) -{ - unsigned int b1,b2,b3,b4; - - struct sockaddr_in socket_address; - struct sockaddr *socket_address_ptr = (struct sockaddr*)&socket_address; - - memset(&socket_address, 0, sizeof(socket_address)); - socket_address.sin_family = AF_INET; - socket_address.sin_port = htons((u_short)port); - - - sscanf(address, "%d.%d.%d.%d",&b1, &b2, &b3, &b4); - socket_address.sin_addr.s_addr = b4 * 256 * 256 *256 + - b3 * 256 * 256 + - b2 * 256 + - b1; - - return *socket_address_ptr; -} - - -struct OverlappedSend { - OVERLAPPED Overlapped; - SOCKET Socket; - void *Buffer; // The data to send - int DataSize; - DWORD NumberOfBytesSent; - static int s_RemainingSends; - static int s_SendsInAir; // Curently sent data (debug only) - static CRITICAL_SECTION s_Lock; - static HANDLE s_SendDoneEvent; - -}; - -int OverlappedSend::s_RemainingSends; -int OverlappedSend::s_SendsInAir; // Curently sent data (debug only) -CRITICAL_SECTION OverlappedSend::s_Lock; -HANDLE OverlappedSend::s_SendDoneEvent; - - -DWORD WINAPI WorkerThreadFunc( LPVOID lpParam ) -{ - BOOL ret; - DWORD NumberOfBytes; - ULONG_PTR CompletionKey; - OVERLAPPED* lpOverlapped; - OverlappedSend *pOverLappedSend; - BOOL ContinueLoop = true; - int iRet; - - while (TRUE) { - ret = GetQueuedCompletionStatus( - g_ComplitionPort, - &NumberOfBytes, - &CompletionKey, - &lpOverlapped, - INFINITE); - ASSERT(ret != 0); - pOverLappedSend = CONTAINING_RECORD(lpOverlapped, OverlappedSend, Overlapped); - // Work on the object itself: - EnterCriticalSection(&pOverLappedSend->s_Lock); - pOverLappedSend->s_SendsInAir--; - if (pOverLappedSend->s_RemainingSends > 0) { - // do the next send - WSABUF Buffers; - Buffers.len = pOverLappedSend->DataSize; - Buffers.buf = (char *) pOverLappedSend->Buffer; - pOverLappedSend->s_SendsInAir++; - pOverLappedSend->s_RemainingSends--; - - iRet = WSASend( - pOverLappedSend->Socket, - &Buffers, - 1, - &pOverLappedSend->NumberOfBytesSent, - 0, - &pOverLappedSend->Overlapped, - NULL - ); - ASSERT((iRet ==0) || (iRet == SOCKET_ERROR && WSAGetLastError() == WSA_IO_PENDING )); - - } else { - // Nothing more to send - signal compleation and exit - SetEvent(pOverLappedSend->s_SendDoneEvent); - ContinueLoop = false; - } - LeaveCriticalSection(&pOverLappedSend->s_Lock); - if (!ContinueLoop) { - break; - } - - } - return 0; -} - -void CreateComplitionPort(SOCKET newfd) -{ - - g_ComplitionPort = CreateIoCompletionPort((HANDLE)newfd, NULL, NULL, 2); - if(g_ComplitionPort == NULL) { - printf("Create complition port failed err=%d", GetLastError()); - exit(1); - } - - - for (int i=0; i s_RemainingSends = (size_t)NumberOfBuffers; - pOverLappedSend->s_SendsInAir = 1; // To force a simulate of the compleation - InitializeCriticalSection(&pOverLappedSend->s_Lock); - pOverLappedSend->s_SendDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - - double Start = GetTimeMs(); - - for(i = 0; i < NumberOfOverlappedSend; i++) { - - buffer = new char [(size_t)BufferSize]; - if (buffer == NULL) { - printf("Error allocating buffer\n"); - exit(1); - } - - pOverLappedSend = new OverlappedSend; - - // Set it's fields - memset(&pOverLappedSend->Overlapped, 0, sizeof (pOverLappedSend->Overlapped)); - pOverLappedSend->Socket = newfd; - pOverLappedSend->Buffer = buffer; - pOverLappedSend->DataSize = (size_t)BufferSize; - - // Post the message that will do the first send - ret = PostQueuedCompletionStatus( - g_ComplitionPort, - (DWORD)BufferSize, - NULL, - &pOverLappedSend->Overlapped - ); - ASSERT(ret != 0); - - } - - // wait for the send - WaitForSingleObject(pOverLappedSend->s_SendDoneEvent, INFINITE); - elapsed = (GetTimeMs() - Start) / 1000; - printf("Finishd sending correctly %f mbytes/sec\n", NumberOfBuffers * BufferSize /elapsed/1024/1024 ); - CloseComplitionPort(); -//Cleanup: - for(i = 0; i < NumberOfOverlappedSend; i++) { - delete []pOverLappedSend->Buffer; - delete pOverLappedSend; - } -} - - - -void SendData(SOCKET newfd, double NumberOfBuffers, double BufferSize, BOOL SendPacketNumber) -{ - int i ; - double d; - CHAR *buffer = NULL; - double elapsed, acc = 0; - - buffer = new char [(size_t)BufferSize]; - if (buffer == NULL) { - printf("Error allocating buffer\n"); - exit(1); - } - - printf("Starting to send syncroniously %lf messages of size %lf\n", NumberOfBuffers, BufferSize ); - - i = 0; - - for (i = 0; i < 10; i++) { - buffer[i] = 'a' + i; - } - double Start = GetTimeMs(); - - for (d=0; d < NumberOfBuffers; d++) { - int j; - if (SendPacketNumber) { - memset(buffer, (char) d, (size_t)BufferSize); - } - - j = send(newfd, buffer, (size_t)BufferSize, 0 ); - acc += j; - if (j!=BufferSize) { - printf("Error send not compleated sent %lf\n", acc); - goto Cleanup; - } - } - elapsed = (GetTimeMs() - Start) / 1000; - printf("Finishd sending correctly %f mbytes/sec (%f seconfs)\n", acc/elapsed/1024/1024, elapsed ); -Cleanup: - free(buffer); -} - - -void RecvData(SOCKET newfd, double NumberOfBuffers, double BufferSize ) -{ - const int ReadSize = 400000; - int read1 = 1; - unsigned char *p; - double elapsed, acc = 0; - int i; - double Start = GetTimeMs(); - char *buffer = new char [ReadSize]; - if (buffer == NULL) { - printf("Error allocating memory"); - exit(4); - } - - while ((read1 != -1) /*&& (acc < (double)BufferSize * NumberOfBuffers)*/) { - read1 = recv(newfd, buffer, ReadSize, 0); - if (read1 == -1 || read1 == 0) { - printf("Finsihed reading, total read %lf bytes last read =%d\n", acc, read1 ); - if (acc != BufferSize * NumberOfBuffers) { - printf("Error, expected to read %lf but read %lf\n", - (BufferSize * NumberOfBuffers), acc); - } - break; - } - else { - acc += read1; - -// printf("read returned %d \"%c%c%c%c\"\n",read1, -// buffer[0],buffer[1], buffer[2], buffer[3]); - } - } - - if (acc != ((double)BufferSize * NumberOfBuffers)) { - printf("Error, expected to read %lf but read %lf", - ((double)BufferSize * NumberOfBuffers), acc); - } else { - elapsed = (GetTimeMs() - Start) / 1000; - printf("Finishd reading correctly %lf mbytes/sec (time = %lf)\n", acc / elapsed/1024/1024, elapsed); - } - delete []buffer; -} - -void PrintUsage(char *name) -{ - printf("The program might be used in client or server mode\n"); - printf("usage is %s \n", name); - printf("usage is %s