In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Hello All,

I am writing a function driver based upon the USBSAMP in KMDF. Actually I am porting a WDM driver code in KMDF for windows 7 and further support. And I don’t have the code for the existing driver what I have is the application code and firmware code and device. So I need to fit in my driver code as per existing understanding between application and the firmware.

Problem Statement : My firmware is writing data at its own wish , which I have to read it through ReadFile in continuous while loop. When readfile API is called from the application , In my driver code the corresponding I/O callback is getting called (i.e UsbSamp_EvtIoRead). From this point I am successfully able to call the WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not getting called as firmware has not written any thing so Bus driver will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”, operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my driver code into it somehow. The one approach what I could see it just use the time out in WdfRequestSend. Then once the time out happens Completion Routine for read will be called and there I will treat this timeout as success. ( ReadAPI is passed with Zero byte read).

Can I resolve the same with the KMDF Continuous Reader ? If so then do I need to have the I/0 readevent without Completion Callback and just send the request down to the Bus driver as in UsbSamp_EvtIoRead.

// Not Completion routing
// WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously without completion and return success from here only.
//
if (!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe), WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”, operation));
status = WdfRequestGetStatus(Request);
goto End;
}
status = WdfRequestGetStatus(Request);
WdfRequestComplete(Request, status);

Then when the KMDF continuous reader callback gets called (which is notification of something written by the firmware/device) I will again use the WdfRequestComplete(Request, status);

Please share your veiw on the same.

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

Ravi Rathore (RBEI/EST2) wrote:

Problem Statement : My firmware is writing data at its own wish ,
which I have to read it through ReadFile in continuous while loop.

Remember that a USB device cannot send data on its own. It can only
send data when the host controller asks it to, and the host controller
will never ask it to send unless there is an outstanding request from a
driver. Does your device have enough buffering to hold the data until
your application is ready?

When readfile API is called from the application , In my driver code
the corresponding I/O callback is getting called (i.e
UsbSamp_EvtIoRead). From this point I am successfully able to call the
WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not
getting called as firmware has not written any thing so Bus driver
will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if(!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”,
operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my
driver code into it somehow.

I can’t tell from this whether you have the specifications for your
device or not. You can’t guess at the specifications for a USB device.
You have to know what triggers data to be sent, how it will be sent,
what size the packets are, and so on.

What do you WANT to happen if the device has no data when you go to read it?

Have you called WdfUsbTrgetPipeFormatRequestForRead? You can’t just
forward an application “read” request down to the USB bus driver. USBD
only understands URBs, so you have to call an API to create a URB.


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

First of all sorry about my English …

Tim Roberts : “Remember that a USB device cannot send data on its own. It can only send data when the host controller asks it to, and the host controller will never ask it
to send unless there is an outstanding request from a driver. Does your device have enough buffering to hold the data until your application is ready?”
Ravi: Yes It has. In my application ReadFile API is being called in continuous while loop in Application which makes always makes a request to driver.

Tim Roberts: “What do you WANT to happen if the device has no data when you go to read it?”
Ravi: My device is processing audio and application needs to depicts any changes in parameters. For example is User has
pressed mute button on the device then it has to reflected in GUI. This is the one of reason GUI application continuously calling ReadFile.

  1. ReadFile API treated as success only if “It return True” AND “It has some bytes read”. If both are true then we do some processing in GUI other wise fail but
    neither case should hange.So if there is no data to be read from the device then ReadFile should succeed but byte read should be Zero. Current this got
    hanged.
  2. When I changed my firmware code as to write every time(i.e in 1 second) some data (junk/test data ), then my driver ReadCompletion Routing is getting called
    and it works perfectly.

Ravi : 1. Is it possible to have a time out value in “WdfRequestSend” so that once time-out happens the Completion Routine will be called and there I will treat this as
success and complete the request with success and zero byte read ?
2. Could this be solved via KMDF continuous Reader ?
3. I got to know that earlier working driver (for which I don’t have source code) is based upon the WDM /6000/bulkusb driver. For the Testing purpose I have
download that and I am trying to modify as per mine multiple interface device descriptor but not able to do so. Still trying …

Ravi : One interesting thing what I found in that sample code(WDM /6000/bulkusb driver) is that BulkUsb_DispatchReadWrite always return STATUS_PENDING which I could not
understand …

DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_DispatchReadWrite;

NTSTATUS
BulkUsb_DispatchReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{

IoSetCompletionRoutine(Irp,
BulkUsb_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);

//
// since we return STATUS_PENDING call IoMarkIrpPending.
// This is the boiler plate code.
// This may cause extra overhead of an APC for the Irp completion
// but this is the correct thing to do.
//

IoMarkIrpPending(Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchReadWrite::”));
BulkUsb_IoIncrement(deviceExtension);

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“IoCallDriver fails with status %X\n”, ntStatus));

