
Dear Benoît Thébaudeau,
Relax the qTD transfer alignment constraints in order to need less qTDs for buffers that are aligned to 512 bytes but not to pages.
Signed-off-by: Benoît Thébaudeau benoit.thebaudeau@advansee.com Cc: Marek Vasut marex@denx.de Cc: Ilya Yanok ilya.yanok@cogentembedded.com Cc: Stefan Herbrechtsmeier stefan@herbrechtsmeier.net
Changes for v2: N/A. Changes for v3:
- New patch.
.../drivers/usb/host/ehci-hcd.c | 68 +++++++++++--------- 1 file changed, 38 insertions(+), 30 deletions(-)
diff --git u-boot-usb-8d5fb14.orig/drivers/usb/host/ehci-hcd.c u-boot-usb-8d5fb14/drivers/usb/host/ehci-hcd.c index 84c7d08..37517cb 100644 --- u-boot-usb-8d5fb14.orig/drivers/usb/host/ehci-hcd.c +++ u-boot-usb-8d5fb14/drivers/usb/host/ehci-hcd.c @@ -215,7 +215,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, volatile struct qTD *vtd; unsigned long ts; uint32_t *tdp;
- uint32_t endpt, token, usbsts;
- uint32_t endpt, maxpacket, token, usbsts; uint32_t c, toggle; uint32_t cmd; int timeout;
@@ -230,6 +230,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, le16_to_cpu(req->value), le16_to_cpu(req->value), le16_to_cpu(req->index));
+#define PKT_ALIGN 512
Make this const int maybe ?
/* * The USB transfer is split into qTD transfers. Eeach qTD transfer is * described by a transfer descriptor (the qTD). The qTDs form a linked @@ -251,43 +252,41 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, if (length > 0 || req == NULL) { /* * Determine the qTD transfer size that will be used for the
* data payload (not considering the final qTD transfer, which
* may be shorter).
* data payload (not considering the first qTD transfer, which
* may be longer or shorter, and the final one, which may be
* shorter).
- In order to keep each packet within a qTD transfer, the qTD
* transfer size is aligned to EHCI_PAGE_SIZE, which is a
* multiple of wMaxPacketSize (except in some cases for
* interrupt transfers, see comment in submit_int_msg()).
* transfer size is aligned to PKT_ALIGN, which is a multiple of
* wMaxPacketSize (except in some cases for interrupt transfers,
* see comment in submit_int_msg()).
* By default, i.e. if the input buffer is page-aligned,
* By default, i.e. if the input buffer is aligned to PKT_ALIGN,
*/ int xfr_sz = QT_BUFFER_CNT; /*
- QT_BUFFER_CNT full pages will be used.
* However, if the input buffer is not page-aligned, the qTD
* transfer size will be one page shorter, and the first qTD
* However, if the input buffer is not aligned to PKT_ALIGN, the
* qTD transfer size will be one page shorter, and the first qTD
*/
- data buffer of each transfer will be page-unaligned.
if ((uint32_t)buffer & (EHCI_PAGE_SIZE - 1))
/* Convert the qTD transfer size to bytes. */ xfr_sz *= EHCI_PAGE_SIZE; /*if ((uint32_t)buffer & (PKT_ALIGN - 1)) xfr_sz--;
* Determine the number of qTDs that will be required for the
* data payload. This value has to be rounded up since the final
* qTD transfer may be shorter than the regular qTD transfer
* size that has just been computed.
* Approximate by excess the number of qTDs that will be
* required for the data payload. The exact formula is way more
* complicated and saves at most 2 qTDs, i.e. a total of 128
*/* bytes.
qtd_count += DIV_ROUND_UP(length, xfr_sz);
/* ZLPs also need a qTD. */
if (!qtd_count)
qtd_count++;
}qtd_count += 2 + length / xfr_sz;
/*
- Threshold value based on the worst-case total size of the qTDs to
allocate - * for a mass-storage transfer of 65535 blocks of 512 bytes.
- Threshold value based on the worst-case total size of the allocated
qTDs for + * a mass-storage transfer of 65535 blocks of 512 bytes. */ -#if CONFIG_SYS_MALLOC_LEN <= 128 * 1024 +#if CONFIG_SYS_MALLOC_LEN <= 64 + 128 * 1024 #warning CONFIG_SYS_MALLOC_LEN may be too small for EHCI #endif qtd = memalign(USB_DMA_MINALIGN, qtd_count * sizeof(struct qTD)); @@ -314,9 +313,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, qh->qh_link = cpu_to_hc32((uint32_t)qh_list | QH_LINK_TYPE_QH); c = (usb_pipespeed(pipe) != USB_SPEED_HIGH && usb_pipeendpoint(pipe) == 0);
- maxpacket = usb_maxpacket(dev, pipe); endpt = (8 << QH_ENDPT1_RL) | (c << QH_ENDPT1_C) |
(usb_maxpacket(dev, pipe) << QH_ENDPT1_MAXPKTLEN) |
(maxpacket << QH_ENDPT1_MAXPKTLEN) |
Is this change really needed? (not that I care much).
[...]
Took me a bit to make it through, but I think I get it ... just real nits above.