ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

in my USB driver, when WdfRequestSend is called from my DPC, i get BSOD with ATTEMPTED_SWITCH_FROM_DPC. can anyone shed any light as to what might be the problem. thanks.

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
This is an illegal operation and the stack track will lead to the offending
code and original DPC routine.
Arguments:
Arg1: 00000000, Original thread which is the cause of the failure
Arg2: 00000000, New thread
Arg3: 00000000, Stack address of the original thread
Arg4: 00000000

TACK_TEXT:
nt!RtlpBreakWithStatusInstruction
nt!KiBugCheckDebugBreak+0x19
nt!KeBugCheck2+0x574
nt!KeBugCheck+0x14
nt!ScPatchFxe+0x46
nt!KiSwapContext+0x2f
nt!KiSwapThread+0x6b
nt!KeWaitForSingleObject+0x1c2
Wdf01000!FxCREvent::EnterCRAndWait+0x1d
Wdf01000!FxCREvent::EnterCRAndWaitAndLeave+0xe
Wdf01000!FxIoTarget::SubmitSync+0x1db
Wdf01000!imp_WdfRequestSend+0x178
acexusb!WdfRequestSend+0x1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @ 569]
acexusb!DdcSfpUsbSndIoctlWrite+0x36 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 597]
acexusb!sfpUsbWrite+0xe9 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 256]
acexusb!bdInterruptSet+0x44 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\bd.c @ 249]
acexusb!EvtSfpIntHandler+0x82 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\device.c @ 341]
Wdf01000!FxDpc::DpcHandler+0x54
Wdf01000!FxDpc::FxDpcThunk+0x16
nt!KiRetireDpcList+0x61
nt!KiIdleLoop+0x28

STACK_COMMAND: kb

FOLLOWUP_IP:
acexusb!WdfRequestSend+1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @ 569]
f4bd7d8d 5d pop ebp

FAULTING_SOURCE_CODE:
565: PWDF_REQUEST_SEND_OPTIONS Options
566: )
567: {
568: return ((PFN_WDFREQUESTSEND) WdfFunctions[WdfRequestSendTableIndex])(WdfDriverGlobals, Request, Target, Options);

569: }
570:
571: //
572: // WDF Function: WdfRequestGetStatus
573: //
574: typedef

What does this code look like:

acexusb!DdcSfpUsbSndIoctlWrite+0x36 [d:\69092s0
merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 597]

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@ddc-web.com
Sent: Friday, September 24, 2010 3:34 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

in my USB driver, when WdfRequestSend is called from my DPC, i get BSOD with
ATTEMPTED_SWITCH_FROM_DPC. can anyone shed any light as to what might be the
problem. thanks.

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
This is an illegal operation and the stack track will lead to the offending
code and original DPC routine.
Arguments:
Arg1: 00000000, Original thread which is the cause of the failure
Arg2: 00000000, New thread
Arg3: 00000000, Stack address of the original thread
Arg4: 00000000

TACK_TEXT:
nt!RtlpBreakWithStatusInstruction
nt!KiBugCheckDebugBreak+0x19
nt!KeBugCheck2+0x574
nt!KeBugCheck+0x14
nt!ScPatchFxe+0x46
nt!KiSwapContext+0x2f
nt!KiSwapThread+0x6b
nt!KeWaitForSingleObject+0x1c2
Wdf01000!FxCREvent::EnterCRAndWait+0x1d
Wdf01000!FxCREvent::EnterCRAndWaitAndLeave+0xe
Wdf01000!FxIoTarget::SubmitSync+0x1db
Wdf01000!imp_WdfRequestSend+0x178
acexusb!WdfRequestSend+0x1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @
569]
acexusb!DdcSfpUsbSndIoctlWrite+0x36 [d:\69092s0
merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 597]
acexusb!sfpUsbWrite+0xe9 [d:\69092s0
merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 256]
acexusb!bdInterruptSet+0x44 [d:\69092s0
merge\drivers\acexusb\solution\project\sys\bd.c @ 249]
acexusb!EvtSfpIntHandler+0x82 [d:\69092s0
merge\drivers\acexusb\solution\project\sys\device.c @ 341]
Wdf01000!FxDpc::DpcHandler+0x54
Wdf01000!FxDpc::FxDpcThunk+0x16
nt!KiRetireDpcList+0x61
nt!KiIdleLoop+0x28

STACK_COMMAND: kb

FOLLOWUP_IP:
acexusb!WdfRequestSend+1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @
569]
f4bd7d8d 5d pop ebp

FAULTING_SOURCE_CODE:
565: PWDF_REQUEST_SEND_OPTIONS Options
566: )
567: {
568: return ((PFN_WDFREQUESTSEND)
WdfFunctions[WdfRequestSendTableIndex])(WdfDriverGlobals, Request, Target,
Options);

569: }
570:
571: //
572: // WDF Function: WdfRequestGetStatus
573: //
574: typedef


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

