Re: USB 2.0 device has 8ms latency

2015-10-22 Thread John Tapsell
On 22 October 2015 at 18:00, Greg KH  wrote:
> On Thu, Oct 22, 2015 at 05:15:50PM +0100, John Tapsell wrote:
>> On 15 October 2015 at 15:37, Alan Stern  wrote:
>> > On Thu, 15 Oct 2015, John Tapsell wrote:
>> >
>> >> I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
>> >> it at all possible that there's a bug in the linux usb code where a
>> >> bInterval value of 1ms is being converted into microframes (8
>> >> microframes)  but then because it's a full speed device it's then
>> >> incorrectly read as an 8ms delay?  I did have a look into the code,
>> >> but got thoroughly lost.  Any pointers on how I could check my wacky
>> >> theory?
>> >
>> > There is no such bug.  Such a thing would have been spotted long, long
>> > ago.
>> >
>> >> I'm just wondering where this 8ms delay comes from.
>> >
>> > Multiple places: time to submit the request, time to reserve
>> > bandwidth for the previously unused interrupt endpoint, time to
>> > complete the transfer, all multiplied by 2.
>> >
>> > You can get more information from usbmon (see
>> > Documentation/usb/usbmon.txt in the kernel source).  But Greg is right;
>> > the protocol you described is terrible.  There's no need for a multiple
>> > ping-pong interchange like that; all you should need to do is wait for
>> > the device to send the next bit (or whatever) of data as soon as it
>> > becomes available.
>> >
>> > Alan Stern
>>
>>
>> I had a look at the windows driver, and found that it is implemented
>> in pretty much exactly the same way as the linux driver, but it
>> operates at twice the speed.  And that's for a user-space USB driver.
>>
>> Any ideas why?
>
> "pretty much"?  What exactly is the difference?

Well, just that one uses the windows API and one uses the linux API :-)

>  And you should be able
> to try out a userspace driver in Linux as well, libusb works on Windows
> and Linux so you can do a good comparison.

Interesting - I'll give it a try, thanks.

John
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-22 Thread Alan Stern
On Thu, 22 Oct 2015, John Tapsell wrote:

> I had a look at the windows driver, and found that it is implemented
> in pretty much exactly the same way as the linux driver, but it
> operates at twice the speed.  And that's for a user-space USB driver.
> 
> Any ideas why?

Windows and Linux allocate bandwidth for interrupt endpoints at 
different times.  The scheme Windows uses involves less overhead, but 
it also makes less total bandwidth available.

I don't know if that's the reason for the difference, but it might be.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-22 Thread John Tapsell
On 15 October 2015 at 15:37, Alan Stern  wrote:
> On Thu, 15 Oct 2015, John Tapsell wrote:
>
>> I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
>> it at all possible that there's a bug in the linux usb code where a
>> bInterval value of 1ms is being converted into microframes (8
>> microframes)  but then because it's a full speed device it's then
>> incorrectly read as an 8ms delay?  I did have a look into the code,
>> but got thoroughly lost.  Any pointers on how I could check my wacky
>> theory?
>
> There is no such bug.  Such a thing would have been spotted long, long
> ago.
>
>> I'm just wondering where this 8ms delay comes from.
>
> Multiple places: time to submit the request, time to reserve
> bandwidth for the previously unused interrupt endpoint, time to
> complete the transfer, all multiplied by 2.
>
> You can get more information from usbmon (see
> Documentation/usb/usbmon.txt in the kernel source).  But Greg is right;
> the protocol you described is terrible.  There's no need for a multiple
> ping-pong interchange like that; all you should need to do is wait for
> the device to send the next bit (or whatever) of data as soon as it
> becomes available.
>
> Alan Stern


I had a look at the windows driver, and found that it is implemented
in pretty much exactly the same way as the linux driver, but it
operates at twice the speed.  And that's for a user-space USB driver.

Any ideas why?

Thanks,

John Tapsell
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-22 Thread Greg KH
On Thu, Oct 22, 2015 at 05:15:50PM +0100, John Tapsell wrote:
> On 15 October 2015 at 15:37, Alan Stern  wrote:
> > On Thu, 15 Oct 2015, John Tapsell wrote:
> >
> >> I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
> >> it at all possible that there's a bug in the linux usb code where a
> >> bInterval value of 1ms is being converted into microframes (8
> >> microframes)  but then because it's a full speed device it's then
> >> incorrectly read as an 8ms delay?  I did have a look into the code,
> >> but got thoroughly lost.  Any pointers on how I could check my wacky
> >> theory?
> >
> > There is no such bug.  Such a thing would have been spotted long, long
> > ago.
> >
> >> I'm just wondering where this 8ms delay comes from.
> >
> > Multiple places: time to submit the request, time to reserve
> > bandwidth for the previously unused interrupt endpoint, time to
> > complete the transfer, all multiplied by 2.
> >
> > You can get more information from usbmon (see
> > Documentation/usb/usbmon.txt in the kernel source).  But Greg is right;
> > the protocol you described is terrible.  There's no need for a multiple
> > ping-pong interchange like that; all you should need to do is wait for
> > the device to send the next bit (or whatever) of data as soon as it
> > becomes available.
> >
> > Alan Stern
> 
> 
> I had a look at the windows driver, and found that it is implemented
> in pretty much exactly the same way as the linux driver, but it
> operates at twice the speed.  And that's for a user-space USB driver.
> 
> Any ideas why?

"pretty much"?  What exactly is the difference?  And you should be able
to try out a userspace driver in Linux as well, libusb works on Windows
and Linux so you can do a good comparison.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


USB 2.0 device has 8ms latency

2015-10-15 Thread John Tapsell
Hi,

  I'm working on a linux driver for a usb to i2c chip (the MCP2221).
The USB chip is USB 2.0  Full Speed, and the driver that I'm working
on is here:

http://ww1.microchip.com/downloads/en/DeviceDoc/mcp2221_0_1.tar.gz

  The driver uses HID Interrupt for communication, and both the in and
out endpoints have a bInterval of 1.

  The problem is that the following function (from the above .tar.gz)
takes 8ms to complete, when I'm expecting 1 or 2ms maximum. It simply
sends a USB packet, then gets the reply.


static int mcp2221_ll_cmd(struct i2c_mcp2221 *dev)
{
   int rv;

   /* tell everybody to leave the URB alone */
   dev->ongoing_usb_ll_op = 1;

   /* submit the interrupt out ep packet */
   if (usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL)) {
   dev_err(>interface->dev,
   "mcp2221(ll): usb_submit_urb intr out failed\n");
   dev->ongoing_usb_ll_op = 0;
   return -EIO;
   }

   /* wait for its completion */
   rv = wait_event_interruptible(dev->usb_urb_completion_wait,
   (!dev->ongoing_usb_ll_op));
   if (rv < 0) {
   dev_err(>interface->dev, "mcp2221(ll): wait interrupted\n");
   goto ll_exit_clear_flag;
   }

   /* tell everybody to leave the URB alone */
   dev->ongoing_usb_ll_op = 1;

   /* submit the interrupt in ep packet */
   if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL)) {
   dev_err(>interface->dev, "mcp2221(ll):
usb_submit_urb intr in failed\n");
   dev->ongoing_usb_ll_op = 0;
   return -EIO;
   }

   /* wait for its completion */
   rv = wait_event_interruptible(dev->usb_urb_completion_wait,
   (!dev->ongoing_usb_ll_op));
   if (rv < 0) {
   dev_err(>interface->dev, "mcp2221(ll): wait interrupted\n");
   goto ll_exit_clear_flag;
   }

ll_exit_clear_flag:
   dev->ongoing_usb_ll_op = 0;
   return rv;
}

(Please let me know what information to provide.  I have oscilloscope
outputs, lsusb outputs, more information about mcp2221, etc.  I just
didn't want to make this a huge dump of irrelevant information)

John Tapsell
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread Alan Stern
On Thu, 15 Oct 2015, John Tapsell wrote:

> I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
> it at all possible that there's a bug in the linux usb code where a
> bInterval value of 1ms is being converted into microframes (8
> microframes)  but then because it's a full speed device it's then
> incorrectly read as an 8ms delay?  I did have a look into the code,
> but got thoroughly lost.  Any pointers on how I could check my wacky
> theory?

There is no such bug.  Such a thing would have been spotted long, long
ago.

> I'm just wondering where this 8ms delay comes from.

Multiple places: time to submit the request, time to reserve 
bandwidth for the previously unused interrupt endpoint, time to 
complete the transfer, all multiplied by 2.

You can get more information from usbmon (see
Documentation/usb/usbmon.txt in the kernel source).  But Greg is right;  
the protocol you described is terrible.  There's no need for a multiple
ping-pong interchange like that; all you should need to do is wait for
the device to send the next bit (or whatever) of data as soon as it
becomes available.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread John Tapsell
On 15 October 2015 at 15:37, Alan Stern  wrote:
> On Thu, 15 Oct 2015, John Tapsell wrote:
>
>> I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
>> it at all possible that there's a bug in the linux usb code where a
>> bInterval value of 1ms is being converted into microframes (8
>> microframes)  but then because it's a full speed device it's then
>> incorrectly read as an 8ms delay?  I did have a look into the code,
>> but got thoroughly lost.  Any pointers on how I could check my wacky
>> theory?
>
> There is no such bug.  Such a thing would have been spotted long, long
> ago.
>
>> I'm just wondering where this 8ms delay comes from.
>
> Multiple places: time to submit the request, time to reserve
> bandwidth for the previously unused interrupt endpoint, time to
> complete the transfer, all multiplied by 2.
>
> You can get more information from usbmon (see
> Documentation/usb/usbmon.txt in the kernel source).  But Greg is right;
> the protocol you described is terrible.  There's no need for a multiple
> ping-pong interchange like that; all you should need to do is wait for
> the device to send the next bit (or whatever) of data as soon as it
> becomes available.

Thanks.  FWIW, the datasheet is here:
http://ww1.microchip.com/downloads/en/DeviceDoc/20005292B.pdf

I don't see any way around this awful protocol.

Time to change chips :)

John Tapsell
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread John Tapsell
Hi Greg,

  I'm trying to write a driver for this specific usb-to-i2c chip
(mcp2221).  It only offers an In and Out Interrupt Endpoint.  To do a
single i2c read I need to:

1. Send a packet saying "I want to read from i2c"
2. Wait for a reply saying 'okay'.
3. Send another packet saying "Please now send me the data that you read"
4. Wait for that reply.

This means a delay of 2x8ms = 16ms  to get a single bit of data.  For
the specific case that I want to use the chip for, this means I'm
reading from my i2c sensor at 62 hz.  I'd really like to do better if
it at all possible.

Any suggestions?

Thanks,

John

On 15 October 2015 at 14:46, Greg KH  wrote:
> On Thu, Oct 15, 2015 at 12:05:52PM +0100, John Tapsell wrote:
>> Hi,
>>
>>   I'm working on a linux driver for a usb to i2c chip (the MCP2221).
>> The USB chip is USB 2.0  Full Speed, and the driver that I'm working
>> on is here:
>>
>> http://ww1.microchip.com/downloads/en/DeviceDoc/mcp2221_0_1.tar.gz
>>
>>   The driver uses HID Interrupt for communication, and both the in and
>> out endpoints have a bInterval of 1.
>>
>>   The problem is that the following function (from the above .tar.gz)
>> takes 8ms to complete, when I'm expecting 1 or 2ms maximum. It simply
>> sends a USB packet, then gets the reply.
>>
>>
>> static int mcp2221_ll_cmd(struct i2c_mcp2221 *dev)
>> {
>>int rv;
>>
>>/* tell everybody to leave the URB alone */
>>dev->ongoing_usb_ll_op = 1;
>>
>>/* submit the interrupt out ep packet */
>>if (usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL)) {
>>dev_err(>interface->dev,
>>"mcp2221(ll): usb_submit_urb intr out 
>> failed\n");
>>dev->ongoing_usb_ll_op = 0;
>>return -EIO;
>>}
>>
>>/* wait for its completion */
>>rv = wait_event_interruptible(dev->usb_urb_completion_wait,
>>(!dev->ongoing_usb_ll_op));
>>if (rv < 0) {
>>dev_err(>interface->dev, "mcp2221(ll): wait 
>> interrupted\n");
>>goto ll_exit_clear_flag;
>>}
>>
>>/* tell everybody to leave the URB alone */
>>dev->ongoing_usb_ll_op = 1;
>>
>>/* submit the interrupt in ep packet */
>>if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL)) {
>>dev_err(>interface->dev, "mcp2221(ll):
>> usb_submit_urb intr in failed\n");
>>dev->ongoing_usb_ll_op = 0;
>>return -EIO;
>>}
>>
>>/* wait for its completion */
>>rv = wait_event_interruptible(dev->usb_urb_completion_wait,
>>(!dev->ongoing_usb_ll_op));
>>if (rv < 0) {
>>dev_err(>interface->dev, "mcp2221(ll): wait 
>> interrupted\n");
>>goto ll_exit_clear_flag;
>>}
>>
>> ll_exit_clear_flag:
>>dev->ongoing_usb_ll_op = 0;
>>return rv;
>> }
>>
>> (Please let me know what information to provide.  I have oscilloscope
>> outputs, lsusb outputs, more information about mcp2221, etc.  I just
>> didn't want to make this a huge dump of irrelevant information)
>
> I don't see anything wrong here, USB isn't guaranteed to have any
> specific latency, what you are doing here is the worst-possible-case for
> a USB system (i.e. send a packet, wait for it to complete, send another
> one, etc.)  There are lots of ways to get much better throughput if that
> is what you are wanting to do.
>
> In fact, what exactly are you trying to do?
>
> thanks,
>
> greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread John Tapsell
On 15 October 2015 at 15:00, Greg KH  wrote:
> A: No.
> Q: Should I include quotations after my reply?
>
> http://daringfireball.net/2007/07/on_top
>
> On Thu, Oct 15, 2015 at 02:56:48PM +0100, John Tapsell wrote:
>> Hi Greg,
>>
>>   I'm trying to write a driver for this specific usb-to-i2c chip
>> (mcp2221).  It only offers an In and Out Interrupt Endpoint.  To do a
>> single i2c read I need to:
>>
>> 1. Send a packet saying "I want to read from i2c"
>> 2. Wait for a reply saying 'okay'.
>> 3. Send another packet saying "Please now send me the data that you read"
>> 4. Wait for that reply.
>>
>> This means a delay of 2x8ms = 16ms  to get a single bit of data.  For
>> the specific case that I want to use the chip for, this means I'm
>> reading from my i2c sensor at 62 hz.  I'd really like to do better if
>> it at all possible.
>>
>> Any suggestions?
>
> For a horrid protocol like this, no, there isn't any way to make it go
> faster, sorry.  That is designed in such a way to make it the worst
> possible thing for a USB system, go kick the person who designed such a
> thing (hint, they have no idea how USB works...)
>
> I strongly suggest going and getting a different sensor chip, don't
> encourage such behaviour by actually buying their hardware.
>
> sorry,
>
> greg k-h

Thank you very much.

I did have one wacky idea.  I'm sure it's stupid, but here it is:  Is
it at all possible that there's a bug in the linux usb code where a
bInterval value of 1ms is being converted into microframes (8
microframes)  but then because it's a full speed device it's then
incorrectly read as an 8ms delay?  I did have a look into the code,
but got thoroughly lost.  Any pointers on how I could check my wacky
theory?

I'm just wondering where this 8ms delay comes from.

Thanks,

John
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread Greg KH
A: No.
Q: Should I include quotations after my reply?

http://daringfireball.net/2007/07/on_top

On Thu, Oct 15, 2015 at 02:56:48PM +0100, John Tapsell wrote:
> Hi Greg,
> 
>   I'm trying to write a driver for this specific usb-to-i2c chip
> (mcp2221).  It only offers an In and Out Interrupt Endpoint.  To do a
> single i2c read I need to:
> 
> 1. Send a packet saying "I want to read from i2c"
> 2. Wait for a reply saying 'okay'.
> 3. Send another packet saying "Please now send me the data that you read"
> 4. Wait for that reply.
> 
> This means a delay of 2x8ms = 16ms  to get a single bit of data.  For
> the specific case that I want to use the chip for, this means I'm
> reading from my i2c sensor at 62 hz.  I'd really like to do better if
> it at all possible.
> 
> Any suggestions?

For a horrid protocol like this, no, there isn't any way to make it go
faster, sorry.  That is designed in such a way to make it the worst
possible thing for a USB system, go kick the person who designed such a
thing (hint, they have no idea how USB works...)

I strongly suggest going and getting a different sensor chip, don't
encourage such behaviour by actually buying their hardware.

sorry,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: USB 2.0 device has 8ms latency

2015-10-15 Thread Greg KH
On Thu, Oct 15, 2015 at 12:05:52PM +0100, John Tapsell wrote:
> Hi,
> 
>   I'm working on a linux driver for a usb to i2c chip (the MCP2221).
> The USB chip is USB 2.0  Full Speed, and the driver that I'm working
> on is here:
> 
> http://ww1.microchip.com/downloads/en/DeviceDoc/mcp2221_0_1.tar.gz
> 
>   The driver uses HID Interrupt for communication, and both the in and
> out endpoints have a bInterval of 1.
> 
>   The problem is that the following function (from the above .tar.gz)
> takes 8ms to complete, when I'm expecting 1 or 2ms maximum. It simply
> sends a USB packet, then gets the reply.
> 
> 
> static int mcp2221_ll_cmd(struct i2c_mcp2221 *dev)
> {
>int rv;
> 
>/* tell everybody to leave the URB alone */
>dev->ongoing_usb_ll_op = 1;
> 
>/* submit the interrupt out ep packet */
>if (usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL)) {
>dev_err(>interface->dev,
>"mcp2221(ll): usb_submit_urb intr out 
> failed\n");
>dev->ongoing_usb_ll_op = 0;
>return -EIO;
>}
> 
>/* wait for its completion */
>rv = wait_event_interruptible(dev->usb_urb_completion_wait,
>(!dev->ongoing_usb_ll_op));
>if (rv < 0) {
>dev_err(>interface->dev, "mcp2221(ll): wait 
> interrupted\n");
>goto ll_exit_clear_flag;
>}
> 
>/* tell everybody to leave the URB alone */
>dev->ongoing_usb_ll_op = 1;
> 
>/* submit the interrupt in ep packet */
>if (usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL)) {
>dev_err(>interface->dev, "mcp2221(ll):
> usb_submit_urb intr in failed\n");
>dev->ongoing_usb_ll_op = 0;
>return -EIO;
>}
> 
>/* wait for its completion */
>rv = wait_event_interruptible(dev->usb_urb_completion_wait,
>(!dev->ongoing_usb_ll_op));
>if (rv < 0) {
>dev_err(>interface->dev, "mcp2221(ll): wait 
> interrupted\n");
>goto ll_exit_clear_flag;
>}
> 
> ll_exit_clear_flag:
>dev->ongoing_usb_ll_op = 0;
>return rv;
> }
> 
> (Please let me know what information to provide.  I have oscilloscope
> outputs, lsusb outputs, more information about mcp2221, etc.  I just
> didn't want to make this a huge dump of irrelevant information)

I don't see anything wrong here, USB isn't guaranteed to have any
specific latency, what you are doing here is the worst-possible-case for
a USB system (i.e. send a packet, wait for it to complete, send another
one, etc.)  There are lots of ways to get much better throughput if that
is what you are wanting to do.

In fact, what exactly are you trying to do?

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html