int pci_get_capability(pci_chipset_tag_t pc, pcitag_t tag, int capid, int *offset, pcireg_t *value) { pcireg_t reg; unsigned int ofs; reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); if (!(reg & PCI_STATUS_CAPLIST_SUPPORT)) return 0; /* Determine the Capability List Pointer register to start with. */ reg = pci_conf_read(pc, tag, PCI_BHLC_REG); switch (PCI_HDRTYPE_TYPE(reg)) { case 0: /* standard device header */ case 1: /* PCI-PCI bridge header */ ofs = PCI_CAPLISTPTR_REG; break; case 2: /* PCI-CardBus Bridge header */ ofs = PCI_CARDBUS_CAPLISTPTR_REG; break; default: return 0; } ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs)); while (ofs != 0) { if ((ofs & 3) || (ofs < 0x40)) { int bus, device, function; pci_decompose_tag(pc, tag, &bus, &device, &function); printf("Skipping broken PCI header on %d:%d:%d\n", bus, device, function); break; } reg = pci_conf_read(pc, tag, ofs); if (PCI_CAPLIST_CAP(reg) == capid) { if (offset) *offset = ofs; if (value) *value = reg; return 1; } ofs = PCI_CAPLIST_NEXT(reg); } return 0; }
int pciaddr_device_is_agp(pci_chipset_tag_t pc, pcitag_t tag) { pcireg_t class, status, rval; int off; /* Check AGP device. */ class = pci_conf_read(pc, tag, PCI_CLASS_REG); if (PCI_CLASS(class) == PCI_CLASS_DISPLAY) { status = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); if (status & PCI_STATUS_CAPLIST_SUPPORT) { rval = pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG); for (off = PCI_CAPLIST_PTR(rval); off != 0; off = PCI_CAPLIST_NEXT(rval) ) { rval = pci_conf_read(pc, tag, off); if (PCI_CAPLIST_CAP(rval) == PCI_CAP_AGP) return (1); } } } return (0); }