On 9/6/2012 10:57 PM, Alan Stern wrote:
> On Thu, 6 Sep 2012, Pavan Kondeti wrote:
> 
>> Hi
>>
>> I am debugging "EHCI host system error" (4.15.2.4) issue. The issue
>> happens during unlinking of URB from an interface driver. In our system
>> the device is always connected to the host. some interfaces are always
>> active (I/O can happen). Other interface's I/O depends on the user
>> space. if user opens the device node, we submit IN URB. This issue
>> happens when unlinking URB upon file close. This issue happens very rarely.
>>
>> I have a doubt in unlink path of EHCI driver. Say if an endpoint has two
>> pending IN URB requests at the time of calling unlinking API.
>> (usb_kill_anchored_urbs API).
>>
>> The QH's queue of this endpoint looks like this.
>>
>> Qtd1 --> Qtd2 --> Dummy
>>
>> EHCI driver kicks in the Async Advance Doorbell handshake after
>> manipulating the QH horizontal pointer in start_unlink_async() function.
>> EHCI driver wait for IAAD interrupt from the controller.
>>
>> Say controller is working on Qtd1. Which means transfer overlay of this
>> QH has reference to Qtd2. controller generates IAAD interrupt (Qtd1 is
>> not completely finished. QH active pointer points to Qtd1). EHCI driver
>> finishes Qtd2 unlinking and points qtd1's next pointer to qtd'2 next
>> pointer and puts this QH back to asynchronous schedule.
>>
>> My doubt is that software updated only QTD1 memory to point it to Qtd'2
>> next pointer i.e dummy. What about the QH's transfer overlay memory?
>> Would not the controller try to access the Qtd2 when QH is put back into
>> schedule.
>>
>> To further clarify my question, I am copy pasting the qh_refresh() code
>> here. In the below code, if we enter "first qtd may already be partially
>> processed" case, should not we update qh->hw->hw_qtd_next and
>> qh->hw->hw_alt_next to reflect the current Qtd memory.
>>
>> static void
>> qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
>> {
>>         struct ehci_qtd *qtd;
>>
>>         if (list_empty (&qh->qtd_list))
>>                 qtd = qh->dummy;
>>         else {
>>                 qtd = list_entry (qh->qtd_list.next,
>>                                 struct ehci_qtd, qtd_list);
>>                 /* first qtd may already be partially processed */
>>                 if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current)
>>                         qtd = NULL;
>>         }
>>
>>         if (qtd)
>>                 qh_update (ehci, qh, qtd);
>> }
> 
> You're absolutely right; this is a bug in the driver.  Would you like 
> to submit a patch to fix it?
> 
Thanks for your response. I will submit a patch.

> (It shouldn't be necessary to update the hw_alt_next field.  The 
> hw_alt_next part of the qTD doesn't get changed when the following qTD 
> is removed.)
> 

Agreed.

Thanks,
Pavan

-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
--
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

Reply via email to