On Mon, 12 Sep 2005, Franck wrote:
> 2005/9/12, Alan Stern <[EMAIL PROTECTED]>:
> > On Mon, 12 Sep 2005, Franck wrote:
> >
> > > Hi,
> > >
> > > I have a question about "usb_release_bandwidth":
> > >
> > > "usb_release_bandwidth" needs an urb as parameters. If I understand,
> > > this function is called when periodic pipes is released ie when an ep
> > > is disabled.
> >
> > No. The bandwidth is released when there are no more URBs queued for the
> > endpoint. That happens when usb_hcd_giveback_urb returns.
> > usb_release_bandwidth should not be called when the endpoint is disabled.
> >
>
> Hm, this is strange...the bandwidth seems to be released whenever
> urb_unlink is called. This means that bandwidth is released even if
> there are still URBs queued for the endpoint. Here is the call tree of
> usb_release_bandwidth:
> usb_hcd_giveback_urb -> urb_unlink -> usb_release_bandwidth
>
> Does it mean that the hcd should call usb_claim_bandwidth but should
> not call usb_release_bandwidth ?
No, it means there's a mistake in urb_unlink. It should not release
the bandwidth reservation. Even if the HCD calls claim_bandwidth again
after giveback_urb returns, there's still a period of time while the
completion routine is running during which the bandwidth information is
wrong.
> I've another question regarding hcd_unlink_urb which calls hcd's
> urb_dequeue routine. When "dequeueing" a no-active URB (meaning it's
> not being transfered), what urb->status value should "urb_dequeue" set
> before calling usb_hcd_giveback_urb ?
It shouldn't set it to anything. urb->status will already have been set
to -ENOENT or -EDISCONN by hcd_unlink_urb, and the dequeue routine should
leave that value alone.
> If it is an active URB, can I
> wait for the next interrupt before calling "usb_hcd_giveback_urb" ?
You not only can, you must! Otherwise you would be giving control of the
URB back to the caller at a time while the hardware was still using it.
> If
> so what return value should be returned in hcd's "xxx_urb_dequeue" ?
You should return 0. That just means your driver knows that the URB has
been dequeued; it doesn't mean you've already called giveback_urb.
In fact, you should always return 0. (The dequeue method really should be
declared as returning void, not int.) However, your _enqueue_ routine
should check urb->status and return an error if it isn't equal to
-EINPROGRESS. This can happen if a second thread tries to unlink an URB
before the first thread has finished submitting it:
Thread 1 Thread 2
-------- --------
Calls usb_submit_urb
-> hcd_submit_urb
Sets urb->status = -EINPROGRESS
Gets as far as the
spin_unlock_irqrestore line
Calls usb_unlink_urb
-> hcd_unlink_urb
sets urb->status to -ENOENT or
-EDISCONN
-> your dequeue routine
Nothing to do: not yet queued
-> your enqueue routine
Return an error; already unlinked
since urb->status != -EINPROGRESS
To be fair, you don't _have_ to do things this way. It would be equally
valid to have both your enqueue and dequeue routines return 0 in this
situation. But then your enqueue routine would have to know that it
shouldn't fully queue the URB; it should set things up so that at the next
interrupt the URB will be sent to giveback_urb. That's a bit more work.
Alan Stern
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel