programmer_table: convert entries to pointers

Allows us to move the individual entries into their respective driver files.

Change-Id: Ifbb0ee4db5a85b1cd2afeafe4dca838579f79878
Signed-off-by: Thomas Heijligen <thomas.heijligen@secunet.de>
Reviewed-on: https://review.coreboot.org/c/flashrom/+/52945
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/cli_classic.c b/cli_classic.c
index 5fd8092..bc2d40d 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -407,7 +407,7 @@
 					"for details.\n");
 			}
 			for (prog = 0; prog < PROGRAMMER_INVALID; prog++) {
-				name = programmer_table[prog].name;
+				name = programmer_table[prog]->name;
 				namelen = strlen(name);
 				if (strncmp(optarg, name, namelen) == 0) {
 					switch (optarg[namelen]) {
@@ -545,7 +545,7 @@
 			/* We need to strdup here because we free(pparam) unconditionally later. */
 			pparam = strdup(CONFIG_DEFAULT_PROGRAMMER_ARGS);
 			msg_pinfo("Using default programmer \"%s\" with arguments \"%s\".\n",
-				  programmer_table[CONFIG_DEFAULT_PROGRAMMER].name, pparam);
+				  programmer_table[CONFIG_DEFAULT_PROGRAMMER]->name, pparam);
 		} else {
 			msg_perr("Please select a programmer with the --programmer parameter.\n"
 #if CONFIG_INTERNAL == 1
diff --git a/flashrom.c b/flashrom.c
index 9cd1003..f5a39b8 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -155,8 +155,8 @@
 	programmer_may_write = 1;
 
 	programmer_param = param;
-	msg_pdbg("Initializing %s programmer\n", programmer_table[programmer].name);
-	ret = programmer_table[programmer].init();
+	msg_pdbg("Initializing %s programmer\n", programmer_table[programmer]->name);
+	ret = programmer_table[programmer]->init();
 	if (programmer_param && strlen(programmer_param)) {
 		if (ret != 0) {
 			/* It is quite possible that any unhandled programmer parameter would have been valid,
@@ -200,7 +200,7 @@
 
 void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len)
 {
-	void *ret = programmer_table[programmer].map_flash_region(descr, phys_addr, len);
+	void *ret = programmer_table[programmer]->map_flash_region(descr, phys_addr, len);
 	msg_gspew("%s: mapping %s from 0x%0*" PRIxPTR " to 0x%0*" PRIxPTR "\n",
 		  __func__, descr, PRIxPTR_WIDTH, phys_addr, PRIxPTR_WIDTH, (uintptr_t) ret);
 	return ret;
@@ -208,7 +208,7 @@
 
 void programmer_unmap_flash_region(void *virt_addr, size_t len)
 {
-	programmer_table[programmer].unmap_flash_region(virt_addr, len);
+	programmer_table[programmer]->unmap_flash_region(virt_addr, len);
 	msg_gspew("%s: unmapped 0x%0*" PRIxPTR "\n", __func__, PRIxPTR_WIDTH, (uintptr_t)virt_addr);
 }
 
@@ -256,7 +256,7 @@
 void programmer_delay(unsigned int usecs)
 {
 	if (usecs > 0)
-		programmer_table[programmer].delay(usecs);
+		programmer_table[programmer]->delay(usecs);
 }
 
 int read_memmapped(struct flashctx *flash, uint8_t *buf, unsigned int start,
@@ -840,12 +840,12 @@
 		  flash->chip->vendor, flash->chip->name, flash->chip->total_size, tmp);
 	free(tmp);
 #if CONFIG_INTERNAL == 1
-	if (programmer_table[programmer].map_flash_region == physmap)
+	if (programmer_table[programmer]->map_flash_region == physmap)
 		msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
 			  PRIxPTR_WIDTH, flash->physical_memory);
 	else
 #endif
-		msg_cinfo("on %s.\n", programmer_table[programmer].name);
+		msg_cinfo("on %s.\n", programmer_table[programmer]->name);
 
 	/* Flash registers may more likely not be mapped if the chip was forced.
 	 * Lock info may be stored in registers, so avoid lock info printing. */
@@ -1586,7 +1586,7 @@
 	int i;
 
 	for (p = 0; p < PROGRAMMER_INVALID; p++) {
-		pname = programmer_table[p].name;
+		pname = programmer_table[p]->name;
 		pnamelen = strlen(pname);
 		if (remaining - pnamelen - 2 < 0) {
 			if (firstline)
@@ -1718,45 +1718,50 @@
 		ret = 1;
 	}
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
-		const struct programmer_entry p = programmer_table[i];
-		if (p.name == NULL) {
+		const struct programmer_entry *const p = programmer_table[i];
+		if (p == NULL) {
+			msg_gerr("Programmer with index %d is NULL instead of a valid pointer!\n", i);
+			ret = 1;
+			continue;
+		}
+		if (p->name == NULL) {
 			msg_gerr("All programmers need a valid name, but the one with index %d does not!\n", i);
 			ret = 1;
 			/* This might hide other problems with this programmer, but allows for better error
 			 * messages below without jumping through hoops. */
 			continue;
 		}
-		switch (p.type) {
+		switch (p->type) {
 		case USB:
 		case PCI:
 		case OTHER:
-			if (p.devs.note == NULL) {
-				if (strcmp("internal", p.name) == 0)
+			if (p->devs.note == NULL) {
+				if (strcmp("internal", p->name) == 0)
 					break; /* This one has its device list stored separately. */
 				msg_gerr("Programmer %s has neither a device list nor a textual description!\n",
-					 p.name);
+					 p->name);
 				ret = 1;
 			}
 			break;
 		default:
-			msg_gerr("Programmer %s does not have a valid type set!\n", p.name);
+			msg_gerr("Programmer %s does not have a valid type set!\n", p->name);
 			ret = 1;
 			break;
 		}
-		if (p.init == NULL) {
-			msg_gerr("Programmer %s does not have a valid init function!\n", p.name);
+		if (p->init == NULL) {
+			msg_gerr("Programmer %s does not have a valid init function!\n", p->name);
 			ret = 1;
 		}
-		if (p.delay == NULL) {
-			msg_gerr("Programmer %s does not have a valid delay function!\n", p.name);
+		if (p->delay == NULL) {
+			msg_gerr("Programmer %s does not have a valid delay function!\n", p->name);
 			ret = 1;
 		}
-		if (p.map_flash_region == NULL) {
-			msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p.name);
+		if (p->map_flash_region == NULL) {
+			msg_gerr("Programmer %s does not have a valid map_flash_region function!\n", p->name);
 			ret = 1;
 		}
-		if (p.unmap_flash_region == NULL) {
-			msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p.name);
+		if (p->unmap_flash_region == NULL) {
+			msg_gerr("Programmer %s does not have a valid unmap_flash_region function!\n", p->name);
 			ret = 1;
 		}
 	}
diff --git a/libflashrom.c b/libflashrom.c
index 23358c9..09a4e4d 100644
--- a/libflashrom.c
+++ b/libflashrom.c
@@ -124,7 +124,7 @@
 
 	if (supported_programmers != NULL) {
 		for (; p < PROGRAMMER_INVALID; ++p) {
-			supported_programmers[p] = programmer_table[p].name;
+			supported_programmers[p] = programmer_table[p]->name;
 		}
 	} else {
 		msg_gerr("Memory allocation error!\n");
@@ -279,7 +279,7 @@
 	unsigned prog;
 
 	for (prog = 0; prog < PROGRAMMER_INVALID; prog++) {
-		if (strcmp(prog_name, programmer_table[prog].name) == 0)
+		if (strcmp(prog_name, programmer_table[prog]->name) == 0)
 			break;
 	}
 	if (prog >= PROGRAMMER_INVALID) {
diff --git a/print.c b/print.c
index feca45e..77cf3d5 100644
--- a/print.c
+++ b/print.c
@@ -425,10 +425,10 @@
 }
 #endif
 
-static void print_supported_devs(const struct programmer_entry prog, const char *const type)
+static void print_supported_devs(const struct programmer_entry *const prog, const char *const type)
 {
-	const struct dev_entry *const devs = prog.devs.dev;
-	msg_ginfo("\nSupported %s devices for the %s programmer:\n", type, prog.name);
+	const struct dev_entry *const devs = prog->devs.dev;
+	msg_ginfo("\nSupported %s devices for the %s programmer:\n", type, prog->name);
 	unsigned int maxvendorlen = strlen("Vendor") + 1;
 	unsigned int maxdevlen = strlen("Device") + 1;
 
@@ -475,7 +475,7 @@
 	msg_ginfo("\n");
 #if CONFIG_INTERNAL == 1
 	msg_ginfo("\nSupported devices for the %s programmer:\n\n",
-	       programmer_table[PROGRAMMER_INTERNAL].name);
+	       programmer_table[PROGRAMMER_INTERNAL]->name);
 	print_supported_chipsets();
 	msg_ginfo("\n");
 	print_supported_boards_helper(boards_known, "mainboards");
@@ -483,8 +483,8 @@
 	print_supported_boards_helper(laptops_known, "mobile devices");
 #endif
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
-		const struct programmer_entry prog = programmer_table[i];
-		switch (prog.type) {
+		const struct programmer_entry *const prog = programmer_table[i];
+		switch (prog->type) {
 		case USB:
 			print_supported_devs(prog, "USB");
 			break;
@@ -492,14 +492,14 @@
 			print_supported_devs(prog, "PCI");
 			break;
 		case OTHER:
-			if (prog.devs.note != NULL) {
-				msg_ginfo("\nSupported devices for the %s programmer:\n", prog.name);
-				msg_ginfo("%s", prog.devs.note);
+			if (prog->devs.note != NULL) {
+				msg_ginfo("\nSupported devices for the %s programmer:\n", prog->name);
+				msg_ginfo("%s", prog->devs.note);
 			}
 			break;
 		default:
 			msg_gerr("\n%s: %s: Uninitialized programmer type! Please report a bug at "
-				 "flashrom@flashrom.org\n", __func__, prog.name);
+				 "flashrom@flashrom.org\n", __func__, prog->name);
 			break;
 		}
 	}
diff --git a/print_wiki.c b/print_wiki.c
index b2ac65c..3610135 100644
--- a/print_wiki.c
+++ b/print_wiki.c
@@ -355,11 +355,11 @@
 	return count;
 }
 
-static void print_supported_devs_wiki_helper(const struct programmer_entry prog)
+static void print_supported_devs_wiki_helper(const struct programmer_entry *const prog)
 {
 	int i = 0;
 	static int c = 0;
-	const struct dev_entry *devs = prog.devs.dev;
+	const struct dev_entry *devs = prog->devs.dev;
 	const unsigned int count = count_supported_devs_wiki(devs);
 
 	/* Alternate colors if the vendor changes. */
@@ -368,7 +368,7 @@
 	for (i = 0; devs[i].vendor_id != 0; i++) {
 		printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
 		if (i == 0)
-			printf("| rowspan=\"%u\" | %s |", count, prog.name);
+			printf("| rowspan=\"%u\" | %s |", count, prog->name);
 		printf("| %s || %s || %04x:%04x || {{%s}}\n", devs[i].vendor_name, devs[i].device_name,
 		       devs[i].vendor_id, devs[i].device_id, test_state_to_template(devs[i].status));
 	}
@@ -381,13 +381,13 @@
 	unsigned int i;
 
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
-		const struct programmer_entry prog = programmer_table[i];
-		switch (prog.type) {
+		const struct programmer_entry *const prog = programmer_table[i];
+		switch (prog->type) {
 		case USB:
-			usb_count += count_supported_devs_wiki(prog.devs.dev);
+			usb_count += count_supported_devs_wiki(prog->devs.dev);
 			break;
 		case PCI:
-			pci_count += count_supported_devs_wiki(prog.devs.dev);
+			pci_count += count_supported_devs_wiki(prog->devs.dev);
 			break;
 		case OTHER:
 		default:
@@ -400,8 +400,8 @@
 	       "{%s%s", pci_count, th_start, programmer_th);
 
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
-		const struct programmer_entry prog = programmer_table[i];
-		if (prog.type == PCI) {
+		const struct programmer_entry *const prog = programmer_table[i];
+		if (prog->type == PCI) {
 			print_supported_devs_wiki_helper(prog);
 		}
 	}
@@ -412,8 +412,8 @@
 	       "{%s%s", usb_count, th_start, programmer_th);
 
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
-		const struct programmer_entry prog = programmer_table[i];
-		if (prog.type == USB) {
+		const struct programmer_entry *const prog = programmer_table[i];
+		if (prog->type == USB) {
 			print_supported_devs_wiki_helper(prog);
 		}
 	}
@@ -426,11 +426,11 @@
 
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
 		static int c = 0;
-		const struct programmer_entry prog = programmer_table[i];
-		if (prog.type == OTHER && prog.devs.note != NULL) {
+		const struct programmer_entry *const prog = programmer_table[i];
+		if (prog->type == OTHER && prog->devs.note != NULL) {
 			c = !c;
 			printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
-			printf("| %s || %s", prog.name, prog.devs.note);
+			printf("| %s || %s", prog->name, prog->devs.note);
 		}
 	}
 	printf("\n|}\n\n|}\n");
diff --git a/programmer.h b/programmer.h
index 945d0a7..324b953 100644
--- a/programmer.h
+++ b/programmer.h
@@ -175,7 +175,7 @@
 	void (*delay) (unsigned int usecs);
 };
 
-extern const struct programmer_entry programmer_table[];
+extern const struct programmer_entry *const programmer_table[];
 extern const size_t programmer_table_size;
 
 int programmer_init(enum programmer prog, const char *param);
diff --git a/programmer_table.c b/programmer_table.c
index 3c6dd58..5c7f0f1 100644
--- a/programmer_table.c
+++ b/programmer_table.c
@@ -14,479 +14,636 @@
 
 #include "programmer.h"
 
-const struct programmer_entry programmer_table[] = {
 #if CONFIG_INTERNAL == 1
-	{
-		.name			= "internal",
-		.type			= OTHER,
-		.devs.note		= NULL,
-		.init			= internal_init,
-		.map_flash_region	= physmap,
-		.unmap_flash_region	= physunmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_internal = {
+	.name			= "internal",
+	.type			= OTHER,
+	.devs.note		= NULL,
+	.init			= internal_init,
+	.map_flash_region	= physmap,
+	.unmap_flash_region	= physunmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_DUMMY == 1
-	{
-		.name			= "dummy",
-		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Dummy device, does nothing and logs all accesses\n",
-		.init			= dummy_init,
-		.map_flash_region	= dummy_map,
-		.unmap_flash_region	= dummy_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_dummy = {
+	.name			= "dummy",
+	.type			= OTHER,
+				/* FIXME */
+	.devs.note		= "Dummy device, does nothing and logs all accesses\n",
+	.init			= dummy_init,
+	.map_flash_region	= dummy_map,
+	.unmap_flash_region	= dummy_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_MEC1308 == 1
-	{
-		.name			= "mec1308",
-		.type			= OTHER,
-		.devs.note		= "Microchip MEC1308 Embedded Controller.\n",
-		.init			= mec1308_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_mec1308 = {
+	.name			= "mec1308",
+	.type			= OTHER,
+	.devs.note		= "Microchip MEC1308 Embedded Controller.\n",
+	.init			= mec1308_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NIC3COM == 1
-	{
-		.name			= "nic3com",
-		.type			= PCI,
-		.devs.dev		= nics_3com,
-		.init			= nic3com_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nic3com = {
+	.name			= "nic3com",
+	.type			= PCI,
+	.devs.dev		= nics_3com,
+	.init			= nic3com_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NICREALTEK == 1
-	{
-		/* This programmer works for Realtek RTL8139 and SMC 1211. */
-		.name			= "nicrealtek",
-		.type			= PCI,
-		.devs.dev		= nics_realtek,
-		.init			= nicrealtek_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nicrealtek = {
+	/* This programmer works for Realtek RTL8139 and SMC 1211. */
+	.name			= "nicrealtek",
+	.type			= PCI,
+	.devs.dev		= nics_realtek,
+	.init			= nicrealtek_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NICNATSEMI == 1
-	{
-		.name			= "nicnatsemi",
-		.type			= PCI,
-		.devs.dev		= nics_natsemi,
-		.init			= nicnatsemi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nicnatsemi = {
+	.name			= "nicnatsemi",
+	.type			= PCI,
+	.devs.dev		= nics_natsemi,
+	.init			= nicnatsemi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_GFXNVIDIA == 1
-	{
-		.name			= "gfxnvidia",
-		.type			= PCI,
-		.devs.dev		= gfx_nvidia,
-		.init			= gfxnvidia_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_gfxnvidia = {
+	.name			= "gfxnvidia",
+	.type			= PCI,
+	.devs.dev		= gfx_nvidia,
+	.init			= gfxnvidia_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_RAIDEN_DEBUG_SPI == 1
-	{
-		.name			= "raiden_debug_spi",
-		.type			= USB,
-		.devs.dev		= devs_raiden,
-		.init			= raiden_debug_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_raiden_debug_spi = {
+	.name			= "raiden_debug_spi",
+	.type			= USB,
+	.devs.dev		= devs_raiden,
+	.init			= raiden_debug_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_DRKAISER == 1
-	{
-		.name			= "drkaiser",
-		.type			= PCI,
-		.devs.dev		= drkaiser_pcidev,
-		.init			= drkaiser_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_drkaiser = {
+	.name			= "drkaiser",
+	.type			= PCI,
+	.devs.dev		= drkaiser_pcidev,
+	.init			= drkaiser_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_SATASII == 1
-	{
-		.name			= "satasii",
-		.type			= PCI,
-		.devs.dev		= satas_sii,
-		.init			= satasii_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_satasii = {
+	.name			= "satasii",
+	.type			= PCI,
+	.devs.dev		= satas_sii,
+	.init			= satasii_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_ATAHPT == 1
-	{
-		.name			= "atahpt",
-		.type			= PCI,
-		.devs.dev		= ata_hpt,
-		.init			= atahpt_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_atahpt = {
+	.name			= "atahpt",
+	.type			= PCI,
+	.devs.dev		= ata_hpt,
+	.init			= atahpt_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_ATAVIA == 1
-	{
-		.name			= "atavia",
-		.type			= PCI,
-		.devs.dev		= ata_via,
-		.init			= atavia_init,
-		.map_flash_region	= atavia_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_atavia = {
+	.name			= "atavia",
+	.type			= PCI,
+	.devs.dev		= ata_via,
+	.init			= atavia_init,
+	.map_flash_region	= atavia_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_ATAPROMISE == 1
-	{
-		.name			= "atapromise",
-		.type			= PCI,
-		.devs.dev		= ata_promise,
-		.init			= atapromise_init,
-		.map_flash_region	= atapromise_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_atapromise = {
+	.name			= "atapromise",
+	.type			= PCI,
+	.devs.dev		= ata_promise,
+	.init			= atapromise_init,
+	.map_flash_region	= atapromise_map,
+	.unmap_flash_region	= fallback_unmap,
+    .delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_IT8212 == 1
-	{
-		.name			= "it8212",
-		.type			= PCI,
-		.devs.dev		= devs_it8212,
-		.init			= it8212_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_it8212 = {
+	.name			= "it8212",
+	.type			= PCI,
+	.devs.dev		= devs_it8212,
+	.init			= it8212_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_FT2232_SPI == 1
-	{
-		.name			= "ft2232_spi",
-		.type			= USB,
-		.devs.dev		= devs_ft2232spi,
-		.init			= ft2232_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_ft2232_spi = {
+	.name			= "ft2232_spi",
+	.type			= USB,
+	.devs.dev		= devs_ft2232spi,
+	.init			= ft2232_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_SERPROG == 1
-	{
-		.name			= "serprog",
-		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "All programmer devices speaking the serprog protocol\n",
-		.init			= serprog_init,
-		.map_flash_region	= serprog_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= serprog_delay,
-	},
+const struct programmer_entry programmer_serprog = {
+	.name			= "serprog",
+	.type			= OTHER,
+				/* FIXME */
+	.devs.note		= "All programmer devices speaking the serprog protocol\n",
+	.init			= serprog_init,
+	.map_flash_region	= serprog_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= serprog_delay,
+};
 #endif
 
 #if CONFIG_BUSPIRATE_SPI == 1
-	{
-		.name			= "buspirate_spi",
-		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Dangerous Prototypes Bus Pirate\n",
-		.init			= buspirate_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_buspirate_spi = {
+	.name			= "buspirate_spi",
+	.type			= OTHER,
+				/* FIXME */
+	.devs.note		= "Dangerous Prototypes Bus Pirate\n",
+	.init			= buspirate_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_DEDIPROG == 1
-	{
-		.name			= "dediprog",
-		.type			= USB,
-		.devs.dev		= devs_dediprog,
-		.init			= dediprog_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_dediprog = {
+	.name			= "dediprog",
+	.type			= USB,
+	.devs.dev		= devs_dediprog,
+	.init			= dediprog_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_DEVELOPERBOX_SPI == 1
-	{
-		.name			= "developerbox",
-		.type			= USB,
-		.devs.dev		= devs_developerbox_spi,
-		.init			= developerbox_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_developerbox = {
+	.name			= "developerbox",
+	.type			= USB,
+	.devs.dev		= devs_developerbox_spi,
+	.init			= developerbox_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+    .delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_ENE_LPC == 1
-	{
-		.name			= "ene_lpc",
-		.type			= OTHER,
-		.devs.note		= "ENE LPC interface keyboard controller\n",
-		.init			= ene_lpc_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_ene_lpc = {
+	.name			= "ene_lpc",
+	.type			= OTHER,
+	.devs.note		= "ENE LPC interface keyboard controller\n",
+	.init			= ene_lpc_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_RAYER_SPI == 1
-	{
-		.name			= "rayer_spi",
-		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "RayeR parallel port programmer\n",
-		.init			= rayer_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_rayer_spi = {
+	.name			= "rayer_spi",
+	.type			= OTHER,
+				/* FIXME */
+	.devs.note		= "RayeR parallel port programmer\n",
+	.init			= rayer_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_PONY_SPI == 1
-	{
-		.name			= "pony_spi",
-		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Programmers compatible with SI-Prog, serbang or AJAWe\n",
-		.init			= pony_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_pony_spi = {
+	.name			= "pony_spi",
+	.type			= OTHER,
+				/* FIXME */
+	.devs.note		= "Programmers compatible with SI-Prog, serbang or AJAWe\n",
+	.init			= pony_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NICINTEL == 1
-	{
-		.name			= "nicintel",
-		.type			= PCI,
-		.devs.dev		= nics_intel,
-		.init			= nicintel_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nicintel = {
+	.name			= "nicintel",
+	.type			= PCI,
+	.devs.dev		= nics_intel,
+	.init			= nicintel_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NICINTEL_SPI == 1
-	{
-		.name			= "nicintel_spi",
-		.type			= PCI,
-		.devs.dev		= nics_intel_spi,
-		.init			= nicintel_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nicintel_spi = {
+	.name			= "nicintel_spi",
+	.type			= PCI,
+	.devs.dev		= nics_intel_spi,
+	.init			= nicintel_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NICINTEL_EEPROM == 1
-	{
-		.name			= "nicintel_eeprom",
-		.type			= PCI,
-		.devs.dev		= nics_intel_ee,
-		.init			= nicintel_ee_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_nicintel_eeprom = {
+	.name			= "nicintel_eeprom",
+	.type			= PCI,
+	.devs.dev		= nics_intel_ee,
+	.init			= nicintel_ee_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_OGP_SPI == 1
-	{
-		.name			= "ogp_spi",
-		.type			= PCI,
-		.devs.dev		= ogp_spi,
-		.init			= ogp_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_ogp_spi = {
+	.name			= "ogp_spi",
+	.type			= PCI,
+	.devs.dev		= ogp_spi,
+	.init			= ogp_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_SATAMV == 1
-	{
-		.name			= "satamv",
-		.type			= PCI,
-		.devs.dev		= satas_mv,
-		.init			= satamv_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_satamv = {
+	.name			= "satamv",
+	.type			= PCI,
+	.devs.dev		= satas_mv,
+	.init			= satamv_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_LINUX_MTD == 1
-	{
-		.name			= "linux_mtd",
-		.type			= OTHER,
-		.devs.note		= "Device files /dev/mtd*\n",
-		.init			= linux_mtd_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_linux_mtd = {
+	.name			= "linux_mtd",
+	.type			= OTHER,
+	.devs.note		= "Device files /dev/mtd*\n",
+	.init			= linux_mtd_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_LINUX_SPI == 1
-	{
-		.name			= "linux_spi",
-		.type			= OTHER,
-		.devs.note		= "Device files /dev/spidev*.*\n",
-		.init			= linux_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_linux_spi = {
+	.name			= "linux_spi",
+	.type			= OTHER,
+	.devs.note		= "Device files /dev/spidev*.*\n",
+	.init			= linux_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_LSPCON_I2C_SPI == 1
-	{
-		.name			= "lspcon_i2c_spi",
-		.type			= OTHER,
-		.devs.note		= "Device files /dev/i2c-*.\n",
-		.init			= lspcon_i2c_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_lspcon_i2c_spi = {
+	.name			= "lspcon_i2c_spi",
+	.type			= OTHER,
+	.devs.note		= "Device files /dev/i2c-*.\n",
+	.init			= lspcon_i2c_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_REALTEK_MST_I2C_SPI == 1
-	{
-		.name			= "realtek_mst_i2c_spi",
-		.type			= OTHER,
-		.devs.note		= "Device files /dev/i2c-*.\n",
-		.init			= realtek_mst_i2c_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_realtek_mst_i2c_spi = {
+	.name			= "realtek_mst_i2c_spi",
+	.type			= OTHER,
+	.devs.note		= "Device files /dev/i2c-*.\n",
+	.init			= realtek_mst_i2c_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_USBBLASTER_SPI == 1
-	{
-		.name			= "usbblaster_spi",
-		.type			= USB,
-		.devs.dev		= devs_usbblasterspi,
-		.init			= usbblaster_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_usbblaster_spi = {
+	.name			= "usbblaster_spi",
+	.type			= USB,
+	.devs.dev		= devs_usbblasterspi,
+	.init			= usbblaster_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_MSTARDDC_SPI == 1
-	{
-		.name			= "mstarddc_spi",
-		.type			= OTHER,
-		.devs.note		= "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
-		.init			= mstarddc_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_mstarddc_spi = {
+	.name			= "mstarddc_spi",
+	.type			= OTHER,
+	.devs.note		= "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
+	.init			= mstarddc_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_PICKIT2_SPI == 1
-	{
-		.name			= "pickit2_spi",
-		.type			= USB,
-		.devs.dev		= devs_pickit2_spi,
-		.init			= pickit2_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_pickit2_spi = {
+	.name			= "pickit2_spi",
+	.type			= USB,
+	.devs.dev		= devs_pickit2_spi,
+	.init			= pickit2_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_CH341A_SPI == 1
-	{
-		.name			= "ch341a_spi",
-		.type			= USB,
-		.devs.dev		= devs_ch341a_spi,
-		.init			= ch341a_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= ch341a_spi_delay,
-	},
+const struct programmer_entry programmer_ch341a_spi = {
+	.name			= "ch341a_spi",
+	.type			= USB,
+	.devs.dev		= devs_ch341a_spi,
+	.init			= ch341a_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= ch341a_spi_delay,
+};
 #endif
 
 #if CONFIG_DIGILENT_SPI == 1
-	{
-		.name			= "digilent_spi",
-		.type			= USB,
-		.devs.dev		= devs_digilent_spi,
-		.init			= digilent_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_digilent_spi = {
+	.name			= "digilent_spi",
+	.type			= USB,
+	.devs.dev		= devs_digilent_spi,
+	.init			= digilent_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_JLINK_SPI == 1
-	{
-		.name			= "jlink_spi",
-		.type			= OTHER,
-		.init			= jlink_spi_init,
-		.devs.note		= "SEGGER J-Link and compatible devices\n",
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_jlink_spi = {
+	.name			= "jlink_spi",
+	.type			= OTHER,
+	.init			= jlink_spi_init,
+	.devs.note		= "SEGGER J-Link and compatible devices\n",
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_NI845X_SPI == 1
-	{
-		.name			= "ni845x_spi",
-		.type			= OTHER, // choose other because NI-845x uses own USB implementation
-		.devs.note		= "National Instruments USB-845x\n",
-		.init			= ni845x_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_ni845x_spi = {
+	.name			= "ni845x_spi",
+	.type			= OTHER, // choose other because NI-845x uses own USB implementation
+	.devs.note		= "National Instruments USB-845x\n",
+	.init			= ni845x_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
 #endif
 
 #if CONFIG_STLINKV3_SPI == 1
-	{
-		.name			= "stlinkv3_spi",
-		.type			= USB,
-		.devs.dev		= devs_stlinkv3_spi,
-		.init			= stlinkv3_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.delay			= internal_delay,
-	},
+const struct programmer_entry programmer_stlinkv3_spi = {
+	.name			= "stlinkv3_spi",
+	.type			= USB,
+	.devs.dev		= devs_stlinkv3_spi,
+	.init			= stlinkv3_spi_init,
+	.map_flash_region	= fallback_map,
+	.unmap_flash_region	= fallback_unmap,
+	.delay			= internal_delay,
+};
+#endif
+
+const struct programmer_entry *const programmer_table[] = {
+
+#if CONFIG_INTERNAL == 1
+    &programmer_internal,
+#endif
+
+#if CONFIG_DUMMY == 1
+    &programmer_dummy,
+#endif
+
+#if CONFIG_MEC1308 == 1
+    &programmer_mec1308,
+#endif
+
+#if CONFIG_NIC3COM == 1
+    &programmer_nic3com,
+#endif
+
+#if CONFIG_NICREALTEK == 1
+    & programmer_nicrealtek,
+#endif
+
+#if CONFIG_NICNATSEMI == 1
+    &programmer_nicnatsemi,
+#endif
+
+#if CONFIG_GFXNVIDIA == 1
+    &programmer_gfxnvidia,
+#endif
+
+#if CONFIG_RAIDEN_DEBUG_SPI == 1
+    &programmer_raiden_debug_spi,
+#endif
+
+#if CONFIG_DRKAISER == 1
+    &programmer_drkaiser,
+#endif
+
+#if CONFIG_SATASII == 1
+    &programmer_satasii,
+#endif
+
+#if CONFIG_ATAHPT == 1
+    &programmer_atahpt,
+#endif
+
+#if CONFIG_ATAVIA == 1
+    &programmer_atavia,
+#endif
+
+#if CONFIG_ATAPROMISE == 1
+    &programmer_atapromise,
+#endif
+
+#if CONFIG_IT8212 == 1
+    &programmer_it8212,
+#endif
+
+#if CONFIG_FT2232_SPI == 1
+    &programmer_ft2232_spi,
+#endif
+
+#if CONFIG_SERPROG == 1
+    &programmer_serprog,
+#endif
+
+#if CONFIG_BUSPIRATE_SPI == 1
+    &programmer_buspirate_spi,
+#endif
+
+#if CONFIG_DEDIPROG == 1
+    &programmer_dediprog,
+#endif
+
+#if CONFIG_DEVELOPERBOX_SPI == 1
+    &programmer_developerbox,
+#endif
+
+#if CONFIG_ENE_LPC == 1
+    &programmer_ene_lpc,
+#endif
+
+#if CONFIG_RAYER_SPI == 1
+    &programmer_rayer_spi,
+#endif
+
+#if CONFIG_PONY_SPI == 1
+    &programmer_pony_spi,
+#endif
+
+#if CONFIG_NICINTEL == 1
+    &programmer_nicintel,
+#endif
+
+#if CONFIG_NICINTEL_SPI == 1
+    &programmer_nicintel_spi,
+#endif
+
+#if CONFIG_NICINTEL_EEPROM == 1
+    &programmer_nicintel_eeprom,
+#endif
+
+#if CONFIG_OGP_SPI == 1
+    &programmer_ogp_spi,
+#endif
+
+#if CONFIG_SATAMV == 1
+    &programmer_satamv,
+#endif
+
+#if CONFIG_LINUX_MTD == 1
+    &programmer_linux_mtd,
+#endif
+
+#if CONFIG_LINUX_SPI == 1
+    &programmer_linux_spi,
+#endif
+
+#if CONFIG_LSPCON_I2C_SPI == 1
+    &programmer_lspcon_i2c_spi,
+#endif
+
+#if CONFIG_REALTEK_MST_I2C_SPI == 1
+    &programmer_realtek_mst_i2c_spi,
+#endif
+
+#if CONFIG_USBBLASTER_SPI == 1
+    &programmer_usbblaster_spi,
+#endif
+
+#if CONFIG_MSTARDDC_SPI == 1
+    &programmer_mstarddc_spi,
+#endif
+
+#if CONFIG_PICKIT2_SPI == 1
+    &programmer_pickit2_spi,
+#endif
+
+#if CONFIG_CH341A_SPI == 1
+    &programmer_ch341a_spi,
+#endif
+
+#if CONFIG_DIGILENT_SPI == 1
+    &programmer_digilent_spi,
+#endif
+
+#if CONFIG_JLINK_SPI == 1
+    &programmer_jlink_spi,
+#endif
+
+#if CONFIG_NI845X_SPI == 1
+    &programmer_ni845x_spi,
+#endif
+
+#if CONFIG_STLINKV3_SPI == 1
+    &programmer_stlinkv3_spi,
 #endif
 };