Linux Device Drivers by Corbet Jonathan & Rubini Alessandro & Kroah-Hartman Greg

Linux Device Drivers by Corbet Jonathan & Rubini Alessandro & Kroah-Hartman Greg

Author:Corbet, Jonathan & Rubini, Alessandro & Kroah-Hartman, Greg [Corbet, Jonathan]
Language: eng
Format: azw3, mobi
Tags: COMPUTERS / Operating Systems / Linux
ISBN: 9780596159740
Publisher: O'Reilly Media
Published: 2009-02-08T16:00:00+00:00

Hardware Abstractions

We complete the discussion of PCI by taking a quick look at how the system handles the plethora of PCI controllers available on the marketplace. This is just an informational section, meant to show the curious reader how the object-oriented layout of the kernel extends down to the lowest levels.

The mechanism used to implement hardware abstraction is the usual structure containing methods. It’s a powerful technique that adds just the minimal overhead of dereferencing a pointer to the normal overhead of a function call. In the case of PCI management, the only hardware-dependent operations are the ones that read and write configuration registers, because everything else in the PCI world is accomplished by directly reading and writing the I/O and memory address spaces, and those are under direct control of the CPU.

Thus, the relevant structure for configuration register access includes only two fields:

struct pci_ops { int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); };

The structure is defined in <linux/pci.h> and used by drivers/pci/pci.c, where the actual public functions are defined.

The two functions that act on the PCI configuration space have more overhead than dereferencing a pointer; they use cascading pointers due to the high object-orientedness of the code, but the overhead is not an issue in operations that are performed quite rarely and never in speed-critical paths. The actual implementation of pci_read_config_byte(dev, where, val), for instance, expands to:

dev->bus->ops->read(bus, devfn, where, 8, val);

The various PCI buses in the system are detected at system boot, and that’s when the struct pci_bus items are created and associated with their features, including the ops field.

Implementing hardware abstraction via “hardware operations” data structures is typical in the Linux kernel. One important example is the struct alpha_machine_vector data structure. It is defined in <asm-alpha/machvec.h> and takes care of everything that may change across different Alpha-based computers.


Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.