2 * Copyright (c) 2008 Intel Corporation. All rights reserved.
\r
3 * Portions Copyright (c) 2009 Microsoft Corporation. All rights reserved.
\r
5 * This software is available to you under the OpenIB.org BSD license
\r
8 * Redistribution and use in source and binary forms, with or
\r
9 * without modification, are permitted provided that the following
\r
10 * conditions are met:
\r
12 * - Redistributions of source code must retain the above
\r
13 * copyright notice, this list of conditions and the following
\r
16 * - Redistributions in binary form must reproduce the above
\r
17 * copyright notice, this list of conditions and the following
\r
18 * disclaimer in the documentation and/or other materials
\r
19 * provided with the distribution.
\r
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
\r
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
25 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
26 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
31 #include "wv_memory.h"
\r
33 #include "wv_ioctl.h"
\r
36 static void WvIoConvertConnParam(WV_IO_CONNECT_PARAM *pIoParam,
\r
37 WV_CONNECT_PARAM *pParam)
\r
39 pIoParam->DataLength = (UINT8) pParam->DataLength;
\r
40 pIoParam->ResponderResources = pParam->ResponderResources;
\r
41 pIoParam->InitiatorDepth = pParam->InitiatorDepth;
\r
42 pIoParam->RetryCount = pParam->RetryCount;
\r
43 pIoParam->RnrRetryCount = pParam->RnrRetryCount;
\r
44 RtlZeroMemory(pIoParam->Reserved, sizeof pIoParam->Reserved);
\r
45 RtlCopyMemory(pIoParam->Data, pParam->Data, pParam->DataLength);
\r
48 CWVConnectEndpoint::CWVConnectEndpoint(CWVProvider *pProvider)
\r
50 pProvider->AddRef();
\r
51 m_pProvider = pProvider;
\r
52 m_hFile = pProvider->m_hFile;
\r
53 m_Socket = INVALID_SOCKET;
\r
57 STDMETHODIMP CWVConnectEndpoint::
\r
64 EpType = WV_IO_EP_TYPE_CONNECT;
\r
65 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CREATE, &EpType, sizeof EpType,
\r
66 &m_Id, sizeof m_Id, &bytes, NULL)) {
\r
69 hr = HRESULT_FROM_WIN32(GetLastError());
\r
75 CWVConnectEndpoint::~CWVConnectEndpoint()
\r
79 if (m_pQp != NULL) {
\r
84 WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DESTROY, &m_Id, sizeof m_Id,
\r
85 NULL, 0, &bytes, NULL);
\r
88 if (m_Socket != INVALID_SOCKET) {
\r
89 closesocket(m_Socket);
\r
91 m_pProvider->Release();
\r
94 STDMETHODIMP CWVConnectEndpoint::
\r
95 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
\r
97 if (riid != IID_IUnknown && riid != IID_IWVEndpoint &&
\r
98 riid != IID_IWVConnectEndpoint) {
\r
100 return E_NOINTERFACE;
\r
108 STDMETHODIMP_(ULONG) CWVConnectEndpoint::
\r
111 return CWVBase::AddRef();
\r
114 STDMETHODIMP_(ULONG) CWVConnectEndpoint::
\r
117 return CWVBase::Release();
\r
120 STDMETHODIMP CWVConnectEndpoint::
\r
121 CancelOverlappedRequests(void)
\r
125 return WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CANCEL, &m_Id, sizeof m_Id,
\r
126 NULL, 0, &bytes, NULL) ?
\r
127 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
130 STDMETHODIMP CWVConnectEndpoint::
\r
131 GetOverlappedResult(OVERLAPPED *pOverlapped,
\r
132 DWORD *pNumberOfBytesTransferred, BOOL bWait)
\r
134 ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);
\r
135 return (HRESULT) pOverlapped->Internal;
\r
138 STDMETHODIMP CWVConnectEndpoint::
\r
139 Modify(DWORD Option, const VOID* pOptionData, SIZE_T OptionLength)
\r
146 bytes = sizeof WV_IO_ID + OptionLength;
\r
147 pId = (WV_IO_ID *) buf.Get(bytes);
\r
149 return WV_NO_MEMORY;
\r
153 pId->Data = Option;
\r
154 RtlCopyMemory(pId + 1, pOptionData, OptionLength);
\r
156 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_MODIFY, pId, bytes,
\r
157 NULL, 0, &bytes, NULL)) {
\r
160 hr = HRESULT_FROM_WIN32(GetLastError());
\r
167 STDMETHODIMP CWVConnectEndpoint::
\r
168 BindAddress(SOCKADDR* pAddress)
\r
170 WV_IO_EP_BIND attr;
\r
176 if (pAddress->sa_family == AF_INET) {
\r
177 any = (((SOCKADDR_IN *) pAddress)->sin_addr.S_un.S_addr == INADDR_ANY);
\r
178 bytes = sizeof(SOCKADDR_IN);
\r
180 any = IN6ADDR_ISANY((SOCKADDR_IN6 *) pAddress);
\r
181 bytes = sizeof(SOCKADDR_IN6);
\r
185 RtlZeroMemory(&attr.Device, sizeof attr.Device);
\r
187 hr = m_pProvider->TranslateAddress(pAddress, (WV_DEVICE_ADDRESS *) &attr.Device);
\r
193 m_Socket = socket(pAddress->sa_family, SOCK_STREAM, IPPROTO_TCP);
\r
194 if (m_Socket == INVALID_SOCKET) {
\r
195 return WvConvertWSAStatus(WSAGetLastError());
\r
198 hr = bind(m_Socket, pAddress, bytes);
\r
204 len = sizeof attr.Address;
\r
205 hr = getsockname(m_Socket, (sockaddr *) &attr.Address, &len);
\r
210 if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_BIND, &attr, sizeof attr,
\r
211 &attr, sizeof attr, &bytes, NULL)) {
\r
212 hr = HRESULT_FROM_WIN32(GetLastError());
\r
219 hr = WvConvertWSAStatus(WSAGetLastError());
\r
221 closesocket(m_Socket);
\r
222 m_Socket = INVALID_SOCKET;
\r
226 STDMETHODIMP CWVConnectEndpoint::
\r
227 Listen(SIZE_T Backlog)
\r
229 WV_IO_EP_LISTEN attr;
\r
234 attr.Backlog = Backlog;
\r
236 if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_LISTEN, &attr, sizeof attr,
\r
237 &attr, sizeof attr, &bytes, NULL)) {
\r
238 hr = HRESULT_FROM_WIN32(GetLastError());
\r
246 STDMETHODIMP CWVConnectEndpoint::
\r
247 Reject(const VOID* pUserData, SIZE_T UserDataLength)
\r
254 bytes = sizeof WV_IO_ID + UserDataLength;
\r
255 pId = (WV_IO_ID *) buf.Get(bytes);
\r
257 return WV_NO_MEMORY;
\r
261 RtlCopyMemory(pId + 1, pUserData, UserDataLength);
\r
263 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_REJECT, pId, bytes,
\r
264 NULL, 0, &bytes, NULL)) {
\r
267 hr = HRESULT_FROM_WIN32(GetLastError());
\r
274 STDMETHODIMP CWVConnectEndpoint::
\r
275 GetRequest(IWVConnectEndpoint* pEndpoint, OVERLAPPED* pOverlapped)
\r
277 WV_IO_EP_GET_REQUEST req;
\r
282 req.EpId = ((CWVConnectEndpoint *) pEndpoint)->m_Id;
\r
283 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_GET_REQUEST,
\r
284 &req, sizeof req, NULL, 0, &bytes, pOverlapped)) {
\r
287 hr = HRESULT_FROM_WIN32(GetLastError());
\r
293 STDMETHODIMP CWVConnectEndpoint::
\r
294 Connect(IWVConnectQueuePair* pQp, const SOCKADDR* pAddress,
\r
295 WV_CONNECT_PARAM* pParam, OVERLAPPED* pOverlapped)
\r
297 WV_IO_EP_CONNECT attr;
\r
301 m_pQp = (CWVConnectQueuePair *) pQp;
\r
304 attr.QpId = m_pQp->m_Id;
\r
306 if (pAddress->sa_family == AF_INET) {
\r
307 RtlCopyMemory(&attr.PeerAddress, pAddress, sizeof(SOCKADDR_IN));
\r
309 RtlCopyMemory(&attr.PeerAddress, pAddress, sizeof(SOCKADDR_IN6));
\r
311 WvIoConvertConnParam(&attr.Param, pParam);
\r
313 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CONNECT, &attr, sizeof attr,
\r
314 NULL, 0, &bytes, pOverlapped)) {
\r
317 hr = HRESULT_FROM_WIN32(GetLastError());
\r
323 STDMETHODIMP CWVConnectEndpoint::
\r
324 Accept(IWVConnectQueuePair* pQp, WV_CONNECT_PARAM* pParam, OVERLAPPED* pOverlapped)
\r
326 WV_IO_EP_ACCEPT attr;
\r
332 if (m_pQp == NULL) {
\r
333 m_pQp = (CWVConnectQueuePair *) pQp;
\r
338 attr.QpId = m_pQp->m_Id;
\r
339 m_pQp->m_pVerbs->nd_modify_qp(m_pQp->m_hVerbsQp, &pout, &size);
\r
340 WvIoConvertConnParam(&attr.Param, pParam);
\r
342 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_ACCEPT, &attr, sizeof attr,
\r
343 pout, size, &bytes, pOverlapped)) {
\r
346 hr = HRESULT_FROM_WIN32(GetLastError());
\r
352 STDMETHODIMP CWVConnectEndpoint::
\r
353 Disconnect(OVERLAPPED* pOverlapped)
\r
355 WV_IO_EP_DISCONNECT attr;
\r
362 attr.QpId = m_pQp->m_Id;
\r
363 m_pQp->m_pVerbs->nd_modify_qp(m_pQp->m_hVerbsQp, &pout, &size);
\r
365 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DISCONNECT,
\r
366 &attr, sizeof attr, pout, size, &bytes, pOverlapped)) {
\r
369 hr = HRESULT_FROM_WIN32(GetLastError());
\r
375 STDMETHODIMP CWVConnectEndpoint::
\r
376 NotifyDisconnect(OVERLAPPED* pOverlapped)
\r
381 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DISCONNECT_NOTIFY,
\r
382 &m_Id, sizeof m_Id, NULL, 0, &bytes, pOverlapped)) {
\r
385 hr = HRESULT_FROM_WIN32(GetLastError());
\r
391 STDMETHODIMP CWVConnectEndpoint::
\r
392 Query(WV_CONNECT_ATTRIBUTES* pAttributes)
\r
394 WV_IO_EP_ATTRIBUTES attr;
\r
398 if (!WvDeviceIoControl(m_hFile, WV_IOCTL_EP_QUERY, &m_Id, sizeof m_Id,
\r
399 &attr, sizeof attr, &bytes, NULL)) {
\r
400 return HRESULT_FROM_WIN32(GetLastError());
\r
403 RtlCopyMemory(&pAttributes->LocalAddress, &attr.LocalAddress,
\r
404 sizeof pAttributes->LocalAddress);
\r
405 RtlCopyMemory(&pAttributes->PeerAddress, &attr.PeerAddress,
\r
406 sizeof pAttributes->PeerAddress);
\r
407 RtlCopyMemory(&pAttributes->Device, &attr.Device, sizeof pAttributes->Device);
\r
408 pAttributes->Param.DataLength = attr.Param.Connect.DataLength;
\r
409 pAttributes->Param.ResponderResources = (SIZE_T) attr.Param.Connect.ResponderResources;
\r
410 pAttributes->Param.InitiatorDepth = (SIZE_T) attr.Param.Connect.InitiatorDepth;
\r
411 pAttributes->Param.RetryCount = attr.Param.Connect.RetryCount;
\r
412 pAttributes->Param.RnrRetryCount = attr.Param.Connect.RnrRetryCount;
\r
413 RtlCopyMemory(pAttributes->Param.Data, attr.Param.Connect.Data, attr.Param.Connect.DataLength);
\r
419 CWVDatagramEndpoint::CWVDatagramEndpoint(CWVProvider *pProvider)
\r
421 pProvider->AddRef();
\r
422 m_pProvider = pProvider;
\r
423 m_hFile = pProvider->m_hFile;
\r
426 STDMETHODIMP CWVDatagramEndpoint::
\r
433 EpType = WV_IO_EP_TYPE_DATAGRAM;
\r
434 if (WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CREATE, &EpType, sizeof EpType,
\r
435 &m_Id, sizeof m_Id, &bytes, NULL)) {
\r
438 hr = HRESULT_FROM_WIN32(GetLastError());
\r
444 CWVDatagramEndpoint::~CWVDatagramEndpoint()
\r
449 WvDeviceIoControl(m_hFile, WV_IOCTL_EP_DESTROY, &m_Id, sizeof m_Id,
\r
450 NULL, 0, &bytes, NULL);
\r
452 m_pProvider->Release();
\r
455 STDMETHODIMP CWVDatagramEndpoint::
\r
456 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
\r
458 if (riid != IID_IUnknown && riid != IID_IWVEndpoint &&
\r
459 riid != IID_IWVDatagramEndpoint) {
\r
461 return E_NOINTERFACE;
\r
469 STDMETHODIMP_(ULONG) CWVDatagramEndpoint::
\r
472 return CWVBase::AddRef();
\r
475 STDMETHODIMP_(ULONG) CWVDatagramEndpoint::
\r
478 return CWVBase::Release();
\r
481 STDMETHODIMP CWVDatagramEndpoint::
\r
482 CancelOverlappedRequests(void)
\r
486 return WvDeviceIoControl(m_hFile, WV_IOCTL_EP_CANCEL, &m_Id, sizeof m_Id,
\r
487 NULL, 0, &bytes, NULL) ?
\r
488 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
491 STDMETHODIMP CWVDatagramEndpoint::
\r
492 GetOverlappedResult(OVERLAPPED *pOverlapped,
\r
493 DWORD *pNumberOfBytesTransferred, BOOL bWait)
\r
495 ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);
\r
496 return (HRESULT) pOverlapped->Internal;
\r
499 STDMETHODIMP CWVDatagramEndpoint::
\r
500 Modify(DWORD Option, const VOID* pOptionData, SIZE_T OptionLength)
\r
502 UNREFERENCED_PARAMETER(Option);
\r
503 UNREFERENCED_PARAMETER(pOptionData);
\r
504 UNREFERENCED_PARAMETER(OptionLength);
\r
509 STDMETHODIMP CWVDatagramEndpoint::
\r
510 BindAddress(SOCKADDR* pAddress)
\r
512 UNREFERENCED_PARAMETER(pAddress);
\r
517 STDMETHODIMP CWVDatagramEndpoint::
\r
518 Listen(SIZE_T Backlog)
\r
520 UNREFERENCED_PARAMETER(Backlog);
\r
525 STDMETHODIMP CWVDatagramEndpoint::
\r
526 Reject(const VOID* pUserData, SIZE_T UserDataLength)
\r
528 UNREFERENCED_PARAMETER(pUserData);
\r
529 UNREFERENCED_PARAMETER(UserDataLength);
\r
534 STDMETHODIMP CWVDatagramEndpoint::
\r
535 GetRequest(IWVDatagramEndpoint* pEndpoint, OVERLAPPED* pOverlapped)
\r
537 UNREFERENCED_PARAMETER(pEndpoint);
\r
538 UNREFERENCED_PARAMETER(pOverlapped);
\r
543 STDMETHODIMP CWVDatagramEndpoint::
\r
544 Lookup(const SOCKADDR* pAddress, const VOID* pUserData,
\r
545 SIZE_T UserDataLength, OVERLAPPED* pOverlapped)
\r
547 UNREFERENCED_PARAMETER(pAddress);
\r
548 UNREFERENCED_PARAMETER(pUserData);
\r
549 UNREFERENCED_PARAMETER(UserDataLength);
\r
550 UNREFERENCED_PARAMETER(pOverlapped);
\r
555 STDMETHODIMP CWVDatagramEndpoint::
\r
556 Accept(WV_DATAGRAM_PARAM* pParam, OVERLAPPED* pOverlapped)
\r
558 UNREFERENCED_PARAMETER(pParam);
\r
559 UNREFERENCED_PARAMETER(pOverlapped);
\r
564 STDMETHODIMP CWVDatagramEndpoint::
\r
565 JoinMulticast(const SOCKADDR* pAddress, OVERLAPPED* pOverlapped)
\r
567 UNREFERENCED_PARAMETER(pAddress);
\r
568 UNREFERENCED_PARAMETER(pOverlapped);
\r
573 STDMETHODIMP CWVDatagramEndpoint::
\r
574 LeaveMulticast(const SOCKADDR* pAddress, OVERLAPPED* pOverlapped)
\r
576 UNREFERENCED_PARAMETER(pAddress);
\r
577 UNREFERENCED_PARAMETER(pOverlapped);
\r
582 STDMETHODIMP CWVDatagramEndpoint::
\r
583 Query(WV_DATAGRAM_ATTRIBUTES* pAttributes)
\r
585 UNREFERENCED_PARAMETER(pAttributes);
\r