This chapter introduced the following symbols and header files.
-
#include <linux/ioctl.h>
This header declares all the macros used to define ioctl commands. It is currently included by
<linux/fs.h>
.-
_IOC_NRBITS
,_IOC_TYPEBITS
,_IOC_SIZEBITS
,_IOC_DIRBITS
The number of bits available for the different bitfields of ioctl commands. There are also four macros that specify the
MASK
s and four that specify theSHIFT
s, but they’re mainly for internal use._IOC_SIZEBITS
is an important value to check, because it changes across architectures.-
_IOC_NONE
,_IOC_READ
,_IOC_WRITE
The possible values for the “direction” bitfield. “Read” and “write” are different bits and can be OR’d to specify read/write. The values are 0 based.
-
_IOC(dir,type,nr,size)
,_IO(type,nr)
,_IOR(type,nr,size)
,_IOW(type,nr,size)
,_IOWR(type,nr,size)
-
_IOC_DIR(nr)
,_IOC_TYPE(nr)
,_IOC_NR(nr)
,_IOC_SIZE(nr)
Macros used to decode a command. In particular,
_IOC_TYPE(nr)
is an OR combination of_IOC_READ
and_IOC_WRITE
.-
#include <asm/uaccess.h>
,int access_ok(int type, const void *addr, unsigned long size);
This function checks that a pointer to user space is actually usable. access_ok returns a nonzero value if the access should be allowed.
-
VERIFY_READ
,VERIFY_WRITE
The possible values for the
type
argument in access_ok.VERIFY_WRITE
is a superset ofVERIFY_READ
.-
#include <asm/uaccess.h>
,int put_user(datum,ptr);
,int get_user(local,ptr);
,int __put_user(datum,ptr);
,int __get_user(local,ptr);
Macros used to store or retrieve a datum to or from user space. The number of bytes being transferred depends on
sizeof(*ptr)
. The regular versions call access_ok first, while the qualified versions (__put_user and __get_user) assume that access_ok has already been called.-
#include <linux/capability.h>
Defines the various
CAP_
symbols for capabilities under Linux 2.2 and later.-
int capable(int capability);
-
#include <linux/wait.h>
,typedef struct { /* ... */ } wait_queue_head_t;
,void init_waitqueue_head(wait_queue_head_t *queue);
,DECLARE_WAIT_QUEUE_HEAD(queue);
The defined type for Linux wait queues. A
wait_queue_head_t
must be explicitly initialized with either init_waitqueue_head at runtime or declare_wait_queue_head at compile time.-
#include <linux/sched.h>
,void interruptible_sleep_on(wait_queue_head_t *q);
,void sleep_on(wait_queue_head_t *q);
,void interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout);
,void sleep_on_timeout(wait_queue_head_t *q, long timeout);
Calling any of these functions puts the current process to sleep on a queue. Usually, you’ll choose the interruptible form to implement blocking read and write.
-
void wake_up(struct wait_queue **q);
,void wake_up_interruptible(struct wait_queue **q);
,void wake_up_sync(struct wait_queue **q);
,void wake_up_interruptible_sync(struct wait_queue **q);
These functions wake processes that are sleeping on the queue
q
. The _interruptible form wakes only interruptible processes. The _sync versions will not reschedule the CPU before returning.-
typedef struct { /* ... */ } wait_queue_t;
,init_waitqueue_entry(wait_queue_t *entry, struct task_struct *task);
The
wait_queue_t
type is used when sleeping without calling sleep_on. Wait queue entries must be initialized prior to use; thetask
argument used is almost alwayscurrent
.-
void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
,void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
,void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
These functions add an entry to a wait queue; add_wait_queue_exclusive adds the entry to the end of the queue for exclusive waits. Entries should be removed from the queue after sleeping with remove_wait_queue.
-
void wait_event(wait_queue_head_t q, int condition);
,int wait_event_interruptible(wait_queue_head_t q, int condition);
These two macros will cause the process to sleep on the given queue until the given
condition
evaluates to a true value.-
void schedule(void);
This function selects a runnable process from the run queue. The chosen process can be
current
or a different one. You won’t usually call schedule directly, because the sleep_on functions do it internally.-
#include <linux/poll.h>
,void poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *p)
This function puts the current process into a wait queue without scheduling immediately. It is designed to be used by the poll method of device drivers.
-
int fasync_helper(struct inode *inode, struct file *filp, int mode, struct fasync_struct **fa);
This function is a “helper” for implementing the fasync device method. The
mode
argument is the same value that is passed to the method, whilefa
points to a device-specificfasync_struct *
.-
void kill_fasync(struct fasync_struct *fa, int sig, int band);
If the driver supports asynchronous notification, this function can be used to send a signal to processes registered in
fa
.-
#include <linux/spinlock.h>
,typedef struct { /* ... */ } spinlock_t;
,void spin_lock_init(spinlock_t *lock);
The
spinlock_t
type defines a spinlock, which must be initialized (with spin_lock_init) prior to use.-
spin_lock(spinlock_t *lock);
,spin_unlock(spinlock_t *lock);
spin_lock locks the given lock, perhaps waiting until it becomes available. The lock can then be released with spin_unlock.
Get Linux Device Drivers, Second Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.