root / hw / pci / slotid_cap.c @ 062db740
History | View | Annotate | Download (1.4 kB)
1 | c759b24f | Michael S. Tsirkin | #include "hw/pci/slotid_cap.h" |
---|---|---|---|
2 | c759b24f | Michael S. Tsirkin | #include "hw/pci/pci.h" |
3 | b4a42f81 | Paolo Bonzini | #include "qemu/error-report.h" |
4 | 762833b3 | Michael S. Tsirkin | |
5 | 762833b3 | Michael S. Tsirkin | #define SLOTID_CAP_LENGTH 4 |
6 | 762833b3 | Michael S. Tsirkin | #define SLOTID_NSLOTS_SHIFT (ffs(PCI_SID_ESR_NSLOTS) - 1) |
7 | 762833b3 | Michael S. Tsirkin | |
8 | 762833b3 | Michael S. Tsirkin | int slotid_cap_init(PCIDevice *d, int nslots, |
9 | 762833b3 | Michael S. Tsirkin | uint8_t chassis, |
10 | 762833b3 | Michael S. Tsirkin | unsigned offset)
|
11 | 762833b3 | Michael S. Tsirkin | { |
12 | 762833b3 | Michael S. Tsirkin | int cap;
|
13 | 762833b3 | Michael S. Tsirkin | if (!chassis) {
|
14 | 762833b3 | Michael S. Tsirkin | error_report("Bridge chassis not specified. Each bridge is required "
|
15 | 762833b3 | Michael S. Tsirkin | "to be assigned a unique chassis id > 0.");
|
16 | 762833b3 | Michael S. Tsirkin | return -EINVAL;
|
17 | 762833b3 | Michael S. Tsirkin | } |
18 | 762833b3 | Michael S. Tsirkin | if (nslots < 0 || nslots > (PCI_SID_ESR_NSLOTS >> SLOTID_NSLOTS_SHIFT)) { |
19 | 762833b3 | Michael S. Tsirkin | /* TODO: error report? */
|
20 | 762833b3 | Michael S. Tsirkin | return -EINVAL;
|
21 | 762833b3 | Michael S. Tsirkin | } |
22 | 762833b3 | Michael S. Tsirkin | |
23 | 762833b3 | Michael S. Tsirkin | cap = pci_add_capability(d, PCI_CAP_ID_SLOTID, offset, SLOTID_CAP_LENGTH); |
24 | 762833b3 | Michael S. Tsirkin | if (cap < 0) { |
25 | 762833b3 | Michael S. Tsirkin | return cap;
|
26 | 762833b3 | Michael S. Tsirkin | } |
27 | 762833b3 | Michael S. Tsirkin | /* We make each chassis unique, this way each bridge is First in Chassis */
|
28 | 762833b3 | Michael S. Tsirkin | d->config[cap + PCI_SID_ESR] = PCI_SID_ESR_FIC | |
29 | 762833b3 | Michael S. Tsirkin | (nslots << SLOTID_NSLOTS_SHIFT); |
30 | 762833b3 | Michael S. Tsirkin | d->cmask[cap + PCI_SID_ESR] = 0xff;
|
31 | 762833b3 | Michael S. Tsirkin | d->config[cap + PCI_SID_CHASSIS_NR] = chassis; |
32 | 762833b3 | Michael S. Tsirkin | /* Note: Chassis number register is non-volatile,
|
33 | 762833b3 | Michael S. Tsirkin | so we don't reset it. */
|
34 | 762833b3 | Michael S. Tsirkin | /* TODO: store in eeprom? */
|
35 | 762833b3 | Michael S. Tsirkin | d->wmask[cap + PCI_SID_CHASSIS_NR] = 0xff;
|
36 | 762833b3 | Michael S. Tsirkin | |
37 | 762833b3 | Michael S. Tsirkin | d->cap_present |= QEMU_PCI_CAP_SLOTID; |
38 | 762833b3 | Michael S. Tsirkin | return 0; |
39 | 762833b3 | Michael S. Tsirkin | } |
40 | 762833b3 | Michael S. Tsirkin | |
41 | 762833b3 | Michael S. Tsirkin | void slotid_cap_cleanup(PCIDevice *d)
|
42 | 762833b3 | Michael S. Tsirkin | { |
43 | 762833b3 | Michael S. Tsirkin | /* TODO: cleanup config space? */
|
44 | 762833b3 | Michael S. Tsirkin | d->cap_present &= ~QEMU_PCI_CAP_SLOTID; |
45 | 762833b3 | Michael S. Tsirkin | } |