summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--flashrom.839
-rw-r--r--nic3com.c41
2 files changed, 52 insertions, 28 deletions
diff --git a/flashrom.8 b/flashrom.8
index 7a48041..abfafaa 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -1,13 +1,17 @@
-.TH FLASHROM 8 "April 11, 2009"
+.TH FLASHROM 8 "May 14, 2009"
.SH NAME
-flashrom \- read, write, verify and erase BIOS/ROM/flash chips
+flashrom \- detect, read, write, verify and erase flash chips
.SH SYNOPSIS
-.B flashrom \fR[\fB\-rwvEVfLhR\fR] [\fB\-c\fR chipname] [\fB\-s\fR exclude_start] [\fB\-e\fR exclude_end]
- [\fB-m\fR [vendor:]part] [\fB-l\fR file.layout] [\fB-i\fR image_name] [file]
+.B flashrom \fR[\fB\-EVfLhR\fR] [\fB\-r\fR file] [\fB\-w\fR file] [\fB\-v\fR file]
+ [\fB\-c\fR chipname] [\fB\-s\fR addr] [\fB\-e\fR addr] [\fB\-m\fR [vendor:]part]
+ [\fB\-l\fR file] [\fB\-i\fR image] [\fB\-p\fR programmer] [file]
.SH DESCRIPTION
.B flashrom
-is a utility for reading, writing, verifying and erasing flash ROM chips.
-It's often used to flash BIOS/coreboot/firmware images.
+is a utility for detecting, reading, writing, verifying and erasing flash ROM
+chips. It's often used to flash BIOS/EFI/coreboot/firmware images in-system
+using a supported mainboard, but it also supports flashing of network cards
+(NICs), SATA controller cards, and other external devices which can program
+flash chips.
.PP
It supports a wide range of DIP32, PLCC32, DIP8, SO8/SOIC8, TSOP32, and
TSOP40 chips, which use various protocols such as LPC, FWH, parallel flash,
@@ -126,11 +130,24 @@ of the box.
.B "\-p, \-\-programmer <name>"
Specify the programmer device. Currently supported are:
.sp
-.BR " internal" " (default, for in-system flashing in the mainboard)"
-.br
-.BR " nic3com" " (for flash ROMs on 3COM network cards)"
-.br
-.BR " dummy" " (just prints all operations and accesses)"
+.BR "* internal" " (default, for in-system flashing in the mainboard)"
+.sp
+.BR "* nic3com" " (for flash ROMs on 3COM network cards)"
+.sp
+If you have multiple supported NICs in your system, you must use
+.B "flashrom -p nic3com=bb:dd.f"
+to explicitly select one of them, where
+.B bb
+is the PCI bus number,
+.B dd
+is the PCI device number, and
+.B f
+is the PCI function number of the desired NIC.
+.sp
+Example:
+.B "flashrom -p nic3com=05:04.0"
+.sp
+.BR "* dummy" " (just prints all operations and accesses)"
.TP
.B "\-h, \-\-help"
Show a help text and exit.
diff --git a/nic3com.c b/nic3com.c
index a982267..baaec4b 100644
--- a/nic3com.c
+++ b/nic3com.c
@@ -67,18 +67,18 @@ static struct nic_status {
uint32_t nic3com_validate(struct pci_dev *dev)
{
- int i = 0;
- uint32_t addr = -1;
+ int i;
+ uint32_t addr;
for (i = 0; nics[i].device_name != NULL; i++) {
if (dev->device_id != nics[i].device_id)
continue;
- addr = pci_read_long(dev, PCI_IO_BASE_ADDRESS) & ~0x03;
+ addr = (uint32_t)(dev->base_addr[0] & ~0x03);
- printf("Found NIC \"3COM %s\" (%04x:%04x), addr = 0x%x\n",
- nics[i].device_name, PCI_VENDOR_ID_3COM,
- nics[i].device_id, addr);
+ printf("Found NIC \"3COM %s\" (%04x:%04x, BDF %02x:%02x.%x)\n",
+ nics[i].device_name, dev->vendor_id,
+ dev->device_id, dev->bus, dev->dev, dev->func);
if (nics[i].status == NT) {
printf("===\nThis NIC is UNTESTED. Please email a "
@@ -90,41 +90,48 @@ uint32_t nic3com_validate(struct pci_dev *dev)
return addr;
}
- return addr;
+ return 0;
}
int nic3com_init(void)
{
struct pci_dev *dev;
char *msg = NULL;
+ int found = 0;
get_io_perms();
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 = PCI_VENDOR_ID_3COM;
if (nic_pcidev != NULL) {
- pci_filter_init(pacc, &filter);
-
if ((msg = pci_filter_parse_slot(&filter, nic_pcidev))) {
fprintf(stderr, "Error: %s\n", msg);
exit(1);
}
}
- if (!filter.vendor && !filter.device) {
- pci_filter_init(pacc, &filter);
- filter.vendor = PCI_VENDOR_ID_3COM;
+ for (dev = pacc->devices; dev; dev = dev->next) {
+ if (pci_filter_match(&filter, dev)) {
+ if ((io_base_addr = nic3com_validate(dev)) != 0)
+ found++;
+ }
}
- dev = pci_dev_find_filter(filter);
-
- if (dev && (dev->vendor_id == PCI_VENDOR_ID_3COM))
- io_base_addr = nic3com_validate(dev);
- else {
+ /* Only continue if exactly one supported NIC has been found. */
+ if (found == 0) {
fprintf(stderr, "Error: No supported 3COM NIC found.\n");
exit(1);
+ } else if (found > 1) {
+ fprintf(stderr, "Error: Multiple supported NICs found. "
+ "Please use 'flashrom -p nic3com=bb:dd.f' \n"
+ "to explicitly select the card with the given BDF "
+ "(PCI bus, device, function).\n");
+ exit(1);
}
/*
OpenPOWER on IntegriCloud