Patchwork Cleanup flashrom.c, move functions, part 1

login
register
about
Submitter Uwe Hermann
Date 2011-07-29 12:10:24
Message ID <20110729121024.GQ4802@greenwood>
Download mbox | patch
Permalink /patch/3315/
State Superseded
Headers show

Comments

Uwe Hermann - 2011-07-29 12:10:24
See patch.


Uwe.
Carl-Daniel Hailfinger - 2011-07-29 21:27:16
Am 29.07.2011 14:10 schrieb Uwe Hermann:
> Cleanup flashrom.c, move functions where they belong.
>
> The file flashrom.c is a random collection of unrelated stuff and should
> be refactored a bit. This is part 1 of that effort.
>   

Does a feature or bugfix depend on this?
I don't see immediate benefits of this patch, and it will break quite a
few unmerged patches. If our patchwork queue was ~10 patches instead of
150 patches, the effort to update them would be manageable, but right
now this is mostly making life harder for people who want to merge
pending patches.


>  - Move main() to cli_classic.c where it belongs, it's the main function of
>    the CLI program. Other frontends/GUIs will have their own main() function.
>
>  - Move programmer_table[] from flashrom.c to programmer.c where it belongs.
>
>  - Move the following functions to print.c as they're purely printing
>    related: nonfatal_help_message(), emergency_help_message(),
>    list_programmers_linebreak(), print_sysinfo(), print_version(), and
>    print_banner().
>
>  - Drop list_programmers(), as it's never used.
>   

list_programmers() was introduced to have a useful programmer list for
libflashrom. Unless libflashrom is dead and buried, I'd like to keep it in.


> Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>
>   


Regards,
Carl-Daniel
Uwe Hermann - 2011-07-30 17:28:15
On Fri, Jul 29, 2011 at 11:27:16PM +0200, Carl-Daniel Hailfinger wrote:
> Am 29.07.2011 14:10 schrieb Uwe Hermann:
> > Cleanup flashrom.c, move functions where they belong.
> >
> > The file flashrom.c is a random collection of unrelated stuff and should
> > be refactored a bit. This is part 1 of that effort.
> >   
> 
> Does a feature or bugfix depend on this?

Only the moving of main() to cli_classic.c. As flashrom.c is part of
libflashrom at the moment, it must not contain a main(). The rest is
optional.

I'll post the main() moving as extra patch.


> I don't see immediate benefits of this patch, and it will break quite a
> few unmerged patches. If our patchwork queue was ~10 patches instead of
> 150 patches, the effort to update them would be manageable, but right
> now this is mostly making life harder for people who want to merge
> pending patches.

Sure, we can postpone the patch until most of the conflicting pending
patches are merged. Shortly after a release is the best time window for
such changes though, I think, so we shouldn't wait too long. When the
next release is nearer nobody will want such "move stuff" changes for sure.

 
> >  - Drop list_programmers(), as it's never used.
> 
> list_programmers() was introduced to have a useful programmer list for
> libflashrom. Unless libflashrom is dead and buried, I'd like to keep it in.

Hm, ok, might be useful in some cases, though I think most frontends
will iterate over programmer_table() themselves and print/do/generate
whatever is needed.

I'll post an updated patch when a few more of the conflicting patches
are merged.
 

Uwe.

Patch

Cleanup flashrom.c, move functions where they belong.

The file flashrom.c is a random collection of unrelated stuff and should
be refactored a bit. This is part 1 of that effort.

 - Move main() to cli_classic.c where it belongs, it's the main function of
   the CLI program. Other frontends/GUIs will have their own main() function.

 - Move programmer_table[] from flashrom.c to programmer.c where it belongs.

 - Move the following functions to print.c as they're purely printing
   related: nonfatal_help_message(), emergency_help_message(),
   list_programmers_linebreak(), print_sysinfo(), print_version(), and
   print_banner().

 - Drop list_programmers(), as it's never used.

Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de>

Index: flash.h
===================================================================
--- flash.h	(Revision 1398)
+++ flash.h	(Arbeitskopie)
@@ -187,6 +187,11 @@ 
 extern const struct flashchip flashchips[];
 
 /* print.c */
