usb: dwc3: fix imbalanced endpoint index

In current implementation, we assume that the IN endpoint number is same
with the OUT endpoint, and assign the dwc3 ep array like this,

  eps[0]  = ep0out  eps[1]  = ep0in
  eps[2]  = ep1out  eps[3]  = ep2in
  ...               ...
  eps[14] = ep7out  eps[15] = ep7in

in fact, the IN endpoint number may be unequal to OUT endpoint on some
platform like RK3588, and the dwc3 ep array are expected to assign like
this,

  eps[0]  = ep0out  eps[1]  = ep0in
  eps[2]  = ep1out  eps[3]  = ep2in
  ...               ...
  eps[12]  = ep6in  eps[13] = ep7in
  eps[14]  = ep8in  eps[15] = ep9in

So increase the index in sequence for the imbalanced endpoint when
epnum is greater than min_eps (min(num_in_eps, num_out_eps)), and the
same time, we should ensure "dep->number" is even numbers are for USB
OUT endpoints, and odd numbers are for USB IN endpoints (Table 6-88 in
the databook).

Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
Signed-off-by: William Wu <william.wu@rock-chips.com>
Change-Id: I1da1af4685a077cf3d60fcd745877ff20e00545a
This commit is contained in:
Frank Wang
2022-06-01 16:45:33 +08:00
committed by Tao Huang
parent 9f450ee283
commit 0de7d2764b
2 changed files with 35 additions and 5 deletions

View File

@@ -285,11 +285,22 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
{
struct dwc3_ep *dep;
u32 windex = le16_to_cpu(wIndex_le);
u32 epnum;
u32 ep, epnum;
u8 num_in_eps, num_out_eps, min_eps;
epnum = (windex & USB_ENDPOINT_NUMBER_MASK) << 1;
if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
epnum |= 1;
num_in_eps = DWC3_NUM_IN_EPS(&dwc->hwparams);
num_out_eps = dwc->num_eps - num_in_eps;
min_eps = min_t(u8, num_in_eps, num_out_eps);
ep = windex & USB_ENDPOINT_NUMBER_MASK;
if (ep + 1 > min_eps && num_in_eps != num_out_eps) {
epnum = ep + min_eps;
} else {
epnum = ep << 1;
if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
epnum |= 1;
}
dep = dwc->eps[epnum];
if (dep == NULL)

View File

@@ -2982,6 +2982,14 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep)
else
size /= 2;
/*
* If enable tx fifos resize, set each in ep maxpacket
* to 1024, it can avoid being dependent on the default
* fifo size, and more flexible use of endpoints.
*/
if (dwc->do_fifo_resize)
size = 1024;
usb_ep_set_maxpacket_limit(&dep->endpoint, size);
dep->endpoint.max_streams = 16;
@@ -3048,13 +3056,24 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
bool direction = epnum & 1;
int ret;
u8 num = epnum >> 1;
u8 num_in_eps, num_out_eps, min_eps;
dep = kzalloc(sizeof(*dep), GFP_KERNEL);
if (!dep)
return -ENOMEM;
num_in_eps = DWC3_NUM_IN_EPS(&dwc->hwparams);
num_out_eps = dwc->num_eps - num_in_eps;
min_eps = min_t(u8, num_in_eps, num_out_eps);
/* reconfig direction and num if num_out_eps != num_in_eps */
if (num + 1 > min_eps && num_in_eps != num_out_eps) {
num = epnum - min_eps;
direction = num + 1 > num_out_eps ? 1 : 0;
}
dep->dwc = dwc;
dep->number = epnum;
dep->number = num << 1 | direction;
dep->direction = direction;
dep->regs = dwc->regs + DWC3_DEP_BASE(epnum);
dwc->eps[epnum] = dep;