Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 6: Device Drivers


Like most kernel data types, requests are equipped with pointers to private data. In this case, not only
one, but two elements (elevator_privateandelevator_private2) are available! They can be set by the
I/O scheduler — traditionally calledelevator— which currently processes the request.


BIOs are used to transfer data between the system and a device. Their definition is examined below.


❑ bioidentifies the current BIO instance whose transfer has not yet been completed.
❑ biotailpoints to the last request, since a list of BIOs may be used in a request.

A request can be used to transmit control commands to a device (more formally, it can be used aspacket
command carrier). The desired commands are listed in thecmdarray. We have omitted several entries
related to bookkeeping required in this case.


The flags associated with a request are split into two parts.cmd_flagscontains a set of generic flags for
the request, andcmd_typedenotes the type of request. The following request types are possible:


<blkdev.h>
enum rq_cmd_type_bits {
REQ_TYPE_FS = 1, /* fs request */
REQ_TYPE_BLOCK_PC, /* scsi command */
REQ_TYPE_SENSE, /* sense request */
REQ_TYPE_PM_SUSPEND, /* suspend request */
REQ_TYPE_PM_RESUME, /* resume request */
REQ_TYPE_PM_SHUTDOWN, /* shutdown request */
REQ_TYPE_FLUSH, /* flush request */
REQ_TYPE_SPECIAL, /* driver defined type */
REQ_TYPE_LINUX_BLOCK, /* generic block layer message */
...
};

The most common request type isREQ_TYPE_FS: It is used for requests that actually transfer data to and
from a block device. The remaining types allow for sending various types of commands as documented
inthesourcecommentstoadevice.


Besides the type, several additional flags characterize the request type:


<blkdev.h>
enum rq_flag_bits {
__REQ_RW, /* not set, read. set, write */
__REQ_FAILFAST, /* no low level driver retries */
__REQ_SORTED, /* elevator knows about this request */
__REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
__REQ_HARDBARRIER, /* may not be passed by drive either */
__REQ_FUA, /* forced unit access */
__REQ_NOMERGE, /* don’t touch this for merging */
__REQ_STARTED, /* drive already may have started this one */
__REQ_DONTPREP, /* don’t call prep for this one */
__REQ_QUEUED, /* uses queueing */
__REQ_ELVPRIV, /* elevator private data attached */
__REQ_FAILED, /* set if the request failed */
__REQ_QUIET, /* don’t worry about errors */
__REQ_PREEMPT, /* set for "ide_preempt" requests */
Free download pdf