//
// if the device was yanked out, then the pipeInformation
// field is invalid.
// similarly if the request was cancelled, then we need not
// invoked reset pipe/device.
//
if((ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED)) {

ntStatus = BulkUsb_ResetPipe(DeviceObject,
pipeInformation);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“BulkUsb_ResetPipe failed\n”));

ntStatus = BulkUsb_ResetDevice(DeviceObject);
}
}
else {

BulkUsb_DbgPrint(3, ("ntStatus is STATUS_CANCELLED or "
“STATUS_DEVICE_NOT_CONNECTED\n”));
}
}

//
// we return STATUS_PENDING and not the status returned by the lower layer.
//
return STATUS_PENDING;

}

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, 29. March 2011 22:05
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Ravi Rathore (RBEI/EST2) wrote:

Problem Statement : My firmware is writing data at its own wish ,
which I have to read it through ReadFile in continuous while loop.

Remember that a USB device cannot send data on its own. It can only
send data when the host controller asks it to, and the host controller
will never ask it to send unless there is an outstanding request from a
driver. Does your device have enough buffering to hold the data until
your application is ready?

When readfile API is called from the application , In my driver code
the corresponding I/O callback is getting called (i.e
UsbSamp_EvtIoRead). From this point I am successfully able to call the
WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not
getting called as firmware has not written any thing so Bus driver
will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if(!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”,
operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my
driver code into it somehow.

I can’t tell from this whether you have the specifications for your
device or not. You can’t guess at the specifications for a USB device.
You have to know what triggers data to be sent, how it will be sent,
what size the packets are, and so on.

What do you WANT to happen if the device has no data when you go to read it?

Have you called WdfUsbTrgetPipeFormatRequestForRead? You can’t just
forward an application “read” request down to the USB bus driver. USBD
only understands URBs, so you have to call an API to create a URB.


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


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

Can you change the app at all? If so, dump your driver and use winusb instead. Then you don’t have to write or maintain a driver at all.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Ravi Rathore (RBEI/EST2)
Sent: Wednesday, March 30, 2011 11:04 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

First of all sorry about my English …

Tim Roberts : “Remember that a USB device cannot send data on its own. It can only send data when the host controller asks it to, and the host controller will never ask it
to send unless there is an outstanding request from a driver. Does your device have enough buffering to hold the data until your application is ready?”
Ravi: Yes It has. In my application ReadFile API is being called in continuous while loop in Application which makes always makes a request to driver.

Tim Roberts: “What do you WANT to happen if the device has no data when you go to read it?”
Ravi: My device is processing audio and application needs to depicts any changes in parameters. For example is User has
pressed mute button on the device then it has to reflected in GUI. This is the one of reason GUI application continuously calling ReadFile.

  1. ReadFile API treated as success only if “It return True” AND “It has some bytes read”. If both are true then we do some processing in GUI other wise fail but
    neither case should hange.So if there is no data to be read from the device then ReadFile should succeed but byte read should be Zero. Current this got
    hanged.
  2. When I changed my firmware code as to write every time(i.e in 1 second) some data (junk/test data ), then my driver ReadCompletion Routing is getting called
    and it works perfectly.

Ravi : 1. Is it possible to have a time out value in “WdfRequestSend” so that once time-out happens the Completion Routine will be called and there I will treat this as
success and complete the request with success and zero byte read ?
2. Could this be solved via KMDF continuous Reader ?
3. I got to know that earlier working driver (for which I don’t have source code) is based upon the WDM /6000/bulkusb driver. For the Testing purpose I have
download that and I am trying to modify as per mine multiple interface device descriptor but not able to do so. Still trying …

Ravi : One interesting thing what I found in that sample code(WDM /6000/bulkusb driver) is that BulkUsb_DispatchReadWrite always return STATUS_PENDING which I could not
understand …

DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_DispatchReadWrite;

NTSTATUS
BulkUsb_DispatchReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{

IoSetCompletionRoutine(Irp,
BulkUsb_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);

//
// since we return STATUS_PENDING call IoMarkIrpPending.
// This is the boiler plate code.
// This may cause extra overhead of an APC for the Irp completion
// but this is the correct thing to do.
//

IoMarkIrpPending(Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchReadWrite::”));
BulkUsb_IoIncrement(deviceExtension);

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“IoCallDriver fails with status %X\n”, ntStatus));

