New patch, with comments from Michael addressed.
(short version of the changelog) 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.
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 903) +++ flashrom-register_shutdown/flash.h (Arbeitskopie) @@ -99,6 +99,8 @@
extern const struct programmer_entry programmer_table[];
+int register_shutdown(void (*function) (void *data), void *data); + int programmer_init(void); int programmer_shutdown(void); void *programmer_map_flash_region(const char *descr, unsigned long phys_addr, Index: flashrom-register_shutdown/flashrom.c =================================================================== --- flashrom-register_shutdown/flashrom.c (Revision 903) +++ flashrom-register_shutdown/flashrom.c (Arbeitskopie) @@ -308,6 +308,35 @@ {}, /* This entry corresponds to PROGRAMMER_INVALID. */ };
+#define SHUTDOWN_MAXFN 4 +static int shutdown_fn_count = 0; +struct shutdown_func_data { + void (*func) (void *data); + void *data; +} shutdown_fn[SHUTDOWN_MAXFN]; + +/* Register a function to be executed on programmer shutdown. + * The advantage over atexit() is that you can supply a void pointer which will + * be used as parameter to the registered function upon programmer shutdown. + * This pointer can point to arbitrary data used by said function, e.g. undo + * information for GPIO settings etc. If unneeded, set data=NULL. + * Please note that the first (void *data) belongs to the function signature of + * the function passed as first parameter. + */ +int register_shutdown(void (*function) (void *data), void *data) +{ + 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].func = function; + shutdown_fn[shutdown_fn_count].data = data; + shutdown_fn_count++; + + return 0; +} + int programmer_init(void) { return programmer_table[programmer].init(); @@ -315,6 +344,10 @@
int programmer_shutdown(void) { + int i; + + for (i = shutdown_fn_count - 1; i >= 0; i--) + shutdown_fn[i].func(shutdown_fn[i].data); return programmer_table[programmer].shutdown(); }