Fix two errors in transfer len calculation, move loop invariant code out
of loop.

If xfer_len is equal to CONFIG_DWC2_MAX_TRANSFER_SIZE (or slightly
smaller), the xfer_len will be to large, e.g.:
  xfer_len = MAX_TRANSFER_SIZE = 65535
  max packet size = 512
    => num_packets = 128
    => IN xfer_len = 65536

For OUT transactions larger than (65536 - mps) bytes, the xfer_len
determination is quite awkward, it is only correct due to:
- max_packet_size for control/bulk/interrupt is required to be
  power-of-two.
- (CONFIG_DWC2_MAX_TRANSFER_SIZE + 1) % max-packet-size is zero
  for all allowed (2^3 ... 2^9) packet sizes

As the max xfer len is loop invariant, it can be moved out of the loop.

Signed-off-by: Stefan Brüns <stefan.bru...@rwth-aachen.de>
---
 drivers/usb/host/dwc2.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c
index 5ef6deb..d317104 100644
--- a/drivers/usb/host/dwc2.c
+++ b/drivers/usb/host/dwc2.c
@@ -786,34 +786,34 @@ int chunk_msg(struct dwc2_priv *priv, struct usb_device 
*dev,
        uint32_t xfer_len;
        uint32_t num_packets;
        int stop_transfer = 0;
+       uint32_t max_xfer_len;
 
        debug("%s: msg: pipe %lx pid %d in %d len %d\n", __func__, pipe, *pid,
              in, len);
 
+       max_xfer_len = CONFIG_DWC2_MAX_PACKET_COUNT * max;
+       if (max_xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
+               max_xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE;
+       if (max_xfer_len > DWC2_DATA_BUF_SIZE)
+               max_xfer_len = DWC2_DATA_BUF_SIZE;
+
+       /* Make sure that max_xfer_len is a multiple of max packet size. */
+       num_packets = max_xfer_len / max;
+       max_xfer_len = num_packets * max;
+
        do {
                /* Initialize channel */
                dwc_otg_hc_init(regs, DWC2_HC_CHANNEL, dev, devnum, ep, in,
                                eptype, max);
 
                xfer_len = len - done;
-               if (xfer_len > CONFIG_DWC2_MAX_TRANSFER_SIZE)
-                       xfer_len = CONFIG_DWC2_MAX_TRANSFER_SIZE - max + 1;
-               if (xfer_len > DWC2_DATA_BUF_SIZE)
-                       xfer_len = DWC2_DATA_BUF_SIZE - max + 1;
 
-               /* Make sure that xfer_len is a multiple of max packet size. */
-               if (xfer_len > 0) {
+               if (xfer_len > max_xfer_len)
+                       xfer_len = max_xfer_len;
+               else if (xfer_len > max)
                        num_packets = (xfer_len + max - 1) / max;
-                       if (num_packets > CONFIG_DWC2_MAX_PACKET_COUNT) {
-                               num_packets = CONFIG_DWC2_MAX_PACKET_COUNT;
-                               xfer_len = num_packets * max;
-                       }
-               } else {
+               else
                        num_packets = 1;
-               }
-
-               if (in)
-                       xfer_len = num_packets * max;
 
                debug("%s: chunk: pid %d xfer_len %u pkts %u\n", __func__,
                      *pid, xfer_len, num_packets);
-- 
2.1.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to