mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user