From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
Gerd Hoffmann <kraxel@redhat.com>,
qemu-devel@nongnu.org, David Gibson <david@gibson.dropbear.id.au>
Subject: Re: [Qemu-devel] [PATCH 04/13] usb-ohci: Use universal DMA helper functions
Date: Thu, 21 Jun 2012 07:36:08 +1000 [thread overview]
Message-ID: <1340228168.28143.178.camel@pasglop> (raw)
In-Reply-To: <4FE23E30.50302@codemonkey.ws>
> > Cc: Gerd Hoffmann<kraxel@redhat.com>
> > Cc: Michael S. Tsirkin<mst@redhat.com>
> >
> > Signed-off-by: David Gibson<david@gibson.dropbear.id.au>
> > Signed-off-by: Benjamin Herrenschmidt<benh@kernel.crashing.org>
>
>
> So... the DMA api is designed to allow for partial result returns which I
> presume an implementation would use as a simplification.
>
> But none of these callers actually check the return code?
>
> Either errors are important and we need to adjust callees to check them or
> errors aren't important and we should return void.
Errors should matter and I agree callers should check them, this is the
series I inherited and I believe it does need improvements in those
areas (though it would be easier if the driver authors were the one to
do those improvements).
> Why leave pci accessors and not implement usb_memory_rw() wrappers?
Well, "usb" is a bit too generic, ehci and ohci would each need to have
their own sets of wrappers. But yes, that's possible... is it really
worth it ? There's nothing fundamentally wrong with using the dma_*
accessors.
Cheers,
Ben.
> Regards,
>
> Anthony Liguori
>
> > ---
> > hw/usb/hcd-ohci.c | 93 +++++++++++++++++++++++++++++------------------------
> > 1 file changed, 51 insertions(+), 42 deletions(-)
> >
> > diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
> > index 1a1cc88..844e7ed 100644
> > --- a/hw/usb/hcd-ohci.c
> > +++ b/hw/usb/hcd-ohci.c
> > @@ -31,7 +31,7 @@
> > #include "hw/usb.h"
> > #include "hw/pci.h"
> > #include "hw/sysbus.h"
> > -#include "hw/qdev-addr.h"
> > +#include "hw/qdev-dma.h"
> >
> > //#define DEBUG_OHCI
> > /* Dump packet contents. */
> > @@ -62,6 +62,7 @@ typedef struct {
> > USBBus bus;
> > qemu_irq irq;
> > MemoryRegion mem;
> > + DMAContext *dma;
> > int num_ports;
> > const char *name;
> >
> > @@ -104,7 +105,7 @@ typedef struct {
> > uint32_t htest;
> >
> > /* SM501 local memory offset */
> > - target_phys_addr_t localmem_base;
> > + dma_addr_t localmem_base;
> >
> > /* Active packets. */
> > uint32_t old_ctl;
> > @@ -482,14 +483,14 @@ static void ohci_reset(void *opaque)
> >
> > /* Get an array of dwords from main memory */
> > static inline int get_dwords(OHCIState *ohci,
> > - uint32_t addr, uint32_t *buf, int num)
> > + dma_addr_t addr, uint32_t *buf, int num)
> > {
> > int i;
> >
> > addr += ohci->localmem_base;
> >
> > for (i = 0; i< num; i++, buf++, addr += sizeof(*buf)) {
> > - cpu_physical_memory_read(addr, buf, sizeof(*buf));
> > + dma_memory_read(ohci->dma, addr, buf, sizeof(*buf));
> > *buf = le32_to_cpu(*buf);
> > }
> >
> > @@ -498,7 +499,7 @@ static inline int get_dwords(OHCIState *ohci,
> >
> > /* Put an array of dwords in to main memory */
> > static inline int put_dwords(OHCIState *ohci,
> > - uint32_t addr, uint32_t *buf, int num)
> > + dma_addr_t addr, uint32_t *buf, int num)
> > {
> > int i;
> >
> > @@ -506,7 +507,7 @@ static inline int put_dwords(OHCIState *ohci,
> >
> > for (i = 0; i< num; i++, buf++, addr += sizeof(*buf)) {
> > uint32_t tmp = cpu_to_le32(*buf);
> > - cpu_physical_memory_write(addr,&tmp, sizeof(tmp));
> > + dma_memory_write(ohci->dma, addr,&tmp, sizeof(tmp));
> > }
> >
> > return 1;
> > @@ -514,14 +515,14 @@ static inline int put_dwords(OHCIState *ohci,
> >
> > /* Get an array of words from main memory */
> > static inline int get_words(OHCIState *ohci,
> > - uint32_t addr, uint16_t *buf, int num)
> > + dma_addr_t addr, uint16_t *buf, int num)
> > {
> > int i;
> >
> > addr += ohci->localmem_base;
> >
> > for (i = 0; i< num; i++, buf++, addr += sizeof(*buf)) {
> > - cpu_physical_memory_read(addr, buf, sizeof(*buf));
> > + dma_memory_read(ohci->dma, addr, buf, sizeof(*buf));
> > *buf = le16_to_cpu(*buf);
> > }
> >
> > @@ -530,7 +531,7 @@ static inline int get_words(OHCIState *ohci,
> >
> > /* Put an array of words in to main memory */
> > static inline int put_words(OHCIState *ohci,
> > - uint32_t addr, uint16_t *buf, int num)
> > + dma_addr_t addr, uint16_t *buf, int num)
> > {
> > int i;
> >
> > @@ -538,40 +539,40 @@ static inline int put_words(OHCIState *ohci,
> >
> > for (i = 0; i< num; i++, buf++, addr += sizeof(*buf)) {
> > uint16_t tmp = cpu_to_le16(*buf);
> > - cpu_physical_memory_write(addr,&tmp, sizeof(tmp));
> > + dma_memory_write(ohci->dma, addr,&tmp, sizeof(tmp));
> > }
> >
> > return 1;
> > }
> >
> > static inline int ohci_read_ed(OHCIState *ohci,
> > - uint32_t addr, struct ohci_ed *ed)
> > + dma_addr_t addr, struct ohci_ed *ed)
> > {
> > return get_dwords(ohci, addr, (uint32_t *)ed, sizeof(*ed)>> 2);
> > }
> >
> > static inline int ohci_read_td(OHCIState *ohci,
> > - uint32_t addr, struct ohci_td *td)
> > + dma_addr_t addr, struct ohci_td *td)
> > {
> > return get_dwords(ohci, addr, (uint32_t *)td, sizeof(*td)>> 2);
> > }
> >
> > static inline int ohci_read_iso_td(OHCIState *ohci,
> > - uint32_t addr, struct ohci_iso_td *td)
> > + dma_addr_t addr, struct ohci_iso_td *td)
> > {
> > return (get_dwords(ohci, addr, (uint32_t *)td, 4)&&
> > get_words(ohci, addr + 16, td->offset, 8));
> > }
> >
> > static inline int ohci_read_hcca(OHCIState *ohci,
> > - uint32_t addr, struct ohci_hcca *hcca)
> > + dma_addr_t addr, struct ohci_hcca *hcca)
> > {
> > - cpu_physical_memory_read(addr + ohci->localmem_base, hcca, sizeof(*hcca));
> > + dma_memory_read(ohci->dma, addr + ohci->localmem_base, hcca, sizeof(*hcca));
> > return 1;
> > }
> >
> > static inline int ohci_put_ed(OHCIState *ohci,
> > - uint32_t addr, struct ohci_ed *ed)
> > + dma_addr_t addr, struct ohci_ed *ed)
> > {
> > /* ed->tail is under control of the HCD.
> > * Since just ed->head is changed by HC, just write back this
> > @@ -583,64 +584,63 @@ static inline int ohci_put_ed(OHCIState *ohci,
> > }
> >
> > static inline int ohci_put_td(OHCIState *ohci,
> > - uint32_t addr, struct ohci_td *td)
> > + dma_addr_t addr, struct ohci_td *td)
> > {
> > return put_dwords(ohci, addr, (uint32_t *)td, sizeof(*td)>> 2);
> > }
> >
> > static inline int ohci_put_iso_td(OHCIState *ohci,
> > - uint32_t addr, struct ohci_iso_td *td)
> > + dma_addr_t addr, struct ohci_iso_td *td)
> > {
> > return (put_dwords(ohci, addr, (uint32_t *)td, 4)&&
> > put_words(ohci, addr + 16, td->offset, 8));
> > }
> >
> > static inline int ohci_put_hcca(OHCIState *ohci,
> > - uint32_t addr, struct ohci_hcca *hcca)
> > + dma_addr_t addr, struct ohci_hcca *hcca)
> > {
> > - cpu_physical_memory_write(addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
> > - (char *)hcca + HCCA_WRITEBACK_OFFSET,
> > - HCCA_WRITEBACK_SIZE);
> > + dma_memory_write(ohci->dma,
> > + addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
> > + (char *)hcca + HCCA_WRITEBACK_OFFSET,
> > + HCCA_WRITEBACK_SIZE);
> > return 1;
> > }
> >
> > /* 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, int write)
> > + uint8_t *buf, int len, DMADirection dir)
> > {
> > - uint32_t ptr;
> > - uint32_t n;
> > + dma_addr_t ptr, n;
> >
> > ptr = td->cbp;
> > n = 0x1000 - (ptr& 0xfff);
> > if (n> len)
> > n = len;
> > - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
> > + dma_memory_rw(ohci->dma, ptr + ohci->localmem_base, buf, n, dir);
> > if (n == len)
> > return;
> > ptr = td->be& ~0xfffu;
> > buf += n;
> > - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
> > + dma_memory_rw(ohci->dma, ptr + ohci->localmem_base, buf, len - n, dir);
> > }
> >
> > /* 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, int write)
> > + uint8_t *buf, int len, DMADirection dir)
> > {
> > - uint32_t ptr;
> > - uint32_t n;
> > + dma_addr_t ptr, n;
> >
> > ptr = start_addr;
> > n = 0x1000 - (ptr& 0xfff);
> > if (n> len)
> > n = len;
> > - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, n, write);
> > + dma_memory_rw(ohci->dma, ptr + ohci->localmem_base, buf, n, dir);
> > if (n == len)
> > return;
> > ptr = end_addr& ~0xfffu;
> > buf += n;
> > - cpu_physical_memory_rw(ptr + ohci->localmem_base, buf, len - n, write);
> > + dma_memory_rw(ohci->dma, ptr + ohci->localmem_base, buf, len - n, dir);
> > }
> >
> > static void ohci_process_lists(OHCIState *ohci, int completion);
> > @@ -803,7 +803,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
> > }
> >
> > if (len&& dir != OHCI_TD_DIR_IN) {
> > - ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len, 0);
> > + ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len,
> > + DMA_DIRECTION_TO_DEVICE);
> > }
> >
> > if (completion) {
> > @@ -827,7 +828,8 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
> > /* Writeback */
> > if (dir == OHCI_TD_DIR_IN&& ret>= 0&& ret<= len) {
> > /* IN transfer succeeded */
> > - ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret, 1);
> > + ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret,
> > + DMA_DIRECTION_FROM_DEVICE);
> > OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
> > OHCI_CC_NOERROR);
> > OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
> > @@ -971,7 +973,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
> > pktlen = len;
> > }
> > if (!completion) {
> > - ohci_copy_td(ohci,&td, ohci->usb_buf, pktlen, 0);
> > + ohci_copy_td(ohci,&td, ohci->usb_buf, pktlen,
> > + DMA_DIRECTION_TO_DEVICE);
> > }
> > }
> > }
> > @@ -1021,7 +1024,8 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
> > }
> > if (ret>= 0) {
> > if (dir == OHCI_TD_DIR_IN) {
> > - ohci_copy_td(ohci,&td, ohci->usb_buf, ret, 1);
> > + ohci_copy_td(ohci,&td, ohci->usb_buf, ret,
> > + DMA_DIRECTION_FROM_DEVICE);
> > #ifdef DEBUG_PACKET
> > DPRINTF(" data:");
> > for (i = 0; i< ret; i++)
> > @@ -1748,11 +1752,14 @@ static USBBusOps ohci_bus_ops = {
> > };
> >
> > static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
> > - int num_ports, uint32_t localmem_base,
> > - char *masterbus, uint32_t firstport)
> > + int num_ports, dma_addr_t localmem_base,
> > + char *masterbus, uint32_t firstport,
> > + DMAContext *dma)
> > {
> > int i;
> >
> > + ohci->dma = dma;
> > +
> > if (usb_frame_time == 0) {
> > #ifdef OHCI_TIME_WARP
> > usb_frame_time = get_ticks_per_sec();
> > @@ -1817,7 +1824,8 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
> > ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */
> >
> > if (usb_ohci_init(&ohci->state,&dev->qdev, ohci->num_ports, 0,
> > - ohci->masterbus, ohci->firstport) != 0) {
> > + ohci->masterbus, ohci->firstport,
> > + pci_dma_context(dev)) != 0) {
> > return -1;
> > }
> > ohci->state.irq = ohci->pci_dev.irq[0];
> > @@ -1831,7 +1839,7 @@ typedef struct {
> > SysBusDevice busdev;
> > OHCIState ohci;
> > uint32_t num_ports;
> > - target_phys_addr_t dma_offset;
> > + dma_addr_t dma_offset;
> > } OHCISysBusState;
> >
> > static int ohci_init_pxa(SysBusDevice *dev)
> > @@ -1839,7 +1847,8 @@ static int ohci_init_pxa(SysBusDevice *dev)
> > OHCISysBusState *s = FROM_SYSBUS(OHCISysBusState, dev);
> >
> > /* Cannot fail as we pass NULL for masterbus */
> > - usb_ohci_init(&s->ohci,&dev->qdev, s->num_ports, s->dma_offset, NULL, 0);
> > + usb_ohci_init(&s->ohci,&dev->qdev, s->num_ports, s->dma_offset, NULL, 0,
> > + NULL);
> > sysbus_init_irq(dev,&s->ohci.irq);
> > sysbus_init_mmio(dev,&s->ohci.mem);
> >
> > @@ -1875,7 +1884,7 @@ static TypeInfo ohci_pci_info = {
> >
> > static Property ohci_sysbus_properties[] = {
> > DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3),
> > - DEFINE_PROP_TADDR("dma-offset", OHCISysBusState, dma_offset, 3),
> > + DEFINE_PROP_DMAADDR("dma-offset", OHCISysBusState, dma_offset, 3),
> > DEFINE_PROP_END_OF_LIST(),
> > };
> >
next prev parent reply other threads:[~2012-06-20 21:36 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-19 6:39 [Qemu-devel] [PATCH 00/13] iommu series Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 01/13] Better support for dma_addr_t variables Benjamin Herrenschmidt
2012-06-20 21:14 ` Anthony Liguori
2012-06-20 21:29 ` Benjamin Herrenschmidt
2012-06-21 1:44 ` David Gibson
2012-06-20 22:26 ` Peter Maydell
2012-06-20 22:59 ` Anthony Liguori
2012-06-21 7:54 ` Peter Maydell
2012-06-22 1:58 ` Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 02/13] Implement cpu_physical_memory_set() Benjamin Herrenschmidt
2012-06-20 21:15 ` Anthony Liguori
2012-06-20 21:30 ` Benjamin Herrenschmidt
2012-06-20 21:37 ` Anthony Liguori
2012-06-21 1:45 ` David Gibson
2012-06-21 1:46 ` David Gibson
2012-06-21 2:50 ` Benjamin Herrenschmidt
2012-06-22 1:58 ` Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 03/13] iommu: Add universal DMA helper functions Benjamin Herrenschmidt
2012-06-20 21:16 ` Anthony Liguori
2012-06-20 21:32 ` Michael S. Tsirkin
2012-06-20 21:38 ` Anthony Liguori
2012-06-20 21:42 ` Michael S. Tsirkin
2012-06-20 21:46 ` Anthony Liguori
2012-06-20 22:00 ` Michael S. Tsirkin
2012-06-20 21:33 ` Benjamin Herrenschmidt
2012-06-20 21:40 ` Michael S. Tsirkin
2012-06-20 22:01 ` Anthony Liguori
2012-06-21 1:48 ` David Gibson
2012-06-22 2:02 ` Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 04/13] usb-ohci: Use " Benjamin Herrenschmidt
2012-06-20 21:18 ` Anthony Liguori
2012-06-20 21:36 ` Benjamin Herrenschmidt [this message]
2012-06-20 21:40 ` Anthony Liguori
2012-06-20 22:02 ` Benjamin Herrenschmidt
2012-06-21 7:33 ` Michael S. Tsirkin
2012-06-21 12:55 ` Anthony Liguori
2012-06-21 14:10 ` Michael S. Tsirkin
2012-06-22 2:28 ` Benjamin Herrenschmidt
2012-06-21 6:43 ` Gerd Hoffmann
2012-06-19 6:39 ` [Qemu-devel] [PATCH 05/13] iommu: Make sglists and dma_bdrv helpers use new universal DMA helpers Benjamin Herrenschmidt
2012-06-20 21:21 ` Anthony Liguori
2012-06-20 21:37 ` Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 06/13] ide/ahci: Use universal DMA helper functions Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 07/13] usb: Convert usb_packet_{map, unmap} to universal DMA helpers Benjamin Herrenschmidt
2012-06-19 13:42 ` Gerd Hoffmann
2012-06-19 20:23 ` Benjamin Herrenschmidt
2012-06-20 3:14 ` David Gibson
2012-06-20 3:52 ` Benjamin Herrenschmidt
2012-06-21 1:42 ` David Gibson
2012-06-20 6:25 ` Gerd Hoffmann
2012-06-20 9:25 ` Benjamin Herrenschmidt
2012-06-20 9:54 ` Gerd Hoffmann
2012-06-19 6:39 ` [Qemu-devel] [PATCH 08/13] iommu: Introduce IOMMU emulation infrastructure Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 09/13] iommu: Add facility to cancel in-use dma memory maps Benjamin Herrenschmidt
2012-06-20 21:25 ` Anthony Liguori
2012-06-20 21:52 ` Benjamin Herrenschmidt
2012-06-22 3:18 ` Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 10/13] pseries: Convert sPAPR TCEs to use generic IOMMU infrastructure Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 11/13] iommu: Allow PCI to use " Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 12/13] pseries: Implement IOMMU and DMA for PAPR PCI devices Benjamin Herrenschmidt
2012-06-19 6:39 ` [Qemu-devel] [PATCH 13/13] Add a memory barrier to DMA functions Benjamin Herrenschmidt
2012-06-20 21:12 ` [Qemu-devel] [PATCH 00/13] iommu series Anthony Liguori
-- strict thread matches above, loose matches on Subject: below --
2012-05-10 4:48 [Qemu-devel] [PATCH 00/13] IOMMU infrastructure Benjamin Herrenschmidt
2012-05-10 4:48 ` [Qemu-devel] [PATCH 04/13] usb-ohci: Use universal DMA helper functions 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=1340228168.28143.178.camel@pasglop \
--to=benh@kernel.crashing.org \
--cc=anthony@codemonkey.ws \
--cc=david@gibson.dropbear.id.au \
--cc=kraxel@redhat.com \
--cc=mst@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).