[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