[flashrom] [PATCH] Support device lists for programmers without PCI/USB IDs

Carl-Daniel Hailfinger c-d.hailfinger.devel.2006 at gmx.net
Mon Feb 29 01:10:16 CET 2016


On 22.02.2016 16:44, Carl-Daniel Hailfinger wrote:
> On 18.08.2014 00:52, Carl-Daniel Hailfinger wrote:
>> > Am 04.04.2013 06:57 schrieb Kyösti Mälkki:
>>>> >> > On Thu, 2013-04-04 at 02:07 +0200, Carl-Daniel Hailfinger wrote:
>>>>>> >>> >> Am 03.04.2013 01:11 schrieb Kyösti Mälkki:
>>>>>>>> >>>> >>> On Wed, 2013-04-03 at 00:03 +0200, Carl-Daniel Hailfinger wrote:
>>>>>>>>>> >>>>> >>>> Based on an idea by Kyösti Mälkki.
>>>>>>>>>> >>>>> >>>>
>>>>>>>> >>>> >>>
>>>>>>>> >>>> >>> The if/elseif/else -approach used in ft2232_spi to parse type= command
>>>>>>>> >>>> >>> line parameter force a redundant listing of the model strings and you do
>>>>>>>> >>>> >>> not list the supported model strings verbatim in flashrom -L output.
>>>>>> >>> >> AFAICS you didn't rework ft2232_spi either. Admittedly the possible
>>>>>> >>> >> changes for ft2232_spi are really not easy (one USB ID corresponds to
>>>>>> >>> >> two types, the other USB IDs correspond to one type each).
>>>> >> > The patch (which never appeared on the mailing list, BTW) was about
>>>> >> > fixing rayer_spi to list the different pinout models with flashrom -L.
>>>> >> > It wasn't a solution to any other programmer hardware. With the existing
>>>> >> > state of review queue, I felt it was better not to suggest global
>>>> >> > changes. Unfortunately, this dev_entry came up during the discussion.
>>>> >> >
>>>>>> >>> >> Anyway, this version should look better.
>>>>>> >>> >>
>>>>>> >>> >> print_wiki.c is still not fully converted.
>>>>>> >>> >> The output of flashrom -L for non-PCI/USB devices should look better
>>>>>> >>> >> now, but I'd appreciate a review of the changes.
>>>> >> > I need a conclusion on patches 3920-3924 first to regain motivation. I
>>>> >> > received Your comments on #flashrom previously, but since then You
>>>> >> > posted these partially conflicting and incompatible patches on the list.
>> > Stefan Tauner has committed those meanwhile.
>> >
>> >
>>>> >> > I will probably return to this topic in an average flashrom review
>>>> >> > feedback time.
>> > New version. Wiki support is done, but I'm not totally happy with the
>> > "Other" device output, especially the column labels. Suggestions are
>> > appreciated. Sample wiki output is here:
>> > https://www.flashrom.org/User:Hailfinger/Tests/--print-wiki2#Other_devices
>> >
>> > I also would love to get a review of the changes for the -L output for
>> > non-ID devices.
>> >
>> > Additional changes compared to previous versions of the patch:
>> > Dediprog is now listed as USB device instead of as a "Other" device.
>> > Rayer_spi now uses the same array for model selection and -L/-z.
>> >
>> > TODO:
>> > Pony_spi should use the same code as Rayer_spi for handling different
>> > variants of the hardware. Debatable whether that should happen in this
>> > patch.
>> > Dediprog should not code the IDs in a table, then use them again in
>> > open-coded form during init. Same for Usbblaster_spi. Ft2232_spi is even
>> > weirder in that regard. In general, all the USB programmers have init
>> > functions without any consistent style whatsoever compared to the
>> > unified PCI programmer init approach.
>> > A few FIXMEs and #warnings mark the places where review would be highly
>> > appreciated.
> New version. pony_spi now uses the same code as rayer_spi.
> dediprog and pickit2_spi are now fixed by Stefan as of r1941/r1942.
> usbblaster_spi and ft2232_spi remain as TODO.
> No common code for usb programmer init yet (whether that's a real TODO
> or not remains to be discussed).
>
> TODO: Use one consistent naming scheme for programmer ID lists. Here is
> our list of device id array names:
> *_devs:
> internal_devs dummy_devs rayer_spi_devs pony_spi_devs buspirate_spi_devs
> linux_spi_devs serprog_devs
> devs_*:
> devs_it8212 devs_ft2232spi devs_usbblasterspi devs_mstarddc_spi
> devs_pickit2_spi devs_dediprog devs_ch341a_spi
> programmer name:
> ata_hpt ata_promise ata_via drkaiser_pcidev gfx_nvidia ogp_spi
> programmer name, plural s:
> satas_mv satas_sii
> inserting _ into the mangled programmer name:
> nics_3com nics_intel nics_intel_ee nics_intel_spi nics_natsemi nics_realtek
> I'd like to use a _devs suffix for the programmer name (or the file
> name, or the internal shorthand for all functions in said programmer
> file, just pick one and stick with it) similar to _init.

New version.
Consistent naming done.
TODOs left:
- print_wiki.c improvements?
- fix missing device close bug found in pony_spi during rework

Handle programmer variants by extending the device list with
variant-specific data.
Make device list variable naming consistent.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>

Index: flashrom-noid_programmers_support_device_list/atahpt.c
===================================================================
--- flashrom-noid_programmers_support_device_list/atahpt.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/atahpt.c	(Arbeitskopie)
@@ -35,7 +35,7 @@
 
 static uint32_t io_base_addr = 0;
 
