Author: uwe
Date: 2009-05-14 20:57:26 +0200 (Thu, 14 May 2009)
New Revision: 510

Modified:
   trunk/flash.h
   trunk/flashrom.c
   trunk/internal.c
   trunk/nic3com.c
Log:
3COM: Add support for users to specify a certain NIC via PCI bus:slot.func
notation, in case there are multiple NICs in one system.

Usage: flashrom -p nic3com=bb:ss.f

Signed-off-by: Christian Ruppert <[email protected]>
Acked-by: Uwe Hermann <[email protected]>



Modified: trunk/flash.h
===================================================================
--- trunk/flash.h       2009-05-14 14:51:14 UTC (rev 509)
+++ trunk/flash.h       2009-05-14 18:57:26 UTC (rev 510)
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <pci/pci.h>
 
 /* for iopl and outb under Solaris */
 #if defined (__sun) && (defined(__i386) || defined(__amd64))
@@ -545,6 +546,7 @@
 
 /* PCI handling for board/chipset_enable */
 struct pci_access *pacc;
+struct pci_dev *pci_dev_find_filter(struct pci_filter filter);
 struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device);
 struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
                              uint16_t card_vendor, uint16_t card_device);
@@ -623,6 +625,7 @@
 #define printf_debug(x...) { if (verbose) printf(x); }
 void map_flash_registers(struct flashchip *flash);
 int read_memmapped(struct flashchip *flash, uint8_t *buf);
+extern char *nic_pcidev;
 
 /* layout.c */
 int show_id(uint8_t *bios, int size, int force);

Modified: trunk/flashrom.c
===================================================================
--- trunk/flashrom.c    2009-05-14 14:51:14 UTC (rev 509)
+++ trunk/flashrom.c    2009-05-14 18:57:26 UTC (rev 510)
@@ -35,6 +35,7 @@
 int exclude_start_page, exclude_end_page;
 int verbose = 0;
 int programmer = PROGRAMMER_INTERNAL;
+char *nic_pcidev = NULL;
 
 const struct programmer_entry programmer_table[] = {
        {
@@ -454,6 +455,8 @@
                                programmer = PROGRAMMER_DUMMY;
                        } else if (strncmp(optarg, "nic3com", 7) == 0) {
                                programmer = PROGRAMMER_NIC3COM;
+                               if (optarg[7] == '=')
+                                       nic_pcidev = strdup(optarg + 8);
                        } else {
                                printf("Error: Unknown programmer.\n");
                                exit(1);

Modified: trunk/internal.c
===================================================================
--- trunk/internal.c    2009-05-14 14:51:14 UTC (rev 509)
+++ trunk/internal.c    2009-05-14 18:57:26 UTC (rev 510)
@@ -34,6 +34,17 @@
 
 struct pci_access *pacc;       /* For board and chipset_enable */
 
+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;

Modified: trunk/nic3com.c
===================================================================
--- trunk/nic3com.c     2009-05-14 14:51:14 UTC (rev 509)
+++ trunk/nic3com.c     2009-05-14 18:57:26 UTC (rev 510)
@@ -24,7 +24,6 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <errno.h>
-#include <pci/pci.h>
 #include "flash.h"
 
 #define BIOS_ROM_ADDR          0x04
@@ -38,6 +37,7 @@
 
 uint32_t io_base_addr;
 struct pci_access *pacc;
+struct pci_filter filter;
 
 #if defined(__FreeBSD__) || defined(__DragonFly__)
 int io_fd;
@@ -69,10 +69,38 @@
        {},
 };
 
+uint32_t nic3com_validate(struct pci_dev *dev)
+{
+       int i = 0;
+       uint32_t addr = -1;
+
+       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;
+
+               printf("Found NIC \"3COM %s\" (%04x:%04x), addr = 0x%x\n",
+                      nics[i].device_name, PCI_VENDOR_ID_3COM,
+                      nics[i].device_id, addr);
+
+               if (nics[i].status == NT) {
+                       printf("===\nThis NIC is UNTESTED. Please email a "
+                              "report including the 'flashrom -p nic3com'\n"
+                              "output to [email protected] if it works "
+                              "for you. Thank you for your help!\n===\n");
+               }
+
+               return addr;
+       }
+
+       return addr;
+}
+
 int nic3com_init(void)
 {
-       int i, found = 0;
        struct pci_dev *dev;
+       char *msg = NULL;
 
 #if defined (__sun) && (defined(__i386) || defined(__amd64))
        if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) {
@@ -90,29 +118,25 @@
        pci_init(pacc);         /* Initialize the PCI library */
        pci_scan_bus(pacc);     /* We want to get the list of devices */
 
-       for (i = 0; nics[i].device_name != NULL; i++) {
-               dev = pci_dev_find(PCI_VENDOR_ID_3COM, nics[i].device_id);
-               if (!dev)
-                       continue;
-
-               io_base_addr = pci_read_long(dev, PCI_IO_BASE_ADDRESS) & ~0x03;
-
-               printf("Found NIC \"3COM %s\" (%04x:%04x), addr = 0x%x\n",
-                      nics[i].device_name, PCI_VENDOR_ID_3COM,
-                      nics[i].device_id, io_base_addr);
-
-               if (nics[i].status == NT) {
-                       printf("===\nThis NIC is UNTESTED. Please email a "
-                              "report including the 'flashrom -p nic3com'\n"
-                              "output to [email protected] if it works "
-                              "for you. Thank you for your help!\n===\n");
+       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);
                }
+       }
 
-               found = 1;
-               break;
+       if (!filter.vendor && !filter.device) {
+               pci_filter_init(pacc, &filter);
+               filter.vendor = PCI_VENDOR_ID_3COM;
        }
 
-       if (!found) {
+       dev = pci_dev_find_filter(filter);
+
+       if (dev && (dev->vendor_id == PCI_VENDOR_ID_3COM))
+               io_base_addr = nic3com_validate(dev);
+       else {
                fprintf(stderr, "Error: No supported 3COM NIC found.\n");
                exit(1);
        }
@@ -129,6 +153,8 @@
 
 int nic3com_shutdown(void)
 {
+       free(nic_pcidev);
+       pci_cleanup(pacc);
        return 0;
 }
 


-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to