From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Michael Kerrisk" Subject: Re: [PATCH 1/1] Userspace I/O (UIO): Documentatin for userspace DMA support Date: Thu, 4 Dec 2008 08:14:41 -0500 Message-ID: References: <208aa0f00812032053w5efb99dbk94511b0f8c1f0925@mail.gmail.com> Reply-To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <208aa0f00812032053w5efb99dbk94511b0f8c1f0925-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org> Content-Disposition: inline Sender: linux-api-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: Edward Estabrook Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Greg KH , hjk-hfZtesqFncYOwBW4kG4KsQ@public.gmane.org, edward_estabrook-+2HdxjxtzLdBDgjK7y7TUQ@public.gmane.org List-Id: linux-api@vger.kernel.org Edward, A few small comments below On Wed, Dec 3, 2008 at 11:53 PM, Edward Estabrook wrote: > From: Edward Estabrook > > Here is a patch updating the Userspace IO documentation to > detail support to dynamically allocate and use coherent DMA > from userspace. This patch applies against 2.6.28-rc6. > > The gist of this implementation is to overload uio's mmap Sometimes you write "uio", sometimes "UIO". Use just one? > functionality to allocate > and map a new DMA region on demand. The bus-specific DMA address as returned by > dma_alloc_coherent() is made available to userspace in the 1st long > word Perhaps use a clearer term than "long word"? Maybe '8 bytes'? > of the newly > created region (as well as through the conventional 'addr' file in sysfs). > > The kernel-api change is that passing an offset value of 0xFFFFF000UL to a uio s/api/API/ > device's mmap() operation will dynamically allocate a DMA region. This cannot > break existing code as the previous UIO code only allowed a maximum of 5 > mappings. > > To allocate a DMA region you use the following: > /* Pass this magic number to mmap as offset to > * dynamically allocate a chunk of memory */ > #define DMA_MEM_ALLOCATE_MMAP_OFFSET 0xFFFFF000UL > > void* memory = mmap (NULL, size, PROT_READ | PROT_WRITE , MAP_SHARED, > fd, DMA_MEM_ALLOCATE_MMAP_OFFSET); > u_int64_t *addr = *(u_int64_t *) memory; > > where 'size' is the size in bytes of the region you want and fd is the s/fd/'fd'/ (consistent with 'size') > opened /dev/uioN file. > > Allocation occurs in page sized pieces by design to ensure that s/page sized pieces/page-sized pieces/ > buffers are page-aligned. > > Memory is released when the uio_unregister_device() is called. Cheers, Michael > Signed-off-by: Edward Estabrook > --- > --- linux-2.6.28-rc6/Documentation/DocBook/uio-howto.tmpl.orig 2008-12-03 > 12:03:43.000000000 -0800 > +++ linux-2.6.28-rc6/Documentation/DocBook/uio-howto.tmpl 2008-12-03 > 13:11:53.000000000 -0800 > @@ -42,6 +42,12 @@ GPL version 2. > > > > + 0.6 > + 2008-12-03 > + ee > + Added description of DMA control. > + > + > 0.5 > 2008-05-22 > hjk > @@ -284,11 +290,17 @@ interested in translating it, please ema > require access to more than one PCI memory region in a driver. > > > + Each UIO device can also dynamically allocate coherent DMA > + memory regions and map these to userspace. Once created they > + can be mapped like any other UIO memory region. > + > + > Each mapping has its own directory in sysfs, the first mapping > appears as /sys/class/uio/uioX/maps/map0/. > Subsequent mappings create directories map1/, > - map2/, and so on. These directories will only > - appear if the size of the mapping is not 0. > + map2/, and so on. These directories will > + appear even if the size of the mapping is 0 to accommodate dynamically > + created DMA mappings. > > > Each mapX/ directory contains two read-only files > @@ -318,6 +330,24 @@ interested in translating it, please ema > offset = N * getpagesize(); > > > + > + From userspace a DMA region may be dynamically allocated and mapped > + via the mmap() call by specifying the size of the > + region in bytes in the length parameter and setting > + offset = 0xFFFFF000. > + > + > + The bus-specific DMA address as required to configure hardware DMA > + registers will be stored in the first long word of the resulting mapped > + region. > + > + > +#define DMA_MEM_ALLOCATE_MMAP_OFFSET 0xFFFFF000UL > +void* memory = mmap (NULL, size, PROT_READ | PROT_WRITE , MAP_SHARED, > + fd, DMA_MEM_ALLOCATE_MMAP_OFFSET); > +u_int64_t *addr = *(u_int64_t *) memory; > + > + > > > > @@ -572,6 +602,50 @@ to set up sysfs files for this mapping. > > > > + > +Allocating DMA region with mmap() > + > + To allocate and map a DMA memory region you use > + use mmap(). You may create as > + many regions as system resources allow by repeated use of > + mmap(). > + > + > + Specify the size of the desired region, in bytes, in the > + length parameter and set > + offset = 0xFFFFF000. The region size will > + be rounded up to a multiple of page size to ensure proper > + alignment. > + > + > + The bus-specific DMA address is stored in the first long word of the > + resulting mapped region. The newly assigned memory index N is > + returned in the second long word of the resulting mapped region. This > + index is only required if the userspace driver needs to unmap and > + then later remap the DMA region as the single call to > + mmap() is sufficient to both allocate and map the > + region. > + > + > + Since every memory mapping has its own directory in sysfs > + /sys/class/uio/uioX/maps/mapN/ will be created > + where N is the dynamically generated index of the mapping just > + allocated. > + > + > + Dynamically allocated DMA regions remain available for use > + until uio_unregister_device() is called, at > + which point the memory is released. > + > + > + #define DMA_MEM_ALLOCATE_MMAP_OFFSET 0xFFFFF000UL > + void* memory = mmap (NULL, size, PROT_READ | PROT_WRITE , MAP_SHARED, > + fd, DMA_MEM_ALLOCATE_MMAP_OFFSET); > + u_int64_t *addr = *(u_int64_t *) memory; > + > + > + > + > > Waiting for interrupts > > @@ -583,7 +657,7 @@ to set up sysfs files for this mapping. > attention because an error occured. > > > - /dev/uioX is a read-only file. A > + /dev/uioX is a read-write file. A > read() will always block until an > interrupt occurs. There is only one legal value for the > count parameter of > -- > To unsubscribe from this list: send the line "unsubscribe linux-api" in > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ git://git.kernel.org/pub/scm/docs/man-pages/man-pages.git man-pages online: http://www.kernel.org/doc/man-pages/online_pages.html Found a bug? http://www.kernel.org/doc/man-pages/reporting_bugs.html -- To unsubscribe from this list: send the line "unsubscribe linux-api" in the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org More majordomo info at http://vger.kernel.org/majordomo-info.html