struct pci_dev *pci_dev_find_filter(struct pci_filter filter) { struct pci_dev *temp; for (temp = pacc->devices; temp; temp = temp->next) if (pci_filter_match(&filter, temp)) return temp; return NULL; }
struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device) { struct pci_dev *temp; struct pci_filter filter; pci_filter_init(NULL, &filter); filter.vendor = vendor; filter.device = device; for (temp = pacc->devices; temp; temp = temp->next) if (pci_filter_match(&filter, temp)) return temp; return NULL; }
struct pci_dev *pci_dev_find_vendorclass(uint16_t vendor, uint16_t devclass) { struct pci_dev *temp; struct pci_filter filter; uint16_t tmp2; pci_filter_init(NULL, &filter); filter.vendor = vendor; for (temp = pacc->devices; temp; temp = temp->next) if (pci_filter_match(&filter, temp)) { /* Read PCI class */ tmp2 = pci_read_word(temp, 0x0a); if (tmp2 == devclass) return temp; } return NULL; }
struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device, uint16_t card_vendor, uint16_t card_device) { struct pci_dev *temp; struct pci_filter filter; pci_filter_init(NULL, &filter); filter.vendor = vendor; filter.device = device; for (temp = pacc->devices; temp; temp = temp->next) if (pci_filter_match(&filter, temp)) { if ((card_vendor == pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID)) && (card_device == pci_read_word(temp, PCI_SUBSYSTEM_ID))) return temp; } return NULL; }
/* * pci_acc_init * * PCI access helper function depending on libpci * * **pacc : if a valid pci_dev is returned * *pacc must be passed to pci_acc_cleanup to free it * * domain: domain * bus: bus * slot: slot * func: func * vendor: vendor * device: device * Pass -1 for one of the six above to match any * * Returns : * struct pci_dev which can be used with pci_{read,write}_* functions * to access the PCI config space of matching pci devices */ struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, int bus, int slot, int func, int vendor, int dev) { struct pci_filter filter_nb_link = { domain, bus, slot, func, vendor, dev }; struct pci_dev *device; *pacc = pci_alloc(); if (*pacc == NULL) return NULL; pci_init(*pacc); pci_scan_bus(*pacc); for (device = (*pacc)->devices; device; device = device->next) { if (pci_filter_match(&filter_nb_link, device)) return device; } pci_cleanup(*pacc); return NULL; }
/* pcidev_init gets an array of allowed PCI device IDs and returns a pointer to struct pci_dev iff exactly one * match was found. If the "pci=bb:dd.f" programmer parameter was specified, a match is only considered if it * also matches the specified bus:device.function. * For convenience, this function also registers its own undo handlers. */ struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar) { struct pci_dev *dev; struct pci_dev *found_dev = NULL; struct pci_filter filter; char *pcidev_bdf; char *msg = NULL; int found = 0; int i; uintptr_t addr = 0; if (pci_init_common() != 0) return NULL; pci_filter_init(pacc, &filter); /* Filter by bb:dd.f (if supplied by the user). */ pcidev_bdf = extract_programmer_param("pci"); if (pcidev_bdf != NULL) { if ((msg = pci_filter_parse_slot(&filter, pcidev_bdf))) { msg_perr("Error: %s\n", msg); return NULL; } } free(pcidev_bdf); for (dev = pacc->devices; dev; dev = dev->next) { if (pci_filter_match(&filter, dev)) { /* Check against list of supported devices. */ for (i = 0; devs[i].device_name != NULL; i++) if ((dev->vendor_id == devs[i].vendor_id) && (dev->device_id == devs[i].device_id)) break; /* Not supported, try the next one. */ if (devs[i].device_name == NULL) continue; msg_pdbg("Found \"%s %s\" (%04x:%04x, BDF %02x:%02x.%x).\n", devs[i].vendor_name, devs[i].device_name, dev->vendor_id, dev->device_id, dev->bus, dev->dev, dev->func); if (devs[i].status == NT) msg_pinfo("===\nThis PCI device is UNTESTED. Please report the 'flashrom -p " "xxxx' output \n" "to [email protected] if it works for you. Please add the name " "of your\n" "PCI device to the subject. Thank you for your help!\n===\n"); /* FIXME: We should count all matching devices, not * just those with a valid BAR. */ if ((addr = pcidev_readbar(dev, bar)) != 0) { found_dev = dev; found++; } } } /* Only continue if exactly one supported PCI dev has been found. */ if (found == 0) { msg_perr("Error: No supported PCI device found.\n"); return NULL; } else if (found > 1) { msg_perr("Error: Multiple supported PCI devices found. Use 'flashrom -p xxxx:pci=bb:dd.f' \n" "to explicitly select the card with the given BDF (PCI bus, device, function).\n"); return NULL; } return found_dev; }
int main (int argc, char *argv[]) { struct pci_access *pacc; struct pci_dev *dev; struct pci_filter filter; char *msg; uint16_t command; int v1_1 = 0, i2c; if (argc != 2 && ((argc != 3) || (!(v1_1 = !strcmp(argv[2], "1.1")) && strcmp(argv[2], "1.0")))) { fprintf(stderr, "VT6307 OHCI mode config\n" "Version 0.9\n" "Copyright (C) 2007 Krzysztof Halasa <*****@*****.**>\n" "\n" "Usage: vt6307ohciver <pci_device> [ 1.0 | 1.1 ]\n"); exit(1); } if (iopl(3)) { fprintf(stderr, "iopl() failed (must be root)\n"); exit(1); } pacc = pci_alloc(); pci_filter_init(pacc, &filter); if ((msg = pci_filter_parse_slot(&filter, argv[1]))) { fprintf(stderr, "Invalid pci_device\n"); exit(1); } filter.vendor = VENDOR_ID; filter.device = DEVICE_ID; pci_init(pacc); pci_scan_bus(pacc); for (dev = pacc->devices; dev; dev = dev->next) if (pci_filter_match(&filter, dev)) break; if (!dev) { fprintf(stderr, "Device %s not found\n", argv[2]); exit(1); } pci_fill_info(dev, PCI_FILL_BASES | PCI_FILL_SIZES); if (dev->size[0] != MEM_SIZE || dev->size[1] != IO_SIZE) { fprintf(stderr, "Unexpected MEM/IO region size, is it" " VT6307 chip?\n"); exit(1); } command = pci_read_word(dev, PCI_COMMAND); if ((command & PCI_COMMAND_IO) == 0) { fprintf(stderr, "Device disabled, trying to enable it\n"); pci_write_word(dev, PCI_COMMAND, command | PCI_COMMAND_IO); } io_ports = dev->base_addr[1] & PCI_BASE_ADDRESS_IO_MASK; i2c = (inl(io_ports + 0x20) & 0x80) ? 0 : 1; fprintf(stderr, "I/O region #1 is at %04X\n", io_ports); fprintf(stderr, "It seems your VT6307 chip is connected to %s " "EEPROM\n", i2c ? "I^2C (24c01 or similar)" : "93c46"); if (argc == 3) { /* enable direct access to pins */ outl_p(inl(io_ports) | 0x80, io_ports); if (i2c) write_i2c(0x22, v1_1 ? 8 : 0); else write_4w(0x11, v1_1 ? 8 : 0); /* disable direct access to pins */ outl_p(0x20, io_ports + 0x20); fprintf(stderr, "Please reboot\n"); } else display(dev->base_addr[0] & PCI_BASE_ADDRESS_MEM_MASK); if ((command & PCI_COMMAND_IO) == 0) { fprintf(stderr, "Disabling device\n"); pci_write_word(dev, PCI_COMMAND, command); } exit(0); }