DMA with ISA and LPC devices ============================ Pierre Ossman This document describes how to do DMA transfers using the old ISA DMA controller. Even though ISA is more or less dead today the LPC bus uses the same DMA system so it will be around for quite some time. Part I - Headers and dependencies --------------------------------- To do ISA style DMA you need to include two headers: #include #include The first is the generic DMA API used to convert virtual addresses to bus addresses (see Documentation/DMA-API.txt for details). The second contains the routines specific to ISA DMA transfers. Since this is not present on all platforms make sure you construct your Kconfig to be dependent on ISA_DMA_API (not ISA) so that nobody tries to build your driver on unsupported platforms. Part II - Buffer allocation --------------------------- The ISA DMA controller has some very strict requirements on which memory it can access so extra care must be taken when allocating buffers. (You usually need a special buffer for DMA transfers instead of transferring directly to and from your normal data structures.) The DMA-able address space is the lowest 16 MB of _physical_ memory. Also the transfer block may not cross page boundaries (which are 64 or 128 KiB depending on which channel you use). In order to allocate a piece of memory that satisfies all these requirements you pass the flag GFP_DMA to kmalloc. Unfortunately the memory available for ISA DMA is scarce so unless you allocate the memory during boot-up it's a good idea to also pass __GFP_REPEAT and __GFP_NOWARN to make the allocater try a bit harder. (This scarcity also means that you should allocate the buffer as early as possible and not release it until the driver is unloaded.) Part III - Address translation ------------------------------ To translate the virtual address to a bus address, use the normal DMA API. Do _not_ use isa_virt_to_phys() even though it does the same thing. The reason for this is that the function isa_virt_to_phys() will require a Kconfig dependency to ISA, not just ISA_DMA_API which is really all you need. Remember that even though the DMA controller has its origins in ISA it is used elsewhere. Note: x86_64 had a broken DMA API when it came to ISA but has since been fixed. If your arch has problems then fix the DMA API instead of reverting to the ISA functions. Part IV - Channels ------------------ A normal ISA DMA controller has 8 channels. The lower four are for 8-bit transfers and the upper four are for 16-bit transfers. (Actually the DMA controller is really two separate controllers where channel 4 is used to give DMA access for the second controller (0-3). This means that of the four 16-bits channels only three are usable.) You allocate these in a similar fashion as all basic resources: extern int request_dma(unsigned int dmanr, const char * device_id); extern void free_dma(unsigned int dmanr); The ability to use 16-bit or 8-bit transfers is _not_ up to you as a driver author but depends on what the hardware supports. Check your specs or test different channels. Part V - Transfer data ---------------------- Now for the good stuff, the actual DMA transfer. :) Before you use any ISA DMA routines you need to claim the DMA lock using claim_dma_lock(). The reason is that some DMA operations are