Re: [PATCH v4 1/1] usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth

2015-07-28 Thread Daniel Mack
On 07/28/2015 03:38 AM, Peter Chen wrote:
 +static void set_ep_max_packet_size (struct f_uac2_opts *uac2_opts,
 + struct usb_endpoint_descriptor *ep_desc, unsigned int factor)
 +{
 + int chmask;
 + int srate;
 + int ssize;
 + u16 max_packet_size;
 +
 + if (ep_desc == fs_epin_desc || ep_desc == hs_epin_desc) {
 + chmask = uac2_opts-p_chmask;   
 + srate = uac2_opts-p_srate;
 + ssize = uac2_opts-p_ssize;
 + } else {
 + WARN_ON (ep_desc != fs_epout_desc  ep_desc != 
 hs_epout_desc);
 + chmask = uac2_opts-c_chmask;
 + srate = uac2_opts-c_srate;
 + ssize = uac2_opts-c_ssize;
 + }
 +
 + max_packet_size = num_channels(chmask) * ssize *
 + DIV_ROUND_UP(srate, factor / (1  (ep_desc-bInterval - 1)));
 + ep_desc-wMaxPacketSize = min(cpu_to_le16(max_packet_size),
 + ep_desc-wMaxPacketSize);
 +}

Thinking about it again, it would probably be nicer to make this
function return wMaxPacketSize directly:

  fs_epin_desc.wMaxPacketSize =
calc_ep_max_packet_size(uac2_opts-p_chmask,
uac2_opts-p_srate,
uac2_opts-p_ssize,
1000);

  hs_epin_desc.wMaxPacketSize =
calc_ep_max_packet_size(uac2_opts-p_chmask,
uac2_opts-p_srate,
uac2_opts-p_ssize,
8000);

  ...



--
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


Re: [PATCH v4 1/1] usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth

2015-07-28 Thread Peter Chen
On Tue, Jul 28, 2015 at 10:13:48AM +0200, Daniel Mack wrote:
 On 07/28/2015 03:38 AM, Peter Chen wrote:
 
  diff --git a/drivers/usb/gadget/function/f_uac2.c 
  b/drivers/usb/gadget/function/f_uac2.c
  index 5318615..6a8e0d2 100644
  --- a/drivers/usb/gadget/function/f_uac2.c
  +++ b/drivers/usb/gadget/function/f_uac2.c
  @@ -975,6 +975,31 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
  %s:%d Error!\n, __func__, __LINE__);
   }
   
  +static void set_ep_max_packet_size (struct f_uac2_opts *uac2_opts,
  +   struct usb_endpoint_descriptor *ep_desc, unsigned int factor)
 
 scripts/checkpatch.pl will complain about a stray space before '(' and
 wrong indentation. Also, uac2_opts can be const.

