mohammed abuhijle | 1 Mar 2007 11:10
Picon

Re: Slow USB bulk transfer

Alright then, thanks for the explanation. I was using 512 because I thought I had to abide by the maxPacketsize of the endpoint I am using.

Now the second problem is that I get a zero as a return value from usb_bulk_write. It is still the same code but with changing the size value of usb_bulk_write to 1 MB instead of 512.

Looking at linux.c, this means that zero bytesdone have been returned and I wrote nothing to the device..!!

What could be going wrong. As you mentioned, bulk is synchronous, so it had to wait until something is written and then come back..I also have the timeout value as zero...which according to my understanding is ignored altogether if we doing bulk read/write...



On 2/28/07, Tim Roberts <timr <at> probo.com> wrote:
mohammed abuhijle wrote:
>
> I have the following code that takes more than a min to finisg:

That's right.


> /*write 40 Mbytes worth of data to the bulk endpoint*/
> /*i am calculating this by: 512 (packet size) * 2 = 1 KB, * 1000 =
> 1MB, * 40 = 40 MB*/
> for (i = 0; i < 2 * 1000 * 40 ; i++){
> ret = usb_bulk_write(cypress_dev_handle, epi,bytes, 512, 0 /*the
> timrout is ignored for bulk transfer*/);
> //printf ("i is:%d\t ret is %d\t bytes is %s\n",i, ret,bytes);
> }

Remember that USB is a "scheduled" bus.  The USB host controller has to
have a frame all planned out before the frame begins.  In your case, you
are sending exactly one packet down, which then gets scheduled into a
frame, and because usb_bulk_write is synchronous, you then wait until
the transfer is complete, thereby wasting the rest of the frame.  That
means you cannot do any better than one packet per frame, 512k bytes per
second, which would make 40MB take 80 seconds.

The USB subsystem will happily chop up a large transfer into
packet-sized pieces as needed, and when it does so, it will pack in as
many packets as it can into a single frame.  You can send megabytes to
usb_bulk_write, and get your 40MB transferred in a second or two.

--
Tim Roberts, timr <at> probo.com
Providenza & Boekelheide, Inc.


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Del Merritt | 1 Mar 2007 16:19
Picon
Favicon

Re: Slow USB bulk transfer

mohammed abuhijle wrote:
> Alright then, thanks for the explanation. I was using 512 because I 
> thought I had to abide by the maxPacketsize of the endpoint I am using.
>
> Now the second problem is that I get a zero as a return value from 
> usb_bulk_write. It is still the same code but with changing the size 
> value of usb_bulk_write to 1 MB instead of 512.

Well, in theory you can say, "here's 1MB; gopher it".  But in practice 
you probably don't want to do that.  First, it's possible Linux has a 
limit on the size of what it buffers.  More likely the device won't like 
something that big, since it too will have to deal with it.  When I 
write, I pick what I consider a "reasonable but still magic" number, 
like 32KB or 64KB.  This keeps the buffers manageable on my end and 
minimizes the likelihood of blowing away some (un)documented buffer 
limit on the device.  If you are using USB 2.0 and know the device well, 
you might want to pick a bigger chunk size, but 64KB (64*1024, not 
64*1000) is probably big enough for many apps to get good throughput and 
small enough to help you catch errors in a timely manner.

It's much like any other packet-driven system: the bigger the packet, 
the better the possible throughput, but the worse the error recovery - 
particularly if you can or have to retransmit the data.

There are other reasons you could be getting nowhere.  Is "epi" the 
input or output endpoint?  What do you see in /var/log/messages?    Do 
you have access to a USB analyzer?  It could be you are getting NAKed or 
STALLed. 

Finally, my read of linux.c's  usb_urb_transfer() suggests that you 
don't want a "0" timeout, since it will force a return before the urb is 
reaped.  I'd make the timeout at least several tens - if not a hundred 
or so - milliseconds.  That will give the kernel a chance to process the 
urb.  You may need to keep tinkering with the timeout and the buffer 
size to get the "best" performance.

-Del