//
// if the device was yanked out, then the pipeInformation
// field is invalid.
// similarly if the request was cancelled, then we need not
// invoked reset pipe/device.
//
if((ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED)) {

ntStatus = BulkUsb_ResetPipe(DeviceObject,
pipeInformation);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“BulkUsb_ResetPipe failed\n”));

ntStatus = BulkUsb_ResetDevice(DeviceObject);
}
}
else {

BulkUsb_DbgPrint(3, ("ntStatus is STATUS_CANCELLED or "
“STATUS_DEVICE_NOT_CONNECTED\n”));
}
}

//
// we return STATUS_PENDING and not the status returned by the lower layer.
//
return STATUS_PENDING;

}

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, 29. March 2011 22:05
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Ravi Rathore (RBEI/EST2) wrote:

Problem Statement : My firmware is writing data at its own wish ,
which I have to read it through ReadFile in continuous while loop.

Remember that a USB device cannot send data on its own. It can only
send data when the host controller asks it to, and the host controller
will never ask it to send unless there is an outstanding request from a
driver. Does your device have enough buffering to hold the data until
your application is ready?

When readfile API is called from the application , In my driver code
the corresponding I/O callback is getting called (i.e
UsbSamp_EvtIoRead). From this point I am successfully able to call the
WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not
getting called as firmware has not written any thing so Bus driver
will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if(!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”,
operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my
driver code into it somehow.

I can’t tell from this whether you have the specifications for your
device or not. You can’t guess at the specifications for a USB device.
You have to know what triggers data to be sent, how it will be sent,
what size the packets are, and so on.

What do you WANT to happen if the device has no data when you go to read it?

Have you called WdfUsbTrgetPipeFormatRequestForRead? You can’t just
forward an application “read” request down to the USB bus driver. USBD
only understands URBs, so you have to call an API to create a URB.


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


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


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

We have already spent effort in it… And it just got stuck with only one problem … Don’t want to give up at this time but I can try with winusb just for my leering not for development …

Primary focus in only on KMDF based USB…

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Thursday, 31. March 2011 11:42
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Can you change the app at all? If so, dump your driver and use winusb instead. Then you don’t have to write or maintain a driver at all.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Ravi Rathore (RBEI/EST2)
Sent: Wednesday, March 30, 2011 11:04 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

First of all sorry about my English …

Tim Roberts : “Remember that a USB device cannot send data on its own. It can only send data when the host controller asks it to, and the host controller will never ask it
to send unless there is an outstanding request from a driver. Does your device have enough buffering to hold the data until your application is ready?”
Ravi: Yes It has. In my application ReadFile API is being called in continuous while loop in Application which makes always makes a request to driver.

Tim Roberts: “What do you WANT to happen if the device has no data when you go to read it?”
Ravi: My device is processing audio and application needs to depicts any changes in parameters. For example is User has
pressed mute button on the device then it has to reflected in GUI. This is the one of reason GUI application continuously calling ReadFile.

  1. ReadFile API treated as success only if “It return True” AND “It has some bytes read”. If both are true then we do some processing in GUI other wise fail but
    neither case should hange.So if there is no data to be read from the device then ReadFile should succeed but byte read should be Zero. Current this got
    hanged.
  2. When I changed my firmware code as to write every time(i.e in 1 second) some data (junk/test data ), then my driver ReadCompletion Routing is getting called
    and it works perfectly.

Ravi : 1. Is it possible to have a time out value in “WdfRequestSend” so that once time-out happens the Completion Routine will be called and there I will treat this as
success and complete the request with success and zero byte read ?
2. Could this be solved via KMDF continuous Reader ?
3. I got to know that earlier working driver (for which I don’t have source code) is based upon the WDM /6000/bulkusb driver. For the Testing purpose I have
download that and I am trying to modify as per mine multiple interface device descriptor but not able to do so. Still trying …

Ravi : One interesting thing what I found in that sample code(WDM /6000/bulkusb driver) is that BulkUsb_DispatchReadWrite always return STATUS_PENDING which I could not
understand …

DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_DispatchReadWrite;

NTSTATUS
BulkUsb_DispatchReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{

IoSetCompletionRoutine(Irp,
BulkUsb_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);

//
// since we return STATUS_PENDING call IoMarkIrpPending.
// This is the boiler plate code.
// This may cause extra overhead of an APC for the Irp completion
// but this is the correct thing to do.
//

IoMarkIrpPending(Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchReadWrite::”));
BulkUsb_IoIncrement(deviceExtension);

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“IoCallDriver fails with status %X\n”, ntStatus));

