In a polling driver, the foo_read() and foo_write() functions are pretty easy to write. Here is an example of foo_write():
foo_write_byte() and foo_handle_error() are either functions defined elsewhere in foo.c or pseudocode. WRITE would be a constant or #define.
It should be clear from this example how to code the foo_read() function as well.
Interrupt-driven drivers are a little more difficult. Here is an example of a foo_write() that is interrupt-driven:
Again, a foo_read() function is written analogously. foo_table[] is an array of structures, each of which has several members, some of which are foo_wait_queue and bytes_xfered, which can be used for both reading and writing. foo_irq[] is an array of 16 integers, and is used for looking up which entry in foo_table[] is associated with the irq generated and reported to the foo_interrupt() function.
To tell the interrupt-handling code to call foo_interrupt(), you need to use either request_irq() or irqaction(). This is either done when foo_open() is called, or if you want to keep things simple, when foo_init() is called. request_irq() is the simpler of the two, and works rather like an old-style signal handler. It takes two arguments: the first is the number of the irq you are requesting, and the second is a pointer to your interrupt handler, which must take an integer argument (the irq that was generated) and have a return type of void. request_irq() returns -EINVAL if irq > 15 or if the pointer to the interrupt handler is NULL, -EBUSY if that interrupt has already been taken, or 0 on success.
irqaction() works rather like the user-level sigaction(),
and in fact reuses the sigaction structure. The
sa_restorer() field of the sigaction structure is not used, but
everything else is the same. See the entry for irqaction() in
Section , Supporting Functions, for further
information about irqaction().