> Looking at linux.c, this means that zero bytesdone have been returned 
> and I wrote nothing to the device..!!
>
> What could be going wrong. As you mentioned, bulk is synchronous, so 
> it had to wait until something is written and then come back..I also 
> have the timeout value as zero...which according to my understanding 
> is ignored altogether if we doing bulk read/write...
>
>
>
> On 2/28/07, *Tim Roberts* <timr <at> probo.com <mailto:timr <at> probo.com>> wrote:
>
>     mohammed abuhijle wrote:
>     >
>     > I have the following code that takes more than a min to finisg:
>
>     That's right.
>
>
>     > /*write 40 Mbytes worth of data to the bulk endpoint*/
>     > /*i am calculating this by: 512 (packet size) * 2 = 1 KB, * 1000 =
>     > 1MB, * 40 = 40 MB*/
>     > for (i = 0; i < 2 * 1000 * 40 ; i++){
>     > ret = usb_bulk_write(cypress_dev_handle, epi,bytes, 512, 0 /*the
>     > timrout is ignored for bulk transfer*/);
>     > //printf ("i is:%d\t ret is %d\t bytes is %s\n",i, ret,bytes);
>     > }
>
>     Remember that USB is a "scheduled" bus.  The USB host controller
>     has to
>     have a frame all planned out before the frame begins.  In your
>     case, you
>     are sending exactly one packet down, which then gets scheduled into a
>     frame, and because usb_bulk_write is synchronous, you then wait until
>     the transfer is complete, thereby wasting the rest of the frame.  That
>     means you cannot do any better than one packet per frame, 512k
>     bytes per
>     second, which would make 40MB take 80 seconds.
>
>     The USB subsystem will happily chop up a large transfer into
>     packet-sized pieces as needed, and when it does so, it will pack in as
>     many packets as it can into a single frame.  You can send
>     megabytes to
>     usb_bulk_write, and get your 40MB transferred in a second or two.
>
>     --
>     Tim Roberts, timr <at> probo.com <mailto:timr <at> probo.com>
>     Providenza & Boekelheide, Inc.
>
>
>     -------------------------------------------------------------------------
>
>     Take Surveys. Earn Cash. Influence the Future of IT
>     Join SourceForge.net's Techsay panel and you'll get the chance to
>     share your
>     opinions on IT & business topics through brief surveys-and earn cash
>     http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
>     <http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV>
>     _______________________________________________
>     Libusb-devel mailing list
>     Libusb-devel <at> lists.sourceforge.net
>     <mailto:Libusb-devel <at> lists.sourceforge.net>
>     https://lists.sourceforge.net/lists/listinfo/libusb-devel
>     <https://lists.sourceforge.net/lists/listinfo/libusb-devel>
>
>
> ------------------------------------------------------------------------
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys-and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> ------------------------------------------------------------------------
>
> _______________________________________________
> Libusb-devel mailing list
> Libusb-devel <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/libusb-devel
>   

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
charles_ic | 2 Mar 2007 10:51
Favicon

Re: usb_control_msg() timeout error


yes, its an oversight on my part. what I did is to use a USB packet sniffer
to see what is happening in windows and compare it with the commands in
linux.

I noticed this particular URB transfer after selecting configuration and
interface.:

5	out down	0x00	1.985	CLASS_INTERFACE	02 00 00 00 18 00 00 00	
URB Header (length: 80)
SequenceNumber: 5
Function: 001b (CLASS_INTERFACE)
PipeHandle: 00000000

SetupPacket:
0000: 00 00 00 00 00 00 00 00 
bmRequestType: 00
  DIR: Host-To-Device
  TYPE: Standard
  RECIPIENT: Device
bRequest: 00  
  GET_STATUS

TransferBuffer: 0x00000018 (24) length
0000: 02 00 00 00 18 00 00 00 02 00 00 00 01 00 00 00 
0010: 00 00 00 00 00 40 00 00 
5	out up	n/a	1.985	CONTROL_TRANSFER	-	0x00000000
URB Header (length: 80)
SequenceNumber: 5
Function: 0008 (CONTROL_TRANSFER)
PipeHandle: 82008a20

SetupPacket:
0000: 21 00 00 00 00 00 18 00 
bmRequestType: 21
  DIR: Host-To-Device
  TYPE: Class
  RECIPIENT: Interface
bRequest: 00  

No TransferBuffer

It looks like on windows, the host request status from the device first
before issuing a BULK or INTERRUPT transfer.(Sequence 6)

I'm not sure what is the equivalent command on the linux platform for the
GET_STATUS request.