-const struct dev_entry ata_hpt[] = {
+const struct id_dev_entry atahpt_devs[] = {
 	{0x1103, 0x0004, NT, "Highpoint", "HPT366/368/370/370A/372/372N"},
 	{0x1103, 0x0005, NT, "Highpoint", "HPT372A/372N"},
 	{0x1103, 0x0006, NT, "Highpoint", "HPT302/302N"},
@@ -66,7 +66,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(ata_hpt, PCI_BASE_ADDRESS_4);
+	dev = pcidev_init(atahpt_devs, PCI_BASE_ADDRESS_4);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/atapromise.c
===================================================================
--- flashrom-noid_programmers_support_device_list/atapromise.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/atapromise.c	(Arbeitskopie)
@@ -50,7 +50,7 @@
 static uint8_t *atapromise_bar = NULL;
 static size_t rom_size = 0;
 
-const struct dev_entry ata_promise[] = {
+const struct id_dev_entry atapromise_devs[] = {
 	{0x105a, 0x4d38, NT, "Promise", "PDC20262 (FastTrak66/Ultra66)"},
 	{0x105a, 0x0d30, NT, "Promise", "PDC20265 (FastTrak100 Lite/Ultra100)"},
 	{0x105a, 0x4d30, OK, "Promise", "PDC20267 (FastTrak100/Ultra100)"},
@@ -117,7 +117,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(ata_promise, PCI_BASE_ADDRESS_4);
+	dev = pcidev_init(atapromise_devs, PCI_BASE_ADDRESS_4);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/atavia.c
===================================================================
--- flashrom-noid_programmers_support_device_list/atavia.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/atavia.c	(Arbeitskopie)
@@ -52,7 +52,7 @@
 #define ENABLE_BYTE(address)	((~(1 << ((address) & 3))) & BROM_BYTE_ENABLE_MASK)
 #define BYTE_OFFSET(address)	(((addr) & 3) * 8)
 
-const struct dev_entry ata_via[] = {
+const struct id_dev_entry atavia_devs[] = {
 	{PCI_VENDOR_ID_VIA, 0x3249, DEP, "VIA", "VT6421A"},
 
 	{},
@@ -146,7 +146,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(ata_via, PCI_ROM_ADDRESS); /* Acutally no BAR setup needed at all. */
+	dev = pcidev_init(atavia_devs, PCI_ROM_ADDRESS); /* Acutally no BAR setup needed at all. */
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/buspirate_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/buspirate_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/buspirate_spi.c	(Arbeitskopie)
@@ -27,6 +27,11 @@
 #include "programmer.h"
 #include "spi.h"
 
+const struct noid_dev_entry buspirate_spi_devs[] = {
+	{"", OK, "Dangerous Prototypes Bus Pirate"},
+	{0},
+};
+
 /* Change this to #define if you want to test without a serial implementation */
 #undef FAKE_COMMUNICATION
 
Index: flashrom-noid_programmers_support_device_list/ch341a_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/ch341a_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/ch341a_spi.c	(Arbeitskopie)
@@ -87,7 +87,7 @@
 
 static struct libusb_device_handle *handle = NULL;
 
-const struct dev_entry devs_ch341a_spi[] = {
+const struct id_dev_entry ch341a_spi_devs[] = {
 	{0x1A86, 0x5512, OK, "Winchiphead (WCH)", "CH341A"},
 
 	{0},
@@ -446,8 +446,8 @@
 
 	libusb_set_debug(NULL, 3); // Enable information, warning and error messages (only).
 
-	uint16_t vid = devs_ch341a_spi[0].vendor_id;
-	uint16_t pid = devs_ch341a_spi[0].device_id;
+	uint16_t vid = ch341a_spi_devs[0].vendor_id;
+	uint16_t pid = ch341a_spi_devs[0].device_id;
 	handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
 	if (handle == NULL) {
 		msg_perr("Couldn't open device %04x:%04x.\n", vid, pid);
Index: flashrom-noid_programmers_support_device_list/dediprog.c
===================================================================
--- flashrom-noid_programmers_support_device_list/dediprog.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/dediprog.c	(Arbeitskopie)
@@ -143,7 +143,7 @@
 	LEAVE_STANDALONE_MODE = 1,
 };
 
-const struct dev_entry devs_dediprog[] = {
+const struct id_dev_entry dediprog_devs[] = {
 	{0x0483, 0xDADA, OK, "Dediprog", "SF100/SF600"},
 
 	{0},
@@ -1025,8 +1025,8 @@
 		return 1;
 	}
 
-	const uint16_t vid = devs_dediprog[0].vendor_id;
-	const uint16_t pid = devs_dediprog[0].device_id;
+	const uint16_t vid = dediprog_devs[0].vendor_id;
+	const uint16_t pid = dediprog_devs[0].device_id;
 	dediprog_handle = get_device_by_vid_pid_number(vid, pid, (unsigned int) usedevice);
 	if (!dediprog_handle) {
 		msg_perr("Could not find a Dediprog programmer on USB.\n");
Index: flashrom-noid_programmers_support_device_list/drkaiser.c
===================================================================
--- flashrom-noid_programmers_support_device_list/drkaiser.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/drkaiser.c	(Arbeitskopie)
@@ -33,7 +33,7 @@
 /* Mask to restrict flash accesses to the 128kB memory window. */
 #define DRKAISER_MEMMAP_MASK		((1 << 17) - 1)
 
-const struct dev_entry drkaiser_pcidev[] = {
+const struct id_dev_entry drkaiser_devs[] = {
 	{0x1803, 0x5057, OK, "Dr. Kaiser", "PC-Waechter (Actel FPGA)"},
 
 	{0},
@@ -64,7 +64,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(drkaiser_pcidev, PCI_BASE_ADDRESS_2);
+	dev = pcidev_init(drkaiser_devs, PCI_BASE_ADDRESS_2);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/dummyflasher.c
===================================================================
--- flashrom-noid_programmers_support_device_list/dummyflasher.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/dummyflasher.c	(Arbeitskopie)
@@ -39,6 +39,11 @@
 #include <sys/stat.h>
 #endif
 
+const struct noid_dev_entry dummy_devs[] = {
+	{"", OK, "Dummy device, does nothing and logs all accesses"},
+	{0},
+};
+
 #if EMULATE_CHIP
 static uint8_t *flashchip_contents = NULL;
 enum emu_chip {
Index: flashrom-noid_programmers_support_device_list/flashrom.c
===================================================================
--- flashrom-noid_programmers_support_device_list/flashrom.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/flashrom.c	(Arbeitskopie)
@@ -64,7 +64,7 @@
 	{
 		.name			= "internal",
 		.type			= OTHER,
-		.devs.note		= NULL,
+		.devs.noid_dev		= internal_devs,
 		.init			= internal_init,
 		.map_flash_region	= physmap,
 		.unmap_flash_region	= physunmap,
@@ -76,8 +76,7 @@
 	{
 		.name			= "dummy",
 		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Dummy device, does nothing and logs all accesses\n",
+		.devs.noid_dev		= dummy_devs,
 		.init			= dummy_init,
 		.map_flash_region	= dummy_map,
 		.unmap_flash_region	= dummy_unmap,
@@ -89,7 +88,7 @@
 	{
 		.name			= "nic3com",
 		.type			= PCI,
-		.devs.dev		= nics_3com,
+		.devs.id_dev		= nic3com_devs,
 		.init			= nic3com_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -102,7 +101,7 @@
 		/* This programmer works for Realtek RTL8139 and SMC 1211. */
 		.name			= "nicrealtek",
 		.type			= PCI,
-		.devs.dev		= nics_realtek,
+		.devs.id_dev		= nicrealtek_devs,
 		.init			= nicrealtek_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -114,7 +113,7 @@
 	{
 		.name			= "nicnatsemi",
 		.type			= PCI,
-		.devs.dev		= nics_natsemi,
+		.devs.id_dev		= nicnatsemi_devs,
 		.init			= nicnatsemi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -126,7 +125,7 @@
 	{
 		.name			= "gfxnvidia",
 		.type			= PCI,
-		.devs.dev		= gfx_nvidia,
+		.devs.id_dev		= gfxnvidia_devs,
 		.init			= gfxnvidia_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -138,7 +137,7 @@
 	{
 		.name			= "drkaiser",
 		.type			= PCI,
-		.devs.dev		= drkaiser_pcidev,
+		.devs.id_dev		= drkaiser_devs,
 		.init			= drkaiser_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -150,7 +149,7 @@
 	{
 		.name			= "satasii",
 		.type			= PCI,
-		.devs.dev		= satas_sii,
+		.devs.id_dev		= satasii_devs,
 		.init			= satasii_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -162,7 +161,7 @@
 	{
 		.name			= "atahpt",
 		.type			= PCI,
-		.devs.dev		= ata_hpt,
+		.devs.id_dev		= atahpt_devs,
 		.init			= atahpt_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -174,7 +173,7 @@
 	{
 		.name			= "atavia",
 		.type			= PCI,
-		.devs.dev		= ata_via,
+		.devs.id_dev		= atavia_devs,
 		.init			= atavia_init,
 		.map_flash_region	= atavia_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -186,7 +185,7 @@
 	{
 		.name			= "atapromise",
 		.type			= PCI,
-		.devs.dev		= ata_promise,
+		.devs.id_dev		= atapromise_devs,
 		.init			= atapromise_init,
 		.map_flash_region	= atapromise_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -198,7 +197,7 @@
 	{
 		.name			= "it8212",
 		.type			= PCI,
-		.devs.dev		= devs_it8212,
+		.devs.id_dev		= it8212_devs,
 		.init			= it8212_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -210,7 +209,7 @@
 	{
 		.name			= "ft2232_spi",
 		.type			= USB,
-		.devs.dev		= devs_ft2232spi,
+		.devs.id_dev		= ft2232_spi_devs,
 		.init			= ft2232_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -222,8 +221,7 @@
 	{
 		.name			= "serprog",
 		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "All programmer devices speaking the serprog protocol\n",
+		.devs.noid_dev		= serprog_devs,
 		.init			= serprog_init,
 		.map_flash_region	= serprog_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -235,8 +233,7 @@
 	{
 		.name			= "buspirate_spi",
 		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Dangerous Prototypes Bus Pirate\n",
+		.devs.noid_dev		= buspirate_spi_devs,
 		.init			= buspirate_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -248,7 +245,7 @@
 	{
 		.name			= "dediprog",
 		.type			= USB,
-		.devs.dev		= devs_dediprog,
+		.devs.id_dev		= dediprog_devs,
 		.init			= dediprog_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -260,8 +257,7 @@
 	{
 		.name			= "rayer_spi",
 		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "RayeR parallel port programmer\n",
+		.devs.noid_dev		= rayer_spi_devs,
 		.init			= rayer_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -273,8 +269,7 @@
 	{
 		.name			= "pony_spi",
 		.type			= OTHER,
-					/* FIXME */
-		.devs.note		= "Programmers compatible with SI-Prog, serbang or AJAWe\n",
+		.devs.noid_dev		= pony_spi_devs,
 		.init			= pony_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -286,7 +281,7 @@
 	{
 		.name			= "nicintel",
 		.type			= PCI,
-		.devs.dev		= nics_intel,
+		.devs.id_dev		= nicintel_devs,
 		.init			= nicintel_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -298,7 +293,7 @@
 	{
 		.name			= "nicintel_spi",
 		.type			= PCI,
-		.devs.dev		= nics_intel_spi,
+		.devs.id_dev		= nicintel_devs_spi,
 		.init			= nicintel_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -310,7 +305,7 @@
 	{
 		.name			= "nicintel_eeprom",
 		.type			= PCI,
-		.devs.dev		= nics_intel_ee,
+		.devs.id_dev		= nicintel_devs_ee,
 		.init			= nicintel_ee_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -322,7 +317,7 @@
 	{
 		.name			= "ogp_spi",
 		.type			= PCI,
-		.devs.dev		= ogp_spi,
+		.devs.id_dev		= ogp_spi,
 		.init			= ogp_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -334,7 +329,7 @@
 	{
 		.name			= "satamv",
 		.type			= PCI,
-		.devs.dev		= satas_mv,
+		.devs.id_dev		= satamv_devs,
 		.init			= satamv_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -346,7 +341,7 @@
 	{
 		.name			= "linux_spi",
 		.type			= OTHER,
-		.devs.note		= "Device files /dev/spidev*.*\n",
+		.devs.noid_dev		= linux_spi_devs,
 		.init			= linux_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -358,7 +353,7 @@
 	{
 		.name			= "usbblaster_spi",
 		.type			= USB,
-		.devs.dev		= devs_usbblasterspi,
+		.devs.id_dev		= usbblaster_spi_devs,
 		.init			= usbblaster_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -370,7 +365,7 @@
 	{
 		.name			= "mstarddc_spi",
 		.type			= OTHER,
-		.devs.note		= "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n",
+		.devs.noid_dev		= mstarddc_spi_devs,
 		.init			= mstarddc_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -382,7 +377,7 @@
 	{
 		.name			= "pickit2_spi",
 		.type			= USB,
-		.devs.dev		= devs_pickit2_spi,
+		.devs.id_dev		= pickit2_spi_devs,
 		.init			= pickit2_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -394,7 +389,7 @@
 	{
 		.name			= "ch341a_spi",
 		.type			= USB,
-		.devs.dev		= devs_ch341a_spi,
+		.devs.id_dev		= ch341a_spi_devs,
 		.init			= ch341a_spi_init,
 		.map_flash_region	= fallback_map,
 		.unmap_flash_region	= fallback_unmap,
@@ -1838,11 +1833,9 @@
 		case USB:
 		case PCI:
 		case OTHER:
-			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);
+			/* The union id_dev/noid_dev should be non-NULL. */
+			if (p.devs.id_dev == NULL) {
+				msg_gerr("Programmer %s doesn't have a device list!\n", p.name);
 				ret = 1;
 			}
 			break;
Index: flashrom-noid_programmers_support_device_list/ft2232_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/ft2232_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/ft2232_spi.c	(Arbeitskopie)
@@ -63,7 +63,7 @@
 #define GOOGLE_SERVO_V2_PID0	0x5002
 #define GOOGLE_SERVO_V2_PID1	0x5003
 
-const struct dev_entry devs_ft2232spi[] = {
+const struct id_dev_entry ft2232_spi_devs[] = {
 	{FTDI_VID, FTDI_FT2232H_PID, OK, "FTDI", "FT2232H"},
 	{FTDI_VID, FTDI_FT4232H_PID, OK, "FTDI", "FT4232H"},
 	{FTDI_VID, FTDI_FT232H_PID, OK, "FTDI", "FT232H"},
@@ -106,9 +106,9 @@
 static const char *get_ft2232_devicename(int ft2232_vid, int ft2232_type)
 {
 	int i;
-	for (i = 0; devs_ft2232spi[i].vendor_name != NULL; i++) {
-		if ((devs_ft2232spi[i].device_id == ft2232_type) && (devs_ft2232spi[i].vendor_id == ft2232_vid))
-				return devs_ft2232spi[i].device_name;
+	for (i = 0; ft2232_spi_devs[i].vendor_name != NULL; i++) {
+		if ((ft2232_spi_devs[i].device_id == ft2232_type) && (ft2232_spi_devs[i].vendor_id == ft2232_vid))
+				return ft2232_spi_devs[i].device_name;
 	}
 	return "unknown device";
 }
@@ -116,9 +116,9 @@
 static const char *get_ft2232_vendorname(int ft2232_vid, int ft2232_type)
 {
 	int i;
-	for (i = 0; devs_ft2232spi[i].vendor_name != NULL; i++) {
-		if ((devs_ft2232spi[i].device_id == ft2232_type) && (devs_ft2232spi[i].vendor_id == ft2232_vid))
-				return devs_ft2232spi[i].vendor_name;
+	for (i = 0; ft2232_spi_devs[i].vendor_name != NULL; i++) {
+		if ((ft2232_spi_devs[i].device_id == ft2232_type) && (ft2232_spi_devs[i].vendor_id == ft2232_vid))
+				return ft2232_spi_devs[i].vendor_name;
 	}
 	return "unknown vendor";
 }
Index: flashrom-noid_programmers_support_device_list/gfxnvidia.c
===================================================================
--- flashrom-noid_programmers_support_device_list/gfxnvidia.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/gfxnvidia.c	(Arbeitskopie)
@@ -34,7 +34,7 @@
 
 uint8_t *nvidia_bar;
 
-const struct dev_entry gfx_nvidia[] = {
+const struct id_dev_entry gfxnvidia_devs[] = {
 	{0x10de, 0x0010, NT, "NVIDIA", "Mutara V08 [NV2]" },
 	{0x10de, 0x0018, NT, "NVIDIA", "RIVA 128" },
 	{0x10de, 0x0020, NT, "NVIDIA", "RIVA TNT" },
@@ -85,7 +85,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(gfx_nvidia, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(gfxnvidia_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/internal.c
===================================================================
--- flashrom-noid_programmers_support_device_list/internal.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/internal.c	(Arbeitskopie)
@@ -97,6 +97,13 @@
 #endif
 
 #if CONFIG_INTERNAL == 1
+/* The presence of this struct instance is an implementation quirk. We store supported chipsets and mainboards
+ * separately.
+ */
+const struct noid_dev_entry internal_devs[] = {
+	{0},
+};
+
 int force_boardenable = 0;
 int force_boardmismatch = 0;
 
Index: flashrom-noid_programmers_support_device_list/it8212.c
===================================================================
--- flashrom-noid_programmers_support_device_list/it8212.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/it8212.c	(Arbeitskopie)
@@ -27,7 +27,7 @@
 
 #define PCI_VENDOR_ID_ITE 0x1283
 
-const struct dev_entry devs_it8212[] = {
+const struct id_dev_entry it8212_devs[] = {
 	{PCI_VENDOR_ID_ITE, 0x8212, NT, "ITE", "8212F PATA RAID"},
 
 	{},
@@ -54,7 +54,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	struct pci_dev *dev = pcidev_init(devs_it8212, PCI_ROM_ADDRESS);
+	struct pci_dev *dev = pcidev_init(it8212_devs, PCI_ROM_ADDRESS);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/linux_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/linux_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/linux_spi.c	(Arbeitskopie)
@@ -40,6 +40,10 @@
  * Raspberry Pi
  * HummingBoard
  */
+const struct noid_dev_entry linux_spi_devs[] = {
+	{"", OK, "Device files /dev/spidev*.*"},
+	{0},
+};
 
 static int fd = -1;
 
Index: flashrom-noid_programmers_support_device_list/mstarddc_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/mstarddc_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/mstarddc_spi.c	(Arbeitskopie)
@@ -35,6 +35,11 @@
 #include "programmer.h"
 #include "spi.h"
 
+const struct noid_dev_entry mstarddc_spi_devs[] = {
+	{"", OK, "MSTAR DDC devices addressable via /dev/i2c-* on Linux.\n"},
+	{0},
+};
+
 static const struct spi_master spi_master_mstarddc;
 
 static int mstarddc_fd;
Index: flashrom-noid_programmers_support_device_list/nic3com.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nic3com.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nic3com.c	(Arbeitskopie)
@@ -35,18 +35,25 @@
 
 static uint32_t io_base_addr = 0;
 static uint32_t internal_conf;
-static uint16_t id;
 
-const struct dev_entry nics_3com[] = {
+struct nic3com_devdata {
+	enum {FAMILY_3C90xB, FAMILY_OTHER} family;
+};
+
+struct nic3com_devdata quirk_3c90xb = {
+	.family = FAMILY_3C90xB,
+};
+
+const struct id_dev_entry nic3com_devs[] = {
 	/* 3C90xB */
-	{0x10b7, 0x9055, OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX"},
-	{0x10b7, 0x9001, NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-T4" },
-	{0x10b7, 0x9004, OK, "3COM", "3C90xB: PCI 10BASE-T (TPO)" },
-	{0x10b7, 0x9005, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI (COMBO)" },
-	{0x10b7, 0x9006, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)" },
-	{0x10b7, 0x900a, NT, "3COM", "3C90xB: PCI 10BASE-FL" },
-	{0x10b7, 0x905a, NT, "3COM", "3C90xB: PCI 10BASE-FX" },
-	{0x10b7, 0x9058, OK, "3COM", "3C905B: Cyclone 10/100/BNC" },
+	{0x10b7, 0x9055, OK, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-TX", &quirk_3c90xb},
+	{0x10b7, 0x9001, NT, "3COM", "3C90xB: PCI 10/100 Mbps; shared 10BASE-T/100BASE-T4", &quirk_3c90xb},
+	{0x10b7, 0x9004, OK, "3COM", "3C90xB: PCI 10BASE-T (TPO)", &quirk_3c90xb},
+	{0x10b7, 0x9005, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2/AUI (COMBO)", &quirk_3c90xb},
+	{0x10b7, 0x9006, NT, "3COM", "3C90xB: PCI 10BASE-T/10BASE2 (TPC)", &quirk_3c90xb},
+	{0x10b7, 0x900a, NT, "3COM", "3C90xB: PCI 10BASE-FL", &quirk_3c90xb},
+	{0x10b7, 0x905a, NT, "3COM", "3C90xB: PCI 10BASE-FX", &quirk_3c90xb},
+	{0x10b7, 0x9058, OK, "3COM", "3C905B: Cyclone 10/100/BNC", &quirk_3c90xb},
 
 	/* 3C905C */
 	{0x10b7, 0x9200, OK, "3COM", "3C905C: EtherLink 10/100 PCI (TX)" },
@@ -72,11 +79,26 @@
 		.chip_writen		= fallback_chip_writen,
 };
 
+static const void *lookup_devdata(uint16_t vendor_id, uint16_t device_id)
+{
+	int i;
+
+	/* Check against list of supported devices. */
+	for (i = 0; nic3com_devs[i].device_name != NULL; i++)
+		if ((vendor_id == nic3com_devs[i].vendor_id) &&
+		    (device_id == nic3com_devs[i].device_id))
+			return nic3com_devs[i].devdata;
+	return NULL;
+}
+
 static int nic3com_shutdown(void *data)
 {
+	struct pci_dev *dev = data;
+	const struct nic3com_devdata *devdata;
+
 	/* 3COM 3C90xB cards need a special fixup. */
-	if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
-	    || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
+	devdata = lookup_devdata(dev->vendor_id, dev->device_id);
+	if (devdata && (devdata->family == FAMILY_3C90xB)) {
 		/* Select register window 3 and restore the receiver status. */
 		OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
 		OUTL(internal_conf, io_base_addr + INTERNAL_CONFIG);
@@ -88,11 +110,12 @@
 int nic3com_init(void)
 {
 	struct pci_dev *dev = NULL;
+	const struct nic3com_devdata *devdata;
 
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(nics_3com, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(nic3com_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
@@ -100,11 +123,9 @@
 	if (!io_base_addr)
 		return 1;
 
-	id = dev->device_id;
-
 	/* 3COM 3C90xB cards need a special fixup. */
-	if (id == 0x9055 || id == 0x9001 || id == 0x9004 || id == 0x9005
-	    || id == 0x9006 || id == 0x900a || id == 0x905a || id == 0x9058) {
+	devdata = lookup_devdata(dev->vendor_id, dev->device_id);
+	if (devdata && (devdata->family == FAMILY_3C90xB)) {
 		/* Select register window 3 and save the receiver status. */
 		OUTW(SELECT_REG_WINDOW + 3, io_base_addr + INT_STATUS);
 		internal_conf = INL(io_base_addr + INTERNAL_CONFIG);
@@ -120,7 +141,7 @@
 	 */
 	OUTW(SELECT_REG_WINDOW + 0, io_base_addr + INT_STATUS);
 
-	if (register_shutdown(nic3com_shutdown, NULL))
+	if (register_shutdown(nic3com_shutdown, (void *)dev))
 		return 1;
 
 	max_rom_decode.parallel = 128 * 1024;
Index: flashrom-noid_programmers_support_device_list/nicintel.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nicintel.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nicintel.c	(Arbeitskopie)
@@ -27,7 +27,7 @@
 uint8_t *nicintel_bar;
 uint8_t *nicintel_control_bar;
 
-const struct dev_entry nics_intel[] = {
+const struct id_dev_entry nicintel_devs[] = {
 	{PCI_VENDOR_ID_INTEL, 0x1209, NT, "Intel", "8255xER/82551IT Fast Ethernet Controller"},
 	{PCI_VENDOR_ID_INTEL, 0x1229, OK, "Intel", "82557/8/9/0/1 Ethernet Pro 100"},
 
@@ -71,7 +71,7 @@
 		return 1;
 
 	/* FIXME: BAR2 is not available if the device uses the CardBus function. */
-	dev = pcidev_init(nics_intel, PCI_BASE_ADDRESS_2);
+	dev = pcidev_init(nicintel_devs, PCI_BASE_ADDRESS_2);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/nicintel_eeprom.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nicintel_eeprom.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nicintel_eeprom.c	(Arbeitskopie)
@@ -64,7 +64,7 @@
 
 #define UNPROG_DEVICE 0x1509
 
-const struct dev_entry nics_intel_ee[] = {
+const struct id_dev_entry nicintel_devs_ee[] = {
 	{PCI_VENDOR_ID_INTEL, 0x150e, OK, "Intel", "82580 Quad Gigabit Ethernet Controller (Copper)"},
 	{PCI_VENDOR_ID_INTEL, 0x150f, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Fiber)"},
 	{PCI_VENDOR_ID_INTEL, 0x1510, NT , "Intel", "82580 Quad Gigabit Ethernet Controller (Backplane)"},
@@ -298,7 +298,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	struct pci_dev *dev = pcidev_init(nics_intel_ee, PCI_BASE_ADDRESS_0);
+	struct pci_dev *dev = pcidev_init(nicintel_devs_ee, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/nicintel_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nicintel_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nicintel_spi.c	(Arbeitskopie)
@@ -76,7 +76,7 @@
 
 uint8_t *nicintel_spibar;
 
-const struct dev_entry nics_intel_spi[] = {
+const struct id_dev_entry nicintel_devs_spi[] = {
 	{PCI_VENDOR_ID_INTEL, 0x105e, OK, "Intel", "82571EB Gigabit Ethernet Controller"},
 	{PCI_VENDOR_ID_INTEL, 0x1076, OK, "Intel", "82541GI Gigabit Ethernet Controller"},
 	{PCI_VENDOR_ID_INTEL, 0x107c, OK, "Intel", "82541PI Gigabit Ethernet Controller"},
@@ -190,7 +190,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(nics_intel_spi, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(nicintel_devs_spi, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/nicnatsemi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nicnatsemi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nicnatsemi.c	(Arbeitskopie)
@@ -31,7 +31,7 @@
 #define BOOT_ROM_DATA		0x54
 
 static uint32_t io_base_addr = 0;
-const struct dev_entry nics_natsemi[] = {
+const struct id_dev_entry nicnatsemi_devs[] = {
 	{0x100b, 0x0020, NT, "National Semiconductor", "DP83815/DP83816"},
 	{0x100b, 0x0022, NT, "National Semiconductor", "DP83820"},
 
@@ -60,7 +60,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(nics_natsemi, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(nicnatsemi_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/nicrealtek.c
===================================================================
--- flashrom-noid_programmers_support_device_list/nicrealtek.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/nicrealtek.c	(Arbeitskopie)
@@ -31,7 +31,7 @@
 static uint32_t io_base_addr = 0;
 static int bios_rom_addr, bios_rom_data;
 
-const struct dev_entry nics_realtek[] = {
+const struct id_dev_entry nicrealtek_devs[] = {
 	{0x10ec, 0x8139, OK, "Realtek", "RTL8139/8139C/8139C+"},
 	{0x10ec, 0x8169, NT, "Realtek", "RTL8169"},
 	{0x1113, 0x1211, OK, "SMC", "1211TX"}, /* RTL8139 clone */
@@ -65,7 +65,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(nics_realtek, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(nicrealtek_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/ogp_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/ogp_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/ogp_spi.c	(Arbeitskopie)
@@ -47,7 +47,7 @@
 static uint32_t ogp_reg__ce;
 static uint32_t ogp_reg_sck;
 
-const struct dev_entry ogp_spi[] = {
+const struct id_dev_entry ogp_spi[] = {
 	{PCI_VENDOR_ID_OGP, 0x0000, OK, "Open Graphics Project", "Development Board OGD1"},
 
 	{0},
Index: flashrom-noid_programmers_support_device_list/pcidev.c
===================================================================
--- flashrom-noid_programmers_support_device_list/pcidev.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/pcidev.c	(Arbeitskopie)
@@ -183,7 +183,7 @@
  * also matches the specified bus:device.function.
  * For convenience, this function also registers its own undo handlers.
  */
-struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar)
+struct pci_dev *pcidev_init(const struct id_dev_entry *devs, int bar)
 {
 	struct pci_dev *dev;
 	struct pci_dev *found_dev = NULL;
Index: flashrom-noid_programmers_support_device_list/pickit2_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/pickit2_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/pickit2_spi.c	(Arbeitskopie)
@@ -55,7 +55,7 @@
 #include "programmer.h"
 #include "spi.h"
 
-const struct dev_entry devs_pickit2_spi[] = {
+const struct id_dev_entry pickit2_spi_devs[] = {
 	{0x04D8, 0x0033, OK, "Microchip", "PICkit 2"},
 
 	{}
@@ -451,8 +451,8 @@
 	usb_init();
 	(void)usb_find_busses();
 	(void)usb_find_devices();
-	const uint16_t vid = devs_pickit2_spi[0].vendor_id;
-	const uint16_t pid = devs_pickit2_spi[0].device_id;
+	const uint16_t vid = pickit2_spi_devs[0].vendor_id;
+	const uint16_t pid = pickit2_spi_devs[0].device_id;
  	struct usb_device *dev = get_device_by_vid_pid(vid, pid, usedevice);
 	if (dev == NULL) {
 		msg_perr("Could not find a PICkit2 on USB!\n");
Index: flashrom-noid_programmers_support_device_list/pony_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/pony_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/pony_spi.c	(Arbeitskopie)
@@ -2,6 +2,7 @@
  * This file is part of the flashrom project.
  *
  * Copyright (C) 2012 Virgil-Adrian Teaca
+ * Copyright (C) 2016 Carl-Daniel Hailfinger
  *
  * 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
@@ -47,22 +48,53 @@
 #include "flash.h"
 #include "programmer.h"
 
-enum pony_type {
-	TYPE_SI_PROG,
-	TYPE_SERBANG,
-	TYPE_AJAWE
-};
-
+struct pony_pindirection {
 /* Pins for master->slave direction */
-static int pony_negate_cs = 1;
-static int pony_negate_sck = 0;
-static int pony_negate_mosi = 0;
+	int negate_cs;
+	int negate_sck;
+	int negate_mosi;
 /* Pins for slave->master direction */
-static int pony_negate_miso = 0;
+	int negate_miso;
+	int (*preinit)(const void *);
+};
 
+static int si_prog_preinit(const void *data);
+
+static const struct pony_pindirection si_prog = {
+	.negate_cs = 1,
+	.negate_sck = 0,
+	.negate_mosi = 0,
+	.negate_miso = 0,
+	.preinit = si_prog_preinit,
+};
+
+static const struct pony_pindirection serbang = {
+	.negate_cs = 0,
+	.negate_sck = 0,
+	.negate_mosi = 0,
+	.negate_miso = 1,
+	.preinit = si_prog_preinit,
+};
+
+static const struct pony_pindirection ajawe = {
+	.negate_cs = 1,
+	.negate_sck = 1,
+	.negate_mosi = 1,
+	.negate_miso = 1,
+};
+
+static const struct pony_pindirection *pindirection = NULL;
+
+const struct noid_dev_entry pony_spi_devs[] = {
+	{"si_prog",	OK,	"SI-Prog",	&si_prog},
+	{"serbang",	OK,	"serbang",	&serbang},
+	{"ajawe",	OK,	"AJAWe",	&ajawe},
+	{0},
+};
+
 static void pony_bitbang_set_cs(int val)
 {
-	if (pony_negate_cs)
+	if (pindirection->negate_cs)
 		val ^=  1;
 
 	sp_set_pin(PIN_TXD, val);
@@ -70,7 +102,7 @@
 
 static void pony_bitbang_set_sck(int val)
 {
-	if (pony_negate_sck)
+	if (pindirection->negate_sck)
 		val ^=  1;
 
 	sp_set_pin(PIN_RTS, val);
@@ -78,7 +110,7 @@
 
 static void pony_bitbang_set_mosi(int val)
 {
-	if (pony_negate_mosi)
+	if (pindirection->negate_mosi)
 		val ^=  1;
 
 	sp_set_pin(PIN_DTR, val);
@@ -88,7 +120,7 @@
 {
 	int tmp = sp_get_pin(PIN_CTS);
 
-	if (pony_negate_miso)
+	if (pindirection->negate_miso)
 		tmp ^= 1;
 
 	return tmp;
@@ -103,14 +135,32 @@
 	.half_period = 0,
 };
 
+static int si_prog_preinit(const void *data)
+{
+	int data_out;
+	int i;
+
+	msg_pdbg("spi_prog_preinit\n");
+
+	/* We toggle RTS/SCK a few times and see if DSR changes too. */
+	for (i = 1; i <= 10; i++) {
+		data_out = i & 1;
+		sp_set_pin(PIN_RTS, data_out);
+		programmer_delay(1000);
+
+		/* If DSR does not change, we are not connected to what we think */
+		if (data_out != sp_get_pin(PIN_DSR))
+			return 1;
+	}
+
+	return 0;
+}
+
 int pony_spi_init(void)
 {
-	int i, data_out;
+	const struct noid_dev_entry *prog = pony_spi_devs;
 	char *arg = NULL;
-	enum pony_type type = TYPE_SI_PROG;
-	char *name;
 	int have_device = 0;
-	int have_prog = 0;
 
 	/* The parameter is in format "dev=/dev/device,type=serbang" */
 	arg = extract_programmer_param("dev");
@@ -130,54 +180,28 @@
 		return 1;
 	}
 
+	/*
+	 * Select the configuration for the specified programmer.
+	 */
 	arg = extract_programmer_param("type");
-	if (arg && !strcasecmp(arg, "serbang")) {
-		type = TYPE_SERBANG;
-	} else if (arg && !strcasecmp(arg, "si_prog")) {
-		type = TYPE_SI_PROG;
-	} else if (arg && !strcasecmp( arg, "ajawe")) {
-		type = TYPE_AJAWE;
-	} else if (arg && !strlen(arg)) {
-		msg_perr("Error: Missing argument for programmer type.\n");
+	if (arg) {
+		for (; prog->type != NULL; prog++) {
+			if (strcasecmp(arg, prog->type) == 0) {
+				break;
+			}
+		}
+		if (prog->type == NULL) {
+			msg_perr("Error: Invalid device type specified.\n");
+			free(arg);
+#warning TODO: Close sp_fd
+			return 1;
+		}
 		free(arg);
-		return 1;
-	} else if (arg){
-		msg_perr("Error: Invalid programmer type specified.\n");
-		free(arg);
-		return 1;
 	}
-	free(arg);
+	msg_pinfo("Using %s pinout.\n", prog->description);
+	pindirection = (struct pony_pindirection *)prog->devdata;
 
 	/*
-	 * Configure the serial port pins, depending on the used programmer.
-	 */
-	switch (type) {
-	case TYPE_AJAWE:
-		pony_negate_cs = 1;
-		pony_negate_sck = 1;
-		pony_negate_mosi = 1;
-		pony_negate_miso = 1;
-		name = "AJAWe";
-		break;
-	case TYPE_SERBANG:
-		pony_negate_cs = 0;
-		pony_negate_sck = 0;
-		pony_negate_mosi = 0;
-		pony_negate_miso = 1;
-		name = "serbang";
-		break;
-	default:
-	case TYPE_SI_PROG:
-		pony_negate_cs = 1;
-		pony_negate_sck = 0;
-		pony_negate_mosi = 0;
-		pony_negate_miso = 0;
-		name = "SI-Prog";
-		break;
-	}
-	msg_pdbg("Using %s programmer pinout.\n", name);
-
-	/*
 	 * Detect if there is a compatible hardware programmer connected.
 	 */
 	pony_bitbang_set_cs(1);
@@ -184,34 +208,13 @@
 	pony_bitbang_set_sck(1);
 	pony_bitbang_set_mosi(1);
 
-	switch (type) {
-	case TYPE_AJAWE:
-		have_prog = 1;
-		break;
-	case TYPE_SI_PROG:
-	case TYPE_SERBANG:
-	default:
-		have_prog = 1;
-		/* We toggle RTS/SCK a few times and see if DSR changes too. */
-		for (i = 1; i <= 10; i++) {
-			data_out = i & 1;
-			sp_set_pin(PIN_RTS, data_out);
-			programmer_delay(1000);
-
-			/* If DSR does not change, we are not connected to what we think */
-			if (data_out != sp_get_pin(PIN_DSR)) {
-				have_prog = 0;
-				break;
-			}
+	if (pindirection->preinit) {
+		if (pindirection->preinit(pindirection)) {
+			msg_perr("No programmer compatible with %s detected.\n", prog->description);
+			return 1;
 		}
-		break;
 	}
 
-	if (!have_prog) {
-		msg_perr("No programmer compatible with %s detected.\n", name);
-		return 1;
-	}
-
 	if (register_spi_bitbang_master(&bitbang_spi_master_pony)) {
 		return 1;
 	}
Index: flashrom-noid_programmers_support_device_list/print.c
===================================================================
--- flashrom-noid_programmers_support_device_list/print.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/print.c	(Arbeitskopie)
@@ -427,9 +427,9 @@
 }
 #endif
 
-void print_supported_devs(const struct programmer_entry prog, const char *const type)
+static void print_supported_id_devs(const struct programmer_entry prog, const char *const type)
 {
-	const struct dev_entry *const devs = prog.devs.dev;
+	const struct id_dev_entry *const devs = prog.devs.id_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;
@@ -466,6 +466,22 @@
 	}
 }
 
+static void print_supported_noid_devs(const struct programmer_entry prog)
+{
+	int i;
+
+	const struct noid_dev_entry *const devs = prog.devs.noid_dev;
+	msg_ginfo("\nSupported models for the %s programmer:\n", prog.name);
+	for (i = 0; devs[i].type != NULL; i++) {
+		if (!strcmp(devs[i].type, ""))
+			msg_pinfo("%s %s\n", devs[i].description, 
+				(devs[i].status == NT) ? " (untested)" : "");
+		else
+			msg_pinfo("%-20s %s %s\n", devs[i].type, devs[i].description, 
+				(devs[i].status == NT) ? " (untested)" : "");
+	}
+}
+
 int print_supported(void)
 {
 	unsigned int i;
@@ -488,18 +504,20 @@
 		const struct programmer_entry prog = programmer_table[i];
 		switch (prog.type) {
 		case USB:
-			print_supported_devs(prog, "USB");
+			print_supported_id_devs(prog, "USB");
 			break;
 #if NEED_PCI == 1
 		case PCI:
-			print_supported_devs(prog, "PCI");
+			print_supported_id_devs(prog, "PCI");
 			break;
 #endif
 		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 CONFIG_INTERNAL == 1
+			/* Already listed above. */
+			if (i == PROGRAMMER_INTERNAL)
+				break;
+#endif
+			print_supported_noid_devs(prog);
 			break;
 		default:
 			msg_gerr("\n%s: %s: Uninitialized programmer type! Please report a bug at "
Index: flashrom-noid_programmers_support_device_list/print_wiki.c
===================================================================
--- flashrom-noid_programmers_support_device_list/print_wiki.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/print_wiki.c	(Arbeitskopie)
@@ -117,6 +117,12 @@
 ! align=\"center\" | IDs\n\
 ! align=\"center\" | Status\n\n";
 
+static const char noid_programmer_th[] = "\
+! align=\"left\" | Programmer\n\
+! align=\"left\" | Description\n\
+! align=\"center\" | ID/Name\n\
+! align=\"center\" | Status\n\n";
+
 /* The output of this module relies on MediaWiki templates to select special formatting styles for table cells
  * reflecting the test status of the respective hardware. This functions returns the correct template name for
  * the supplied enum test_state. */
@@ -350,21 +356,22 @@
 
 /* Following functions are not needed when no PCI/USB programmers are compiled in,
  * but since print_wiki code has no size constraints we include it unconditionally. */
-static int count_supported_devs_wiki(const struct dev_entry *devs)
+static int count_supported_id_devs_wiki(const struct id_dev_entry *devs)
 {
 	unsigned int count = 0;
 	unsigned int i = 0;
+
 	for (i = 0; devs[i].vendor_id != 0; i++)
 		count++;
 	return count;
 }
 
-static void print_supported_devs_wiki_helper(const struct programmer_entry prog)
+static void print_supported_id_devs_wiki_helper(const struct programmer_entry prog)
 {
 	int i = 0;
 	static int c = 0;
-	const struct dev_entry *devs = prog.devs.dev;
-	const unsigned int count = count_supported_devs_wiki(devs);
+	const struct id_dev_entry *devs = prog.devs.id_dev;
+	const unsigned int count = count_supported_id_devs_wiki(devs);
 
 	/* Alternate colors if the vendor changes. */
 	c = !c;
@@ -378,10 +385,41 @@
 	}
 }
 
+static int count_supported_noid_devs_wiki(const struct noid_dev_entry *devs)
+{
+	unsigned int count = 0;
+	unsigned int i = 0;
+
+	for (i = 0; devs[i].type != NULL; i++)
+		count++;
+	return count;
+}
+
+static void print_supported_noid_devs_wiki_helper(const struct programmer_entry prog)
+{
+	int i = 0;
+	static int c = 0;
+	const struct noid_dev_entry *devs = prog.devs.noid_dev;
+	const unsigned int count = count_supported_noid_devs_wiki(devs);
+
+	/* Alternate colors if the programmer driver changes. */
+	c = !c;
+
+#warning Caveat: prog.devs.noid_dev.type may be an empty string, change formatting in that case (see print.c)
+	for (i = 0; devs[i].type != NULL; i++) {
+		printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
+		if (i == 0)
+			printf("| rowspan=\"%u\" | %s |", count, prog.name);
+		printf("| %s || %s || {{%s}}\n", devs[i].description,
+		       devs[i].type, test_state_to_template(devs[i].status));
+	}
+}
+
 static void print_supported_devs_wiki()
 {
 	unsigned int pci_count = 0;
 	unsigned int usb_count = 0;
+	unsigned int other_count = 0;
 	unsigned int i;
 
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
@@ -388,12 +426,19 @@
 		const struct programmer_entry prog = programmer_table[i];
 		switch (prog.type) {
 		case USB:
-			usb_count += count_supported_devs_wiki(prog.devs.dev);
+			usb_count += count_supported_id_devs_wiki(prog.devs.id_dev);
 			break;
 		case PCI:
-			pci_count += count_supported_devs_wiki(prog.devs.dev);
+			pci_count += count_supported_id_devs_wiki(prog.devs.id_dev);
 			break;
 		case OTHER:
+#if CONFIG_INTERNAL == 1
+			/* Already handled in print_supported_chipsets_wiki()/print_supported_boards_wiki(). */
+			if (i == PROGRAMMER_INTERNAL)
+				break;
+#endif
+			other_count += count_supported_noid_devs_wiki(prog.devs.noid_dev);
+			break;
 		default:
 			break;
 		}
@@ -406,7 +451,7 @@
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
 		const struct programmer_entry prog = programmer_table[i];
 		if (prog.type == PCI) {
-			print_supported_devs_wiki_helper(prog);
+			print_supported_id_devs_wiki_helper(prog);
 		}
 	}
 	printf("\n|}\n\n|}\n");
@@ -418,23 +463,24 @@
 	for (i = 0; i < PROGRAMMER_INVALID; i++) {
 		const struct programmer_entry prog = programmer_table[i];
 		if (prog.type == USB) {
-			print_supported_devs_wiki_helper(prog);
+			print_supported_id_devs_wiki_helper(prog);
 		}
 	}
 	printf("\n|}\n\n|}\n");
 
-	printf("\n== Other programmers ==\n\n"
-	       "{%s", th_start);
-	printf("! align=\"left\" | Programmer\n"
-	       "! align=\"left\" | Note\n\n");
+	printf("\n== Other devices ==\n\n"
+	       "Total amount of supported other devices flashrom can use as a programmer: '''%d'''\n\n"
+	       "{%s%s", other_count, th_start, noid_programmer_th);
 
 	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) {
-			c = !c;
-			printf("|- bgcolor=\"#%s\"\n", (c) ? "eeeeee" : "dddddd");
-			printf("| %s || %s", prog.name, prog.devs.note);
+#if CONFIG_INTERNAL == 1
+		/* Already handled in print_supported_chipsets_wiki()/print_supported_boards_wiki(). */
+		if (i == PROGRAMMER_INTERNAL)
+			continue;
+#endif
+		if (prog.type == OTHER) {
+			print_supported_noid_devs_wiki_helper(prog);
 		}
 	}
 	printf("\n|}\n\n|}\n");
Index: flashrom-noid_programmers_support_device_list/programmer.h
===================================================================
--- flashrom-noid_programmers_support_device_list/programmer.h	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/programmer.h	(Arbeitskopie)
@@ -120,12 +120,20 @@
 	OTHER,
 };
 
-struct dev_entry {
+struct noid_dev_entry {
+	const char *type;
+	const enum test_state status;
+	const char *description;
+	const void *devdata;
+};
+
+struct id_dev_entry {
 	uint16_t vendor_id;
 	uint16_t device_id;
 	const enum test_state status;
 	const char *vendor_name;
 	const char *device_name;
+	const void *devdata;
 };
 
 struct programmer_entry {
@@ -132,8 +140,8 @@
 	const char *name;
 	const enum programmer_type type;
 	union {
-		const struct dev_entry *const dev;
-		const char *const note;
+		const struct noid_dev_entry *const noid_dev;
+		const struct id_dev_entry *const id_dev;
 	} devs;
 
 	int (*init) (void);
@@ -192,7 +200,7 @@
 extern struct pci_access *pacc;
 int pci_init_common(void);
 uintptr_t pcidev_readbar(struct pci_dev *dev, int bar);
-struct pci_dev *pcidev_init(const struct dev_entry *devs, int bar);
+struct pci_dev *pcidev_init(const struct id_dev_entry *devs, int bar);
 /* rpci_write_* are reversible writes. The original PCI config space register
  * contents will be restored on shutdown.
  */
@@ -345,6 +353,7 @@
 int register_superio(struct superio s);
 extern enum chipbustype internal_buses_supported;
 int internal_init(void);
+extern const struct noid_dev_entry internal_devs[];
 #endif
 
 /* hwaccess.c */
@@ -385,78 +394,79 @@
 int dummy_init(void);
 void *dummy_map(const char *descr, uintptr_t phys_addr, size_t len);
 void dummy_unmap(void *virt_addr, size_t len);
+extern const struct noid_dev_entry dummy_devs[];
 #endif
 
 /* nic3com.c */
 #if CONFIG_NIC3COM == 1
 int nic3com_init(void);
-extern const struct dev_entry nics_3com[];
+extern const struct id_dev_entry nic3com_devs[];
 #endif
 
 /* gfxnvidia.c */
 #if CONFIG_GFXNVIDIA == 1
 int gfxnvidia_init(void);
-extern const struct dev_entry gfx_nvidia[];
+extern const struct id_dev_entry gfxnvidia_devs[];
 #endif
 
 /* drkaiser.c */
 #if CONFIG_DRKAISER == 1
 int drkaiser_init(void);
-extern const struct dev_entry drkaiser_pcidev[];
+extern const struct id_dev_entry drkaiser_devs[];
 #endif
 
 /* nicrealtek.c */
 #if CONFIG_NICREALTEK == 1
 int nicrealtek_init(void);
-extern const struct dev_entry nics_realtek[];
+extern const struct id_dev_entry nicrealtek_devs[];
 #endif
 
 /* nicnatsemi.c */
 #if CONFIG_NICNATSEMI == 1
 int nicnatsemi_init(void);
-extern const struct dev_entry nics_natsemi[];
+extern const struct id_dev_entry nicnatsemi_devs[];
 #endif
 
 /* nicintel.c */
 #if CONFIG_NICINTEL == 1
 int nicintel_init(void);
-extern const struct dev_entry nics_intel[];
+extern const struct id_dev_entry nicintel_devs[];
 #endif
 
 /* nicintel_spi.c */
 #if CONFIG_NICINTEL_SPI == 1
 int nicintel_spi_init(void);
-extern const struct dev_entry nics_intel_spi[];
+extern const struct id_dev_entry nicintel_devs_spi[];
 #endif
 
 /* nicintel_eeprom.c */
 #if CONFIG_NICINTEL_EEPROM == 1
 int nicintel_ee_init(void);
-extern const struct dev_entry nics_intel_ee[];
+extern const struct id_dev_entry nicintel_devs_ee[];
 #endif
 
 /* ogp_spi.c */
 #if CONFIG_OGP_SPI == 1
 int ogp_spi_init(void);
-extern const struct dev_entry ogp_spi[];
+extern const struct id_dev_entry ogp_spi[];
 #endif
 
 /* satamv.c */
 #if CONFIG_SATAMV == 1
 int satamv_init(void);
-extern const struct dev_entry satas_mv[];
+extern const struct id_dev_entry satamv_devs[];
 #endif
 
 /* satasii.c */
 #if CONFIG_SATASII == 1
 int satasii_init(void);
-extern const struct dev_entry satas_sii[];
+extern const struct id_dev_entry satasii_devs[];
 #endif
 
 /* atahpt.c */
 #if CONFIG_ATAHPT == 1
 int atahpt_init(void);
-extern const struct dev_entry ata_hpt[];
+extern const struct id_dev_entry atahpt_devs[];
 #endif
 
 /* atavia.c */
@@ -463,7 +473,7 @@
 #if CONFIG_ATAVIA == 1
 int atavia_init(void);
 void *atavia_map(const char *descr, uintptr_t phys_addr, size_t len);
-extern const struct dev_entry ata_via[];
+extern const struct id_dev_entry atavia_devs[];
 #endif
 
 /* atapromise.c */
@@ -470,46 +480,49 @@
 #if CONFIG_ATAPROMISE == 1
 int atapromise_init(void);
 void *atapromise_map(const char *descr, uintptr_t phys_addr, size_t len);
-extern const struct dev_entry ata_promise[];
+extern const struct id_dev_entry atapromise_devs[];
 #endif
 
 /* it8212.c */
 #if CONFIG_IT8212 == 1
 int it8212_init(void);
-extern const struct dev_entry devs_it8212[];
+extern const struct id_dev_entry it8212_devs[];
 #endif
 
 /* ft2232_spi.c */
 #if CONFIG_FT2232_SPI == 1
 int ft2232_spi_init(void);
-extern const struct dev_entry devs_ft2232spi[];
+extern const struct id_dev_entry ft2232_spi_devs[];
 #endif
 
 /* usbblaster_spi.c */
 #if CONFIG_USBBLASTER_SPI == 1
 int usbblaster_spi_init(void);
-extern const struct dev_entry devs_usbblasterspi[];
+extern const struct id_dev_entry usbblaster_spi_devs[];
 #endif
 
 /* mstarddc_spi.c */
 #if CONFIG_MSTARDDC_SPI == 1
 int mstarddc_spi_init(void);
+extern const struct noid_dev_entry mstarddc_spi_devs[];
 #endif
 
 /* pickit2_spi.c */
 #if CONFIG_PICKIT2_SPI == 1
 int pickit2_spi_init(void);
-extern const struct dev_entry devs_pickit2_spi[];
+extern const struct id_dev_entry pickit2_spi_devs[];
 #endif
 
 /* rayer_spi.c */
 #if CONFIG_RAYER_SPI == 1
 int rayer_spi_init(void);
+extern const struct noid_dev_entry rayer_spi_devs[];
 #endif
 
 /* pony_spi.c */
 #if CONFIG_PONY_SPI == 1
 int pony_spi_init(void);
+extern const struct noid_dev_entry pony_spi_devs[];
 #endif
 
 /* bitbang_spi.c */
@@ -518,17 +531,19 @@
 /* buspirate_spi.c */
 #if CONFIG_BUSPIRATE_SPI == 1
 int buspirate_spi_init(void);
+extern const struct noid_dev_entry buspirate_spi_devs[];
 #endif
 
 /* linux_spi.c */
 #if CONFIG_LINUX_SPI == 1
 int linux_spi_init(void);
+extern const struct noid_dev_entry linux_spi_devs[];
 #endif
 
 /* dediprog.c */
 #if CONFIG_DEDIPROG == 1
 int dediprog_init(void);
-extern const struct dev_entry devs_dediprog[];
+extern const struct id_dev_entry dediprog_devs[];
 #endif
 
 /* ch341a_spi.c */
@@ -535,7 +550,7 @@
 #if CONFIG_CH341A_SPI == 1
 int ch341a_spi_init(void);
 void ch341a_spi_delay(unsigned int usecs);
-extern const struct dev_entry devs_ch341a_spi[];
+extern const struct id_dev_entry ch341a_spi_devs[];
 #endif
 
 /* flashrom.c */
@@ -732,6 +747,7 @@
 int serprog_init(void);
 void serprog_delay(unsigned int usecs);
 void *serprog_map(const char *descr, uintptr_t phys_addr, size_t len);
+extern const struct noid_dev_entry serprog_devs[];
 #endif
 
 /* serial.c */
Index: flashrom-noid_programmers_support_device_list/rayer_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/rayer_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/rayer_spi.c	(Arbeitskopie)
@@ -40,13 +40,6 @@
  * Default settings are for the RayeR hardware.
  */
 
-struct rayer_programmer {
-	const char *type;
-	const enum test_state status;
-	const char *description;
-	const void *dev_data;
-};
-
 struct rayer_pinout {
 	uint8_t cs_bit;
 	uint8_t sck_bit;
@@ -113,7 +106,7 @@
 	.miso_bit = 7,
 };
 
-static const struct rayer_programmer rayer_spi_types[] = {
+const struct noid_dev_entry rayer_spi_devs[] = {
 	{"rayer",		NT,	"RayeR SPIPGM",					&rayer_spipgm},
 	{"xilinx",		NT,	"Xilinx Parallel Cable III (DLC 5)",		&xilinx_dlc5},
 	{"byteblastermv",	OK,	"Altera ByteBlasterMV",				&altera_byteblastermv},
@@ -171,7 +164,7 @@
 
 int rayer_spi_init(void)
 {
-	const struct rayer_programmer *prog = rayer_spi_types;
+	const struct noid_dev_entry *prog = rayer_spi_devs;
 	char *arg = NULL;
 
 	/* Non-default port requested? */
@@ -223,7 +216,7 @@
 		free(arg);
 	}
 	msg_pinfo("Using %s pinout.\n", prog->description);
-	pinout = (struct rayer_pinout *)prog->dev_data;
+	pinout = (struct rayer_pinout *)prog->devdata;
 
 	if (rget_io_perms())
 		return 1;
Index: flashrom-noid_programmers_support_device_list/satamv.c
===================================================================
--- flashrom-noid_programmers_support_device_list/satamv.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/satamv.c	(Arbeitskopie)
@@ -29,7 +29,7 @@
 uint8_t *mv_bar;
 uint16_t mv_iobar;
 
-const struct dev_entry satas_mv[] = {
+const struct id_dev_entry satamv_devs[] = {
 	/* 88SX6041 and 88SX6042 are the same according to the datasheet. */
 	{0x11ab, 0x7042, OK, "Marvell", "88SX7042 PCI-e 4-port SATA-II"},
 
@@ -83,7 +83,7 @@
 		return 1;
 
 	/* BAR0 has all internal registers memory mapped. */
-	dev = pcidev_init(satas_mv, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(satamv_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/satasii.c
===================================================================
--- flashrom-noid_programmers_support_device_list/satasii.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/satasii.c	(Arbeitskopie)
@@ -30,7 +30,7 @@
 static uint8_t *sii_bar;
 static uint16_t id;
 
-const struct dev_entry satas_sii[] = {
+const struct id_dev_entry satasii_devs[] = {
 	{0x1095, 0x0680, OK, "Silicon Image", "PCI0680 Ultra ATA-133 Host Ctrl"},
 	{0x1095, 0x3112, OK, "Silicon Image", "SiI 3112 [SATALink/SATARaid] SATA Ctrl"},
 	{0x1095, 0x3114, OK, "Silicon Image", "SiI 3114 [SATALink/SATARaid] SATA Ctrl"},
@@ -77,7 +77,7 @@
 	if (rget_io_perms())
 		return 1;
 
-	dev = pcidev_init(satas_sii, PCI_BASE_ADDRESS_0);
+	dev = pcidev_init(satasii_devs, PCI_BASE_ADDRESS_0);
 	if (!dev)
 		return 1;
 
Index: flashrom-noid_programmers_support_device_list/serprog.c
===================================================================
--- flashrom-noid_programmers_support_device_list/serprog.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/serprog.c	(Arbeitskopie)
@@ -46,6 +46,11 @@
 
 #define MSGHEADER "serprog: "
 
+const struct noid_dev_entry serprog_devs[] = {
+	{"", OK, "All programmer devices speaking the serprog protocol"},
+	{0},
+};
+
 /*
  * FIXME: This prototype was added to help reduce diffs for the shutdown
  * registration patch, which shifted many lines of code to place
Index: flashrom-noid_programmers_support_device_list/usbblaster_spi.c
===================================================================
--- flashrom-noid_programmers_support_device_list/usbblaster_spi.c	(Revision 1946)
+++ flashrom-noid_programmers_support_device_list/usbblaster_spi.c	(Arbeitskopie)
@@ -49,7 +49,7 @@
 #define ALTERA_VID		0x09fb
 #define ALTERA_USBBLASTER_PID	0x6001
 
-const struct dev_entry devs_usbblasterspi[] = {
+const struct id_dev_entry usbblaster_spi_devs[] = {
 	{ALTERA_VID, ALTERA_USBBLASTER_PID, OK, "Altera", "USB-Blaster"},
 
 	{}





More information about the flashrom mailing list