Fab Tillier
2012-06-19 02:43:48 UTC
WinVerbs and WinMad have logic to remove the device from under users when it goes away. However, that logic is never allowed to do its magic because the HCA driver fails the query remove IRP if an app is still active. This patch moves the check to the pre-interrupt disable WDF callback (EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED), and fails removal if apps are still active. This allows other drivers to clean up nicely.
Signed-off-by: Fab Tillier <***@microsoft.com>
Index: hw/mlx4/kernel/hca/drv.c
===================================================================
--- hw/mlx4/kernel/hca/drv.c (revision 3414)
+++ hw/mlx4/kernel/hca/drv.c (working copy)
@@ -522,16 +503,18 @@
return STATUS_SUCCESS;
}
-#ifdef NTDDI_WIN8
-EVT_WDF_DEVICE_QUERY_REMOVE EvtDeviceQueryRemove;
-#endif
+
+EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED EvtDeviceD0ExitPreInterruptsDisabled;
+
NTSTATUS
-EvtDeviceQueryRemove(
- IN WDFDEVICE Device
+EvtDeviceD0ExitPreInterruptsDisabled(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE TargetState
)
{
PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);
HCA_ENTER( HCA_DBG_PNP );
+ UNREFERENCED_PARAMETER(TargetState);
if (atomic_read(&p_fdo->usecnt)) {
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP,
("MLX4_HCA: Can't get unloaded. %d applications are still in work\n", p_fdo->usecnt));
@@ -541,6 +524,7 @@
return STATUS_SUCCESS;
}
+
char *GetNotificationTypeString(WDF_SPECIAL_FILE_TYPE NotificationType)
{
switch(NotificationType) {
@@ -618,8 +602,8 @@
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&Callbacks);
Callbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
Callbacks.EvtDeviceReleaseHardware = EvtDeviceReleaseHardware;
- Callbacks.EvtDeviceQueryRemove = EvtDeviceQueryRemove;
Callbacks.EvtDeviceD0Entry = EvtDeviceD0Entry;
+ Callbacks.EvtDeviceD0ExitPreInterruptsDisabled = EvtDeviceD0ExitPreInterruptsDisabled;
Callbacks.EvtDeviceD0Exit = EvtDeviceD0Exit;
Callbacks.EvtDeviceUsageNotification = EvtDeviceUsageNotification;
Signed-off-by: Fab Tillier <***@microsoft.com>
Index: hw/mlx4/kernel/hca/drv.c
===================================================================
--- hw/mlx4/kernel/hca/drv.c (revision 3414)
+++ hw/mlx4/kernel/hca/drv.c (working copy)
@@ -522,16 +503,18 @@
return STATUS_SUCCESS;
}
-#ifdef NTDDI_WIN8
-EVT_WDF_DEVICE_QUERY_REMOVE EvtDeviceQueryRemove;
-#endif
+
+EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED EvtDeviceD0ExitPreInterruptsDisabled;
+
NTSTATUS
-EvtDeviceQueryRemove(
- IN WDFDEVICE Device
+EvtDeviceD0ExitPreInterruptsDisabled(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE TargetState
)
{
PFDO_DEVICE_DATA p_fdo = FdoGetData(Device);
HCA_ENTER( HCA_DBG_PNP );
+ UNREFERENCED_PARAMETER(TargetState);
if (atomic_read(&p_fdo->usecnt)) {
HCA_PRINT(TRACE_LEVEL_ERROR, HCA_DBG_PNP,
("MLX4_HCA: Can't get unloaded. %d applications are still in work\n", p_fdo->usecnt));
@@ -541,6 +524,7 @@
return STATUS_SUCCESS;
}
+
char *GetNotificationTypeString(WDF_SPECIAL_FILE_TYPE NotificationType)
{
switch(NotificationType) {
@@ -618,8 +602,8 @@
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&Callbacks);
Callbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
Callbacks.EvtDeviceReleaseHardware = EvtDeviceReleaseHardware;
- Callbacks.EvtDeviceQueryRemove = EvtDeviceQueryRemove;
Callbacks.EvtDeviceD0Entry = EvtDeviceD0Entry;
+ Callbacks.EvtDeviceD0ExitPreInterruptsDisabled = EvtDeviceD0ExitPreInterruptsDisabled;
Callbacks.EvtDeviceD0Exit = EvtDeviceD0Exit;
Callbacks.EvtDeviceUsageNotification = EvtDeviceUsageNotification;