Questions on multiple URB's

Hello Gurus,

I am new to USB drivers, i had developed drivers for a PCI card before.
So new to USB framework.

I have a streaming USB device which outputs MPEG data on a bulk endpoint of 564 bytes/transaction. I am trying to read the data on bulk endpoint and send it to udp port to play it on VLC player.

I want to know what is and how does multiple URB’s work?

Any suggestions, information or references regarding multiple URB’s or developing drivers for USB devices will be appreciated.

Thanks,
Mahi

xxxxx@gmail.com wrote:

I am new to USB drivers, i had developed drivers for a PCI card before.
So new to USB framework.

I have a streaming USB device which outputs MPEG data on a bulk endpoint of 564 bytes/transaction. I am trying to read the data on bulk endpoint and send it to udp port to play it on VLC player.

I want to know what is and how does multiple URB’s work?

I’m not sure what you’re asking. To submit multiple URBs, you just do
it. Create a set of URBs and submit them. The key is that you don’t
wait for each one to complete. Submit them in a bunch, and set a
completion routine so that you can send it on.

Are you expecting the kernel driver to transmit over a UDP port? That’s
a bad design. I would have expected you to create a real capture
driver, so that it could participate in arbitrary DirectShow graphs.

Do you really get 564 bytes per request, or is it a continuous data
stream that happens to occur in 564 byte chunks? Here’s the reason I
ask. Your bulk endpoint has a maximum packet size of 512 bytes. So,
will you get a packet of 512 bytes, then a packet of 52 bytes? Or will
you get a continuous set of 512 byte packets, and then it’s up to you to
find the MPEG transport stream chunk boundaries?

If you really get 512 then 52, that means you can’t submit a single
large URB. The request will be terminated as soon as there is a short
packet.


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

Thanks for your reply Guru Tim, :slight_smile:

I’m not sure what you’re asking. To submit multiple URBs, you just do
it. Create a set of URBs and submit them. The key is that you don’t
wait for each one to complete. Submit them in a bunch, and set a
completion routine so that you can send it on.

Right now am developing a driver from DDK’s bulk USB driver sample,
am creating 8 work items, each work item will create a URB for 564 bytes and sends it down to USB host. From Completion routine am streaming data on to UDP port.
I know this not an optimal solution and was looking for some tips in this board and saw the topic of multiple URB’s and am not sure how to use and would like to explore more on it.

Are you expecting the kernel driver to transmit over a UDP port? That’s
a bad design. I would have expected you to create a real capture
driver, so that it could participate in arbitrary DirectShow graphs.

That will be my end solution, right now i chose to stream on UDP port so that i can test my USB driver. Once i understand its working then i will move it on to capture the data. Since am new to USB drivers i would like to get the basics right.

Do you really get 564 bytes per request, or is it a continuous data
stream that happens to occur in 564 byte chunks? Here’s the reason I
ask. Your bulk endpoint has a maximum packet size of 512 bytes. So,
will you get a packet of 512 bytes, then a packet of 52 bytes? Or will
you get a continuous set of 512 byte packets, and then it’s up to you to
find the MPEG transport stream chunk boundaries?

Yes, its a continuous data stream that happens to occur in 564 byte chunks.

If you really get 512 then 52, that means you can’t submit a single
large URB. The request will be terminated as soon as there is a short
packet.

Thanks,
Mahi

Mahendra Kondur wrote:

Right now am developing a driver from DDK’s bulk USB driver
sample, am creating 8 work items, each work item will create
a URB for 564 bytes and sends it down to USB host. From
Completion routine am streaming data on to UDP port.

The work items are not necessary. Just submit all eight URBs from your driver’s start path. You can resubmit them in the completion routine.

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, May 14, 2008 2:54 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Questions on multiple URB’s

Right now am developing a driver from DDK’s bulk USB driver sample,

Not a good idea. BulkUsb sample is obsolete and rather bad. Instead, use
WDF. Both KMDF or UMDF drivers should be much easier to write for you
especially if you’re just starting.

am creating 8 work items, each work item will create a URB
for 564 bytes and sends it down to USB host.

Again, not a good idea. Work items are processed in context of system
threads create for this purpose and shouldn’t be overused. Their main
purpose is to postpone processing to point when IRQL drops down to
PASSIVE_LEVEL. There is (or at least was) limited number of system
threads processing workitems and if you use them this way, you can block
other drivers.

You should create own thread for URB processing or process them directly
in completion routine. Thread can be an advantage in your case if you
want to send data to network.

That will be my end solution, right now i chose to stream on
UDP port so that i can test my USB driver. Once i understand
its working then i will move it on to capture the data. Since
am new to USB drivers i would like to get the basics right.

The fastest way how to get basics right is to use WDF.

Yes, its a continuous data stream that happens to occur in
564 byte chunks.

