Add --list-supported option which lists the supported ROM chips, chipsets, and mainboards

Corresponding to flashrom svn r199 and coreboot v2 svn r3133.

Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>
Acked-by: Ward Vandewege <ward@gnu.org>
diff --git a/board_enable.c b/board_enable.c
index da5043f..5b4b39a 100644
--- a/board_enable.c
+++ b/board_enable.c
@@ -500,6 +500,18 @@
 	{0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL}	/* Keep this */
 };
 
+void print_supported_boards(void)
+{
+	int i;
+
+	printf("\nSupported mainboards (this list is not exhaustive!):\n\n");
+
+	for (i = 0; board_pciid_enables[i].name != NULL; i++)
+		printf("%s\n", board_pciid_enables[i].name);
+
+	printf("\nSee also: http://coreboot.org/Flashrom\n");
+}
+
 /**
  * Match boards on coreboot table gathered vendor and part name.
  * Require main PCI IDs to match too as extra safety.
diff --git a/chipset_enable.c b/chipset_enable.c
index 84cb191..872f254 100644
--- a/chipset_enable.c
+++ b/chipset_enable.c
@@ -561,6 +561,17 @@
 	{0x1166, 0x0205, "Broadcom HT-1000", enable_flash_ht1000},
 };
 
+void print_supported_chipsets(void)
+{
+	int i;
+
+	printf("\nSupported chipsets:\n\n");
+
+	for (i = 0; i < ARRAY_SIZE(enables); i++)
+		printf("%s (%04x:%04x)\n", enables[i].name,
+		       enables[i].vendor, enables[i].device);
+}
+
 int chipset_flash_enable(void)
 {
 	struct pci_dev *dev = 0;
@@ -568,8 +579,7 @@
 	int i;
 
 	/* Now let's try to find the chipset we have... */
-	/* TODO: Use ARRAY_SIZE. */
-	for (i = 0; i < sizeof(enables) / sizeof(enables[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(enables); i++) {
 		dev = pci_dev_find(enables[i].vendor, enables[i].device);
 		if (dev)
 			break;
diff --git a/flash.h b/flash.h
index 67d276f..f15ab21 100644
--- a/flash.h
+++ b/flash.h
@@ -30,6 +30,8 @@
 #include <stdint.h>
 #include <stdio.h>
 
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
 struct flashchip {
 	const char *name;
 	/* With 32bit manufacture_id and model_id we can cover IDs up to
@@ -287,11 +289,14 @@
 struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
 			      uint16_t card_vendor, uint16_t card_device);
 
+
 /* board_enable.c */
 int board_flash_enable(const char *vendor, const char *part);
+void print_supported_boards(void);
 
 /* chipset_enable.c */
 int chipset_flash_enable(void);
+void print_supported_chipsets(void);
 
 /* Physical memory mapping device */
 #if defined (__sun) && (defined(__i386) || defined(__amd64))
diff --git a/flashrom.8 b/flashrom.8
index 287b7f7..21e9036 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -2,13 +2,13 @@
 .SH NAME
 flashrom \- a universal BIOS/ROM/flash programming utility
 .SH SYNOPSIS
-.B flashrom \fR[\fB\-rwvEVfhR\fR] [\fB\-c\fR chipname] [\fB\-s\fR exclude_start] [\fB\-e\fR exclude_end]
+.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]
 .SH DESCRIPTION
 .B flashrom
 is a universal flash programming utility for DIP, PLCC, or SPI flash ROM
 chips. It can be used to flash BIOS/coreboot/firmware images, for example.
-
+.sp
 (see
 .B http://coreboot.org
 for details on coreboot)
@@ -61,6 +61,17 @@
 .B <name>
 from flash layout.
 .TP
+.B "\-L, \-\-list\-supported"
+List the ROM chips, chipsets, and mainboards supported by flashrom.
+The list of mainboards consists of those boards which need a special
+ROM write-enable function for flashrom to work.
+.sp
+There are many other boards which will work out of the box, without such
+special support in flashrom. Some of the known-good/known-bad and tested ones
+are listed at
+.BR http://coreboot.org/Flashrom#Supported_mainboards ,
+but the list is not exhaustive, of course.
+.TP
 .B "\-h, \-\-help"
 Show a help text and exit.
 .TP
diff --git a/flashrom.c b/flashrom.c
index 59196bc..a176319 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -193,9 +193,19 @@
 	return 0;
 }
 
+void print_supported_chips(void)
+{
+	int i;
+
+	printf("Supported ROM chips:\n\n");
+
+	for (i = 0; flashchips[i].name != NULL; i++)
+		printf("%s\n", flashchips[i].name);
+}
+
 void usage(const char *name)
 {
-	printf("usage: %s [-rwvEVfhR] [-c chipname] [-s exclude_start]\n", name);
+	printf("usage: %s [-rwvEVfLhR] [-c chipname] [-s exclude_start]\n", name);
 	printf("       [-e exclude_end] [-m [vendor:]part] [-l file.layout] [-i imagename] [file]\n");
 	printf
 	    ("   -r | --read:                      read flash and save into file\n"
@@ -210,8 +220,10 @@
 	     "   -f | --force:                     force write without checking image\n"
 	     "   -l | --layout <file.layout>:      read rom layout from file\n"
 	     "   -i | --image <name>:              only flash image name from flash layout\n"
+	     "   -L | --list-supported:            print supported devices\n"
+	     "   -h | --help:                      print this help text\n"
 	     "   -R | --version:                   print the version (release)\n"
-            "\n" " If no file is specified, then all that happens"
+	     "\n" " If no file is specified, then all that happens"
 	     " is that flash info is dumped.\n\n");
 	exit(1);
 }
@@ -245,6 +257,7 @@
 		{"force", 0, 0, 'f'},
 		{"layout", 1, 0, 'l'},
 		{"image", 1, 0, 'i'},
+		{"list-supported", 0, 0, 'L'},
 		{"help", 0, 0, 'h'},
 		{"version", 0, 0, 'R'},
 		{0, 0, 0, 0}
@@ -264,7 +277,7 @@
 	}
 
 	setbuf(stdout, NULL);
-	while ((opt = getopt_long(argc, argv, "rRwvVEfc:s:e:m:l:i:h",
+	while ((opt = getopt_long(argc, argv, "rRwvVEfc:s:e:m:l:i:Lh",
 				  long_options, &option_index)) != EOF) {
 		switch (opt) {
 		case 'r':
@@ -317,6 +330,12 @@
 			tempstr = strdup(optarg);
 			find_romentry(tempstr);
 			break;
+		case 'L':
+			print_supported_chips();
+			print_supported_chipsets();
+			print_supported_boards();
+			exit(0);
+			break;
 		case 'R':
 			print_version();
 			exit(0);