Alexander Goncharov has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/72160 )
Change subject: ni845_spi: refactor singleton states into reentrant pattern ......................................................................
ni845_spi: 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.
TOPIC=register_master_api
Change-Id: I45fcb8e20582cb0c532c4a9f0c78543a25f8d484 Signed-off-by: Alexander Goncharov chat@joursoir.net --- M ni845x_spi.c 1 file changed, 71 insertions(+), 31 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/60/72160/1
diff --git a/ni845x_spi.c b/ni845x_spi.c index de907af..7d96eb0 100644 --- a/ni845x_spi.c +++ b/ni845x_spi.c @@ -40,13 +40,14 @@ USE_HIGHER };
-static unsigned char CS_number; // use chip select 0 as default -static enum USB845x_type device_pid = Unknown_NI845X_Device; - -static uInt32 device_handle; -static NiHandle configuration_handle; -static uint16_t io_voltage_in_mV; -static bool ignore_io_voltage_limits; +struct ni845x_spi_data { + unsigned char CS_number; // use chip select 0 as default + enum USB845x_type device_pid; + Int32 device_handle; + NiHandle configuration_handle; + uint16_t io_voltage_in_mV; + bool ignore_io_voltage_limits; +};
// USB-8452 supported voltages, keep this array in ascending order! static const uint8_t usb8452_io_voltages_in_100mV[5] = { @@ -223,7 +224,8 @@ static int usb8452_spi_set_io_voltage(uint16_t requested_io_voltage_mV, uint16_t *set_io_voltage_mV, enum voltage_coerce_mode coerce_mode, - enum USB845x_type device_pid) + enum USB845x_type device_pid, + uInt32 device_handle) { int i = 0; uint8_t selected_voltage_100mV = 0; @@ -388,16 +390,17 @@
static void ni845x_spi_cleanup(NiHandle configuration_handle, uInt32 device_handle) { + struct ni845x_spi_data *data = data; int32 ret = 0;
- if (configuration_handle != 0) { - ret = ni845xSpiConfigurationClose(configuration_handle); + if (data->configuration_handle != 0) { + ret = ni845xSpiConfigurationClose(data->configuration_handle); if (ret) ni845x_report_error("ni845xSpiConfigurationClose", ret); }
- if (device_handle != 0) { - ret = ni845xClose(device_handle); + if (data->device_handle != 0) { + ret = ni845xClose(data->device_handle); if (ret) ni845x_report_error("ni845xClose", ret); } @@ -412,76 +415,79 @@
static void ni845x_warn_over_max_voltage(const struct flashctx *flash) { - if (device_pid == USB8451) { + const struct ni845x_spi_data *data = flash->mst->spi.data; + + if (data->device_pid == USB8451) { msg_pwarn("The %s chip maximum voltage is %.1fV, while the USB-8451 " "IO voltage levels are 3.3V.\n" "Ignoring this because ignore_io_voltage_limits parameter is set.\n", flash->chip->name, flash->chip->voltage.max / 1000.0f); - } else if (device_pid == USB8452) { + } else if (data->device_pid == USB8452) { msg_pwarn("The %s chip maximum voltage is %.1fV, while the USB-8452 " "IO voltage is set to %.1fV.\n" "Ignoring this because ignore_io_voltage_limits parameter is set.\n", flash->chip->name, flash->chip->voltage.max / 1000.0f, - io_voltage_in_mV / 1000.0f); + data->io_voltage_in_mV / 1000.0f); } }
static int ni845x_spi_io_voltage_check(const struct flashctx *flash) { + const struct ni845x_spi_data *data = flash->mst->spi.data; static bool first_transmit = true;
if (first_transmit && flash->chip) { first_transmit = false; - if (io_voltage_in_mV > flash->chip->voltage.max) { - if (ignore_io_voltage_limits) { + if (data->io_voltage_in_mV > flash->chip->voltage.max) { + if (data->ignore_io_voltage_limits) { ni845x_warn_over_max_voltage(flash); return 0; }
- if (device_pid == USB8451) { + if (data->device_pid == USB8451) { msg_perr("The %s chip maximum voltage is %.1fV, while the USB-8451 " "IO voltage levels are 3.3V.\nAborting operations\n", flash->chip->name, flash->chip->voltage.max / 1000.0f); return -1; - } else if (device_pid == USB8452) { + } else if (data->device_pid == USB8452) { msg_perr("Lowering IO voltage because the %s chip maximum voltage is %.1fV, " "(%.1fV was set)\n", flash->chip->name, flash->chip->voltage.max / 1000.0f, - io_voltage_in_mV / 1000.0f); + data->io_voltage_in_mV / 1000.0f); if (usb8452_spi_set_io_voltage(flash->chip->voltage.max, - &io_voltage_in_mV, + &data->io_voltage_in_mV, USE_LOWER)) { msg_perr("Unable to lower the IO voltage below " "the chip's maximum voltage\n"); return -1; } } - } else if (io_voltage_in_mV < flash->chip->voltage.min) { - if (device_pid == USB8451) { + } else if (data->io_voltage_in_mV < flash->chip->voltage.min) { + if (data->device_pid == USB8451) { msg_pwarn("Flash operations might be unreliable, because the %s chip's " "minimum voltage is %.1fV, while the USB-8451's " "IO voltage levels are 3.3V.\n", flash->chip->name, flash->chip->voltage.min / 1000.0f); - return ignore_io_voltage_limits ? 0 : -1; - } else if (device_pid == USB8452) { + return data->ignore_io_voltage_limits ? 0 : -1; + } else if (data->device_pid == USB8452) { msg_pwarn("Raising the IO voltage because the %s chip's " "minimum voltage is %.1fV, " "(%.1fV was set)\n", flash->chip->name, flash->chip->voltage.min / 1000.0f, - io_voltage_in_mV / 1000.0f); + data->io_voltage_in_mV / 1000.0f); if (usb8452_spi_set_io_voltage(flash->chip->voltage.min, - &io_voltage_in_mV, + &data->io_voltage_in_mV, USE_HIGHER)) { msg_pwarn("Unable to raise the IO voltage above the chip's " "minimum voltage\n" "Flash operations might be unreliable.\n"); - return ignore_io_voltage_limits ? 0 : -1; + return data->ignore_io_voltage_limits ? 0 : -1; } } } @@ -495,6 +501,7 @@ const unsigned char *write_arr, unsigned char *read_arr) { + const struct ni845x_spi_data *data = flash->mst->spi.data; uInt32 read_size = 0; uInt8 *transfer_buffer = NULL; int32 ret = 0; @@ -510,8 +517,8 @@
memcpy(transfer_buffer, write_arr, write_cnt);
- ret = ni845xSpiWriteRead(device_handle, - configuration_handle, + ret = ni845xSpiWriteRead(data->device_handle, + data->configuration_handle, (write_cnt + read_cnt), transfer_buffer, &read_size, transfer_buffer); if (ret < 0) { // Negative specifies an error, meaning the function did not perform the expected behavior. @@ -558,6 +565,12 @@ int spi_speed_KHz = 1000; // selecting 1 MHz SCK is a good bet char *serial_number = NULL; // by default open the first connected device char *ignore_io_voltage_limits_str = NULL; + bool ignore_io_voltage_limits; + uint16_t io_voltage_in_mV; + unsigned char CS_number; + enum USB845x_type device_pid = Unknown_NI845X_Device; + NiHandle configuration_handle; + uInt32 device_handle; int32 tmp = 0;
// read the cs parameter (which Chip select should we use) @@ -623,7 +636,7 @@ goto err; }
- if (usb8452_spi_set_io_voltage(requested_io_voltage_mV, &io_voltage_in_mV, USE_LOWER) < 0) { + if (usb8452_spi_set_io_voltage(requested_io_voltage_mV, &io_voltage_in_mV, USE_LOWER, device_pid) < 0) { // no alert here usb8452_spi_set_io_voltage already printed that goto err; } @@ -633,6 +646,18 @@ goto err; }
+ struct ni845x_spi_data *data = calloc(1, sizeof(*data)); + if (!data) { + msg_perr("Unable to allocate space for SPI master data\n"); + return 1; + } + data->CS_number = CS_number; + data->device_pid = device_pid; + data->device_handle = device_handle; + data->configuration_handle = configuration_handle; + data->io_voltage_in_mV = io_voltage_in_mV; + data->ignore_io_voltage_limits = ignore_io_voltage_limits;; + return register_spi_master(&spi_programmer_ni845x, NULL);
err: