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