Block Device Drivers: Interrupts
I am going to take the foo driver I started developing last month, and add interrupt service to it. It is hard to write good, detailed code for a hypothetical and vaguely defined device, so (as usual) if you want to understand better after reading this, take a look at some real devices. I suggest the hd and floppy devices; start from the do_hd_request() and do_fd_request() routines and follow the logic through.
static void do_foo_request(void) {
if (foo_busy)
/* another request is being processed;
this one will automatically follow */
return;
foo_busy = 1;
foo_initialize_io();
}
static void foo_initialize_io(void) {
if (CURRENT->cmd == READ) {
SET_INTR(foo_read_intr);
} else {
SET_INTR(foo_write_intr);
}
/* send hardware command to start io
based on request; just a request to
read if read and preparing data for
entire write; write takes more code */
}
static void foo_read_intr(void) {
int error=0;
CLEAR_INTR;
/* read data from device and put in
CURRENT->buffer; set error=1 if error
This is actually most of the function... */
/* successful if no error */
end_request(error?0:1);
if (!CURRENT)
/* allow new requests to be processed */
foo_busy = 0;
/* INIT_REQUEST will return if no requests */
INIT_REQUEST;
/* Now prepare to do I/O on next request */
foo_initialize_io();
}
static void foo_write_intr(void) {
int error=0;
CLEAR_INTR;
/* data has been written. error=1 if error */
/* successful if no error */
end_request(error?0:1);
if (!CURRENT)
/* allow new requests to be processed */ foo_busy = 0;
/* INIT_REQUEST will return if no requests */
INIT_REQUEST;
/* Now prepare to do I/O on next request */
foo_initialize_io();
}
In blk.h, we need to add a few lines to the FOO_MAJOR section:
#elif (MAJOR_NR == FOO_MAJOR) #define DEVICE_NAME "foobar" #define DEVICE_REQUEST do_foo_request #define DEVICE_INTR do_foo #define DEVICE_NR(device) (MINOR(device) > 6) #define DEVICE_ON(device) #define DEVICE_OFF(device) #endif
Note that many functions are missing from this; this is the important part to understanding interrupt-driven device drivers; the “heart”, if you will. Also note that, obviously, I haven't tried to compile or run this hypothetical driver. I may have made some mistakes—you are bound to make mistakes of your own while writing your driver, and finding bugs in this skeleton will be good practice for finding bugs in your own driver, if you are so inclined. I do suggest that when you write your own driver, you start with code from some other working driver rather than starting from this skeleton code.
An explanation of some of the new ideas here is in order. The first new idea is (obviously, I hope) the use of interrupt routines to do part of servicing the hardware and walking down the request list. I used separate routines for reading and writing; this isn't fundamentally necessary, but it does generally help allow cleaner code and smaller, easier-to-read interrupt service routines. Most (all?) of the interrupt-driven device drivers of any kind in the real kernel use separate routines for reading and writing.
We also have a separate routine to do most of the I/O setup instead of doing it in the request() procedure. This is so that the interrupt routines can call the separate routings to set up the next request, if necessary, upon completion of a request. Again, this is a design feature that makes most real-world drivers smaller and easier to write and debug.
It must be noted that any routine that is called from an interrupt is different than all the other routines I have described so far. Routines called from an interrupt do not execute in the context of any calling user-level program and cannot write to user-level memory. They can only write to kernel memory. If they absolutely need to allocate memory, they must do so with the GFP_ATOMIC priority. In general, it is best for them to write into buffers allocated from user-process-context routines with priority GFP_KERNEL before the interrupt routines are set up. They also can wake up processes sleeping on an event, as end_request() does, but they cannot sleep themselves.
The header file blk.h provides some nice macros which are used here. I won't document them all (most are documented in The Linux Kernel Hackers' Guide, the KHG), but I will mention the ones I use, which are used to manage interrupts.
Instead of setting up interrupts manually, it is easier and better to use the SET_INTR() macro. (If you want to know how to set them up manually, read the definitions of SET_INTR in blk.h.) Easier because you just do SET_INTR(interrupt_handling_function), and better because if you set up automatic timeouts (which we will cover later), SET_INTR() automatically sets them up.
Then, when the interrupt has been serviced, the interrupt service routine (foo_read_intr() or foo_write_intr() above) clears the interrupt, so that spurious interrupts don't get delivered to a procedure that thinks that it is supposed to read or write to the current request. It is possible—it only takes a little more work—to provide an interrupt routing to handle spurious interrupts. If you are interested, read the hd driver.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Designing Electronics with Linux | May 22, 2013 |
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




2 hours 35 min ago
2 hours 52 min ago
4 hours 45 min ago
6 hours 39 min ago
13 hours 33 min ago
13 hours 49 min ago
15 hours 40 min ago
21 hours 32 min ago
1 day 2 hours ago
1 day 2 hours ago