[ofw] [RFC] [PATCH 2/4] mthca: respond to query interface IOCTL

Sean Hefty sean.hefty at intel.com
Tue Apr 22 16:35:17 PDT 2008


Enhance mthca to respond to a query interface IOCTL by drivers trying
to obtain the verbs interface.

Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Additional changes are needed to the mthca driver in order to support
multiple users of the interface.  For example, completion callbacks would
need to be set on a per CQ basis, rather than having one callback system
wide.  This would improve performance by allow direct callbacks into
the appropriate driver, rather than making indirect calls through IBAL,
which then forwards the notification for a fast path operation.

Index: hca_pnp.c
===================================================================
--- hca_pnp.c	(revision 1006)
+++ hca_pnp.c	(working copy)
@@ -12,6 +12,7 @@
 
 #include "hca_driver.h"
 #include "mthca_dev.h"
+#include <rdma\verbs.h>
 
 #if defined(EVENT_TRACING)
 #ifdef offsetof
@@ -23,6 +24,9 @@
 #include <initguid.h>
 #include <wdmguid.h>
 
+#define MTHCA_VERBS_MIN_VERSION		2
+#define MTHCA_VERBS_MAX_VERSION		2
+
 extern const char *mthca_version;
 
 static NTSTATUS
@@ -112,6 +116,12 @@
 	IN				hca_dev_ext_t* const		p_ext );
 
 static NTSTATUS
+hca_query_interface(
+	IN				DEVICE_OBJECT* const		p_dev_obj,
+	IN				IRP* const					p_irp, 
+		OUT			cl_irp_action_t* const		p_action );
+
+static NTSTATUS
 __get_ci_interface(
 	IN				DEVICE_OBJECT* const		p_dev_obj );
 
@@ -145,6 +155,7 @@
 #pragma alloc_text (PAGE, hca_cancel_remove)
 #pragma alloc_text (PAGE, hca_surprise_remove)
 #pragma alloc_text (PAGE, hca_query_capabilities)
+#pragma alloc_text (PAGE, hca_query_interface)
 #pragma alloc_text (PAGE, hca_query_pnp_state)
 #pragma alloc_text (PAGE, hca_query_bus_relations)
 #pragma alloc_text (PAGE, hca_query_removal_relations)
@@ -185,7 +196,7 @@
 	vfptrHcaPnp.pfn_query_resources = cl_irp_ignore;
 	vfptrHcaPnp.pfn_query_res_req = cl_irp_ignore;
 	vfptrHcaPnp.pfn_query_bus_info = cl_irp_ignore;
-	vfptrHcaPnp.pfn_query_interface = cl_irp_ignore;
+	vfptrHcaPnp.pfn_query_interface = hca_query_interface;
 	vfptrHcaPnp.pfn_read_config = cl_irp_ignore;
 	vfptrHcaPnp.pfn_write_config = cl_irp_ignore;
 	vfptrHcaPnp.pfn_eject = cl_irp_ignore;
@@ -1249,7 +1260,114 @@
 }
 
 
+static VOID
+__hca_noop( VOID *context )
+{
+	UNREFERENCED_PARAMETER(context);
+}
+
+
 static NTSTATUS
+__query_ci_ifc(
+	IN					DEVICE_OBJECT* const		p_dev_obj,
+	IN					IO_STACK_LOCATION* const	p_io_stack )
+{
+	RDMA_INTERFACE_VERBS	*p_ifc;
+	hca_dev_ext_t			*p_ext;
+	ci_interface_t			*p_hca_ifc;
+	NTSTATUS				status;
+	UINT8					version;
+
+	HCA_ENTER( HCA_DBG_PNP );
+
+	version = VerbsVersionMajor(p_io_stack->Parameters.QueryInterface.Version);
+	if( version < MTHCA_VERBS_MIN_VERSION || version > MTHCA_VERBS_MAX_VERSION )
+	{
+		status = STATUS_NOT_SUPPORTED;
+		goto exit;
+	}
+
+	if( p_io_stack->Parameters.QueryInterface.Size < sizeof(RDMA_INTERFACE_VERBS) )
+	{
+		status = STATUS_BUFFER_TOO_SMALL;
+		goto exit;
+	}
+
+	p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;
+	p_hca_ifc = __alloc_hca_ifc( p_ext );
+	if( !p_hca_ifc )
+	{
+		status = STATUS_NO_MEMORY;
+		goto exit;
+	}
+
+	p_ifc = (RDMA_INTERFACE_VERBS *) p_io_stack->Parameters.QueryInterface.Interface;
+
+	p_ifc->InterfaceHeader.Size = sizeof(RDMA_INTERFACE_VERBS);
+	p_ifc->InterfaceHeader.Version = VerbsVersion(version, 0);
+	p_ifc->InterfaceHeader.Context = p_dev_obj;
+	p_ifc->InterfaceHeader.InterfaceReference = __hca_noop;
+	p_ifc->InterfaceHeader.InterfaceDereference = __hca_noop;
+	p_ifc->Verbs = *p_hca_ifc;
+	p_ifc->Verbs.p_hca_dev = &p_ext->hca.hob;
+
+	ExFreePool( p_hca_ifc );
+	status = STATUS_SUCCESS;
+
+exit:
+	HCA_EXIT( HCA_DBG_PNP );
+	return status;
+}
+
+
+static NTSTATUS
+hca_query_interface(
+	IN				DEVICE_OBJECT* const		p_dev_obj,
+	IN				IRP* const					p_irp, 
+		OUT			cl_irp_action_t* const		p_action )
+{
+	NTSTATUS			status;
+	IO_STACK_LOCATION	*p_io_stack;
+
+	HCA_ENTER( HCA_DBG_PNP );
+
+#pragma warning( push, 3 )
+	PAGED_CODE();
+#pragma warning( pop )
+
+
+	p_io_stack = IoGetCurrentIrpStackLocation( p_irp );
+	
+	/* Compare requested GUID with our supported interface GUIDs. */
+	if( IsEqualGUID( p_io_stack->Parameters.QueryInterface.InterfaceType,
+		&GUID_RDMA_INTERFACE_VERBS ) )
+	{
+		status = __query_ci_ifc( p_dev_obj, p_io_stack );
+		*p_action = IrpComplete;
+	}
+	else
+	{
+		status = p_irp->IoStatus.Status;
+		*p_action = IrpSkip;
+	}
+
+	HCA_EXIT( HCA_DBG_PNP );
+	return status;
+}
+
+
+static NTSTATUS
 hca_query_pnp_state(
 	IN				DEVICE_OBJECT* const		p_dev_obj,
 	IN				IRP* const					p_irp, 





More information about the ofw mailing list