Table of Contents
Please have a look at uio_cif.c
as an
example. The following paragraphs explain the different
sections of this file.
This structure tells the framework the details of your driver, Some of the members are required, others are optional.
char *name
: Required. The name of your driver as
it will appear in sysfs. I recommend using the name of your module for this.
char *version
: Required. This string appears in
/sys/class/uio/uioX/version
.
struct uio_mem mem[ MAX_UIO_MAPS ]
: Required if you
have memory that can be mapped with mmap()
. For each
mapping you need to fill one of the uio_mem
structures.
See the description below for details.
long irq
: Required. If your hardware generates an
interrupt, it's your modules task to determine the irq number during
initialization. If you don't have a hardware generated interrupt but
want to trigger the interrupt handler in some other way, set
irq
to UIO_IRQ_CUSTOM
.
If you had no interrupt at all, you could set
irq
to UIO_IRQ_NONE
, though this
rarely makes sense.
unsigned long irq_flags
: Required if you've set
irq
to a hardware interrupt number. The flags given
here will be used in the call to request_irq()
.
int (*mmap)(struct uio_info *info, struct vm_area_struct
*vma)
: Optional. If you need a special
mmap()
function, you can set it here. If this
pointer is not NULL, your mmap()
will be called
instead of the built-in one.
int (*open)(struct uio_info *info, struct inode *inode)
: Optional. You might want to have your own
open()
, e.g. to enable interrupts only when your
device is actually used.
int (*release)(struct uio_info *info, struct inode *inode)
: Optional. If you define your own
open()
, you will probably also want a custom
release()
function.
Usually, your device will have one or more memory regions that can be mapped
to user space. For each region, you have to set up a
struct uio_mem
in the mem[]
array.
Here's a description of the fields of struct uio_mem
:
int memtype
: Required if the mapping is used. Set this to
UIO_MEM_PHYS
if you you have physical memory on your
card to be mapped. Use UIO_MEM_LOGICAL
for logical
memory (e.g. allocated with kmalloc()
). There's also
UIO_MEM_VIRTUAL
for virtual memory.
unsigned long addr
: Required if the mapping is used.
Fill in the address of your memory block. This address is the one that
appears in sysfs.
unsigned long size
: Fill in the size of the
memory block that addr
points to. If size
is zero, the mapping is considered unused. Note that you
must initialize size
with zero for
all unused mappings.
void *internal_addr
: If you have to access this memory
region from within your kernel module, you will want to map it internally by
using something like ioremap()
. Addresses
returned by this function cannot be mapped to user space, so you must not
store it in addr
. Use internal_addr
instead to remember such an address.
Please do not touch the kobj
element of
struct uio_mem
! It is used by the UIO framework
to set up sysfs files for this mapping. Simply leave it alone.