1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-26 22:52:34 +02:00

ni845x_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>
Ticket: https://ticket.coreboot.org/issues/391
Reviewed-on: https://review.coreboot.org/c/flashrom/+/72160
Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Alexander Goncharov 2023-01-19 12:30:00 +04:00 committed by Anastasia Klimchuk
parent 0f0f952740
commit e0fe2c7ca1

View File

@ -47,13 +47,14 @@ enum voltage_coerce_mode {
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;
uInt32 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] = {
@ -394,98 +395,104 @@ static void ni845x_spi_print_available_devices(void)
static int ni845x_spi_shutdown(void *data)
{
struct ni845x_spi_data *ni_data = data;
int32 ret = 0;
if (configuration_handle != 0) {
ret = ni845xSpiConfigurationClose(configuration_handle);
if (ni_data->configuration_handle != 0) {
ret = ni845xSpiConfigurationClose(ni_data->configuration_handle);
if (ret)
ni845x_report_error("ni845xSpiConfigurationClose", ret);
}
if (device_handle != 0) {
ret = ni845xClose(device_handle);
if (ni_data->device_handle != 0) {
ret = ni845xClose(ni_data->device_handle);
if (ret)
ni845x_report_error("ni845xClose", ret);
}
return 0;
free(data);
return ret;
}
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)
{
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,
device_pid,
device_handle)) {
data->device_pid,
data->device_handle)) {
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,
device_pid,
device_handle)) {
data->device_pid,
data->device_handle)) {
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;
}
}
}
@ -499,6 +506,7 @@ static int ni845x_spi_transmit(const struct flashctx *flash,
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;
@ -514,8 +522,8 @@ static int ni845x_spi_transmit(const struct flashctx *flash,
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.
@ -560,6 +568,10 @@ static int ni845x_spi_init(const struct programmer_cfg *cfg)
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;
unsigned char CS_number = 0;
enum USB845x_type device_pid = Unknown_NI845X_Device;
uInt32 device_handle;
int32 tmp = 0;
// read the cs parameter (which Chip select should we use)
@ -618,27 +630,38 @@ static int ni845x_spi_init(const struct programmer_cfg *cfg)
}
free(serial_number);
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->ignore_io_voltage_limits = ignore_io_voltage_limits;
// open the SPI config handle
tmp = ni845xSpiConfigurationOpen(&configuration_handle);
tmp = ni845xSpiConfigurationOpen(&data->configuration_handle);
if (tmp != 0) {
ni845x_report_error("ni845xSpiConfigurationOpen", tmp);
goto err;
}
if (usb8452_spi_set_io_voltage(requested_io_voltage_mV, &io_voltage_in_mV, USE_LOWER, device_pid, device_handle) < 0) {
if (usb8452_spi_set_io_voltage(requested_io_voltage_mV, &data->io_voltage_in_mV,
USE_LOWER, data->device_pid, data->device_handle) < 0) {
// no alert here usb8452_spi_set_io_voltage already printed that
goto err;
}
if (ni845x_spi_set_speed(configuration_handle, spi_speed_KHz)) {
if (ni845x_spi_set_speed(data->configuration_handle, spi_speed_KHz)) {
msg_perr("Unable to set SPI speed\n");
goto err;
}
return register_spi_master(&spi_programmer_ni845x, NULL);
return register_spi_master(&spi_programmer_ni845x, data);
err:
ni845x_spi_shutdown(NULL);
ni845x_spi_shutdown(data);
return 1;
}