//
// if the device was yanked out, then the pipeInformation
// field is invalid.
// similarly if the request was cancelled, then we need not
// invoked reset pipe/device.
//
if((ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED)) {

ntStatus = BulkUsb_ResetPipe(DeviceObject,
pipeInformation);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“BulkUsb_ResetPipe failed\n”));

ntStatus = BulkUsb_ResetDevice(DeviceObject);
}
}
else {

BulkUsb_DbgPrint(3, ("ntStatus is STATUS_CANCELLED or "
“STATUS_DEVICE_NOT_CONNECTED\n”));
}
}

//
// we return STATUS_PENDING and not the status returned by the lower layer.
//
return STATUS_PENDING;

}

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, 29. March 2011 22:05
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Ravi Rathore (RBEI/EST2) wrote:

Problem Statement : My firmware is writing data at its own wish ,
which I have to read it through ReadFile in continuous while loop.

Remember that a USB device cannot send data on its own. It can only
send data when the host controller asks it to, and the host controller
will never ask it to send unless there is an outstanding request from a
driver. Does your device have enough buffering to hold the data until
your application is ready?

When readfile API is called from the application , In my driver code
the corresponding I/O callback is getting called (i.e
UsbSamp_EvtIoRead). From this point I am successfully able to call the
WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not
getting called as firmware has not written any thing so Bus driver
will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if(!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”,
operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my
driver code into it somehow.

I can’t tell from this whether you have the specifications for your
device or not. You can’t guess at the specifications for a USB device.
You have to know what triggers data to be sent, how it will be sent,
what size the packets are, and so on.

What do you WANT to happen if the device has no data when you go to read it?

Have you called WdfUsbTrgetPipeFormatRequestForRead? You can’t just
forward an application “read” request down to the USB bus driver. USBD
only understands URBs, so you have to call an API to create a URB.


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


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


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


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

Addition info:

If I cancel the ReadAPI request (i.e. closing application from Task Manager which calls ReadAPI ) the ReadCompletion Routing is getting called because of resting the pipe info.

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Doron Holan
Sent: Thursday, 31. March 2011 11:42
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Can you change the app at all? If so, dump your driver and use winusb instead. Then you don’t have to write or maintain a driver at all.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Ravi Rathore (RBEI/EST2)
Sent: Wednesday, March 30, 2011 11:04 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

First of all sorry about my English …

Tim Roberts : “Remember that a USB device cannot send data on its own. It can only send data when the host controller asks it to, and the host controller will never ask it
to send unless there is an outstanding request from a driver. Does your device have enough buffering to hold the data until your application is ready?”
Ravi: Yes It has. In my application ReadFile API is being called in continuous while loop in Application which makes always makes a request to driver.

Tim Roberts: “What do you WANT to happen if the device has no data when you go to read it?”
Ravi: My device is processing audio and application needs to depicts any changes in parameters. For example is User has
pressed mute button on the device then it has to reflected in GUI. This is the one of reason GUI application continuously calling ReadFile.

  1. ReadFile API treated as success only if “It return True” AND “It has some bytes read”. If both are true then we do some processing in GUI other wise fail but
    neither case should hange.So if there is no data to be read from the device then ReadFile should succeed but byte read should be Zero. Current this got
    hanged.
  2. When I changed my firmware code as to write every time(i.e in 1 second) some data (junk/test data ), then my driver ReadCompletion Routing is getting called
    and it works perfectly.

Ravi : 1. Is it possible to have a time out value in “WdfRequestSend” so that once time-out happens the Completion Routine will be called and there I will treat this as
success and complete the request with success and zero byte read ?
2. Could this be solved via KMDF continuous Reader ?
3. I got to know that earlier working driver (for which I don’t have source code) is based upon the WDM /6000/bulkusb driver. For the Testing purpose I have
download that and I am trying to modify as per mine multiple interface device descriptor but not able to do so. Still trying …

Ravi : One interesting thing what I found in that sample code(WDM /6000/bulkusb driver) is that BulkUsb_DispatchReadWrite always return STATUS_PENDING which I could not
understand …

DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = BulkUsb_DispatchReadWrite;

NTSTATUS
BulkUsb_DispatchReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{

IoSetCompletionRoutine(Irp,
BulkUsb_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);

//
// since we return STATUS_PENDING call IoMarkIrpPending.
// This is the boiler plate code.
// This may cause extra overhead of an APC for the Irp completion
// but this is the correct thing to do.
//

IoMarkIrpPending(Irp);

BulkUsb_DbgPrint(3, (“BulkUsb_DispatchReadWrite::”));
BulkUsb_IoIncrement(deviceExtension);

ntStatus = IoCallDriver(deviceExtension->TopOfStackDeviceObject,
Irp);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“IoCallDriver fails with status %X\n”, ntStatus));

