From 515ab3de05f81253b94e7dd659f09c50724fb830 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Fri, 15 May 2009 17:02:34 +0000 Subject: Refactor parts of the 3COM NIC code Move the reusable PCI specific parts into pcidev.c, they'll be usable for other NIC code (Realtek, VIA, ...) and also for SATA/IDE controller cards as external programmers (for every PCI device which can program EEPROMs basically). Also add print_supported_pcidevs() to show the supported PCI devices (currently only NICs, soon more) in the 'flashrom -L' output. Corresponding to flashrom svn r515. Signed-off-by: Uwe Hermann Acked-by: Carl-Daniel Hailfinger --- pcidev.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 pcidev.c (limited to 'pcidev.c') diff --git a/pcidev.c b/pcidev.c new file mode 100644 index 00000000..549d083a --- /dev/null +++ b/pcidev.c @@ -0,0 +1,115 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include "flash.h" + +uint32_t io_base_addr; +struct pci_access *pacc; +struct pci_filter filter; +char *pcidev_bdf = NULL; + +uint32_t pcidev_validate(struct pci_dev *dev, struct pcidev_status *devs) +{ + int i; + uint32_t addr; + + for (i = 0; devs[i].device_name != NULL; i++) { + if (dev->device_id != devs[i].device_id) + continue; + + addr = (uint32_t)(dev->base_addr[0] & ~0x03); + + printf("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 == PCI_NT) { + printf("===\nThis PCI device is UNTESTED. Please email " + "a report including the 'flashrom -p xxxxxx'\n" + "output to flashrom@coreboot.org if it works " + "for you. Thank you for your help!\n===\n"); + } + + return addr; + } + + return 0; +} + +uint32_t pcidev_init(uint16_t vendor_id, struct pcidev_status *devs) +{ + struct pci_dev *dev; + char *msg = NULL; + int found = 0; + uint32_t addr = 0; + + pacc = pci_alloc(); /* Get the pci_access structure */ + pci_init(pacc); /* Initialize the PCI library */ + pci_scan_bus(pacc); /* We want to get the list of devices */ + pci_filter_init(pacc, &filter); + + /* Filter by vendor and also bb:dd.f (if supplied by the user). */ + filter.vendor = vendor_id; + if (pcidev_bdf != NULL) { + if ((msg = pci_filter_parse_slot(&filter, pcidev_bdf))) { + fprintf(stderr, "Error: %s\n", msg); + exit(1); + } + } + + for (dev = pacc->devices; dev; dev = dev->next) { + if (pci_filter_match(&filter, dev)) { + if ((addr = pcidev_validate(dev, devs)) != 0) + found++; + } + } + + /* Only continue if exactly one supported PCI dev has been found. */ + if (found == 0) { + fprintf(stderr, "Error: No supported PCI device found.\n"); + exit(1); + } else if (found > 1) { + fprintf(stderr, "Error: Multiple supported PCI devices found. " + "Please use 'flashrom -p xxxxxx=bb:dd.f' \n" + "to explicitly select the card with the given BDF " + "(PCI bus, device, function).\n"); + exit(1); + } + + return addr; +} + +void print_supported_pcidevs(struct pcidev_status *devs) +{ + int i; + + for (i = 0; devs[i].vendor_name != NULL; i++) { + printf("%s %s [%02x:%02x]%s\n", devs[i].vendor_name, + devs[i].device_name, devs[i].vendor_id, + devs[i].device_id, + (devs[i].status == PCI_NT) ? " (untested)" : ""); + } +} -- cgit v1.2.3