static int register_controllers(void) { struct pci_device_iterator *pci_dev_iter; struct pci_device *pci_dev; struct pci_id_match match; int rc; printf("Initializing NVMe Controllers\n"); pci_system_init(); match.vendor_id = PCI_MATCH_ANY; match.subvendor_id = PCI_MATCH_ANY; match.subdevice_id = PCI_MATCH_ANY; match.device_id = PCI_MATCH_ANY; match.device_class = NVME_CLASS_CODE; match.device_class_mask = 0xFFFFFF; pci_dev_iter = pci_id_match_iterator_create(&match); rc = 0; while ((pci_dev = pci_device_next(pci_dev_iter))) { struct nvme_controller *ctrlr; if (pci_device_has_non_null_driver(pci_dev)) { fprintf(stderr, "non-null kernel driver attached to nvme\n"); fprintf(stderr, " controller at pci bdf %d:%d:%d\n", pci_dev->bus, pci_dev->dev, pci_dev->func); fprintf(stderr, " skipping...\n"); continue; } pci_device_probe(pci_dev); ctrlr = nvme_attach(pci_dev); if (ctrlr == NULL) { fprintf(stderr, "nvme_attach failed for controller at pci bdf %d:%d:%d\n", pci_dev->bus, pci_dev->dev, pci_dev->func); rc = 1; continue; } register_ctrlr(ctrlr, pci_dev); } pci_iterator_destroy(pci_dev_iter); return rc; }
Bool xf86PciAddMatchingDev(DriverPtr drvp) { const struct pci_id_match *const devices = drvp->supported_devices; int j; struct pci_device *pPci; struct pci_device_iterator *iter; int numFound = 0; iter = pci_id_match_iterator_create(NULL); while ((pPci = pci_device_next(iter)) != NULL) { /* Determine if this device is supported by the driver. If it is, * add it to the list of devices to configure. */ for (j = 0; !END_OF_MATCHES(devices[j]); j++) { if (PCI_ID_COMPARE(devices[j].vendor_id, pPci->vendor_id) && PCI_ID_COMPARE(devices[j].device_id, pPci->device_id) && ((devices[j].device_class_mask & pPci->device_class) == devices[j].device_class)) { if (xf86CheckPciSlot(pPci)) { GDevPtr pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_PCI, pPci, -1); if (pGDev != NULL) { /* After configure pass 1, chipID and chipRev are * treated as over-rides, so clobber them here. */ pGDev->chipID = -1; pGDev->chipRev = -1; } numFound++; } break; } } } pci_iterator_destroy(iter); return numFound != 0; }
int pci_device_vgaarb_init(void) { struct pci_device *dev = pci_sys->vga_target; struct pci_device_iterator *iter; struct pci_id_match vga_match = { PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, (PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8), 0x00ffff00 }; struct pci_vga pv; int err; #ifdef CPU_ALLOWAPERTURE int mib[2]; int allowaperture; size_t len; mib[0] = CTL_MACHDEP; mib[1] = CPU_ALLOWAPERTURE; len = sizeof(allowaperture); if (sysctl(mib, 2, &allowaperture, &len, NULL, 0) == 0 && allowaperture == 0) { /* No direct hardware access allowed. */ pci_sys->vga_count = 0; return 0; } #endif pv.pv_sel.pc_bus = 0; pv.pv_sel.pc_dev = 0; pv.pv_sel.pc_func = 0; err = ioctl(pcifd[0], PCIOCGETVGA, &pv); if (err) return err; pci_sys->vga_target = pci_device_find_by_slot(0, pv.pv_sel.pc_bus, pv.pv_sel.pc_dev, pv.pv_sel.pc_func); /* Count the number of VGA devices in domain 0. */ iter = pci_id_match_iterator_create(&vga_match); if (iter == NULL) return -1; pci_sys->vga_count = 0; while ((dev = pci_device_next(iter)) != NULL) { if (dev->domain == 0) { pci_sys->vga_count++; pv.pv_sel.pc_bus = dev->bus; pv.pv_sel.pc_dev = dev->dev; pv.pv_sel.pc_func = dev->func; if (ioctl(pcifd[0], PCIOCGETVGA, &pv)) continue; if (pv.pv_decode) dev->vgaarb_rsrc = VGA_ARB_RSRC_LEGACY_IO | VGA_ARB_RSRC_LEGACY_MEM; } } pci_iterator_destroy(iter); return 0; }
unsigned int init_pci(unsigned char bus, const unsigned char forcemem) { int ret = pci_system_init(); if (ret) die(_("Failed to init pciaccess")); struct pci_id_match match; match.vendor_id = 0x1002; match.device_id = PCI_MATCH_ANY; match.subvendor_id = PCI_MATCH_ANY; match.subdevice_id = PCI_MATCH_ANY; match.device_class = 0; match.device_class_mask = 0; match.match_data = 0; struct pci_device_iterator *iter = pci_id_match_iterator_create(&match); struct pci_device *dev = NULL; char busid[32]; while ((dev = pci_device_next(iter))) { pci_device_probe(dev); if ((dev->device_class & 0x00ffff00) != 0x00030000 && (dev->device_class & 0x00ffff00) != 0x00038000) continue; snprintf(busid, sizeof(busid), "pci:%04x:%02x:%02x.%u", dev->domain, dev->bus, dev->dev, dev->func); if (!bus || bus == dev->bus) break; } pci_iterator_destroy(iter); if (!dev) die(_("Can't find Radeon cards")); const unsigned int device_id = dev->device_id; int reg = 2; if (getfamily(device_id) >= BONAIRE) reg = 5; if (!dev->regions[reg].size) die(_("Can't get the register area size")); // printf("Found area %p, size %lu\n", area, dev->regions[reg].size); // DRM support for VRAM drm_fd = drmOpen(NULL, busid); if (drm_fd >= 0) { drmVersionPtr ver = drmGetVersion(drm_fd); if (strcmp(ver->name, "radeon") != 0 && strcmp(ver->name, "amdgpu") != 0) { close(drm_fd); drm_fd = -1; } strcpy(drm_name, ver->name); drmFreeVersion(ver); } if (drm_fd < 0 && access("/dev/ati/card0", F_OK) == 0) // fglrx path drm_fd = open("/dev/ati/card0", O_RDWR); use_ioctl = 0; if (drm_fd >= 0) { authenticate_drm(drm_fd); uint32_t rreg = 0x8010; use_ioctl = get_drm_value(drm_fd, RADEON_INFO_READ_REG, &rreg); } if (forcemem) { printf(_("Forcing the /dev/mem path.\n")); use_ioctl = 0; } if (!use_ioctl) { int mem = open("/dev/mem", O_RDONLY); if (mem < 0) die(_("Cannot access GPU registers, are you root?")); area = mmap(NULL, MMAP_SIZE, PROT_READ, MAP_PRIVATE, mem, dev->regions[reg].base_addr + 0x8000); if (area == MAP_FAILED) die(_("mmap failed")); } bits.vram = 0; if (drm_fd < 0) { printf(_("Failed to open DRM node, no VRAM support.\n")); } else { drmDropMaster(drm_fd); drmVersionPtr ver = drmGetVersion(drm_fd); /* printf("Version %u.%u.%u, name %s\n", ver->version_major, ver->version_minor, ver->version_patchlevel, ver->name);*/ if (ver->version_major < 2 || (ver->version_major == 2 && ver->version_minor < 36)) { printf(_("Kernel too old for VRAM reporting.\n")); drmFreeVersion(ver); goto out; } drmFreeVersion(ver); // No version indicator, so we need to test once // We use different codepaths for radeon and amdgpu // We store vram_size and check below if the ret value is sane if (strcmp(drm_name, "radeon") == 0) { struct drm_radeon_gem_info gem; ret = drmCommandWriteRead(drm_fd, DRM_RADEON_GEM_INFO, &gem, sizeof(gem)); vramsize = gem.vram_size; } else if (strcmp(drm_name, "amdgpu") == 0) { #ifdef ENABLE_AMDGPU struct drm_amdgpu_info_vram_gtt vram_gtt = {}; struct drm_amdgpu_info request; memset(&request, 0, sizeof(request)); request.return_pointer = (unsigned long) &vram_gtt; request.return_size = sizeof(vram_gtt); request.query = AMDGPU_INFO_VRAM_GTT; ret = drmCommandWrite(drm_fd, DRM_AMDGPU_INFO, &request, sizeof(request)); vramsize = vram_gtt.vram_size; #else printf(_("amdgpu DRM driver is used, but amdgpu VRAM size reporting is not enabled\n")); #endif } if (ret) { printf(_("Failed to get VRAM size, error %d\n"), ret); goto out; } ret = getvram(); if (ret == 0) { if (strcmp(drm_name, "amdgpu") == 0) { #ifndef ENABLE_AMDGPU printf(_("amdgpu DRM driver is used, but amdgpu VRAM usage reporting is not enabled\n")); #endif } printf(_("Failed to get VRAM usage, kernel likely too old\n")); goto out; } bits.vram = 1; } out: pci_system_cleanup(); return device_id; }
int main(int argc, char **argv) { struct pci_device_iterator *pci_dev_iter; struct pci_device *pci_dev; struct dev *iter; struct pci_id_match match; int rc, i; rc = rte_eal_init(sizeof(ealargs) / sizeof(ealargs[0]), (char **)(void *)(uintptr_t)ealargs); if (rc < 0) { fprintf(stderr, "could not initialize dpdk\n"); exit(1); } request_mempool = rte_mempool_create("nvme_request", 8192, nvme_request_size(), 128, 0, NULL, NULL, NULL, NULL, SOCKET_ID_ANY, 0); if (request_mempool == NULL) { fprintf(stderr, "could not initialize request mempool\n"); exit(1); } pci_system_init(); match.vendor_id = PCI_MATCH_ANY; match.subvendor_id = PCI_MATCH_ANY; match.subdevice_id = PCI_MATCH_ANY; match.device_id = PCI_MATCH_ANY; match.device_class = NVME_CLASS_CODE; match.device_class_mask = 0xFFFFFF; pci_dev_iter = pci_id_match_iterator_create(&match); rc = 0; while ((pci_dev = pci_device_next(pci_dev_iter))) { struct nvme_controller *ctrlr; struct dev *dev; if (pci_device_has_non_uio_driver(pci_dev)) { fprintf(stderr, "non-uio kernel driver attached to nvme\n"); fprintf(stderr, " controller at pci bdf %d:%d:%d\n", pci_dev->bus, pci_dev->dev, pci_dev->func); fprintf(stderr, " skipping...\n"); continue; } pci_device_probe(pci_dev); ctrlr = nvme_attach(pci_dev); if (ctrlr == NULL) { fprintf(stderr, "failed to attach to NVMe controller at PCI BDF %d:%d:%d\n", pci_dev->bus, pci_dev->dev, pci_dev->func); rc = 1; continue; } /* add to dev list */ dev = &devs[num_devs++]; dev->pci_dev = pci_dev; dev->ctrlr = ctrlr; } pci_iterator_destroy(pci_dev_iter); if (num_devs) { rc = nvme_register_io_thread(); if (rc != 0) return rc; } foreach_dev(iter) { reserve_controller(iter->ctrlr, iter->pci_dev); } printf("Cleaning up...\n"); for (i = 0; i < num_devs; i++) { struct dev *dev = &devs[i]; nvme_detach(dev->ctrlr); } if (num_devs) nvme_unregister_io_thread(); return rc; }
Bool xf86PciProbeDev(DriverPtr drvp) { int i, j; struct pci_device *pPci; Bool foundScreen = FALSE; const struct pci_id_match *const devices = drvp->supported_devices; GDevPtr *devList; const unsigned numDevs = xf86MatchDevice(drvp->driverName, &devList); for (i = 0; i < numDevs; i++) { struct pci_device_iterator *iter; unsigned device_id; /* Find the pciVideoRec associated with this device section. */ iter = pci_id_match_iterator_create(NULL); while ((pPci = pci_device_next(iter)) != NULL) { if (devList[i]->busID && *devList[i]->busID) { if (xf86ComparePciBusString(devList[i]->busID, ((pPci->domain << 8) | pPci->bus), pPci->dev, pPci->func)) { break; } } else if (xf86IsPrimaryPci(pPci)) { break; } } pci_iterator_destroy(iter); if (pPci == NULL) { continue; } device_id = (devList[i]->chipID > 0) ? devList[i]->chipID : pPci->device_id; /* Once the pciVideoRec is found, determine if the device is supported * by the driver. If it is, probe it! */ for (j = 0; !END_OF_MATCHES(devices[j]); j++) { if (PCI_ID_COMPARE(devices[j].vendor_id, pPci->vendor_id) && PCI_ID_COMPARE(devices[j].device_id, device_id) && ((devices[j].device_class_mask & pPci->device_class) == devices[j].device_class)) { int entry; /* Allow the same entity to be used more than once for * devices with multiple screens per entity. This assumes * implicitly that there will be a screen == 0 instance. * * FIXME Need to make sure that two different drivers don't * FIXME claim the same screen > 0 instance. */ if ((devList[i]->screen == 0) && !xf86CheckPciSlot(pPci)) continue; DebugF("%s: card at %d:%d:%d is claimed by a Device section\n", drvp->driverName, pPci->bus, pPci->dev, pPci->func); /* Allocate an entry in the lists to be returned */ entry = xf86ClaimPciSlot(pPci, drvp, device_id, devList[i], devList[i]->active); if ((entry == -1) && (devList[i]->screen > 0)) { unsigned k; for (k = 0; k < xf86NumEntities; k++) { EntityPtr pEnt = xf86Entities[k]; if (pEnt->bus.type != BUS_PCI) continue; if (pEnt->bus.id.pci == pPci) { entry = k; xf86AddDevToEntity(k, devList[i]); break; } } } if (entry != -1) { if ((*drvp->PciProbe) (drvp, entry, pPci, devices[j].match_data)) { foundScreen = TRUE; } else xf86UnclaimPciSlot(pPci, devList[i]); } break; } } } free(devList); return foundScreen; }
int nva_init() { int ret; ret = pci_system_init(); if (ret) return -1; struct pci_id_match nv_match = {0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000}; struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match); if (!it) { pci_system_cleanup(); return -1; } struct pci_device *dev; while (dev = pci_device_next(it)) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); struct pci_id_match nv_sgs_match = {0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0x30000, 0xffff0000}; it = pci_id_match_iterator_create(&nv_sgs_match); if (!it) { pci_system_cleanup(); return -1; } while (dev = pci_device_next(it)) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); int i; for (i = 0; i < nva_cardsnum; i++) { dev = nva_cards[i].pci; ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0); if (ret) return -1; nva_cards[i].boot0 = nva_rd32(i, 0); nva_cards[i].chipset = nva_cards[i].boot0 >> 20 & 0xff; if (nva_cards[i].chipset < 0x10) { if (nva_cards[i].boot0 & 0xf000) { if (nva_cards[i].boot0 & 0xf00000) nva_cards[i].chipset = 5; else nva_cards[i].chipset = 4; } else { nva_cards[i].chipset = nva_cards[i].boot0 >> 16 & 0xf; if ((nva_cards[i].boot0 & 0xff) >= 0x20) nva_cards[i].is_nv03p = 1; } } if (nva_cards[i].chipset < 0x04) nva_cards[i].card_type = nva_cards[i].chipset; else if (nva_cards[i].chipset < 0x10) nva_cards[i].card_type = 0x04; else if (nva_cards[i].chipset < 0x20) nva_cards[i].card_type = 0x10; else if (nva_cards[i].chipset < 0x30) nva_cards[i].card_type = 0x20; else if (nva_cards[i].chipset < 0x40) nva_cards[i].card_type = 0x30; else if (nva_cards[i].chipset < 0x50 || nva_cards[i].chipset & 0xf0 == 0x60) nva_cards[i].card_type = 0x40; else if (nva_cards[i].chipset < 0xc0) nva_cards[i].card_type = 0x50; else nva_cards[i].card_type = 0xc0; } return 0; }
int nva_init() { int ret; ret = pci_system_init(); if (ret) return -1; int i; for (i = 0; i < ARRAY_SIZE(nv_match); i++) { struct pci_device_iterator* it = pci_id_match_iterator_create(&nv_match[i]); if (!it) { pci_system_cleanup(); return -1; } struct pci_device *dev; while ((dev = pci_device_next(it))) { struct nva_card c = { 0 }; ret = pci_device_probe(dev); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); continue; } c.pci = dev; ADDARRAY(nva_cards, c); } pci_iterator_destroy(it); } for (i = 0; i < nva_cardsnum; i++) { struct pci_device *dev; dev = nva_cards[i].pci; ret = pci_device_map_range(dev, dev->regions[0].base_addr, dev->regions[0].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar0); if (ret) { fprintf (stderr, "WARN: Can't probe %04x:%02x:%02x.%x\n", dev->domain, dev->bus, dev->dev, dev->func); int j; for (j = i + 1; j < nva_cardsnum; j++) { nva_cards[j-1] = nva_cards[j]; } nva_cardsnum--; i--; continue; } nva_cards[i].bar0len = dev->regions[0].size; if (dev->regions[1].size) { nva_cards[i].hasbar1 = 1; nva_cards[i].bar1len = dev->regions[1].size; ret = pci_device_map_range(dev, dev->regions[1].base_addr, dev->regions[1].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar1); if (ret) { nva_cards[i].bar1 = 0; } } if (dev->regions[2].size) { nva_cards[i].hasbar2 = 1; nva_cards[i].bar2len = dev->regions[2].size; ret = pci_device_map_range(dev, dev->regions[2].base_addr, dev->regions[2].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2); if (ret) { nva_cards[i].bar2 = 0; } } else if (dev->regions[3].size) { nva_cards[i].hasbar2 = 1; nva_cards[i].bar2len = dev->regions[3].size; ret = pci_device_map_range(dev, dev->regions[3].base_addr, dev->regions[3].size, PCI_DEV_MAP_FLAG_WRITABLE, &nva_cards[i].bar2); if (ret) { nva_cards[i].bar2 = 0; } } uint32_t pmc_id = nva_rd32(i, 0); parse_pmc_id(pmc_id, &nva_cards[i].chipset); } return (nva_cardsnum == 0); }