1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-28 15:33:42 +02:00
flashrom/pcidev.c
Uwe Hermann 515ab3de05 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 <uwe@hermann-uwe.de>
Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
2009-05-15 17:02:34 +00:00

116 lines
3.2 KiB
C

/*
* This file is part of the flashrom project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
*
* 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 <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#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)" : "");
}
}