Would anyone be able to tell me if this is correct:

status = usb_control_msg(dev, USB_TYPE_VENDOR | 0x80 | USB_RECIP_INTERFACE,
0, 1 ,0,(char *)&ptr, 64, 300);

Thanks!
charles_ic

Tim Roberts wrote:
> 
> charles_ic wrote:
>> This is the process i did:
>> ...
>> char ptr[64];
>> ...
>>
>> // when I try to retrieve status of the device to enable download...
>>
>> status = usb_control_msg(dev, USB_TYPE_VENDOR | 0x80 |
>> USB_RECIP_INTERFACE,
>> START_DL, 1 ,0,(char *)&ptr, 64, 300);
>>   
> 
> This says that the device has to send 64 bytes of response to the
> START_DL command.  Is that really how the device will respond?  In my
> experience, the command to start a download is usually an output command
> that doesn't return anything.
> 
> -- 
> Tim Roberts, timr <at> probo.com
> Providenza & Boekelheide, Inc.
> 
> 
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share
> your
> opinions on IT & business topics through brief surveys-and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> Libusb-devel mailing list
> Libusb-devel <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/libusb-devel
> 
> 

--

-- 
View this message in context: http://www.nabble.com/usb_control_msg%28%29-timeout-error-tf1885498.html#a9266802
Sent from the LibUSB Dev mailing list archive at Nabble.com.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Tim Roberts | 2 Mar 2007 20:58

Re: usb_control_msg() timeout error

charles_ic wrote:
> yes, its an oversight on my part. what I did is to use a USB packet sniffer
> to see what is happening in windows and compare it with the commands in
> linux.
>
> I noticed this particular URB transfer after selecting configuration and
> interface.:
>
> 5	out down	0x00	1.985	CLASS_INTERFACE	02 00 00 00 18 00 00 00	
> URB Header (length: 80)
> SequenceNumber: 5
> Function: 001b (CLASS_INTERFACE)
> PipeHandle: 00000000
>
> SetupPacket:
> 0000: 00 00 00 00 00 00 00 00 
> bmRequestType: 00
>   DIR: Host-To-Device
>   TYPE: Standard
>   RECIPIENT: Device
> bRequest: 00  
>   GET_STATUS
>
>
> TransferBuffer: 0x00000018 (24) length
> 0000: 02 00 00 00 18 00 00 00 02 00 00 00 01 00 00 00 
> 0010: 00 00 00 00 00 40 00 00 
>   

> 5	out up	n/a	1.985	CONTROL_TRANSFER	-	0x00000000
> URB Header (length: 80)
> SequenceNumber: 5
> Function: 0008 (CONTROL_TRANSFER)
> PipeHandle: 82008a20
>
> SetupPacket:
> 0000: 21 00 00 00 00 00 18 00 
> bmRequestType: 21
>   DIR: Host-To-Device
>   TYPE: Class
>   RECIPIENT: Interface
> bRequest: 00  
>
>
> No TransferBuffer
>
>
> It looks like on windows, the host request status from the device first
> before issuing a BULK or INTERRUPT transfer.(Sequence 6)
>   
> I'm not sure what is the equivalent command on the linux platform for the
> GET_STATUS request.
>   

GET_STATUS is not a Windows concept, it is a USB standard command. 
However, your sniffer is confused in some way, because the GET_STATUS
command is always sent as Device-to-Host, with a bmRequestType of 80. 
Plus, GET_STATUS is supposed to return 2 bytes, but the setup packet
shows it asking for 0.  Further, the setup packet for the second half of
the transaction shows a wLength of 0x18, but the sniffer shows the
transfer buffer with the first half.

I'm guessing the GET_STATUS command never really happened.

> Would anyone be able to tell me if this is correct:
>
> status = usb_control_msg(dev, USB_TYPE_VENDOR | 0x80 | USB_RECIP_INTERFACE,
> 0, 1 ,0,(char *)&ptr, 64, 300);
>   

Absolutely not.  You are setting bmRequestType to C1 (device-to-host,
vendor, interface) instead of 21 (host-to-device, class, interface), and
you're trying to transfer 64 bytes when nothing in the long shows a
64-byte transfer.

More like this, I should think, if the sniffer is close to correct:

  unsigned long data[] = { 2, 24, 2, 1, 0, 0x400 };
  status = usb_control_msg( dev, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
    0, 0, 0, (char*)data, sizeof(data), 300 );

