Re: [PATCH v2] usb: dwc3: Fix assignment of EP transfer resources

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

 



On 2/16/2016 1:28 PM, Felipe Balbi wrote:
> 
> Hi,
> 
> John Youn <John.Youn@xxxxxxxxxxxx> writes:
>> The assignement of EP transfer resources was not handled properly in the
>> dwc3 driver. Commit aebda6187181 ("usb: dwc3: Reset the transfer
>> resource index on SET_INTERFACE") previously fixed one aspect of this
>> where resources may be exhausted with multiple calls to SET_INTERFACE.
>> However, it introduced an issue where composite devices with multiple
>> interfaces can be assigned the same transfer resources for different
>> endpoints. This patch solves both issues.
>>
>> The assignment of transfer resources cannot perfectly follow the data
>> book due to the fact that the controller driver does not have all
>> knowledge of the configuration in advance. It is given this information
>> piecemeal by the composite gadget framework after every
>> SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
>> programming model in this scenario can cause errors. For two reasons:
>>
>> 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION and
>> SET_INTERFACE (8.1.5). This is incorrect in the scenario of multiple
>> interfaces.
>>
>> 2) The databook does not mention doing more DEPXFERCFG for new endpoint
>> on alt setting (8.1.6).
>>
>> The following simplified method is used instead:
>>
>> All hardware endpoints can be assigned a transfer resource and this
>> setting will stay persistent until either a core reset or hibernation.
>> So whenever we do a DEPSTARTCFG(0) we can go ahead and do DEPXFERCFG for
>> every hardware endpoint as well. We are guaranteed that there are as
>> many transfer resources as endpoints.
>>
>> This patch triggers off of the calling dwc3_gadget_start_config() for
>> EP0-out, which always happens first, and which should only happen in one
>> of the above conditions.
> 
> very good commit log. Thank you :-)
> 
>> Fixes: aebda6187181 ("usb: dwc3: Reset the transfer resource index on SET_INTERFACE")
> 
> you missed:
> 
> Cc: <stable@xxxxxxxxxxxxxxx> # v....
> 
>> Reported-by: Ravi Babu <ravibabu@xxxxxx>
>> Signed-off-by: John Youn <johnyoun@xxxxxxxxxxxx>
>> ---
>>
>> Hi Ravi,
>>
>> This is a simplified version of the previous patch. Could you verify
>> that it works with your test scenario?
>>
>> Thanks,
>> John
>>
>> v2:
>> * Simplified assignment of resources by doing all endpoints at once.
>>
>>
>>  drivers/usb/dwc3/core.h   |  1 -
>>  drivers/usb/dwc3/ep0.c    |  5 -----
>>  drivers/usb/dwc3/gadget.c | 38 ++++++++++++++++++++------------------
>>  3 files changed, 20 insertions(+), 24 deletions(-)
>>
>> diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
>> index 2913068..e4f8b90 100644
>> --- a/drivers/usb/dwc3/core.h
>> +++ b/drivers/usb/dwc3/core.h
>> @@ -856,7 +856,6 @@ struct dwc3 {
>>  	unsigned		pullups_connected:1;
>>  	unsigned		resize_fifos:1;
>>  	unsigned		setup_packet_pending:1;
>> -	unsigned		start_config_issued:1;
>>  	unsigned		three_stage_setup:1;
>>  	unsigned		usb3_lpm_capable:1;
>>  
>> diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>> index 3a9354a..8d6b75c 100644
>> --- a/drivers/usb/dwc3/ep0.c
>> +++ b/drivers/usb/dwc3/ep0.c
>> @@ -555,7 +555,6 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
>>  	int ret;
>>  	u32 reg;
>>  
>> -	dwc->start_config_issued = false;
>>  	cfg = le16_to_cpu(ctrl->wValue);
>>  
>>  	switch (state) {
>> @@ -737,10 +736,6 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
>>  		dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
>>  		ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
>>  		break;
>> -	case USB_REQ_SET_INTERFACE:
>> -		dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_INTERFACE");
>> -		dwc->start_config_issued = false;
>> -		/* Fall through */
>>  	default:
>>  		dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
>>  		ret = dwc3_ep0_delegate_req(dwc, ctrl);
>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>> index 7d1dd82..ae2e546 100644
>> --- a/drivers/usb/dwc3/gadget.c
>> +++ b/drivers/usb/dwc3/gadget.c
>> @@ -385,24 +385,34 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
>>  	dep->trb_pool_dma = 0;
>>  }
>>  
>> +static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);
>> +
>>  static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
>>  {
>>  	struct dwc3_gadget_ep_cmd_params params;
>>  	u32			cmd;
>> +	int			i, ret;
> 
> I'd prefer if these two variables would be split into their own lines:
> 
> 	int			ret;
> 	int			i;
> 
>> +	if (dep->number)
>> +		return 0;
>>  
>>  	memset(&params, 0x00, sizeof(params));
>> +	cmd = DWC3_DEPCMD_DEPSTARTCFG;
>>  
>> -	if (dep->number != 1) {
>> -		cmd = DWC3_DEPCMD_DEPSTARTCFG;
>> -		/* XferRscIdx == 0 for ep0 and 2 for the remaining */
>> -		if (dep->number > 1) {
>> -			if (dwc->start_config_issued)
>> -				return 0;
>> -			dwc->start_config_issued = true;
>> -			cmd |= DWC3_DEPCMD_PARAM(2);
>> -		}
>> +	ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
>> +	if (ret)
>> +		return ret;
>> +
>> +	for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
>> +		int epnum, dir;
> 
> ditto. Also, (nit-picking, sorry) I'd prefer if the structure
> declaration would come first:
> 
> 		struct dwc3_ep *dep = dwc->eps[i];
>                 int epnum;
>                 int dir;
> 
> also, do you mind adding a comment somewhere here explaining that we're
> not following the databook for a reason... It could be an almost
> carbon-copy of your commit log, actually.
> 

Ok. I'll resubmit with your feedback.

Regards,
John
--
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