Multiport Ethernet Device

I know. I used an accessor function and this was still returning NULL. The context was created in the bus driver (dpc_get_data), and the child device wants to access it. Since the bus driver created the object…I’m assuming thats why I can’t retrieve it in the child device.

Should it be working this way?

dpc_data = dpc_get_data(dpc);

> dpc_data = WdfObjectContextGetObject(dpc);

this function takes an object *CONTEXT* (ie your DPC_DATA) and gives you the object the context is tied to (the WDFDPC in this case). You already have the object (WDFDPC), you probably want to get the associated context (DPC_DATA). You should call the accessor function specified in WDF_DECLARE_CONTEXT_TYPE_WITH_NAME to get the context pointer

WdfSpinLockAcquire(fdo_data->device_spin_lock);

You cannot acquire a spinlock in this way in an ISR. A normal spinlock can be acquired at an IRQL <= DISPATCH_LEVEL. Your ISR runs at DIRQL. If you need to synchronize with your ISR from a DPC or other function that runs at IRQL < DIRQL. That means you need to acquire the interrupt spinlock (WdfInterruptAcquireLock, WdfInterruptReleaseLock) in the DPC/other function and not in the ISR (which automatically holds the lock when calling your ISR, thus if you acquire, you will deadlock)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, October 8, 2012 8:57 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

Here is my code…

---- BUS CODE ----

BOOLEAN bus_interrupt_isr(
IN WDFINTERRUPT Interrupt,
IN ULONG MessageID
)
{
PFDO_DEVICE_DATA fdo_data = NULL;
ULONG port_number;
ULONG imask;
ULONG ievent;
PVOID bar_address;
BOOLEAN enqueue_state;

UNREFERENCED_PARAMETER(MessageID);

fdo_data = fdo_get_data(WdfInterruptGetDevice(Interrupt));

WdfSpinLockAcquire(fdo_data->device_spin_lock);
// Send interrupt to each port
for (port_number = 1;port_number <= NUM_OF_PORTS;port_number++)
{
// Don’t do anything if interrupt is not registered for port
if (fdo_data->dpc_list[port_number-1] == NULL)
{
continue;
}

// Compute bar0 address for each port
bar_address =
(PUCHAR)(ULONG_PTR)fdo_data->pci_bus_info.pci_bar0_virtual +
((port_number - 1) * fdo_data->pci_bus_info.pci_bar0_length);

imask = READ_REGISTER_ULONG((PULONG)((PUCHAR)bar_address + IMASK_OFFSET));
ievent = READ_REGISTER_ULONG((PULONG)((PUCHAR)bar_address + IEVENT_OFFSET));

if (imask && ievent)
{
// Disable Interrupts
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)bar_address + IMASK_OFFSET), 0);

// Queue DPC in miniport (upper edge)
ASSERT(fdo_data->dpc_list[port_number-1]);
enqueue_state = WdfDpcEnqueue(fdo_data->dpc_list[port_number-1]);
}
}

WdfSpinLockRelease(fdo_data->device_spin_lock);
// Acknowledge the interrupt(s)
return TRUE;
}

BOOLEAN register_interrupt(
IN WDFDEVICE child_device,
IN PVOID context,
IN PFN_WDF_DPC callback
)
{
PPDO_DEVICE_DATA pdo_data = NULL;
PFDO_DEVICE_DATA fdo_data = NULL;
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN ret_val = TRUE;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_DPC_CONFIG dpc_config;
PDPC_DATA dpc_data;
WDFDPC isr_dpc;

pdo_data = pdo_get_data(child_device);

fdo_data = fdo_get_data(pdo_data->bus_device);

// Initialize DPC data
WDF_DPC_CONFIG_INIT(&dpc_config, callback);
dpc_config.AutomaticSerialization = TRUE;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DPC_DATA);
attributes.ParentObject = pdo_data->bus_device;
status = WdfDpcCreate(&dpc_config, &attributes, &isr_dpc);
if (!NT_SUCCESS(status))
{
ret_val = FALSE;
}
else
{
dpc_data = dpc_get_data(isr_dpc);
dpc_data->context = context;
WdfSpinLockAcquire(fdo_data->device_spin_lock);
fdo_data->dpc_list[pdo_data->port_number-1] = isr_dpc;
WdfSpinLockRelease(fdo_data->device_spin_lock);
}

