![Scott Smedley](/assets/img/avatar_default.png)
This is a driver for the DT3155 Digitizer Signed-off-by: Scott Smedley <ss@aao.gov.au> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
99 lines
4 KiB
Text
99 lines
4 KiB
Text
|
|
The allocator shown here exploits high memory. This document explains
|
|
how a user can deal with drivers uses this allocator and how a
|
|
programmer can link in the module.
|
|
|
|
The module is being used by my pxc and pxdrv device drivers (as well as
|
|
other ones), available from ftp.systemy.it/pub/develop and
|
|
ftp.linux.it/pub/People/Rubini
|
|
|
|
User's manual
|
|
=============
|
|
|
|
|
|
One of the most compelling problems with any DMA-capable device is the
|
|
allocation of a suitable memory buffer. The "allocator" module tries
|
|
to deal with the problem in a clean way. The module is able to use
|
|
high memory (above the one used in normal operation) for DMA
|
|
allocation.
|
|
|
|
To prevent the kernel for using high memory, so that it remains
|
|
available for DMA, you should pass a command line argument to the
|
|
kernel. Command line arguments can be passed to Lilo, to Loadlin or
|
|
to whichever loader you are using (unless it's very poor in design).
|
|
For Lilo, either use "append=" in /etc/lilo.conf or add commandline
|
|
arguments to the interactive prompt. For example, I have a 32MB box
|
|
and reserve two megs for DMA:
|
|
|
|
In lilo.conf:
|
|
image = /zImage
|
|
label = linux
|
|
append = "mem=30M"
|
|
|
|
Or, interactively:
|
|
LILO: linux mem=30M
|
|
|
|
Once the kernel is booted with the right command-line argument, any
|
|
driver linked with the allocator module will be able to get
|
|
DMA-capable memory without much trouble (unless the various drivers
|
|
need more memory than available).
|
|
|
|
The module implements an alloc/free mechanism, so that it can serve
|
|
multiple drivers at the same time. Note however that the allocator
|
|
uses all of high memory and assumes to be the only piece of software
|
|
using such memory.
|
|
|
|
|
|
Programmer's manual
|
|
===================
|
|
|
|
The allocator, as released, is designed to be linked to a device
|
|
driver. In this case, the driver must call allocator_init() before
|
|
using the allocator and must call allocator_cleanup() before
|
|
unloading. This is usually done from within init_module() and
|
|
cleanup_module(). If the allocator is linked to a driver, it won't be
|
|
possible for several drivers to allocate high DMA memory, as explained
|
|
above.
|
|
|
|
It is possible, on the other hand, to compile the module as a standalone
|
|
module, so that several modules can rely on the allocator for they DMA
|
|
buffers. To compile the allocator as a standalone module, do the
|
|
following in this directory (or provide a suitable Makefile, or edit
|
|
the source code):
|
|
|
|
make allocator.o CC="gcc -Dallocator_init=init_module -Dallocator_cleanup=cleanup_module -include /usr/include/linux/module.h"
|
|
|
|
The previous commandline tells to include <linux/module.h> in the
|
|
first place, and to rename the init and cleanup function to the ones
|
|
needed for module loading and unloading. Drivers using a standalone
|
|
allocator won't need to call allocator_init() nor allocator_cleanup().
|
|
|
|
The allocator exports the following functions (declared in allocator.h):
|
|
|
|
unsigned long allocator_allocate_dma (unsigned long kilobytes,
|
|
int priority);
|
|
|
|
This function returns a physical address, over high_memory,
|
|
which corresponds to an area of at least "kilobytes" kilobytes.
|
|
The area will be owned by the module calling the function.
|
|
The returned address can be passed to device boards, to instruct
|
|
their DMA controllers, via phys_to_bus(). The address can be used
|
|
by C code after vremap()/ioremap(). The "priority" argument should
|
|
be GFP_KERNEL or GFP_ATOMIC, according to the context of the
|
|
caller; it is used to call kmalloc(), as the allocator must keep
|
|
track of any region it gives away. In case of error the function
|
|
returns 0, and the caller is expected to issue a -ENOMEM error.
|
|
|
|
|
|
void allocator_free_dma (unsigned long address);
|
|
|
|
This function is the reverse of the previous one. If a driver
|
|
doesn't free the DMA memory it allocated, the allocator will
|
|
consider such memory as busy. Note, however, that
|
|
allocator_cleanup() calls kfree() on every region it reclaimed,
|
|
so that a driver with the allocator linked in can avoid calling
|
|
allocator_free_dma() at unload time.
|
|
|
|
|
|
|