Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 13 Oct 2014 17:41:18 -0600
From:      Ian Lepore <ian@FreeBSD.org>
To:        Martin Galvan <omgalvan.86@gmail.com>
Cc:        freebsd-drivers@freebsd.org, freebsd-embedded@freebsd.org
Subject:   Re: A few questions about SD/MMC drivers
Message-ID:  <1413243678.12052.376.camel@revolution.hippie.lan>
In-Reply-To: <CAN19L9G8peskHjaYGrUO5ga6oq3PmUy-fqtyKnQoJ2-B4p-=EA@mail.gmail.com>
References:  <CAN19L9ENsuAR6_aXwJSRdfDz6UgE6kU%2BrCkGGsdK7tRcUes%2B0w@mail.gmail.com> <20141006171521.GD26076@kib.kiev.ua> <CAN19L9E0K4rhffRwAo-oyxtajCy4R3Y1bF%2BS7RkSD-NKA_MH%2BA@mail.gmail.com> <0B7F1C7B-7E38-48FD-B3CF-A4512A45E4C0@bsdimp.com> <CAN19L9G8peskHjaYGrUO5ga6oq3PmUy-fqtyKnQoJ2-B4p-=EA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2014-10-13 at 20:25 -0300, Martin Galvan wrote:
> 2014-10-13 11:57 GMT-03:00 Warner Losh <imp@bsdimp.com>:
> > On Oct 12, 2014, at 11:24 PM, Martin Galvan <omgalvan.86@gmail.com> wrote:
> >> The host found in Allwinner SoCs uses a DMA controller which works
> >> with a linked list of descriptors, each having info on a data buffer.
> >> In the Linux driver they allocate a coherent DMA buffer using
> >> dma_alloc_coherent to get both the virtual and bus addresses of the
> >> descriptor list. When it's time to do a DMA transfer, the Linux driver
> >> allocates a scatterlist with each entry being a buffer corresponding
> >> to a descriptor; it then loops through the descriptor list setting the
> >> "buffer pointer" field of each one to the bus address of the
> >> corresponding scatterlist entry, and the "next descriptor" to the bus
> >> address of the following descriptor. It's pretty neat, though it's
> >> worth mentioning the scatterlist that the MMC request handler maps
> >> already contains the virtual addresses of the requested buffers.
> >>
> >> Do we have anything like that on BSD? If not, what would be a simple
> >> algorithm to make this work?
> >
> > Pretty much all of that is covered in busdma(8). The mechanics are a bit
> > different than Linux, sure, but all that functionality is there.
> 
> Actually, other than being able to alloc DMA buffers and get their bus
> addresses I didn't see anything like the Linux scatterlists.
> 
> The main problem here is that the Linux mmc_data struct comes with an
> already-filled scatterlist. In that case, all I have to do is build
> the descriptor chain with the buffer addresses from the scatterlist
> entries. The only thing that's similar to that in the BSD API is
> mbuf_sg, which is used for network stuff. I didn't see anything that
> could allow me to build a descriptor chain-- all I saw was that the
> BSD mmc_data type has a buffer instead of a scatterlist.
> 
> I'm thinking of telling the DMA controller to work with a single
> descriptor whose buffer is the one that comes inside mmc_data, but I'm
> not sure if this would be right.
> 
> Again thanks a lot for your answers.

When you map the buffer with bus_dmamap_load() your callback function is
passed an array of bus_dma_segment structures, each element of the array
is the physical address and size of a contiguous physical segment that
makes up part of the overall buffer.  You are g'teed not to get more
segments than the limit specified in the dma tag used for the map (but
that just means the map function fails if there are too many segments,
not that some sort of automatic copy/consolidate is done for you).  In
general you won't have a problem if you handle (512 * MAX_DATA +
PAGE_SIZE - 1) / PAGE_SIZE segments (MAX_DATA is a horrible ivar name
but I guess we're stuck with it now).

If you need a linked list rather than an array of physical addr/size
tuples, you'll have to write a callback function that creates the list
from the array.

-- Ian





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1413243678.12052.376.camel>