blob: fc9addccaf7c5bfbf68fc651ea09dc014bc71eff (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# All about the L5 PCI(e) driver
## Overview
The PCI(e) bus driver is responsible for communicating with the PCI(e) root complex or host bridge,
enumerating devices, and bringing up PCI(e) device drivers. The bus is made up of several devices that
each have their own device drivers as well. These device drivers communicate with the PCI(e) bus driver
during initialization to advertise themselves.
## Initialization basics
A PCI(e) device driver must have a generic module initialization routine to initialize basic state
as well as advertising itself to the PCI(e) bus driver, a basic routine of this kind may look like this:
```c
static int
driver_init(struct module *modp)
{
int error;
...
/* Advertise ourselves to the PCI(e) bus driver */
if ((error = pci_advoc(&driver)) < 0) {
pr_trace("failed to advocate for HBA\n");
return error;
}
...
return 0;
}
static int
dev_attach(struct pci_adv *adv)
{
struct bus_space bs;
...
return hw_init();
}
static struct pci_adv driver = {
.lookup = PCI_CS_ID(class, subcls), /* Class/subclass IDs */
.attach = dev_attach, /* Attach routine */
.classrev = 1 /* We are using class/subclass */
};
MODULE_EXPORT("driver-name", MODTYPE_PCI, driver_init);
```
The ``pci_adv`` structure contains information describing the device that the driver advocates itself
for. The lookup field can either be a pair of device ID and vendor ID values or device class and
subclass values (denoted to be used by the boolean ``classrev`` field).
## Device attachment
When a PCI(e) devices is attached and/or detected, the PCI(e) bus driver will look for a PCI(e) device
driver with a matching ``pci_adv`` lookup field. If one is found, the ``attach`` callback is invoked in
which the device / hardware initialization begins and the drivers functionality kicks on.
|