That’s really strange. What is your bulk-in endpoint size?

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

xxxxx@gmail.com wrote:

Right now am developing a driver from DDK’s bulk USB driver sample,
am creating 8 work items, each work item will create a URB for 564 bytes and sends it down to USB host. From Completion routine am streaming data on to UDP port.

Why would you create work items? Just create and submit the URBs in a
“for” loop.

> Are you expecting the kernel driver to transmit over a UDP port? That’s
> a bad design. I would have expected you to create a real capture
> driver, so that it could participate in arbitrary DirectShow graphs.
>

That will be my end solution, right now i chose to stream on UDP port so that i can test my USB driver. Once i understand its working then i will move it on to capture the data. Since am new to USB drivers i would like to get the basics right.

The USB part is the easy part…

Yes, its a continuous data stream that happens to occur in 564 byte chunks.

In that case, you definitely do NOT want to submit 564-byte URBs. There
is no buffering anywhere in the USB path. If you submit a 564-byte URB,
the host controller driver will chop it up into a 512-byte piece and a
52-byte piece. If your device sends a continuous stream of 512-byte
packets, then the second request will fail with a condition called
“babble”. The device is never told how large the read request is. It
is merely given an opportunity to transmit. If the host controller
allocates room in the frame for 52 bytes, but your device sends 512,
that’s a protocol violation.


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

Thanks guys,

I will try your suggestions today and will let you guys know how it worked.

Michal,

My Bulk endpoint size is 564 bytes.

Thanks,
Mahi

If UDP is not the final solution, I would not even bother starting with it. It is going to be more complicated then what you want to do in the end. If you want to just stream the data somewhere, define a set of IOCTLs and have an app read the data.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@gmail.com
Sent: Wednesday, May 14, 2008 10:12 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Questions on multiple URB’s

Thanks guys,

I will try your suggestions today and will let you guys know how it worked.

Michal,

My Bulk endpoint size is 564 bytes.

Thanks,
Mahi


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

> -----Original Message-----

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@gmail.com
Sent: Wednesday, May 14, 2008 7:12 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Questions on multiple URB’s

My Bulk endpoint size is 564 bytes.

Sorry, that’s impossible. Maximum bulk endpoint size for high speed
device is 512 bytes according to USB 2.0 specification.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]

xxxxx@gmail.com wrote:

Thanks guys,

I will try your suggestions today and will let you guys know how it worked.

Michal,

My Bulk endpoint size is 564 bytes.

No, it’s not. That’s illegal. A bulk endpoint max packet size is 512
bytes. Always.


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

Tim, Michal

Sorry for my wrong information. Bulk endpoint max size is 512 Bytes. am sending 564 bytes buffer in the URB so as Tim said earlier Host driver is splitting it for me.

now i have small doubt…
Which is optimal, Sending a large buffer of non-multiple of 512 in my case 564 bytes to host and let host bother of spliting or Client split the buffer with 512 bytes?

Mahi

xxxxx@gmail.com wrote:

Sorry for my wrong information. Bulk endpoint max size is 512 Bytes. am sending 564 bytes buffer in the URB so as Tim said earlier Host driver is splitting it for me.

now i have small doubt…
Which is optimal, Sending a large buffer of non-multiple of 512 in my case 564 bytes to host and let host bother of spliting or Client split the buffer with 512 bytes?

This isn’t really the right question to ask. I thought I asked this
before, but perhaps it wasn’t clear.

There are two ways that your device could send its 564 byte buffers.
Note here that I am talking about the DEVICE, not about your driver.
The device doesn’t *know* how much data your driver is requesting.
That’s not how USB works. The device is just told “transmit now”, and
the DEVICE decides how the data will be sent.

One way would be as alternating packets of 512 and 52:
pkt 0: 512 bytes
pkt 1: 52 bytes, first buffer complete
pkt 2: 512 bytes
pkt 3: 52 bytes, second buffer complete
etc.

The other way would be as a steady stream:
pkt 0: 512 bytes (start of first buffer)
pkt 1: 512 bytes (last 52 bytes of first buffer, first 460 of second
buffer)
pkt 2: 512 bytes (last 104 of second buffer, first 408 of third buffer)
pkt 3: 512 bytes (last 156 of third buffer, first 356 of fourth buffer)

The difference is CRITICALLY important. If the device uses the first
method, then you must submit multiple URBs of 564 bytes. You could try
to submit a larger URB, but the transfer would terminate as soon as the
short packet arrived. Anything less than the maximum packet size
terminates a USB transfer.

If the device uses the second method, as I suspect it does, then you
CANNOT use URBs of 564 bytes. You MUST use URBs that are a multiple of
512 bytes, and divide them into 564-byte buffers in your driver. If you
do not use a multiple of 512, you will get the
USBD_STATUS_BABBLE_DETECTED error.


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