oh, I forget to run it when send this version.

 
  +{
  +   int chmask;
  +   int srate;
  +   int ssize;
 
 These can be put in one line.
 

I will change it

  +   u16 max_packet_size;
  +
  +   if (ep_desc == fs_epin_desc || ep_desc == hs_epin_desc) {
  +   chmask = uac2_opts-p_chmask;   
  +   srate = uac2_opts-p_srate;
  +   ssize = uac2_opts-p_ssize;
  +   } else {
  +   WARN_ON (ep_desc != fs_epout_desc  ep_desc != 
  hs_epout_desc);
 
 I would rather pass a boolean flag called 'is_playback' than checking
 the input parameter like this. But I forgot this detail in my proposal,
 I admit.
 
 Apart from that, I like the patch.

I will change it, thanks.

 
 Thanks,
 Daniel
 
 
 
  +   chmask = uac2_opts-c_chmask;
  +   srate = uac2_opts-c_srate;
  +   ssize = uac2_opts-c_ssize;
  +   }
  +
  +   max_packet_size = num_channels(chmask) * ssize *
  +   DIV_ROUND_UP(srate, factor / (1  (ep_desc-bInterval - 1)));
  +   ep_desc-wMaxPacketSize = min(cpu_to_le16(max_packet_size),
  +   ep_desc-wMaxPacketSize);
  +}
  +
   static int
   afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
   {
  @@ -1070,10 +1095,14 @@ afunc_bind(struct usb_configuration *cfg, struct 
  usb_function *fn)
  uac2-p_prm.uac2 = uac2;
  uac2-c_prm.uac2 = uac2;
   
  +   /* Calculate wMaxPacketSize according to audio bandwidth */
  +   set_ep_max_packet_size(uac2_opts, fs_epin_desc, 1000);
  +   set_ep_max_packet_size(uac2_opts, fs_epout_desc, 1000);
  +   set_ep_max_packet_size(uac2_opts, hs_epin_desc, 8000);
  +   set_ep_max_packet_size(uac2_opts, hs_epout_desc, 8000);
  +
  hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
  -   hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize;
  hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
  -   hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
   
  ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
  if (ret)
  
 

-- 

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


Re: [PATCH v4 1/1] usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth

2015-07-28 Thread Daniel Mack
On 07/28/2015 11:30 AM, Daniel Mack wrote:
 On 07/28/2015 03:38 AM, Peter Chen wrote:
 +static void set_ep_max_packet_size (struct f_uac2_opts *uac2_opts,
 +struct usb_endpoint_descriptor *ep_desc, unsigned int factor)
 +{
 +int chmask;
 +int srate;
 +int ssize;
 +u16 max_packet_size;
 +
 +if (ep_desc == fs_epin_desc || ep_desc == hs_epin_desc) {
 +chmask = uac2_opts-p_chmask;   
 +srate = uac2_opts-p_srate;
 +ssize = uac2_opts-p_ssize;
 +} else {
 +WARN_ON (ep_desc != fs_epout_desc  ep_desc != 
 hs_epout_desc);
 +chmask = uac2_opts-c_chmask;
 +srate = uac2_opts-c_srate;
 +ssize = uac2_opts-c_ssize;
 +}
 +
 +max_packet_size = num_channels(chmask) * ssize *
 +DIV_ROUND_UP(srate, factor / (1  (ep_desc-bInterval - 1)));
 +ep_desc-wMaxPacketSize = min(cpu_to_le16(max_packet_size),
 +ep_desc-wMaxPacketSize);
 +}
 
 Thinking about it again, it would probably be nicer to make this
 function return wMaxPacketSize directly:

Ah, no, that doesn't make sense, sorry. We need bInterval and the
current value of wMaxPacketSize as well. Just stick with your current
approach then :)


--
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


Re: [PATCH v4 1/1] usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth

2015-07-28 Thread Daniel Mack
On 07/28/2015 03:38 AM, Peter Chen wrote:

 diff --git a/drivers/usb/gadget/function/f_uac2.c 
 b/drivers/usb/gadget/function/f_uac2.c
 index 5318615..6a8e0d2 100644
 --- a/drivers/usb/gadget/function/f_uac2.c
 +++ b/drivers/usb/gadget/function/f_uac2.c
 @@ -975,6 +975,31 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
   %s:%d Error!\n, __func__, __LINE__);
  }
  
 +static void set_ep_max_packet_size (struct f_uac2_opts *uac2_opts,
 + struct usb_endpoint_descriptor *ep_desc, unsigned int factor)

scripts/checkpatch.pl will complain about a stray space before '(' and
wrong indentation. Also, uac2_opts can be const.

 +{
 + int chmask;
 + int srate;
 + int ssize;

These can be put in one line.

 + u16 max_packet_size;
 +
 + if (ep_desc == fs_epin_desc || ep_desc == hs_epin_desc) {
 + chmask = uac2_opts-p_chmask;   
 + srate = uac2_opts-p_srate;
 + ssize = uac2_opts-p_ssize;
 + } else {
 + WARN_ON (ep_desc != fs_epout_desc  ep_desc != 
 hs_epout_desc);

I would rather pass a boolean flag called 'is_playback' than checking
the input parameter like this. But I forgot this detail in my proposal,
I admit.

Apart from that, I like the patch.


Thanks,
Daniel



 + chmask = uac2_opts-c_chmask;
 + srate = uac2_opts-c_srate;
 + ssize = uac2_opts-c_ssize;
 + }
 +
 + max_packet_size = num_channels(chmask) * ssize *
 + DIV_ROUND_UP(srate, factor / (1  (ep_desc-bInterval - 1)));
 + ep_desc-wMaxPacketSize = min(cpu_to_le16(max_packet_size),
 + ep_desc-wMaxPacketSize);
 +}
 +
  static int
  afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
  {
 @@ -1070,10 +1095,14 @@ afunc_bind(struct usb_configuration *cfg, struct 
 usb_function *fn)
   uac2-p_prm.uac2 = uac2;
   uac2-c_prm.uac2 = uac2;
  
 + /* Calculate wMaxPacketSize according to audio bandwidth */
 + set_ep_max_packet_size(uac2_opts, fs_epin_desc, 1000);
 + set_ep_max_packet_size(uac2_opts, fs_epout_desc, 1000);
 + set_ep_max_packet_size(uac2_opts, hs_epin_desc, 8000);
 + set_ep_max_packet_size(uac2_opts, hs_epout_desc, 8000);
 +
   hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
 - hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize;
   hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
 - hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
  
   ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
   if (ret)
 

--
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


[PATCH v4 1/1] usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth

2015-07-27 Thread Peter Chen
According to USB Audio Device 2.0 Spec, Ch4.10.1.1:
wMaxPacketSize is defined as follows:
Maximum packet size this endpoint is capable of sending or receiving
when this configuration is selected.
This is determined by the audio bandwidth constraints of the endpoint.

In current code, the wMaxPacketSize is defined as the maximum packet size
for ISO endpoint, and it will let the host reserve much more space than
it really needs, so that we can't let more endpoints work together at
one frame.

We find this issue when we try to let 4 f_uac2 gadgets work together [1]
at FS connection.

[1]http://www.spinics.net/lists/linux-usb/msg123478.html

Cc: andrze...@samsung.com
Cc: Daniel Mack zon...@gmail.com
Cc: ti...@suse.de
Cc: sta...@vger.kernel.org #v3.18+
Cc: Alan Stern st...@rowland.harvard.edu
Signed-off-by: Peter Chen peter.c...@freescale.com
---
Changes for v4:
- Add helper set_ep_max_packet_size to calculate max packet size

Changes for v3:
- Consider 'bInterval' to calculate wMaxPacketSize
- playback endpoint is IN ep, and capture endpoint is OUT ep

Changes for v2:
- Using DIV_ROUND_UP to calculate max packet size

 drivers/usb/gadget/function/f_uac2.c | 33 +++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/gadget/function/f_uac2.c 
b/drivers/usb/gadget/function/f_uac2.c
index 5318615..6a8e0d2 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -975,6 +975,31 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep)
%s:%d Error!\n, __func__, __LINE__);
 }
 
+static void set_ep_max_packet_size (struct f_uac2_opts *uac2_opts,
+   struct usb_endpoint_descriptor *ep_desc, unsigned int factor)
+{
+   int chmask;
+   int srate;
+   int ssize;
+   u16 max_packet_size;
+
+   if (ep_desc == fs_epin_desc || ep_desc == hs_epin_desc) {
+   chmask = uac2_opts-p_chmask;   
+   srate = uac2_opts-p_srate;
+   ssize = uac2_opts-p_ssize;
+   } else {
+   WARN_ON (ep_desc != fs_epout_desc  ep_desc != 
hs_epout_desc);
+   chmask = uac2_opts-c_chmask;
+   srate = uac2_opts-c_srate;
+   ssize = uac2_opts-c_ssize;
+   }
+
+   max_packet_size = num_channels(chmask) * ssize *
+   DIV_ROUND_UP(srate, factor / (1  (ep_desc-bInterval - 1)));
+   ep_desc-wMaxPacketSize = min(cpu_to_le16(max_packet_size),
+   ep_desc-wMaxPacketSize);
+}
+
 static int
 afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
 {
@@ -1070,10 +1095,14 @@ afunc_bind(struct usb_configuration *cfg, struct 
usb_function *fn)
uac2-p_prm.uac2 = uac2;
uac2-c_prm.uac2 = uac2;
 
+   /* Calculate wMaxPacketSize according to audio bandwidth */
+   set_ep_max_packet_size(uac2_opts, fs_epin_desc, 1000);
+   set_ep_max_packet_size(uac2_opts, fs_epout_desc, 1000);
+   set_ep_max_packet_size(uac2_opts, hs_epin_desc, 8000);
+   set_ep_max_packet_size(uac2_opts, hs_epout_desc, 8000);
+
hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress;
-   hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize;
hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress;
-   hs_epin_desc.wMaxPacketSize = fs_epin_desc.wMaxPacketSize;
 
ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL);
if (ret)
-- 
1.9.1

--
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