diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 658739410992..7b5190082aa8 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -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) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 539034cc0e5f..623afe6ba90f 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -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;