diff options
author | Alexander Goncharov <chat@joursoir.net> | 2023-01-24 12:41:00 +0400 |
---|---|---|
committer | Anastasia Klimchuk <aklm@chromium.org> | 2023-02-20 08:28:07 +0000 |
commit | 248fa24490df1942c83823483f75b762406c6bb7 (patch) | |
tree | 35c86746f151e8163f516b99d16636bb77719ec4 | |
parent | 57b3be8839b02d6d8d1c9d10d9fbb5cf2d946d6f (diff) | |
download | flashrom-248fa24490df1942c83823483f75b762406c6bb7.tar.gz flashrom-248fa24490df1942c83823483f75b762406c6bb7.tar.bz2 flashrom-248fa24490df1942c83823483f75b762406c6bb7.zip |
dummyflasher: use new API to register shutdown function
This allows masters to register shutdown function in *_master
struct, which means there is no need to call register_shutdown in init
function, since this call is now a part of register_*_master.
A dummy programmer can register masters for multiple buses that share a
programmer's data (a pointer to struct emu_data) with each other. To
avoid unexpected memory freeing by shutdown function, we need to keep
track of how many buses are using the shared resource. Use the
reference counting technique to achieve this.
TEST=ninja test
Change-Id: I0c67c25b0f53cd8c564c4ea0f09f2728e856f6ea
Signed-off-by: Alexander Goncharov <chat@joursoir.net>
Ticket: https://ticket.coreboot.org/issues/391
Reviewed-on: https://review.coreboot.org/c/flashrom/+/72408
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
-rw-r--r-- | dummyflasher.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/dummyflasher.c b/dummyflasher.c index 2bdd10cf..08973327 100644 --- a/dummyflasher.c +++ b/dummyflasher.c @@ -75,6 +75,10 @@ struct emu_data { unsigned int spi_write_256_chunksize; uint8_t *flashchip_contents; + + /* An instance of this structure is shared between multiple masters, so + * store the number of references to clean up only once at shutdown time. */ + uint8_t refs_cnt; }; /* A legit complete SFDP table based on the MX25L6436E (rev. 1.8) datasheet. */ @@ -905,6 +909,11 @@ static int dummy_shutdown(void *data) { msg_pspew("%s\n", __func__); struct emu_data *emu_data = (struct emu_data *)data; + + emu_data->refs_cnt--; + if (emu_data->refs_cnt != 0) + return 0; + if (emu_data->emu_chip != EMULATE_NONE) { if (emu_data->emu_persistent_image && emu_data->emu_modified) { msg_pdbg("Writing %s\n", emu_data->emu_persistent_image); @@ -933,6 +942,7 @@ static const struct spi_master spi_master_dummyflasher = { .multicommand = default_spi_send_multicommand, .read = default_spi_read, .write_256 = dummy_spi_write_256, + .shutdown = dummy_shutdown, .probe_opcode = dummy_spi_probe_opcode, .delay = dummy_nop_delay, }; @@ -948,15 +958,17 @@ static const struct par_master par_master_dummyflasher = { .chip_writew = dummy_chip_writew, .chip_writel = dummy_chip_writel, .chip_writen = dummy_chip_writen, + .shutdown = dummy_shutdown, .delay = dummy_nop_delay, }; static const struct opaque_master opaque_master_dummyflasher = { - .probe = probe_variable_size, - .read = dummy_opaque_read, - .write = dummy_opaque_write, - .erase = dummy_opaque_erase, - .delay = dummy_nop_delay, + .probe = probe_variable_size, + .read = dummy_opaque_read, + .write = dummy_opaque_write, + .erase = dummy_opaque_erase, + .shutdown = dummy_shutdown, + .delay = dummy_nop_delay, }; static int init_data(const struct programmer_cfg *cfg, @@ -1410,21 +1422,20 @@ static int dummy_init(const struct programmer_cfg *cfg) } dummy_init_out: - if (register_shutdown(dummy_shutdown, data)) { - free(data->emu_persistent_image); - free(data->flashchip_contents); - free(data); - return 1; - } - - if (dummy_buses_supported & BUS_PROG) + if (dummy_buses_supported & BUS_PROG) { + data->refs_cnt++; ret |= register_opaque_master(&opaque_master_dummyflasher, data); - if (dummy_buses_supported & BUS_NONSPI) + } + if ((dummy_buses_supported & BUS_NONSPI) && !ret) { + data->refs_cnt++; ret |= register_par_master(&par_master_dummyflasher, dummy_buses_supported & BUS_NONSPI, data); - if (dummy_buses_supported & BUS_SPI) + } + if ((dummy_buses_supported & BUS_SPI) && !ret) { + data->refs_cnt++; ret |= register_spi_master(&spi_master_dummyflasher, data); + } return ret; } |