RE: Question regarding DMA xfer to user space directly

Lee, Shuyu
2003-07-10T20:41:00Z

Alan(Shih),

I have also struggled with the same issue - how to DMA data to a user buffer
directly. The following is my solution. Hopefully it will make your life
easier. Based on the inquiries I received privately since I posted my
questions, you are not the only one who is stuck on this issue.

Here is the pseudo code:

User code:
pUsrVirt = malloc(bufSize);
pass pUsrVirt and bufSize to driver via an ioctl call;

Driver code;
receive pUsrVirt and bufSize from user via an ioctl call;
alloc_kiovec(1, &iobuf);
map_user_kiobuf(READ, iobuf, (unsigned long)pUsrVirt, bufSize);
physAddr = page_to_bus(iobuf->maplist[idx])
+ ((unsigned long)pUsrVirt & OFFMASK);
Once you get the physical address, physAddr, for a particular memory page,
you can then construct the DMA chain.

A few things you should be aware of:
1) If you use RedHat7.2 or RedHat8.0, make sure that you compile your driver
using the gcc comes with them (gcc2.96 and gcc3.2 respectively). gcc2.95 and
gcc3.2.1 will NOT work.
2) If you use RedHat7.2, add the following define in your code.
#if (__GNUC__ == 2 && __GNUC_MINOR__ == 96)
#define page_to_bus(page) \
(ULONG)(((page) - mem_map) << PAGE_SHIFT)
#endif

Hope that helps.
Shuyu
PS. I'd like to take this opportunity to thank everyone who helped me
solving this problem.

-----Original Message-----
From: Alan Shih [mailto:alan@storlinksemi.com]
Sent: Wednesday, July 09, 2003 1:35 PM
To: Alan Cox
Cc: Linux Kernel Mailing List
Subject: RE: Question regarding DMA xfer to user space directly

Next question would be what are the steps that the driver need to ping user
pages before setting up the xfer?

Thanks.

-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk]
Sent: Tuesday, July 08, 2003 8:22 AM
To: Alan Shih
Cc: Linux Kernel Mailing List
Subject: Re: Question regarding DMA xfer to user space directly

On Maw, 2003-07-08 at 15:50, Alan Shih wrote:
> Is there a provision in MM for DMA transfer to user space directly without
> allocating a kernel buffer?

Yes. Its used both for O_DIRECT I/O (direct to disk I/O from userspace)
and for things like tv capture cards. The kernel allows a driver to pin
user pages and obtain mappings for them. Note that for large systems
user pages may be above the 32bit boundary so you need DAC capable
hardware to get the best results

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/