buspirate_spi.c: Refactor singleton states into reentrant pattern
Move global singleton states into a struct and store within
the spi_master data field for the life-time of the driver.
This is one of the steps on the way to move spi_master data
memory management behind the initialisation API, for more
context see other patches under the same topic "register_master_api".
Change-Id: I418bbfff15fb126b042fbc9be09dbf59f4d243b8
Signed-off-by: Anastasia Klimchuk <aklm@chromium.org>
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/52958
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Original-Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72209
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/buspirate_spi.c b/buspirate_spi.c
index 6c9ee4a..34fabe7 100644
--- a/buspirate_spi.c
+++ b/buspirate_spi.c
@@ -51,26 +51,28 @@
#define sp_flush_incoming(...) 0
#endif
-static unsigned char *bp_commbuf = NULL;
-static int bp_commbufsize = 0;
+struct bp_spi_data {
+ unsigned char *bp_commbuf;
+ int bp_commbufsize;
+};
-static int buspirate_commbuf_grow(int bufsize)
+static int buspirate_commbuf_grow(int bufsize, unsigned char **bp_commbuf, int *bp_commbufsize)
{
unsigned char *tmpbuf;
/* Never shrink. realloc() calls are expensive. */
- if (bufsize <= bp_commbufsize)
+ if (bufsize <= *bp_commbufsize)
return 0;
- tmpbuf = realloc(bp_commbuf, bufsize);
+ tmpbuf = realloc(*bp_commbuf, bufsize);
if (!tmpbuf) {
/* Keep the existing buffer because memory is already tight. */
msg_perr("Out of memory!\n");
return ERROR_OOM;
}
- bp_commbuf = tmpbuf;
- bp_commbufsize = bufsize;
+ *bp_commbuf = tmpbuf;
+ *bp_commbufsize = bufsize;
return 0;
}
@@ -168,6 +170,8 @@
static int buspirate_spi_shutdown(void *data)
{
+ struct bp_spi_data *bp_data = data;
+ unsigned char *const bp_commbuf = bp_data->bp_commbuf;
int ret = 0, ret2 = 0;
/* No need to allocate a buffer here, we know that bp_commbuf is at least DEFAULT_BUFSIZE big. */
@@ -195,14 +199,14 @@
/* Keep the oldest error, it is probably the best indicator. */
if (ret2 && !ret)
ret = ret2;
- bp_commbufsize = 0;
+
free(bp_commbuf);
- bp_commbuf = NULL;
if (ret)
msg_pdbg("Bus Pirate shutdown failed.\n");
else
msg_pdbg("Bus Pirate shutdown completed.\n");
+ free(data);
return ret;
}
@@ -230,6 +234,8 @@
int ret = 0;
bool pullup = false;
bool psu = false;
+ unsigned char *bp_commbuf;
+ int bp_commbufsize;
dev = extract_programmer_param("dev");
if (dev && !strlen(dev)) {
@@ -294,7 +300,6 @@
#define DEFAULT_BUFSIZE (16 + 3)
bp_commbuf = malloc(DEFAULT_BUFSIZE);
if (!bp_commbuf) {
- bp_commbufsize = 0;
msg_perr("Out of memory!\n");
free(dev);
return ERROR_OOM;
@@ -304,12 +309,20 @@
ret = buspirate_serialport_setup(dev);
free(dev);
if (ret) {
- bp_commbufsize = 0;
free(bp_commbuf);
- bp_commbuf = NULL;
return ret;
}
+
+ struct bp_spi_data *bp_data = calloc(1, sizeof(*bp_data));
+ if (!bp_data) {
+ msg_perr("Unable to allocate space for SPI master data\n");
+ free(bp_commbuf);
+ return 1;
+ }
+ bp_data->bp_commbuf = bp_commbuf;
+ bp_data->bp_commbufsize = bp_commbufsize;
+
/* This is the brute force version, but it should work.
* It is likely to fail if a previous flashrom run was aborted during a write with the new SPI commands
* in firmware v5.5 because that firmware may wait for up to 4096 bytes of input before responding to
@@ -406,10 +419,12 @@
if (BP_FWVERSION(fw_version_major, fw_version_minor) >= BP_FWVERSION(5, 5)) {
msg_pdbg("Using SPI command set v2.\n");
/* Sensible default buffer size. */
- if (buspirate_commbuf_grow(260 + 5)) {
+ if (buspirate_commbuf_grow(260 + 5, &bp_commbuf, &bp_commbufsize)) {
ret = ERROR_OOM;
goto init_err_cleanup_exit;
}
+ bp_data->bp_commbuf = bp_commbuf;
+ bp_data->bp_commbufsize = bp_commbufsize;
spi_master_buspirate.max_data_read = 2048;
spi_master_buspirate.max_data_write = 256;
spi_master_buspirate.command = buspirate_spi_send_command_v2;
@@ -418,10 +433,12 @@
msg_pinfo("Reading/writing a flash chip may take hours.\n");
msg_pinfo("It is recommended to upgrade to firmware 5.5 or newer.\n");
/* Sensible default buffer size. */
- if (buspirate_commbuf_grow(16 + 3)) {
+ if (buspirate_commbuf_grow(16 + 3, &bp_commbuf, &bp_commbufsize)) {
ret = ERROR_OOM;
goto init_err_cleanup_exit;
}
+ bp_data->bp_commbuf = bp_commbuf;
+ bp_data->bp_commbufsize = bp_commbufsize;
spi_master_buspirate.max_data_read = 12;
spi_master_buspirate.max_data_write = 12;
spi_master_buspirate.command = buspirate_spi_send_command_v1;
@@ -588,22 +605,23 @@
goto init_err_cleanup_exit;
}
- if (register_shutdown(buspirate_spi_shutdown, NULL) != 0) {
+ if (register_shutdown(buspirate_spi_shutdown, bp_data) != 0) {
ret = 1;
goto init_err_cleanup_exit;
}
- register_spi_master(&spi_master_buspirate, NULL);
+ register_spi_master(&spi_master_buspirate, bp_data);
return 0;
init_err_cleanup_exit:
- buspirate_spi_shutdown(NULL);
+ buspirate_spi_shutdown(bp_data);
return ret;
}
static int buspirate_spi_send_command_v1(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr)
{
+ struct bp_spi_data *bp_data = flash->mst->spi.data;
unsigned int i = 0;
int ret = 0;
@@ -611,9 +629,11 @@
return SPI_INVALID_LENGTH;
/* 3 bytes extra for CS#, len, CS#. */
- if (buspirate_commbuf_grow(writecnt + readcnt + 3))
+ if (buspirate_commbuf_grow(writecnt + readcnt + 3, &bp_data->bp_commbuf, &bp_data->bp_commbufsize))
return ERROR_OOM;
+ unsigned char *const bp_commbuf = bp_data->bp_commbuf;
+
/* Assert CS# */
bp_commbuf[i++] = 0x02;
@@ -657,6 +677,7 @@
static int buspirate_spi_send_command_v2(const struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
const unsigned char *writearr, unsigned char *readarr)
{
+ struct bp_spi_data *bp_data = flash->mst->spi.data;
int i = 0, ret = 0;
if (writecnt > 4096 || readcnt > 4096 || (readcnt + writecnt) > 4096)
@@ -665,9 +686,11 @@
/* 5 bytes extra for command, writelen, readlen.
* 1 byte extra for Ack/Nack.
*/
- if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1)))
+ if (buspirate_commbuf_grow(max(writecnt + 5, readcnt + 1), &bp_data->bp_commbuf, &bp_data->bp_commbufsize))
return ERROR_OOM;
+ unsigned char *const bp_commbuf = bp_data->bp_commbuf;
+
/* Combined SPI write/read. */
bp_commbuf[i++] = 0x04;
bp_commbuf[i++] = (writecnt >> 8) & 0xff;