NTSTATUS DdcSfpUsbSndIoctlWrite(PDEVICE_CONTEXT pDeviceContext)
{
#ifdef ENABLE_READ_SEND_OPTIONS
WDF_REQUEST_SEND_OPTIONS wdfSendOpt;

/* configure send options */
WDF_REQUEST_SEND_OPTIONS_INIT(&wdfSendOpt,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
/* | WDF_REQUEST_SEND_OPTION_TIMEOUT*/
);
/* WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&wdfSendOpt,100000); */
#endif

DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME"DdcSfpUsbSndIoctlWrite: ENTER\n");

/* Send request to our usb device */
if (WdfRequestSend( pDeviceContext->wrRequest,
WdfUsbTargetPipeGetIoTarget(pDeviceContext->BulkWritePipe),
&wdfSendOpt) == FALSE)
{ /* Framework could not send the request for some reason. */
DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME “DdcSfpUsbSndIoctlWrite:\n”
“FAIL WdfRequestSend usbwrite for read\n”);

return WdfRequestGetStatus(pDeviceContext->wrRequest);
}

DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME"DdcSfpUsbSndIoctlWrite: EXIT\n");

return STATUS_SUCCESS;
}

Is ENABLE_READ_SEND_OPTIONS defined?

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@ddc-web.com
Sent: Friday, September 24, 2010 3:46 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

NTSTATUS DdcSfpUsbSndIoctlWrite(PDEVICE_CONTEXT pDeviceContext)
{
#ifdef ENABLE_READ_SEND_OPTIONS
WDF_REQUEST_SEND_OPTIONS wdfSendOpt;

/* configure send options */
WDF_REQUEST_SEND_OPTIONS_INIT(&wdfSendOpt,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
/* | WDF_REQUEST_SEND_OPTION_TIMEOUT*/
);
/* WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&wdfSendOpt,100000); */
#endif

DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME"DdcSfpUsbSndIoctlWrite: ENTER\n");

/* Send request to our usb device */
if (WdfRequestSend( pDeviceContext->wrRequest,

WdfUsbTargetPipeGetIoTarget(pDeviceContext->BulkWritePipe),
&wdfSendOpt) == FALSE)
{ /* Framework could not send the request for some reason. */
DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME “DdcSfpUsbSndIoctlWrite:\n”
“FAIL WdfRequestSend usbwrite for read\n”);

return WdfRequestGetStatus(pDeviceContext->wrRequest);
}

DDC_SFPUSB_DETAIL_DEBUG(DRIVER_NAME"DdcSfpUsbSndIoctlWrite: EXIT\n");

return STATUS_SUCCESS;
}


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

yes. the other macro in the function is a piece of code snippet that calls KdPrint.

xxxxx@ddc-web.com wrote:

NTSTATUS DdcSfpUsbSndIoctlWrite(PDEVICE_CONTEXT pDeviceContext)
{
#ifdef ENABLE_READ_SEND_OPTIONS
WDF_REQUEST_SEND_OPTIONS wdfSendOpt;

/* configure send options */
WDF_REQUEST_SEND_OPTIONS_INIT(&wdfSendOpt,
WDF_REQUEST_SEND_OPTION_SYNCHRONOUS
/* | WDF_REQUEST_SEND_OPTION_TIMEOUT*/
);
/* WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&wdfSendOpt,100000); */
#endif

The error is completely descriptive. You’re doing a synchronous
operation, meaning “send this down and wait for the results”. You can’t
wait in a DPC. You need to fire this off and use a completion routine
to catch the results.


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

This bugcheck is caused by your own choices, to wit:

Wdf01000!FxIoTarget::SubmitSync+0x1db

If that’s on the stack, you are doing synchronous I/O- and you can’t do that at dispatch level (which a DPC is). Set a completion routine and complete your processing there, or send the synchronous I/O from a work item.

-----Original Message-----

in my USB driver, when WdfRequestSend is called from my DPC, i get BSOD with ATTEMPTED_SWITCH_FROM_DPC. can anyone shed any light as to what might be the problem. thanks.

ATTEMPTED_SWITCH_FROM_DPC (b8)
A wait operation, attach process, or yield was attempted from a DPC routine.
This is an illegal operation and the stack track will lead to the offending code and original DPC routine.
Arguments:
Arg1: 00000000, Original thread which is the cause of the failure
Arg2: 00000000, New thread
Arg3: 00000000, Stack address of the original thread
Arg4: 00000000

TACK_TEXT:
nt!RtlpBreakWithStatusInstruction
nt!KiBugCheckDebugBreak+0x19
nt!KeBugCheck2+0x574
nt!KeBugCheck+0x14
nt!ScPatchFxe+0x46
nt!KiSwapContext+0x2f
nt!KiSwapThread+0x6b
nt!KeWaitForSingleObject+0x1c2
Wdf01000!FxCREvent::EnterCRAndWait+0x1d
Wdf01000!FxCREvent::EnterCRAndWaitAndLeave+0xe
Wdf01000!FxIoTarget::SubmitSync+0x1db
Wdf01000!imp_WdfRequestSend+0x178
acexusb!WdfRequestSend+0x1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @ 569]
acexusb!DdcSfpUsbSndIoctlWrite+0x36 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 597]
acexusb!sfpUsbWrite+0xe9 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\sfpusb.c @ 256]
acexusb!bdInterruptSet+0x44 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\bd.c @ 249]
acexusb!EvtSfpIntHandler+0x82 [d:\69092s0 merge\drivers\acexusb\solution\project\sys\device.c @ 341]
Wdf01000!FxDpc::DpcHandler+0x54
Wdf01000!FxDpc::FxDpcThunk+0x16
nt!KiRetireDpcList+0x61
nt!KiIdleLoop+0x28

