Date: Fri, 23 Dec 2016 21:25:43 +0000 (UTC) From: tony moseby <xmoseby@yahoo.se> To: Warner Losh <imp@bsdimp.com>, Martin Galvan <omgalvan.86@gmail.com> Cc: "freebsd-drivers@freebsd.org" <freebsd-drivers@freebsd.org>, Ian Lepore <ian@freebsd.org>, "freebsd-embedded@freebsd.org" <freebsd-embedded@freebsd.org> Subject: SV: A few questions about SD/MMC drivers Message-ID: <2053136483.1957700.1482528343527@mail.yahoo.com> References: <2053136483.1957700.1482528343527.ref@mail.yahoo.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Hello Ian, I can read that you have been involved in a similar problem that I am facin= g now.I am running FreeBSD 8.2 and a armv5TE (marvel mv78100), I have an ss= d disk(4Giga).While running the system and doing disk acesses=C2=A0 after s= ometime (can be days or at least several hours)the system total freezes.Ser= ial port freezes and=C2=A0 ethernet freezes.(just internal connections, no = public). If I do not use the disk, this(the freeze) do not occur.My watchdog is disa= bled , so I am suspecting that the kernel crashes and that is the cause of = the freeze.I connected an emulator to=C2=A0 the board, but whenever the fre= eze 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 yo= u have any ideas?ThanksBR/T =20 Den tisdag, 14 oktober 2014 2:29 skrev Warner Losh <imp@bsdimp.com>: =20 The buffer is always contiguous in virtual space, but maybe not necessaril= y in physical space, hence the need for SG list. For buffers smaller than one page, the difference doesn=E2=80=99t matter :) But with multi-block support= , you=E2=80=99ll need to cope with the difference. Warner On Oct 13, 2014, at 6:19 PM, Martin Galvan <omgalvan.86@gmail.com> wrote: > Well, that makes sense now. I'll try it out and let you know if it > worked, thanks a ton! >=20 > 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? >=20 > 2014-10-13 20:41 GMT-03:00 Ian Lepore <ian@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@bsdimp.com>: >>>> On Oct 12, 2014, at 11:24 PM, Martin Galvan <omgalvan.86@gmail.com> wr= ote: >>>>> 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 drive= r >>>>> allocates a scatterlist with each entry being a buffer corresponding >>>>> to a descriptor; it then loops through the descriptor list setting th= e >>>>> "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. >>>>>=20 >>>>> Do we have anything like that on BSD? If not, what would be a simple >>>>> algorithm to make this work? >>>>=20 >>>> Pretty much all of that is covered in busdma(8). The mechanics are a b= it >>>> different than Linux, sure, but all that functionality is there. >>>=20 >>> Actually, other than being able to alloc DMA buffers and get their bus >>> addresses I didn't see anything like the Linux scatterlists. >>>=20 >>> 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. >>>=20 >>> 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. >>>=20 >>> Again thanks a lot for your answers. >>=20 >> 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.=C2=A0 You are g'teed not to get mor= e >> 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).=C2=A0= 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). >>=20 >> 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. >>=20 >> -- Ian >>=20 >>=20 =20
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?2053136483.1957700.1482528343527>