--

-- 
Tim Roberts, timr <at> probo.com
Providenza & Boekelheide, Inc.

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Wael Adel | 3 Mar 2007 08:58
Picon

stange devices detected?

hi all,


i have installed libusb on my labtop.

the strange thing that when i run the simple test program which is
libusbtest.c in the folder of tests i got the following output:
 
 
    Dev#1 OHCI Hsost controller
    Dev#2 Broadcom Corp - Acer Module
    Dev#1 OHCI Host controller
    Dev#1 EHCI Host controller
    Dev#3 USB20 Camera
 
Although i did not connect any device to any of my usb ports.
Does anyone know how can this happen?
or how can i use theses devices to transfer data from my labtop to another computer.

i m using SUSE 10.2 distro.

thanks in advance.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Wael Adel | 3 Mar 2007 09:42
Picon

usb concepts.

hi all,
i have read some documents about usb concepts and how it works but really i have a question:
 
Isochronous and interrupt endpoints reserve a
fixed amount of bandwidth in the USB frame as soon as they are configured.right?
 
i have read this in one of the mailing list threads: 
 
If there are already too many reservations, the device will not be allowed
to configure. So, a device is required to have an alternate setting 0
in which none of the isoch and interrupt endpoints get any bandwidth 
and at least one other alternate setting with bandwidth.
 
if this mean that to make my device work in case of many reservations ,
i should make it alternate setting 0 so that the interrupt and isochronous endpoints will not reserve any part from the usb bandwidth?
so why at least one other alternate setting with bandwidth is required?
 
thanks in advance.
  
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Wael Adel | 3 Mar 2007 09:48
Picon

Isochronous , interrupt , bulk transfers?

hi all,
i have one question:
 
to transfer data through  device i use usb_write_interrupt  in case of interrupt
to transfer data through  device i use usb_write_bulk       in case of bulk
 but isnt Isochronous case is implemented in libusb?
i mean if i have a stream of data i want to transfer what  API should i use?
 
thanks in advance
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Wael Adel | 3 Mar 2007 10:12
Picon

usb_control_msg before usb_write_bulk is a must?

hi all,
i want to know if
i MUST use
usb_control_msg
before using
usb_write_bulk
or not?
 
thanks in advance .
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Timo Juhani Lindfors | 3 Mar 2007 17:14
Picon
Picon
Favicon
Gravatar

Re: Isochronous , interrupt , bulk transfers?

Hi,

On Sat, Mar 03, 2007 at 10:48:17AM +0200, Wael Adel wrote:
> to transfer data through  device i use usb_write_bulk       in case of bulk
> but isnt Isochronous case is implemented in libusb?

http://iki.fi/lindi/usb/libusb_augment.c
http://iki.fi/lindi/usb/libusb_augment.h

has a partial linux-only implementation of isochronous transfers for
libusb 0.x. You can use them without recompiling any libraries. Just
#include "libusb_augment.h" and link libusb_augment.c against your
program.

Libusb 1.0 and openusb probably do/will support isochronous transfers
but I haven't followed them closely.

best regars,
Timo Lindfors

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Wael Adel | 3 Mar 2007 19:16
Picon

Re: Isochronous , interrupt , bulk transfers?


thanks for your help
but may i ask how can i distinguish between transmitting ischronous tranfers
and receiving ischronous tranfers?
 
On 3/3/07, Timo Juhani Lindfors <timo.lindfors <at> iki.fi > wrote:
Hi,

On Sat, Mar 03, 2007 at 10:48:17AM +0200, Wael Adel wrote:
> to transfer data through  device i use usb_write_bulk       in case of bulk
> but isnt Isochronous case is implemented in libusb?

http://iki.fi/lindi/usb/libusb_augment.c
http://iki.fi/lindi/usb/libusb_augment.h

has a partial linux-only implementation of isochronous transfers for
libusb 0.x. You can use them without recompiling any libraries. Just
#include "libusb_augment.h" and link libusb_augment.c against your
program.

Libusb 1.0 and openusb probably do/will support isochronous transfers
but I haven't followed them closely.

best regars,
Timo Lindfors

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Libusb-devel mailing list
Libusb-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusb-devel

Gmane