Re: [PATCH 2/2] usb: gadget: uac2: add req_number as parameter

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

 



On Wed, Jan 04, 2017 at 10:19:23AM +0800, Peter Chen wrote:
> There are only two requests for uac2, it may not be enough at high
> loading system which usb interrupt handler can't be serviced on
> time, then the data will be lost since it is isoc transfer for audio.
> 
> In this patch, we introduce a parameter for the number for usb request,
> and the user can override it if current number for request is not enough
> for his/her use case.
> 
> Besides, update this parameter for legacy audio gadget and documentation.
> 
> Signed-off-by: Peter Chen <peter.chen@xxxxxxx>
> ---
>  Documentation/usb/gadget-testing.txt |  2 ++
>  drivers/usb/gadget/function/f_uac2.c | 39 +++++++++++++++++++++++++++---------
>  drivers/usb/gadget/function/u_uac2.h |  2 ++
>  drivers/usb/gadget/legacy/audio.c    |  1 +
>  4 files changed, 34 insertions(+), 10 deletions(-)
> 
> diff --git a/Documentation/usb/gadget-testing.txt b/Documentation/usb/gadget-testing.txt
> index 5819605..fb0cc4d 100644
> --- a/Documentation/usb/gadget-testing.txt
> +++ b/Documentation/usb/gadget-testing.txt
> @@ -632,6 +632,8 @@ The uac2 function provides these attributes in its function directory:
>  	p_chmask - playback channel mask
>  	p_srate - playback sampling rate
>  	p_ssize - playback sample size (bytes)
> +	req_number - the number of pre-allocated request for both capture
> +		     and playback
>  
>  The attributes have sane default values.
>  
> diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
> index 3f4e478..f6a0d3a 100644
> --- a/drivers/usb/gadget/function/f_uac2.c
> +++ b/drivers/usb/gadget/function/f_uac2.c
> @@ -22,9 +22,6 @@
>  
>  #include "u_uac2.h"
>  
> -/* Keep everyone on toes */
> -#define USB_XFERS	2
> -
>  /*
>   * The driver implements a simple UAC_2 topology.
>   * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture
> @@ -78,7 +75,7 @@ struct uac2_rtd_params {
>  	size_t period_size;
>  
>  	unsigned max_psize;
> -	struct uac2_req ureq[USB_XFERS];
> +	struct uac2_req *ureq;
>  
>  	spinlock_t lock;
>  };
> @@ -269,6 +266,8 @@ static int
>  uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
>  {
>  	struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream);
> +	struct audio_dev *agdev = uac2_to_agdev(uac2);
> +	struct f_uac2_opts *uac2_opts = agdev_to_uac2_opts(agdev);
>  	struct uac2_rtd_params *prm;
>  	unsigned long flags;
>  	int err = 0;
> @@ -300,7 +299,7 @@ uac2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
>  
>  	/* Clear buffer after Play stops */
>  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss)
> -		memset(prm->rbuf, 0, prm->max_psize * USB_XFERS);
> +		memset(prm->rbuf, 0, prm->max_psize * uac2_opts->req_number);
>  
>  	return err;
>  }
> @@ -943,6 +942,8 @@ static inline void
>  free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
>  {
>  	struct snd_uac2_chip *uac2 = prm->uac2;
> +	struct audio_dev *agdev = uac2_to_agdev(uac2);
> +	struct f_uac2_opts *uac2_opts = agdev_to_uac2_opts(agdev);
>  	int i;
>  
>  	if (!prm->ep_enabled)
> @@ -950,7 +951,7 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
>  
>  	prm->ep_enabled = false;
>  
> -	for (i = 0; i < USB_XFERS; i++) {
> +	for (i = 0; i < uac2_opts->req_number; i++) {
>  		if (prm->ureq[i].req) {
>  			usb_ep_dequeue(ep, prm->ureq[i].req);
>  			usb_ep_free_request(ep, prm->ureq[i].req);
> @@ -1095,7 +1096,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
>  
>  	prm = &agdev->uac2.c_prm;
>  	prm->max_psize = hs_epout_desc.wMaxPacketSize;
> -	prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL);
> +	prm->ureq = kcalloc(uac2_opts->req_number, sizeof(struct uac2_req),
> +			GFP_KERNEL);
> +	if (!prm->ureq) {
> +		ret = -ENOMEM;
> +		goto err_free_descs;
> +	}
> +	prm->rbuf = kcalloc(uac2_opts->req_number, prm->max_psize, GFP_KERNEL);
>  	if (!prm->rbuf) {
>  		prm->max_psize = 0;
>  		ret = -ENOMEM;
> @@ -1104,7 +1111,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
>  
>  	prm = &agdev->uac2.p_prm;
>  	prm->max_psize = hs_epin_desc.wMaxPacketSize;
> -	prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL);
> +	prm->ureq = kcalloc(uac2_opts->req_number, sizeof(struct uac2_req),
> +			GFP_KERNEL);
> +	if (!prm->ureq) {
> +		ret = -ENOMEM;
> +		goto err_free_descs;
> +	}
> +	prm->rbuf = kcalloc(uac2_opts->req_number, prm->max_psize, GFP_KERNEL);
>  	if (!prm->rbuf) {
>  		prm->max_psize = 0;
>  		ret = -ENOMEM;
> @@ -1117,6 +1130,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
>  	return 0;
>  
>  err_no_memory:
> +	kfree(agdev->uac2.p_prm.ureq);
> +	kfree(agdev->uac2.c_prm.ureq);
>  	kfree(agdev->uac2.p_prm.rbuf);
>  	kfree(agdev->uac2.c_prm.rbuf);
>  err_free_descs:
> @@ -1129,6 +1144,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
>  {
>  	struct usb_composite_dev *cdev = fn->config->cdev;
>  	struct audio_dev *agdev = func_to_agdev(fn);
> +	struct f_uac2_opts *opts = agdev_to_uac2_opts(agdev);
>  	struct snd_uac2_chip *uac2 = &agdev->uac2;
>  	struct usb_gadget *gadget = cdev->gadget;
>  	struct device *dev = &uac2->pdev.dev;
> @@ -1159,7 +1175,6 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
>  		agdev->as_out_alt = alt;
>  		req_len = prm->max_psize;
>  	} else if (intf == agdev->as_in_intf) {
> -		struct f_uac2_opts *opts = agdev_to_uac2_opts(agdev);
>  		unsigned int factor, rate;
>  		struct usb_endpoint_descriptor *ep_desc;
>  
> @@ -1205,7 +1220,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
>  	prm->ep_enabled = true;
>  	usb_ep_enable(ep);
>  
> -	for (i = 0; i < USB_XFERS; i++) {
> +	for (i = 0; i < opts->req_number; i++) {
>  		if (!prm->ureq[i].req) {
>  			req = usb_ep_alloc_request(ep, GFP_ATOMIC);
>  			if (req == NULL)
> @@ -1489,6 +1504,7 @@ UAC2_ATTRIBUTE(p_ssize);
>  UAC2_ATTRIBUTE(c_chmask);
>  UAC2_ATTRIBUTE(c_srate);
>  UAC2_ATTRIBUTE(c_ssize);
> +UAC2_ATTRIBUTE(req_number);
>  
>  static struct configfs_attribute *f_uac2_attrs[] = {
>  	&f_uac2_opts_attr_p_chmask,
> @@ -1497,6 +1513,7 @@ static struct configfs_attribute *f_uac2_attrs[] = {
>  	&f_uac2_opts_attr_c_chmask,
>  	&f_uac2_opts_attr_c_srate,
>  	&f_uac2_opts_attr_c_ssize,
> +	&f_uac2_opts_attr_req_number,
>  	NULL,
>  };
>  
> @@ -1534,6 +1551,7 @@ static struct usb_function_instance *afunc_alloc_inst(void)
>  	opts->c_chmask = UAC2_DEF_CCHMASK;
>  	opts->c_srate = UAC2_DEF_CSRATE;
>  	opts->c_ssize = UAC2_DEF_CSSIZE;
> +	opts->req_number = UAC2_DEF_REQ_NUM;
>  	return &opts->func_inst;
>  }
>  
> @@ -1562,6 +1580,7 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
>  
>  	prm = &agdev->uac2.c_prm;
>  	kfree(prm->rbuf);
> +	kfree(prm->ureq);
>  	usb_free_all_descriptors(f);
>  }
>  
> diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h
> index 78dd372..19eeb83 100644
> --- a/drivers/usb/gadget/function/u_uac2.h
> +++ b/drivers/usb/gadget/function/u_uac2.h
> @@ -24,6 +24,7 @@
>  #define UAC2_DEF_CCHMASK 0x3
>  #define UAC2_DEF_CSRATE 64000
>  #define UAC2_DEF_CSSIZE 2
> +#define UAC2_DEF_REQ_NUM 2
>  
>  struct f_uac2_opts {
>  	struct usb_function_instance	func_inst;
> @@ -33,6 +34,7 @@ struct f_uac2_opts {
>  	int				c_chmask;
>  	int				c_srate;
>  	int				c_ssize;
> +	int				req_number;
>  	bool				bound;
>  
>  	struct mutex			lock;
> diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c
> index 5d7b3c6..8a39f42 100644
> --- a/drivers/usb/gadget/legacy/audio.c
> +++ b/drivers/usb/gadget/legacy/audio.c
> @@ -229,6 +229,7 @@ static int audio_bind(struct usb_composite_dev *cdev)
>  	uac2_opts->c_chmask = c_chmask;
>  	uac2_opts->c_srate = c_srate;
>  	uac2_opts->c_ssize = c_ssize;
> +	uac2_opts->req_number = UAC2_DEF_REQ_NUM;
>  #else
>  	uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst);
>  	uac1_opts->fn_play = fn_play;
> -- 

A nice ping...

-- 

Best Regards,
Peter Chen
--
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