From: Alexey Kardashevskiy <aik@ozlabs.ru>
To: qemu-devel@nongnu.org
Cc: aik@ozlabs.ru, Anthony Liguori <aliguori@us.ibm.com>,
Alexander Graf <agraf@suse.de>, Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH] RFC: hcd-ohci: add dma error handling
Date: Wed, 17 Jul 2013 19:46:05 +1000 [thread overview]
Message-ID: <1374054365-27001-1-git-send-email-aik@ozlabs.ru> (raw)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Current hcd-ohci does not handle DMA errors which can actually
happen.
However it is not clear what approach should be used here -
for example, get_dwords returns positive number saying that there
is no error as all the callers consider the return value as fail
if it is less than zero. Normally you would expect bool=true/int=0
as success and bool=false/int=-1 as fail.
Any suggestion?
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
hw/usb/hcd-ohci.c | 77 +++++++++++++++++++++++++++++++++++++------------------
1 file changed, 52 insertions(+), 25 deletions(-)
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index a096ecf..48297da 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -508,7 +508,9 @@ static inline int get_dwords(OHCIState *ohci,
addr += ohci->localmem_base;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- dma_memory_read(ohci->as, addr, buf, sizeof(*buf));
+ if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) {
+ return -1;
+ }
*buf = le32_to_cpu(*buf);
}
@@ -525,7 +527,9 @@ static inline int put_dwords(OHCIState *ohci,
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
uint32_t tmp = cpu_to_le32(*buf);
- dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp));
+ if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) {
+ return -1;
+ }
}
return 1;
@@ -540,7 +544,9 @@ static inline int get_words(OHCIState *ohci,
addr += ohci->localmem_base;
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
- dma_memory_read(ohci->as, addr, buf, sizeof(*buf));
+ if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) {
+ return -1;
+ }
*buf = le16_to_cpu(*buf);
}
@@ -557,7 +563,9 @@ static inline int put_words(OHCIState *ohci,
for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
uint16_t tmp = cpu_to_le16(*buf);
- dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp));
+ if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) {
+ return -1;
+ }
}
return 1;
@@ -585,8 +593,8 @@ static inline int ohci_read_iso_td(OHCIState *ohci,
static inline int ohci_read_hcca(OHCIState *ohci,
dma_addr_t addr, struct ohci_hcca *hcca)
{
- dma_memory_read(ohci->as, addr + ohci->localmem_base, hcca, sizeof(*hcca));
- return 1;
+ return dma_memory_read(ohci->as, addr + ohci->localmem_base,
+ hcca, sizeof(*hcca)) ? -1 : 0;
}
static inline int ohci_put_ed(OHCIState *ohci,
@@ -617,16 +625,15 @@ static inline int ohci_put_iso_td(OHCIState *ohci,
static inline int ohci_put_hcca(OHCIState *ohci,
dma_addr_t addr, struct ohci_hcca *hcca)
{
- dma_memory_write(ohci->as,
- addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
- (char *)hcca + HCCA_WRITEBACK_OFFSET,
- HCCA_WRITEBACK_SIZE);
- return 1;
+ return dma_memory_write(ohci->as,
+ addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
+ (char *)hcca + HCCA_WRITEBACK_OFFSET,
+ HCCA_WRITEBACK_SIZE) ? -1 : 0;
}
/* Read/Write the contents of a TD from/to main memory. */
-static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
- uint8_t *buf, int len, DMADirection dir)
+static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
+ uint8_t *buf, int len, DMADirection dir)
{
dma_addr_t ptr, n;
@@ -634,18 +641,26 @@ static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
n = 0x1000 - (ptr & 0xfff);
if (n > len)
n = len;
- dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir);
- if (n == len)
- return;
+
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+ return -1;
+ }
+ if (n == len) {
+ return 0;
+ }
ptr = td->be & ~0xfffu;
buf += n;
- dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, len - n, dir);
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+ len - n, dir)) {
+ return -1;
+ }
+ return 0;
}
/* Read/Write the contents of an ISO TD from/to main memory. */
-static void ohci_copy_iso_td(OHCIState *ohci,
- uint32_t start_addr, uint32_t end_addr,
- uint8_t *buf, int len, DMADirection dir)
+static int ohci_copy_iso_td(OHCIState *ohci,
+ uint32_t start_addr, uint32_t end_addr,
+ uint8_t *buf, int len, DMADirection dir)
{
dma_addr_t ptr, n;
@@ -653,12 +668,20 @@ static void ohci_copy_iso_td(OHCIState *ohci,
n = 0x1000 - (ptr & 0xfff);
if (n > len)
n = len;
- dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir);
- if (n == len)
- return;
+
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+ return -1;
+ }
+ if (n == len) {
+ return 0;
+ }
ptr = end_addr & ~0xfffu;
buf += n;
- dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, len - n, dir);
+ if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+ len - n, dir)) {
+ return -1;
+ }
+ return 0;
}
static void ohci_process_lists(OHCIState *ohci, int completion);
@@ -1236,7 +1259,11 @@ static void ohci_frame_boundary(void *opaque)
OHCIState *ohci = opaque;
struct ohci_hcca hcca;
- ohci_read_hcca(ohci, ohci->hcca, &hcca);
+ if (ohci_read_hcca(ohci, ohci->hcca, &hcca)) {
+ fprintf(stderr, "usb-ohci: HCCA read error at %x\n", ohci->hcca);
+ /* TODO: Add signaling of DMA errors to the guest */
+ return;
+ }
/* Process all the lists at the end of the frame */
if (ohci->ctl & OHCI_CTL_PLE) {
--
1.8.3.2
next reply other threads:[~2013-07-17 9:46 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-17 9:46 Alexey Kardashevskiy [this message]
2013-07-17 11:15 ` [Qemu-devel] [PATCH] RFC: hcd-ohci: add dma error handling Benjamin Herrenschmidt
2013-07-17 12:31 ` Alexander Graf
2013-07-17 12:47 ` Benjamin Herrenschmidt
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=1374054365-27001-1-git-send-email-aik@ozlabs.ru \
--to=aik@ozlabs.ru \
--cc=agraf@suse.de \
--cc=aliguori@us.ibm.com \
--cc=kraxel@redhat.com \
--cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).