diff --git a/plugins/flashrom/README.md b/plugins/flashrom/README.md index 12c3eef5f..ee0423d7c 100644 --- a/plugins/flashrom/README.md +++ b/plugins/flashrom/README.md @@ -50,10 +50,6 @@ Internal device uses hardware ID values which are derived from SMBIOS. They should match the values provided by `fwupdtool hwids` or the `ComputerHardwareIds.exe` Windows utility. -lspcon-i2c-spi devices use the customized DeviceInstanceId values, e.g. - - * FLASHROM-LSPCON-I2C-SPI\VEN_1AF8&DEV_0175 - Update Behavior --------------- diff --git a/plugins/flashrom/flashrom.quirk b/plugins/flashrom/flashrom.quirk index 03613612c..0fb5222f4 100644 --- a/plugins/flashrom/flashrom.quirk +++ b/plugins/flashrom/flashrom.quirk @@ -32,14 +32,3 @@ VersionFormat=number [0ee5867c-93f0-5fb4-adf1-9d686ea1183a] Branch=coreboot VersionFormat=number - -# match all devices with this udev subsystem -[I2C] -Plugin = flashrom - -# Parade PS175 -[1AF80175:00] -Plugin=flashrom -FlashromProgrammer=lspcon_i2c_spi -Name=PS175 -Vendor=Parade diff --git a/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.c b/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.c deleted file mode 100644 index f674d4887..000000000 --- a/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2021 Daniel Campello - * - * SPDX-License-Identifier: LGPL-2.1+ - */ - -#include "config.h" - -#include "fu-flashrom-device.h" -#include "fu-flashrom-lspcon-i2c-spi-device.h" - -#include -#include -#include -#include -#include -#include - -#define I2C_PATH_REGEX "/i2c-([0-9]+)/" -#define HID_LENGTH 8 - -struct _FuFlashromLspconI2cSpiDevice { - FuFlashromDevice parent_instance; - gint bus_number; - guint8 active_partition; -}; - -G_DEFINE_TYPE (FuFlashromLspconI2cSpiDevice, fu_flashrom_lspcon_i2c_spi_device, - FU_TYPE_FLASHROM_DEVICE) - -struct romentry { - guint32 start; - guint32 end; - gboolean included; - const gchar *name; - const gchar *file; -}; - -struct flashrom_layout { - struct romentry *entries; - gsize num_entries; -}; - -static const struct romentry ENTRIES_TEMPLATE[6] = { - { .start = 0x00002, .end = 0x00003, .included = FALSE, .name = "FLAG" }, - { .start = 0x10000, .end = 0x1ffff, .included = FALSE, .name = "PAR1" }, - { .start = 0x20000, .end = 0x2ffff, .included = FALSE, .name = "PAR2" }, - { .start = 0x15000, .end = 0x15002, .included = FALSE, .name = "VER1" }, - { .start = 0x25000, .end = 0x25002, .included = FALSE, .name = "VER2" }, - { .start = 0x35000, .end = 0x35002, .included = FALSE, .name = "VERBOOT" }, -}; - -typedef struct flashrom_layout FlashromLayout; - -static FlashromLayout * -create_flash_layout (void) -{ - struct flashrom_layout *out = g_new (FlashromLayout, 1); -#if GLIB_CHECK_VERSION(2,67,3) - out->entries = g_memdup2 (ENTRIES_TEMPLATE, sizeof (ENTRIES_TEMPLATE)); -#else - out->entries = g_memdup (ENTRIES_TEMPLATE, sizeof (ENTRIES_TEMPLATE)); -#endif - out->num_entries = sizeof (ENTRIES_TEMPLATE) / sizeof (*ENTRIES_TEMPLATE); - return out; -} - -static void -dispose_flash_layout (FlashromLayout *layout) { - g_free (layout->entries); - g_free (layout); -} - -G_DEFINE_AUTOPTR_CLEANUP_FUNC(FlashromLayout, dispose_flash_layout); - - -static void -fu_flashrom_lspcon_i2c_spi_device_init (FuFlashromLspconI2cSpiDevice *self) -{ - fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE); - fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR); -} - -static gboolean -fu_flashrom_lspcon_i2c_spi_device_probe (FuDevice *device, GError **error) -{ - FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device); - FuFlashromDevice *flashrom_device = FU_FLASHROM_DEVICE (device); - FuDeviceClass *klass = - FU_DEVICE_CLASS (fu_flashrom_lspcon_i2c_spi_device_parent_class); - g_autoptr(GRegex) regex = NULL; - g_autoptr(GMatchInfo) info = NULL; - const gchar *path = NULL; - - /* FuFlashromDevice->probe */ - if (!klass->probe (device, error)) - return FALSE; - - if (g_strcmp0 (fu_flashrom_device_get_programmer_name (flashrom_device), - "lspcon_i2c_spi") != 0) { - g_set_error_literal (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "invalid programmer"); - return FALSE; - } - - /* get bus number out of sysfs path */ - path = fu_udev_device_get_sysfs_path (FU_UDEV_DEVICE (device)); - regex = g_regex_new (I2C_PATH_REGEX, 0, 0, error); - if (regex && g_regex_match_full (regex, path, -1, 0, 0, &info, error)) { - self->bus_number = g_ascii_strtoll ( g_match_info_fetch (info, 1), - NULL, 10); - return TRUE; - } - return FALSE; -} - -static gboolean -fu_flashrom_lspcon_i2c_spi_device_open (FuDevice *device, - GError **error) -{ - FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device); - FuFlashromDevice *flashrom_device = FU_FLASHROM_DEVICE (device); - FuDeviceClass *klass = - FU_DEVICE_CLASS (fu_flashrom_lspcon_i2c_spi_device_parent_class); - g_autofree gchar *temp = NULL; - g_autofree gchar *bus_path = NULL; - gint bus_fd = -1; - - /* flashrom_programmer_init() mutates the programmer_args string. */ - temp = g_strdup_printf ("bus=%d", self->bus_number); - fu_flashrom_device_set_programmer_args (flashrom_device, temp); - - /* open the bus, not the device represented by self */ - bus_path = g_strdup_printf ("/dev/i2c-%d", self->bus_number); - g_debug ("communicating with device on %s", bus_path); - if ((bus_fd = g_open (bus_path, O_RDWR, 0)) == -1) { - g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno), - "failed to open %s read-write", bus_path); - return FALSE; - } - fu_udev_device_set_fd (FU_UDEV_DEVICE (self), bus_fd); - fu_udev_device_set_flags (FU_UDEV_DEVICE (self), FU_UDEV_DEVICE_FLAG_NONE); - - return klass->open (device, error); -} - -static gboolean -probe_active_flash_partition (FuFlashromLspconI2cSpiDevice *self, - guint8 *partition, - GError **error) -{ - guint8 data; - - /* read register 0x0e on page 5, which is set to the currently-running - * flash partition number */ - if (!fu_udev_device_ioctl (FU_UDEV_DEVICE (self), - I2C_SLAVE, (guint8 *) (0x9a >> 1), NULL, error)) { - g_prefix_error (error, "failed to set I2C slave address: "); - return FALSE; - } - if (!fu_udev_device_pwrite (FU_UDEV_DEVICE (self), 0, 0x0e, error)) { - g_prefix_error (error, "failed to write register address: "); - return FALSE; - } - if (!fu_udev_device_pread (FU_UDEV_DEVICE (self), 0, &data, error)) { - g_prefix_error (error, "failed to read register value: "); - return FALSE; - } - *partition = data; - return TRUE; -} - -static gboolean -fu_flashrom_lspcon_i2c_spi_device_set_version (FuDevice *device, GError **error) -{ - FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device); - FuFlashromDevice *flashrom_device = FU_FLASHROM_DEVICE (device); - g_autofree gchar *contents = NULL; - g_autofree gchar *version = NULL; - struct flashrom_flashctx *flashctx = NULL; - g_autoptr(FlashromLayout) layout = create_flash_layout (); - gsize flash_size; - guint32 addr; - - /* set up flashrom layout */ - flashctx = fu_flashrom_device_get_flashctx (flashrom_device); - flashrom_layout_set (flashctx, layout); - - /* get the active partition */ - if (!probe_active_flash_partition (self, &self->active_partition, error)) - return FALSE; - g_debug ("device reports running from partition %d", self->active_partition); - if (self->active_partition < 1 || self->active_partition > 3) { - g_set_error (error, FWUPD_ERROR, FWUPD_ERROR_BROKEN_SYSTEM, - "Unexpected active flash partition: %d", - self->active_partition); - return FALSE; - } - - /* read version bytes for the active partition from device flash */ - layout->entries[self->active_partition + 2].included = TRUE; - - /* read the current flash contents */ - fu_device_set_status (device, FWUPD_STATUS_DEVICE_READ); - flash_size = fu_flashrom_device_get_flash_size (flashrom_device); - contents = g_malloc0 (flash_size); - if (flashrom_image_read (flashctx, contents, flash_size)) { - g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_READ, - "failed to read flash contents"); - return FALSE; - } - - /* extract the active partition's version number */ - addr = layout->entries[self->active_partition + 2].start; - g_return_val_if_fail (addr < (flash_size - 2), FALSE); - version = g_strdup_printf ("%d.%d", contents[addr], contents[addr + 2]); - fu_device_set_version (device, version); - - return TRUE; -} - -static gboolean -fu_flashrom_lspcon_i2c_spi_device_setup (FuDevice *device, GError **error) -{ - const gchar *hw_id = NULL; - g_autofree gchar *vid = NULL; - g_autofree gchar *pid = NULL; - g_autofree gchar *vendor_id = NULL; - g_autofree gchar *instance_id = NULL; - - hw_id = fu_udev_device_get_sysfs_attr (FU_UDEV_DEVICE (device), "name", error); - if (hw_id == NULL) { - g_set_error_literal (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "HID not found"); - return FALSE; - } - vid = g_strndup (hw_id, HID_LENGTH / 2); - pid = g_strndup (&hw_id[HID_LENGTH / 2], HID_LENGTH / 2); - vendor_id = g_strdup_printf ("I2C:%s", vid); - fu_device_add_vendor_id (device, vendor_id); - - instance_id = g_strdup_printf ("FLASHROM-LSPCON-I2C-SPI\\VEN_%s&DEV_%s", vid, pid); - fu_device_add_instance_id (device, instance_id); - - return fu_flashrom_lspcon_i2c_spi_device_set_version (device, error); -} - -static gboolean -fu_flashrom_lspcon_i2c_spi_device_write_firmware (FuDevice *device, - FuFirmware *firmware, - FwupdInstallFlags flags, - GError **error) -{ - FuFlashromDevice *parent = FU_FLASHROM_DEVICE (device); - FuFlashromLspconI2cSpiDevice *self = FU_FLASHROM_LSPCON_I2C_SPI_DEVICE (device); - struct flashrom_flashctx *flashctx = fu_flashrom_device_get_flashctx (parent); - gsize flash_size = fu_flashrom_device_get_flash_size (parent); - g_autofree guint8 *newcontents = g_malloc0 (flash_size); - g_autoptr(FlashromLayout) layout = create_flash_layout (); - /* if the boot partition is active we could flash either, but prefer - * the first */ - const guint8 target_partition = self->active_partition == 1 ? 2 : 1; - const gsize region_size = layout->entries[target_partition].end - - layout->entries[target_partition].start + 1; - gsize sz = 0; - gint rc; - const guint8 *buf; - g_autoptr(GBytes) blob_fw = fu_firmware_get_bytes (firmware, error); - if (blob_fw == NULL) - return FALSE; - - buf = g_bytes_get_data (blob_fw, &sz); - - if (sz != region_size) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "invalid image size 0x%x, expected 0x%x", - (guint) sz, (guint) flash_size); - return FALSE; - } - if (!fu_memcpy_safe (newcontents, flash_size, - layout->entries[target_partition].start, buf, sz, 0, - region_size, error)) - return FALSE; - - flashrom_flag_set (flashctx, FLASHROM_FLAG_VERIFY_AFTER_WRITE, TRUE); - flashrom_layout_set (flashctx, layout); - - fu_device_set_status (device, FWUPD_STATUS_DEVICE_WRITE); - fu_device_set_progress (device, 0); /* urgh */ - - /* write target_partition only */ - layout->entries[target_partition].included = TRUE; - rc = flashrom_image_write (flashctx, (void *) newcontents, flash_size, - NULL /* refbuffer */); - if (rc != 0) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_WRITE, - "image write failed, err=%i", rc); - return FALSE; - } - - /* only include flag area on layout */ - layout->entries[0].included = TRUE; - layout->entries[target_partition].included = FALSE; - - /* Flag area is header bytes (0x55, 0xAA) followed by the bank ID to - * boot from (1 or 2) and the two's complement inverse of that bank ID - * (0 or 0xFF). We only write bytes 2 and 3, assuming the header is - * already valid. */ - newcontents[2] = (gint8) target_partition; - newcontents[3] = (gint8) -target_partition + 1; - - /* write flag area */ - rc = flashrom_image_write (flashctx, (void *) newcontents, flash_size, - NULL /* refbuffer */); - if (rc != 0) { - g_set_error (error, - FWUPD_ERROR, - FWUPD_ERROR_WRITE, - "flag write failed, err=%i", rc); - return FALSE; - } - - /* success */ - return TRUE; -} - -static void -fu_flashrom_lspcon_i2c_spi_device_class_init (FuFlashromLspconI2cSpiDeviceClass *klass) -{ - FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); - klass_device->probe = fu_flashrom_lspcon_i2c_spi_device_probe; - klass_device->open = fu_flashrom_lspcon_i2c_spi_device_open; - klass_device->setup = fu_flashrom_lspcon_i2c_spi_device_setup; - klass_device->write_firmware = fu_flashrom_lspcon_i2c_spi_device_write_firmware; - klass_device->reload = fu_flashrom_lspcon_i2c_spi_device_set_version; -} diff --git a/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.h b/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.h deleted file mode 100644 index f11dda665..000000000 --- a/plugins/flashrom/fu-flashrom-lspcon-i2c-spi-device.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2021 Daniel Campello - * - * SPDX-License-Identifier: LGPL-2.1+ - */ - -#pragma once - -#include "fu-flashrom-device.h" - -#define FU_TYPE_FLASHROM_LSPCON_I2C_SPI_DEVICE \ - (fu_flashrom_lspcon_i2c_spi_device_get_type ()) -G_DECLARE_FINAL_TYPE (FuFlashromLspconI2cSpiDevice, - fu_flashrom_lspcon_i2c_spi_device, FU, - FLASHROM_LSPCON_I2C_SPI_DEVICE, FuFlashromDevice) diff --git a/plugins/flashrom/fu-plugin-flashrom.c b/plugins/flashrom/fu-plugin-flashrom.c index da5fd0c52..aeb301131 100644 --- a/plugins/flashrom/fu-plugin-flashrom.c +++ b/plugins/flashrom/fu-plugin-flashrom.c @@ -26,7 +26,6 @@ #include #include "fu-flashrom-internal-device.h" -#include "fu-flashrom-lspcon-i2c-spi-device.h" #include @@ -41,8 +40,6 @@ fu_plugin_init (FuPlugin *plugin) fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "linux_lockdown"); fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_CONFLICTS, "coreboot"); /* obsoleted */ fu_plugin_add_flag (plugin, FWUPD_PLUGIN_FLAG_REQUIRE_HWID); - fu_plugin_add_device_gtype (plugin, FU_TYPE_FLASHROM_LSPCON_I2C_SPI_DEVICE); - fu_plugin_add_udev_subsystem (plugin, "i2c"); fu_context_add_quirk_key (ctx, "FlashromProgrammer"); } diff --git a/plugins/flashrom/meson.build b/plugins/flashrom/meson.build index 889ffb426..5a2a86844 100644 --- a/plugins/flashrom/meson.build +++ b/plugins/flashrom/meson.build @@ -10,7 +10,6 @@ shared_module('fu_plugin_flashrom', sources : [ 'fu-flashrom-device.c', 'fu-flashrom-internal-device.c', - 'fu-flashrom-lspcon-i2c-spi-device.c', 'fu-plugin-flashrom.c', ], include_directories : [