From: Andrey Smirnov <andrew.smirnov@gmail.com>
To: barebox@lists.infradead.org
Cc: Andrey Smirnov <andrew.smirnov@gmail.com>
Subject: [PATCH 07/18] usb: host: ehci: Simplify qTD buffer synchronization
Date: Wed, 22 May 2019 00:34:03 -0700 [thread overview]
Message-ID: <20190522073414.9308-8-andrew.smirnov@gmail.com> (raw)
In-Reply-To: <20190522073414.9308-1-andrew.smirnov@gmail.com>
Only two buffers ever need to be sychronized and DMA direction of it
is always known based on the type of request we are
processing. Simplify the code by moving synchronization to be a part
of ehci_prepare_qtd(). While at it convert the code to use
dma_map_single() API.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
drivers/usb/host/ehci-hcd.c | 90 ++++++++++++++++++++-----------------
drivers/usb/host/ehci.h | 2 -
2 files changed, 49 insertions(+), 43 deletions(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ad244637e..9758e1ed7 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -184,15 +184,11 @@ out:
return ret;
}
-static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
+static int ehci_td_buffer(struct qTD *td, dma_addr_t addr, size_t sz)
{
- uint32_t addr, delta, next;
+ uint32_t delta, next;
int idx;
- addr = (uint32_t) buf;
- td->qtd_dma = addr;
- td->length = sz;
-
idx = 0;
while (idx < 5) {
td->qt_buffer[idx] = cpu_to_hc32(addr);
@@ -213,8 +209,11 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
return 0;
}
-static int ehci_prepare_qtd(struct qTD *td, uint32_t token,
- void *buffer, size_t length)
+static int ehci_prepare_qtd(struct device_d *dev,
+ struct qTD *td, uint32_t token,
+ void *buffer, size_t length,
+ dma_addr_t *buffer_dma,
+ enum dma_data_direction dma_direction)
{
int ret;
@@ -226,7 +225,12 @@ static int ehci_prepare_qtd(struct qTD *td, uint32_t token,
td->qt_token = cpu_to_hc32(token);
if (length) {
- ret = ehci_td_buffer(td, buffer, length);
+ *buffer_dma = dma_map_single(dev, buffer, length,
+ dma_direction);
+ if (dma_mapping_error(dev, *buffer_dma))
+ return -EFAULT;
+
+ ret = ehci_td_buffer(td, *buffer_dma, length);
if (ret)
return ret;
}
@@ -257,12 +261,15 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
{
struct usb_host *host = dev->host;
struct ehci_host *ehci = to_ehci(host);
+ const bool dir_in = usb_pipein(pipe);
+ dma_addr_t buffer_dma, req_dma;
struct QH *qh;
struct qTD *td;
uint32_t *tdp;
uint32_t endpt, token, usbsts;
uint32_t c, toggle;
- int ret = 0, i;
+ int ret = 0;
+
dev_dbg(ehci->dev, "pipe=%lx, buffer=%p, length=%d, req=%p\n", pipe,
buffer, length, req);
@@ -320,9 +327,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
if (req != NULL) {
td = &ehci->td[0];
- ret = ehci_prepare_qtd(td, QT_TOKEN_DT(0) | QT_TOKEN_IOC(0) |
+ ret = ehci_prepare_qtd(ehci->dev,
+ td, QT_TOKEN_DT(0) | QT_TOKEN_IOC(0) |
QT_TOKEN_PID(QT_TOKEN_PID_SETUP),
- req, sizeof(*req));
+ req, sizeof(*req),
+ &req_dma, DMA_TO_DEVICE);
if (ret) {
dev_dbg(ehci->dev, "unable construct SETUP td\n");
return ret;
@@ -334,14 +343,25 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
}
if (length > 0 || req == NULL) {
+ enum dma_data_direction dir;
+ unsigned int pid;
+
td = &ehci->td[1];
- ret = ehci_prepare_qtd(td, QT_TOKEN_DT(toggle) |
+ if (dir_in) {
+ dir = DMA_FROM_DEVICE;
+ pid = QT_TOKEN_PID_IN;
+ } else {
+ dir = DMA_TO_DEVICE;
+ pid = QT_TOKEN_PID_OUT;
+ }
+
+ ret = ehci_prepare_qtd(ehci->dev,
+ td, QT_TOKEN_DT(toggle) |
QT_TOKEN_IOC(req == NULL) |
- QT_TOKEN_PID(usb_pipein(pipe) ?
- QT_TOKEN_PID_IN :
- QT_TOKEN_PID_OUT),
- buffer, length);
+ QT_TOKEN_PID(pid),
+ buffer, length,
+ &buffer_dma, dir);
if (ret) {
dev_err(ehci->dev, "unable construct DATA td\n");
return ret;
@@ -353,29 +373,19 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
if (req) {
td = &ehci->td[2];
- ehci_prepare_qtd(td, QT_TOKEN_DT(1) | QT_TOKEN_IOC(1) |
- QT_TOKEN_PID(usb_pipein(pipe) ?
+ ehci_prepare_qtd(ehci->dev,
+ td, QT_TOKEN_DT(1) | QT_TOKEN_IOC(1) |
+ QT_TOKEN_PID(dir_in ?
QT_TOKEN_PID_OUT :
QT_TOKEN_PID_IN),
- NULL, 0);
+ NULL, 0,
+ NULL, DMA_NONE);
*tdp = cpu_to_hc32((uint32_t)td);
tdp = &td->qt_next;
}
ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
- /* Flush dcache */
- if (IS_ENABLED(CONFIG_MMU)) {
- for (i = 0; i < NUM_TD; i ++) {
- struct qTD *qtd = &ehci->td[i];
- if (!qtd->qtd_dma)
- continue;
- dma_sync_single_for_device((unsigned long)qtd->qtd_dma,
- qtd->length,
- DMA_BIDIRECTIONAL);
- }
- }
-
usbsts = ehci_readl(&ehci->hcor->or_usbsts);
ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
@@ -394,15 +404,13 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
return -ETIMEDOUT;
}
- if (IS_ENABLED(CONFIG_MMU)) {
- for (i = 0; i < NUM_TD; i ++) {
- struct qTD *qtd = &ehci->td[i];
- if (!qtd->qtd_dma)
- continue;
- dma_sync_single_for_cpu((unsigned long)qtd->qtd_dma,
- qtd->length, DMA_BIDIRECTIONAL);
- }
- }
+ if (req)
+ dma_unmap_single(ehci->dev, req_dma, sizeof(*req),
+ DMA_TO_DEVICE);
+
+ if (length)
+ dma_unmap_single(ehci->dev, buffer_dma, length,
+ dir_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
ret = ehci_enable_async_schedule(ehci, false);
if (ret < 0) {
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index f82b6a0d1..e88e37e14 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -147,8 +147,6 @@ struct qTD {
#define QT_TOKEN_STATUS_SPLITXSTATE 0x02
#define QT_TOKEN_STATUS_PERR 0x01
uint32_t qt_buffer[5];
- unsigned long qtd_dma;
- size_t length;
} __attribute__ ((aligned (32)));
/* Queue Head (QH). */
--
2.21.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
next prev parent reply other threads:[~2019-05-22 7:34 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-22 7:33 [PATCH 00/18] EHCI improvements Andrey Smirnov
2019-05-22 7:33 ` [PATCH 01/18] usb: host: ehci: Do not zero out DMA coherent memory Andrey Smirnov
2019-05-22 7:33 ` [PATCH 02/18] usb: host: ehci: Share code to enable/disable async schedule Andrey Smirnov
2019-05-22 7:33 ` [PATCH 03/18] usb: host: ehci: Use to USBSTS to wait for transfer completion Andrey Smirnov
2019-05-22 7:34 ` [PATCH 04/18] usb: host: ehci: Replace magic number with macros Andrey Smirnov
2019-05-22 7:34 ` [PATCH 05/18] usb: host: ehci: Drop unnecessary cleanup code Andrey Smirnov
2019-05-22 7:34 ` [PATCH 06/18] usb: host: ehci: Introduce ehci_prepare_qtd() Andrey Smirnov
2019-05-22 7:34 ` Andrey Smirnov [this message]
2019-05-22 7:34 ` [PATCH 08/18] usb: host: ehci: Simplify ehci_td_buffer() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 09/18] usb: host: ehci: Initialize qTDs explicitly Andrey Smirnov
2019-05-22 7:34 ` [PATCH 10/18] usb: host: ehci: Simplify ehci_submit_async()'s epilogue Andrey Smirnov
2019-05-22 7:34 ` [PATCH 11/18] usb: host: ehci: Drop needless assignments in ehci_submit_async() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 12/18] usb: host: ehci: Use bool to simplify ehci_submit_async() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 13/18] usb: host: ehci: Add a comment explaing IOC setting for data Andrey Smirnov
2019-05-22 7:34 ` [PATCH 14/18] usb: host: ehci: Replace explicit printf() with dev_err() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 15/18] usb: host: ehci: Drop explicit memset() in ehci_init() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 16/18] usb: host: ehci: Treat ehci->qh_list as an array Andrey Smirnov
2019-05-22 7:34 ` [PATCH 17/18] ush: host: ehci: Simplify QH initialization in ehci_submit_async() Andrey Smirnov
2019-05-22 7:34 ` [PATCH 18/18] usb: host: ehci: Allocate only NUM_QH queue heads for qh_list Andrey Smirnov
2019-05-23 7:57 ` [PATCH 00/18] EHCI improvements Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190522073414.9308-8-andrew.smirnov@gmail.com \
--to=andrew.smirnov@gmail.com \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox