From: shefty Date: Thu, 11 Dec 2008 21:32:27 +0000 (+0000) Subject: winmad: initial working kernel driver X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=188cd3bb6daf4cabe7e2f57cbb5cd175b7306246;p=~shefty%2Frdma-win.git winmad: initial working kernel driver git-svn-id: svn://openib.tc.cornell.edu/gen1@1779 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/branches/winverbs/core/winmad/kernel/winmad.inx b/branches/winverbs/core/winmad/kernel/winmad.inx index 18cbe735..89427ae9 100644 --- a/branches/winverbs/core/winmad/kernel/winmad.inx +++ b/branches/winverbs/core/winmad/kernel/winmad.inx @@ -29,7 +29,7 @@ [Version] Signature = "$WINDOWS NT$" -Class = InfiniBandHca +Class = InfiniBandController ClassGUID = {58517E00-D3CF-40c9-A679-CEE5752F4491} Provider = %OFA% DriverVer = 05/20/2008 diff --git a/branches/winverbs/core/winmad/kernel/wm_driver.c b/branches/winverbs/core/winmad/kernel/wm_driver.c index dc5ee20e..8ac92b66 100644 --- a/branches/winverbs/core/winmad/kernel/wm_driver.c +++ b/branches/winverbs/core/winmad/kernel/wm_driver.c @@ -56,20 +56,30 @@ static EVT_WDF_DEVICE_FILE_CREATE WmFileCreate; static EVT_WDF_FILE_CLEANUP WmFileCleanup; static EVT_WDF_FILE_CLOSE WmFileClose; -WM_IB_DEVICE *WmIbDeviceGet(NET64 Guid) +static WM_IB_DEVICE *WmIbDeviceFind(NET64 Guid) { WM_IB_DEVICE *cur_dev, *dev = NULL; LIST_ENTRY *entry; - KeAcquireGuardedMutex(&Lock); for (entry = DevList.Flink; entry != &DevList; entry = entry->Flink) { cur_dev = CONTAINING_RECORD(entry, WM_IB_DEVICE, Entry); if (cur_dev->Guid == Guid) { - InterlockedIncrement(&cur_dev->Ref); dev = cur_dev; break; } } + return dev; +} + +WM_IB_DEVICE *WmIbDeviceGet(NET64 Guid) +{ + WM_IB_DEVICE *dev; + + KeAcquireGuardedMutex(&Lock); + dev = WmIbDeviceFind(Guid); + if (dev != NULL) { + InterlockedIncrement(&dev->Ref); + } KeReleaseGuardedMutex(&Lock); return dev; } @@ -101,8 +111,7 @@ static VOID WmIoDeviceControl(WDFQUEUE Queue, WDFREQUEST Request, WmDeregister(prov, Request); break; case WM_IOCTL_CANCEL: - // TODO!!! - WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED); + WmProviderCancel(prov, Request); break; default: WdfRequestComplete(Request, STATUS_PROCEDURE_NOT_FOUND); @@ -118,7 +127,6 @@ static VOID WmIoRead(WDFQUEUE Queue, WDFREQUEST Request, size_t Length) file = WdfRequestGetFileObject(Request); prov = WmProviderGetContext(file); - WmProviderRead(prov, Request); } @@ -130,7 +138,6 @@ static VOID WmIoWrite(WDFQUEUE Queue, WDFREQUEST Request, size_t Length) file = WdfRequestGetFileObject(Request); prov = WmProviderGetContext(file); - WmProviderWrite(prov, Request); } @@ -221,29 +228,47 @@ err1: WdfDeviceInitFree(pinit); } -static NTSTATUS WmInitIbPorts(WM_IB_DEVICE *pDevice) +static ib_ca_attr_t *WmQueryCaAttributes(WM_IB_DEVICE *pDevice) { - NTSTATUS status; - ib_api_status_t ib_status; ib_ca_attr_t *attr; UINT32 size; - UINT8 i; + ib_api_status_t ib_status; size = 0; - ib_status = pDevice->IbInterface.query_ca(pDevice->hDevice, NULL, &size); + ib_status = pDevice->VerbsInterface.Verbs. + query_ca(pDevice->VerbsInterface.Verbs.p_hca_dev, NULL, &size, NULL); if (ib_status != IB_INSUFFICIENT_MEMORY) { - return STATUS_UNSUCCESSFUL; + attr = NULL; + goto out; } attr = ExAllocatePoolWithTag(PagedPool, size, 'acmw'); if (attr == NULL) { - return STATUS_NO_MEMORY; + goto out; } - ib_status = pDevice->IbInterface.query_ca(pDevice->hDevice, attr, &size); + ib_status = pDevice->VerbsInterface.Verbs. + query_ca(pDevice->VerbsInterface.Verbs.p_hca_dev, attr, &size, NULL); if (ib_status != IB_SUCCESS) { - status = STATUS_UNSUCCESSFUL; - goto out; + ExFreePool(attr); + attr = NULL; + } + +out: + return attr; +} + +static NTSTATUS WmAddCa(WM_IB_DEVICE *pDevice) +{ + NTSTATUS status; + ib_api_status_t ib_status; + ib_ca_attr_t *attr; + UINT32 size; + UINT8 i; + + attr = WmQueryCaAttributes(pDevice); + if (attr == NULL) { + return STATUS_NO_MEMORY; } size = sizeof(WM_IB_PORT) * attr->num_ports; @@ -264,55 +289,6 @@ out: return status; } -static NTSTATUS WmInitIbDevice(WDFDEVICE Device, WM_IB_DEVICE *pDevice) -{ - NTSTATUS status; - ib_api_status_t ib_status; - - status = WdfFdoQueryForInterface(Device, &GUID_IB_AL_INTERFACE, - (PINTERFACE) &pDevice->IbInterface, - sizeof(pDevice->IbInterface), - AL_INTERFACE_VERSION, NULL); - if (!NT_SUCCESS(status)) { - return status; - } - - ib_status = pDevice->IbInterface.open_al(&pDevice->hIbal); - if (ib_status != IB_SUCCESS) { - goto err1; - } - - ib_status = pDevice->IbInterface.open_ca(pDevice->hIbal, pDevice->Guid, - NULL, pDevice, &pDevice->hDevice); - if (ib_status != IB_SUCCESS) { - goto err2; - } - - ib_status = pDevice->IbInterface.alloc_pd(pDevice->hDevice, IB_PDT_ALIAS, - pDevice, &pDevice->hPd); - if (ib_status != IB_SUCCESS) { - goto err3; - } - - status = WmInitIbPorts(pDevice); - if (!NT_SUCCESS(status)) { - goto err4; - } - - return STATUS_SUCCESS; - -err4: - pDevice->IbInterface.dealloc_pd(pDevice->hPd, NULL); -err3: - pDevice->IbInterface.close_ca(pDevice->hDevice, NULL); -err2: - pDevice->IbInterface.close_al(pDevice->hIbal); - pDevice->hIbal = NULL; -err1: - pDevice->IbInterface.wdm.InterfaceDereference(pDevice->IbInterface.wdm.Context); - return STATUS_UNSUCCESSFUL; -} - static NTSTATUS WmPowerD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState) { WM_IB_DEVICE *dev; @@ -320,10 +296,6 @@ static NTSTATUS WmPowerD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE Previous NTSTATUS status; dev = WmIbDeviceGetContext(Device); - if (dev->hIbal != NULL) { - return STATUS_SUCCESS; - } - status = WdfFdoQueryForInterface(Device, &GUID_RDMA_INTERFACE_VERBS, (PINTERFACE) &dev->VerbsInterface, sizeof(dev->VerbsInterface), VerbsVersion(2, 0), @@ -333,9 +305,18 @@ static NTSTATUS WmPowerD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE Previous } dev->Guid = dev->VerbsInterface.Verbs.guid; - dev->IbInterface.wdm.InterfaceDereference(dev->IbInterface.wdm.Context); + status = WmAddCa(dev); + + dev->VerbsInterface.InterfaceHeader.InterfaceDereference(dev->VerbsInterface. + InterfaceHeader.Context); + if (!NT_SUCCESS(status)) { + return status; + } - status = WmInitIbDevice(Device, dev); + status = WdfFdoQueryForInterface(Device, &GUID_IB_AL_INTERFACE, + (PINTERFACE) &dev->IbInterface, + sizeof(dev->IbInterface), + AL_INTERFACE_VERSION, NULL); if (!NT_SUCCESS(status)) { return status; } @@ -348,7 +329,6 @@ static NTSTATUS WmPowerD0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE Previous if (create) { WmCreateControlDevice(WdfGetDriver()); } - return STATUS_SUCCESS; } @@ -391,10 +371,7 @@ static VOID WmIbDeviceCleanup(WDFDEVICE Device) BOOLEAN destroy; WDFDEVICE ctrldev; - pdev = WmIbDeviceGetContext(Device); - if (pdev->hIbal == NULL) { - return; - } + pdev = (WmIbDeviceGetContext(Device)); KeAcquireGuardedMutex(&Lock); RemoveEntryList(&pdev->Entry); @@ -404,19 +381,17 @@ static VOID WmIbDeviceCleanup(WDFDEVICE Device) for (entry = ProvList.Flink; entry != &ProvList; entry = entry->Flink) { prov = CONTAINING_RECORD(entry, WM_PROVIDER, Entry); WmProviderRemoveHandler(prov, pdev); - } - + } KeReleaseGuardedMutex(&Lock); if (InterlockedDecrement(&pdev->Ref) > 0) { KeWaitForSingleObject(&pdev->Event, Executive, KernelMode, FALSE, NULL); } - ExFreePool(pdev->pPortArray); - pdev->IbInterface.dealloc_pd(pdev->hPd, NULL); - pdev->IbInterface.close_ca(pdev->hDevice, NULL); - pdev->IbInterface.close_al(pdev->hIbal); pdev->IbInterface.wdm.InterfaceDereference(pdev->IbInterface.wdm.Context); + if (pdev->pPortArray != NULL) { + ExFreePool(pdev->pPortArray); + } if (destroy) { WdfObjectDelete(ctrldev); diff --git a/branches/winverbs/core/winmad/kernel/wm_driver.h b/branches/winverbs/core/winmad/kernel/wm_driver.h index c1c308ae..423b1bf8 100644 --- a/branches/winverbs/core/winmad/kernel/wm_driver.h +++ b/branches/winverbs/core/winmad/kernel/wm_driver.h @@ -67,8 +67,9 @@ typedef struct _WM_IB_DEVICE ib_al_ifc_t IbInterface; }; ib_al_handle_t hIbal; - ib_ca_handle_t hDevice; - ib_pd_handle_t hPd; + ib_pnp_handle_t hPnp; + //ib_ca_handle_t hDevice; + //ib_pd_handle_t hPd; int PortCount; WM_IB_PORT *pPortArray; diff --git a/branches/winverbs/core/winmad/kernel/wm_provider.c b/branches/winverbs/core/winmad/kernel/wm_provider.c index 372e501c..7efdba3d 100644 --- a/branches/winverbs/core/winmad/kernel/wm_provider.c +++ b/branches/winverbs/core/winmad/kernel/wm_provider.c @@ -89,7 +89,6 @@ static ib_mad_element_t *WmRemoveMad(WM_PROVIDER *pProvider) pProvider->MadHead = (ib_mad_element_t *) mad->p_next; mad->p_next = NULL; } - return mad; } @@ -105,7 +104,7 @@ void WmProviderFlushReceives(WM_PROVIDER *pProvider, WM_REGISTRATION *pRegistrat next = mad->p_next; mad->p_next = NULL; - if (mad->context1 == pRegistration) { + if (mad->send_context1 == pRegistration) { pRegistration->pDevice->IbInterface.put_mad(mad); } else { WmInsertMad(pProvider, mad); @@ -119,7 +118,6 @@ void WmProviderCleanup(WM_PROVIDER *pProvider) WM_REGISTRATION *reg; while ((reg = IndexListRemoveHead(&pProvider->RegIndex)) != NULL) { - RemoveEntryList(®->Entry); WmRegFree(reg); } @@ -220,7 +218,7 @@ static NTSTATUS WmCopyRead(WM_PROVIDER *pProvider, WM_IO_MAD *pIoMad, { WM_REGISTRATION *reg; - reg = (WM_REGISTRATION *) pMad->context1; + reg = (WM_REGISTRATION *) pMad->send_context1; pIoMad->Id = reg->Id; pIoMad->Status = pMad->status; @@ -280,7 +278,7 @@ void WmProviderRead(WM_PROVIDER *pProvider, WDFREQUEST Request) len = outlen; status = WmCopyRead(pProvider, wmad, pProvider->MadHead, &len); if (NT_SUCCESS(status)) { - reg = (WM_REGISTRATION *) pProvider->MadHead->context1; + reg = (WM_REGISTRATION *) pProvider->MadHead->send_context1; reg->pDevice->IbInterface.put_mad(WmRemoveMad(pProvider)); } WdfObjectReleaseLock(pProvider->ReadQueue); @@ -304,7 +302,6 @@ static NTSTATUS WmSendMad(WM_REGISTRATION *pRegistration, WM_IO_MAD *pIoMad, UIN mad->context1 = pRegistration; RtlCopyMemory(mad->p_mad_buf, pIoMad + 1, size); - mad->size = size; mad->remote_qp = pIoMad->Address.Qpn; mad->remote_qkey = pIoMad->Address.Qkey; mad->resp_expected = (pIoMad->Timeout > 0); @@ -323,6 +320,7 @@ static NTSTATUS WmSendMad(WM_REGISTRATION *pRegistration, WM_IO_MAD *pIoMad, UIN mad->remote_sl = pIoMad->Address.ServiceLevel; mad->pkey_index = pIoMad->Address.PkeyIndex; mad->path_bits = pIoMad->Address.PathBits; + mad->p_mad_buf->trans_id &= 0xFFFFFFFF00000000; ib_status = pifc->send_mad(pRegistration->hService, mad, NULL); if (ib_status != IB_SUCCESS) { @@ -344,7 +342,7 @@ void WmProviderWrite(WM_PROVIDER *pProvider, WDFREQUEST Request) WM_IO_MAD *wmad; size_t inlen; - status = WdfRequestRetrieveInputBuffer(Request, sizeof(WM_IO_MAD) + 256, + status = WdfRequestRetrieveInputBuffer(Request, sizeof(WM_IO_MAD) + 24, &wmad, &inlen); if (!NT_SUCCESS(status)) { goto out; @@ -385,14 +383,14 @@ void WmReceiveHandler(ib_mad_svc_handle_t hService, void *Context, status = WdfRequestRetrieveOutputBuffer(request, sizeof(WM_IO_MAD), &wmad, &len); if (!NT_SUCCESS(status)) { - reg = (WM_REGISTRATION *) pMad->context1; + reg = (WM_REGISTRATION *) pMad->send_context1; reg->pDevice->IbInterface.put_mad(pMad); goto out; } status = WmCopyRead(prov, wmad, pMad, &len); if (NT_SUCCESS(status)) { - reg = (WM_REGISTRATION *) pMad->context1; + reg = (WM_REGISTRATION *) pMad->send_context1; reg->pDevice->IbInterface.put_mad(pMad); } else { WmInsertMad(prov, pMad); @@ -406,9 +404,12 @@ out: void WmSendHandler(ib_mad_svc_handle_t hService, void *Context, ib_mad_element_t *pMad) { - WM_PROVIDER *prov = Context; - UNREFERENCED_PARAMETER(hService); - pMad; + if (pMad->status == IB_SUCCESS) { + ((WM_REGISTRATION *) pMad->context1)->pDevice->IbInterface.put_mad(pMad); + } else { + pMad->send_context1 = (void*) pMad->context1; + WmReceiveHandler(hService, Context, pMad); + } } void WmProviderCancel(WM_PROVIDER *pProvider, WDFREQUEST Request) diff --git a/branches/winverbs/core/winmad/kernel/wm_provider.h b/branches/winverbs/core/winmad/kernel/wm_provider.h index 0873b075..d35b87fb 100644 --- a/branches/winverbs/core/winmad/kernel/wm_provider.h +++ b/branches/winverbs/core/winmad/kernel/wm_provider.h @@ -77,5 +77,6 @@ void WmSendHandler(ib_mad_svc_handle_t hService, void *Context, ib_mad_element_t *pMad); void WmProviderFlushReceives(WM_PROVIDER *pProvider, struct _WM_REGISTRATION *pRegistration); +void WmProviderCancel(WM_PROVIDER *pProvider, WDFREQUEST Request); #endif // _WM_PROVIDER_H_ diff --git a/branches/winverbs/core/winmad/kernel/wm_reg.c b/branches/winverbs/core/winmad/kernel/wm_reg.c index 8b9ca84b..94d61915 100644 --- a/branches/winverbs/core/winmad/kernel/wm_reg.c +++ b/branches/winverbs/core/winmad/kernel/wm_reg.c @@ -46,7 +46,6 @@ WM_REGISTRATION *WmRegAcquire(WM_PROVIDER *pProvider, UINT64 Id) WmProviderEnableRemove(pProvider); } KeReleaseGuardedMutex(&pProvider->Lock); - return reg; } @@ -85,7 +84,6 @@ static int WmConvertMethods(ib_mad_svc_t *svc, WM_IO_REGISTER *pAttributes) } } } - return unsolicited; } @@ -97,6 +95,7 @@ static NTSTATUS WmRegInit(WM_REGISTRATION *pRegistration, WM_IO_REGISTER *pAttri ib_api_status_t ib_status; NTSTATUS status; + RtlZeroMemory(&attr, sizeof attr); if (pAttributes->Qpn == 0) { attr.qp_type = IB_QPT_QP0_ALIAS; } else if (pAttributes->Qpn == IB_QP1) { @@ -115,19 +114,36 @@ static NTSTATUS WmRegInit(WM_REGISTRATION *pRegistration, WM_IO_REGISTER *pAttri goto err1; } - RtlZeroMemory(&attr, sizeof attr); + ib_status = dev->IbInterface.open_al(&pRegistration->hIbal); + if (ib_status != IB_SUCCESS) { + status = STATUS_UNSUCCESSFUL; + goto err1; + } + + ib_status = dev->IbInterface.open_ca(pRegistration->hIbal, pAttributes->Guid, + NULL, NULL, &pRegistration->hCa); + if (ib_status != IB_SUCCESS) { + goto err2; + } + + ib_status = dev->IbInterface.alloc_pd(pRegistration->hCa, IB_PDT_ALIAS, + NULL, &pRegistration->hPd); + if (ib_status != IB_SUCCESS) { + goto err3; + } + attr.sq_depth = attr.rq_depth = 1; attr.sq_sge = attr.rq_sge = 1; attr.sq_signaled = 1; - ib_status = dev->IbInterface.get_spl_qp(dev->hPd, + ib_status = dev->IbInterface.get_spl_qp(pRegistration->hPd, dev->pPortArray[pAttributes->Port].Guid, &attr, pRegistration, NULL, &pRegistration->hMadPool, &pRegistration->hQp); if (ib_status != IB_SUCCESS) { status = STATUS_UNSUCCESSFUL; - goto err1; + goto err4; } svc.mad_svc_context = pRegistration->pProvider; @@ -142,14 +158,20 @@ static NTSTATUS WmRegInit(WM_REGISTRATION *pRegistration, WM_IO_REGISTER *pAttri &pRegistration->hService); if (ib_status != IB_SUCCESS) { status = STATUS_UNSUCCESSFUL; - goto err2; + goto err5; } pRegistration->pDevice = dev; return STATUS_SUCCESS; -err2: +err5: dev->IbInterface.destroy_qp(pRegistration->hQp, NULL); +err4: + dev->IbInterface.dealloc_pd(pRegistration->hPd, NULL); +err3: + dev->IbInterface.close_ca(pRegistration->hCa, NULL); +err2: + dev->IbInterface.close_al(pRegistration->hIbal); err1: WmIbDevicePut(dev); pRegistration->pDevice = NULL; @@ -253,6 +275,10 @@ void WmRegRemoveHandler(WM_REGISTRATION *pRegistration) } pRegistration->pDevice->IbInterface.destroy_qp(pRegistration->hQp, NULL); + pRegistration->pDevice->IbInterface.dealloc_pd(pRegistration->hPd, NULL); + pRegistration->pDevice->IbInterface.close_ca(pRegistration->hCa, NULL); + pRegistration->pDevice->IbInterface.close_al(pRegistration->hIbal); + WmProviderFlushReceives(pRegistration->pProvider, pRegistration); WmIbDevicePut(pRegistration->pDevice); pRegistration->pDevice = NULL; diff --git a/branches/winverbs/core/winmad/kernel/wm_reg.h b/branches/winverbs/core/winmad/kernel/wm_reg.h index 4dd03ccb..7de4acc6 100644 --- a/branches/winverbs/core/winmad/kernel/wm_reg.h +++ b/branches/winverbs/core/winmad/kernel/wm_reg.h @@ -43,8 +43,10 @@ typedef struct _WM_REGISTRATION { WM_PROVIDER *pProvider; WM_IB_DEVICE *pDevice; - LIST_ENTRY Entry; + ib_al_handle_t hIbal; + ib_ca_handle_t hCa; + ib_pd_handle_t hPd; ib_qp_handle_t hQp; ib_pool_key_t hMadPool; ib_mad_svc_handle_t hService;