//
// if the device was yanked out, then the pipeInformation
// field is invalid.
// similarly if the request was cancelled, then we need not
// invoked reset pipe/device.
//
if((ntStatus != STATUS_CANCELLED) &&
(ntStatus != STATUS_DEVICE_NOT_CONNECTED)) {

ntStatus = BulkUsb_ResetPipe(DeviceObject,
pipeInformation);

if(!NT_SUCCESS(ntStatus)) {

BulkUsb_DbgPrint(1, (“BulkUsb_ResetPipe failed\n”));

ntStatus = BulkUsb_ResetDevice(DeviceObject);
}
}
else {

BulkUsb_DbgPrint(3, ("ntStatus is STATUS_CANCELLED or "
“STATUS_DEVICE_NOT_CONNECTED\n”));
}
}

//
// we return STATUS_PENDING and not the status returned by the lower layer.
//
return STATUS_PENDING;

}

Mit freundlichen Gr??en / Best regards

Ravi Rathore
RBEI/EST2

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Tuesday, 29. March 2011 22:05
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] In KMDF USBSAMP Driver: ReadFILE API Hangs for Ever

Ravi Rathore (RBEI/EST2) wrote:

Problem Statement : My firmware is writing data at its own wish ,
which I have to read it through ReadFile in continuous while loop.