return ret_val;
}

---- MINIPORT CODE ----
VOID dpc_handler(
IN WDFDPC dpc
)
{
PDPC_DATA dpc_data;
PSEL_ETHLITE_ADAPTER adapter;
PSEL_ETHLITE_ISR_INFO info;
ULONG event;

// ASSUMPTIONS: interrupts have been disabled

dpc_data = WdfObjectContextGetObject(dpc);

ASSERT(dpc_data != NULL); <– THIS FAILS

adapter = dpc_data->context;

info = &(adapter->isr);
}


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Are you saying you want to share a context and KMDF object across two different drivers? If so, that is not supported. The object and context belong to the driver that created it, it is not meant to be shared across binary boundaries

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, October 8, 2012 11:37 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

I know. I used an accessor function and this was still returning NULL. The context was created in the bus driver (dpc_get_data), and the child device wants to access it. Since the bus driver created the object…I’m assuming thats why I can’t retrieve it in the child device.

Should it be working this way?

dpc_data = dpc_get_data(dpc);


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks for the ISR locking info. In regards to the context information, its not working.

– BUS DRIVER –
// Initialize DPC data
WDF_DPC_CONFIG_INIT(&dpc_config, callback);
dpc_config.AutomaticSerialization = TRUE;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DPC_DATA);
attributes.ParentObject = pdo_data->bus_device;
status = WdfDpcCreate(&dpc_config, &attributes, &isr_dpc);
if (!NT_SUCCESS(status))
{
ret_val = FALSE;
}
else
{
dpc_data = dpc_get_data(isr_dpc);
dpc_data->context = context;
WdfSpinLockAcquire(fdo_data->device_spin_lock);
fdo_data->dpc_list[pdo_data->port_number-1] = isr_dpc;
WdfSpinLockRelease(fdo_data->device_spin_lock);
}

– MINIPORT CODE —
dpc_data = dpc_get_data(dpc); <– returns NULL

VERY TRUE! Guess the problem now lies in how to pass the “miniport adapter context” to the bus driver when “registering” interrupts, and then somehow receiving this “miniport adapter context” when the minport’s DPC is called by the bus driver.

Like I just said, you CANNOT share a context and object across binary boundaries.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, October 8, 2012 11:45 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

Thanks for the ISR locking info. In regards to the context information, its not working.

– BUS DRIVER –
// Initialize DPC data
WDF_DPC_CONFIG_INIT(&dpc_config, callback);
dpc_config.AutomaticSerialization = TRUE;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DPC_DATA);
attributes.ParentObject = pdo_data->bus_device;
status = WdfDpcCreate(&dpc_config, &attributes, &isr_dpc);
if (!NT_SUCCESS(status))
{
ret_val = FALSE;
}
else
{
dpc_data = dpc_get_data(isr_dpc);
dpc_data->context = context;
WdfSpinLockAcquire(fdo_data->device_spin_lock);
fdo_data->dpc_list[pdo_data->port_number-1] = isr_dpc;
WdfSpinLockRelease(fdo_data->device_spin_lock);
}

– MINIPORT CODE —
dpc_data = dpc_get_data(dpc); <– returns NULL


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

xxxxx@gmail.com wrote:

I know. I used an accessor function and this was still returning NULL. The context was created in the bus driver (dpc_get_data), and the child device wants to access it. Since the bus driver created the object…I’m assuming thats why I can’t retrieve it in the child device.

Should it be working this way?

dpc_data = dpc_get_data(dpc);

A WDFDPC, like all KMDF objects, is a handle. KMDF handles are not
global. There is a table in each driver that maps KMDF handles to the
address of KMDF objects. The table is local to the driver, managed by
code that is statically linked to your driver. In order to find the
address of the data structure for that object, KMDF looks up the handle
in the table of handles for that driver. If the handle is not in the
table, then the corresponding object cannot be found. That’s the case
here. The WDFDPC object was created by your bus driver. Only your bus
driver can find that object from its handle. No other driver can do
so. When you use the handle in another driver, it’s just a random number.

(The fact that a KMDF handle can be trivially converted to an address is
an implementation detail that does not change the reality.)


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

The dpc can have a layer of indirection. The dpc routine is the bus driver’s and your code calls the miniport’s DPC like routine with the appropriate context

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, October 8, 2012 11:46 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