STACK_COMMAND: kb

FOLLOWUP_IP:
acexusb!WdfRequestSend+1d [c:\winddk\6000\inc\wdf\kmdf\10\wdfrequest.h @ 569]
f4bd7d8d 5d pop ebp

FAULTING_SOURCE_CODE:
565: PWDF_REQUEST_SEND_OPTIONS Options
566: )
567: {
568: return ((PFN_WDFREQUESTSEND) WdfFunctions[WdfRequestSendTableIndex])(WdfDriverGlobals, Request, Target, Options);

569: }
570:
571: //
572: // WDF Function: WdfRequestGetStatus
573: //
574: typedef

Then your problem is that you’re doing exactly what the error message says
that you’re doing - waiting in a DPC - because you’re request is
synchronous.

You need to use a completion routine.

Good luck,

mm

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@ddc-web.com
Sent: Friday, September 24, 2010 3:53 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

yes. the other macro in the function is a piece of code snippet that calls
KdPrint.


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

When I call WdfIoTargetStop , It come across the same error code.

Does WdfIoTargetStop can be called in EVT_WDF_USB_READER_COMPLETION_ROUTINE ?

Which stop action are you passing to the api?

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@hotmail.com
Sent: September 25, 2010 1:19 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

When I call WdfIoTargetStop , It come across the same error code.

Does WdfIoTargetStop can be called in EVT_WDF_USB_READER_COMPLETION_ROUTINE ?


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

>Which stop action are you passing to the api?

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@hotmail.com
>Sent: September 25, 2010 1:19 AM
>To: Windows System Software Devs Interest List
>Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

>When I call WdfIoTargetStop , It come across the same error code.

>Does WdfIoTargetStop can be called in EVT_WDF_USB_READER_COMPLETION_ROUTINE ?

Code :
I call WdfUsbTargetPipeConfigContinuousReader in PrepareHardware() function.
code :
WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipeHandle);
WDF_USB_CONTINUOUS_READER_CONFIG_INIT(&wdfConIntReaderCfg,
EvtUsbDeviceBulkInComplete,
pDeviceExtContext,
pipeMaxsize);
ntStatus = WdfUsbTargetPipeConfigContinuousReader(pipeHandle,&wdfConIntReaderCfg);

and call WdfIoTargetStart in DeviceD0Entry .

EvtUsbDeviceBulkInComplete function :
NTSTATUS EvtUsbDeviceBulkInComplete (WDFUSBPIPE Pipe,WDFMEMORY Buffer,size_t NumBytesTransferred,WDFCONTEXT Context)
{
WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(PipeHandle),WdfIoTargetCancelSentIo);
}

Every time the EvtUsbDeviceBulkInComplete is called ,I crash .

error code :ATTEMPTED_SWITCH_FROM_DPC (b8)

if I stop with action=WdfIoTargetSentIoUndefined . It will not crash ,but lost the data. the transfer will not be completed.

You do not use the undefined value, it is used as a sentinel for a value you have not set yet. Why are you stopping a content reader in the completion routine?

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@hotmail.com
Sent: September 25, 2010 6:50 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

if I stop with action=WdfIoTargetSentIoUndefined . It will not crash ,but lost the data. the transfer will not be completed.


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

getting so much data that makes my interval buffer full .so I stop the reader untill the application issues a read request to make the available interval buffer is larger than pipeMaxsize ,then I will call WdfIoTargetStart to restart the reader.

look at the log when calling EvtUsbDeviceBulkinComplete . As soon as receiving any data , I push it into interval buffer ,and waiting the application to read the data . sometimes , the reader should be stop while the availbale Interval buffer is less than pipeMaxsize . and restart the reader after pulling the data out of buffer.

