|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.