VERY TRUE! Guess the problem now lies in how to pass the “miniport adapter context” to the bus driver when “registering” interrupts, and then somehow receiving this “miniport adapter context” when the minport’s DPC is called by the bus driver.


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

>> The dpc routine is the bus driver’s and

> your code calls the miniport’s DPC like routine with the appropriate context

The question is “how” to call the DPC-like routine from the bus driver…

typedef
Function_class(EVT_MY_DPC)
IRQL_requires_same
IRQL_requires(DISPATCH_LEVEL)
VOID
EVT_MY_DPC(
In
PVOID Context
);

typedef EVT_MY_DPC *PFN_MY_DPC;

BOOLEAN register_interrupt(
IN WDFDEVICE child_device,
IN PVOID context,
IN PFN_MY_DPC callback
)
{
PPDO_DEVICE_DATA pdo_data = NULL;
PFDO_DEVICE_DATA fdo_data = NULL;
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN ret_val = TRUE;
WDF_OBJECT_ATTRIBUTES attributes;
WDF_DPC_CONFIG dpc_config;
PDPC_DATA dpc_data;
WDFDPC isr_dpc;

pdo_data = pdo_get_data(child_device);

fdo_data = fdo_get_data(pdo_data->bus_device);

// Initialize DPC data
WDF_DPC_CONFIG_INIT(&dpc_config, bus_dpc_handler);
dpc_config.AutomaticSerialization = TRUE;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DPC_DATA);
attributes.ParentObject = pdo_data->bus_device;
status = WdfDpcCreate(&dpc_config, &attributes, &isr_dpc);
if (!NT_SUCCESS(status))
{
ret_val = FALSE;
}
else
{
dpc_data = dpc_get_data(isr_dpc);
dpc_data->context = context;
dpc_data->callback = callback;
WdfSpinLockAcquire(fdo_data->device_spin_lock);
fdo_data->dpc_list[pdo_data->port_number-1] = isr_dpc;
WdfSpinLockRelease(fdo_data->device_spin_lock);
}

return ret_val;
}

VOID bus_dpc_handler(
IN WDFDPC dpc
)
{
PDPC_DATA dpc_data;
dpc_data = dpc_get_data(isr_dpc);
dpc_data->callback(dpc_data->context);
}

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Monday, October 8, 2012 11:54 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

> The dpc routine is the bus driver’s and your code calls the
> miniport’s DPC like routine with the appropriate context

The question is “how” to call the DPC-like routine from the bus driver…


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thanks. We need the ability to delete posts since some of them overlapped.

back to the original problem, even with the updated DPC handling, my miniport driver still gets stuck when pausing…and never hits the MINIPORT_PAUSE function. I don’t have any pending NBLs nor OIDs, and my check_for_hang function is continuously called…

Break into the debugger and see if there are any threads stuck in your driver

d

debt from my phone


From: xxxxx@gmail.com
Sent: 10/8/2012 6:43 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

back to the original problem, even with the updated DPC handling, my miniport driver still gets stuck when pausing…and never hits the MINIPORT_PAUSE function. I don’t have any pending NBLs nor OIDs, and my check_for_hang function is continuously called…


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I don’t know of a solid way to check for a stuck thread in my NDIS driver. I think it may have something to do with the DPCs. When I let the miniport driver handle ISRs, using the NDIS register/deregister interrupt functions, my driver was able to to pause. Using the bus driver as the ISR handler, and exposing register/deregister functions from the bus driver, my miniport driver cannot successfully pause…

Break into the debugger,

!stacks 2 <your driver name no .sys>

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, October 10, 2012 10:01 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

I don’t know of a solid way to check for a stuck thread in my NDIS driver. I think it may have something to do with the DPCs. When I let the miniport driver handle ISRs, using the NDIS register/deregister interrupt functions, my driver was able to to pause. Using the bus driver as the ISR handler, and exposing register/deregister functions from the bus driver, my miniport driver cannot successfully pause…


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

My output is below. Could it be a spin lock? confused…