Log :
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 4618 .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 5130 .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 5642 .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 6154 .
Received a read request of 512 bytes
Number bytes Need to read = 512, and haveDataLen = 6154.
Pull Circular Buffer and DataLen Left= 5642) .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
compelete Read=512.
Push Data and DataLen Left= 6154 .
EvtUsbDeviceBulkinComplete. Transfer Length = 293
Push Data and DataLen Left= 6447 .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 6959 .
EvtUsbDeviceBulkinComplete. Transfer Length = 512
Push Data and DataLen Left= 7471 .
EvtUsbDeviceBulkinComplete. Transfer Length = 218
Push Data and DataLen Left= 7689 .

if(leftBuffer < pipeMaxsize)
WdfIoTargetStop()

Podun Yu wrote:

WdfIoTargetStop(
WdfUsbTargetPipeGetIoTarget(PipeHandle),
WdfIoTargetCancelSentIo
);

I think Doron once mentioned on this group (actually it seems like it was Eliyas on the managed group) that WdfIoTargetCancelSentIo silently transforms to WdfIoTargetWaitForSentIoToComplete under the covers, violating both your expectations about functionality and supported IRQL. Gotcha!

Podun Yu wrote:

getting so much data that makes my interval buffer full .
so I stop the reader untill the application issues a read
request to make the available interval buffer is larger
than pipeMaxsize

By the way, I would recommend a little hysteresis here. Why not let the usermode app drain your buffer almost completely before turning the reader back on?

Also, pipeMaxsize is probably not relevant here – consider that if you have three outstanding reads of say, 4K, issued from the continuous reader and pending at the hub, they could all potentially complete after you issue the call to WdfIoTargetStop() – so you need to account for that possibility.

>I think Doron once mentioned on this group (actually it seems like it was Eliyas

on the managed group) that WdfIoTargetCancelSentIo silently transforms to
WdfIoTargetWaitForSentIoToComplete under the covers, violating both your
expectations about functionality and supported IRQL. Gotcha!

I really want to make the action = leavetopending while I will restart the reader later ,so I don’t want to lost any request, But MSDN says that run in PASSIVE_LAVEL only!

Do you means that the hub(or whatever) process the request with action = WdfIoTargetWaitForSentIoToComplete indeed?

By the way, I would recommend a little hysteresis here. Why not let the
usermode app drain your buffer almost completely before turning the reader back
on?

It is not so fast to issue the read request . I already complete the mask request with 80FULL event .
and It issue a read request , you can see that in the Log . But the driver gets so much data at the moment. So I should really *Stop* the reader .

Also, pipeMaxsize is probably not relevant here – consider that if you have
three outstanding reads of say, 4K, issued from the continuous reader and
pending at the hub, they could all potentially complete after you issue the call
to WdfIoTargetStop() – so you need to account for that possibility.

Ok , Any advices to resolved the question that I mention at the beginning :
When the buffer is full ,what should I do ?
Maybe stop reader is just one of the methods. but I would like this method will be doable .

Either queue a work item and stopot from there or just queue the data internally until the sends another read data request.

d

dent from a phpne with no keynoard

-----Original Message-----
From: xxxxx@hotmail.com
Sent: September 26, 2010 9:10 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] ATTEMPTED_SWITCH_FROM_DPC when WdfRequestSend Called

>I think Doron once mentioned on this group (actually it seems like it was Eliyas
>on the managed group) that WdfIoTargetCancelSentIo silently transforms to
>WdfIoTargetWaitForSentIoToComplete under the covers, violating both your
>expectations about functionality and supported IRQL. Gotcha!

I really want to make the action = leavetopending while I will restart the reader later ,so I don’t want to lost any request, But MSDN says that run in PASSIVE_LAVEL only!

Do you means that the hub(or whatever) process the request with action = WdfIoTargetWaitForSentIoToComplete indeed?

>By the way, I would recommend a little hysteresis here. Why not let the
>usermode app drain your buffer almost completely before turning the reader back
>on?

It is not so fast to issue the read request . I already complete the mask request with 80FULL event .
and It issue a read request , you can see that in the Log . But the driver gets so much data at the moment. So I should really Stop the reader .

>Also, pipeMaxsize is probably not relevant here – consider that if you have
>three outstanding reads of say, 4K, issued from the continuous reader and
>pending at the hub, they could all potentially complete after you issue the call
>to WdfIoTargetStop() – so you need to account for that possibility.

Ok , Any advices to resolved the question that I mention at the beginning :
When the buffer is full ,what should I do ?
Maybe stop reader is just one of the methods. but I would like this method will be doable .


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

>Either queue a work item and stopot from there or just queue the data internally

until the sends another read data request.

I didn’t catch you , can you expatiate on the *work item* or any key words that i can google on it?
and queue the data internally means I need another queue ? or create a new internal buffer ?