#include "bus_port_mgr.h"\r
#include "bus_iou_mgr.h"\r
#include "al_dev.h"\r
+#include <rdma/verbs.h>\r
+\r
/* Safe string functions. */\r
#if WINVER == 0x500\r
/*\r
atomic32_t n_al_ifc_ref;\r
/* Number of references on the CI interface. */\r
atomic32_t n_ci_ifc_ref;\r
+ /* HCA interface stuff */\r
+ RDMA_INTERFACE_VERBS hca_ifc;\r
+ boolean_t hca_ifc_taken;\r
\r
struct _bus_filter_instance *bus_filter;\r
\r
IN IRP* const p_irp,\r
OUT cl_irp_action_t* const p_action );\r
\r
+static void\r
+__set_ifc(\r
+ OUT ib_al_ifc_t* const p_ifc );\r
+\r
\r
/* All PnP code is called at passive, so it can all be paged out. */\r
#ifdef ALLOC_PRAGMA\r
}\r
\r
\r
+/* Forwards the request to the HCA's FDO. */\r
+static NTSTATUS\r
+__get_ifc(\r
+ IN DEVICE_OBJECT* const pDevObj,\r
+ IN const GUID* const pGuid,\r
+ IN USHORT size,\r
+ IN USHORT Version,\r
+ IN OUT PVOID InterfaceSpecificData,\r
+ OUT PINTERFACE pHcaIfc )\r
+{\r
+ NTSTATUS status;\r
+ IRP *pIrp;\r
+ IO_STATUS_BLOCK ioStatus;\r
+ IO_STACK_LOCATION *pIoStack;\r
+ DEVICE_OBJECT *pDev;\r
+ KEVENT event;\r
+\r
+ BUS_ENTER( BUS_DBG_PNP );\r
+\r
+ CL_ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL );\r
+\r
+ pDev = IoGetAttachedDeviceReference( pDevObj );\r
+\r
+ KeInitializeEvent( &event, NotificationEvent, FALSE );\r
+\r
+ /* Build the IRP for the HCA. */\r
+ pIrp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, pDev,\r
+ NULL, 0, NULL, &event, &ioStatus );\r
+ if( !pIrp )\r
+ {\r
+ ObDereferenceObject( pDev );\r
+ BUS_PRINT( BUS_DBG_PNP, \r
+ ("IoBuildSynchronousFsdRequest failed.\n"));\r
+ return STATUS_INSUFFICIENT_RESOURCES;\r
+ }\r
+\r
+ /* Copy the request query parameters. */\r
+ pIoStack = IoGetNextIrpStackLocation( pIrp );\r
+ pIoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
+ pIoStack->Parameters.QueryInterface.Size = size;\r
+ pIoStack->Parameters.QueryInterface.Version = Version;\r
+ pIoStack->Parameters.QueryInterface.InterfaceType = pGuid;\r
+ pIoStack->Parameters.QueryInterface.Interface = (INTERFACE*)pHcaIfc;\r
+ pIoStack->Parameters.QueryInterface.InterfaceSpecificData = InterfaceSpecificData;\r
+\r
+ pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
+\r
+ /* Send the IRP. */\r
+ status = IoCallDriver( pDev, pIrp );\r
+ if( status == STATUS_PENDING )\r
+ {\r
+ KeWaitForSingleObject( &event, Executive, KernelMode,\r
+ FALSE, NULL );\r
+\r
+ status = ioStatus.Status;\r
+ }\r
+ ObDereferenceObject( pDev );\r
+\r
+ BUS_EXIT( BUS_DBG_PNP );\r
+ return status;\r
+}\r
+\r
static NTSTATUS\r
fdo_start(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
ASSERT( NT_SUCCESS( status ) );\r
}\r
\r
+ /* get MLX4_HCA verbs interface */\r
+ status = __get_ifc( p_dev_obj, &GUID_RDMA_INTERFACE_VERBS,\r
+ sizeof(RDMA_INTERFACE_VERBS), \r
+ VerbsVersion(VERBS_MAJOR_VER, VERBS_MINOR_VER), \r
+ p_ext, (PINTERFACE)&p_ext->hca_ifc );\r
+ if( !NT_SUCCESS( status ) ) \r
+ {\r
+ BUS_TRACE_EXIT(BUS_DBG_PNP,\r
+ ("Getting MLX4 BUS interface failed: status=0x%x\n", status));\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+ p_ext->hca_ifc_taken = TRUE;\r
+\r
+ /* register HCA */\r
+ ib_status = ib_register_ca( &p_ext->hca_ifc.Verbs );\r
+ if( ib_status != IB_SUCCESS )\r
+ {\r
+ BUS_TRACE_EXIT( BUS_DBG_ERROR, ("ib_register_ca returned %s.\n",\r
+ ib_get_err_str(ib_status)) );\r
+ return STATUS_UNSUCCESSFUL;\r
+ }\r
+\r
BUS_PRINT(BUS_DBG_PNP,\r
("%s exit %x\n",p_bfi->whoami,status));\r
BUS_EXIT( BUS_DBG_PNP );\r
NTSTATUS status;\r
bus_filter_t *p_bfi;\r
int ic;\r
+ ib_api_status_t ib_status;\r
\r
BUS_ENTER( BUS_DBG_PNP );\r
\r
p_ext->p_iou_mgr = NULL;\r
}\r
\r
+ if (p_ext->hca_ifc_taken) {\r
+ ib_status = ib_deregister_ca( p_ext->hca_ifc.Verbs.guid );\r
+ if( ib_status != IB_SUCCESS ) {\r
+ BUS_PRINT( BUS_DBG_ERROR, ("ib_deregister_ca returned %s.\n",\r
+ ib_get_err_str(ib_status)) );\r
+ }\r
+ p_ext->hca_ifc.InterfaceHeader.InterfaceDereference(\r
+ p_ext->hca_ifc.InterfaceHeader.Context);\r
+ }\r
+\r
BUS_PRINT( BUS_DBG_PNP, ("Releasing BusFilter %s\n", p_bfi->whoami ));\r
if (p_bfi) {\r
p_ext->bus_filter = NULL;\r
p_ifc->wdm.InterfaceReference = al_ref_ifc;\r
p_ifc->wdm.InterfaceDereference = al_deref_ifc;\r
\r
- al_set_ifc( p_ifc );\r
+ __set_ifc( p_ifc );\r
\r
// take the reference before returning.\r
al_ref_ifc( p_dev_obj );\r
return STATUS_SUCCESS;\r
}\r
\r
-\r
-void\r
-al_set_ifc(\r
+static void\r
+__set_ifc(\r
OUT ib_al_ifc_t* const p_ifc )\r
{\r
BUS_ENTER( BUS_DBG_PNP );\r
#if !defined _BUS_DRV_PNP_H_\r
#define _BUS_DRV_PNP_H_\r
\r
-\r
#include "bus_driver.h"\r
-#include "iba/ib_al_ifc.h"\r
-\r
\r
/****f* InfiniBand Bus Driver: Plug and Play/bus_add_device\r
* NAME\r
*********/\r
\r
\r
-void\r
-al_set_ifc(\r
- OUT ib_al_ifc_t* const p_ifc );\r
-\r
void\r
al_ref_ifc(\r
IN DEVICE_OBJECT* p_dev_obj );\r
\r
size = 0;\r
ib_status = pDevice->VerbsInterface.Verbs.\r
- query_ca(pDevice->VerbsInterface.Verbs.p_hca_dev, NULL, &size, NULL);\r
+ query_ca(pDevice->VerbsInterface.p_hca_obj, NULL, &size, NULL);\r
if (ib_status != IB_INSUFFICIENT_MEMORY) {\r
attr = NULL;\r
goto out;\r
}\r
\r
ib_status = pDevice->VerbsInterface.Verbs.\r
- query_ca(pDevice->VerbsInterface.Verbs.p_hca_dev, attr, &size, NULL);\r
+ query_ca(pDevice->VerbsInterface.p_hca_obj, attr, &size, NULL);\r
if (ib_status != IB_SUCCESS) {\r
ExFreePool(attr);\r
attr = NULL;\r
if (!NT_SUCCESS(status)) {\r
return status;\r
}\r
- dev->hDevice = dev->Interface.Verbs.p_hca_dev;\r
+ dev->hDevice = dev->Interface.p_hca_obj;\r
\r
KeAcquireGuardedMutex(&Lock);\r
create = IsListEmpty(&DevList);\r
#define DRV_VERSION "1.0"\r
#define DRV_RELDATE "02/01/2008"\r
\r
-#define MLX_VERBS_MIN_VERSION 2\r
-#define MLX_VERBS_MAX_VERSION 2\r
-\r
GLOBALS g;\r
\r
/*\r
__get_ci_interface(\r
IN DEVICE_OBJECT* const p_dev_obj );\r
\r
-static void\r
-__hca_deregister(\r
- IN FDO_DEVICE_DATA *p_fdo );\r
-\r
-static NTSTATUS\r
-__hca_register(\r
- IN DEVICE_OBJECT *p_dev_obj );\r
-\r
-static NTSTATUS\r
-__pnp_notify_target(\r
- IN void *pNotifyStruct,\r
- IN void *context );\r
-\r
-static NTSTATUS\r
-__pnp_notify_ifc(\r
- IN void *pNotifyStruct,\r
- IN void *context );\r
-\r
\r
#ifdef ALLOC_PRAGMA\r
#pragma alloc_text (INIT, DriverEntry)\r
#pragma alloc_text (PAGE, hca_query_capabilities)\r
#pragma alloc_text (PAGE, hca_query_interface)\r
#pragma alloc_text (PAGE, hca_query_pnp_state)\r
-#pragma alloc_text (PAGE, hca_query_bus_relations)\r
-#pragma alloc_text (PAGE, hca_query_removal_relations)\r
#pragma alloc_text (PAGE, hca_set_power)\r
#pragma alloc_text (PAGE, __alloc_hca_ifc)\r
#pragma alloc_text (PAGE, __get_ci_interface)\r
-#pragma alloc_text (PAGE, __hca_register)\r
-#pragma alloc_text (PAGE, __pnp_notify_target)\r
-#pragma alloc_text (PAGE, __pnp_notify_ifc)\r
#endif\r
\r
\r
return status;\r
}\r
\r
-static NTSTATUS\r
-__get_ci_interface(\r
- IN DEVICE_OBJECT* const p_dev_obj )\r
-{\r
- NTSTATUS status;\r
- IRP *p_irp;\r
- PFDO_DEVICE_DATA p_fdo;\r
- IO_STATUS_BLOCK ioStatus;\r
- IO_STACK_LOCATION *pIoStack;\r
- KEVENT event;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
-\r
- KeInitializeEvent( &event, NotificationEvent, FALSE );\r
-\r
- /* Query for the verbs interface. */\r
- p_irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, p_fdo->p_al_dev,\r
- NULL, 0, NULL, &event, &ioStatus );\r
- if( !p_irp )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoBuildSynchronousFsdRequest failed.\n"));\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- }\r
-\r
- /* Format the IRP. */\r
- pIoStack = IoGetNextIrpStackLocation( p_irp );\r
- pIoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
- pIoStack->Parameters.QueryInterface.Version = IB_CI_INTERFACE_VERSION;\r
- pIoStack->Parameters.QueryInterface.Size = sizeof(ib_ci_ifc_t);\r
- pIoStack->Parameters.QueryInterface.Interface = \r
- (INTERFACE*)&p_fdo->ci_ifc;\r
- pIoStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;\r
- pIoStack->Parameters.QueryInterface.InterfaceType = \r
- &GUID_IB_CI_INTERFACE;\r
- p_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
-\r
- /* Send the IRP. */\r
- status = IoCallDriver( p_fdo->p_al_dev, p_irp );\r
- if( status == STATUS_PENDING )\r
- {\r
- KeWaitForSingleObject( &event, Executive, KernelMode, \r
- FALSE, NULL );\r
-\r
- status = ioStatus.Status;\r
- }\r
-\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR,HCA_DBG_PNP, \r
- ("Query interface for verbs returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-__pnp_notify_target(\r
- IN void *pNotifyStruct,\r
- IN void *context )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- DEVICE_OBJECT *p_dev_obj;\r
- PFDO_DEVICE_DATA p_fdo;\r
- TARGET_DEVICE_REMOVAL_NOTIFICATION *pNotify;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- pNotify = (TARGET_DEVICE_REMOVAL_NOTIFICATION*)pNotifyStruct;\r
- p_dev_obj = (DEVICE_OBJECT*)context;\r
- p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
-\r
- if( IsEqualGUID( &pNotify->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE ) )\r
- {\r
- if ( p_fdo->state == HCA_REGISTERED) {\r
- /* Release AL's CI interface. */\r
- p_fdo->ci_ifc.wdm.InterfaceDereference( p_fdo->ci_ifc.wdm.Context );\r
- p_fdo->state = HCA_IFC_DEREFERENCED;\r
- }\r
-\r
- /* Release AL's file object so that it can unload. */\r
- CL_ASSERT( p_fdo->p_al_dev );\r
- CL_ASSERT( p_fdo->p_al_file_obj );\r
- CL_ASSERT( p_fdo->p_al_file_obj == pNotify->FileObject );\r
- if( p_fdo->p_al_file_obj ) {\r
- ObDereferenceObject( p_fdo->p_al_file_obj );\r
- p_fdo->p_al_file_obj = NULL;\r
- p_fdo->p_al_dev = NULL;\r
- }\r
- }\r
- else if( IsEqualGUID( &pNotify->Event, \r
- &GUID_TARGET_DEVICE_REMOVE_COMPLETE ) )\r
- {\r
- if (p_fdo->ci_ifc.deregister_ca) {\r
- /* Notify AL that the CA is being removed. */\r
- p_fdo->ci_ifc.deregister_ca( p_fdo->hca.guid );\r
- p_fdo->ci_ifc.deregister_ca = NULL;\r
- }\r
-\r
- if ( p_fdo->state == HCA_REGISTERED) {\r
- /* Release AL's CI interface. */\r
- p_fdo->ci_ifc.wdm.InterfaceDereference( p_fdo->ci_ifc.wdm.Context );\r
- }\r
- p_fdo->state = HCA_STARTED;\r
-\r
- /* Release AL's file object so that it can unload. */\r
- if( p_fdo->p_al_file_obj )\r
- {\r
- ObDereferenceObject( p_fdo->p_al_file_obj );\r
- p_fdo->p_al_file_obj = NULL;\r
- p_fdo->p_al_dev = NULL;\r
- }\r
-\r
- /* Cancel our target device change registration. */\r
- if (p_fdo->pnp_target_entry) {\r
- IoUnregisterPlugPlayNotification( p_fdo->pnp_target_entry );\r
- p_fdo->pnp_target_entry = NULL;\r
- }\r
-\r
- }\r
- else if( IsEqualGUID( &pNotify->Event, \r
- &GUID_TARGET_DEVICE_REMOVE_CANCELLED ) )\r
- {\r
- /* Cancel our target device change registration. */\r
- if (p_fdo->pnp_target_entry) {\r
- IoUnregisterPlugPlayNotification( p_fdo->pnp_target_entry );\r
- p_fdo->pnp_target_entry = NULL;\r
- }\r
-\r
- /* Get the device object pointer for the AL. */\r
- CL_ASSERT( !p_fdo->p_al_file_obj );\r
- CL_ASSERT( !p_fdo->p_al_dev );\r
- /* Get the AL device object. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_SHIM ,("Calling IoGetDeviceObjectPointer.\n"));\r
- status = IoGetDeviceObjectPointer( &p_fdo->al_sym_name,\r
- FILE_ALL_ACCESS, &p_fdo->p_al_file_obj, &p_fdo->p_al_dev );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_SHIM, \r
- ("IoGetDeviceObjectPointer returned %08x.\n", status ));\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- /* Register for removal notification of the IB Fabric root device. */\r
- status = IoRegisterPlugPlayNotification( \r
- EventCategoryTargetDeviceChange, 0, p_fdo->p_al_file_obj, \r
- p_dev_obj->DriverObject, __pnp_notify_target, p_dev_obj, \r
- &p_fdo->pnp_target_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- CL_ASSERT( p_fdo->state == HCA_IFC_DEREFERENCED );\r
- if ( p_fdo->state == HCA_IFC_DEREFERENCED) {\r
- /* Release AL's CI interface. */\r
- p_fdo->ci_ifc.wdm.InterfaceReference( p_fdo->ci_ifc.wdm.Context );\r
- p_fdo->state = HCA_REGISTERED;\r
- }\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
static ci_interface_t*\r
__alloc_hca_ifc(\r
IN PFDO_DEVICE_DATA const p_fdo )\r
return pIfc;\r
}\r
\r
-static void\r
-__hca_deregister(\r
- IN PFDO_DEVICE_DATA p_fdo )\r
-{\r
- HCA_ENTER( HCA_DBG_PNP );\r
- \r
- if ( p_fdo->state == HCA_REGISTERED) {\r
- if (p_fdo->ci_ifc.deregister_ca) {\r
- /* Notify AL that the CA is being removed. */\r
- p_fdo->ci_ifc.deregister_ca( p_fdo->hca.guid );\r
- p_fdo->ci_ifc.deregister_ca = NULL;\r
- /* Release AL's CI interface. */\r
- p_fdo->ci_ifc.wdm.InterfaceDereference( p_fdo->ci_ifc.wdm.Context );\r
- p_fdo->state = HCA_STARTED;\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP,\r
- ("***** HCA deregistered \n"));\r
- }\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
-}\r
-\r
-static NTSTATUS\r
-__hca_register(\r
- IN DEVICE_OBJECT *p_dev_obj )\r
-{\r
- PFDO_DEVICE_DATA p_fdo;\r
- NTSTATUS status;\r
- ib_api_status_t ib_status;\r
- ci_interface_t *p_hca_ifc;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
- \r
- p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
-\r
- ASSERT( p_fdo->state == HCA_STARTED );\r
- ASSERT( p_fdo->p_al_dev );\r
-\r
- /* Get the AL's lower interface. */\r
- status = __get_ci_interface( p_dev_obj );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR,HCA_DBG_PNP, \r
- ("__get_ci_interface returned %08x.\n", status));\r
- goto exit;\r
- }\r
-\r
- /* Allocate and populate our HCA interface structure. */\r
- p_hca_ifc = __alloc_hca_ifc( p_fdo );\r
- if( !p_hca_ifc )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("__alloc_hca_ifc failed.\n"));\r
- status = STATUS_NO_MEMORY;\r
- goto exit;\r
- }\r
-\r
- /* Notify AL that we're available... */\r
- ib_status = p_fdo->ci_ifc.register_ca( p_hca_ifc );\r
- ExFreePool( p_hca_ifc );\r
- if( ib_status != IB_SUCCESS )\r
- {\r
- p_fdo->ci_ifc.wdm.InterfaceDereference( p_fdo->ci_ifc.wdm.Context );\r
- status = STATUS_INSUFFICIENT_RESOURCES;\r
- goto exit;\r
- }\r
-\r
- p_fdo->state = HCA_REGISTERED;\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP,\r
- ("***** HCA registered \n"));\r
-exit:\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-__pnp_notify_ifc(\r
- IN void *pNotifyStruct,\r
- IN void *context )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- DEVICE_OBJECT *p_dev_obj;\r
- PFDO_DEVICE_DATA p_fdo;\r
- DEVICE_INTERFACE_CHANGE_NOTIFICATION *pNotify;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- pNotify = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)pNotifyStruct;\r
- p_dev_obj = (DEVICE_OBJECT*)context;\r
- p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
-\r
- if( !IsEqualGUID( &pNotify->Event, &GUID_DEVICE_INTERFACE_ARRIVAL ) )\r
- goto done;\r
-\r
- /*\r
- * Sanity check. We should only be getting notifications of the \r
- * CI interface exported by AL.\r
- */\r
- ASSERT( \r
- IsEqualGUID( &pNotify->InterfaceClassGuid, &GUID_IB_CI_INTERFACE ) );\r
-\r
- if( p_fdo->state != HCA_STARTED )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Invalid state: %d\n", p_fdo->state));\r
- goto done;\r
- }\r
-\r
- /* save symbolic name of IBAL for a case of cancelled IBAL removal */\r
- if (!p_fdo->al_sym_name.Buffer) {\r
- p_fdo->al_sym_name.Length = pNotify->SymbolicLinkName->Length;\r
- p_fdo->al_sym_name.MaximumLength = pNotify->SymbolicLinkName->MaximumLength;\r
- p_fdo->al_sym_name.Buffer = ExAllocatePoolWithTag( NonPagedPool, \r
- p_fdo->al_sym_name.MaximumLength * sizeof(wchar_t),\r
- 'cfin' );\r
- if (!p_fdo->al_sym_name.Buffer)\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("allocation of sym IBAL name failed.\n"));\r
- goto done;\r
- }\r
- RtlCopyUnicodeString( &p_fdo->al_sym_name, pNotify->SymbolicLinkName );\r
- }\r
-\r
- ASSERT( !p_fdo->p_al_dev );\r
- ASSERT( !p_fdo->p_al_file_obj );\r
-\r
- /* Get the AL device object. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Calling IoGetDeviceObjectPointer.\n"));\r
- status = IoGetDeviceObjectPointer( pNotify->SymbolicLinkName,\r
- FILE_ALL_ACCESS, &p_fdo->p_al_file_obj, &p_fdo->p_al_dev );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoGetDeviceObjectPointer returned %08x.\n", status ));\r
- goto done;\r
- }\r
-\r
- /* Register for removal notification of the IB Fabric root device. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PNP, \r
- ("Registering for target notifications.\n"));\r
- status = IoRegisterPlugPlayNotification( \r
- EventCategoryTargetDeviceChange, 0, p_fdo->p_al_file_obj, \r
- p_dev_obj->DriverObject, __pnp_notify_target, p_dev_obj, \r
- &p_fdo->pnp_target_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- goto err_reg_notify;\r
- }\r
-\r
- status = __hca_register( p_dev_obj );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("__get_ci_interface returned %08x.\n", status));\r
- goto err_reg_hca;\r
- }\r
- goto done;\r
- \r
-err_reg_hca:\r
- IoUnregisterPlugPlayNotification( p_fdo->pnp_target_entry );\r
- p_fdo->pnp_target_entry = NULL;\r
-err_reg_notify:\r
- ObDereferenceObject( p_fdo->p_al_file_obj );\r
- p_fdo->p_al_file_obj = NULL;\r
- p_fdo->p_al_dev = NULL;\r
-done:\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
static void\r
__unmap_hca_memory(\r
IN PFDO_DEVICE_DATA const p_fdo )\r
\r
switch( p_fdo->state )\r
{\r
- case HCA_REGISTERED:\r
- __hca_deregister( p_fdo );\r
-\r
- /* Fall through. */\r
case HCA_STARTED:\r
/* dequeue HCA */\r
mlnx_hca_remove( &p_fdo->hca );\r
*/\r
p_fdo->state = HCA_STARTED;\r
\r
- /* Register for interface arrival of the IB_AL device. */\r
- status = IoRegisterPlugPlayNotification(\r
- EventCategoryDeviceInterfaceChange,\r
- PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,\r
- (void*)&GUID_IB_CI_INTERFACE, p_dev_obj->DriverObject,\r
- __pnp_notify_ifc, p_dev_obj, &p_fdo->pnp_ifc_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- p_fdo->state = HCA_ADDED;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,\r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- }\r
-\r
/* We get started fully powered. */\r
p_fdo->DevicePowerState = PowerDeviceD0;\r
powerState.DeviceState = PowerDeviceD0;\r
return status;\r
}\r
\r
-\r
-static NTSTATUS\r
-hca_query_removal_relations(\r
- IN DEVICE_OBJECT* const p_dev_obj,\r
- IN IRP* const p_irp, \r
- OUT cl_irp_action_t* const p_action )\r
-{\r
- NTSTATUS status;\r
- PFDO_DEVICE_DATA p_fdo;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
-\r
- if( p_fdo->state == HCA_REGISTERED )\r
- {\r
- status = p_fdo->ci_ifc.get_relations( p_fdo->hca.guid, p_irp );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- *p_action = IrpComplete;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("AL get_relations returned %08x.\n", status));\r
- return status;\r
- }\r
- }\r
-\r
- *p_action = IrpPassDown;\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-hca_query_bus_relations(\r
- IN DEVICE_OBJECT* const p_dev_obj,\r
- IN IRP* const p_irp, \r
- OUT cl_irp_action_t* const p_action )\r
-{\r
- NTSTATUS status;\r
- DEVICE_RELATIONS *p_rel;\r
- PFDO_DEVICE_DATA p_fdo;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_fdo = p_dev_obj->DeviceExtension;\r
-\r
- //cl_event_wait_on( &p_fdo->mutex, EVENT_NO_TIMEOUT, FALSE );\r
- if( p_fdo->state == HCA_REGISTERED )\r
- {\r
- status = p_fdo->ci_ifc.get_relations( p_fdo->hca.guid, p_irp );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- //cl_event_signal( &p_fdo->mutex );\r
- *p_action = IrpComplete;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("AL get_relations returned %08x.\n", status));\r
- return status;\r
- }\r
- }\r
- else\r
- {\r
- status = cl_alloc_relations( p_irp, 1 );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("cl_alloc_relations returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
- p_rel->Count = 0;\r
- p_rel->Objects[0] = NULL;\r
- }\r
-\r
- //cl_event_signal( &p_fdo->mutex );\r
-\r
- *p_action = IrpPassDown;\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
static NTSTATUS\r
hca_query_stop(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
return status;\r
}\r
\r
-\r
-static VOID\r
-__hca_noop( VOID *context )\r
+static void\r
+__ref_ifc(\r
+ IN DEVICE_OBJECT* p_dev_obj )\r
{\r
- UNREFERENCED_PARAMETER(context);\r
+ PFDO_DEVICE_DATA p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
+\r
+ HCA_ENTER( HCA_DBG_PNP );\r
+\r
+ cl_atomic_inc( &p_fdo->n_hca_ifc_ref );\r
+ ObReferenceObject( p_dev_obj );\r
+\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
+ ("MLX4_HCA: CA_guid %I64x, hca_ifc_ref %d\n",\r
+ p_fdo->hca.guid, p_fdo->n_hca_ifc_ref) );\r
+\r
+ HCA_EXIT( HCA_DBG_PNP );\r
}\r
\r
+static void\r
+__deref_ifc(\r
+ IN DEVICE_OBJECT* p_dev_obj )\r
+{\r
+ PFDO_DEVICE_DATA p_fdo = (PFDO_DEVICE_DATA)p_dev_obj->DeviceExtension;\r
+\r
+ HCA_ENTER( HCA_DBG_PNP );\r
+\r
+ cl_atomic_dec( &p_fdo->n_hca_ifc_ref );\r
+ ObDereferenceObject( p_dev_obj );\r
+\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
+ ("MLX4_HCA: CA_guid %I64x, hca_ifc_ref %d\n",\r
+ p_fdo->hca.guid, p_fdo->n_hca_ifc_ref) );\r
+\r
+ HCA_EXIT( HCA_DBG_PNP );\r
+}\r
\r
static NTSTATUS\r
__query_ci_ifc(\r
HCA_ENTER( HCA_DBG_PNP );\r
\r
version = VerbsVersionMajor(p_io_stack->Parameters.QueryInterface.Version);\r
- if( version < MLX_VERBS_MIN_VERSION || version > MLX_VERBS_MAX_VERSION )\r
+ if( version > VERBS_MAJOR_VER )\r
{\r
status = STATUS_NOT_SUPPORTED;\r
goto exit;\r
p_ifc = (RDMA_INTERFACE_VERBS *) p_io_stack->Parameters.QueryInterface.Interface;\r
\r
p_ifc->InterfaceHeader.Size = sizeof(RDMA_INTERFACE_VERBS);\r
- p_ifc->InterfaceHeader.Version = VerbsVersion(version, 0);\r
+ p_ifc->InterfaceHeader.Version = VerbsVersion(VERBS_MAJOR_VER, VERBS_MINOR_VER);\r
p_ifc->InterfaceHeader.Context = p_dev_obj;\r
- p_ifc->InterfaceHeader.InterfaceReference = __hca_noop;\r
- p_ifc->InterfaceHeader.InterfaceDereference = __hca_noop;\r
+ p_ifc->InterfaceHeader.InterfaceReference = __ref_ifc;\r
+ p_ifc->InterfaceHeader.InterfaceDereference = __deref_ifc;\r
p_ifc->Verbs = *p_hca_ifc;\r
- p_ifc->Verbs.p_hca_dev = &p_fdo->hca;\r
- ASSERT(p_ifc->Verbs.p_hca_dev); \r
+ p_ifc->p_hca_obj = &p_fdo->hca;\r
+\r
+ /* take the reference before returning. */\r
+ __ref_ifc( p_dev_obj );\r
\r
ExFreePool( p_hca_ifc );\r
status = STATUS_SUCCESS;\r
goto err_hca_reg;\r
}\r
\r
- if( p_fdo->p_al_dev ) {\r
- status = __hca_register( p_dev_obj );\r
- if( !NT_SUCCESS( status ) ) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PO, \r
- ("!!! __hca_register failed (%#x) \n", status));\r
- goto err_hca_reg;\r
- }\r
- }\r
-\r
p_fdo->DevicePowerState = pIoStack->Parameters.Power.State.DeviceState;\r
powerState = PoSetPowerState( p_dev_obj, DevicePowerState,\r
pIoStack->Parameters.Power.State );\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PO, \r
("***** Remove the HCA \n"));\r
\r
- {\r
- __hca_deregister( p_fdo );\r
-\r
- // release MLX4_BUS resources\r
- if(p_fdo->bus_ib_ifc_taken) {\r
- p_fdo->bus_ib_ifc_taken = FALSE;\r
- __put_ifc( (PINTERFACE)&p_fdo->bus_ib_ifc );\r
- }\r
+ // release MLX4_BUS resources\r
+ if(p_fdo->bus_ib_ifc_taken) {\r
+ p_fdo->bus_ib_ifc_taken = FALSE;\r
+ __put_ifc( (PINTERFACE)&p_fdo->bus_ib_ifc );\r
}\r
\r
IoCopyCurrentIrpStackLocationToNext( p_irp );\r
vfptrHcaPnp.pfn_query_pnp_state = hca_query_pnp_state;\r
vfptrHcaPnp.pfn_filter_res_req = cl_irp_skip;\r
vfptrHcaPnp.pfn_dev_usage_notification = cl_do_sync_pnp;\r
- vfptrHcaPnp.pfn_query_bus_relations = hca_query_bus_relations;\r
+ vfptrHcaPnp.pfn_query_bus_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_ejection_relations = cl_irp_ignore;\r
- vfptrHcaPnp.pfn_query_removal_relations = hca_query_removal_relations;\r
+ vfptrHcaPnp.pfn_query_removal_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_target_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_unknown = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_resources = cl_irp_ignore;\r
{\r
HCA_SHUTDOWN,\r
HCA_ADDED,\r
- HCA_STARTED,\r
- HCA_IFC_DEREFERENCED,\r
- HCA_REGISTERED\r
+ HCA_STARTED\r
\r
} hca_reg_state_t;\r
/*\r
* HCA_STARTED\r
* IRP_MN_START_DEVICE was called. The HCA is fully functional.\r
*\r
-* HCA_IFC_DEREFERENCED\r
-* DEVICE_QUERY_REMOVE for IBBUS was received.\r
-*\r
-* HCA_REGISTERED\r
-* Fully functional and registered with the bus root.\r
*********/\r
\r
//\r
/* -------------------------------------------------\r
* IBAL DATA \r
* ------------------------------------------------ */\r
- ib_ci_ifc_t ci_ifc; /* Interface for the lower edge of the IB_AL device. */\r
+ /* Number of references on the upper interface. */\r
+ atomic32_t n_hca_ifc_ref;\r
hca_reg_state_t state; /* State for tracking registration with AL */\r
DEVICE_OBJECT * p_al_dev; /* IB_AL FDO */\r
FILE_OBJECT * p_al_file_obj; /* IB_AL file object */\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR , HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR , HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SRQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SRQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_cq *ib_cq_p = (struct ib_cq *)h_cq;\r
- PREP_IBDEV_FOR_PRINT(ib_cq_p->device);\r
\r
HCA_ENTER(HCA_DBG_CQ);\r
\r
if (status != IB_SUCCESS && status != IB_NOT_FOUND)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_CQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_CQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_cq *ib_cq_p = (struct ib_cq *)h_cq;\r
- PREP_IBDEV_FOR_PRINT(ib_cq_p->device);\r
\r
HCA_ENTER(HCA_DBG_CQ);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_CQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_CQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_cq *ib_cq_p = (struct ib_cq *)h_cq;\r
- PREP_IBDEV_FOR_PRINT(ib_cq_p->device);\r
\r
HCA_ENTER(HCA_DBG_CQ);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_CQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_CQ);\r
return status;\r
*/\r
char mlnx_uvp_lib_name[MAX_LIB_NAME] = {"mthcau"};\r
\r
-void reregister_hca( hca_dev_ext_t *p_ext );\r
void mlnx_poll_eq(struct ib_device *device, BOOLEAN bStart);\r
\r
\r
\r
switch ( p_ci_op->command )\r
{\r
- case FW_REREGISTER_HCA:\r
- reregister_hca(p_ext);\r
- break;\r
- \r
case FW_MAP_CRSPACE:\r
status = __map_crspace(p_context, p_hob, p_data, length);\r
break;\r
{\r
HCA_SHUTDOWN,\r
HCA_ADDED,\r
- HCA_STARTED,\r
- HCA_IFC_DEREFERENCED,\r
- HCA_REGISTERED\r
+ HCA_STARTED\r
\r
} hca_reg_state_t;\r
/*\r
* HCA_STARTED\r
* IRP_MN_START_DEVICE was called. The HCA is fully functional.\r
*\r
-* HCA_IFC_DEREFERENCED\r
-* DEVICE_QUERY_REMOVE for IBBUS was received.\r
-*\r
-* HCA_REGISTERED\r
-* Fully functional and registered with the bus root.\r
*********/\r
\r
\r
/* -------------------------------------------------\r
* IB_AL DATA \r
* ------------------------------------------------ */\r
- ib_ci_ifc_t ci_ifc; /* Interface for the lower edge of the IB_AL device. */\r
+ /* Number of references on the upper interface. */\r
+ atomic32_t n_hca_ifc_ref;\r
hca_reg_state_t state; /* State for tracking registration with AL */\r
DEVICE_OBJECT * p_al_dev; /* IB_AL FDO */\r
FILE_OBJECT * p_al_file_obj; /* IB_AL file object */\r
#define HOB_FROM_IBDEV(dev_p) (mlnx_hob_t *)&dev_p->mdev->ext->hca.hob\r
\r
\r
-#define IB_GET_ERR_STR ib_dev->mdev->ext->ci_ifc.get_err_str\r
-#if DBG || defined( EVENT_TRACING )\r
-#define PREP_IBDEV_FOR_PRINT(val) struct ib_device *ib_dev = val\r
-#else\r
-#define PREP_IBDEV_FOR_PRINT(val)\r
-#endif\r
-\r
/***********************************\r
Firmware Update definitions\r
***********************************/\r
int err;\r
ib_api_status_t status;\r
struct ib_qp *ib_qp_p = (struct ib_qp *)h_qp;\r
- PREP_IBDEV_FOR_PRINT(ib_qp_p->device);\r
mlnx_mcast_t *mcast_p;\r
\r
HCA_ENTER(HCA_DBG_MCAST);\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_MCAST,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MCAST);\r
return status;\r
int err;\r
struct ib_mr *mr_p;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
- PREP_IBDEV_FOR_PRINT(ib_pd_p->device);\r
\r
HCA_ENTER(HCA_DBG_MEMORY);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
struct ib_mr *mr_p;\r
struct ib_phys_buf *buffer_list;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
- PREP_IBDEV_FOR_PRINT(ib_pd_p->device);\r
\r
UNUSED_PARAM( um_call );\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
ib_api_status_t status;\r
int err;\r
struct ib_mr *ib_mr = (struct ib_mr *)h_mr;\r
- PREP_IBDEV_FOR_PRINT(ib_mr->device);\r
\r
HCA_ENTER(HCA_DBG_SHIM);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
struct ib_fmr * fmr_p;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
struct ib_fmr_attr fmr_attr;\r
- PREP_IBDEV_FOR_PRINT(ib_pd_p->device);\r
\r
HCA_ENTER(HCA_DBG_MEMORY);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
ib_api_status_t status;\r
struct ib_fmr *ib_fmr = (struct ib_fmr *)h_fmr;\r
uint64_t vaddr = (*p_vaddr) & ~(PAGE_SIZE - 1);\r
- PREP_IBDEV_FOR_PRINT(ib_fmr->device);\r
\r
HCA_ENTER(HCA_DBG_MEMORY);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
int err;\r
struct ib_fmr *ib_fmr = (struct ib_fmr *)*ph_fmr;\r
struct list_head fmr_list;\r
- PREP_IBDEV_FOR_PRINT(ib_fmr->device);\r
\r
HCA_ENTER(HCA_DBG_MEMORY);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
{\r
ib_api_status_t status;\r
int err;\r
- struct ib_fmr *fmr = (struct ib_fmr *)h_fmr;\r
- PREP_IBDEV_FOR_PRINT(fmr->device);\r
- UNUSED_PARAM_WOWPP(fmr);\r
\r
HCA_ENTER(HCA_DBG_MEMORY);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR ,HCA_DBG_MEMORY,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MEMORY);\r
return status;\r
#include <initguid.h>\r
#include <wdmguid.h>\r
\r
-#define MTHCA_VERBS_MIN_VERSION 2\r
-#define MTHCA_VERBS_MAX_VERSION 2\r
-\r
extern const char *mthca_version;\r
hca_dev_ext_t *g_ext = NULL;\r
\r
__get_ci_interface(\r
IN DEVICE_OBJECT* const p_dev_obj );\r
\r
-static void\r
-__hca_deregister(\r
- IN hca_dev_ext_t *p_ext );\r
-\r
-static NTSTATUS\r
-__hca_register(\r
- IN DEVICE_OBJECT *p_dev_obj );\r
-\r
-static NTSTATUS\r
-__pnp_notify_target(\r
- IN void *pNotifyStruct,\r
- IN void *context );\r
-\r
-static NTSTATUS\r
-__pnp_notify_ifc(\r
- IN void *pNotifyStruct,\r
- IN void *context );\r
-\r
\r
#ifdef ALLOC_PRAGMA\r
#pragma alloc_text (PAGE, hca_add_device)\r
#pragma alloc_text (PAGE, hca_query_capabilities)\r
#pragma alloc_text (PAGE, hca_query_interface)\r
#pragma alloc_text (PAGE, hca_query_pnp_state)\r
-#pragma alloc_text (PAGE, hca_query_bus_relations)\r
-#pragma alloc_text (PAGE, hca_query_removal_relations)\r
#pragma alloc_text (PAGE, hca_set_power)\r
#pragma alloc_text (PAGE, __alloc_hca_ifc)\r
#pragma alloc_text (PAGE, __get_ci_interface)\r
-#pragma alloc_text (PAGE, __hca_register)\r
-#pragma alloc_text (PAGE, __pnp_notify_target)\r
-#pragma alloc_text (PAGE, __pnp_notify_ifc)\r
#endif\r
\r
\r
vfptrHcaPnp.pfn_query_pnp_state = hca_query_pnp_state;\r
vfptrHcaPnp.pfn_filter_res_req = cl_irp_skip;\r
vfptrHcaPnp.pfn_dev_usage_notification = cl_do_sync_pnp;\r
- vfptrHcaPnp.pfn_query_bus_relations = hca_query_bus_relations;\r
+ vfptrHcaPnp.pfn_query_bus_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_ejection_relations = cl_irp_ignore;\r
- vfptrHcaPnp.pfn_query_removal_relations = hca_query_removal_relations;\r
+ vfptrHcaPnp.pfn_query_removal_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_target_relations = cl_irp_ignore;\r
vfptrHcaPnp.pfn_unknown = cl_irp_ignore;\r
vfptrHcaPnp.pfn_query_resources = cl_irp_ignore;\r
}\r
\r
\r
-static NTSTATUS\r
-__get_ci_interface(\r
- IN DEVICE_OBJECT* const p_dev_obj )\r
-{\r
- NTSTATUS status;\r
- IRP *p_irp;\r
- hca_dev_ext_t *p_ext;\r
- IO_STATUS_BLOCK ioStatus;\r
- IO_STACK_LOCATION *pIoStack;\r
- KEVENT event;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
-\r
- KeInitializeEvent( &event, NotificationEvent, FALSE );\r
-\r
- /* Query for the verbs interface. */\r
- p_irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, p_ext->p_al_dev,\r
- NULL, 0, NULL, &event, &ioStatus );\r
- if( !p_irp )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoBuildSynchronousFsdRequest failed.\n"));\r
- return STATUS_INSUFFICIENT_RESOURCES;\r
- }\r
-\r
- /* Format the IRP. */\r
- pIoStack = IoGetNextIrpStackLocation( p_irp );\r
- pIoStack->MinorFunction = IRP_MN_QUERY_INTERFACE;\r
- pIoStack->Parameters.QueryInterface.Version = IB_CI_INTERFACE_VERSION;\r
- pIoStack->Parameters.QueryInterface.Size = sizeof(ib_ci_ifc_t);\r
- pIoStack->Parameters.QueryInterface.Interface = \r
- (INTERFACE*)&p_ext->ci_ifc;\r
- pIoStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;\r
- pIoStack->Parameters.QueryInterface.InterfaceType = \r
- &GUID_IB_CI_INTERFACE;\r
- p_irp->IoStatus.Status = STATUS_NOT_SUPPORTED;\r
-\r
- /* Send the IRP. */\r
- status = IoCallDriver( p_ext->p_al_dev, p_irp );\r
- if( status == STATUS_PENDING )\r
- {\r
- KeWaitForSingleObject( &event, Executive, KernelMode, \r
- FALSE, NULL );\r
-\r
- status = ioStatus.Status;\r
- }\r
-\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR,HCA_DBG_PNP, \r
- ("Query interface for verbs returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-__pnp_notify_target(\r
- IN void *pNotifyStruct,\r
- IN void *context )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- DEVICE_OBJECT *p_dev_obj;\r
- hca_dev_ext_t *p_ext;\r
- TARGET_DEVICE_REMOVAL_NOTIFICATION *pNotify;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- pNotify = (TARGET_DEVICE_REMOVAL_NOTIFICATION*)pNotifyStruct;\r
- p_dev_obj = (DEVICE_OBJECT*)context;\r
- p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
-\r
- if( IsEqualGUID( &pNotify->Event, &GUID_TARGET_DEVICE_QUERY_REMOVE ) )\r
- {\r
- if ( p_ext->state == HCA_REGISTERED) {\r
- /* Release AL's CI interface. */\r
- p_ext->ci_ifc.wdm.InterfaceDereference( p_ext->ci_ifc.wdm.Context );\r
- p_ext->state = HCA_IFC_DEREFERENCED;\r
- }\r
-\r
- /* Release AL's file object so that it can unload. */\r
- CL_ASSERT( p_ext->p_al_dev );\r
- CL_ASSERT( p_ext->p_al_file_obj );\r
- CL_ASSERT( p_ext->p_al_file_obj == pNotify->FileObject );\r
- if( p_ext->p_al_file_obj ) {\r
- ObDereferenceObject( p_ext->p_al_file_obj );\r
- p_ext->p_al_file_obj = NULL;\r
- p_ext->p_al_dev = NULL;\r
- }\r
- }\r
- else if( IsEqualGUID( &pNotify->Event, \r
- &GUID_TARGET_DEVICE_REMOVE_COMPLETE ) )\r
- {\r
- if (p_ext->ci_ifc.deregister_ca) {\r
- /* Notify AL that the CA is being removed. */\r
- p_ext->ci_ifc.deregister_ca( p_ext->hca.guid );\r
- p_ext->ci_ifc.deregister_ca = NULL;\r
- }\r
-\r
- if ( p_ext->state == HCA_REGISTERED) {\r
- /* Release AL's CI interface. */\r
- p_ext->ci_ifc.wdm.InterfaceDereference( p_ext->ci_ifc.wdm.Context );\r
- }\r
- p_ext->state = HCA_STARTED;\r
-\r
- /* Release AL's file object so that it can unload. */\r
- if( p_ext->p_al_file_obj )\r
- {\r
- ObDereferenceObject( p_ext->p_al_file_obj );\r
- p_ext->p_al_file_obj = NULL;\r
- p_ext->p_al_dev = NULL;\r
- }\r
-\r
- /* Cancel our target device change registration. */\r
- if (p_ext->pnp_target_entry) {\r
- IoUnregisterPlugPlayNotification( p_ext->pnp_target_entry );\r
- p_ext->pnp_target_entry = NULL;\r
- }\r
-\r
- }\r
- else if( IsEqualGUID( &pNotify->Event, \r
- &GUID_TARGET_DEVICE_REMOVE_CANCELLED ) )\r
- {\r
- /* Cancel our target device change registration. */\r
- if (p_ext->pnp_target_entry) {\r
- IoUnregisterPlugPlayNotification( p_ext->pnp_target_entry );\r
- p_ext->pnp_target_entry = NULL;\r
- }\r
-\r
- /* Get the device object pointer for the AL. */\r
- CL_ASSERT( !p_ext->p_al_file_obj );\r
- CL_ASSERT( !p_ext->p_al_dev );\r
- /* Get the AL device object. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_SHIM ,("Calling IoGetDeviceObjectPointer.\n"));\r
- status = IoGetDeviceObjectPointer( &p_ext->al_sym_name,\r
- FILE_ALL_ACCESS, &p_ext->p_al_file_obj, &p_ext->p_al_dev );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_SHIM, \r
- ("IoGetDeviceObjectPointer returned %08x.\n", status ));\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- /* Register for removal notification of the IB Fabric root device. */\r
- status = IoRegisterPlugPlayNotification( \r
- EventCategoryTargetDeviceChange, 0, p_ext->p_al_file_obj, \r
- p_dev_obj->DriverObject, __pnp_notify_target, p_dev_obj, \r
- &p_ext->pnp_target_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- CL_ASSERT( p_ext->state == HCA_IFC_DEREFERENCED );\r
- if ( p_ext->state == HCA_IFC_DEREFERENCED) {\r
- /* Release AL's CI interface. */\r
- p_ext->ci_ifc.wdm.InterfaceReference( p_ext->ci_ifc.wdm.Context );\r
- p_ext->state = HCA_REGISTERED;\r
- }\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
static ci_interface_t*\r
__alloc_hca_ifc(\r
IN hca_dev_ext_t* const p_ext )\r
return pIfc;\r
}\r
\r
-static void\r
-__hca_deregister(\r
- IN hca_dev_ext_t *p_ext )\r
-{\r
- HCA_ENTER( HCA_DBG_PNP );\r
- \r
- if ( p_ext->state == HCA_REGISTERED) {\r
- if (p_ext->ci_ifc.deregister_ca) {\r
- /* Notify AL that the CA is being removed. */\r
- p_ext->ci_ifc.deregister_ca( p_ext->hca.guid );\r
- p_ext->ci_ifc.deregister_ca = NULL;\r
- /* Release AL's CI interface. */\r
- p_ext->ci_ifc.wdm.InterfaceDereference( p_ext->ci_ifc.wdm.Context );\r
- p_ext->state = HCA_STARTED;\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP,\r
- ("***** HCA deregistered \n"));\r
- }\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PNP );\r
-}\r
-\r
-static NTSTATUS\r
-__hca_register(\r
- IN DEVICE_OBJECT *p_dev_obj )\r
-{\r
- hca_dev_ext_t *p_ext;\r
- NTSTATUS status;\r
- ib_api_status_t ib_status;\r
- ci_interface_t *p_hca_ifc;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
- \r
- p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
-\r
- ASSERT( p_ext->state == HCA_STARTED );\r
- ASSERT( p_ext->p_al_dev );\r
-\r
- /* Get the AL's lower interface. */\r
- status = __get_ci_interface( p_dev_obj );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR,HCA_DBG_PNP, \r
- ("__get_ci_interface returned %08x.\n", status));\r
- goto exit;\r
- }\r
-\r
- /* Allocate and populate our HCA interface structure. */\r
- p_hca_ifc = __alloc_hca_ifc( p_ext );\r
- if( !p_hca_ifc )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("__alloc_hca_ifc failed.\n"));\r
- status = STATUS_NO_MEMORY;\r
- goto exit;\r
- }\r
-\r
- /* Notify AL that we're available... */\r
- ib_status = p_ext->ci_ifc.register_ca( p_hca_ifc );\r
- ExFreePool( p_hca_ifc );\r
- if( ib_status != IB_SUCCESS )\r
- {\r
- p_ext->ci_ifc.wdm.InterfaceDereference( p_ext->ci_ifc.wdm.Context );\r
- status = STATUS_INSUFFICIENT_RESOURCES;\r
- goto exit;\r
- }\r
-\r
- p_ext->state = HCA_REGISTERED;\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP,\r
- ("***** HCA registered \n"));\r
-exit:\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-__pnp_notify_ifc(\r
- IN void *pNotifyStruct,\r
- IN void *context )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- DEVICE_OBJECT *p_dev_obj;\r
- hca_dev_ext_t *p_ext;\r
- DEVICE_INTERFACE_CHANGE_NOTIFICATION *pNotify;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- pNotify = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)pNotifyStruct;\r
- p_dev_obj = (DEVICE_OBJECT*)context;\r
- p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
-\r
- if( !IsEqualGUID( &pNotify->Event, &GUID_DEVICE_INTERFACE_ARRIVAL ) )\r
- goto done;\r
-\r
- /*\r
- * Sanity check. We should only be getting notifications of the \r
- * CI interface exported by AL.\r
- */\r
- ASSERT( \r
- IsEqualGUID( &pNotify->InterfaceClassGuid, &GUID_IB_CI_INTERFACE ) );\r
-\r
- if( p_ext->state != HCA_STARTED )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("Invalid state: %d\n", p_ext->state));\r
- goto done;\r
- }\r
-\r
- /* save symbolic name of IBAL for a case of cancelled IBAL removal */\r
- if (!p_ext->al_sym_name.Buffer) {\r
- p_ext->al_sym_name.Length = pNotify->SymbolicLinkName->Length;\r
- p_ext->al_sym_name.MaximumLength = pNotify->SymbolicLinkName->MaximumLength;\r
- p_ext->al_sym_name.Buffer = ExAllocatePoolWithTag( NonPagedPool, \r
- p_ext->al_sym_name.MaximumLength * sizeof(wchar_t),\r
- 'cfin' );\r
- if (!p_ext->al_sym_name.Buffer)\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_PNP ,("allocation of sym IBAL name failed.\n"));\r
- goto done;\r
- }\r
- RtlCopyUnicodeString( &p_ext->al_sym_name, pNotify->SymbolicLinkName );\r
- }\r
-\r
- ASSERT( !p_ext->p_al_dev );\r
- ASSERT( !p_ext->p_al_file_obj );\r
-\r
- /* Get the AL device object. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_PNP ,("Calling IoGetDeviceObjectPointer.\n"));\r
- status = IoGetDeviceObjectPointer( pNotify->SymbolicLinkName,\r
- FILE_ALL_ACCESS, &p_ext->p_al_file_obj, &p_ext->p_al_dev );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoGetDeviceObjectPointer returned %08x.\n", status ));\r
- goto done;\r
- }\r
-\r
- /* Register for removal notification of the IB Fabric root device. */\r
- HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PNP, \r
- ("Registering for target notifications.\n"));\r
- status = IoRegisterPlugPlayNotification( \r
- EventCategoryTargetDeviceChange, 0, p_ext->p_al_file_obj, \r
- p_dev_obj->DriverObject, __pnp_notify_target, p_dev_obj, \r
- &p_ext->pnp_target_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- goto err_reg_notify;\r
- }\r
-\r
- status = __hca_register( p_dev_obj );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("__get_ci_interface returned %08x.\n", status));\r
- goto err_reg_hca;\r
- }\r
- goto done;\r
- \r
-err_reg_hca:\r
- IoUnregisterPlugPlayNotification( p_ext->pnp_target_entry );\r
- p_ext->pnp_target_entry = NULL;\r
-err_reg_notify:\r
- ObDereferenceObject( p_ext->p_al_file_obj );\r
- p_ext->p_al_file_obj = NULL;\r
- p_ext->p_al_dev = NULL;\r
-done:\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return status;\r
-}\r
-\r
\r
/*\r
* Walk the resource lists and store the information. The write-only\r
*/\r
p_ext->state = HCA_STARTED;\r
\r
- /* Register for interface arrival of the IB_AL device. */\r
- status = IoRegisterPlugPlayNotification(\r
- EventCategoryDeviceInterfaceChange,\r
- PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES,\r
- (void*)&GUID_IB_CI_INTERFACE, p_dev_obj->DriverObject,\r
- __pnp_notify_ifc, p_dev_obj, &p_ext->pnp_ifc_entry );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- p_ext->state = HCA_ADDED;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP,\r
- ("IoRegisterPlugPlayNotification returned %08x.\n", status));\r
- }\r
-\r
/* We get started fully powered. */\r
p_ext->DevicePowerState = PowerDeviceD0;\r
powerState.DeviceState = PowerDeviceD0;\r
\r
switch( p_ext->state )\r
{\r
- case HCA_REGISTERED:\r
- __hca_deregister( p_ext );\r
-\r
- /* Fall through. */\r
case HCA_STARTED:\r
/* dequeue HCA */\r
mlnx_hca_remove( &p_ext->hca );\r
}\r
\r
\r
-static NTSTATUS\r
-hca_query_removal_relations(\r
- IN DEVICE_OBJECT* const p_dev_obj,\r
- IN IRP* const p_irp, \r
- OUT cl_irp_action_t* const p_action )\r
-{\r
- NTSTATUS status;\r
- hca_dev_ext_t *p_ext;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
-\r
- if( p_ext->state == HCA_REGISTERED )\r
- {\r
- status = p_ext->ci_ifc.get_relations( p_ext->hca.guid, p_irp );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- *p_action = IrpComplete;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("AL get_relations returned %08x.\n", status));\r
- return status;\r
- }\r
- }\r
-\r
- *p_action = IrpPassDown;\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-static NTSTATUS\r
-hca_query_bus_relations(\r
- IN DEVICE_OBJECT* const p_dev_obj,\r
- IN IRP* const p_irp, \r
- OUT cl_irp_action_t* const p_action )\r
-{\r
- NTSTATUS status;\r
- DEVICE_RELATIONS *p_rel;\r
- hca_dev_ext_t *p_ext;\r
-\r
- HCA_ENTER( HCA_DBG_PNP );\r
-\r
- p_ext = p_dev_obj->DeviceExtension;\r
-\r
- //cl_event_wait_on( &p_ext->mutex, EVENT_NO_TIMEOUT, FALSE );\r
- if( p_ext->state == HCA_REGISTERED )\r
- {\r
- status = p_ext->ci_ifc.get_relations( p_ext->hca.guid, p_irp );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- //cl_event_signal( &p_ext->mutex );\r
- *p_action = IrpComplete;\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("AL get_relations returned %08x.\n", status));\r
- return status;\r
- }\r
- }\r
- else\r
- {\r
- status = cl_alloc_relations( p_irp, 1 );\r
- if( !NT_SUCCESS( status ) )\r
- {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("cl_alloc_relations returned %08x.\n", status));\r
- return status;\r
- }\r
-\r
- p_rel = (DEVICE_RELATIONS*)p_irp->IoStatus.Information;\r
- p_rel->Count = 0;\r
- p_rel->Objects[0] = NULL;\r
- }\r
-\r
- //cl_event_signal( &p_ext->mutex );\r
-\r
- *p_action = IrpPassDown;\r
- HCA_EXIT( HCA_DBG_PNP );\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
static NTSTATUS\r
hca_query_stop(\r
IN DEVICE_OBJECT* const p_dev_obj,\r
return status;\r
}\r
\r
-\r
-static VOID\r
-__hca_noop( VOID *context )\r
+static void\r
+__ref_ifc(\r
+ IN DEVICE_OBJECT* p_dev_obj )\r
{\r
- UNREFERENCED_PARAMETER(context);\r
+ hca_dev_ext_t *p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
+\r
+ HCA_ENTER( HCA_DBG_PNP );\r
+\r
+ cl_atomic_inc( &p_ext->n_hca_ifc_ref );\r
+ ObReferenceObject( p_dev_obj );\r
+\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
+ ("MLX4_HCA: CA_guid %I64x, hca_ifc_ref %d\n",\r
+ p_ext->hca.guid, p_ext->n_hca_ifc_ref) );\r
+\r
+ HCA_EXIT( HCA_DBG_PNP );\r
}\r
\r
+static void\r
+__deref_ifc(\r
+ IN DEVICE_OBJECT* p_dev_obj )\r
+{\r
+ hca_dev_ext_t *p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
+\r
+ HCA_ENTER( HCA_DBG_PNP );\r
+\r
+ cl_atomic_dec( &p_ext->n_hca_ifc_ref );\r
+ ObDereferenceObject( p_dev_obj );\r
+\r
+ HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
+ ("MLX4_HCA: CA_guid %I64x, hca_ifc_ref %d\n",\r
+ p_ext->hca.guid, p_ext->n_hca_ifc_ref) );\r
+\r
+ HCA_EXIT( HCA_DBG_PNP );\r
+}\r
\r
static NTSTATUS\r
__query_ci_ifc(\r
HCA_ENTER( HCA_DBG_PNP );\r
\r
version = VerbsVersionMajor(p_io_stack->Parameters.QueryInterface.Version);\r
- if( version < MTHCA_VERBS_MIN_VERSION || version > MTHCA_VERBS_MAX_VERSION )\r
+ if( version > VERBS_MAJOR_VER )\r
{\r
status = STATUS_NOT_SUPPORTED;\r
goto exit;\r
p_ifc = (RDMA_INTERFACE_VERBS *) p_io_stack->Parameters.QueryInterface.Interface;\r
\r
p_ifc->InterfaceHeader.Size = sizeof(RDMA_INTERFACE_VERBS);\r
- p_ifc->InterfaceHeader.Version = VerbsVersion(version, 0);\r
+ p_ifc->InterfaceHeader.Version = VerbsVersion(VERBS_MAJOR_VER, VERBS_MINOR_VER);\r
p_ifc->InterfaceHeader.Context = p_dev_obj;\r
- p_ifc->InterfaceHeader.InterfaceReference = __hca_noop;\r
- p_ifc->InterfaceHeader.InterfaceDereference = __hca_noop;\r
+ p_ifc->InterfaceHeader.InterfaceReference = __ref_ifc;\r
+ p_ifc->InterfaceHeader.InterfaceDereference = __deref_ifc;\r
p_ifc->Verbs = *p_hca_ifc;\r
- p_ifc->Verbs.p_hca_dev = &p_ext->hca.hob;\r
+ p_ifc->p_hca_obj = &p_ext->hca.hob;\r
+\r
+ /* take the reference before returning. */\r
+ __ref_ifc( p_dev_obj );\r
\r
ExFreePool( p_hca_ifc );\r
status = STATUS_SUCCESS;\r
goto err_mthca_init;\r
}\r
\r
- if( p_ext->p_al_dev ) {\r
- status = __hca_register( p_dev_obj );\r
- if( !NT_SUCCESS( status ) ) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PO, \r
- ("!!! __hca_register failed (%#x) \n", status));\r
- goto err_hca_reg;\r
- }\r
- }\r
-\r
p_ext->DevicePowerState = pIoStack->Parameters.Power.State.DeviceState;\r
powerState = PoSetPowerState( p_dev_obj, DevicePowerState,\r
pIoStack->Parameters.Power.State );\r
\r
goto exit;\r
\r
-err_hca_reg:\r
err_mthca_init:\r
/* Flag device as having failed. */\r
p_ext->pnpState |= PNP_DEVICE_FAILED;\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PO, \r
("***** Remove the HCA \n"));\r
\r
- {\r
- __hca_deregister( p_ext );\r
- mthca_remove_one( p_ext );\r
- }\r
+ mthca_remove_one( p_ext );\r
\r
IoCopyCurrentIrpStackLocationToNext( p_irp );\r
#pragma warning( push, 3 )\r
return status;\r
}\r
\r
-static void\r
-__reregister_hca_cb(\r
- IN DEVICE_OBJECT* p_dev_obj,\r
- IN void* context )\r
-{\r
-#define SLEEP_TIME 100000 // 100 msec\r
-#define POLL_TRIES 20 // to wait for 2 sec\r
- int i;\r
- NTSTATUS status;\r
- LARGE_INTEGER interval;\r
- hca_dev_ext_t *p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
- PIO_WORKITEM pPoWorkItem = (PIO_WORKITEM)context;\r
-\r
- HCA_ENTER( HCA_DBG_PO );\r
-\r
- IoFreeWorkItem( pPoWorkItem );\r
-\r
- /* wait SLEEP_TIME_USEC usec for application to exit */\r
- interval.QuadPart = (-10) * SLEEP_TIME;\r
- KeDelayExecutionThread( KernelMode, FALSE, &interval );\r
- for (i=0; p_ext->usecnt && i < POLL_TRIES; ++i) {\r
- KeDelayExecutionThread( KernelMode, FALSE, &interval );\r
- }\r
-\r
- if (!p_ext->usecnt) {\r
- /* reregister HCA */\r
- __hca_deregister( p_ext );\r
-\r
- if( p_ext->p_al_dev ) {\r
- status = __hca_register( p_dev_obj );\r
- if( !NT_SUCCESS( status ) ) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR, HCA_DBG_PNP, \r
- ("__hca_register returned 0x%08X.\n", status));\r
- }\r
- }\r
- }\r
-\r
- HCA_EXIT( HCA_DBG_PO );\r
-}\r
-\r
-\r
-void reregister_hca( hca_dev_ext_t *p_ext )\r
-{\r
- DEVICE_OBJECT *p_dev_obj = (DEVICE_OBJECT *)p_ext->cl_ext.p_self_do;\r
- PIO_WORKITEM pPoWorkItem;\r
-\r
- /* Process in a work item - deregister_ca and HcaDeinit block. */\r
- pPoWorkItem = IoAllocateWorkItem( p_dev_obj );\r
- if( pPoWorkItem ) \r
- IoQueueWorkItem( pPoWorkItem, __reregister_hca_cb, \r
- DelayedWorkQueue, pPoWorkItem );\r
- \r
-}\r
-\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SHIM,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SHIM);\r
return status;\r
err_user_unsupported:\r
if( status != IB_INSUFFICIENT_MEMORY && status != IB_SUCCESS )\r
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_SHIM,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
HCA_EXIT(HCA_DBG_SHIM);\r
return status;\r
}\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_SHIM,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SHIM);\r
return status;\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SHIM,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SHIM);\r
return status;\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_PD,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_PD);\r
return status;\r
ib_api_status_t status;\r
int err;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
- PREP_IBDEV_FOR_PRINT(ib_pd_p->device);\r
\r
HCA_ENTER( HCA_DBG_PD);\r
\r
if (status != IB_SUCCESS) \r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PD\r
- ,("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ,("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_PD);\r
return status;\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_AV);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_ah *ib_ah_p = (struct ib_ah *)h_av;\r
- PREP_IBDEV_FOR_PRINT(ib_ah_p->device);\r
\r
HCA_ENTER(HCA_DBG_AV);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_AV);\r
return status;\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_AV);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_ah *ib_ah_p = (struct ib_ah *)h_av;\r
- PREP_IBDEV_FOR_PRINT(ib_ah_p->device);\r
\r
HCA_ENTER(HCA_DBG_AV);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_AV,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_AV);\r
return status;\r
struct ib_srq_init_attr srq_init_attr;\r
struct ib_ucontext *p_context = NULL;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
- struct ib_device *ib_dev = ib_pd_p->device;\r
\r
HCA_ENTER(HCA_DBG_SRQ);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SRQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SRQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_srq *ib_srq = (struct ib_srq *)h_srq;\r
- struct ib_device *ib_dev = ib_srq->device;\r
UNUSED_PARAM(p_umv_buf);\r
- UNUSED_PARAM_WOWPP(ib_dev);\r
-\r
+ \r
HCA_ENTER(HCA_DBG_SRQ);\r
\r
err = ibv_modify_srq(ib_srq, (void*)p_srq_attr, srq_attr_mask);\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SRQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SRQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_srq *ib_srq = (struct ib_srq *)h_srq;\r
- struct ib_device *ib_dev = ib_srq->device;\r
UNUSED_PARAM(p_umv_buf);\r
- UNUSED_PARAM_WOWPP(ib_dev);\r
\r
HCA_ENTER(HCA_DBG_SRQ);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SRQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SRQ);\r
return status;\r
int err;\r
ib_api_status_t status = IB_SUCCESS;\r
struct ib_srq *ib_srq = (struct ib_srq *)h_srq;\r
- struct ib_device *ib_dev = ib_srq->device;\r
- UNUSED_PARAM_WOWPP(ib_dev);\r
\r
HCA_ENTER(HCA_DBG_SRQ);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_SRQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_SRQ);\r
return status;\r
struct ib_qp_init_attr qp_init_attr;\r
struct ib_ucontext *p_context = NULL;\r
struct ib_pd *ib_pd_p = (struct ib_pd *)h_pd;\r
- struct ib_device *ib_dev = ib_pd_p->device;\r
\r
HCA_ENTER(HCA_DBG_QP);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
OUT ib_qp_handle_t *ph_qp )\r
{\r
ib_api_status_t status;\r
- PREP_IBDEV_FOR_PRINT(((struct ib_pd*)h_pd)->device);\r
\r
HCA_ENTER(HCA_DBG_SHIM);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
IN OUT ci_umv_buf_t *p_umv_buf )\r
{\r
ib_api_status_t status;\r
- PREP_IBDEV_FOR_PRINT(((struct ib_pd*)h_pd)->device);\r
\r
//NB: algorithm of mthca_alloc_sqp() requires port_num\r
// PRM states, that special pares are created in couples, so\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
struct ib_qp_attr qp_attr;\r
int qp_attr_mask;\r
struct ib_qp *ib_qp_p = (struct ib_qp *)h_qp;\r
- PREP_IBDEV_FOR_PRINT(ib_qp_p->device);\r
\r
HCA_ENTER(HCA_DBG_QP);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
ib_api_status_t status;\r
int err;\r
struct ib_qp *ib_qp_p = (struct ib_qp *)h_qp;\r
- PREP_IBDEV_FOR_PRINT(ib_qp_p->device);\r
\r
UNUSED_PARAM( timewait );\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_QP,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_QP);\r
return status;\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_CQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_CQ);\r
return status;\r
ib_api_status_t status;\r
int err;\r
struct ib_cq *ib_cq_p = (struct ib_cq *)h_cq;\r
- PREP_IBDEV_FOR_PRINT(ib_cq_p->device);\r
\r
HCA_ENTER( HCA_DBG_QP);\r
\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_CQ,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_CQ);\r
return status;\r
if (status != IB_SUCCESS)\r
{\r
HCA_PRINT(TRACE_LEVEL_ERROR,HCA_DBG_MAD,\r
- ("completes with ERROR status %s\n", IB_GET_ERR_STR(status)));\r
+ ("completes with ERROR status %#x\n", status));\r
}\r
HCA_EXIT(HCA_DBG_MAD);\r
return status;\r
{\r
INTERFACE InterfaceHeader;\r
ci_interface_t Verbs;\r
+ void * p_hca_obj;\r
\r
} RDMA_INTERFACE_VERBS;\r
\r
#define FW_WRITE_CMD 0x09
#define FW_MAP_CRSPACE 0x0A
#define FW_UNMAP_CRSPACE 0x0B
-#define FW_REREGISTER_HCA 0x0c
#define FW_OPEN_IF 0xe7
#define FW_CLOSE_IF 0x7e
ib_api_status_t\r
al_test_register_var_mem( void );\r
\r
-ib_api_status_t\r
-al_test_reregister_hca( void );\r
-\r
ib_api_status_t\r
al_test_multi_send_recv( void );\r
\r
+++ /dev/null
-/*\r
- * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
- * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. \r
- * Portions Copyright (c) 2008 Microsoft Corporation. All rights reserved.\r
- *\r
- * This software is available to you under the OpenIB.org BSD license\r
- * below:\r
- *\r
- * Redistribution and use in source and binary forms, with or\r
- * without modification, are permitted provided that the following\r
- * conditions are met:\r
- *\r
- * - Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * - Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
- * SOFTWARE.\r
- *\r
- * $Id$\r
- */\r
-\r
-#include <iba/ib_types.h>\r
-#include <iba/ib_al.h>\r
-#include <complib/cl_memory.h>\r
-#include <complib/cl_timer.h>\r
-#include <alts_debug.h>\r
-#include <alts_common.h>\r
-#include <mthca/mthca_vc.h>\r
-\r
-\r
-/*\r
- * Function prototypes\r
- */\r
-\r
-\r
-/*\r
- * Test Case RegisterMemRegion\r
- */\r
-ib_api_status_t\r
-al_test_reregister_hca(\r
- void\r
- )\r
-{\r
- ib_api_status_t ib_status = IB_SUCCESS;\r
- ib_al_handle_t h_al = NULL;\r
- ib_ca_handle_t h_ca = NULL;\r
- ib_ci_op_t ci_op;\r
-\r
- ALTS_ENTER( ALTS_DBG_VERBOSE );\r
-\r
- while(1)\r
- {\r
- /* Open AL */\r
- ib_status = alts_open_al(&h_al);\r
-\r
- if(ib_status != IB_SUCCESS)\r
- break;\r
-\r
- CL_ASSERT(h_al);\r
-\r
- /* Open CA */\r
- ib_status = alts_open_ca(h_al,&h_ca);\r
- if(ib_status != IB_SUCCESS)\r
- break;\r
-\r
- CL_ASSERT(h_ca);\r
-\r
- /* send ioctl */\r
- memset( &ci_op, 0, sizeof(ci_op) );\r
- ci_op.command = FW_REREGISTER_HCA;\r
-\r
- ib_status = ib_ci_call (h_ca, NULL, 0, &ci_op);\r
- if(ib_status != IB_SUCCESS)\r
- ALTS_PRINT( ALTS_DBG_ERROR,\r
- ("ib_ci_call failed status = %s\n",\r
- ib_get_err_str(ib_status)) );\r
- else\r
- ALTS_PRINT( ALTS_DBG_INFO, \r
- ("ib_ci_call PASSED.\n") );\r
- break;\r
- }\r
-\r
- if(h_ca)\r
- alts_close_ca(h_ca);\r
-\r
- if(h_al)\r
- alts_close_al(h_al);\r
-\r
- ALTS_EXIT( ALTS_DBG_VERBOSE);\r
- return ib_status;\r
-}\r
-\r
..\openclose.c \\r
..\querycaattr.c \\r
..\registermemregion.c \\r
- ..\reregister_hca.c \\r
..\registerpnp.c \\r
..\smatests.c\r
\r
case RegisterVarMemRegions:\r
ib_status = al_test_register_var_mem();\r
break;\r
- case ReregisterHca:\r
- ib_status = al_test_reregister_hca();\r
- break;\r
case RegisterPhyMemRegion:\r
CL_PRINT( ALTS_DBG_VERBOSE, alts_dbg_lvl,\r
("altsapp: RegisterPhyMemRegion not implemented.\n") );\r