4.000044 847d5798 000049b Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!ExWaitForRundownProtectionReleaseCacheAware+0x9c
tcpip!FlPnpEvent+0x1c4
ndis!ndisPnPNotifyBinding+0x13b
ndis!ndisPnPNotifyAllTransports+0x26c
ndis!ndisCloseMiniportBindings+0xb8
ndis!ndisPnPRemoveDevice+0x23c
ndis!ndisPnPRemoveDeviceEx+0xaa
ndis!ndisPnPDispatch+0x3cf
nt!IovCallDriver+0x258
nt!IofCallDriver+0x1b
nt!IopSynchronousCall+0xc2
nt!IopRemoveDevice+0xd4
nt!PnpRemoveLockedDeviceNode+0x16c
nt!PnpDeleteLockedDeviceNode+0x2d
nt!PnpDeleteLockedDeviceNodes+0x4c
nt!PnpProcessQueryRemoveAndEject+0x946
nt!PnpProcessTargetDeviceEvent+0x38
nt!PnpDeviceEventWorker+0x216
nt!ExpWorkerThread+0x10d
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d0 89f12cb8 004f605 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisThreadPoolTimerHandler+0xd9
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d4 89f129e0 004e30b Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeRemoveQueueEx+0x4f8
nt!KeRemoveQueue+0x1b
ndis!ndisWorkerThread+0x22
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d8 89f14c38 0000390 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisCmWaitThread+0x5b
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19

My guess is that you are not draining and completing all pending io and tcpip is waiting for that io to complete before it allows remove to further progress

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, October 10, 2012 10:43 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Multiport Ethernet Device

My output is below. Could it be a spin lock? confused…

4.000044 847d5798 000049b Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!ExWaitForRundownProtectionReleaseCacheAware+0x9c
tcpip!FlPnpEvent+0x1c4
ndis!ndisPnPNotifyBinding+0x13b
ndis!ndisPnPNotifyAllTransports+0x26c
ndis!ndisCloseMiniportBindings+0xb8
ndis!ndisPnPRemoveDevice+0x23c
ndis!ndisPnPRemoveDeviceEx+0xaa
ndis!ndisPnPDispatch+0x3cf
nt!IovCallDriver+0x258
nt!IofCallDriver+0x1b
nt!IopSynchronousCall+0xc2
nt!IopRemoveDevice+0xd4
nt!PnpRemoveLockedDeviceNode+0x16c
nt!PnpDeleteLockedDeviceNode+0x2d
nt!PnpDeleteLockedDeviceNodes+0x4c
nt!PnpProcessQueryRemoveAndEject+0x946
nt!PnpProcessTargetDeviceEvent+0x38
nt!PnpDeviceEventWorker+0x216
nt!ExpWorkerThread+0x10d
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d0 89f12cb8 004f605 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisThreadPoolTimerHandler+0xd9
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d4 89f129e0 004e30b Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeRemoveQueueEx+0x4f8
nt!KeRemoveQueue+0x1b
ndis!ndisWorkerThread+0x22
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d8 89f14c38 0000390 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisCmWaitThread+0x5b
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

As I said eariler, you definitely have something pending in your miniport
driver. In my experience, 99% of cases are due to packets that I thought I
have completed.

I don’t know about recent NDIS but in early NDIS 6 that I actively worked
on couple years ago doesn’t have debug facility to track outstanding NBL. I
ended up writing my own by wrapping the ndis SendComplete routine in
conjunction with the “hook” in miniportsendnetbufferlists. In such way, I
can probe hung NBL as a outsider.

I would suggest as a test, you complete all NBLs as they come in right off
the spot to rule in/out whether it’s a pending send issue.

Good luck!

On Wed, Oct 10, 2012 at 10:42 AM, wrote:

> My output is below. Could it be a spin lock? confused…
>
> 4.000044 847d5798 000049b Blocked nt!KiSwapContext+0x26
> nt!KiSwapThread+0x266
> nt!KiCommitThreadWait+0x1df
> nt!KeWaitForSingleObject+0x393
>
> nt!ExWaitForRundownProtectionReleaseCacheAware+0x9c
> tcpip!FlPnpEvent+0x1c4
> ndis!ndisPnPNotifyBinding+0x13b
>
> ndis!ndisPnPNotifyAllTransports+0x26c
> ndis!ndisCloseMiniportBindings+0xb8
> ndis!ndisPnPRemoveDevice+0x23c
> ndis!ndisPnPRemoveDeviceEx+0xaa
> ndis!ndisPnPDispatch+0x3cf
> nt!IovCallDriver+0x258
> nt!IofCallDriver+0x1b
> nt!IopSynchronousCall+0xc2
> nt!IopRemoveDevice+0xd4
> nt!PnpRemoveLockedDeviceNode+0x16c
> nt!PnpDeleteLockedDeviceNode+0x2d
> nt!PnpDeleteLockedDeviceNodes+0x4c
>
> nt!PnpProcessQueryRemoveAndEject+0x946
> nt!PnpProcessTargetDeviceEvent+0x38
> nt!PnpDeviceEventWorker+0x216
> nt!ExpWorkerThread+0x10d
> nt!PspSystemThreadStartup+0x9e
> nt!KiThreadStartup+0x19
> 4.0000d0 89f12cb8 004f605 Blocked nt!KiSwapContext+0x26
> nt!KiSwapThread+0x266
> nt!KiCommitThreadWait+0x1df
> nt!KeWaitForSingleObject+0x393
>
> nt!VerifierKeWaitForSingleObject+0xfe
>
> ndis!ndisThreadPoolTimerHandler+0xd9
> nt!PspSystemThreadStartup+0x9e
> nt!KiThreadStartup+0x19
> 4.0000d4 89f129e0 004e30b Blocked nt!KiSwapContext+0x26
> nt!KiSwapThread+0x266
> nt!KiCommitThreadWait+0x1df
> nt!KeRemoveQueueEx+0x4f8
> nt!KeRemoveQueue+0x1b
> ndis!ndisWorkerThread+0x22
> nt!PspSystemThreadStartup+0x9e
> nt!KiThreadStartup+0x19
> 4.0000d8 89f14c38 0000390 Blocked nt!KiSwapContext+0x26
> nt!KiSwapThread+0x266
> nt!KiCommitThreadWait+0x1df
> nt!KeWaitForSingleObject+0x393
>
> nt!VerifierKeWaitForSingleObject+0xfe
> ndis!ndisCmWaitThread+0x5b
> nt!PspSystemThreadStartup+0x9e
> nt!KiThreadStartup+0x19
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

I am completing all sends on the fly now, and now the driver gets stuck after PAUSE…

kd> !stacks 2 ndis
Proc.Thread .Thread Ticks ThreadState Blocker

Max cache size is : 1048576 bytes (0x400 KB)
Total memory in cache : 0 bytes (0 KB)
Number of regions cached: 0
0 full reads broken into 0 partial reads
counts: 0 cached/0 uncached, 0.00% cached
bytes : 0 cached/0 uncached, 0.00% cached
** Prototype PTEs are implicitly decoded
[8476c920 System]
4.0000d0 89f10d28 000c305 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisThreadPoolTimerHandler+0xd9
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d4 89f10a50 00010c6 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeRemoveQueueEx+0x4f8
nt!KeRemoveQueue+0x1b
ndis!ndisWorkerThread+0x22
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.0000d8 89f12cc0 0000181 Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisCmWaitThread+0x5b
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19
4.000174 89f9cd48 00008be Blocked nt!KiSwapContext+0x26
nt!KiSwapThread+0x266
nt!KiCommitThreadWait+0x1df
nt!KeWaitForSingleObject+0x393
nt!VerifierKeWaitForSingleObject+0xfe
ndis!ndisPauseMiniport+0x1a0
ndis!ndisCloseMiniportBindings+0xcb
ndis!ndisPnPRemoveDevice+0x23c
ndis!ndisPnPRemoveDeviceEx+0xaa
ndis!ndisPnPDispatch+0x3cf
nt!IovCallDriver+0x258
nt!IofCallDriver+0x1b
nt!IopSynchronousCall+0xc2
nt!IopRemoveDevice+0xd4
nt!PnpRemoveLockedDeviceNode+0x16c
nt!PnpDeleteLockedDeviceNode+0x2d
nt!PnpDeleteLockedDeviceNodes+0x4c
nt!PnpProcessQueryRemoveAndEject+0x946
nt!PnpProcessTargetDeviceEvent+0x38
nt!PnpDeviceEventWorker+0x216
nt!ExpWorkerThread+0x10d
nt!PspSystemThreadStartup+0x9e
nt!KiThreadStartup+0x19

It looks like it is not pausing because I have pending receives. For some reason my returnnetbufferlists function stops getting called, and therefore my pending receive count never goes to zero, thus causing my driver to be stuck in the pausing state