SOURCES= \\r
mthca_log.mc \\r
hca.rc \\r
- mthca_kmdf.c \\r
wmi.c \\r
mthca_log.c \\r
\\r
\r
MSC_OPTIMIZATION=/Oi\r
# ignore volatile ignored warning @ line 318 in mt_atmoic.h\r
-MSC_WARNING_LEVEL= /W4 /wd4197 /wd4324 /wd4201\r
+MSC_WARNING_LEVEL= /W4 /wd4197 /wd4201 /wd4324\r
/*\r
+ * Copyright (c) 2008 Intel corporation. All rights reserved.\r
* Copyright (c) 2005 SilverStorm Technologies. All rights reserved.\r
*\r
* This software is available to you under the OpenIB.org BSD license\r
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
* SOFTWARE.\r
*\r
- * $Id: hca_driver.c 931 2008-01-31 09:20:41Z leonidk $\r
+ * $Id$\r
*/\r
\r
\r
/*\r
- * Provides the driver entry points for the Tavor VPD.\r
+ * Provides KMDF driver entry points for the Tavor VPD.\r
+ * Driver: load/unload, start/stop.\r
*/\r
\r
#include <mt_utils.h>\r
#include "hca_driver.h"\r
#include "hca_debug.h"\r
+#include "hca_pnp.h"\r
\r
+#include <ntintsafe.h>\r
+#include <initguid.h>\r
+\r
+#include "mthca_public.h"\r
#include "mthca_log.h"\r
#if defined(EVENT_TRACING)\r
#ifdef offsetof\r
#endif\r
#include "hca_driver.tmh"\r
#endif\r
+\r
+\r
+\r
+DRIVER_INITIALIZE DriverEntry;\r
+DRIVER_UNLOAD hca_drv_unload;\r
+\r
+NTSTATUS\r
+DriverEntry (\r
+ IN PDRIVER_OBJECT DriverObject,\r
+ IN PUNICODE_STRING RegistryPath );\r
+\r
+NTSTATUS\r
+HcaWmiRegistration( WDFDEVICE Device );\r
+\r
+NTSTATUS\r
+HcaAllocSWResources(PFDO_DATA fdoData);\r
+\r
+NTSTATUS\r
+HcaFreeSWResources(PFDO_DATA fdoData);\r
+\r
+VOID\r
+HcaEvtDeviceSelfManagedIoCleanup( IN WDFDEVICE Device );\r
+\r
+NTSTATUS\r
+HcaEvtDeviceSelfManagedIoSuspend( IN WDFDEVICE Device );\r
+\r
+\r
+#define PARAMATER_NAME_LEN 80\r
+\r
#include "mthca_dev.h"\r
#include <wdmguid.h>\r
#include <initguid.h>\r
void reregister_hca( hca_dev_ext_t *p_ext );\r
\r
\r
-NTSTATUS\r
+static NTSTATUS\r
HcaEntry(\r
IN PDRIVER_OBJECT p_driver_obj,\r
IN PUNICODE_STRING p_registry_path );\r
__read_registry(\r
IN UNICODE_STRING* const p_Param_Path );\r
\r
-static void\r
+void\r
hca_drv_unload(\r
IN PDRIVER_OBJECT p_driver_obj );\r
\r
fw_flash_deinit(\r
IN BUS_INTERFACE_STANDARD *p_BusInterface );\r
\r
+\r
#ifdef ALLOC_PRAGMA\r
-#pragma alloc_text (INIT, HcaEntry)\r
-#pragma alloc_text (INIT, __read_registry)\r
+#pragma alloc_text (INIT, DriverEntry)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceAdd)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceContextCleanup)\r
+#pragma alloc_text (PAGE, HcaReadRegistryValue)\r
+#pragma alloc_text (PAGE, HcaWriteRegistryValue)\r
+#pragma alloc_text (PAGE, HcaEvtDriverContextCleanup)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceSelfManagedIoCleanup)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceSelfManagedIoSuspend)\r
+#pragma alloc_text (PAGE, HcaReadFdoRegistryKeyValue)\r
#pragma alloc_text (PAGE, hca_drv_unload)\r
#pragma alloc_text (PAGE, hca_sysctl)\r
#endif\r
\r
-NTSTATUS\r
+\r
+static NTSTATUS\r
HcaEntry(\r
IN PDRIVER_OBJECT p_driver_obj,\r
IN PUNICODE_STRING p_registry_path )\r
NTSTATUS status;\r
cl_status_t cl_status;\r
\r
+ UNREFERENCED_PARAMETER( p_driver_obj ); // XXX\r
+\r
HCA_ENTER( HCA_DBG_DEV );\r
\r
/* init common mechanisms */\r
#endif\r
/* init core */\r
if (ib_core_init()) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_INIT ,("Failed to init core, aborting.\n"));\r
+ HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_INIT,\r
+ ("Failed to init core, aborting.\n"));\r
return STATUS_UNSUCCESSFUL;\r
}\r
\r
/* init uverbs module */\r
if (ib_uverbs_init()) {\r
- HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_INIT ,("Failed ib_uverbs_init, aborting.\n"));\r
+ HCA_PRINT( TRACE_LEVEL_ERROR ,HCA_DBG_INIT,\r
+ ("Failed ib_uverbs_init, aborting.\n"));\r
return STATUS_UNSUCCESSFUL;\r
}\r
HCA_EXIT( HCA_DBG_DEV );\r
+\r
return STATUS_SUCCESS;\r
}\r
\r
#if defined(EVENT_TRACING)\r
WPP_CLEANUP(p_driver_obj);\r
#endif\r
-\r
}\r
\r
\r
}\r
return status;\r
}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Installable driver initialization entry point.\r
+ This entry point is called directly by the I/O system.\r
+\r
+Arguments:\r
+\r
+ DriverObject - pointer to the driver object\r
+\r
+ RegistryPath - pointer to a unicode string representing the path,\r
+ to driver-specific key in the registry.\r
+\r
+Return Value:\r
+\r
+ STATUS_SUCCESS if successful,\r
+ STATUS_UNSUCCESSFUL otherwise.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+DriverEntry (\r
+ IN PDRIVER_OBJECT DriverObject,\r
+ IN PUNICODE_STRING RegistryPath )\r
+{\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ WDF_DRIVER_CONFIG config;\r
+ WDF_OBJECT_ATTRIBUTES attrib;\r
+ WDFDRIVER driver;\r
+ PDRIVER_CONTEXT driverContext;\r
+\r
+ //\r
+ // Initialize WPP Tracing\r
+ //\r
+#if defined(EVENT_TRACING)\r
+ WPP_INIT_TRACING( DriverObject, RegistryPath );\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,\r
+ "mthca - KM Driver Framework Edition \n");\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,\r
+ "Built %s %s\n", __DATE__, __TIME__);\r
+\r
+// WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrib, DRIVER_CONTEXT);\r
+\r
+ //\r
+ // Register a cleanup callback so that we can call WPP_CLEANUP when\r
+ // the framework driver object is deleted during driver unload.\r
+ //\r
+ attrib.EvtCleanupCallback = HcaEvtDriverContextCleanup;\r
+\r
+ //\r
+ // Initialize the Driver Config structure..\r
+ //\r
+ WDF_DRIVER_CONFIG_INIT(&config, HcaEvtDeviceAdd);\r
+\r
+ //\r
+ // Create a WDFDRIVER object.\r
+ //\r
+ status = WdfDriverCreate(DriverObject,\r
+ RegistryPath,\r
+ &attrib,\r
+ &config,\r
+ &driver);\r
+\r
+ if (!NT_SUCCESS(status)) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,\r
+ "WdfDriverCreate failed with status %!STATUS!\n", status);\r
+ //\r
+ // Cleanup tracing here because DriverContextCleanup will not be called\r
+ // as we have failed to create WDFDRIVER object itself.\r
+ // Please note that if your return failure from DriverEntry after the\r
+ // WDFDRIVER object is created successfully, you don't have to\r
+ // call WPP cleanup because in those cases DriverContextCleanup\r
+ // will be executed when the framework deletes the DriverObject.\r
+ //\r
+#if defined(EVENT_TRACING)\r
+ WPP_CLEANUP(DriverObject);\r
+#endif\r
+ return status;\r
+ }\r
+\r
+ driverContext = GetDriverContext(driver);\r
+ driverContext->DrvObj = DriverObject; // for DeviceAdd\r
+#if 0\r
+ //\r
+ // Create a driver wide lookside list used for allocating memory for the\r
+ // MP_RFD structure for all device instances (if there are multiple present).\r
+ //\r
+ status = WdfLookasideListCreate(WDF_NO_OBJECT_ATTRIBUTES, // LookAsideAttributes\r
+ sizeof(MP_RFD),\r
+ NonPagedPool,\r
+ WDF_NO_OBJECT_ATTRIBUTES, // MemoryAttributes\r
+ PCIDRV_POOL_TAG,\r
+ &driverContext->RecvLookaside );\r
+ if (!NT_SUCCESS(status))\r
+ {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,\r
+ "Couldn't allocate lookaside list status %!STATUS!\n", status);\r
+ return status;\r
+ }\r
+ if (!NT_SUCCESS(status))\r
+ return status;\r
+#endif\r
+\r
+ return HcaEntry( DriverObject, RegistryPath );\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+\r
+ EvtDeviceAdd is called by the framework in response to AddDevice\r
+ call from the PnP manager.\r
+\r
+Arguments:\r
+\r
+ Driver - Handle to a framework driver object created in DriverEntry\r
+\r
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceAdd (\r
+ IN WDFDRIVER Driver,\r
+ IN PWDFDEVICE_INIT DeviceInit )\r
+{\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\r
+ WDF_POWER_POLICY_EVENT_CALLBACKS powerPolicyCallbacks;\r
+ WDF_OBJECT_ATTRIBUTES fdoAttributes;\r
+ WDFDEVICE device;\r
+ PFDO_DATA fdoData = NULL;\r
+\r
+ UNREFERENCED_PARAMETER( Driver );\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ //\r
+ // I/O type is Buffered by default. If required to use something else,\r
+ // call WdfDeviceInitSetIoType with the appropriate type.\r
+ //\r
+ WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);\r
+\r
+ //\r
+ // Zero out the PnpPowerCallbacks structure.\r
+ //\r
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\r
+\r
+ //\r
+ // Set Callbacks for any of the functions we are interested in.\r
+ // If no callback is set, Framework will take the default action\r
+ // by itself. This sample provides many of the possible callbacks,\r
+ // mostly because it's a fairly complex sample that drives full-featured\r
+ // hardware. Drivers derived from this sample will often be able to\r
+ // provide only some of these.\r
+ //\r
+\r
+ //\r
+ // These callback is invoked to tear down all the driver-managed state\r
+ // that is set up in this function. Many times, this callback won't do\r
+ // much of anything, since many of the things that are set up here will\r
+ // have their lifetimes automatically managed by the Framework.\r
+ //\r
+\r
+ //\r
+ // These two callbacks set up and tear down hardware state,\r
+ // specifically that which only has to be done once.\r
+ //\r
+\r
+ pnpPowerCallbacks.EvtDevicePrepareHardware = HcaEvtDevicePrepareHardware;\r
+ pnpPowerCallbacks.EvtDeviceReleaseHardware = HcaEvtDeviceReleaseHardware;\r
+\r
+ //\r
+ // These two callbacks set up and tear down hardware state that must be\r
+ // done every time the device moves in and out of the D0-working state.\r
+ //\r
+\r
+ pnpPowerCallbacks.EvtDeviceD0Entry = HcaEvtDeviceD0Entry;\r
+ pnpPowerCallbacks.EvtDeviceD0Exit = HcaEvtDeviceD0Exit;\r
+\r
+ //\r
+ // These next two callbacks are for doing work at PASSIVE_LEVEL (low IRQL)\r
+ // after all the interrupts are connected and before they are disconnected.\r
+ //\r
+ // Some drivers need to do device initialization and tear-down while the\r
+ // interrupt is connected. (This is a problem for these devices, since\r
+ // it opens them up to taking interrupts before they are actually ready\r
+ // to handle them, or to taking them after they have torn down too much\r
+ // to be able to handle them.) While this hardware design pattern is to\r
+ // be discouraged, it is possible to handle it by doing device init and\r
+ // tear down in these routines rather than in EvtDeviceD0Entry and\r
+ // EvtDeviceD0Exit.\r
+ //\r
+ // In this sample these callbacks don't do anything.\r
+ //\r
+\r
+ pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled =\r
+ HcaEvtDeviceD0EntryPostInterruptsEnabled;\r
+ pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled =\r
+ HcaEvtDeviceD0ExitPreInterruptsDisabled;\r
+\r
+ //\r
+ // This next group of five callbacks allow a driver to become involved in\r
+ // starting and stopping operations within a driver as the driver moves\r
+ // through various PnP/Power states. These functions are not necessary\r
+ // if the Framework is managing all the device's queues and there is no\r
+ // activity going on that isn't queue-based. This sample provides these\r
+ // callbacks because it uses watchdog timer to monitor whether the device\r
+ // is working or not and it needs to start and stop the timer when the\r
+ // device is started or removed. It cannot start and stop the timers in the\r
+ // D0Entry and D0Exit callbacks because if the device is surprise-removed,\r
+ // D0Exit will not be called.\r
+ //\r
+ pnpPowerCallbacks.EvtDeviceSelfManagedIoInit =\r
+ HcaEvtDeviceSelfManagedIoInit;\r
+ pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup =\r
+ HcaEvtDeviceSelfManagedIoCleanup;\r
+ pnpPowerCallbacks.EvtDeviceSelfManagedIoSuspend =\r
+ HcaEvtDeviceSelfManagedIoSuspend;\r
+ pnpPowerCallbacks.EvtDeviceSelfManagedIoRestart =\r
+ HcaEvtDeviceSelfManagedIoRestart;\r
+\r
+ //\r
+ // Register the PnP and power callbacks. Power policy related callbacks will\r
+ // be registered later.\r
+ //\r
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\r
+\r
+ //\r
+ // Init the power policy callbacks\r
+ //\r
+ WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(&powerPolicyCallbacks);\r
+\r
+ //\r
+ // This group of three callbacks allows this sample driver to manage\r
+ // arming the device for wake from the S0 state. Networking devices can\r
+ // optionally be put into a low-power state when there is no networking\r
+ // cable plugged into them. This sample implements this feature.\r
+ //\r
+ powerPolicyCallbacks.EvtDeviceArmWakeFromS0 = HcaEvtDeviceWakeArmS0;\r
+ powerPolicyCallbacks.EvtDeviceDisarmWakeFromS0 = HcaEvtDeviceWakeDisarmS0;\r
+ powerPolicyCallbacks.EvtDeviceWakeFromS0Triggered =\r
+ HcaEvtDeviceWakeTriggeredS0;\r
+\r
+ //\r
+ // This group of three callbacks allows the device to be armed for wake\r
+ // from Sx (S1, S2, S3 or S4.) Networking devices can optionally be put\r
+ // into a state where a packet sent to them will cause the device's wake\r
+ // signal to be triggered, which causes the machine to wake, moving back\r
+ // into the S0 state.\r
+ //\r
+\r
+ powerPolicyCallbacks.EvtDeviceArmWakeFromSx = HcaEvtDeviceWakeArmSx;\r
+ powerPolicyCallbacks.EvtDeviceDisarmWakeFromSx = HcaEvtDeviceWakeDisarmSx;\r
+ powerPolicyCallbacks.EvtDeviceWakeFromSxTriggered =\r
+ HcaEvtDeviceWakeTriggeredSx;\r
+\r
+ WdfDeviceInitSetDeviceType( DeviceInit,\r
+ FILE_DEVICE_INFINIBAND|FILE_DEVICE_SECURE_OPEN );\r
+\r
+ WdfDeviceInitSetExclusive(DeviceInit, TRUE);\r
+ //\r
+ // Register the power policy callbacks.\r
+ //\r
+ WdfDeviceInitSetPowerPolicyEventCallbacks(DeviceInit,&powerPolicyCallbacks);\r
+\r
+ // Since we are the function driver, we are now the power policy owner\r
+ // for the device according to the default framework rule. We will register\r
+ // our power policy callbacks after finding the wakeup capability of the\r
+ // device.\r
+\r
+\r
+ // Specify the context type and size for the device we are about to create.\r
+\r
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);\r
+\r
+\r
+ // ContextCleanup will be called by the framework when it deletes the\r
+ // device. So you can defer freeing any resources allocated to Cleanup\r
+ // callback in the event AddDevice returns any error after the device is\r
+ // created.\r
+\r
+ fdoAttributes.EvtCleanupCallback = HcaEvtDeviceContextCleanup;\r
+\r
+ status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);\r
+\r
+ if ( !NT_SUCCESS(status)) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "WdfDeviceInitialize failed %!STATUS!\n", status);\r
+ return status;\r
+ }\r
+\r
+ //\r
+ // Device creation is complete.\r
+ // Get the DeviceExtension and initialize it.\r
+ //\r
+ fdoData = FdoGetData(device);\r
+ RtlZeroMemory( (VOID*)fdoData, sizeof(*fdoData) );\r
+\r
+ fdoData->WdfDevice = device; // for pre-KMDF routines.\r
+\r
+ // from deprecated hca_add_device()\r
+ cl_spinlock_init( &fdoData->uctx_lock );\r
+ cl_qlist_init( &fdoData->uctx_list );\r
+ atomic_set( &fdoData->usecnt, 0 );\r
+ fdoData->state = HCA_ADDED;\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n",\r
+ WdfDeviceWdmGetPhysicalDevice (device),\r
+ WdfDeviceWdmGetDeviceObject (device),\r
+ WdfDeviceWdmGetAttachedDevice(device),\r
+ fdoData);\r
+\r
+ // Initialize the device extension and allocate all the software resources\r
+\r
+ status = HcaAllocSWResources(fdoData);\r
+ if (!NT_SUCCESS (status)){\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "HcaAllocSWResources failed: %!STATUS!\n",\r
+ status);\r
+ return status;\r
+ }\r
+\r
+ //\r
+ // If we own the power policy and if our device supports wait-wake then we\r
+ // will set our power-policy and update S0-Idle policy.\r
+ //\r
+ if(IsPoMgmtSupported(fdoData) )\r
+ {\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "Device has wait-wake capability\n");\r
+ status = HcaSetPowerPolicy(fdoData);\r
+ if (!NT_SUCCESS (status)) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "HcaSetPowerPolicy failed %!STATUS!\n", status);\r
+ return status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Tell the Framework that this device will need an interface so that\r
+ // application can interact with it.\r
+ //\r
+ status = WdfDeviceCreateDeviceInterface( device,\r
+ (LPGUID)&GUID_DEVINTERFACE_RDMA_IO,\r
+ NULL );\r
+ if (!NT_SUCCESS (status))\r
+ {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "WdfDeviceCreateDeviceInterface failed %!STATUS!\n",status);\r
+ return status;\r
+ }\r
+\r
+ status = HcaWmiRegistration(device);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s() ret %x\n",__FUNCTION__, status);\r
+ return status;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceContextCleanup event callback cleans up anything done in\r
+ EvtDeviceAdd, except those things that are automatically cleaned\r
+ up by the Framework.\r
+\r
+ In the case of this sample, everything is automatically handled. In a\r
+ driver derived from this sample, it's quite likely that this function could\r
+ be deleted.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+Return Value:\r
+\r
+ VOID\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceContextCleanup ( WDFDEVICE Device )\r
+{\r
+ PFDO_DATA fdoData;\r
+ NTSTATUS status;\r
+\r
+ PAGED_CODE();\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ status = HcaFreeSWResources(fdoData);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ HcaEvtDeviceSelfManagedIoInit is called by the Framework when the device\r
+ enters the D0 state. Its job is to start any I/O-related actions that the\r
+ Framework isn't managing. This might include releasing queues that are not\r
+ power-managed, that is, the Framework is not automatically holding and\r
+ releasing them across PnP/Power transitions. (The default behavior for\r
+ WDFQUEUE is auto-managed, so most queues don't need to be dealt with here.)\r
+ This might also include setting up non-queue-based actions.\r
+\r
+ If you allow the Framework to manage most or all of your queues, then when\r
+ you build a driver from this sample, you can probably delete this function.\r
+\r
+ In this driver, the SelfManagedIo callbacks are used to implement a\r
+ watchdog timer.\r
+\r
+ This function is not marked pagable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failures will result in the device stack being torn down.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceSelfManagedIoInit( IN WDFDEVICE Device )\r
+{\r
+ PFDO_DATA fdoData = NULL;\r
+ NTSTATUS status=STATUS_SUCCESS;\r
+// WDF_TIMER_CONFIG wdfTimerConfig;\r
+// WDF_OBJECT_ATTRIBUTES timerAttributes;\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+#if 0\r
+ // To minimize init-time, create a timer DPC to do link detection.\r
+ // This DPC will also be used to check for hardware hang.\r
+ //\r
+ WDF_TIMER_CONFIG_INIT(&wdfTimerConfig, NICWatchDogEvtTimerFunc);\r
+\r
+ WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);\r
+ timerAttributes.ParentObject = fdoData->WdfDevice;\r
+\r
+ status = WdfTimerCreate(\r
+ &wdfTimerConfig,\r
+ &timerAttributes,\r
+ &fdoData->WatchDogTimer\r
+ );\r
+\r
+ if(!NT_SUCCESS(status) ) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "Error: WdfTimerCreate create failed 0x%x\n", status);\r
+ return status;\r
+ }\r
+\r
+ NICStartWatchDogTimer(fdoData);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s() ret %x\n", __FUNCTION__, status);\r
+\r
+ return status;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceSelfManagedIoSuspend is called by the Framework before the device\r
+ leaves the D0 state. Its job is to stop any I/O-related actions that the\r
+ Framework isn't managing, and which cannot be handled when the device\r
+ hardware isn't available. In general, this means reversing anything that\r
+ was done in EvtDeviceSelfManagedIoStart.\r
+\r
+ If you allow the Framework to manage most or all of your queues, then when\r
+ you build a driver from this sample, you can probably delete this function.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failures will result in the device stack being torn down.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceSelfManagedIoSuspend( IN WDFDEVICE Device )\r
+{\r
+ PFDO_DATA fdoData = NULL;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "--> HcaEvtDeviceSelfManagedIoSuspend\n");\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+#if 0\r
+ //\r
+ // Stop the watchdog timer and wait for DPC to run to completion if\r
+ // it's already fired.\r
+ //\r
+ WdfTimerStop(fdoData->WatchDogTimer, TRUE);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- HcaEvtDeviceSelfManagedIoSuspend\n");\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+NTSTATUS\r
+HcaEvtDeviceSelfManagedIoRestart(\r
+ IN WDFDEVICE Device\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceSelfManagedIoRestart is called by the Framework before the device\r
+ is restarted for one of the following reasons:\r
+ a) the PnP resources were rebalanced (framework received\r
+ query-stop and stop IRPS )\r
+ b) the device resumed from a low power state to D0.\r
+\r
+ This function is not marked pagable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failure will cause the device stack to be torn down.\r
+\r
+--*/\r
+{\r
+ PFDO_DATA fdoData;\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "--> HcaEvtDeviceSelfManagedIoRestart\n");\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ //\r
+ // Restart the watchdog timer.\r
+ //\r
+#if 0\r
+ NICStartWatchDogTimer(fdoData);\r
+#endif\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- HcaEvtDeviceSelfManagedIoRestart\n");\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceSelfManagedIoCleanup is called by the Framework when the device is\r
+ being torn down, either in response to the WDM IRP_MN_REMOVE_DEVICE\r
+ It will be called only once. Its job is to stop all outstanding I/O in the driver\r
+ that the Framework is not managing.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+Return Value:\r
+\r
+ None\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceSelfManagedIoCleanup( IN WDFDEVICE Device )\r
+{\r
+ PFDO_DATA fdoData = NULL;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "--> HcaEvtDeviceSelfManagedIoCleanup\n");\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+#if 0\r
+ if(fdoData->WatchDogTimer) {\r
+ WdfObjectDelete(fdoData->WatchDogTimer);\r
+ }\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- HcaEvtDeviceSelfManagedIoCleanup\n");\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This event is called when the framework receives IRP_MJ_DEVICE_CONTROL\r
+ requests from the system.\r
+\r
+Arguments:\r
+\r
+ Queue - Handle to the framework queue object that is associated\r
+ with the I/O request.\r
+ Request - Handle to a framework request object.\r
+\r
+ OutputBufferLength - length of the request's output buffer,\r
+ if an output buffer is available.\r
+ InputBufferLength - length of the request's input buffer,\r
+ if an input buffer is available.\r
+\r
+ IoControlCode - the driver-defined or system-defined I/O control code\r
+ (IOCTL) that is associated with the request.\r
+Return Value:\r
+\r
+ VOID\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtIoDeviceControl(\r
+ IN WDFQUEUE Queue,\r
+ IN WDFREQUEST Request,\r
+ IN size_t OutputBufferLength,\r
+ IN size_t InputBufferLength,\r
+ IN ULONG IoControlCode )\r
+{\r
+ //NTSTATUS status= STATUS_SUCCESS;\r
+ PFDO_DATA fdoData = NULL;\r
+ WDFDEVICE hDevice;\r
+ WDF_REQUEST_PARAMETERS params;\r
+\r
+ UNREFERENCED_PARAMETER(OutputBufferLength);\r
+ UNREFERENCED_PARAMETER(InputBufferLength);\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS,\r
+ "HcaEvtIoDeviceControl called %p\n", Request);\r
+\r
+ hDevice = WdfIoQueueGetDevice(Queue);\r
+ fdoData = FdoGetData(hDevice);\r
+\r
+ WDF_REQUEST_PARAMETERS_INIT(¶ms);\r
+\r
+ WdfRequestGetParameters(\r
+ Request,\r
+ ¶ms\r
+ );\r
+\r
+ switch (IoControlCode)\r
+ {\r
+#if 0\r
+ case IOCTL_NDISPROT_QUERY_OID_VALUE:\r
+\r
+ ASSERT((IoControlCode & 0x3) == METHOD_BUFFERED);\r
+\r
+ NICHandleQueryOidRequest(\r
+ Queue,\r
+ Request,\r
+ ¶ms\r
+ );\r
+ break;\r
+\r
+ case IOCTL_NDISPROT_SET_OID_VALUE:\r
+\r
+ ASSERT((IoControlCode & 0x3) == METHOD_BUFFERED);\r
+\r
+ NICHandleSetOidRequest(\r
+ Queue,\r
+ Request,\r
+ ¶ms\r
+ );\r
+\r
+ break;\r
+\r
+ case IOCTL_NDISPROT_INDICATE_STATUS:\r
+\r
+ status = WdfRequestForwardToIoQueue(Request,\r
+ fdoData->PendingIoctlQueue);\r
+ if(!NT_SUCCESS(status)){\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,\r
+ "WdfRequestForwardToIoQueue failed 0x%x\n", status);\r
+ WdfRequestComplete(Request, status);\r
+ break;\r
+ }\r
+\r
+ break;\r
+#endif\r
+ default:\r
+ ASSERTMSG(FALSE, "Invalid IOCTL request\n");\r
+ WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine is used to queue workitems so that the callback\r
+ functions can be executed at PASSIVE_LEVEL in the conext of\r
+ a system thread.\r
+\r
+Arguments:\r
+\r
+ FdoData - pointer to a device extenion.\r
+\r
+ CallbackFunction - Function to invoke when at PASSIVE_LEVEL.\r
+\r
+ Context1 & 2 - Meaning of the context values depends on the\r
+ callback function.\r
+\r
+Return Value:\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaQueuePassiveLevelCallback(\r
+ IN PFDO_DATA FdoData,\r
+ IN PFN_WDF_WORKITEM CallbackFunction,\r
+ IN PVOID Context1,\r
+ IN PVOID Context2 )\r
+{\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ PWORKER_ITEM_CONTEXT context;\r
+ WDF_OBJECT_ATTRIBUTES attributes;\r
+ WDF_WORKITEM_CONFIG workitemConfig;\r
+ WDFWORKITEM hWorkItem;\r
+\r
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WORKER_ITEM_CONTEXT);\r
+\r
+ attributes.ParentObject = FdoData->WdfDevice;\r
+\r
+ WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CallbackFunction);\r
+\r
+ status = WdfWorkItemCreate( &workitemConfig,\r
+ &attributes,\r
+ &hWorkItem);\r
+\r
+ if (!NT_SUCCESS(status)) {\r
+ return status;\r
+ }\r
+\r
+ context = GetWorkItemContext(hWorkItem);\r
+\r
+ context->FdoData = FdoData;\r
+ context->Argument1 = Context1;\r
+ context->Argument2 = Context2;\r
+\r
+ //\r
+ // Execute this work item.\r
+ //\r
+ WdfWorkItemEnqueue(hWorkItem);\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Can be used to read any REG_DWORD registry value stored\r
+ under Device Parameter.\r
+\r
+Arguments:\r
+\r
+ FdoData - pointer to the device extension\r
+ Name - Name of the registry value\r
+ Value -\r
+\r
+\r
+Return Value:\r
+\r
+ TRUE if successful\r
+ FALSE if not present/error in reading registry\r
+\r
+--*/\r
+\r
+BOOLEAN\r
+HcaReadRegistryValue(\r
+ __in PFDO_DATA FdoData,\r
+ __in PWCHAR Name,\r
+ __out PULONG Value )\r
+{\r
+ WDFKEY hKey = NULL;\r
+ NTSTATUS status;\r
+ BOOLEAN retValue = FALSE;\r
+ UNICODE_STRING valueName;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "--> %s()\n", __FUNCTION__);\r
+\r
+ *Value = 0;\r
+\r
+ status = WdfDeviceOpenRegistryKey(FdoData->WdfDevice,\r
+ PLUGPLAY_REGKEY_DEVICE,\r
+ STANDARD_RIGHTS_ALL,\r
+ WDF_NO_OBJECT_ATTRIBUTES,\r
+ &hKey);\r
+\r
+ if (NT_SUCCESS (status)) {\r
+\r
+ RtlInitUnicodeString(&valueName,Name);\r
+\r
+ status = WdfRegistryQueryULong( hKey,\r
+ &valueName,\r
+ Value );\r
+\r
+ if (NT_SUCCESS (status)) {\r
+ retValue = TRUE;\r
+ }\r
+\r
+ WdfRegistryClose(hKey);\r
+ }\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,\r
+ "<-- %s() %ws %d \n", __FUNCTION__, Name, *Value);\r
+\r
+ return retValue;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Can be used to write any REG_DWORD registry value stored\r
+ under Device Parameter.\r
+\r
+Arguments:\r
+\r
+\r
+Return Value:\r
+\r
+ TRUE - if write is successful\r
+ FALSE - otherwise\r
+\r
+--*/\r
+\r
+BOOLEAN\r
+HcaWriteRegistryValue(\r
+ __in PFDO_DATA FdoData,\r
+ __in PWCHAR Name,\r
+ __in ULONG Value )\r
+{\r
+ WDFKEY hKey = NULL;\r
+ NTSTATUS status;\r
+ BOOLEAN retValue = FALSE;\r
+ UNICODE_STRING valueName;\r
+\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "--> %s()\n", __FUNCTION__);\r
+\r
+ //\r
+ // write the value out to the registry\r
+ //\r
+ status = WdfDeviceOpenRegistryKey(FdoData->WdfDevice,\r
+ PLUGPLAY_REGKEY_DEVICE,\r
+ STANDARD_RIGHTS_ALL,\r
+ WDF_NO_OBJECT_ATTRIBUTES,\r
+ &hKey);\r
+\r
+ if (NT_SUCCESS (status)) {\r
+\r
+ RtlInitUnicodeString(&valueName,Name);\r
+\r
+ status = WdfRegistryAssignULong (hKey,\r
+ &valueName,\r
+ Value );\r
+\r
+ if (NT_SUCCESS (status)) {\r
+ retValue = TRUE;\r
+ }\r
+\r
+ WdfRegistryClose(hKey);\r
+ }\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,\r
+ "<-- ret %s() %s\n", __FUNCTION__, (retValue ? "True":"False"));\r
+\r
+ return retValue;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Can be used to read any REG_DWORD registry value stored\r
+ under Device Parameter.\r
+\r
+Arguments:\r
+\r
+ FdoData - pointer to the device extension\r
+ Name - Name of the registry value\r
+ Value -\r
+\r
+\r
+Return Value:\r
+\r
+ TRUE if successful\r
+ FALSE if not present/error in reading registry\r
+\r
+--*/\r
+\r
+BOOLEAN\r
+HcaReadFdoRegistryKeyValue(\r
+ __in PWDFDEVICE_INIT DeviceInit,\r
+ __in PWCHAR Name,\r
+ __out PULONG Value )\r
+{\r
+ WDFKEY hKey = NULL;\r
+ NTSTATUS status;\r
+ BOOLEAN retValue = FALSE;\r
+ UNICODE_STRING valueName;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ *Value = 0;\r
+\r
+ status = WdfFdoInitOpenRegistryKey(DeviceInit,\r
+ PLUGPLAY_REGKEY_DEVICE,\r
+ STANDARD_RIGHTS_ALL,\r
+ WDF_NO_OBJECT_ATTRIBUTES,\r
+ &hKey);\r
+\r
+ if (NT_SUCCESS (status)) {\r
+\r
+ RtlInitUnicodeString(&valueName,Name);\r
+\r
+ status = WdfRegistryQueryULong (hKey,\r
+ &valueName,\r
+ Value);\r
+\r
+ if (NT_SUCCESS (status)) {\r
+ retValue = TRUE;\r
+ }\r
+\r
+ WdfRegistryClose(hKey);\r
+ }\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
+ "<-- %s() %ws %d \n", __FUNCTION__, Name, *Value);\r
+\r
+ return retValue;\r
+}\r
+\r
+\r
+/*++\r
+Routine Description:\r
+\r
+ Free all the resources allocated in DriverEntry.\r
+\r
+Arguments:\r
+\r
+ Driver - handle to a WDF Driver object.\r
+\r
+Return Value:\r
+\r
+ VOID.\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDriverContextCleanup( IN WDFDRIVER Driver )\r
+{\r
+ UNREFERENCED_PARAMETER( Driver );\r
+\r
+ PAGED_CODE ();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s()\n",__FUNCTION__);\r
+\r
+ // Stop WPP Tracing\r
+ //\r
+ WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ) );\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s()\n",__FUNCTION__);\r
+}\r
+\r
+\r
+#if !defined(EVENT_TRACING)\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Debug print for the sample driver.\r
+\r
+Arguments:\r
+\r
+ TraceEventsLevel - print level between 0 and 3, with 3 the most verbose\r
+\r
+Return Value:\r
+\r
+ None.\r
+\r
+ --*/\r
+\r
+VOID\r
+TraceEvents (\r
+ IN ULONG TraceEventsLevel,\r
+ IN ULONG TraceEventsFlag,\r
+ IN PCCHAR DebugMessage,\r
+ ... )\r
+ {\r
+#if 1 // always for starters... DBG\r
+\r
+#define TEMP_BUFFER_SIZE 512\r
+ va_list list;\r
+ CHAR debugMessageBuffer[TEMP_BUFFER_SIZE];\r
+ NTSTATUS status;\r
+\r
+ va_start(list, DebugMessage);\r
+\r
+ if (DebugMessage) {\r
+\r
+ //\r
+ // Using new safe string functions instead of _vsnprintf.\r
+ // This function takes care of NULL terminating if the message\r
+ // is longer than the buffer.\r
+ //\r
+ status = RtlStringCbVPrintfA( debugMessageBuffer,\r
+ sizeof(debugMessageBuffer),\r
+ DebugMessage,\r
+ list );\r
+ if(!NT_SUCCESS(status)) {\r
+\r
+ DbgPrint (_DRIVER_NAME_": RtlStringCbVPrintfA failed %x\n",\r
+ status);\r
+ return;\r
+ }\r
+ if (TraceEventsLevel <= TRACE_LEVEL_INFORMATION ||\r
+ (TraceEventsLevel <= g_mthca_dbg_level &&\r
+ ((TraceEventsFlag & g_mthca_dbg_flags) == TraceEventsFlag))) {\r
+ DbgPrint(debugMessageBuffer);\r
+ }\r
+ }\r
+ va_end(list);\r
+\r
+ return;\r
+#else\r
+ UNREFERENCED_PARAMETER(TraceEventsLevel);\r
+ UNREFERENCED_PARAMETER(TraceEventsFlag);\r
+ UNREFERENCED_PARAMETER(DebugMessage);\r
+#endif\r
+}\r
+\r
+#endif\r
+\r
+\r
+NTSTATUS\r
+HcaAllocSWResources(PFDO_DATA fdoData)\r
+{\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
+ "--> %s() fdoData %p\n", __FUNCTION__, fdoData);\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+NTSTATUS\r
+HcaFreeSWResources(PFDO_DATA fdoData)\r
+{\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
+ "--> %s() fdoData %p\n", __FUNCTION__, fdoData);\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
#include "trace.h"\r
\r
\r
-#include "hca_pnp.h"\r
#include "hca_pci.h"\r
\r
#if !defined(FILE_DEVICE_INFINIBAND) // Not defined in WXP DDK\r
EVT_WDF_OBJECT_CONTEXT_CLEANUP HcaEvtDriverContextCleanup;\r
EVT_WDF_DEVICE_CONTEXT_CLEANUP HcaEvtDeviceContextCleanup;\r
\r
-EVT_WDF_DEVICE_D0_ENTRY HcaEvtDeviceD0Entry;\r
-EVT_WDF_DEVICE_D0_EXIT HcaEvtDeviceD0Exit;\r
-EVT_WDF_DEVICE_PREPARE_HARDWARE HcaEvtDevicePrepareHardware;\r
-EVT_WDF_DEVICE_RELEASE_HARDWARE HcaEvtDeviceReleaseHardware;\r
-\r
EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP HcaEvtDeviceSelfManagedIoCleanup;\r
EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT HcaEvtDeviceSelfManagedIoInit;\r
EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND HcaEvtDeviceSelfManagedIoSuspend;\r
EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART HcaEvtDeviceSelfManagedIoRestart;\r
-\r
-EVT_WDF_DEVICE_SURPRISE_REMOVAL HcaEvtDeviceSurpriseRemoval;\r
-\r
-EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 HcaEvtDeviceWakeArmS0;\r
-EVT_WDF_DEVICE_ARM_WAKE_FROM_SX HcaEvtDeviceWakeArmSx;\r
-EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 HcaEvtDeviceWakeDisarmS0;\r
-EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX HcaEvtDeviceWakeDisarmSx;\r
-EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED HcaEvtDeviceWakeTriggeredS0;\r
-EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED HcaEvtDeviceWakeTriggeredSx;\r
-EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED HcaEvtDeviceD0EntryPostInterruptsEnabled;\r
-EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED HcaEvtDeviceD0ExitPreInterruptsDisabled;\r
-\r
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HcaEvtIoDeviceControl;\r
\r
NTSTATUS\r
WDFDEVICE hDevice\r
);\r
\r
-PCHAR\r
-DbgDevicePowerString(\r
- IN WDF_POWER_DEVICE_STATE Type\r
- );\r
-\r
\r
BOOLEAN\r
HcaReadFdoRegistryKeyValue(\r
/* BEGIN_ICS_COPYRIGHT ****************************************\r
** END_ICS_COPYRIGHT ****************************************/\r
-\r
/*\r
- $Revision: 1.1 $\r
-*/\r
-\r
+ * Copyright (c) 2008 Intel corporation. All rights reserved.\r
+ * Copyright (c) 2005 SilverStorm Technologies. 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
+ *\r
+ * $Id$\r
+ */\r
\r
/*\r
- * Provides the driver entry points for the Tavor VPD.\r
+ * Provides driver entry points for Plug-n-Play power management.\r
*/\r
\r
#include "hca_driver.h"\r
+#include "hca_pnp.h"\r
#include "mthca_dev.h"\r
\r
#if defined(EVENT_TRACING)\r
\r
\r
#ifdef ALLOC_PRAGMA\r
+#pragma alloc_text (PAGE, HcaEvtDevicePrepareHardware)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceReleaseHardware)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceWakeArmS0)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceWakeDisarmS0)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceWakeTriggeredS0)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceWakeArmSx)\r
+#pragma alloc_text (PAGE, HcaSetPowerPolicy)\r
+\r
#pragma alloc_text (PAGE, hca_add_device)\r
#pragma alloc_text (PAGE, hca_start)\r
#pragma alloc_text (PAGE, hca_query_stop)\r
#pragma alloc_text (PAGE, __hca_register)\r
#pragma alloc_text (PAGE, __pnp_notify_target)\r
#pragma alloc_text (PAGE, __pnp_notify_ifc)\r
+\r
+#pragma alloc_text (PAGE, HcaEvtDeviceD0ExitPreInterruptsDisabled)\r
+#pragma alloc_text (PAGE, HcaEvtDeviceD0EntryPostInterruptsEnabled)\r
+\r
#endif\r
\r
\r
}\r
\r
\r
+#ifdef NOT_USED_XXX\r
+\r
NTSTATUS\r
hca_add_device(\r
IN PDRIVER_OBJECT pDriverObj,\r
UNREFERENCED_PARAMETER(pDriverObj);\r
\r
HCA_ENTER(HCA_DBG_PNP);\r
-#if 0\r
+\r
/*\r
* Create the device so that we have a device extension to store stuff in.\r
*/\r
("IoCreateDevice returned 0x%08X.\n", status));\r
return status;\r
}\r
-#endif\r
\r
p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
cl_memclr( p_ext, sizeof(hca_dev_ext_t) );\r
cl_qlist_init( &p_ext->uctx_list );\r
atomic_set(&p_ext->usecnt, 0);\r
\r
-#if 0\r
/* Attach to the device stack. */\r
pNextDevObj = IoAttachDeviceToDeviceStack( p_dev_obj, pPdo );\r
if( !pNextDevObj )\r
("IoAttachDeviceToDeviceStack failed.\n"));\r
return STATUS_NO_SUCH_DEVICE;\r
}\r
-#endif\r
-\r
-// XXX fixup pNextDevObj... STAN\r
- pNextDevObj = NULL;\r
\r
/* Inititalize the complib extension. */\r
cl_init_pnp_po_ext( p_dev_obj, pNextDevObj, pPdo, 0, &vfptrHcaPnp, NULL );\r
\r
return status;\r
}\r
-\r
+#endif\r
\r
static NTSTATUS\r
__get_ci_interface(\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
+ HCA_PRINT( TRACE_LEVEL_INFORMATION ,HCA_DBG_SHIM,\r
+ ("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
/* We get started fully powered. */\r
p_ext->DevicePowerState = PowerDeviceD0;\r
powerState.DeviceState = PowerDeviceD0;\r
- powerState = PoSetPowerState ( p_ext->cl_ext.p_self_do, DevicePowerState, powerState );\r
+ powerState = PoSetPowerState ( p_ext->cl_ext.p_self_do,\r
+ DevicePowerState, powerState );\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PNP, \r
("PoSetPowerState: old state %d, new state to %d\n", \r
powerState.DeviceState, p_ext->DevicePowerState ));\r
\r
/* release the resources, allocated in hca_start */\r
static void\r
-__hca_release_resources(\r
- IN DEVICE_OBJECT* const p_dev_obj )\r
+__hca_release_resources( IN DEVICE_OBJECT* const p_dev_obj )\r
{\r
hca_dev_ext_t *p_ext = (hca_dev_ext_t*)p_dev_obj->DeviceExtension;\r
\r
/* Notify the power manager that the device is powered down. */\r
p_ext->DevicePowerState = PowerDeviceD3;\r
powerState.DeviceState = PowerDeviceD3;\r
- powerState = PoSetPowerState ( p_ext->cl_ext.p_self_do, DevicePowerState, powerState );\r
+ powerState = PoSetPowerState ( p_ext->cl_ext.p_self_do,\r
+ DevicePowerState, powerState );\r
\r
HCA_PRINT( TRACE_LEVEL_INFORMATION, HCA_DBG_PNP, \r
("PoSetPowerState: old state %d, new state to %d\n", \r
\r
}\r
\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceStart event callback performs operations that are necessary\r
+ to make the driver's device operational. The framework calls the driver's\r
+ EvtDeviceStart callback when the PnP manager sends an IRP_MN_START_DEVICE\r
+ request to the driver stack.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+ Resources - Handle to a collection of framework resource objects.\r
+ This collection identifies the raw (bus-relative) hardware\r
+ resources that have been assigned to the device.\r
+\r
+ ResourcesTranslated - Handle to a collection of framework resource objects.\r
+ This collection identifies the translated (system-physical)\r
+ hardware resources that have been assigned to the device.\r
+ The resources appear from the CPU's point of view.\r
+ Use this list of resources to map I/O space and\r
+ device-accessible memory into virtual address space\r
+\r
+Return Value:\r
+\r
+ WDF status code\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDevicePrepareHardware (\r
+ WDFDEVICE Device,\r
+ WDFCMRESLIST Resources,\r
+ WDFCMRESLIST ResourcesTranslated )\r
+{\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+ PFDO_DATA fdoData = NULL;\r
+ DEVICE_OBJECT* p_dev_obj;\r
+\r
+ UNREFERENCED_PARAMETER(Resources);\r
+ UNREFERENCED_PARAMETER(ResourcesTranslated);\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+ p_dev_obj = WdfDeviceWdmGetAttachedDevice(Device),\r
+\r
+#if 0\r
+ status = NICMapHWResources(fdoData, ResourcesTranslated);\r
+ if (!NT_SUCCESS (status)){\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "NICMapHWResources failed: %!STATUS!\n", status);\r
+ return status;\r
+ }\r
+#endif\r
+\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s() ret %x\n", __FUNCTION__, status);\r
+\r
+ return status;\r
+\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceReleaseHardware is called by the framework whenever the PnP manager\r
+ is revoking ownership of our resources. This may be in response to either\r
+ IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. The callback is made before\r
+ passing down the IRP to the lower driver.\r
+\r
+ In this callback, do anything necessary to free those resources.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+ ResourcesTranslated - Handle to a collection of framework resource objects.\r
+ This collection identifies the translated (system-physical)\r
+ hardware resources that have been assigned to the device.\r
+ The resources appear from the CPU's point of view.\r
+ Use this list of resources to map I/O space and\r
+ device-accessible memory into virtual address space\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failures will be logged, but not acted on.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceReleaseHardware(\r
+ IN WDFDEVICE Device,\r
+ IN WDFCMRESLIST ResourcesTranslated )\r
+{\r
+ PFDO_DATA fdoData;\r
+ PDEVICE_OBJECT p_dev_obj;\r
+\r
+ UNREFERENCED_PARAMETER(ResourcesTranslated);\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+ p_dev_obj = WdfDeviceWdmGetAttachedDevice(Device),\r
+\r
+#if 0\r
+ //\r
+ // Unmap any I/O ports. Disconnecting from the interrupt will be done\r
+ // automatically by the framework.\r
+ //\r
+ NICUnmapHWResources(fdoData);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/*++\r
+\r
+Updated Routine Description:\r
+ DbgDevicePowerString does not change in this stage of the function driver.\r
+\r
+--*/\r
+\r
+static PCHAR\r
+DbgDevicePowerString( IN WDF_POWER_DEVICE_STATE Type )\r
+{\r
+ switch (Type)\r
+ {\r
+ case WdfPowerDeviceInvalid:\r
+ return "WdfPowerDeviceInvalid";\r
+ case WdfPowerDeviceD0:\r
+ return "WdfPowerDeviceD0";\r
+ case PowerDeviceD1:\r
+ return "WdfPowerDeviceD1";\r
+ case WdfPowerDeviceD2:\r
+ return "WdfPowerDeviceD2";\r
+ case WdfPowerDeviceD3:\r
+ return "WdfPowerDeviceD3";\r
+ case WdfPowerDeviceD3Final:\r
+ return "WdfPowerDeviceD3Final";\r
+ case WdfPowerDevicePrepareForHibernation:\r
+ return "WdfPowerDevicePrepareForHibernation";\r
+ case WdfPowerDeviceMaximum:\r
+ return "PowerDeviceMaximum";\r
+ default:\r
+ return "UnKnown Device Power State";\r
+ }\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceD0Entry event callback must perform any operations that are\r
+ necessary before the specified device is used. It will be called every\r
+ time the hardware needs to be (re-)initialized. This includes after\r
+ IRP_MN_START_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE,\r
+ IRP_MN_SET_POWER-D0.\r
+\r
+ This function is not marked pageable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+ This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
+ driver can optionally make this function pageable if DO_POWER_PAGABLE\r
+ is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
+ at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
+ not do anything that will cause a page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+ PreviousState - Device power state which the device was in most recently.\r
+ If the device is being newly started, this will be\r
+ PowerDeviceUnspecified.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceD0Entry(\r
+ IN WDFDEVICE Device,\r
+ IN WDF_POWER_DEVICE_STATE PreviousState )\r
+{\r
+ PFDO_DATA fdoData;\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,\r
+ "-->HcaEvtDeviceD0Entry - coming from %s\n",\r
+ DbgDevicePowerString(PreviousState));\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ ASSERT(PowerDeviceD0 != PreviousState);\r
+\r
+ fdoData->DevicePowerState = PowerDeviceD0;\r
+\r
+ if(IsPoMgmtSupported(fdoData)){\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER,\r
+ "Entering fully on state\n");\r
+#ifdef XXX\r
+ MPSetPowerD0 (fdoData);\r
+#endif\r
+ }\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--HcaEvtDeviceD0Entry\n");\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+NTSTATUS\r
+HcaEvtDeviceD0Exit(\r
+ IN WDFDEVICE Device,\r
+ IN WDF_POWER_DEVICE_STATE TargetState\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This routine undoes anything done in EvtDeviceD0Entry. It is called\r
+ whenever the device leaves the D0 state, which happens when the device is\r
+ stopped, when it is removed, and when it is powered off.\r
+\r
+ The device is still in D0 when this callback is invoked, which means that\r
+ the driver can still touch hardware in this routine.\r
+\r
+ Note that interrupts have already been disabled by the time that this\r
+ callback is invoked.\r
+\r
+ EvtDeviceD0Exit event callback must perform any operations that are\r
+ necessary before the specified device is moved out of the D0 state. If the\r
+ driver needs to save hardware state before the device is powered down, then\r
+ that should be done here.\r
+\r
+ This function runs at PASSIVE_LEVEL, though it is generally not paged. A\r
+ driver can optionally make this function pageable if DO_POWER_PAGABLE is set.\r
+\r
+ Even if DO_POWER_PAGABLE isn't set, this function still runs at\r
+ PASSIVE_LEVEL. In this case, though, the function absolutely must not do\r
+ anything that will cause a page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a framework device object.\r
+\r
+ TargetState - Device power state which the device will be put in once this\r
+ callback is complete.\r
+\r
+Return Value:\r
+\r
+ Success implies that the device can be used. Failure will result in the\r
+ device stack being torn down.\r
+\r
+--*/\r
+{\r
+ PFDO_DATA fdoData;\r
+\r
+ UNREFERENCED_PARAMETER(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,\r
+ "-->HcaEvtDeviceD0Exit - moving to %s\n",\r
+ DbgDevicePowerString(TargetState));\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ fdoData->DevicePowerState = TargetState;\r
+\r
+ switch (TargetState) {\r
+ case WdfPowerDeviceD1:\r
+ case WdfPowerDeviceD2:\r
+ case WdfPowerDeviceD3:\r
+\r
+ if(IsPoMgmtSupported(fdoData)){\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER,\r
+ "Entering a deeper sleep state\n");\r
+#ifdef XXX\r
+ MPSetPowerLow (fdoData, TargetState);\r
+#endif\r
+ }\r
+ break;\r
+\r
+ case WdfPowerDevicePrepareForHibernation:\r
+\r
+ //\r
+ // Fill in any code to save hardware state here. Do not put in any\r
+ // code to shut the device off. If this device cannot support being\r
+ // in the paging path (or being a parent or grandparent of a paging\r
+ // path device) then this whole case can be deleted.\r
+ //\r
+ ASSERT(FALSE); // This driver shouldn't get this.\r
+ break;\r
+\r
+ case WdfPowerDeviceD3Final:\r
+ //\r
+ // Reset and put the device into a known initial state we're shutting\r
+ // down for the last time.\r
+ //\r
+#if 0\r
+ NICShutdown(fdoData);\r
+#endif\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--HcaEvtDeviceD0Exit\n");\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeArmS0 is called when the Framework arms the device for\r
+ wake in the S0 state. If there is any device-specific initialization\r
+ that needs to be done to arm internal wake signals, or to route internal\r
+ interrupt signals to the wake logic, it should be done here. The device\r
+ will be moved out of the D0 state soon after this callback is invoked.\r
+\r
+ In this sample, wake from S0 involves waking on packet arrival, as does\r
+ wake from Sx. A more common NIC implementation might wake on cable\r
+ insertion.\r
+\r
+ This function is pageable and it will run at PASSIVE_LEVEL.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failure will result in the device remaining in the D0 state.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceWakeArmS0( IN WDFDEVICE Device )\r
+{\r
+ NTSTATUS status=STATUS_SUCCESS;\r
+ PFDO_DATA fdoData;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ //\r
+ // Add pattern before sending wait-wake\r
+ //\r
+#if 0\r
+ status = NICConfigureForWakeUp(fdoData, TRUE);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s() %x\n", __FUNCTION__, status);\r
+\r
+ return status;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeArmSx is called when the Framework arms the device for\r
+ wake from the S1, S2, S3 or S4 states. If there is any device-specific\r
+ initialization that needs to be done to arm internal wake signals, or to\r
+ route internal interrupt signals to the wake logic, it should be done here.\r
+ The device will be moved out of the D0 state soon after this callback is\r
+ invoked.\r
+\r
+ In this sample, wake from Sx involves arming for wake on packet arrival.\r
+ Cable insertion should not be enabled, as nobody would want their machine\r
+ to wake up simply because they plugged the cable in.\r
+\r
+ This function runs at PASSIVE_LEVEL. Whether it is pageable or not depends\r
+ on whether the device has set DO_POWER_PAGABLE.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ NTSTATUS - Failure will result in the device not being armed for wake\r
+ while the system is in Sx.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceWakeArmSx( IN WDFDEVICE Device )\r
+{\r
+ NTSTATUS status=STATUS_SUCCESS;\r
+ PFDO_DATA fdoData;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+ //\r
+ // Add pattern before sending wait-wake\r
+ //\r
+#if 0\r
+ status = NICConfigureForWakeUp(fdoData, TRUE);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s() ret %x\n", __FUNCTION__, status);\r
+\r
+ return status;\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeDisarmS0 reverses anything done in EvtDeviceWakeArmS0.\r
+\r
+ This function is pageable and it will run at PASSIVE_LEVEL.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ VOID.\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceWakeDisarmS0( IN WDFDEVICE Device )\r
+{\r
+ NTSTATUS status=STATUS_SUCCESS;\r
+ PFDO_DATA fdoData;\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+#if 0\r
+ status = NICConfigureForWakeUp(fdoData, FALSE);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s %x\n", __FUNCTION__, status);\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeDisarmSx reverses anything done in EvtDeviceWakeArmSx.\r
+\r
+ This function is not marked pageable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+ This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
+ driver can optionally make this function pageable if DO_POWER_PAGABLE\r
+ is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
+ at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
+ not do anything that will cause a page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ VOID\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceWakeDisarmSx( IN WDFDEVICE Device )\r
+{\r
+ NTSTATUS status=STATUS_SUCCESS;\r
+ PFDO_DATA fdoData;\r
+\r
+ UNREFERENCED_PARAMETER(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+#if 0\r
+ status = NICConfigureForWakeUp(fdoData, FALSE);\r
+#endif\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
+ "<-- %s %x\n", __FUNCTION__, status);\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeTriggeredS0 will be called whenever the device triggers its\r
+ wake signal after being armed for wake from S0.\r
+\r
+ This function is pageable and runs at PASSIVE_LEVEL.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ VOID\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceWakeTriggeredS0( IN WDFDEVICE Device )\r
+{\r
+ UNREFERENCED_PARAMETER(Device);\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
+\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ EvtDeviceWakeTriggeredSx will be called whenever the device triggers its\r
+ wake signal after being armed for wake from Sx.\r
+\r
+ This function is not marked pageable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+ This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
+ driver can optionally make this function pageable if DO_POWER_PAGABLE\r
+ is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
+ at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
+ not do anything that will cause a page fault.\r
+\r
+Arguments:\r
+\r
+ Device - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ VOID\r
+\r
+--*/\r
+\r
+VOID\r
+HcaEvtDeviceWakeTriggeredSx( IN WDFDEVICE Device )\r
+{\r
+ UNREFERENCED_PARAMETER(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s", __FUNCTION__);\r
+\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s", __FUNCTION__);\r
+\r
+ return;\r
+}\r
+\r
+\r
+\r
+NTSTATUS\r
+HcaSetPowerPolicy(\r
+ IN PFDO_DATA FdoData\r
+ )\r
+{\r
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;\r
+ WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings;\r
+ NTSTATUS status = STATUS_SUCCESS;\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ PAGED_CODE();\r
+\r
+ //\r
+ // Init the idle policy structure.\r
+ //\r
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCanWakeFromS0);\r
+ idleSettings.IdleTimeout = 10000; // 10-sec\r
+\r
+ status = WdfDeviceAssignS0IdleSettings(FdoData->WdfDevice, &idleSettings);\r
+ if ( !NT_SUCCESS(status)) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status);\r
+ return status;\r
+ }\r
+\r
+ //\r
+ // Init wait-wake policy structure.\r
+ //\r
+ WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);\r
+\r
+ status = WdfDeviceAssignSxWakeSettings(FdoData->WdfDevice, &wakeSettings);\r
+ if (!NT_SUCCESS(status)) {\r
+ TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
+ "WdfDeviceAssignSxWakeSettings failed %x\n", status);\r
+ return status;\r
+ }\r
+\r
+ TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return status;\r
+}\r
+\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This event is called so that driver can do PASSIVE_LEVEL work before\r
+ the interrupt is disconnected and disabled.\r
+\r
+Arguments:\r
+\r
+ Interrupt - Handle to a Framework interrupt object.\r
+\r
+ AssociatedDevice - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ STATUS_SUCCESS - indicates success.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceD0ExitPreInterruptsDisabled(\r
+ IN WDFDEVICE Device,\r
+ IN WDF_POWER_DEVICE_STATE TargetState )\r
+{\r
+ PFDO_DATA fdoData;\r
+\r
+ UNREFERENCED_PARAMETER(TargetState);\r
+\r
+ PAGED_CODE();\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return STATUS_SUCCESS;\r
+\r
+}\r
+\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ This event is called so that driver can do PASSIVE_LEVEL work after\r
+ the interrupt is connected and enabled. Here we start the watchdog timer.\r
+ Watch dog timer is used to do the initial link detection during\r
+ start and then used to make sure the device is not stuck for any reason.\r
+\r
+ This function is not marked pageable because this function is in the\r
+ device power up path. When a function is marked pagable and the code\r
+ section is paged out, it will generate a page fault which could impact\r
+ the fast resume behavior because the client driver will have to wait\r
+ until the system drivers can service this page fault.\r
+\r
+Arguments:\r
+\r
+ Interrupt - Handle to a Framework interrupt object.\r
+\r
+ AssociatedDevice - Handle to a Framework device object.\r
+\r
+Return Value:\r
+\r
+ STATUS_SUCCESS - indicates success.\r
+\r
+--*/\r
+\r
+NTSTATUS\r
+HcaEvtDeviceD0EntryPostInterruptsEnabled(\r
+ IN WDFDEVICE Device,\r
+ IN WDF_POWER_DEVICE_STATE PreviousState )\r
+{\r
+ PFDO_DATA fdoData;\r
+\r
+ UNREFERENCED_PARAMETER( PreviousState );\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
+\r
+ fdoData = FdoGetData(Device);\r
+\r
+ TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
+\r
+ return STATUS_SUCCESS;\r
+\r
+}\r
+\r
void hca_init_vfptr( void );
+
+EVT_WDF_DEVICE_D0_ENTRY HcaEvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT HcaEvtDeviceD0Exit;
+EVT_WDF_DEVICE_PREPARE_HARDWARE HcaEvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE HcaEvtDeviceReleaseHardware;
+
+EVT_WDF_DEVICE_SURPRISE_REMOVAL HcaEvtDeviceSurpriseRemoval;
+
+EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 HcaEvtDeviceWakeArmS0;
+EVT_WDF_DEVICE_ARM_WAKE_FROM_SX HcaEvtDeviceWakeArmSx;
+EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 HcaEvtDeviceWakeDisarmS0;
+EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX HcaEvtDeviceWakeDisarmSx;
+EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED HcaEvtDeviceWakeTriggeredS0;
+EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED HcaEvtDeviceWakeTriggeredSx;
+EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED HcaEvtDeviceD0EntryPostInterruptsEnabled;
+EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED HcaEvtDeviceD0ExitPreInterruptsDisabled;
+
NTSTATUS
-hca_add_device(
- IN PDRIVER_OBJECT pDriverObj,
- IN PDEVICE_OBJECT pPdo,
- IN PDEVICE_OBJECT p_dev_obj );
+HcaEvtDeviceD0ExitPreInterruptsDisabled(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE TargetState );
+
+NTSTATUS
+HcaEvtDeviceD0EntryPostInterruptsEnabled(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE PreviousState );
+static __inline BOOLEAN
+IsPoMgmtSupported( IN PFDO_DATA FdoData )
+{
+#if 1
+ UNREFERENCED_PARAMETER(FdoData);
+ return TRUE;
+#else
+ if (FdoData->RevsionID >= E100_82559_A_STEP
+ /*&& FdoData->RevsionID <= E100_82559_C_STEP*/)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
#endif
+}
+
+
+#endif /* _HCA_PNP_H_ */
+++ /dev/null
-/*\r
- * Copyright (c) 2008 Intel Corporation. All rights reserved.\r
- * Copyright (c) 2005 SilverStorm Technologies. 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
-/*++\r
-Copyright (c) Microsoft Corporation. All rights reserved.\r
-\r
- THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY\r
- KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\r
- IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR\r
- PURPOSE.\r
-\r
-Module Name:\r
-\r
- mthca_kmdf.c\r
-\r
-Abstract:\r
-\r
- The WDM interfaces in this sample are derrived from the PciDrv KMDF samples\r
- function driver (e100 NIC). mthca interfaces have been merged.\r
- Goal is to provide a skeleton KMDF wrapper around the existing mthca driver\r
- as a starting point in the migrate to a full KMDF driver enviroment.\r
-\r
-Environment:\r
-\r
- Kernel mode\r
-\r
---*/\r
-\r
-#include "hca_driver.h"\r
-#include <ntintsafe.h>\r
-#include <initguid.h>\r
-\r
-#include "mthca_public.h"\r
-\r
-DRIVER_INITIALIZE DriverEntry;\r
-DRIVER_UNLOAD hca_drv_unload;\r
-\r
-// hca_driver.c - previous DriverEntry()\r
-NTSTATUS\r
-HcaEntry (\r
- IN PDRIVER_OBJECT p_driver_obj,\r
- IN PUNICODE_STRING p_registry_path );\r
-\r
-void\r
-hca_drv_unload( IN PDRIVER_OBJECT p_driver_obj );\r
-\r
-NTSTATUS\r
-HcaWmiRegistration( WDFDEVICE Device );\r
-\r
-NTSTATUS\r
-HcaAllocSWResources(PFDO_DATA fdoData);\r
-\r
-NTSTATUS\r
-HcaFreeSWResources(PFDO_DATA fdoData);\r
-\r
-VOID\r
-HcaEvtDeviceSelfManagedIoCleanup( IN WDFDEVICE Device );\r
-\r
-NTSTATUS\r
-HcaEvtDeviceSelfManagedIoSuspend( IN WDFDEVICE Device );\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0ExitPreInterruptsDisabled(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE TargetState );\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0EntryPostInterruptsEnabled(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE PreviousState );\r
-\r
-\r
-#if defined(EVENT_TRACING)\r
-//\r
-// The trace message header (.tmh) file must be included in a source file\r
-// before any WPP macro calls and after defining a WPP_CONTROL_GUIDS\r
-// macro (defined in toaster.h). During the compilation, WPP scans the source\r
-// files for DoTraceMessage() calls and builds a .tmh file which stores a unique\r
-// data GUID for each message, the text resource string for each message,\r
-// and the data types of the variables passed in for each message. This file\r
-// is automatically generated and used during post-processing.\r
-//\r
-#include "pcidrv.tmh"\r
-#endif\r
-\r
-#ifdef ALLOC_PRAGMA\r
-#pragma alloc_text (INIT, DriverEntry)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceAdd)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceContextCleanup)\r
-#pragma alloc_text (PAGE, HcaEvtDevicePrepareHardware)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceReleaseHardware)\r
-#pragma alloc_text (PAGE, HcaReadRegistryValue)\r
-#pragma alloc_text (PAGE, HcaWriteRegistryValue)\r
-#pragma alloc_text (PAGE, HcaEvtDriverContextCleanup)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceSelfManagedIoCleanup)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceSelfManagedIoSuspend)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceWakeArmS0)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceWakeDisarmS0)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceWakeTriggeredS0)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceWakeArmSx)\r
-#pragma alloc_text (PAGE, HcaSetPowerPolicy)\r
-#pragma alloc_text (PAGE, HcaReadFdoRegistryKeyValue)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceD0ExitPreInterruptsDisabled)\r
-#pragma alloc_text (PAGE, HcaEvtDeviceD0EntryPostInterruptsEnabled)\r
-#endif\r
-\r
-#define PARAMATER_NAME_LEN 80\r
-\r
-__inline\r
-BOOLEAN\r
-IsPoMgmtSupported(\r
- IN PFDO_DATA FdoData\r
- )\r
-{\r
-#if 1\r
- UNREFERENCED_PARAMETER(FdoData);\r
- return TRUE;\r
-#else\r
- if (FdoData->RevsionID >= E100_82559_A_STEP\r
- /*&& FdoData->RevsionID <= E100_82559_C_STEP*/)\r
- {\r
- return TRUE;\r
- }\r
- else\r
- {\r
- return FALSE;\r
- }\r
-#endif\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Installable driver initialization entry point.\r
- This entry point is called directly by the I/O system.\r
-\r
-Arguments:\r
-\r
- DriverObject - pointer to the driver object\r
-\r
- RegistryPath - pointer to a unicode string representing the path,\r
- to driver-specific key in the registry.\r
-\r
-Return Value:\r
-\r
- STATUS_SUCCESS if successful,\r
- STATUS_UNSUCCESSFUL otherwise.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-DriverEntry (\r
- IN PDRIVER_OBJECT DriverObject,\r
- IN PUNICODE_STRING RegistryPath )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- WDF_DRIVER_CONFIG config;\r
- WDF_OBJECT_ATTRIBUTES attrib;\r
- WDFDRIVER driver;\r
- PDRIVER_CONTEXT driverContext;\r
-\r
- //\r
- // Initialize WPP Tracing\r
- //\r
-#if defined(EVENT_TRACING)\r
- WPP_INIT_TRACING( DriverObject, RegistryPath );\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,\r
- "mthca - KM Driver Framework Edition \n");\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT,\r
- "Built %s %s\n", __DATE__, __TIME__);\r
-\r
-// WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attrib, DRIVER_CONTEXT);\r
-\r
- //\r
- // Register a cleanup callback so that we can call WPP_CLEANUP when\r
- // the framework driver object is deleted during driver unload.\r
- //\r
- attrib.EvtCleanupCallback = HcaEvtDriverContextCleanup;\r
-\r
- //\r
- // Initialize the Driver Config structure..\r
- //\r
- WDF_DRIVER_CONFIG_INIT(&config, HcaEvtDeviceAdd);\r
-\r
- //\r
- // Create a WDFDRIVER object.\r
- //\r
- status = WdfDriverCreate(DriverObject,\r
- RegistryPath,\r
- &attrib,\r
- &config,\r
- &driver);\r
-\r
- if (!NT_SUCCESS(status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,\r
- "WdfDriverCreate failed with status %!STATUS!\n", status);\r
- //\r
- // Cleanup tracing here because DriverContextCleanup will not be called\r
- // as we have failed to create WDFDRIVER object itself.\r
- // Please note that if your return failure from DriverEntry after the\r
- // WDFDRIVER object is created successfully, you don't have to\r
- // call WPP cleanup because in those cases DriverContextCleanup\r
- // will be executed when the framework deletes the DriverObject.\r
- //\r
-#if defined(EVENT_TRACING)\r
- WPP_CLEANUP(DriverObject);\r
-#endif\r
- return status;\r
- }\r
-\r
- driverContext = GetDriverContext(driver);\r
- driverContext->DrvObj = DriverObject; // for DeviceAdd\r
-#if 0\r
- //\r
- // Create a driver wide lookside list used for allocating memory for the\r
- // MP_RFD structure for all device instances (if there are multiple present).\r
- //\r
- status = WdfLookasideListCreate(WDF_NO_OBJECT_ATTRIBUTES, // LookAsideAttributes\r
- sizeof(MP_RFD),\r
- NonPagedPool,\r
- WDF_NO_OBJECT_ATTRIBUTES, // MemoryAttributes\r
- PCIDRV_POOL_TAG,\r
- &driverContext->RecvLookaside\r
- );\r
- if (!NT_SUCCESS(status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_INIT,\r
- "Couldn't allocate lookaside list status %!STATUS!\n", status);\r
- return status;\r
- }\r
-#endif\r
- if (!NT_SUCCESS(status))\r
- return status;\r
-\r
- return HcaEntry( DriverObject, RegistryPath );\r
-}\r
-\r
-\r
-/*++\r
-Routine Description:\r
-\r
- EvtDeviceAdd is called by the framework in response to AddDevice\r
- call from the PnP manager.\r
-\r
-Arguments:\r
-\r
- Driver - Handle to a framework driver object created in DriverEntry\r
-\r
- DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.\r
-\r
-Return Value:\r
-\r
- NTSTATUS\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceAdd(\r
- IN WDFDRIVER Driver,\r
- IN PWDFDEVICE_INIT DeviceInit )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;\r
- WDF_POWER_POLICY_EVENT_CALLBACKS powerPolicyCallbacks;\r
- WDF_OBJECT_ATTRIBUTES fdoAttributes;\r
- WDFDEVICE device;\r
- PFDO_DATA fdoData = NULL;\r
- PDRIVER_CONTEXT DriverContext;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "-->%s() Driver: 0x%p\n", __FUNCTION__, Driver);\r
-\r
- //\r
- // I/O type is Buffered by default. If required to use something else,\r
- // call WdfDeviceInitSetIoType with the appropriate type.\r
- //\r
- WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);\r
-\r
- //\r
- // Zero out the PnpPowerCallbacks structure.\r
- //\r
- WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);\r
-\r
- //\r
- // Set Callbacks for any of the functions we are interested in.\r
- // If no callback is set, Framework will take the default action\r
- // by itself. This sample provides many of the possible callbacks,\r
- // mostly because it's a fairly complex sample that drives full-featured\r
- // hardware. Drivers derived from this sample will often be able to\r
- // provide only some of these.\r
- //\r
-\r
- //\r
- // These callback is invoked to tear down all the driver-managed state\r
- // that is set up in this function. Many times, this callback won't do\r
- // much of anything, since many of the things that are set up here will\r
- // have their lifetimes automatically managed by the Framework.\r
- //\r
-\r
- //\r
- // These two callbacks set up and tear down hardware state,\r
- // specifically that which only has to be done once.\r
- //\r
-\r
- pnpPowerCallbacks.EvtDevicePrepareHardware = HcaEvtDevicePrepareHardware;\r
- pnpPowerCallbacks.EvtDeviceReleaseHardware = HcaEvtDeviceReleaseHardware;\r
-\r
- //\r
- // These two callbacks set up and tear down hardware state that must be\r
- // done every time the device moves in and out of the D0-working state.\r
- //\r
-\r
- pnpPowerCallbacks.EvtDeviceD0Entry = HcaEvtDeviceD0Entry;\r
- pnpPowerCallbacks.EvtDeviceD0Exit = HcaEvtDeviceD0Exit;\r
-\r
- //\r
- // These next two callbacks are for doing work at PASSIVE_LEVEL (low IRQL)\r
- // after all the interrupts are connected and before they are disconnected.\r
- //\r
- // Some drivers need to do device initialization and tear-down while the\r
- // interrupt is connected. (This is a problem for these devices, since\r
- // it opens them up to taking interrupts before they are actually ready\r
- // to handle them, or to taking them after they have torn down too much\r
- // to be able to handle them.) While this hardware design pattern is to\r
- // be discouraged, it is possible to handle it by doing device init and\r
- // tear down in these routines rather than in EvtDeviceD0Entry and\r
- // EvtDeviceD0Exit.\r
- //\r
- // In this sample these callbacks don't do anything.\r
- //\r
-\r
- pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled =\r
- HcaEvtDeviceD0EntryPostInterruptsEnabled;\r
- pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled =\r
- HcaEvtDeviceD0ExitPreInterruptsDisabled;\r
-\r
- //\r
- // This next group of five callbacks allow a driver to become involved in\r
- // starting and stopping operations within a driver as the driver moves\r
- // through various PnP/Power states. These functions are not necessary\r
- // if the Framework is managing all the device's queues and there is no\r
- // activity going on that isn't queue-based. This sample provides these\r
- // callbacks because it uses watchdog timer to monitor whether the device\r
- // is working or not and it needs to start and stop the timer when the\r
- // device is started or removed. It cannot start and stop the timers in the\r
- // D0Entry and D0Exit callbacks because if the device is surprise-removed,\r
- // D0Exit will not be called.\r
- //\r
- pnpPowerCallbacks.EvtDeviceSelfManagedIoInit =\r
- HcaEvtDeviceSelfManagedIoInit;\r
- pnpPowerCallbacks.EvtDeviceSelfManagedIoCleanup =\r
- HcaEvtDeviceSelfManagedIoCleanup;\r
- pnpPowerCallbacks.EvtDeviceSelfManagedIoSuspend =\r
- HcaEvtDeviceSelfManagedIoSuspend;\r
- pnpPowerCallbacks.EvtDeviceSelfManagedIoRestart =\r
- HcaEvtDeviceSelfManagedIoRestart;\r
-\r
- //\r
- // Register the PnP and power callbacks. Power policy related callbacks will\r
- // be registered later.\r
- //\r
- WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);\r
-\r
- //\r
- // Init the power policy callbacks\r
- //\r
- WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(&powerPolicyCallbacks);\r
-\r
- //\r
- // This group of three callbacks allows this sample driver to manage\r
- // arming the device for wake from the S0 state. Networking devices can\r
- // optionally be put into a low-power state when there is no networking\r
- // cable plugged into them. This sample implements this feature.\r
- //\r
- powerPolicyCallbacks.EvtDeviceArmWakeFromS0 = HcaEvtDeviceWakeArmS0;\r
- powerPolicyCallbacks.EvtDeviceDisarmWakeFromS0 = HcaEvtDeviceWakeDisarmS0;\r
- powerPolicyCallbacks.EvtDeviceWakeFromS0Triggered =\r
- HcaEvtDeviceWakeTriggeredS0;\r
-\r
- //\r
- // This group of three callbacks allows the device to be armed for wake\r
- // from Sx (S1, S2, S3 or S4.) Networking devices can optionally be put\r
- // into a state where a packet sent to them will cause the device's wake\r
- // signal to be triggered, which causes the machine to wake, moving back\r
- // into the S0 state.\r
- //\r
-\r
- powerPolicyCallbacks.EvtDeviceArmWakeFromSx = HcaEvtDeviceWakeArmSx;\r
- powerPolicyCallbacks.EvtDeviceDisarmWakeFromSx = HcaEvtDeviceWakeDisarmSx;\r
- powerPolicyCallbacks.EvtDeviceWakeFromSxTriggered =\r
- HcaEvtDeviceWakeTriggeredSx;\r
-\r
- WdfDeviceInitSetDeviceType( DeviceInit,\r
- FILE_DEVICE_INFINIBAND|FILE_DEVICE_SECURE_OPEN );\r
-\r
- WdfDeviceInitSetExclusive(DeviceInit, TRUE);\r
- //\r
- // Register the power policy callbacks.\r
- //\r
- WdfDeviceInitSetPowerPolicyEventCallbacks(DeviceInit,&powerPolicyCallbacks);\r
-\r
- // Since we are the function driver, we are now the power policy owner\r
- // for the device according to the default framework rule. We will register\r
- // our power policy callbacks after finding the wakeup capability of the\r
- // device.\r
-\r
-\r
- // Specify the context type and size for the device we are about to create.\r
-\r
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);\r
-\r
-\r
- // ContextCleanup will be called by the framework when it deletes the\r
- // device. So you can defer freeing any resources allocated to Cleanup\r
- // callback in the event AddDevice returns any error after the device is\r
- // created.\r
-\r
- fdoAttributes.EvtCleanupCallback = HcaEvtDeviceContextCleanup;\r
-\r
- status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);\r
-\r
- if ( !NT_SUCCESS(status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "WdfDeviceInitialize failed %!STATUS!\n", status);\r
- return status;\r
- }\r
-\r
- //\r
- // Device creation is complete.\r
- // Get the DeviceExtension and initialize it.\r
- //\r
- fdoData = FdoGetData(device);\r
- fdoData->WdfDevice = device;\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "PDO(0x%p) FDO(0x%p), Lower(0x%p) DevExt (0x%p)\n",\r
- WdfDeviceWdmGetPhysicalDevice (device),\r
- WdfDeviceWdmGetDeviceObject (device),\r
- WdfDeviceWdmGetAttachedDevice(device),\r
- fdoData);\r
-\r
- DriverContext = GetDriverContext(Driver);\r
-\r
- status = hca_add_device( DriverContext->DrvObj,\r
- WdfDeviceWdmGetPhysicalDevice(device),\r
- WdfDeviceWdmGetAttachedDevice(device) );\r
- //\r
- // Initialize the device extension and allocate all the software resources\r
- //\r
- status = HcaAllocSWResources(fdoData);\r
- if (!NT_SUCCESS (status)){\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "HcaAllocSWResources failed: %!STATUS!\n",\r
- status);\r
- return status;\r
- }\r
-\r
- //\r
- // If we own the power policy and if our device supports wait-wake then we\r
- // will set our power-policy and update S0-Idle policy.\r
- //\r
- if(IsPoMgmtSupported(fdoData) )\r
- {\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "Device has wait-wake capability\n");\r
- status = HcaSetPowerPolicy(fdoData);\r
- if (!NT_SUCCESS (status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "HcaSetPowerPolicy failed %!STATUS!\n", status);\r
- return status;\r
- }\r
- }\r
-\r
- //\r
- // Tell the Framework that this device will need an interface so that\r
- // application can interact with it.\r
- //\r
- status = WdfDeviceCreateDeviceInterface(\r
- device,\r
- (LPGUID) &GUID_DEVINTERFACE_RDMA_IO,\r
- NULL );\r
-\r
- if (!NT_SUCCESS (status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "WdfDeviceCreateDeviceInterface failed %!STATUS!\n",status);\r
- return status;\r
- }\r
-\r
- status = HcaWmiRegistration(device);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s \n",__FUNCTION__);\r
-\r
- return status;\r
-}\r
-\r
-VOID\r
-HcaEvtDeviceContextCleanup (\r
- WDFDEVICE Device\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceContextCleanup event callback cleans up anything done in\r
- EvtDeviceAdd, except those things that are automatically cleaned\r
- up by the Framework.\r
-\r
- In the case of this sample, everything is automatically handled. In a\r
- driver derived from this sample, it's quite likely that this function could\r
- be deleted.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
-Return Value:\r
-\r
- VOID\r
-\r
---*/\r
-{\r
- PFDO_DATA fdoData = NULL;\r
- NTSTATUS status;\r
-\r
- PAGED_CODE();\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDeviceContextCleanup\n");\r
-\r
- status = HcaFreeSWResources(fdoData);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDeviceContextCleanup\n");\r
-\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceStart event callback performs operations that are necessary\r
- to make the driver's device operational. The framework calls the driver's\r
- EvtDeviceStart callback when the PnP manager sends an IRP_MN_START_DEVICE\r
- request to the driver stack.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
- Resources - Handle to a collection of framework resource objects.\r
- This collection identifies the raw (bus-relative) hardware\r
- resources that have been assigned to the device.\r
-\r
- ResourcesTranslated - Handle to a collection of framework resource objects.\r
- This collection identifies the translated (system-physical)\r
- hardware resources that have been assigned to the device.\r
- The resources appear from the CPU's point of view.\r
- Use this list of resources to map I/O space and\r
- device-accessible memory into virtual address space\r
-\r
-Return Value:\r
-\r
- WDF status code\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDevicePrepareHardware (\r
- WDFDEVICE Device,\r
- WDFCMRESLIST Resources,\r
- WDFCMRESLIST ResourcesTranslated )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- PFDO_DATA fdoData = NULL;\r
-\r
- UNREFERENCED_PARAMETER(Resources);\r
- UNREFERENCED_PARAMETER(ResourcesTranslated);\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDevicePrepareHardware\n");\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
-#if 0\r
- status = NICMapHWResources(fdoData, ResourcesTranslated);\r
- if (!NT_SUCCESS (status)){\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "NICMapHWResources failed: %!STATUS!\n", status);\r
- return status;\r
- }\r
-#endif\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDevicePrepareHardware\n");\r
-\r
- return status;\r
-\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceReleaseHardware is called by the framework whenever the PnP manager\r
- is revoking ownership of our resources. This may be in response to either\r
- IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. The callback is made before\r
- passing down the IRP to the lower driver.\r
-\r
- In this callback, do anything necessary to free those resources.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
- ResourcesTranslated - Handle to a collection of framework resource objects.\r
- This collection identifies the translated (system-physical)\r
- hardware resources that have been assigned to the device.\r
- The resources appear from the CPU's point of view.\r
- Use this list of resources to map I/O space and\r
- device-accessible memory into virtual address space\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failures will be logged, but not acted on.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceReleaseHardware(\r
- IN WDFDEVICE Device,\r
- IN WDFCMRESLIST ResourcesTranslated )\r
-{\r
- PFDO_DATA fdoData = NULL;\r
-\r
- UNREFERENCED_PARAMETER(ResourcesTranslated);\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDeviceReleaseHardware\n");\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
-#if 0\r
- //\r
- // Unmap any I/O ports. Disconnecting from the interrupt will be done\r
- // automatically by the framework.\r
- //\r
- NICUnmapHWResources(fdoData);\r
-#endif\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDeviceReleaseHardware\n");\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceD0Entry event callback must perform any operations that are\r
- necessary before the specified device is used. It will be called every\r
- time the hardware needs to be (re-)initialized. This includes after\r
- IRP_MN_START_DEVICE, IRP_MN_CANCEL_STOP_DEVICE, IRP_MN_CANCEL_REMOVE_DEVICE,\r
- IRP_MN_SET_POWER-D0.\r
-\r
- This function is not marked pageable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
- This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
- driver can optionally make this function pageable if DO_POWER_PAGABLE\r
- is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
- at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
- not do anything that will cause a page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
- PreviousState - Device power state which the device was in most recently.\r
- If the device is being newly started, this will be\r
- PowerDeviceUnspecified.\r
-\r
-Return Value:\r
-\r
- NTSTATUS\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0Entry(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE PreviousState )\r
-{\r
- PFDO_DATA fdoData;\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,\r
- "-->HcaEvtDeviceD0Entry - coming from %s\n",\r
- DbgDevicePowerString(PreviousState));\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- ASSERT(PowerDeviceD0 != PreviousState);\r
-\r
- fdoData->DevicePowerState = PowerDeviceD0;\r
-\r
- if(IsPoMgmtSupported(fdoData)){\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER,\r
- "Entering fully on state\n");\r
-#ifdef XXX\r
- MPSetPowerD0 (fdoData);\r
-#endif\r
- }\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--HcaEvtDeviceD0Entry\n");\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0Exit(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE TargetState\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine undoes anything done in EvtDeviceD0Entry. It is called\r
- whenever the device leaves the D0 state, which happens when the device is\r
- stopped, when it is removed, and when it is powered off.\r
-\r
- The device is still in D0 when this callback is invoked, which means that\r
- the driver can still touch hardware in this routine.\r
-\r
- Note that interrupts have already been disabled by the time that this\r
- callback is invoked.\r
-\r
- EvtDeviceD0Exit event callback must perform any operations that are\r
- necessary before the specified device is moved out of the D0 state. If the\r
- driver needs to save hardware state before the device is powered down, then\r
- that should be done here.\r
-\r
- This function runs at PASSIVE_LEVEL, though it is generally not paged. A\r
- driver can optionally make this function pageable if DO_POWER_PAGABLE is set.\r
-\r
- Even if DO_POWER_PAGABLE isn't set, this function still runs at\r
- PASSIVE_LEVEL. In this case, though, the function absolutely must not do\r
- anything that will cause a page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
- TargetState - Device power state which the device will be put in once this\r
- callback is complete.\r
-\r
-Return Value:\r
-\r
- Success implies that the device can be used. Failure will result in the\r
- device stack being torn down.\r
-\r
---*/\r
-{\r
- PFDO_DATA fdoData;\r
-\r
- UNREFERENCED_PARAMETER(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER,\r
- "-->HcaEvtDeviceD0Exit - moving to %s\n",\r
- DbgDevicePowerString(TargetState));\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- fdoData->DevicePowerState = TargetState;\r
-\r
- switch (TargetState) {\r
- case WdfPowerDeviceD1:\r
- case WdfPowerDeviceD2:\r
- case WdfPowerDeviceD3:\r
-\r
- if(IsPoMgmtSupported(fdoData)){\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_POWER,\r
- "Entering a deeper sleep state\n");\r
-#ifdef XXX\r
- MPSetPowerLow (fdoData, TargetState);\r
-#endif\r
- }\r
- break;\r
-\r
- case WdfPowerDevicePrepareForHibernation:\r
-\r
- //\r
- // Fill in any code to save hardware state here. Do not put in any\r
- // code to shut the device off. If this device cannot support being\r
- // in the paging path (or being a parent or grandparent of a paging\r
- // path device) then this whole case can be deleted.\r
- //\r
- ASSERT(FALSE); // This driver shouldn't get this.\r
- break;\r
-\r
- case WdfPowerDeviceD3Final:\r
- //\r
- // Reset and put the device into a known initial state we're shutting\r
- // down for the last time.\r
- //\r
-#if 0\r
- NICShutdown(fdoData);\r
-#endif\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
-\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_POWER, "<--HcaEvtDeviceD0Exit\n");\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- HcaEvtDeviceSelfManagedIoInit is called by the Framework when the device\r
- enters the D0 state. Its job is to start any I/O-related actions that the\r
- Framework isn't managing. This might include releasing queues that are not\r
- power-managed, that is, the Framework is not automatically holding and\r
- releasing them across PnP/Power transitions. (The default behavior for\r
- WDFQUEUE is auto-managed, so most queues don't need to be dealt with here.)\r
- This might also include setting up non-queue-based actions.\r
-\r
- If you allow the Framework to manage most or all of your queues, then when\r
- you build a driver from this sample, you can probably delete this function.\r
-\r
- In this driver, the SelfManagedIo callbacks are used to implement a\r
- watchdog timer.\r
-\r
- This function is not marked pagable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failures will result in the device stack being torn down.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceSelfManagedIoInit( IN WDFDEVICE Device )\r
-{\r
- PFDO_DATA fdoData = NULL;\r
- NTSTATUS status=STATUS_SUCCESS;\r
-// WDF_TIMER_CONFIG wdfTimerConfig;\r
-// WDF_OBJECT_ATTRIBUTES timerAttributes;\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
-#if 0\r
- // To minimize init-time, create a timer DPC to do link detection.\r
- // This DPC will also be used to check for hardware hang.\r
- //\r
- WDF_TIMER_CONFIG_INIT(&wdfTimerConfig, NICWatchDogEvtTimerFunc);\r
-\r
- WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);\r
- timerAttributes.ParentObject = fdoData->WdfDevice;\r
-\r
- status = WdfTimerCreate(\r
- &wdfTimerConfig,\r
- &timerAttributes,\r
- &fdoData->WatchDogTimer\r
- );\r
-\r
- if(!NT_SUCCESS(status) ) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "Error: WdfTimerCreate create failed 0x%x\n", status);\r
- return status;\r
- }\r
-\r
- NICStartWatchDogTimer(fdoData);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- %s() ret %x\n", __FUNCTION__, status);\r
-\r
- return status;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceSelfManagedIoSuspend is called by the Framework before the device\r
- leaves the D0 state. Its job is to stop any I/O-related actions that the\r
- Framework isn't managing, and which cannot be handled when the device\r
- hardware isn't available. In general, this means reversing anything that\r
- was done in EvtDeviceSelfManagedIoStart.\r
-\r
- If you allow the Framework to manage most or all of your queues, then when\r
- you build a driver from this sample, you can probably delete this function.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failures will result in the device stack being torn down.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceSelfManagedIoSuspend( IN WDFDEVICE Device )\r
-{\r
- PFDO_DATA fdoData = NULL;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDeviceSelfManagedIoSuspend\n");\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
-#if 0\r
- //\r
- // Stop the watchdog timer and wait for DPC to run to completion if\r
- // it's already fired.\r
- //\r
- WdfTimerStop(fdoData->WatchDogTimer, TRUE);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDeviceSelfManagedIoSuspend\n");\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-NTSTATUS\r
-HcaEvtDeviceSelfManagedIoRestart(\r
- IN WDFDEVICE Device\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceSelfManagedIoRestart is called by the Framework before the device\r
- is restarted for one of the following reasons:\r
- a) the PnP resources were rebalanced (framework received\r
- query-stop and stop IRPS )\r
- b) the device resumed from a low power state to D0.\r
-\r
- This function is not marked pagable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failure will cause the device stack to be torn down.\r
-\r
---*/\r
-{\r
- PFDO_DATA fdoData;\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDeviceSelfManagedIoRestart\n");\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- //\r
- // Restart the watchdog timer.\r
- //\r
-#if 0\r
- NICStartWatchDogTimer(fdoData);\r
-#endif\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDeviceSelfManagedIoRestart\n");\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceSelfManagedIoCleanup is called by the Framework when the device is\r
- being torn down, either in response to the WDM IRP_MN_REMOVE_DEVICE\r
- It will be called only once. Its job is to stop all outstanding I/O in the driver\r
- that the Framework is not managing.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a framework device object.\r
-\r
-Return Value:\r
-\r
- None\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDeviceSelfManagedIoCleanup( IN WDFDEVICE Device )\r
-{\r
- PFDO_DATA fdoData = NULL;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "--> HcaEvtDeviceSelfManagedIoCleanup\n");\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
-#if 0\r
- if(fdoData->WatchDogTimer) {\r
- WdfObjectDelete(fdoData->WatchDogTimer);\r
- }\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- HcaEvtDeviceSelfManagedIoCleanup\n");\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This event is called when the framework receives IRP_MJ_DEVICE_CONTROL\r
- requests from the system.\r
-\r
-Arguments:\r
-\r
- Queue - Handle to the framework queue object that is associated\r
- with the I/O request.\r
- Request - Handle to a framework request object.\r
-\r
- OutputBufferLength - length of the request's output buffer,\r
- if an output buffer is available.\r
- InputBufferLength - length of the request's input buffer,\r
- if an input buffer is available.\r
-\r
- IoControlCode - the driver-defined or system-defined I/O control code\r
- (IOCTL) that is associated with the request.\r
-Return Value:\r
-\r
- VOID\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtIoDeviceControl(\r
- IN WDFQUEUE Queue,\r
- IN WDFREQUEST Request,\r
- IN size_t OutputBufferLength,\r
- IN size_t InputBufferLength,\r
- IN ULONG IoControlCode )\r
-{\r
- //NTSTATUS status= STATUS_SUCCESS;\r
- PFDO_DATA fdoData = NULL;\r
- WDFDEVICE hDevice;\r
- WDF_REQUEST_PARAMETERS params;\r
-\r
- UNREFERENCED_PARAMETER(OutputBufferLength);\r
- UNREFERENCED_PARAMETER(InputBufferLength);\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTLS,\r
- "HcaEvtIoDeviceControl called %p\n", Request);\r
-\r
- hDevice = WdfIoQueueGetDevice(Queue);\r
- fdoData = FdoGetData(hDevice);\r
-\r
- WDF_REQUEST_PARAMETERS_INIT(¶ms);\r
-\r
- WdfRequestGetParameters(\r
- Request,\r
- ¶ms\r
- );\r
-\r
- switch (IoControlCode)\r
- {\r
-#if 0\r
- case IOCTL_NDISPROT_QUERY_OID_VALUE:\r
-\r
- ASSERT((IoControlCode & 0x3) == METHOD_BUFFERED);\r
-\r
- NICHandleQueryOidRequest(\r
- Queue,\r
- Request,\r
- ¶ms\r
- );\r
- break;\r
-\r
- case IOCTL_NDISPROT_SET_OID_VALUE:\r
-\r
- ASSERT((IoControlCode & 0x3) == METHOD_BUFFERED);\r
-\r
- NICHandleSetOidRequest(\r
- Queue,\r
- Request,\r
- ¶ms\r
- );\r
-\r
- break;\r
-\r
- case IOCTL_NDISPROT_INDICATE_STATUS:\r
-\r
- status = WdfRequestForwardToIoQueue(Request,\r
- fdoData->PendingIoctlQueue);\r
- if(!NT_SUCCESS(status)){\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTLS,\r
- "WdfRequestForwardToIoQueue failed 0x%x\n", status);\r
- WdfRequestComplete(Request, status);\r
- break;\r
- }\r
-\r
- break;\r
-#endif\r
- default:\r
- ASSERTMSG(FALSE, "Invalid IOCTL request\n");\r
- WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);\r
- break;\r
- }\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeArmS0 is called when the Framework arms the device for\r
- wake in the S0 state. If there is any device-specific initialization\r
- that needs to be done to arm internal wake signals, or to route internal\r
- interrupt signals to the wake logic, it should be done here. The device\r
- will be moved out of the D0 state soon after this callback is invoked.\r
-\r
- In this sample, wake from S0 involves waking on packet arrival, as does\r
- wake from Sx. A more common NIC implementation might wake on cable\r
- insertion.\r
-\r
- This function is pageable and it will run at PASSIVE_LEVEL.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failure will result in the device remaining in the D0 state.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceWakeArmS0( IN WDFDEVICE Device )\r
-{\r
- NTSTATUS status=STATUS_SUCCESS;\r
- PFDO_DATA fdoData;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- //\r
- // Add pattern before sending wait-wake\r
- //\r
-#if 0\r
- status = NICConfigureForWakeUp(fdoData, TRUE);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- %s() %x\n", __FUNCTION__, status);\r
-\r
- return status;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeArmSx is called when the Framework arms the device for\r
- wake from the S1, S2, S3 or S4 states. If there is any device-specific\r
- initialization that needs to be done to arm internal wake signals, or to\r
- route internal interrupt signals to the wake logic, it should be done here.\r
- The device will be moved out of the D0 state soon after this callback is\r
- invoked.\r
-\r
- In this sample, wake from Sx involves arming for wake on packet arrival.\r
- Cable insertion should not be enabled, as nobody would want their machine\r
- to wake up simply because they plugged the cable in.\r
-\r
- This function runs at PASSIVE_LEVEL. Whether it is pageable or not depends\r
- on whether the device has set DO_POWER_PAGABLE.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- NTSTATUS - Failure will result in the device not being armed for wake\r
- while the system is in Sx.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceWakeArmSx( IN WDFDEVICE Device )\r
-{\r
- NTSTATUS status=STATUS_SUCCESS;\r
- PFDO_DATA fdoData;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
- //\r
- // Add pattern before sending wait-wake\r
- //\r
-#if 0\r
- status = NICConfigureForWakeUp(fdoData, TRUE);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- %s() ret %x\n", __FUNCTION__, status);\r
-\r
- return status;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeDisarmS0 reverses anything done in EvtDeviceWakeArmS0.\r
-\r
- This function is pageable and it will run at PASSIVE_LEVEL.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- VOID.\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDeviceWakeDisarmS0( IN WDFDEVICE Device )\r
-{\r
- NTSTATUS status=STATUS_SUCCESS;\r
- PFDO_DATA fdoData;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-#if 0\r
- status = NICConfigureForWakeUp(fdoData, FALSE);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- %s %x\n", __FUNCTION__, status);\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeDisarmSx reverses anything done in EvtDeviceWakeArmSx.\r
-\r
- This function is not marked pageable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
- This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
- driver can optionally make this function pageable if DO_POWER_PAGABLE\r
- is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
- at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
- not do anything that will cause a page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- VOID\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDeviceWakeDisarmSx( IN WDFDEVICE Device )\r
-{\r
- NTSTATUS status=STATUS_SUCCESS;\r
- PFDO_DATA fdoData;\r
-\r
- UNREFERENCED_PARAMETER(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-#if 0\r
- status = NICConfigureForWakeUp(fdoData, FALSE);\r
-#endif\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,\r
- "<-- %s %x\n", __FUNCTION__, status);\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeTriggeredS0 will be called whenever the device triggers its\r
- wake signal after being armed for wake from S0.\r
-\r
- This function is pageable and runs at PASSIVE_LEVEL.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- VOID\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDeviceWakeTriggeredS0( IN WDFDEVICE Device )\r
-{\r
- UNREFERENCED_PARAMETER(Device);\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s\n", __FUNCTION__);\r
-\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s\n", __FUNCTION__);\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- EvtDeviceWakeTriggeredSx will be called whenever the device triggers its\r
- wake signal after being armed for wake from Sx.\r
-\r
- This function is not marked pageable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
- This function runs at PASSIVE_LEVEL, even though it is not paged. A\r
- driver can optionally make this function pageable if DO_POWER_PAGABLE\r
- is set. Even if DO_POWER_PAGABLE isn't set, this function still runs\r
- at PASSIVE_LEVEL. In this case, though, the function absolutely must\r
- not do anything that will cause a page fault.\r
-\r
-Arguments:\r
-\r
- Device - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- VOID\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDeviceWakeTriggeredSx( IN WDFDEVICE Device )\r
-{\r
- UNREFERENCED_PARAMETER(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s", __FUNCTION__);\r
-\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s", __FUNCTION__);\r
-\r
- return;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This routine is used to queue workitems so that the callback\r
- functions can be executed at PASSIVE_LEVEL in the conext of\r
- a system thread.\r
-\r
-Arguments:\r
-\r
- FdoData - pointer to a device extenion.\r
-\r
- CallbackFunction - Function to invoke when at PASSIVE_LEVEL.\r
-\r
- Context1 & 2 - Meaning of the context values depends on the\r
- callback function.\r
-\r
-Return Value:\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaQueuePassiveLevelCallback(\r
- IN PFDO_DATA FdoData,\r
- IN PFN_WDF_WORKITEM CallbackFunction,\r
- IN PVOID Context1,\r
- IN PVOID Context2 )\r
-{\r
- NTSTATUS status = STATUS_SUCCESS;\r
- PWORKER_ITEM_CONTEXT context;\r
- WDF_OBJECT_ATTRIBUTES attributes;\r
- WDF_WORKITEM_CONFIG workitemConfig;\r
- WDFWORKITEM hWorkItem;\r
-\r
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, WORKER_ITEM_CONTEXT);\r
-\r
- attributes.ParentObject = FdoData->WdfDevice;\r
-\r
- WDF_WORKITEM_CONFIG_INIT(&workitemConfig, CallbackFunction);\r
-\r
- status = WdfWorkItemCreate( &workitemConfig,\r
- &attributes,\r
- &hWorkItem);\r
-\r
- if (!NT_SUCCESS(status)) {\r
- return status;\r
- }\r
-\r
- context = GetWorkItemContext(hWorkItem);\r
-\r
- context->FdoData = FdoData;\r
- context->Argument1 = Context1;\r
- context->Argument2 = Context2;\r
-\r
- //\r
- // Execute this work item.\r
- //\r
- WdfWorkItemEnqueue(hWorkItem);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Can be used to read any REG_DWORD registry value stored\r
- under Device Parameter.\r
-\r
-Arguments:\r
-\r
- FdoData - pointer to the device extension\r
- Name - Name of the registry value\r
- Value -\r
-\r
-\r
-Return Value:\r
-\r
- TRUE if successful\r
- FALSE if not present/error in reading registry\r
-\r
---*/\r
-\r
-BOOLEAN\r
-HcaReadRegistryValue(\r
- __in PFDO_DATA FdoData,\r
- __in PWCHAR Name,\r
- __out PULONG Value )\r
-{\r
- WDFKEY hKey = NULL;\r
- NTSTATUS status;\r
- BOOLEAN retValue = FALSE;\r
- UNICODE_STRING valueName;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "--> %s()\n", __FUNCTION__);\r
-\r
- *Value = 0;\r
-\r
- status = WdfDeviceOpenRegistryKey(FdoData->WdfDevice,\r
- PLUGPLAY_REGKEY_DEVICE,\r
- STANDARD_RIGHTS_ALL,\r
- WDF_NO_OBJECT_ATTRIBUTES,\r
- &hKey);\r
-\r
- if (NT_SUCCESS (status)) {\r
-\r
- RtlInitUnicodeString(&valueName,Name);\r
-\r
- status = WdfRegistryQueryULong( hKey,\r
- &valueName,\r
- Value );\r
-\r
- if (NT_SUCCESS (status)) {\r
- retValue = TRUE;\r
- }\r
-\r
- WdfRegistryClose(hKey);\r
- }\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,\r
- "<-- %s() %ws %d \n", __FUNCTION__, Name, *Value);\r
-\r
- return retValue;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Can be used to write any REG_DWORD registry value stored\r
- under Device Parameter.\r
-\r
-Arguments:\r
-\r
-\r
-Return Value:\r
-\r
- TRUE - if write is successful\r
- FALSE - otherwise\r
-\r
---*/\r
-\r
-BOOLEAN\r
-HcaWriteRegistryValue(\r
- __in PFDO_DATA FdoData,\r
- __in PWCHAR Name,\r
- __in ULONG Value )\r
-{\r
- WDFKEY hKey = NULL;\r
- NTSTATUS status;\r
- BOOLEAN retValue = FALSE;\r
- UNICODE_STRING valueName;\r
-\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT, "--> %s()\n", __FUNCTION__);\r
-\r
- //\r
- // write the value out to the registry\r
- //\r
- status = WdfDeviceOpenRegistryKey(FdoData->WdfDevice,\r
- PLUGPLAY_REGKEY_DEVICE,\r
- STANDARD_RIGHTS_ALL,\r
- WDF_NO_OBJECT_ATTRIBUTES,\r
- &hKey);\r
-\r
- if (NT_SUCCESS (status)) {\r
-\r
- RtlInitUnicodeString(&valueName,Name);\r
-\r
- status = WdfRegistryAssignULong (hKey,\r
- &valueName,\r
- Value );\r
-\r
- if (NT_SUCCESS (status)) {\r
- retValue = TRUE;\r
- }\r
-\r
- WdfRegistryClose(hKey);\r
- }\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_INIT,\r
- "<-- ret %s() %s\n", __FUNCTION__, (retValue ? "True":"False"));\r
-\r
- return retValue;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Can be used to read any REG_DWORD registry value stored\r
- under Device Parameter.\r
-\r
-Arguments:\r
-\r
- FdoData - pointer to the device extension\r
- Name - Name of the registry value\r
- Value -\r
-\r
-\r
-Return Value:\r
-\r
- TRUE if successful\r
- FALSE if not present/error in reading registry\r
-\r
---*/\r
-\r
-BOOLEAN\r
-HcaReadFdoRegistryKeyValue(\r
- __in PWDFDEVICE_INIT DeviceInit,\r
- __in PWCHAR Name,\r
- __out PULONG Value )\r
-{\r
- WDFKEY hKey = NULL;\r
- NTSTATUS status;\r
- BOOLEAN retValue = FALSE;\r
- UNICODE_STRING valueName;\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- *Value = 0;\r
-\r
- status = WdfFdoInitOpenRegistryKey(DeviceInit,\r
- PLUGPLAY_REGKEY_DEVICE,\r
- STANDARD_RIGHTS_ALL,\r
- WDF_NO_OBJECT_ATTRIBUTES,\r
- &hKey);\r
-\r
- if (NT_SUCCESS (status)) {\r
-\r
- RtlInitUnicodeString(&valueName,Name);\r
-\r
- status = WdfRegistryQueryULong (hKey,\r
- &valueName,\r
- Value);\r
-\r
- if (NT_SUCCESS (status)) {\r
- retValue = TRUE;\r
- }\r
-\r
- WdfRegistryClose(hKey);\r
- }\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
- "<-- %s() %ws %d \n", __FUNCTION__, Name, *Value);\r
-\r
- return retValue;\r
-}\r
-\r
-\r
-/*++\r
-Routine Description:\r
-\r
- Free all the resources allocated in DriverEntry.\r
-\r
-Arguments:\r
-\r
- Driver - handle to a WDF Driver object.\r
-\r
-Return Value:\r
-\r
- VOID.\r
-\r
---*/\r
-\r
-VOID\r
-HcaEvtDriverContextCleanup( IN WDFDRIVER Driver )\r
-{\r
- UNREFERENCED_PARAMETER( Driver );\r
-\r
- PAGED_CODE ();\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "--> %s()\n",__FUNCTION__);\r
-\r
- // Stop WPP Tracing\r
- //\r
- WPP_CLEANUP( WdfDriverWdmGetDriverObject( Driver ) );\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, "<-- %s()\n",__FUNCTION__);\r
-}\r
-\r
-\r
-NTSTATUS\r
-HcaSetPowerPolicy(\r
- IN PFDO_DATA FdoData\r
- )\r
-{\r
- WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;\r
- WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings;\r
- NTSTATUS status = STATUS_SUCCESS;\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- PAGED_CODE();\r
-\r
- //\r
- // Init the idle policy structure.\r
- //\r
- WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCanWakeFromS0);\r
- idleSettings.IdleTimeout = 10000; // 10-sec\r
-\r
- status = WdfDeviceAssignS0IdleSettings(FdoData->WdfDevice, &idleSettings);\r
- if ( !NT_SUCCESS(status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "WdfDeviceSetPowerPolicyS0IdlePolicy failed %x\n", status);\r
- return status;\r
- }\r
-\r
- //\r
- // Init wait-wake policy structure.\r
- //\r
- WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);\r
-\r
- status = WdfDeviceAssignSxWakeSettings(FdoData->WdfDevice, &wakeSettings);\r
- if (!NT_SUCCESS(status)) {\r
- TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP,\r
- "WdfDeviceAssignSxWakeSettings failed %x\n", status);\r
- return status;\r
- }\r
-\r
- TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
-\r
- return status;\r
-}\r
-\r
-\r
-/*++\r
-\r
-Updated Routine Description:\r
- DbgDevicePowerString does not change in this stage of the function driver.\r
-\r
---*/\r
-\r
-PCHAR\r
-DbgDevicePowerString( IN WDF_POWER_DEVICE_STATE Type )\r
-{\r
- switch (Type)\r
- {\r
- case WdfPowerDeviceInvalid:\r
- return "WdfPowerDeviceInvalid";\r
- case WdfPowerDeviceD0:\r
- return "WdfPowerDeviceD0";\r
- case PowerDeviceD1:\r
- return "WdfPowerDeviceD1";\r
- case WdfPowerDeviceD2:\r
- return "WdfPowerDeviceD2";\r
- case WdfPowerDeviceD3:\r
- return "WdfPowerDeviceD3";\r
- case WdfPowerDeviceD3Final:\r
- return "WdfPowerDeviceD3Final";\r
- case WdfPowerDevicePrepareForHibernation:\r
- return "WdfPowerDevicePrepareForHibernation";\r
- case WdfPowerDeviceMaximum:\r
- return "PowerDeviceMaximum";\r
- default:\r
- return "UnKnown Device Power State";\r
- }\r
-}\r
-\r
-\r
-#if !defined(EVENT_TRACING)\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Debug print for the sample driver.\r
-\r
-Arguments:\r
-\r
- TraceEventsLevel - print level between 0 and 3, with 3 the most verbose\r
-\r
-Return Value:\r
-\r
- None.\r
-\r
- --*/\r
-\r
-VOID\r
-TraceEvents (\r
- IN ULONG TraceEventsLevel,\r
- IN ULONG TraceEventsFlag,\r
- IN PCCHAR DebugMessage,\r
- ... )\r
- {\r
-#if 1 // always for starters... DBG\r
-\r
-#define TEMP_BUFFER_SIZE 512\r
- va_list list;\r
- CHAR debugMessageBuffer[TEMP_BUFFER_SIZE];\r
- NTSTATUS status;\r
-\r
- va_start(list, DebugMessage);\r
-\r
- if (DebugMessage) {\r
-\r
- //\r
- // Using new safe string functions instead of _vsnprintf.\r
- // This function takes care of NULL terminating if the message\r
- // is longer than the buffer.\r
- //\r
- status = RtlStringCbVPrintfA( debugMessageBuffer,\r
- sizeof(debugMessageBuffer),\r
- DebugMessage,\r
- list );\r
- if(!NT_SUCCESS(status)) {\r
-\r
- DbgPrint (_DRIVER_NAME_": RtlStringCbVPrintfA failed %x\n",\r
- status);\r
- return;\r
- }\r
- if (TraceEventsLevel <= TRACE_LEVEL_INFORMATION ||\r
- (TraceEventsLevel <= g_mthca_dbg_level &&\r
- ((TraceEventsFlag & g_mthca_dbg_flags) == TraceEventsFlag))) {\r
- DbgPrint(debugMessageBuffer);\r
- }\r
- }\r
- va_end(list);\r
-\r
- return;\r
-#else\r
- UNREFERENCED_PARAMETER(TraceEventsLevel);\r
- UNREFERENCED_PARAMETER(TraceEventsFlag);\r
- UNREFERENCED_PARAMETER(DebugMessage);\r
-#endif\r
-}\r
-\r
-#endif\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This event is called so that driver can do PASSIVE_LEVEL work before\r
- the interrupt is disconnected and disabled.\r
-\r
-Arguments:\r
-\r
- Interrupt - Handle to a Framework interrupt object.\r
-\r
- AssociatedDevice - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- STATUS_SUCCESS - indicates success.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0ExitPreInterruptsDisabled(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE TargetState )\r
-{\r
- PFDO_DATA fdoData;\r
-\r
- UNREFERENCED_PARAMETER(TargetState);\r
-\r
- PAGED_CODE();\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
-\r
- return STATUS_SUCCESS;\r
-\r
-}\r
-\r
-\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This event is called so that driver can do PASSIVE_LEVEL work after\r
- the interrupt is connected and enabled. Here we start the watchdog timer.\r
- Watch dog timer is used to do the initial link detection during\r
- start and then used to make sure the device is not stuck for any reason.\r
-\r
- This function is not marked pageable because this function is in the\r
- device power up path. When a function is marked pagable and the code\r
- section is paged out, it will generate a page fault which could impact\r
- the fast resume behavior because the client driver will have to wait\r
- until the system drivers can service this page fault.\r
-\r
-Arguments:\r
-\r
- Interrupt - Handle to a Framework interrupt object.\r
-\r
- AssociatedDevice - Handle to a Framework device object.\r
-\r
-Return Value:\r
-\r
- STATUS_SUCCESS - indicates success.\r
-\r
---*/\r
-\r
-NTSTATUS\r
-HcaEvtDeviceD0EntryPostInterruptsEnabled(\r
- IN WDFDEVICE Device,\r
- IN WDF_POWER_DEVICE_STATE PreviousState )\r
-{\r
- PFDO_DATA fdoData;\r
-\r
- UNREFERENCED_PARAMETER( PreviousState );\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "--> %s()\n", __FUNCTION__);\r
-\r
- fdoData = FdoGetData(Device);\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
-\r
- return STATUS_SUCCESS;\r
-\r
-}\r
-\r
-NTSTATUS\r
-HcaAllocSWResources(PFDO_DATA fdoData)\r
-{\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
- "--> %s() fdoData %p\n", __FUNCTION__, fdoData);\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
-NTSTATUS\r
-HcaFreeSWResources(PFDO_DATA fdoData)\r
-{\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP,\r
- "--> %s() fdoData %p\n", __FUNCTION__, fdoData);\r
-\r
- TraceEvents(TRACE_LEVEL_VERBOSE, DBG_PNP, "<-- %s()\n", __FUNCTION__);\r
-\r
- return STATUS_SUCCESS;\r
-}\r
-\r
+++ /dev/null
-/*\r
- * Copyright (c) 2008 Intel Corporation. All rights reserved.\r
- * Copyright (c) 2005 SilverStorm Technologies. 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
-#ifndef _PCIDRV_H_\r
-#define _PCIDRV_H_\r
-\r
-//\r
-// PciDrv/KMDF Function prototypes\r
-//\r
-\r
-EVT_WDF_DRIVER_DEVICE_ADD HcaEvtDeviceAdd;\r
-\r
-EVT_WDF_OBJECT_CONTEXT_CLEANUP HcaEvtDriverContextCleanup;\r
-EVT_WDF_DEVICE_CONTEXT_CLEANUP HcaEvtDeviceContextCleanup;\r
-\r
-EVT_WDF_DEVICE_D0_ENTRY HcaEvtDeviceD0Entry;\r
-EVT_WDF_DEVICE_D0_EXIT HcaEvtDeviceD0Exit;\r
-EVT_WDF_DEVICE_PREPARE_HARDWARE HcaEvtDevicePrepareHardware;\r
-EVT_WDF_DEVICE_RELEASE_HARDWARE HcaEvtDeviceReleaseHardware;\r
-\r
-EVT_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP HcaEvtDeviceSelfManagedIoCleanup;\r
-EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT HcaEvtDeviceSelfManagedIoInit;\r
-EVT_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND HcaEvtDeviceSelfManagedIoSuspend;\r
-EVT_WDF_DEVICE_SELF_MANAGED_IO_RESTART HcaEvtDeviceSelfManagedIoRestart;\r
-\r
-EVT_WDF_DEVICE_SURPRISE_REMOVAL HcaEvtDeviceSurpriseRemoval;\r
-\r
-EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 HcaEvtDeviceWakeArmS0;\r
-EVT_WDF_DEVICE_ARM_WAKE_FROM_SX HcaEvtDeviceWakeArmSx;\r
-EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 HcaEvtDeviceWakeDisarmS0;\r
-EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX HcaEvtDeviceWakeDisarmSx;\r
-EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED HcaEvtDeviceWakeTriggeredS0;\r
-EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED HcaEvtDeviceWakeTriggeredSx;\r
-EVT_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED HcaEvtDeviceD0EntryPostInterruptsEnabled;\r
-EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED HcaEvtDeviceD0ExitPreInterruptsDisabled;\r
-\r
-EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HcaEvtIoDeviceControl;\r
-\r
-NTSTATUS\r
-HcaReturnResources (\r
- IN OUT PFDO_DATA FdoData\r
- );\r
-\r
-NTSTATUS\r
-HcaSetPowerPolicy(\r
- IN PFDO_DATA FdoData\r
- );\r
-\r
-NTSTATUS\r
-HcaQueuePassiveLevelCallback(\r
- IN PFDO_DATA FdoData,\r
- IN PFN_WDF_WORKITEM CallbackFunction,\r
- IN PVOID Context1,\r
- IN PVOID Context2\r
- );\r
-\r
-BOOLEAN\r
-HcaReadRegistryValue(\r
- __in PFDO_DATA FdoData,\r
- __in PWCHAR Name,\r
- __out PULONG Value\r
- );\r
-\r
-BOOLEAN\r
-HcaWriteRegistryValue(\r
- __in PFDO_DATA FdoData,\r
- __in PWCHAR Name,\r
- __in ULONG Value\r
- );\r
-\r
-\r
-NTSTATUS\r
-HcaWmiRegistration(\r
- WDFDEVICE hDevice\r
-);\r
-\r
-PCHAR\r
-DbgDevicePowerString(\r
- IN WDF_POWER_DEVICE_STATE Type\r
- );\r
-\r
-\r
-BOOLEAN\r
-HcaReadFdoRegistryKeyValue(\r
- __in PWDFDEVICE_INIT DeviceInit,\r
- __in PWCHAR Name,\r
- __out PULONG Value\r
- );\r
-\r
-\r
-#endif // _PCIDRV_H_\r