In case of OTG mode, with an OTG adapter plugged, the dwc2_check_param_tx_fifo_sizes function reads DPTXFSIZN registers while the controller is in Host mode, and, because DPTXFSIZN registers are Device specific registers, the values read are 0. Then, g_tx_fifo_size[fifo] values are considered invalid because in the comparison test, they need to be greater than min and lower than dptxfszn which is 0. To fix this issue, force the controller in device mode if needed before reading the DPTXFSIZN registers, and restore the previous mode if needed after reading. Fixes: 3c6aea7344c3 ("usb: dwc2: gadget: Add checking for g-tx-fifo-size parameter") Signed-off-by: Amelie Delaunay <amelie.delaunay@xxxxxx> --- drivers/usb/dwc2/params.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/dwc2/params.c b/drivers/usb/dwc2/params.c index ef73af6..302fefb 100644 --- a/drivers/usb/dwc2/params.c +++ b/drivers/usb/dwc2/params.c @@ -469,6 +469,7 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) int fifo; int min; u32 total = 0; + bool forced; u32 dptxfszn; fifo_count = dwc2_hsotg_tx_fifo_count(hsotg); @@ -483,6 +484,12 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) dwc2_set_param_tx_fifo_sizes(hsotg); } + /* + * Reading DPTXFSIZN registers requires the controller to be in device + * mode. The mode will be forced, if necessary, to read these values. + */ + forced = dwc2_force_mode_if_needed(hsotg, false); + for (fifo = 1; fifo <= fifo_count; fifo++) { dptxfszn = (dwc2_readl(hsotg->regs + DPTXFSIZN(fifo)) & FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT; @@ -495,6 +502,9 @@ static void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg) hsotg->params.g_tx_fifo_size[fifo] = dptxfszn; } } + + if (forced) + dwc2_clear_force_mode(hsotg); } #define CHECK_RANGE(_param, _min, _max, _def) do { \ -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html