mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-06 02:36:24 +00:00
Rename and modernize the udev plugin
The new plugin is called `optionrom` as this is the only type of image that it parses for verification only. FuUdevDevice is also the generic parent already.
This commit is contained in:
parent
8523ebebf2
commit
c15c7835be
@ -320,6 +320,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
|
|||||||
%if 0%{?have_uefi}
|
%if 0%{?have_uefi}
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_nvme.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_nvme.so
|
||||||
%endif
|
%endif
|
||||||
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_optionrom.so
|
||||||
%if 0%{?have_redfish}
|
%if 0%{?have_redfish}
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_redfish.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_redfish.so
|
||||||
%endif
|
%endif
|
||||||
@ -340,7 +341,6 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom
|
|||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_thelio_io.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_thelio_io.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_udev.so
|
|
||||||
%if 0%{?have_uefi}
|
%if 0%{?have_uefi}
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
|
||||||
|
@ -6,6 +6,7 @@ subdir('fastboot')
|
|||||||
subdir('steelseries')
|
subdir('steelseries')
|
||||||
subdir('dell-dock')
|
subdir('dell-dock')
|
||||||
subdir('nitrokey')
|
subdir('nitrokey')
|
||||||
|
subdir('optionrom')
|
||||||
subdir('rts54hid')
|
subdir('rts54hid')
|
||||||
subdir('rts54hub')
|
subdir('rts54hub')
|
||||||
subdir('solokey')
|
subdir('solokey')
|
||||||
@ -13,7 +14,6 @@ subdir('synaptics-cxaudio')
|
|||||||
subdir('synaptics-prometheus')
|
subdir('synaptics-prometheus')
|
||||||
subdir('test')
|
subdir('test')
|
||||||
subdir('thelio-io')
|
subdir('thelio-io')
|
||||||
subdir('udev')
|
|
||||||
subdir('unifying')
|
subdir('unifying')
|
||||||
subdir('upower')
|
subdir('upower')
|
||||||
subdir('wacom-raw')
|
subdir('wacom-raw')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
UDev Support
|
OptionROM Support
|
||||||
============
|
=================
|
||||||
|
|
||||||
Introduction
|
Introduction
|
||||||
------------
|
------------
|
117
plugins/optionrom/fu-optionrom-device.c
Normal file
117
plugins/optionrom/fu-optionrom-device.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2019 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "fu-rom.h"
|
||||||
|
#include "fu-optionrom-device.h"
|
||||||
|
|
||||||
|
struct _FuOptionromDevice {
|
||||||
|
FuUdevDevice parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FuOptionromDevice, fu_optionrom_device, FU_TYPE_UDEV_DEVICE)
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_optionrom_device_probe (FuUdevDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
GUdevDevice *udev_device = fu_udev_device_get_dev (device);
|
||||||
|
const gchar *guid = NULL;
|
||||||
|
|
||||||
|
guid = g_udev_device_get_property (udev_device, "FWUPD_GUID");
|
||||||
|
if (guid == NULL) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"no FWUPD_GUID property");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the physical ID */
|
||||||
|
if (!fu_udev_device_set_physical_id (device, "pci", error))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GBytes *
|
||||||
|
fu_optionrom_device_read_firmware (FuDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
FuUdevDevice *udev_device = FU_UDEV_DEVICE (device);
|
||||||
|
g_autofree gchar *guid = NULL;
|
||||||
|
g_autofree gchar *rom_fn = NULL;
|
||||||
|
g_autoptr(FuRom) rom = NULL;
|
||||||
|
g_autoptr(GFile) file = NULL;
|
||||||
|
|
||||||
|
/* open the file */
|
||||||
|
rom_fn = g_build_filename (fu_udev_device_get_sysfs_path (udev_device), "rom", NULL);
|
||||||
|
if (rom_fn == NULL) {
|
||||||
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INTERNAL,
|
||||||
|
"Unable to read firmware from device");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
file = g_file_new_for_path (rom_fn);
|
||||||
|
rom = fu_rom_new ();
|
||||||
|
if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* update version */
|
||||||
|
if (g_strcmp0 (fu_device_get_version (device),
|
||||||
|
fu_rom_get_version (rom)) != 0) {
|
||||||
|
g_debug ("changing version of %s from %s to %s",
|
||||||
|
fu_device_get_id (device),
|
||||||
|
fu_device_get_version (device),
|
||||||
|
fu_rom_get_version (rom));
|
||||||
|
fu_device_set_version (device, fu_rom_get_version (rom),
|
||||||
|
FWUPD_VERSION_FORMAT_UNKNOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Also add the GUID from the firmware as the firmware may be more
|
||||||
|
* generic, which also allows us to match the GUID when doing 'verify'
|
||||||
|
* on a device with a different PID to the firmware */
|
||||||
|
/* update guid */
|
||||||
|
guid = g_strdup_printf ("PCI\\VEN_%04X&DEV_%04X",
|
||||||
|
fu_rom_get_vendor (rom),
|
||||||
|
fu_rom_get_model (rom));
|
||||||
|
fu_device_add_guid (device, guid);
|
||||||
|
|
||||||
|
/* get new data */
|
||||||
|
return fu_rom_get_data (rom);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_optionrom_device_init (FuOptionromDevice *self)
|
||||||
|
{
|
||||||
|
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
|
||||||
|
fu_device_add_icon (FU_DEVICE (self), "audio-card");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_optionrom_device_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
G_OBJECT_CLASS (fu_optionrom_device_parent_class)->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_optionrom_device_class_init (FuOptionromDeviceClass *klass)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass);
|
||||||
|
FuUdevDeviceClass *klass_udev_device = FU_UDEV_DEVICE_CLASS (klass);
|
||||||
|
object_class->finalize = fu_optionrom_device_finalize;
|
||||||
|
klass_device->read_firmware = fu_optionrom_device_read_firmware;
|
||||||
|
klass_udev_device->probe = fu_optionrom_device_probe;
|
||||||
|
}
|
||||||
|
|
||||||
|
FuOptionromDevice *
|
||||||
|
fu_optionrom_device_new (FuUdevDevice *device)
|
||||||
|
{
|
||||||
|
FuOptionromDevice *self = g_object_new (FU_TYPE_OPTIONROM_DEVICE, NULL);
|
||||||
|
fu_device_incorporate (FU_DEVICE (self), FU_DEVICE (device));
|
||||||
|
return self;
|
||||||
|
}
|
18
plugins/optionrom/fu-optionrom-device.h
Normal file
18
plugins/optionrom/fu-optionrom-device.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fu-plugin.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define FU_TYPE_OPTIONROM_DEVICE (fu_optionrom_device_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (FuOptionromDevice, fu_optionrom_device, FU, OPTIONROM_DEVICE, FuUdevDevice)
|
||||||
|
|
||||||
|
FuOptionromDevice *fu_optionrom_device_new (FuUdevDevice *device);
|
||||||
|
|
||||||
|
G_END_DECLS
|
37
plugins/optionrom/fu-plugin-optionrom.c
Normal file
37
plugins/optionrom/fu-plugin-optionrom.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
|
||||||
|
#include "fu-optionrom-device.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
fu_plugin_init (FuPlugin *plugin)
|
||||||
|
{
|
||||||
|
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||||
|
fu_plugin_add_udev_subsystem (plugin, "pci");
|
||||||
|
fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_CONFLICTS, "udev");
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_plugin_udev_device_added (FuPlugin *plugin, FuUdevDevice *device, GError **error)
|
||||||
|
{
|
||||||
|
g_autoptr(FuOptionromDevice) dev = NULL;
|
||||||
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
|
|
||||||
|
/* interesting device? */
|
||||||
|
if (g_strcmp0 (fu_udev_device_get_subsystem (device), "pci") != 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
dev = fu_optionrom_device_new (device);
|
||||||
|
locker = fu_device_locker_new (dev, error);
|
||||||
|
if (locker == NULL)
|
||||||
|
return FALSE;
|
||||||
|
fu_plugin_device_add (plugin, FU_DEVICE (dev));
|
||||||
|
return TRUE;
|
||||||
|
}
|
@ -17,7 +17,6 @@
|
|||||||
static gboolean
|
static gboolean
|
||||||
fu_fuzzer_rom_parse (const gchar *fn, GError **error)
|
fu_fuzzer_rom_parse (const gchar *fn, GError **error)
|
||||||
{
|
{
|
||||||
GPtrArray *checksums;
|
|
||||||
g_autoptr(FuRom) rom = NULL;
|
g_autoptr(FuRom) rom = NULL;
|
||||||
g_autoptr(GFile) file = NULL;
|
g_autoptr(GFile) file = NULL;
|
||||||
|
|
||||||
@ -29,14 +28,6 @@ fu_fuzzer_rom_parse (const gchar *fn, GError **error)
|
|||||||
g_print ("filename:%s\n", fn);
|
g_print ("filename:%s\n", fn);
|
||||||
g_print ("kind:%s\n", fu_rom_kind_to_string (fu_rom_get_kind (rom)));
|
g_print ("kind:%s\n", fu_rom_kind_to_string (fu_rom_get_kind (rom)));
|
||||||
g_print ("version:%s\n", fu_rom_get_version (rom));
|
g_print ("version:%s\n", fu_rom_get_version (rom));
|
||||||
checksums = fu_rom_get_checksums (rom);
|
|
||||||
for (guint i = 0; i < checksums->len; i++) {
|
|
||||||
const gchar *checksum = g_ptr_array_index (checksums, i);
|
|
||||||
g_autofree gchar *checksum_display = NULL;
|
|
||||||
checksum_display = fwupd_checksum_format_for_display (checksum);
|
|
||||||
g_print ("checksum:%s\n", checksum_display);
|
|
||||||
}
|
|
||||||
g_print ("guid:%s\n", fu_rom_get_guid (rom));
|
|
||||||
g_print ("vendor:%u\n", fu_rom_get_vendor (rom));
|
g_print ("vendor:%u\n", fu_rom_get_vendor (rom));
|
||||||
g_print ("model:%u\n\n", fu_rom_get_model (rom));
|
g_print ("model:%u\n\n", fu_rom_get_model (rom));
|
||||||
return TRUE;
|
return TRUE;
|
@ -39,11 +39,8 @@ typedef struct {
|
|||||||
|
|
||||||
struct _FuRom {
|
struct _FuRom {
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
GPtrArray *checksums;
|
|
||||||
GInputStream *stream;
|
|
||||||
FuRomKind kind;
|
FuRomKind kind;
|
||||||
gchar *version;
|
gchar *version;
|
||||||
gchar *guid;
|
|
||||||
guint16 vendor_id;
|
guint16 vendor_id;
|
||||||
guint16 device_id;
|
guint16 device_id;
|
||||||
GPtrArray *hdrs; /* of FuRomPciHeader */
|
GPtrArray *hdrs; /* of FuRomPciHeader */
|
||||||
@ -548,8 +545,6 @@ fu_rom_load_data (FuRom *self,
|
|||||||
guint32 sz = buffer_sz;
|
guint32 sz = buffer_sz;
|
||||||
guint32 jump = 0;
|
guint32 jump = 0;
|
||||||
guint32 hdr_sz = 0;
|
guint32 hdr_sz = 0;
|
||||||
g_autoptr(GChecksum) checksum_sha1 = g_checksum_new (G_CHECKSUM_SHA1);
|
|
||||||
g_autoptr(GChecksum) checksum_sha256 = g_checksum_new (G_CHECKSUM_SHA256);
|
|
||||||
|
|
||||||
g_return_val_if_fail (FU_IS_ROM (self), FALSE);
|
g_return_val_if_fail (FU_IS_ROM (self), FALSE);
|
||||||
|
|
||||||
@ -674,19 +669,6 @@ fu_rom_load_data (FuRom *self,
|
|||||||
/* update checksum */
|
/* update checksum */
|
||||||
if (flags & FU_ROM_LOAD_FLAG_BLANK_PPID)
|
if (flags & FU_ROM_LOAD_FLAG_BLANK_PPID)
|
||||||
fu_rom_find_and_blank_serial_numbers (self);
|
fu_rom_find_and_blank_serial_numbers (self);
|
||||||
for (guint i = 0; i < self->hdrs->len; i++) {
|
|
||||||
hdr = g_ptr_array_index (self->hdrs, i);
|
|
||||||
g_checksum_update (checksum_sha1, hdr->rom_data, hdr->rom_len);
|
|
||||||
g_checksum_update (checksum_sha256, hdr->rom_data, hdr->rom_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* done updating checksums */
|
|
||||||
g_ptr_array_add (self->checksums, g_strdup (g_checksum_get_string (checksum_sha1)));
|
|
||||||
g_ptr_array_add (self->checksums, g_strdup (g_checksum_get_string (checksum_sha256)));
|
|
||||||
|
|
||||||
/* update guid */
|
|
||||||
self->guid = g_strdup_printf ("PCI\\VEN_%04X&DEV_%04X",
|
|
||||||
self->vendor_id, self->device_id);
|
|
||||||
|
|
||||||
/* not known */
|
/* not known */
|
||||||
if (self->version == NULL) {
|
if (self->version == NULL) {
|
||||||
@ -710,13 +692,13 @@ fu_rom_load_file (FuRom *self, GFile *file, FuRomLoadFlags flags,
|
|||||||
g_autoptr(GError) error_local = NULL;
|
g_autoptr(GError) error_local = NULL;
|
||||||
g_autofree gchar *fn = NULL;
|
g_autofree gchar *fn = NULL;
|
||||||
g_autofree guint8 *buffer = NULL;
|
g_autofree guint8 *buffer = NULL;
|
||||||
g_autoptr(GFileOutputStream) output_stream = NULL;
|
g_autoptr(GInputStream) stream = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (FU_IS_ROM (self), FALSE);
|
g_return_val_if_fail (FU_IS_ROM (self), FALSE);
|
||||||
|
|
||||||
/* open file */
|
/* open file */
|
||||||
self->stream = G_INPUT_STREAM (g_file_read (file, cancellable, &error_local));
|
stream = G_INPUT_STREAM (g_file_read (file, cancellable, &error_local));
|
||||||
if (self->stream == NULL) {
|
if (stream == NULL) {
|
||||||
g_set_error_literal (error,
|
g_set_error_literal (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_AUTH_FAILED,
|
FWUPD_ERROR_AUTH_FAILED,
|
||||||
@ -727,6 +709,7 @@ fu_rom_load_file (FuRom *self, GFile *file, FuRomLoadFlags flags,
|
|||||||
/* we have to enable the read for devices */
|
/* we have to enable the read for devices */
|
||||||
fn = g_file_get_path (file);
|
fn = g_file_get_path (file);
|
||||||
if (g_str_has_prefix (fn, "/sys")) {
|
if (g_str_has_prefix (fn, "/sys")) {
|
||||||
|
g_autoptr(GFileOutputStream) output_stream = NULL;
|
||||||
output_stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE,
|
output_stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE,
|
||||||
cancellable, error);
|
cancellable, error);
|
||||||
if (output_stream == NULL)
|
if (output_stream == NULL)
|
||||||
@ -738,7 +721,7 @@ fu_rom_load_file (FuRom *self, GFile *file, FuRomLoadFlags flags,
|
|||||||
|
|
||||||
/* read out the header */
|
/* read out the header */
|
||||||
buffer = g_malloc ((gsize) buffer_sz);
|
buffer = g_malloc ((gsize) buffer_sz);
|
||||||
sz = g_input_stream_read (self->stream, buffer, buffer_sz,
|
sz = g_input_stream_read (stream, buffer, buffer_sz,
|
||||||
cancellable, error);
|
cancellable, error);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -753,7 +736,7 @@ fu_rom_load_file (FuRom *self, GFile *file, FuRomLoadFlags flags,
|
|||||||
/* ensure we got enough data to fill the buffer */
|
/* ensure we got enough data to fill the buffer */
|
||||||
while (sz < buffer_sz) {
|
while (sz < buffer_sz) {
|
||||||
gssize sz_chunk;
|
gssize sz_chunk;
|
||||||
sz_chunk = g_input_stream_read (self->stream,
|
sz_chunk = g_input_stream_read (stream,
|
||||||
buffer + sz,
|
buffer + sz,
|
||||||
buffer_sz - sz,
|
buffer_sz - sz,
|
||||||
cancellable,
|
cancellable,
|
||||||
@ -794,13 +777,6 @@ fu_rom_get_version (FuRom *self)
|
|||||||
return self->version;
|
return self->version;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
|
||||||
fu_rom_get_guid (FuRom *self)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail (FU_IS_ROM (self), NULL);
|
|
||||||
return self->guid;
|
|
||||||
}
|
|
||||||
|
|
||||||
guint16
|
guint16
|
||||||
fu_rom_get_vendor (FuRom *self)
|
fu_rom_get_vendor (FuRom *self)
|
||||||
{
|
{
|
||||||
@ -815,10 +791,15 @@ fu_rom_get_model (FuRom *self)
|
|||||||
return self->device_id;
|
return self->device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPtrArray *
|
GBytes *
|
||||||
fu_rom_get_checksums (FuRom *self)
|
fu_rom_get_data (FuRom *self)
|
||||||
{
|
{
|
||||||
return self->checksums;
|
GByteArray *buf = g_byte_array_new ();
|
||||||
|
for (guint i = 0; i < self->hdrs->len; i++) {
|
||||||
|
FuRomPciHeader *hdr = g_ptr_array_index (self->hdrs, i);
|
||||||
|
g_byte_array_append (buf, hdr->rom_data, hdr->rom_len);
|
||||||
|
}
|
||||||
|
return g_byte_array_free_to_bytes (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -831,7 +812,6 @@ fu_rom_class_init (FuRomClass *klass)
|
|||||||
static void
|
static void
|
||||||
fu_rom_init (FuRom *self)
|
fu_rom_init (FuRom *self)
|
||||||
{
|
{
|
||||||
self->checksums = g_ptr_array_new_with_free_func (g_free);
|
|
||||||
self->hdrs = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_rom_pci_header_free);
|
self->hdrs = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_rom_pci_header_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,11 +821,7 @@ fu_rom_finalize (GObject *object)
|
|||||||
FuRom *self = FU_ROM (object);
|
FuRom *self = FU_ROM (object);
|
||||||
|
|
||||||
g_free (self->version);
|
g_free (self->version);
|
||||||
g_free (self->guid);
|
|
||||||
g_ptr_array_unref (self->checksums);
|
|
||||||
g_ptr_array_unref (self->hdrs);
|
g_ptr_array_unref (self->hdrs);
|
||||||
if (self->stream != NULL)
|
|
||||||
g_object_unref (self->stream);
|
|
||||||
|
|
||||||
G_OBJECT_CLASS (fu_rom_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fu_rom_parent_class)->finalize (object);
|
||||||
}
|
}
|
@ -46,8 +46,7 @@ gboolean fu_rom_extract_all (FuRom *self,
|
|||||||
GError **error);
|
GError **error);
|
||||||
FuRomKind fu_rom_get_kind (FuRom *self);
|
FuRomKind fu_rom_get_kind (FuRom *self);
|
||||||
const gchar *fu_rom_get_version (FuRom *self);
|
const gchar *fu_rom_get_version (FuRom *self);
|
||||||
GPtrArray *fu_rom_get_checksums (FuRom *self);
|
GBytes *fu_rom_get_data (FuRom *self);
|
||||||
const gchar *fu_rom_get_guid (FuRom *self);
|
|
||||||
guint16 fu_rom_get_vendor (FuRom *self);
|
guint16 fu_rom_get_vendor (FuRom *self);
|
||||||
guint16 fu_rom_get_model (FuRom *self);
|
guint16 fu_rom_get_model (FuRom *self);
|
||||||
const gchar *fu_rom_kind_to_string (FuRomKind kind);
|
const gchar *fu_rom_kind_to_string (FuRomKind kind);
|
@ -24,41 +24,34 @@ fu_rom_func (void)
|
|||||||
FuRomKind kind;
|
FuRomKind kind;
|
||||||
const gchar *fn;
|
const gchar *fn;
|
||||||
const gchar *ver;
|
const gchar *ver;
|
||||||
const gchar *csum;
|
|
||||||
guint16 vendor;
|
guint16 vendor;
|
||||||
guint16 model;
|
guint16 model;
|
||||||
} data[] = {
|
} data[] = {
|
||||||
{ FU_ROM_KIND_ATI,
|
{ FU_ROM_KIND_ATI,
|
||||||
"Asus.9800PRO.256.unknown.031114.rom",
|
"Asus.9800PRO.256.unknown.031114.rom",
|
||||||
"008.015.041.001",
|
"008.015.041.001",
|
||||||
"3137385685298bbf7db2c8304f60d89005c731ed",
|
|
||||||
0x1002, 0x4e48 },
|
0x1002, 0x4e48 },
|
||||||
{ FU_ROM_KIND_ATI, /* atombios */
|
{ FU_ROM_KIND_ATI, /* atombios */
|
||||||
"Asus.R9290X.4096.131014.rom",
|
"Asus.R9290X.4096.131014.rom",
|
||||||
"015.039.000.006.003515",
|
"015.039.000.006.003515",
|
||||||
"d8e32fa09a00ab9dcc96a990266f3fe5a99eacc5",
|
|
||||||
0x1002, 0x67b0 },
|
0x1002, 0x67b0 },
|
||||||
{ FU_ROM_KIND_ATI, /* atombios, with serial */
|
{ FU_ROM_KIND_ATI, /* atombios, with serial */
|
||||||
"Asus.HD7970.3072.121018.rom",
|
"Asus.HD7970.3072.121018.rom",
|
||||||
"015.023.000.002.000000",
|
"015.023.000.002.000000",
|
||||||
"ba8b6ce38f2499c8463fc9d983b8e0162b1121e4",
|
|
||||||
0x1002, 0x6798 },
|
0x1002, 0x6798 },
|
||||||
{ FU_ROM_KIND_NVIDIA,
|
{ FU_ROM_KIND_NVIDIA,
|
||||||
"Asus.GTX480.1536.100406_1.rom",
|
"Asus.GTX480.1536.100406_1.rom",
|
||||||
"70.00.1A.00.02",
|
"70.00.1A.00.02",
|
||||||
"3fcab24e60934850246fcfc4f42eceb32540a0ad",
|
|
||||||
0x10de, 0x06c0 },
|
0x10de, 0x06c0 },
|
||||||
{ FU_ROM_KIND_NVIDIA, /* nvgi */
|
{ FU_ROM_KIND_NVIDIA, /* nvgi */
|
||||||
"Asus.GTX980.4096.140905.rom",
|
"Asus.GTX980.4096.140905.rom",
|
||||||
"84.04.1F.00.02",
|
"84.04.1F.00.02",
|
||||||
"98f58321145bd347156455356bc04c5b04a292f5",
|
|
||||||
0x10de, 0x13c0 },
|
0x10de, 0x13c0 },
|
||||||
{ FU_ROM_KIND_NVIDIA, /* nvgi, with serial */
|
{ FU_ROM_KIND_NVIDIA, /* nvgi, with serial */
|
||||||
"Asus.TitanBlack.6144.140212.rom",
|
"Asus.TitanBlack.6144.140212.rom",
|
||||||
"80.80.4E.00.01",
|
"80.80.4E.00.01",
|
||||||
"3c80f35d4e3c440ffb427957d9271384113d7721",
|
|
||||||
0x10de, 0x100c },
|
0x10de, 0x100c },
|
||||||
{ FU_ROM_KIND_UNKNOWN, NULL, NULL, NULL, 0x0000, 0x0000 }
|
{ FU_ROM_KIND_UNKNOWN, NULL, NULL, 0x0000, 0x0000 }
|
||||||
};
|
};
|
||||||
|
|
||||||
for (guint i = 0; data[i].fn != NULL; i++) {
|
for (guint i = 0; data[i].fn != NULL; i++) {
|
||||||
@ -80,7 +73,6 @@ fu_rom_func (void)
|
|||||||
g_assert_no_error (error);
|
g_assert_no_error (error);
|
||||||
g_assert (ret);
|
g_assert (ret);
|
||||||
g_assert_cmpstr (fu_rom_get_version (rom), ==, data[i].ver);
|
g_assert_cmpstr (fu_rom_get_version (rom), ==, data[i].ver);
|
||||||
g_assert_cmpstr (g_ptr_array_index (fu_rom_get_checksums (rom), 0), ==, data[i].csum);
|
|
||||||
g_assert_cmpint (fu_rom_get_kind (rom), ==, data[i].kind);
|
g_assert_cmpint (fu_rom_get_kind (rom), ==, data[i].kind);
|
||||||
g_assert_cmpint (fu_rom_get_vendor (rom), ==, data[i].vendor);
|
g_assert_cmpint (fu_rom_get_vendor (rom), ==, data[i].vendor);
|
||||||
g_assert_cmpint (fu_rom_get_model (rom), ==, data[i].model);
|
g_assert_cmpint (fu_rom_get_model (rom), ==, data[i].model);
|
||||||
@ -123,7 +115,6 @@ fu_rom_all_func (void)
|
|||||||
}
|
}
|
||||||
g_assert_cmpstr (fu_rom_get_version (rom), !=, NULL);
|
g_assert_cmpstr (fu_rom_get_version (rom), !=, NULL);
|
||||||
g_assert_cmpstr (fu_rom_get_version (rom), !=, "\0");
|
g_assert_cmpstr (fu_rom_get_version (rom), !=, "\0");
|
||||||
g_assert_cmpint (fu_rom_get_checksums(rom)->len, !=, 0);
|
|
||||||
g_assert_cmpint (fu_rom_get_kind (rom), !=, FU_ROM_KIND_UNKNOWN);
|
g_assert_cmpint (fu_rom_get_kind (rom), !=, FU_ROM_KIND_UNKNOWN);
|
||||||
} while (TRUE);
|
} while (TRUE);
|
||||||
}
|
}
|
@ -1,9 +1,10 @@
|
|||||||
cargs = ['-DG_LOG_DOMAIN="FuPluginUdev"']
|
cargs = ['-DG_LOG_DOMAIN="FuPluginOptionrom"']
|
||||||
|
|
||||||
shared_module('fu_plugin_udev',
|
shared_module('fu_plugin_optionrom',
|
||||||
fu_hash,
|
fu_hash,
|
||||||
sources : [
|
sources : [
|
||||||
'fu-plugin-udev.c',
|
'fu-plugin-optionrom.c',
|
||||||
|
'fu-optionrom-device.c',
|
||||||
'fu-rom.c',
|
'fu-rom.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
@ -50,7 +51,7 @@ if get_option('tests')
|
|||||||
testdatadir = join_paths(meson.current_source_dir(), 'tests')
|
testdatadir = join_paths(meson.current_source_dir(), 'tests')
|
||||||
cargs += '-DTESTDATADIR="' + testdatadir + '"'
|
cargs += '-DTESTDATADIR="' + testdatadir + '"'
|
||||||
e = executable(
|
e = executable(
|
||||||
'udev-self-test',
|
'optionrom-self-test',
|
||||||
fu_hash,
|
fu_hash,
|
||||||
sources : [
|
sources : [
|
||||||
'fu-self-test.c',
|
'fu-self-test.c',
|
||||||
@ -69,5 +70,5 @@ if get_option('tests')
|
|||||||
],
|
],
|
||||||
c_args : cargs
|
c_args : cargs
|
||||||
)
|
)
|
||||||
test('udev-self-test', e)
|
test('optionrom-self-test', e)
|
||||||
endif
|
endif
|
@ -1,104 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015-2016 Richard Hughes <richard@hughsie.com>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: LGPL-2.1+
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
|
||||||
#include "fu-rom.h"
|
|
||||||
#include "fu-plugin-vfuncs.h"
|
|
||||||
|
|
||||||
void
|
|
||||||
fu_plugin_init (FuPlugin *plugin)
|
|
||||||
{
|
|
||||||
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
|
||||||
fu_plugin_add_udev_subsystem (plugin, "pci");
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_plugin_verify (FuPlugin *plugin,
|
|
||||||
FuDevice *device,
|
|
||||||
FuPluginVerifyFlags flags,
|
|
||||||
GError **error)
|
|
||||||
{
|
|
||||||
GPtrArray *checksums;
|
|
||||||
const gchar *rom_fn;
|
|
||||||
g_autoptr(GFile) file = NULL;
|
|
||||||
g_autoptr(FuRom) rom = NULL;
|
|
||||||
|
|
||||||
/* open the file */
|
|
||||||
rom_fn = fu_device_get_metadata (device, "RomFilename");
|
|
||||||
if (rom_fn == NULL) {
|
|
||||||
g_set_error_literal (error,
|
|
||||||
FWUPD_ERROR,
|
|
||||||
FWUPD_ERROR_INTERNAL,
|
|
||||||
"Unable to read firmware from device");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
file = g_file_new_for_path (rom_fn);
|
|
||||||
rom = fu_rom_new ();
|
|
||||||
if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* update version */
|
|
||||||
if (g_strcmp0 (fu_device_get_version (device),
|
|
||||||
fu_rom_get_version (rom)) != 0) {
|
|
||||||
g_debug ("changing version of %s from %s to %s",
|
|
||||||
fu_device_get_id (device),
|
|
||||||
fu_device_get_version (device),
|
|
||||||
fu_rom_get_version (rom));
|
|
||||||
fu_device_set_version (device, fu_rom_get_version (rom),
|
|
||||||
FWUPD_VERSION_FORMAT_UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Also add the GUID from the firmware as the firmware may be more
|
|
||||||
* generic, which also allows us to match the GUID when doing 'verify'
|
|
||||||
* on a device with a different PID to the firmware */
|
|
||||||
fu_device_add_guid (device, fu_rom_get_guid (rom));
|
|
||||||
|
|
||||||
/* update checksums */
|
|
||||||
checksums = fu_rom_get_checksums (rom);
|
|
||||||
for (guint i = 0; i < checksums->len; i++) {
|
|
||||||
const gchar *checksum = g_ptr_array_index (checksums, i);
|
|
||||||
fu_device_add_checksum (device, checksum);
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_plugin_udev_device_added (FuPlugin *plugin, FuUdevDevice *device, GError **error)
|
|
||||||
{
|
|
||||||
GUdevDevice *udev_device = fu_udev_device_get_dev (FU_UDEV_DEVICE (device));
|
|
||||||
const gchar *guid = NULL;
|
|
||||||
g_autofree gchar *rom_fn = NULL;
|
|
||||||
|
|
||||||
/* interesting device? */
|
|
||||||
if (g_strcmp0 (fu_udev_device_get_subsystem (device), "pci") != 0)
|
|
||||||
return TRUE;
|
|
||||||
guid = g_udev_device_get_property (udev_device, "FWUPD_GUID");
|
|
||||||
if (guid == NULL)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* set the physical ID */
|
|
||||||
if (!fu_udev_device_set_physical_id (device, "pci", error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* did we get enough data */
|
|
||||||
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_INTERNAL);
|
|
||||||
fu_device_add_icon (FU_DEVICE (device), "audio-card");
|
|
||||||
|
|
||||||
/* get the FW version from the rom when unlocked */
|
|
||||||
rom_fn = g_build_filename (fu_udev_device_get_sysfs_path (device), "rom", NULL);
|
|
||||||
if (g_file_test (rom_fn, G_FILE_TEST_EXISTS))
|
|
||||||
fu_device_set_metadata (FU_DEVICE (device), "RomFilename", rom_fn);
|
|
||||||
|
|
||||||
/* we never open the device, so convert the instance IDs */
|
|
||||||
if (!fu_device_setup (FU_DEVICE (device), error))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* insert to hash */
|
|
||||||
fu_plugin_device_add (plugin, FU_DEVICE (device));
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user