On Tue, Jul 14, 2015 at 04:04:23PM -0400, Daniel Mack wrote: > Hi, > > On 07/14/2015 04:29 AM, Peter Chen wrote: > > 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. > > ... > > > diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c > > index 6d3eb8b..0ed6f0e 100644 > > --- a/drivers/usb/gadget/function/f_uac2.c > > +++ b/drivers/usb/gadget/function/f_uac2.c > > @@ -987,6 +987,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) > > struct f_uac2_opts *uac2_opts; > > struct usb_string *us; > > int ret; > > + u16 c_max_packet_size, p_max_packet_size; > > > > uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); > > > > @@ -1070,6 +1071,29 @@ 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 */ > > + c_max_packet_size = uac2_opts->c_chmask * uac2_opts->c_ssize > > + * uac2_opts->c_srate / 1000; > > + p_max_packet_size = uac2_opts->p_chmask * uac2_opts->p_ssize > > + * uac2_opts->p_srate / 1000; > > For high-speed endpoints, we in fact have 8 microframes per frame, and > the factor also depends on the endpoint's polling interval. See what > afunc_set_alt() does here. > > Did you test this in HS or FS setups or both? It only has problem at FS setup. > > > + if ((c_max_packet_size > fs_epout_desc.wMaxPacketSize) || > > + (p_max_packet_size > fs_epin_desc.wMaxPacketSize)) { > > + dev_err(dev, "parameters are incorrect\n"); > > + goto err; > > + } > > + /* > > + * Keep max packet size is multiplier of 4, and > > + * a little larger than bandwidth. > > + * Eg, for frame rate 44100, 1 channel, and 16 bits data > > + * we need to reserve more than 44 * 2 bytes. > > + */ > > + c_max_packet_size += (4 - (c_max_packet_size % 4)); > > I guess DIV_ROUND_UP() allows you to account for the packets that are > sent when the devision residue accumulator overflows. See > agdev_iso_complete(). Thanks, I will check it. > > > + fs_epin_desc.wMaxPacketSize = min(cpu_to_le16(c_max_packet_size), > > + fs_epin_desc.wMaxPacketSize); > > + p_max_packet_size += (4 - (p_max_packet_size % 4)); > > + fs_epout_desc.wMaxPacketSize = min(cpu_to_le16(p_max_packet_size), > > + fs_epout_desc.wMaxPacketSize); > > + > > hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; > > hs_epout_desc.wMaxPacketSize = fs_epout_desc.wMaxPacketSize; > > We probably have to pass different values for the two settings, as they > can't be the same once they contain pre-calculated values. > > You mean we may have different wMaxPacketSize value for FS and HS? Current f_uac2 does not support it, it only one group parameter for packet size. -- Best Regards, Peter Chen -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html