[ofw] [PATCH] [RFC] winverbs: driver framework

Sean Hefty sean.hefty at intel.com
Thu Apr 3 15:10:20 PDT 2008


Provide the kernel driver framework for WinVerbs.  The driver uses the KMDF
(kernel mode driver framework) and builds using the WDK.

The driver loads as an upper filter driver for InfiniBandHca class drivers.
It responds to standard PnP device add/remove device requests to track available
HCAs in the system.

A user interface is exposed through a single control device.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
The driver will install and load in response to HCA drivers.  The userspace
library can open the driver's control device and issue IOCTLs.  Currently,
the driver only responds to a GUID query request; it will return the number of
HCAs in the system, along with a made up GUID for that device.  The driver
does not yet interface directly with the HCA's direct-call verbs interface.

Inline is a partial patch that highlight's the relevant code.  (I removed some
header files that defined a few short structures that aren't currently used,
and the build info.)  The full patch is attached.

The code looks pretty if tabs are set to 4 space...


Index: wv_driver.c
===================================================================
--- wv_driver.c	(revision 0)
+++ wv_driver.c	(revision 0)
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2008 Intel Corporation. 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 AWV
+ * 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.
+ */
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <wdmsec.h>
+#include <winerror.h>
+#include <initguid.h>
+
+#include "wv_driver.h"
+#include "wv_ioctl.h"
+#include "wv_provider.h"
+#include "wv_device.h"
+#include "wv_pd.h"
+#include "wv_cq.h"
+#include "wv_srq.h"
+#include "wv_qp.h"
+#include "wv_listen.h"
+#include "wv_ep.h"
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_RDMA_DEVICE, WvGetRdmaDevice)
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(WV_PROVIDER, WvGetProvider)
+
+static WDFDEVICE	ControlDevice;
+KGUARDED_MUTEX		DevLock;
+LIST_ENTRY			DevList;
+
+static EVT_WDF_DRIVER_DEVICE_ADD			WvDeviceAdd;
+static EVT_WDF_OBJECT_CONTEXT_CLEANUP		WvDeviceCleanup;
+static EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL	WvIoDeviceControl;
+static EVT_WDF_DEVICE_FILE_CREATE			WvFileCreate;
+static EVT_WDF_FILE_CLEANUP					WvFileCleanup;
+static EVT_WDF_FILE_CLOSE					WvFileClose;
+
+static VOID WvIoDeviceControl(WDFQUEUE Queue, WDFREQUEST Request,
+							  size_t OutLen, size_t InLen, ULONG IoControlCode)
+{
+	WDFFILEOBJECT	file;
+	WV_PROVIDER		*prov;
+	UNREFERENCED_PARAMETER(OutLen);
+	UNREFERENCED_PARAMETER(InLen);
+	UNREFERENCED_PARAMETER(Queue);
+
+	file = WdfRequestGetFileObject(Request);
+	prov = WvGetProvider(file);
+
+	switch (IoControlCode) {
+	case WV_IOCTL_GUID_QUERY:
+		WvGuidQuery(Request);
+		break;
+	//case WV_IOCTL_LIBRARY_QUERY:WvLibraryQuery;break;
+	//case WV_IOCTL_DEVICE_OPEN:WvDeviceOpen;break;
+	//case WV_IOCTL_DEVICE_CLOSE:WvDeviceClose;break;
+	//case WV_IOCTL_DEVICE_QUERY:WvDevideQuery;break;
+	//case WV_IOCTL_DEVICE_PORT_QUERY:WvDevicePortQuery;break;
+	//case WV_IOCTL_DEVICE_GID_QUERY:WvDeviceGidQuery;break;
+	//case WV_IOCTL_DEVICE_PKEY_QUERY:WvDevicePkeyQuery;break;
+	//case WV_IOCTL_DEVICE_NOTIFY:WvDeviceNotify;break;
+	//case WV_IOCTL_DEVICE_CANCEL:WvDeviceCancel;break;
+	//case WV_IOCTL_PD_ALLOCATE:WvPdAllocate;break;
+	//case WV_IOCTL_PD_DEALLOCATE:WvPdDeallocate;break;
+	//case WV_IOCTL_MEMORY_REGISTER:WvMemoryRegister;break;
+	//case WV_IOCTL_MEMORY_DEREGISTER:WvmemoryDeregister;break;
+	//case WV_IOCTL_MW_ALLOCATE:WvMwAllocate;break;
+	//case WV_IOCTL_MW_DEALLOCATE:WvMwDeallocate;break;
+	//case WV_IOCTL_AH_CREATE:WvAhCreate;break;
+	//case WV_IOCTL_AH_DESTROY:WvAhDestroy;break;
+	//case WV_IOCTL_CQ_CREATE:WvCqCreate;break;
+	//case WV_IOCTL_CQ_DESTROY:WvCqDestroy;break;
+	//case WV_IOCTL_CQ_RESIZE:WvCqResize;break;
+	//case WV_IOCTL_CQ_NOTIFY:WvCqNotify;break;
+	//case WV_IOCTL_CQ_BATCH_NOTIFY:WvCqBatchNotify;break;
+	//case WV_IOCTL_CQ_CANCEL:WvCqCancel;break;
+	//case WV_IOCTL_SRQ_CREATE :WvSrqCreate;break;
+	//case WV_IOCTL_SRQ_DESTROY:WvSrqDestroy;break;
+	//case WV_IOCTL_SRQ_QUERY:WvSrqQuery;break;
+	//case WV_IOCTL_SRQ_MODIFY:WvSrqModify;break;
+	//case WV_IOCTL_SRQ_NOTIFY:WvSrqNotify;break;
+	//case WV_IOCTL_SRQ_CANCEL:WvSrqCancel;break;
+	//case WV_IOCTL_QP_CREATE:WvQpCreate;break;
+	//case WV_IOCTL_QP_DESTROY:WvQpDestroy;break;
+	//case WV_IOCTL_QP_QUERY:WvQpQuery;break;
+	//case WV_IOCTL_QP_MODIFY:WvQpModify;break;
+	//case WV_IOCTL_QP_ATTACH:WvQpAttach;break;
+	//case WV_IOCTL_QP_DETACH:WvQpDetach;break;
+	//case WV_IOCTL_QP_CANCEL:WvQpCancel;break;
+	//case WV_IOCTL_ADDRESS_QUERY:WvAddressQuery;break;
+	//case WV_IOCTL_EP_CREATE:WvEpCreate;break;
+	//case WV_IOCTL_EP_DESTROY:WvEpDestroy;break;
+	//case WV_IOCTL_EP_BIND:WvEpBind;break;
+	//case WV_IOCTL_EP_REJECT:WvEpReject;break;
+	//case WV_IOCTL_EP_CONNECT:WvEpConnect;break;
+	//case WV_IOCTL_EP_ACCEPT:WvEpAccept;break;
+	//case WV_IOCTL_EP_DISCONNECT:WvEpDisconnect;break;
+	//case WV_IOCTL_EP_DISCONNECT_NOTIFY:WvEpDisconnectNotify;break;
+	//case WV_IOCTL_EP_QUERY:WvEpQuery;break;
+	//case WV_IOCTL_EP_LOOKUP:WvEpLookup;break;
+	//case WV_IOCTL_EP_MULTICAST_JOIN:WvEpMulticastJoin;break;
+	//case WV_IOCTL_EP_MULTICAST_LEAVE:WvEpMulticastLeave;break;
+	//case WV_IOCTL_EP_CANCEL:WvEpCancel;break;
+	//case WV_IOCTL_LISTEN:WvListen;break;
+	//case WV_IOCTL_LISTEN_DESTROY:WvListenDestroy;break;
+	//case WV_IOCTL_LISTEN_GET_REQUEST:WvListenGetRequest;break;
+	//case WV_IOCTL_LISTEN_CANCEL:WvListenCancel;break;
+	default:
+		WdfRequestComplete(Request, E_NOINTERFACE);
+		break;
+	}
+}
+
+static VOID WvFileCreate(WDFDEVICE Device, WDFREQUEST Request,
+						 WDFFILEOBJECT FileObject)
+{
+	WV_PROVIDER	*prov;
+
+	UNREFERENCED_PARAMETER(Device);
+
+	prov = WvGetProvider(FileObject);
+	WvProviderInit(prov);
+	WdfRequestComplete(Request, STATUS_SUCCESS);
+}
+
+static VOID WvFileCleanup(WDFFILEOBJECT FileObject)
+{
+	UNREFERENCED_PARAMETER(FileObject);
+}
+
+static VOID WvFileClose(WDFFILEOBJECT FileObject)
+{
+	WV_PROVIDER *prov;
+
+	prov = WvGetProvider(FileObject);
+	WvProviderDestroy(prov);
+}
+
+static VOID WvCreateControlDevice(WDFDRIVER Driver)
+{
+	PWDFDEVICE_INIT			pinit;
+	WDF_FILEOBJECT_CONFIG	fileconfig;
+	WDF_OBJECT_ATTRIBUTES	attr;
+	WDF_IO_QUEUE_CONFIG		ioconfig;
+	NTSTATUS				status;
+	WDFQUEUE				queue;
+	DECLARE_CONST_UNICODE_STRING(name, L"\\Device\\WinVerbs");
+	DECLARE_CONST_UNICODE_STRING(symlink, L"\\DosDevices\\WinVerbs");
+
+	pinit = WdfControlDeviceInitAllocate(Driver,
+
&SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R);
+	if (pinit == NULL) {
+			return;
+	}
+
+	WdfDeviceInitSetExclusive(pinit, FALSE);
+	status = WdfDeviceInitAssignName(pinit, &name);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+
+	WDF_FILEOBJECT_CONFIG_INIT(&fileconfig, WvFileCreate, WvFileClose,
+							   WvFileCleanup);
+	WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, WV_PROVIDER);
+	WdfDeviceInitSetFileObjectConfig(pinit, &fileconfig, &attr);
+
+	WDF_OBJECT_ATTRIBUTES_INIT(&attr);
+	status = WdfDeviceCreate(&pinit, &attr, &ControlDevice);
+	if (!NT_SUCCESS(status)) {
+		goto err1;
+	}
+
+	status = WdfDeviceCreateSymbolicLink(ControlDevice, &symlink);
+	if (!NT_SUCCESS(status)) {
+		goto err2;
+	}
+
+	WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioconfig, WdfIoQueueDispatchParallel);
+	ioconfig.EvtIoDeviceControl = WvIoDeviceControl;
+	status = WdfIoQueueCreate(ControlDevice, &ioconfig,
+							  WDF_NO_OBJECT_ATTRIBUTES, &queue);
+	if (!NT_SUCCESS(status)) {
+		goto err2;
+	}
+
+	WdfControlFinishInitializing(ControlDevice);
+	return;
+
+err2:
+	WdfObjectDelete(ControlDevice);
+err1:
+	WdfDeviceInitFree(pinit);
+}
+
+static NTSTATUS WvDeviceAdd(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
+{
+	WDF_OBJECT_ATTRIBUTES	attr;
+	WDFDEVICE				dev;
+	NTSTATUS				status;
+	WV_RDMA_DEVICE			*pdev;
+	BOOLEAN					create;
+
+	WdfFdoInitSetFilter(DeviceInit);
+
+	WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, WV_RDMA_DEVICE);
+	attr.EvtCleanupCallback = WvDeviceCleanup;
+	status = WdfDeviceCreate(&DeviceInit, &attr, &dev);
+	if (!NT_SUCCESS(status)) {
+		return status;
+	}
+
+	pdev = WvGetRdmaDevice(dev);
+	pdev->Guid = 0x1234567890ABCDEF;
+
+	KeAcquireGuardedMutex(&DevLock);
+	create = IsListEmpty(&DevList);
+	InsertHeadList(&DevList, &pdev->Entry);
+	KeReleaseGuardedMutex(&DevLock);
+
+	if (create) {
+		WvCreateControlDevice(Driver);
+	}
+
+	return status;
+}
+
+static VOID WvDeviceCleanup(WDFDEVICE Device)
+{
+	WV_RDMA_DEVICE			*pdev;
+	BOOLEAN					destroy;
+	WDFDEVICE				ctrldev;
+
+	pdev = WvGetRdmaDevice(Device);
+	KeAcquireGuardedMutex(&DevLock);
+	RemoveEntryList(&pdev->Entry);
+	destroy = IsListEmpty(&DevList);
+	ctrldev = ControlDevice;
+	KeReleaseGuardedMutex(&DevLock);
+
+	if (destroy) {
+		WdfObjectDelete(ctrldev);
+	}
+}
+
+NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
+{
+	WDF_DRIVER_CONFIG		config;
+	NTSTATUS				status;
+	WDFDRIVER				driv;
+
+	InitializeListHead(&DevList);
+	KeInitializeGuardedMutex(&DevLock);
+
+	WDF_DRIVER_CONFIG_INIT(&config, WvDeviceAdd);
+	status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES,
+							 &config, &driv);
+	if (!NT_SUCCESS(status)) {
+		return status;
+	}
+
+	return STATUS_SUCCESS;
+}
Index: wv_driver.h
===================================================================
--- wv_driver.h	(revision 0)
+++ wv_driver.h	(revision 0)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008 Intel Corporation. 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 AWV
+ * 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.
+ */
+
+#pragma once
+
+#ifndef _WV_DRIVER_H_
+#define _WV_DRIVER_H_
+
+#include <ntddk.h>
+#include <wdm.h>
+#include <iba\ib_types.h>
+#include <iba\ib_ci.h>
+
+typedef struct _WV_RDMA_DEVICE
+{
+	UINT64			Guid;
+	LIST_ENTRY		Entry;
+	ci_interface_t	Verbs;
+	ib_ca_handle_t	hVerbsDevice;
+
+}	WV_RDMA_DEVICE;
+
+extern KGUARDED_MUTEX	DevLock;
+extern LIST_ENTRY		DevList;
+
+#endif // _WV_DRIVER_H_
Index: wv_provider.c
===================================================================
--- wv_provider.c	(revision 0)
+++ wv_provider.c	(revision 0)
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2008 Intel Corporation. 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 AWV
+ * 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.
+ */
+
+#include <winerror.h>
+
+#include <rdma\wvstatus.h>
+#include "wv_driver.h"
+#include "wv_ioctl.h"
+#include "wv_provider.h"
+#include "wv_device.h"
+
+void WvGuidQuery(WDFREQUEST Request)
+{
+	WV_IO_GUID_LIST	*pioGuids;
+	size_t			len = 0;
+	WV_RDMA_DEVICE	*pdev;
+	ULONG			count, i;
+	LIST_ENTRY		*pentry;
+	NTSTATUS		status;
+
+	status = WdfRequestRetrieveOutputBuffer(Request, sizeof(WV_IO_GUID_LIST),
+											&pioGuids, &len);
+	if (!NT_SUCCESS(status)) {
+		goto out;
+	}
+
+	count = (len - sizeof(UINT64)) / sizeof(UINT64);
+	i = 0;
+	len = sizeof(UINT64);
+	KeAcquireGuardedMutex(&DevLock);
+	for (pentry = DevList.Flink; pentry != &DevList; pentry = pentry->Flink) {
+		pdev = CONTAINING_RECORD(pentry, WV_RDMA_DEVICE, Entry);
+		if (i < count) {
+			pioGuids->Guid[i] = pdev->Guid;
+			len += sizeof(UINT64);
+		}
+		i++;
+	}
+	pioGuids->Count = i;
+	KeReleaseGuardedMutex(&DevLock);
+
+out:
+	WdfRequestCompleteWithInformation(Request, status, len);
+}
+
+void WvProviderInit(WV_PROVIDER *pProvider)
+{
+	InitializeListHead(&pProvider->DevList);
+	KeInitializeGuardedMutex(&pProvider->Lock);
+}
+
+void WvProviderDestroy(WV_PROVIDER *pProvider)
+{
+	LIST_ENTRY *entry;
+	WV_DEVICE *dev;
+
+	while (!IsListEmpty(&pProvider->DevList)) {
+		entry = RemoveHeadList(&pProvider->DevList);
+		dev = CONTAINING_RECORD(entry, WV_DEVICE, Entry);
+		//WvDeviceDestroy(dev);
+	}
+}
Index: wv_provider.h
===================================================================
--- wv_provider.h	(revision 0)
+++ wv_provider.h	(revision 0)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2008 Intel Corporation. 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 AWV
+ * 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.
+ */
+
+#pragma once
+
+#ifndef _WV_PROVIDER_H_
+#define _WV_PROVIDER_H_
+
+#include <ntddk.h>
+#include <wdf.h>
+#include <wdm.h>
+
+typedef struct _WV_PROVIDER
+{
+	KGUARDED_MUTEX	Lock;
+	LIST_ENTRY		DevList;
+
+}	WV_PROVIDER;
+
+void WvProviderInit(WV_PROVIDER *pProvider);
+void WvProviderDestroy(WV_PROVIDER *pProvider);
+
+void WvGuidQuery(WDFREQUEST Request);
+
+#endif // _WV_PROVIDER_H_

-------------- next part --------------
A non-text attachment was scrubbed...
Name: wv-driver.patch
Type: application/octet-stream
Size: 34722 bytes
Desc: not available
URL: <http://lists.openfabrics.org/pipermail/ofw/attachments/20080403/8c7ab03f/attachment.obj>


More information about the ofw mailing list