Remember that a USB device cannot send data on its own. It can only
send data when the host controller asks it to, and the host controller
will never ask it to send unless there is an outstanding request from a
driver. Does your device have enough buffering to hold the data until
your application is ready?

When readfile API is called from the application , In my driver code
the corresponding I/O callback is getting called (i.e
UsbSamp_EvtIoRead). From this point I am successfully able to call the
WdfRequestSend but corresponding WdfRequestSetCompletionRoutine is not
getting called as firmware has not written any thing so Bus driver
will not respond back to this completion call-back.

WdfRequestSetCompletionRoutine(Request, ReadWriteCompletion, NULL);
//
// Send the request asynchronously.
//
if(!WdfRequestSend(Request, WdfUsbTargetPipeGetIoTarget(pipe),
WDF_NO_SEND_OPTIONS)) {
UsbSamp_DbgPrint(1, (“WdfRequestSend for %s failed\n”,
operation));
status = WdfRequestGetStatus(Request);
goto End;
}

Please let me know what could be solution for it as I need to fit my
driver code into it somehow.

I can’t tell from this whether you have the specifications for your
device or not. You can’t guess at the specifications for a USB device.
You have to know what triggers data to be sent, how it will be sent,
what size the packets are, and so on.

What do you WANT to happen if the device has no data when you go to read it?

Have you called WdfUsbTrgetPipeFormatRequestForRead? You can’t just
forward an application “read” request down to the USB bus driver. USBD
only understands URBs, so you have to call an API to create a URB.


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


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


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


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


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

Ravi Rathore (RBEI/EST2) wrote:

Tim Roberts: “What do you WANT to happen if the device has no data when you go to read it?”
Ravi: My device is processing audio and application needs to depicts any changes in parameters. For example is User has pressed mute button on the device then it has to reflected in GUI. This is the one of reason GUI application continuously calling ReadFile.

  1. ReadFile API treated as success only if “It return True” AND “It has some bytes read”. If both are true then we do some processing in GUI other wise fail but neither case should hange.So if there is no data to be read from the device then ReadFile should succeed but byte read should be Zero. Current this got hanged.

Sure, and that’s generally what you want. You can solve this problem in
your application. Your problem occurs because you are doing synchronous
reads – you submit the read and wait for a result before moving on. If
you were to use asynchronous reads, you could submit the read and leave
it pending, then have a loop that checks for completion every second or
so. Your app doesn’t need to sit there doing nothing.

  1. When I changed my firmware code as to write every time(i.e in 1 second) some data (junk/test data ), then my driver ReadCompletion Routing is getting called and it works perfectly.

If you have data that occurs only occasionally, then a bulk pipe is a
horribly bad choice. You need to use an interrupt pipe for this. When
you send a bulk request and the device has no data, the host controller
retries that request CONTINUOUSLY, over and over and over and over and
over, until the read succeeds. That sucks up bandwidth and power. With
an interrupt pipe, the host controller will only ask your board for data
during your reserved time slot, and only once during that slot. That’s
why keyboards and mice use interrupt pipes.

Ravi : 1. Is it possible to have a time out value in “WdfRequestSend” so that once time-out happens the Completion Routine will be called and there I will treat this as success and complete the request with success and zero byte read ?

You can certainly set the timeout policy on the USB pipe. However, I
don’t think that’s necessary. You should think about your application’s
approach to the I/O.

  1. Could this be solved via KMDF continuous Reader ?

How would that possibly make it any better? If the device hasn’t sent
any data, the continuous reader cannot magically make data appear. No,
you just need to make your application handle the situation you have.

Ravi : One interesting thing what I found in that sample code(WDM /6000/bulkusb driver) is that BulkUsb_DispatchReadWrite always return STATUS_PENDING which I could not understand …

Many people have complained about issues in the bulkusb sample. That’s
partly why it does not exist any longer. Yes, I would argue that this
code is wrong. If the IoCallDriver returns something other than
success, the driver should be calling IoCompleteRequest, should not be
calling IoMarkPending, and should be returning the status it got from
IoCallDriver.


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