RE: [PATCH] usb: xhci: fixes lost of data for xHCI Cadence Controllers

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

 



>> Stream endpoint can skip part of TD during next transfer
>> initialization after beginning stopped during active stream data transfer.
>> The Set TR Dequeue Pointer command does not clear all internal
>> transfer-related variables that position stream endpoint on transfer ring.
>>
>> USB Controller stores all endpoint state information within RsvdO
>> fields inside endpoint context structure. For stream endpoints, all
>> relevant information regarding particular StreamID is stored within
>> corresponding Stream Endpoint context.
>> Whenever driver wants to stop stream endpoint traffic, it invokes Stop
>> Endpoint command which forces the controller to dump all endpoint
>> state-related variables into RsvdO spaces into endpoint context and
>> stream endpoint context. Whenever driver wants to reinitialize
>> endpoint starting point on Transfer Ring, it uses the Set TR Dequeue
>> Pointer command to update dequeue pointer for particular stream in
>> Stream Endpoint Context. When stream endpoint is forced to stop active
>> transfer in the middle of TD, it dumps an information about TRB bytes
>> left in RsvdO fields in Stream Endpoint Context which will be used in
>> next transfer initialization to designate starting point for XDMA.
>> This field is not cleared during Set TR Dequeue Pointer command which
>> causes XDMA to skip over transfer ring and leads to data loss on stream
>pipe.
>
>xHC should clear the EDTLA field when processing a Set TR Dequeue Pointer
>command:
>
>xhci spec v1.2, section 4.6.10 Set TR Dequeue Pointer:
>"The xHC shall perform the following operations when setting a ring address:
>  ...
>Clear any prior transfer state, e.g. setting the EDTLA to 0, clearing any partially
>completed USB2 split transactions, etc."
>
>>
>> Patch fixes this by clearing out all RsvdO fields before initializing
>> new transfer via that StreamID.
>
>Looks like patch also writes edtl back to ctx->reserved[0], is there a reason for
>this?
>
>>
>> Field Rsvd0 is reserved field, so patch should not have impact for
>> other xHCI controllers.
>>
>> Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence
>> USBSSP DRD Driver")
>> cc: <stable@xxxxxxxxxxxxxxx>
>> Signed-off-by: Pawel Laszczak <pawell@xxxxxxxxxxx>
>> ---
>>   drivers/usb/host/xhci-ring.c | 13 +++++++++++++
>>   1 file changed, 13 insertions(+)
>>
>> diff --git a/drivers/usb/host/xhci-ring.c
>> b/drivers/usb/host/xhci-ring.c index 1dde53f6eb31..7fc1c4efcae2 100644
>> --- a/drivers/usb/host/xhci-ring.c
>> +++ b/drivers/usb/host/xhci-ring.c
>> @@ -1385,7 +1385,20 @@ static void xhci_handle_cmd_set_deq(struct
>xhci_hcd *xhci, int slot_id,
>>   		if (ep->ep_state & EP_HAS_STREAMS) {
>>   			struct xhci_stream_ctx *ctx =
>>   				&ep->stream_info-
>>stream_ctx_array[stream_id];
>> +			u32 edtl;
>> +
>>   			deq = le64_to_cpu(ctx->stream_ring) &
>SCTX_DEQ_MASK;
>> +			edtl = EVENT_TRB_LEN(le32_to_cpu(ctx-
>>reserved[1]));
>
>Isn't edtl in reserved[0], not in reserved[1]?
>
>Also unclear why we read it at all, it should be set to 0 by controller, right?
>
>> +
>> +			/*
>> +			 * Existing Cadence xHCI controllers store some
>endpoint state information
>> +			 * within Rsvd0 fields of Stream Endpoint context. This
>field is
>> +not
>
>Aren't these fields RsvdO (Reserved and Opaque)?
>Driver shouldn't normally touch these fields, they are used by xHC as
>temporary workspace.

Yes, it should be. This a real issue that occurred during testing UASP disk and
this workaround fixes it, so it's looks like that this Rsvd0 field can be changed.

>
>> +			 * cleared during Set TR Dequeue Pointer command
>which causes XDMA to skip
>> +			 * over transfer ring and leads to data loss on stream
>pipe.
>> +			 * To fix this issue driver must clear Rsvd0 field.
>> +			 */
>> +			ctx->reserved[1] = 0;
>> +			ctx->reserved[0] = cpu_to_le32(edtl);
>
>why are we writing back edtl?, also note that it's read from ctx->reserved[1]
>above, and now written to back to ctx->reserved[0].
>
>I understood that issue was those RsvdO fields needs to be cleared manually
>for this host as hardware fails to clear them during a "Set TR Dequeue
>Pointer" command.
>
>Am I misunderstanding something?

Yes, you understand it so well.

In fact edtl should be zeroed and simple clearing of reserved[0] and reserved[1]  should be sufficient.

Thanks 
Pawel

>
>Thanks
>Mathias





[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux