Doug Alcorn wrote:
> Here's what I think I know about using interrupt endpoints.  You
> create a urb with a completion handler.  You fill in the urb with a
> data transfer buffer the size of the endpoint's wMaxPacketSize and the
> interval set to endpoint->bInterval.  Then you submit this urb.  What

True on 2.4, and almost so on 2.5, at least for full speed.  For high
speed, notice that fill_int_urb() translates bInterval to microframes
by using (1 << (bInterval - 1)) per the USB 2.0 spec.

The "almost" on 2.5 is that this relates to something I still expect
will change before 2.5 finishes.  Specifically, the wMaxPacket size
limitation ... if you're sending (or receiving) 97 byte events, then
the HCD should map that to N packets, one per interval, instead of
device drivers.  In 2.5.37 the EHCI and OHCI drivers are ready to do
that (nyet UHCI) but usb_submit_urb() still enforces that old limit.

On 2.5 good practice may involve using usb_buffer_alloc() too, since
that's a way to reduce IOMMU costs of handling interrupts.  (PC level
platforms don't have IOMMUs.)


> happens is that every bInterval milliseconds, the usb-core does a read
> on the interrupt endpoint.  If something's read, your completion
> handler gets called.  Then, kindly enough your urb keeps getting
> resubmitted every bInterval milliseconds until you unlink the urb.

Again, subject to change in 2.5 ... that "automagic" mode masks some
errors, and interferes with queueing interrupt urbs.  But true for
2.4 and, right now, 2.5 -- yes.  (Again, I still expect this to be
fixed in the 2.5 tree.  Other than the UHCI updates, this is easy.)

You want URB queueing even at usb 1.1 speed, bInterval == 1, since
otherwise you can't realistically meet the transfer interval guarantee.
(That's on top of the reason that having special cases in APIs is
extremely error prone -- they're the best places for bugs to hide.
All transfer types should be queueable, or none.)

Even with zero interrupt latencies, the HC might still win the race
and finish the next frame's periodic schedule by the time your driver
returns from its completion and the HCD re-enables that transfer.
And for USB 2.0 high bandwidth interrupt transfers, 24 KByte/msec,
you'll want queueing for related reasons ... )


> Assuming that is about right, here's how my code works.  I have a
> probe function (probe_dp) that initializes the endpoints
> (init_endpoints_dp).  That initialization simply loops over the
> endpoints and saves them off to my private device structure.  When the
> interrupt endpoint is found, a urb is filled in with the usb_device, a
> rcv int pipe, a freshly allocated buffer, my call-back, and the
> bInterval timeout.  After the endpoints are initialized, I call
> getdeviceinfo_dp which actually writes two packets to the device and
> reads two packets from the device.  All this is done with usb_bulk_msg
> and works wonderfully. 

Using usb_bulk_msg() for the bulk endpoints, yes, it should be fine.


> When this get device info function returns to my probing function I
> assume I really do have a device I'm going to keep.  So, I submit the
> interrupt urb.  At this point, the submission fails with an -ENODEV.
> What this likely means is that either I don't have a urb, or the urb's
> usb_device pointer is bad.  I can't figure out why either would be the
> case.  If someone smart could take a look at my code or my logic
> described here and tell me why I'm loosing my device I'd appreciate
> it.

I had no particular insights from skimming your code.  When you apply
judicious dbg() printfs, what does it tell you about why that failed?
Or if you're a debugger user, you can set breakpoints .. :)

- Dave




-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to