2 * Copyright (c) 2008 Intel Corporation. All rights reserved.
\r
4 * This software is available to you under the OpenIB.org BSD license
\r
7 * Redistribution and use in source and binary forms, with or
\r
8 * without modification, are permitted provided that the following
\r
9 * conditions are met:
\r
11 * - Redistributions of source code must retain the above
\r
12 * copyright notice, this list of conditions and the following
\r
15 * - Redistributions in binary form must reproduce the above
\r
16 * copyright notice, this list of conditions and the following
\r
17 * disclaimer in the documentation and/or other materials
\r
18 * provided with the distribution.
\r
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AWV
\r
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
30 #include "wv_base.h"
\r
31 #include "wv_memory.h"
\r
35 #include "wv_ioctl.h"
\r
37 CWVProtectionDomain::CWVProtectionDomain(CWVDevice *pDevice)
\r
40 m_pDevice = pDevice;
\r
41 m_pVerbs = &pDevice->m_Verbs;
\r
42 m_hFile = pDevice->m_hFile;
\r
46 STDMETHODIMP CWVProtectionDomain::
\r
51 ib_api_status_t stat;
\r
53 ci_umv_buf_t verbsData;
\r
56 stat = m_pVerbs->pre_allocate_pd(m_pDevice->m_hVerbsDevice, &verbsData,
\r
58 if (stat != IB_SUCCESS) {
\r
59 return WvConvertIbStatus(stat);
\r
62 bytes = sizeof WV_IO_ID + max(verbsData.input_size, verbsData.output_size);
\r
63 pId = (WV_IO_ID *) buf.Get(bytes);
\r
69 pId->Id = m_pDevice->m_Id;
\r
70 pId->VerbInfo = verbsData.command;
\r
71 RtlCopyMemory(pId + 1, (void *) (ULONG_PTR) verbsData.p_inout_buf,
\r
72 verbsData.input_size);
\r
74 if (WvDeviceIoControl(m_hFile, WV_IOCTL_PD_ALLOCATE,
\r
75 pId, sizeof WV_IO_ID + verbsData.input_size,
\r
76 pId, sizeof WV_IO_ID + verbsData.output_size,
\r
81 hr = HRESULT_FROM_WIN32(GetLastError());
\r
84 verbsData.status = pId->VerbInfo;
\r
85 RtlCopyMemory((void *) (ULONG_PTR) verbsData.p_inout_buf, pId + 1,
\r
86 verbsData.output_size);
\r
90 m_pVerbs->post_allocate_pd(m_pDevice->m_hVerbsDevice, (ib_api_status_t) hr,
\r
91 &m_hVerbsPd, &verbsData);
\r
95 CWVProtectionDomain::~CWVProtectionDomain()
\r
101 m_pVerbs->pre_deallocate_pd(m_hVerbsPd);
\r
102 hr = WvDeviceIoControl(m_hFile, WV_IOCTL_PD_DEALLOCATE, &m_Id, sizeof m_Id,
\r
103 NULL, 0, &bytes, NULL) ?
\r
104 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
105 m_pVerbs->post_deallocate_pd(m_hVerbsPd, (ib_api_status_t) hr);
\r
107 m_pDevice->Release();
\r
110 STDMETHODIMP CWVProtectionDomain::
\r
111 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
\r
113 if (riid != IID_IUnknown && riid != IID_IWVProtectionDomain) {
\r
115 return E_NOINTERFACE;
\r
123 STDMETHODIMP_(ULONG) CWVProtectionDomain::
\r
126 return CWVBase::AddRef();
\r
129 STDMETHODIMP_(ULONG) CWVProtectionDomain::
\r
132 return CWVBase::Release();
\r
135 STDMETHODIMP CWVProtectionDomain::
\r
136 CancelOverlappedRequests(void)
\r
140 return WvDeviceIoControl(m_hFile, WV_IOCTL_PD_CANCEL, &m_Id, sizeof m_Id,
\r
141 NULL, 0, &bytes, NULL) ?
\r
142 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
145 STDMETHODIMP CWVProtectionDomain::
\r
146 GetOverlappedResult(OVERLAPPED *pOverlapped,
\r
147 DWORD *pNumberOfBytesTransferred, BOOL bWait)
\r
149 ::GetOverlappedResult(m_hFile, pOverlapped, pNumberOfBytesTransferred, bWait);
\r
150 return (HRESULT) pOverlapped->Internal;
\r
153 STDMETHODIMP CWVProtectionDomain::
\r
154 CreateSharedReceiveQueue(SIZE_T MaxWr, SIZE_T MaxSge,
\r
155 SIZE_T SrqLimit, IWVSharedReceiveQueue** ppSrq)
\r
157 return CWVSharedReceiveQueue::CreateInstance(this, MaxWr, MaxSge,
\r
161 STDMETHODIMP CWVProtectionDomain::
\r
162 CreateConnectQueuePair(WV_QP_CREATE* pAttributes, IWVConnectQueuePair** ppQp)
\r
164 return CWVConnectQueuePair::CreateInstance(this, pAttributes, ppQp);
\r
167 STDMETHODIMP CWVProtectionDomain::
\r
168 CreateDatagramQueuePair(WV_QP_CREATE* pAttributes, IWVDatagramQueuePair** ppQp)
\r
170 return CWVDatagramQueuePair::CreateInstance(this, pAttributes, ppQp);
\r
173 STDMETHODIMP CWVProtectionDomain::
\r
174 RegisterMemory(const VOID* pBuffer, SIZE_T BufferLength, DWORD AccessFlags,
\r
175 OVERLAPPED* pOverlapped, WV_MEMORY_KEYS *pKeys)
\r
177 WV_IO_MEMORY_REGISTER reg;
\r
182 reg.Address = (UINT64) (ULONG_PTR) pBuffer;
\r
183 reg.BufferLength = BufferLength;
\r
184 reg.AccessFlags = AccessFlags;
\r
187 if (WvDeviceIoControl(m_hFile, WV_IOCTL_MEMORY_REGISTER, ®, sizeof reg,
\r
188 pKeys, sizeof WV_MEMORY_KEYS, &bytes, pOverlapped)) {
\r
191 hr = HRESULT_FROM_WIN32(GetLastError());
\r
197 STDMETHODIMP CWVProtectionDomain::
\r
198 DeregisterMemory(UINT32 Lkey, OVERLAPPED* pOverlapped)
\r
206 hr = WvDeviceIoControl(m_hFile, WV_IOCTL_MEMORY_DEREGISTER, &id, sizeof id,
\r
207 NULL, 0, &bytes, pOverlapped) ?
\r
208 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
212 STDMETHODIMP CWVProtectionDomain::
\r
213 AllocateMemoryWindow(IWVMemoryWindow** ppMw)
\r
215 return CWVMemoryWindow::CreateInstance(this, ppMw);
\r
218 STDMETHODIMP CWVProtectionDomain::
\r
219 CreateAddressHandle(WV_ADDRESS_VECTOR* pAddress, IWVAddressHandle** ppAh, ULONG_PTR *pAhKey)
\r
221 return CWVAddressHandle::CreateInstance(this, pAddress, ppAh, pAhKey);
\r
225 //-----------------------
\r
226 // Memory Window routines
\r
227 //-----------------------
\r
229 CWVMemoryWindow::CWVMemoryWindow(CWVProtectionDomain *pPd)
\r
233 m_pVerbs = pPd->m_pVerbs;
\r
234 m_hFile = pPd->m_hFile;
\r
238 STDMETHODIMP CWVMemoryWindow::
\r
243 ib_api_status_t stat;
\r
245 ci_umv_buf_t verbsData;
\r
248 stat = m_pVerbs->pre_create_mw(m_pPd->m_hVerbsPd, &verbsData, &m_hVerbsMw);
\r
249 if (stat != IB_SUCCESS) {
\r
250 return WvConvertIbStatus(stat);
\r
253 bytes = sizeof WV_IO_ID + max(verbsData.input_size, verbsData.output_size);
\r
254 pId = (WV_IO_ID *) buf.Get(bytes);
\r
260 pId->Id = m_pPd->m_Id;
\r
261 pId->VerbInfo = verbsData.command;
\r
262 RtlCopyMemory(pId + 1, (void *) (ULONG_PTR) verbsData.p_inout_buf,
\r
263 verbsData.input_size);
\r
265 if (WvDeviceIoControl(m_hFile, WV_IOCTL_MW_ALLOCATE,
\r
266 pId, sizeof WV_IO_ID + verbsData.input_size,
\r
267 pId, sizeof WV_IO_ID + verbsData.output_size,
\r
271 m_Rkey = pId->Data;
\r
273 hr = HRESULT_FROM_WIN32(GetLastError());
\r
276 verbsData.status = pId->VerbInfo;
\r
277 RtlCopyMemory((void *) (ULONG_PTR) verbsData.p_inout_buf, pId + 1,
\r
278 verbsData.output_size);
\r
282 m_pVerbs->post_create_mw(m_pPd->m_hVerbsPd, (ib_api_status_t) hr,
\r
283 m_Rkey, &m_hVerbsMw, &verbsData);
\r
287 CWVMemoryWindow::~CWVMemoryWindow()
\r
293 m_pVerbs->pre_destroy_mw(m_hVerbsMw);
\r
294 hr = WvDeviceIoControl(m_hFile, WV_IOCTL_MW_DEALLOCATE,
\r
295 &m_Id, sizeof m_Id, NULL, 0, &bytes, NULL) ?
\r
296 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
297 m_pVerbs->post_destroy_mw(m_hVerbsMw, (ib_api_status_t) hr);
\r
302 STDMETHODIMP CWVMemoryWindow::
\r
303 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
\r
305 if (riid != IID_IUnknown && riid != IID_IWVMemoryWindow) {
\r
307 return E_NOINTERFACE;
\r
315 STDMETHODIMP_(ULONG) CWVMemoryWindow::
\r
318 return CWVBase::AddRef();
\r
321 STDMETHODIMP_(ULONG) CWVMemoryWindow::
\r
324 return CWVBase::Release();
\r
328 //------------------------
\r
329 // Address Handle routines
\r
330 //------------------------
\r
332 CWVAddressHandle::CWVAddressHandle(CWVProtectionDomain *pPd)
\r
336 m_pVerbs = pPd->m_pVerbs;
\r
337 m_hFile = pPd->m_hFile;
\r
341 STDMETHODIMP CWVAddressHandle::
\r
342 Create(WV_ADDRESS_VECTOR* pAddress)
\r
344 WV_IO_AH_CREATE *pav;
\r
346 ib_api_status_t stat;
\r
348 ci_umv_buf_t verbsData;
\r
352 hr = ConvertAv(&attr, pAddress);
\r
357 stat = m_pVerbs->pre_create_av(m_pPd->m_hVerbsPd, &attr, &verbsData, &m_hVerbsAh);
\r
358 if (stat != IB_SUCCESS) {
\r
359 if (stat == IB_VERBS_PROCESSING_DONE) {
\r
360 m_Id = (ULONG_PTR) m_hVerbsAh;
\r
362 return WvConvertIbStatus(stat);
\r
365 bytes = sizeof WV_IO_AH_CREATE + max(verbsData.input_size, verbsData.output_size);
\r
366 pav = (WV_IO_AH_CREATE *) buf.Get(bytes);
\r
372 pav->Id.Id = m_pPd->m_Id;
\r
373 pav->Id.VerbInfo = verbsData.command;
\r
374 RtlCopyMemory(&pav->AddressVector, pAddress, sizeof(pav->AddressVector));
\r
375 RtlCopyMemory(pav + 1, (void *) (ULONG_PTR) verbsData.p_inout_buf,
\r
376 verbsData.input_size);
\r
378 if (WvDeviceIoControl(m_hFile, WV_IOCTL_AH_CREATE,
\r
379 pav, sizeof WV_IO_AH_CREATE + verbsData.input_size,
\r
380 pav, sizeof WV_IO_AH_CREATE + verbsData.output_size,
\r
385 hr = HRESULT_FROM_WIN32(GetLastError());
\r
388 verbsData.status = pav->Id.VerbInfo;
\r
389 RtlCopyMemory((void *) (ULONG_PTR) verbsData.p_inout_buf, pav + 1,
\r
390 verbsData.output_size);
\r
394 m_pVerbs->post_create_av(m_pPd->m_hVerbsPd, (ib_api_status_t) hr,
\r
395 &m_hVerbsAh, &verbsData);
\r
399 CWVAddressHandle::~CWVAddressHandle()
\r
403 ib_api_status_t stat;
\r
406 stat = m_pVerbs->pre_destroy_av(m_hVerbsAh);
\r
407 if (stat != IB_VERBS_PROCESSING_DONE) {
\r
408 hr = WvDeviceIoControl(m_hFile, WV_IOCTL_AH_DESTROY,
\r
409 &m_Id, sizeof m_Id, NULL, 0, &bytes, NULL) ?
\r
410 WV_SUCCESS : HRESULT_FROM_WIN32(GetLastError());
\r
411 m_pVerbs->post_destroy_av(m_hVerbsAh, (ib_api_status_t) hr);
\r
417 STDMETHODIMP CWVAddressHandle::
\r
418 QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
\r
420 if (riid != IID_IUnknown && riid != IID_IWVAddressHandle) {
\r
422 return E_NOINTERFACE;
\r
430 STDMETHODIMP_(ULONG) CWVAddressHandle::
\r
433 return CWVBase::AddRef();
\r
436 STDMETHODIMP_(ULONG) CWVAddressHandle::
\r
439 return CWVBase::Release();
\r
442 STDMETHODIMP CWVAddressHandle::
\r
443 ConvertAv(ib_av_attr_t *pVerbsAv, WV_ADDRESS_VECTOR *pAv)
\r
448 pVerbsAv->grh_valid = pAv->Route.Valid;
\r
449 if (pVerbsAv->grh_valid) {
\r
450 hr = m_pPd->m_pDevice->FindGid(pAv->PortNumber, &pAv->Route.SGid, &index);
\r
455 pVerbsAv->grh.resv1 = (UINT16) index;
\r
456 pVerbsAv->grh.ver_class_flow =
\r
457 _byteswap_ulong(_byteswap_ulong(pAv->Route.FlowLabel) |
\r
458 (pAv->Route.TrafficClass << 20));
\r
459 pVerbsAv->grh.hop_limit = pAv->Route.HopLimit;
\r
460 RtlCopyMemory(&pVerbsAv->grh.src_gid, &pAv->Route.SGid, sizeof(pAv->Route.SGid));
\r
461 RtlCopyMemory(&pVerbsAv->grh.dest_gid, &pAv->Route.DGid, sizeof(pAv->Route.DGid));
\r
464 pVerbsAv->port_num = pAv->PortNumber;
\r
465 pVerbsAv->sl = pAv->ServiceLevel;
\r
466 pVerbsAv->dlid = pAv->DLid;
\r
467 pVerbsAv->static_rate = pAv->StaticRate;
\r
468 pVerbsAv->path_bits = pAv->SourcePathBits;
\r