+void nonfatal_help_message(void);
+void emergency_help_message(void);
+void list_programmers_linebreak(int startcol, int cols, int paren);
+void print_version(void);
+void print_banner(void);
 char *flashbuses_to_text(enum chipbustype bustype);
 void print_supported(void);
 void print_supported_wiki(void);
@@ -213,9 +218,6 @@ 
 int verify_range(struct flashchip *flash, uint8_t *cmpbuf, int start, int len, const char *message);
 int need_erase(uint8_t *have, uint8_t *want, int len, enum write_granularity gran);
 char *strcat_realloc(char *dest, const char *src);
-void print_version(void);
-void print_banner(void);
-void list_programmers_linebreak(int startcol, int cols, int paren);
 int selfcheck(void);
 int doit(struct flashchip *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it);
 int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename);
Index: cli_classic.c
===================================================================
--- cli_classic.c	(Revision 1398)
+++ cli_classic.c	(Arbeitskopie)
@@ -443,3 +443,9 @@ 
 	programmer_shutdown();
 	return ret;
 }
+
+int main(int argc, char *argv[])
+{
+	return cli_classic(argc, argv);
+}
+
Index: flashrom.c
===================================================================
--- flashrom.c	(Revision 1398)
+++ flashrom.c	(Arbeitskopie)
@@ -31,9 +31,6 @@ 
 #include <stdlib.h>
 #include <ctype.h>
 #include <getopt.h>
-#if HAVE_UTSNAME == 1
-#include <sys/utsname.h>
-#endif
 #include "flash.h"
 #include "flashchips.h"
 #include "programmer.h"
@@ -124,336 +121,6 @@ 
 /* Is writing allowed with this programmer? */
 int programmer_may_write;
 
-const struct programmer_entry programmer_table[] = {
-#if CONFIG_INTERNAL == 1
-	{
-		.name			= "internal",
-		.init			= internal_init,
-		.map_flash_region	= physmap,
-		.unmap_flash_region	= physunmap,
-		.chip_readb		= internal_chip_readb,
-		.chip_readw		= internal_chip_readw,
-		.chip_readl		= internal_chip_readl,
-		.chip_readn		= internal_chip_readn,
-		.chip_writeb		= internal_chip_writeb,
-		.chip_writew		= internal_chip_writew,
-		.chip_writel		= internal_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_DUMMY == 1
-	{
-		.name			= "dummy",
-		.init			= dummy_init,
-		.map_flash_region	= dummy_map,
-		.unmap_flash_region	= dummy_unmap,
-		.chip_readb		= dummy_chip_readb,
-		.chip_readw		= dummy_chip_readw,
-		.chip_readl		= dummy_chip_readl,
-		.chip_readn		= dummy_chip_readn,
-		.chip_writeb		= dummy_chip_writeb,
-		.chip_writew		= dummy_chip_writew,
-		.chip_writel		= dummy_chip_writel,
-		.chip_writen		= dummy_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_NIC3COM == 1
-	{
-		.name			= "nic3com",
-		.init			= nic3com_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nic3com_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nic3com_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_NICREALTEK == 1
-	{
-		/* This programmer works for Realtek RTL8139 and SMC 1211. */
-		.name			= "nicrealtek",
-		//.name			= "nicsmc1211",
-		.init			= nicrealtek_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicrealtek_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicrealtek_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_NICNATSEMI == 1
-	{
-		.name			= "nicnatsemi",
-		.init			= nicnatsemi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicnatsemi_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicnatsemi_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_GFXNVIDIA == 1
-	{
-		.name			= "gfxnvidia",
-		.init			= gfxnvidia_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= gfxnvidia_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= gfxnvidia_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_DRKAISER == 1
-	{
-		.name			= "drkaiser",
-		.init			= drkaiser_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= drkaiser_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= drkaiser_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_SATASII == 1
-	{
-		.name			= "satasii",
-		.init			= satasii_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= satasii_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= satasii_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_ATAHPT == 1
-	{
-		.name			= "atahpt",
-		.init			= atahpt_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= atahpt_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= atahpt_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_FT2232_SPI == 1
-	{
-		.name			= "ft2232_spi",
-		.init			= ft2232_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_SERPROG == 1
-	{
-		.name			= "serprog",
-		.init			= serprog_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= serprog_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= serprog_chip_readn,
-		.chip_writeb		= serprog_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= serprog_delay,
-	},
-#endif
-
-#if CONFIG_BUSPIRATE_SPI == 1
-	{
-		.name			= "buspirate_spi",
-		.init			= buspirate_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_DEDIPROG == 1
-	{
-		.name			= "dediprog",
-		.init			= dediprog_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_RAYER_SPI == 1
-	{
-		.name			= "rayer_spi",
-		.init			= rayer_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_NICINTEL == 1
-	{
-		.name			= "nicintel",
-		.init			= nicintel_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= nicintel_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= nicintel_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_NICINTEL_SPI == 1
-	{
-		.name			= "nicintel_spi",
-		.init			= nicintel_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_OGP_SPI == 1
-	{
-		.name			= "ogp_spi",
-		.init			= ogp_spi_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= noop_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= noop_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-#if CONFIG_SATAMV == 1
-	{
-		.name			= "satamv",
-		.init			= satamv_init,
-		.map_flash_region	= fallback_map,
-		.unmap_flash_region	= fallback_unmap,
-		.chip_readb		= satamv_chip_readb,
-		.chip_readw		= fallback_chip_readw,
-		.chip_readl		= fallback_chip_readl,
-		.chip_readn		= fallback_chip_readn,
-		.chip_writeb		= satamv_chip_writeb,
-		.chip_writew		= fallback_chip_writew,
-		.chip_writel		= fallback_chip_writel,
-		.chip_writen		= fallback_chip_writen,
-		.delay			= internal_delay,
-	},
-#endif
-
-	{}, /* This entry corresponds to PROGRAMMER_INVALID. */
-};
-
 #define SHUTDOWN_MAXFN 32
 static int shutdown_fn_count = 0;
 struct shutdown_func_data {
@@ -1564,137 +1231,6 @@ 
 	return ret;
 }
 
-void nonfatal_help_message(void)
-{
-	msg_gerr("Writing to the flash chip apparently didn't do anything.\n"
-		"This means we have to add special support for your board, "
-		  "programmer or flash chip.\n"
-		"Please report this on IRC at irc.freenode.net (channel "
-		  "#flashrom) or\n"
-		"mail flashrom@flashrom.org!\n"
-		"-------------------------------------------------------------"
-		  "------------------\n"
-		"You may now reboot or simply leave the machine running.\n");
-}
-
-void emergency_help_message(void)
-{
-	msg_gerr("Your flash chip is in an unknown state.\n"
-		"Get help on IRC at irc.freenode.net (channel #flashrom) or\n"
-		"mail flashrom@flashrom.org with FAILED: your board name in "
-		  "the subject line!\n"
-		"-------------------------------------------------------------"
-		  "------------------\n"
-		"DO NOT REBOOT OR POWEROFF!\n");
-}
-
-/* The way to go if you want a delimited list of programmers */
-void list_programmers(const char *delim)
-{
-	enum programmer p;
-	for (p = 0; p < PROGRAMMER_INVALID; p++) {
-		msg_ginfo("%s", programmer_table[p].name);
-		if (p < PROGRAMMER_INVALID - 1)
-			msg_ginfo("%s", delim);
-	}
-	msg_ginfo("\n");	
-}
-
-void list_programmers_linebreak(int startcol, int cols, int paren)
-{
-	const char *pname;
-	int pnamelen, remaining = 0, firstline = 1, i;
-	enum programmer p;
-
-	for (p = 0; p < PROGRAMMER_INVALID; p++) {
-		pname = programmer_table[p].name;
-		pnamelen = strlen(pname);
-		if (remaining - pnamelen - 2 < 0) {
-			if (firstline)
-				firstline = 0;
-			else
-				printf("\n");
-			for (i = 0; i < startcol; i++)
-				printf(" ");
-			remaining = cols - startcol;
-		} else {
-			printf(" ");
-			remaining--;
-		}
-		if (paren && (p == 0)) {
-			printf("(");
-			remaining--;
-		}
-		printf("%s", pname);
-		remaining -= pnamelen;
-		if (p < PROGRAMMER_INVALID - 1) {
-			printf(",");
-			remaining--;
-		} else {
-			if (paren)
-				printf(")");
-			printf("\n");
-		}
-	}
-}
-
-void print_sysinfo(void)
-{
-#if HAVE_UTSNAME == 1
-	struct utsname osinfo;
-	uname(&osinfo);
-
-	msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
-		  osinfo.machine);
-#else
-	msg_ginfo(" on unknown machine");
-#endif
-	msg_ginfo(", built with");
-#if NEED_PCI == 1
-#ifdef PCILIB_VERSION
-	msg_ginfo(" libpci %s,", PCILIB_VERSION);
-#else
-	msg_ginfo(" unknown PCI library,");
-#endif
-#endif
-#ifdef __clang__
-	msg_ginfo(" LLVM Clang");
-#ifdef __clang_version__
-	msg_ginfo(" %s,", __clang_version__);
-#else
-	msg_ginfo(" unknown version (before r102686),");
-#endif
-#elif defined(__GNUC__)
-	msg_ginfo(" GCC");
-#ifdef __VERSION__
-	msg_ginfo(" %s,", __VERSION__);
-#else
-	msg_ginfo(" unknown version,");
-#endif
-#else
-	msg_ginfo(" unknown compiler,");
-#endif
-#if defined (__FLASHROM_LITTLE_ENDIAN__)
-	msg_ginfo(" little endian");
-#else
-	msg_ginfo(" big endian");
-#endif
-	msg_ginfo("\n");
-}
-
-void print_version(void)
-{
-	msg_ginfo("flashrom v%s", flashrom_version);
-	print_sysinfo();
-}
-
-void print_banner(void)
-{
-	msg_ginfo("flashrom is free software, get the source code at "
-		  "http://www.flashrom.org\n");
-	msg_ginfo("\n");
-}
-
 int selfcheck(void)
 {
 	int ret = 0;
@@ -1703,7 +1239,7 @@ 
 	/* Safety check. Instead of aborting after the first error, check
 	 * if more errors exist.
 	 */
-	if (ARRAY_SIZE(programmer_table) - 1 != PROGRAMMER_INVALID) {
+	if (programmer_table_size() - 1 != PROGRAMMER_INVALID) {
 		msg_gerr("Programmer table miscompilation!\n");
 		ret = 1;
 	}
@@ -1790,11 +1326,6 @@ 
 	}
 }
 
-int main(int argc, char *argv[])
-{
-	return cli_classic(argc, argv);
-}
-
 /* FIXME: This function signature needs to be improved once doit() has a better
  * function signature.
  */
Index: programmer.c
===================================================================
--- programmer.c	(Revision 1398)
+++ programmer.c	(Arbeitskopie)
@@ -19,7 +19,343 @@ 
  */
 
 #include "flash.h"
+#include "programmer.h"
 
+const struct programmer_entry programmer_table[] = {
+#if CONFIG_INTERNAL == 1
+	{
+		.name			= "internal",
+		.init			= internal_init,
+		.map_flash_region	= physmap,
+		.unmap_flash_region	= physunmap,
+		.chip_readb		= internal_chip_readb,
+		.chip_readw		= internal_chip_readw,
+		.chip_readl		= internal_chip_readl,
+		.chip_readn		= internal_chip_readn,
+		.chip_writeb		= internal_chip_writeb,
+		.chip_writew		= internal_chip_writew,
+		.chip_writel		= internal_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_DUMMY == 1
+	{
+		.name			= "dummy",
+		.init			= dummy_init,
+		.map_flash_region	= dummy_map,
+		.unmap_flash_region	= dummy_unmap,
+		.chip_readb		= dummy_chip_readb,
+		.chip_readw		= dummy_chip_readw,
+		.chip_readl		= dummy_chip_readl,
+		.chip_readn		= dummy_chip_readn,
+		.chip_writeb		= dummy_chip_writeb,
+		.chip_writew		= dummy_chip_writew,
+		.chip_writel		= dummy_chip_writel,
+		.chip_writen		= dummy_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_NIC3COM == 1
+	{
+		.name			= "nic3com",
+		.init			= nic3com_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= nic3com_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nic3com_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_NICREALTEK == 1
+	{
+		/* This programmer works for Realtek RTL8139 and SMC 1211. */
+		.name			= "nicrealtek",
+		//.name			= "nicsmc1211",
+		.init			= nicrealtek_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= nicrealtek_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicrealtek_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_NICNATSEMI == 1
+	{
+		.name			= "nicnatsemi",
+		.init			= nicnatsemi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= nicnatsemi_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicnatsemi_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_GFXNVIDIA == 1
+	{
+		.name			= "gfxnvidia",
+		.init			= gfxnvidia_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= gfxnvidia_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= gfxnvidia_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_DRKAISER == 1
+	{
+		.name			= "drkaiser",
+		.init			= drkaiser_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= drkaiser_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= drkaiser_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_SATASII == 1
+	{
+		.name			= "satasii",
+		.init			= satasii_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= satasii_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= satasii_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_ATAHPT == 1
+	{
+		.name			= "atahpt",
+		.init			= atahpt_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= atahpt_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= atahpt_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_FT2232_SPI == 1
+	{
+		.name			= "ft2232_spi",
+		.init			= ft2232_spi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_SERPROG == 1
+	{
+		.name			= "serprog",
+		.init			= serprog_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= serprog_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= serprog_chip_readn,
+		.chip_writeb		= serprog_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= serprog_delay,
+	},
+#endif
+
+#if CONFIG_BUSPIRATE_SPI == 1
+	{
+		.name			= "buspirate_spi",
+		.init			= buspirate_spi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_DEDIPROG == 1
+	{
+		.name			= "dediprog",
+		.init			= dediprog_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_RAYER_SPI == 1
+	{
+		.name			= "rayer_spi",
+		.init			= rayer_spi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_NICINTEL == 1
+	{
+		.name			= "nicintel",
+		.init			= nicintel_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= nicintel_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= nicintel_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_NICINTEL_SPI == 1
+	{
+		.name			= "nicintel_spi",
+		.init			= nicintel_spi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_OGP_SPI == 1
+	{
+		.name			= "ogp_spi",
+		.init			= ogp_spi_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= noop_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= noop_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+#if CONFIG_SATAMV == 1
+	{
+		.name			= "satamv",
+		.init			= satamv_init,
+		.map_flash_region	= fallback_map,
+		.unmap_flash_region	= fallback_unmap,
+		.chip_readb		= satamv_chip_readb,
+		.chip_readw		= fallback_chip_readw,
+		.chip_readl		= fallback_chip_readl,
+		.chip_readn		= fallback_chip_readn,
+		.chip_writeb		= satamv_chip_writeb,
+		.chip_writew		= fallback_chip_writew,
+		.chip_writel		= fallback_chip_writel,
+		.chip_writen		= fallback_chip_writen,
+		.delay			= internal_delay,
+	},
+#endif
+
+	{}, /* This entry corresponds to PROGRAMMER_INVALID. */
+};
+
+int programmer_table_size(void)
+{
+	return ARRAY_SIZE(programmer_table);
+}
+
 /* No-op shutdown() for programmers which don't need special handling */
 int noop_shutdown(void)
 {
Index: programmer.h
===================================================================
--- programmer.h	(Revision 1398)
+++ programmer.h	(Arbeitskopie)
@@ -107,6 +107,8 @@ 
 
 extern const struct programmer_entry programmer_table[];
 
+int programmer_table_size(void);
+
 int programmer_init(char *param);
 int programmer_shutdown(void);
 
Index: print.c
===================================================================
--- print.c	(Revision 1398)
+++ print.c	(Arbeitskopie)
@@ -22,10 +22,147 @@ 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
+#if HAVE_UTSNAME == 1
+#include <sys/utsname.h>
+#endif
 #include "flash.h"
 #include "flashchips.h"
 #include "programmer.h"
 
+void nonfatal_help_message(void)
+{
+	msg_gerr("Writing to the flash chip apparently didn't do anything.\n"
+		"This means we have to add special support for your board, "
+		  "programmer or flash chip.\n"
+		"Please report this on IRC at irc.freenode.net (channel "
+		  "#flashrom) or\n"
+		"mail flashrom@flashrom.org!\n"
+		"-------------------------------------------------------------"
+		  "------------------\n"
+		"You may now reboot or simply leave the machine running.\n");
+}
+
+void emergency_help_message(void)
+{
+	msg_gerr("Your flash chip is in an unknown state.\n"
+		"Get help on IRC at irc.freenode.net (channel #flashrom) or\n"
+		"mail flashrom@flashrom.org with FAILED: your board name in "
+		  "the subject line!\n"
+		"-------------------------------------------------------------"
+		  "------------------\n"
+		"DO NOT REBOOT OR POWEROFF!\n");
+}
+
+// TODO: Unused?
+#if 0
+/* The way to go if you want a delimited list of programmers */
+void list_programmers(const char *delim)
+{
+	enum programmer p;
+	for (p = 0; p < PROGRAMMER_INVALID; p++) {
+		msg_ginfo("%s", programmer_table[p].name);
+		if (p < PROGRAMMER_INVALID - 1)
+			msg_ginfo("%s", delim);
+	}
+	msg_ginfo("\n");	
+}
+#endif
+
+void list_programmers_linebreak(int startcol, int cols, int paren)
+{
+	const char *pname;
+	int pnamelen, remaining = 0, firstline = 1, i;
+	enum programmer p;
+
+	for (p = 0; p < PROGRAMMER_INVALID; p++) {
+		pname = programmer_table[p].name;
+		pnamelen = strlen(pname);
+		if (remaining - pnamelen - 2 < 0) {
+			if (firstline)
+				firstline = 0;
+			else
+				printf("\n");
+			for (i = 0; i < startcol; i++)
+				printf(" ");
+			remaining = cols - startcol;
+		} else {
+			printf(" ");
+			remaining--;
+		}
+		if (paren && (p == 0)) {
+			printf("(");
+			remaining--;
+		}
+		printf("%s", pname);
+		remaining -= pnamelen;
+		if (p < PROGRAMMER_INVALID - 1) {
+			printf(",");
+			remaining--;
+		} else {
+			if (paren)
+				printf(")");
+			printf("\n");
+		}
+	}
+}
+
+static void print_sysinfo(void)
+{
+#if HAVE_UTSNAME == 1
+	struct utsname osinfo;
+	uname(&osinfo);
+
+	msg_ginfo(" on %s %s (%s)", osinfo.sysname, osinfo.release,
+		  osinfo.machine);
+#else
+	msg_ginfo(" on unknown machine");
+#endif
+	msg_ginfo(", built with");
+#if NEED_PCI == 1
+#ifdef PCILIB_VERSION
+	msg_ginfo(" libpci %s,", PCILIB_VERSION);
+#else
+	msg_ginfo(" unknown PCI library,");
+#endif
+#endif
+#ifdef __clang__
+	msg_ginfo(" LLVM Clang");
+#ifdef __clang_version__
+	msg_ginfo(" %s,", __clang_version__);
+#else
+	msg_ginfo(" unknown version (before r102686),");
+#endif
+#elif defined(__GNUC__)
+	msg_ginfo(" GCC");
+#ifdef __VERSION__
+	msg_ginfo(" %s,", __VERSION__);
+#else
+	msg_ginfo(" unknown version,");
+#endif
+#else
+	msg_ginfo(" unknown compiler,");
+#endif
+#if defined (__FLASHROM_LITTLE_ENDIAN__)
+	msg_ginfo(" little endian");
+#else
+	msg_ginfo(" big endian");
+#endif
+	msg_ginfo("\n");
+}
+
+void print_version(void)
+{
+	msg_ginfo("flashrom v%s", flashrom_version);
+	print_sysinfo();
+}
+
+void print_banner(void)
+{
+	msg_ginfo("flashrom is free software, get the source code at "
+		  "http://www.flashrom.org\n");
+	msg_ginfo("\n");
+}
+
 /*
  * Return a string corresponding to the bustype parameter.
  * Memory is obtained with malloc() and must be freed with free() by the caller.