Re: some questions about ehci period scheduling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



hi alan:
>> > > BTW, I have another question about iso_stream_schedule.
>> > > When if (likely (!list_empty (&stream->td_list)))  happen,
>> > > why don't we just take last scheduled microframe,  stream->next_uframe
>> > > as start point directly?
>> >
>> > We do exactly that if URB_ISO_ASAP isn't set.  But first the routine
>> > has to check and see if the schedule is already full, and it prints a
>> > debugging message if all the assigned microframes have already expired.
>> Does below source show us what you mean?
>>         if (unlikely(start < period)) {
>>             ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n",
>>                     urb, stream->next_uframe, base,
>>                     period, mod);
>>             status = -ENOSPC;
>>             goto fail;
>>         }
>
> That's the first part (checking if the schedule is already full).
> This is the second part (printing a debug message if all the assigned
> microframes have already expired):
Does this "expired" come from (controller frame pointer) >
(stream->next_uframe)?
Suppose controller frame pointer = 640 and stream->next_uframe = 600.
And that mean Controller have scan our last schedule uframe?

>
>                 /*
>                  * Not ASAP: Use the next slot in the stream,
>                  * no matter what.
>                  */
>                 else if (start + span - period < now2) {
>                         ehci_dbg(ehci, "iso underrun %p (%u+%u < %u)\n",
>                                         urb, start + base,
>                                         span - period, now2 + base);
>                 }
>
>> if so, I have one question, why we use ( (last scan frame and last
>> schedule frame) < end point interval) to determine schedule is full?
>
> If start < period, it means that the last packet on the schedule (which
> is assigned to uframe start - period) comes before base.  The only way
> this can happen is if the packets occupy the entire schedule and wrap
> around.
base in your example base should be 8's multiple, right?
if so, I try to rewrite your example.
(if anything wrong, please correct me)
>
(rewrite version)
 If you think about a few examples, you'll understand.  Suppose the
 endpoint's interval is 8 uframes, starting from uframe 3.  Suppose base
 is 496, and suppose the schedule really is full.  Then there will be
 packets scheduled for uframes 507, 515, ..., 8187, 3, 11, ..., 491, 499
 (note that 491 is slightly before 496), and stream->next_uframe will be
 499.  So start will be set to (499 - 496) & 8191 = 3.  The fact that 3
 < 8 indicates the schedule is full.

(rewrite version)
 Now suppose everything else is the same, but the schedule isn't
 completely full.  For this example, let's suppose the last scheduled
 packet is in uframe 483, so stream->next_uframe is equal to 491.  Then
 start will be set to (491 - 496) & 8191 = 8196.  The fact that 8196 >=
 8 indicates the schedule isn't full.

In above case, driver should try to stop this urb if it try to
schedule more than 1 packet, right?


(rewrite version)
 Consider one more example: Everything else is the same, but there's
 only one packet in the schedule.  It is assigned to uframe 507, and
 stream->next_uframe is 515.  Then start will be set to (515 - 496) &
 8191 = 19, and the fact that 19 >= 8 indicates the schedule isn't full.

> Does this help?
Yes, it did help me a lot. :)

>
>> Below is where we handle URB_ISO_ASAP,
>>         if (urb->transfer_flags & URB_ISO_ASAP)
>>                 start += (next - start + period - 1) & -period;
>>
>> Why don't we just use start as next?
>
> If start < next then we don't want to use it.  Packets scheduled before
> next might not be seen by the hardware, because of the isochronous
> scheduling threshold (see section 4.7.2.1 in the EHCI spec).
when we calculate next, we have already put isochronous scheduling threshold.
        if (ehci->i_thresh)
            next = now + ehci->i_thresh;    /* uframe cache */
        else
            next = (now + 2 + 7) & ~0x07;    /* full frame cache */

so when handling URB_ISO_ASAP, is it possible to change as below
            if (urb->transfer_flags & URB_ISO_ASAP)
-                start += (next - start + period - 1) & -period;
+               start = (next + base);

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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux