Some programmers want to run certain functions during programmer shutdown, but the function choice depends on the code path taken during programmer init. Rather than rebuilding the whole init logic in the shutdown function, it is now possible to register functions for execution on programmer shutdown. The behaviour is similar to atexit(), but the registered functions will be run on programmer shutdown instead of on exit. Registered functions must have the prototype void function(void); and will be executed in reverse registration order directly before calling the programmer-specific shutdown() function. It is recommended to have shutdown() only disable programmer/hardware access and leave all code path sensitive shutdown to functions registered with register_shutdown(). If in doubt, consult man atexit.
Usage example (try running the dummy flasher with this patch applied):
--- dummyflasher.c 2010-02-12 02:35:18.000000000 +0100 +++ dummyflasher.c 2010-02-12 03:52:59.000000000 +0100 @@ -24,6 +24,18 @@ #include <sys/types.h> #include "flash.h"
+void foo(void) +{
- msg_pinfo("This is %s and was added first, will be executed second.\n",
__func__);
+}
+void bar(void) +{
- msg_pinfo("This is %s and was added second, will be executed first.\n",
__func__);
+}
int dummy_init(void) { int i; @@ -61,6 +73,9 @@ if (buses_supported == CHIP_BUSTYPE_NONE) msg_pdbg("Support for all flash bus types disabled.\n"); free(programmer_param);
- register_shutdown(foo);
- register_shutdown(bar); return 0;
}
The most prominent use case is resetting the EC after flashing on laptops. Anders, this should fit your requirements.
Note: There are quite a few code paths in flashrom which proceed to terminate flashrom without any programmer shutdown. Those code paths will not get the benefit of register_shutdown() and they should be changed wherever possible.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: flashrom-register_shutdown/flash.h =================================================================== --- flashrom-register_shutdown/flash.h (Revision 895) +++ flashrom-register_shutdown/flash.h (Arbeitskopie) @@ -100,6 +100,7 @@ extern const struct programmer_entry programmer_table[];
int programmer_init(void); +int register_shutdown(void (*function)(void)); int programmer_shutdown(void); void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, size_t len); Index: flashrom-register_shutdown/flashrom.c =================================================================== --- flashrom-register_shutdown/flashrom.c (Revision 895) +++ flashrom-register_shutdown/flashrom.c (Arbeitskopie) @@ -313,8 +313,28 @@ return programmer_table[programmer].init(); }
+#define SHUTDOWN_MAXFN 4 +static int shutdown_fn_count = 0; +void (*shutdown_fn[SHUTDOWN_MAXFN]) (void); + +int register_shutdown(void (*function)(void)) +{ + if (shutdown_fn_count >= SHUTDOWN_MAXFN) { + msg_perr("Tried to register more than %n shutdown functions.\n", + SHUTDOWN_MAXFN); + return 1; + } + shutdown_fn[shutdown_fn_count++] = function; + + return 0; +} + int programmer_shutdown(void) { + int i; + + for (i = shutdown_fn_count - 1; i >= 0; i--) + shutdown_fn[i](); return programmer_table[programmer].shutdown(); }