SV: A few questions about SD/MMC drivers

tony moseby xmoseby at yahoo.se
Fri Dec 23 21:40:02 UTC 2016


Hello Ian,
I can read that you have been involved in a similar problem that I am facing now.I am running FreeBSD 8.2 and a armv5TE (marvel mv78100), I have an ssd disk(4Giga).While running the system and doing disk acesses  after sometime (can be days or at least several hours)the system total freezes.Serial port freezes and  ethernet freezes.(just internal connections, no public).
If I do not use the disk, this(the freeze) do not occur.My watchdog is disabled , so I am suspecting that the kernel crashes and that is the cause of the freeze.I connected an emulator to  the board, but whenever the freeze occur,the emulator looses also contactwith the CPU.I have tested to do a lot of read/write towards the ssd,often this also causes freeze, but for a coupleof times I can see the kernel crashing with alignment fault 1.Do you have any ideas?ThanksBR/T


 

    Den tisdag, 14 oktober 2014 2:29 skrev Warner Losh <imp at bsdimp.com>:
 

 The buffer is always contiguous in virtual space, but maybe not necessarily
in physical space, hence the need for SG list. For buffers smaller than one
page, the difference doesn’t matter :) But with multi-block support, you’ll
need to cope with the difference.

Warner

On Oct 13, 2014, at 6:19 PM, Martin Galvan <omgalvan.86 at gmail.com> wrote:

> Well, that makes sense now. I'll try it out and let you know if it
> worked, thanks a ton!
> 
> Just to be clear, though (and forgive me for my ignorance on this
> matter): is the "buffer" referenced in mmc_data always contiguous in
> memory? If so, why use segments/scatterlists at all? I thought the
> whole point of using descriptor lists in DMA transfers was to work
> with portions of memory that weren't next to each other. If the data
> we want to transfer is all in a single contiguous region, wouldn't a
> single descriptor with the required bus address and buffer length be
> enough?
> 
> 2014-10-13 20:41 GMT-03:00 Ian Lepore <ian at freebsd.org>:
>> On Mon, 2014-10-13 at 20:25 -0300, Martin Galvan wrote:
>>> 2014-10-13 11:57 GMT-03:00 Warner Losh <imp at bsdimp.com>:
>>>> On Oct 12, 2014, at 11:24 PM, Martin Galvan <omgalvan.86 at 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
>> 
>> 


   


More information about the freebsd-embedded mailing list