Hello Thomas, I went ahead and started looking into shutdown functions. Almost of them use global variables, but I already have ideas on how to rewrite it. Now I start coding a prototype and want to implement struct example_data. But I have run into a problem with its initialization:
1) In theory, we can declare a static variable within each programmer's file. It would be convenient, but this method has a big disadvantage. We allocate private_data for every programmers but use only one. static struct example_data { ... } private_data; 2) It's not possible to add a variable to struct programmer_entry because the structure is read only (structures in programmer.h are declared as const). 3) Use a static global variable in flashrom.c. Lesser of two evils principle as they say static const struct programmer_entry *programmer = NULL; static const char *programmer_param = NULL; static void *programmer_data = NULL; The next issue is the initialization of programmer_data: a) Do it inside programmer->init(). The problem here is the duplication of programmer_data init code in each function. b) Do it outside programmer->init(). The problem here is that we can't find out the size of example_data (it can be drkaised_data, it85spi_data and etc) programmer_data = calloc(1, sizeof(EXAMPLE_DATA)); if (!data) { ... } ... ret = programmer->init(&programmer_data); Perhaps there is some simpler solution, but I don't notice it. -- Joursoir On Sat, 19 Mar 2022 21:49:41 +0000 Thomas Heijligen <s...@posteo.de> wrote: > Hi Joursoir, > > Beside the internal programmer, most programmer manipulate only a few > things, so it is not that much. A data struct for each programmer > should be used to store the context of the programmer instead of > setting global variables. This gives the programmer a defined lifecycle > . The shutdown() function should take care of all initialized items > from the init() function. That can also be a pointer to memory mapped > I/O, a pci_dev or libusb context. > > When we take a simple programmer like the drkaiser pci programmer, > there is a pci device, a pointer to memory mapped I/O and one register. > This can easily be handled in a few lines. > > * The internal programmer is some kind of special, since it was part of > the flashrom core before other programmers exits. > * How to implement certain aspects is then part of the project. > * We try to reduce the amount of global variables. This project is part > of it. > > -- Thomas > > On Sat, 2022-03-19 at 15:59 +0300, Joursoir wrote: > > Hello Thomas and Anastasia, > > > > Thank you for the quick answer. Now I understand the idea of the > > project more correctly. It really will be great if programmers > > have their own shutdown functions. > > > > In your example you have used pci_write_*(), but the real flashrom > > code uses only rpci_write_* (it registers an undo-callback). Saving > > the data to some structure on every pci_write_*() is unnecessary > > complexity. So, we can continue to use rpci_write_*(), which will do > > work for us, but in a different way. The main problem is that > > register_shutdown() often occurs not in example_init(), but in its > > called funcs. Let's see on the example of internal programmer: > > > > internal_init() -> chipset_flash_enable() -> > > -> chipset_enables[i].doit() -> enable_flash_vt823x() > > > > The last one can contain 1 or more rpci_write_*(). I suggest not to > > register shutdown in rcpi_write_*(), but to fill a linked list with > > value that should be restored. It will be restored in > > example_shutdown(). > > > > Should global variables be used? In the case of an internal > > programmer, struct example_data will go a long way before data is > > written to it. > > _______________________________________________ > > flashrom mailing list -- flashrom@flashrom.org > > To unsubscribe send an email to flashrom-le...@flashrom.org > _______________________________________________ flashrom mailing list -- flashrom@flashrom.org To unsubscribe send an email to flashrom-le...@flashrom.org