mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 16:16:50 +00:00
plugins/flashrom: manage flashrom context at plugin level
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This commit is contained in:
parent
ddf4e10d7b
commit
e1d708a4ff
@ -28,12 +28,11 @@ struct _FuFlashromDevice {
|
|||||||
FuUdevDevice parent_instance;
|
FuUdevDevice parent_instance;
|
||||||
FuIfdRegion region;
|
FuIfdRegion region;
|
||||||
struct flashrom_flashctx *flashctx;
|
struct flashrom_flashctx *flashctx;
|
||||||
struct flashrom_programmer *flashprog;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(FuFlashromDevice, fu_flashrom_device, FU_TYPE_UDEV_DEVICE)
|
G_DEFINE_TYPE(FuFlashromDevice, fu_flashrom_device, FU_TYPE_UDEV_DEVICE)
|
||||||
|
|
||||||
enum { PROP_0, PROP_REGION, PROP_LAST };
|
enum { PROP_0, PROP_FLASHCTX, PROP_REGION, PROP_LAST };
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_flashrom_device_set_quirk_kv(FuDevice *device,
|
fu_flashrom_device_set_quirk_kv(FuDevice *device,
|
||||||
@ -81,37 +80,6 @@ static gboolean
|
|||||||
fu_flashrom_device_open(FuDevice *device, GError **error)
|
fu_flashrom_device_open(FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
||||||
gint rc;
|
|
||||||
|
|
||||||
if (flashrom_programmer_init(&self->flashprog, "internal", NULL)) {
|
|
||||||
g_set_error_literal(error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
|
||||||
"programmer initialization failed");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
rc = flashrom_flash_probe(&self->flashctx, self->flashprog, NULL);
|
|
||||||
if (rc == 3) {
|
|
||||||
g_set_error_literal(error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
|
||||||
"flash probe failed: multiple chips were found");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (rc == 2) {
|
|
||||||
g_set_error_literal(error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
|
||||||
"flash probe failed: no chip was found");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (rc != 0) {
|
|
||||||
g_set_error_literal(error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_NOT_SUPPORTED,
|
|
||||||
"flash probe failed: unknown error");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the flash size from the device if not already been quirked */
|
/* get the flash size from the device if not already been quirked */
|
||||||
if (fu_device_get_firmware_size_max(device) == 0) {
|
if (fu_device_get_firmware_size_max(device) == 0) {
|
||||||
@ -129,15 +97,6 @@ fu_flashrom_device_open(FuDevice *device, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fu_flashrom_device_close(FuDevice *device, GError **error)
|
|
||||||
{
|
|
||||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(device);
|
|
||||||
flashrom_flash_release(self->flashctx);
|
|
||||||
flashrom_programmer_shutdown(self->flashprog);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_flashrom_device_prepare(FuDevice *device,
|
fu_flashrom_device_prepare(FuDevice *device,
|
||||||
FuProgress *progress,
|
FuProgress *progress,
|
||||||
@ -326,6 +285,9 @@ fu_flashrom_device_get_property(GObject *object, guint prop_id, GValue *value, G
|
|||||||
{
|
{
|
||||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
|
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_FLASHCTX:
|
||||||
|
g_value_set_pointer(value, self->flashctx);
|
||||||
|
break;
|
||||||
case PROP_REGION:
|
case PROP_REGION:
|
||||||
g_value_set_uint(value, self->region);
|
g_value_set_uint(value, self->region);
|
||||||
break;
|
break;
|
||||||
@ -343,6 +305,9 @@ fu_flashrom_device_set_property(GObject *object,
|
|||||||
{
|
{
|
||||||
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
|
FuFlashromDevice *self = FU_FLASHROM_DEVICE(object);
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_FLASHCTX:
|
||||||
|
self->flashctx = g_value_get_pointer(value);
|
||||||
|
break;
|
||||||
case PROP_REGION:
|
case PROP_REGION:
|
||||||
self->region = g_value_get_uint(value);
|
self->region = g_value_get_uint(value);
|
||||||
fu_device_set_logical_id(FU_DEVICE(self), fu_ifd_region_to_string(self->region));
|
fu_device_set_logical_id(FU_DEVICE(self), fu_ifd_region_to_string(self->region));
|
||||||
@ -383,22 +348,39 @@ fu_flashrom_device_class_init(FuFlashromDeviceClass *klass)
|
|||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME);
|
||||||
g_object_class_install_property(object_class, PROP_REGION, pspec);
|
g_object_class_install_property(object_class, PROP_REGION, pspec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FuFlashromDevice:flashctx:
|
||||||
|
*
|
||||||
|
* The JSON root member for the device.
|
||||||
|
*/
|
||||||
|
pspec =
|
||||||
|
g_param_spec_pointer("flashctx",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
||||||
|
g_object_class_install_property(object_class, PROP_FLASHCTX, pspec);
|
||||||
|
|
||||||
object_class->constructed = fu_flashrom_device_constructed;
|
object_class->constructed = fu_flashrom_device_constructed;
|
||||||
object_class->finalize = fu_flashrom_device_finalize;
|
object_class->finalize = fu_flashrom_device_finalize;
|
||||||
klass_device->set_quirk_kv = fu_flashrom_device_set_quirk_kv;
|
klass_device->set_quirk_kv = fu_flashrom_device_set_quirk_kv;
|
||||||
klass_device->probe = fu_flashrom_device_probe;
|
klass_device->probe = fu_flashrom_device_probe;
|
||||||
klass_device->open = fu_flashrom_device_open;
|
klass_device->open = fu_flashrom_device_open;
|
||||||
klass_device->close = fu_flashrom_device_close;
|
|
||||||
klass_device->set_progress = fu_flashrom_device_set_progress;
|
klass_device->set_progress = fu_flashrom_device_set_progress;
|
||||||
klass_device->prepare = fu_flashrom_device_prepare;
|
klass_device->prepare = fu_flashrom_device_prepare;
|
||||||
klass_device->write_firmware = fu_flashrom_device_write_firmware;
|
klass_device->write_firmware = fu_flashrom_device_write_firmware;
|
||||||
}
|
}
|
||||||
|
|
||||||
FuDevice *
|
FuDevice *
|
||||||
fu_flashrom_device_new(FuContext *ctx, FuIfdRegion region)
|
fu_flashrom_device_new(FuContext *ctx, struct flashrom_flashctx *flashctx, FuIfdRegion region)
|
||||||
{
|
{
|
||||||
return FU_DEVICE(
|
return FU_DEVICE(g_object_new(FU_TYPE_FLASHROM_DEVICE,
|
||||||
g_object_new(FU_TYPE_FLASHROM_DEVICE, "context", ctx, "region", region, NULL));
|
"context",
|
||||||
|
ctx,
|
||||||
|
"flashctx",
|
||||||
|
flashctx,
|
||||||
|
"region",
|
||||||
|
region,
|
||||||
|
NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
FuIfdRegion
|
FuIfdRegion
|
||||||
|
@ -12,8 +12,10 @@
|
|||||||
#define FU_TYPE_FLASHROM_DEVICE (fu_flashrom_device_get_type())
|
#define FU_TYPE_FLASHROM_DEVICE (fu_flashrom_device_get_type())
|
||||||
G_DECLARE_FINAL_TYPE(FuFlashromDevice, fu_flashrom_device, FU, FLASHROM_DEVICE, FuUdevDevice)
|
G_DECLARE_FINAL_TYPE(FuFlashromDevice, fu_flashrom_device, FU, FLASHROM_DEVICE, FuUdevDevice)
|
||||||
|
|
||||||
|
struct flashrom_flashctx;
|
||||||
|
|
||||||
FuDevice *
|
FuDevice *
|
||||||
fu_flashrom_device_new(FuContext *ctx, FuIfdRegion region);
|
fu_flashrom_device_new(FuContext *ctx, struct flashrom_flashctx *flashctx, FuIfdRegion region);
|
||||||
|
|
||||||
FuIfdRegion
|
FuIfdRegion
|
||||||
fu_flashrom_device_get_region(FuFlashromDevice *self);
|
fu_flashrom_device_get_region(FuFlashromDevice *self);
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#define SELFCHECK_TRUE 1
|
#define SELFCHECK_TRUE 1
|
||||||
|
|
||||||
struct FuPluginData {
|
struct FuPluginData {
|
||||||
|
struct flashrom_flashctx *flashctx;
|
||||||
|
struct flashrom_programmer *flashprog;
|
||||||
gchar *guid; /* GUID from quirks that activated this plugin */
|
gchar *guid; /* GUID from quirks that activated this plugin */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +37,10 @@ static void
|
|||||||
fu_plugin_flashrom_destroy(FuPlugin *plugin)
|
fu_plugin_flashrom_destroy(FuPlugin *plugin)
|
||||||
{
|
{
|
||||||
FuPluginData *data = fu_plugin_get_data(plugin);
|
FuPluginData *data = fu_plugin_get_data(plugin);
|
||||||
|
if (data->flashctx != NULL)
|
||||||
|
flashrom_flash_release(data->flashctx);
|
||||||
|
if (data->flashprog != NULL)
|
||||||
|
flashrom_programmer_shutdown(data->flashprog);
|
||||||
g_free(data->guid);
|
g_free(data->guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,12 +168,13 @@ fu_plugin_flashrom_add_device(FuPlugin *plugin,
|
|||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
FuContext *ctx = fu_plugin_get_context(plugin);
|
FuContext *ctx = fu_plugin_get_context(plugin);
|
||||||
|
FuPluginData *data = fu_plugin_get_data(plugin);
|
||||||
const gchar *dmi_vendor;
|
const gchar *dmi_vendor;
|
||||||
const gchar *product = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_PRODUCT_NAME);
|
const gchar *product = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_PRODUCT_NAME);
|
||||||
const gchar *vendor = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_MANUFACTURER);
|
const gchar *vendor = fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_MANUFACTURER);
|
||||||
const gchar *region_str = fu_ifd_region_to_string(region);
|
const gchar *region_str = fu_ifd_region_to_string(region);
|
||||||
g_autofree gchar *name = g_strdup_printf("%s (%s)", product, region_str);
|
g_autofree gchar *name = g_strdup_printf("%s (%s)", product, region_str);
|
||||||
g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx, region);
|
g_autoptr(FuDevice) device = fu_flashrom_device_new(ctx, data->flashctx, region);
|
||||||
|
|
||||||
fu_device_set_name(device, name);
|
fu_device_set_name(device, name);
|
||||||
fu_device_set_vendor(device, vendor);
|
fu_device_set_vendor(device, vendor);
|
||||||
@ -261,6 +268,7 @@ fu_plugin_flashrom_find_guid(FuPlugin *plugin, GError **error)
|
|||||||
static gboolean
|
static gboolean
|
||||||
fu_plugin_flashrom_startup(FuPlugin *plugin, GError **error)
|
fu_plugin_flashrom_startup(FuPlugin *plugin, GError **error)
|
||||||
{
|
{
|
||||||
|
gint rc;
|
||||||
const gchar *guid;
|
const gchar *guid;
|
||||||
FuPluginData *data = fu_plugin_get_data(plugin);
|
FuPluginData *data = fu_plugin_get_data(plugin);
|
||||||
|
|
||||||
@ -278,6 +286,38 @@ fu_plugin_flashrom_startup(FuPlugin *plugin, GError **error)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
flashrom_set_log_callback(fu_plugin_flashrom_debug_cb);
|
flashrom_set_log_callback(fu_plugin_flashrom_debug_cb);
|
||||||
|
|
||||||
|
if (flashrom_programmer_init(&data->flashprog, "internal", NULL)) {
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"programmer initialization failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = flashrom_flash_probe(&data->flashctx, data->flashprog, NULL);
|
||||||
|
if (rc == 3) {
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"flash probe failed: multiple chips were found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (rc == 2) {
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"flash probe failed: no chip was found");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (rc != 0) {
|
||||||
|
g_set_error_literal(error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"flash probe failed: unknown error");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user