mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-13 19:37:17 +00:00
superio: Move all the IT85xx code to a subclassed device object
This commit is contained in:
parent
ebd55e5d14
commit
ebedf62b15
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "fu-plugin-vfuncs.h"
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
|
||||||
#include "fu-superio-device.h"
|
#include "fu-superio-it85-device.h"
|
||||||
|
|
||||||
#define FU_QUIRKS_SUPERIO_CHIPSETS "SuperioChipsets"
|
#define FU_QUIRKS_SUPERIO_CHIPSETS "SuperioChipsets"
|
||||||
|
|
||||||
@ -41,12 +41,26 @@ fu_plugin_superio_coldplug_chipset (FuPlugin *plugin, const gchar *chipset, GErr
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create IT8xxx */
|
/* create IT89xx or IT89xx */
|
||||||
dev = g_object_new (FU_TYPE_SUPERIO_DEVICE,
|
if (id >> 8 == 0x85) {
|
||||||
"chipset", chipset,
|
dev = g_object_new (FU_TYPE_SUPERIO_IT85_DEVICE,
|
||||||
"id", id,
|
"chipset", chipset,
|
||||||
"port", port,
|
"id", id,
|
||||||
NULL);
|
"port", port,
|
||||||
|
NULL);
|
||||||
|
} else if (id >> 8 == 0x89) {
|
||||||
|
dev = g_object_new (FU_TYPE_SUPERIO_DEVICE,
|
||||||
|
"chipset", chipset,
|
||||||
|
"id", id,
|
||||||
|
"port", port,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
g_set_error (error,
|
||||||
|
G_IO_ERROR,
|
||||||
|
G_IO_ERROR_NOT_SUPPORTED,
|
||||||
|
"SuperIO chip %s has unsupported Id", chipset);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* unlock */
|
/* unlock */
|
||||||
locker = fu_device_locker_new (dev, error);
|
locker = fu_device_locker_new (dev, error);
|
||||||
|
@ -17,10 +17,6 @@
|
|||||||
|
|
||||||
#define FU_PLUGIN_SUPERIO_TIMEOUT 0.25 /* s */
|
#define FU_PLUGIN_SUPERIO_TIMEOUT 0.25 /* s */
|
||||||
|
|
||||||
/* unknown source, IT87 only */
|
|
||||||
#define SIO_CMD_EC_GET_NAME_STR 0x92
|
|
||||||
#define SIO_CMD_EC_GET_VERSION_STR 0x93
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
gint fd;
|
gint fd;
|
||||||
@ -206,7 +202,7 @@ fu_superio_device_ec_write1 (FuSuperioDevice *self, guint8 data, GError **error)
|
|||||||
return fu_superio_outb (priv->fd, priv->pm1_iobad1, data, error);
|
return fu_superio_outb (priv->fd, priv->pm1_iobad1, data, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
fu_superio_device_ec_flush (FuSuperioDevice *self, GError **error)
|
fu_superio_device_ec_flush (FuSuperioDevice *self, GError **error)
|
||||||
{
|
{
|
||||||
FuSuperioDevicePrivate *priv = GET_PRIVATE (self);
|
FuSuperioDevicePrivate *priv = GET_PRIVATE (self);
|
||||||
@ -231,7 +227,7 @@ fu_superio_device_ec_flush (FuSuperioDevice *self, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
gboolean
|
||||||
fu_superio_device_ec_get_param (FuSuperioDevice *self, guint8 param, guint8 *data, GError **error)
|
fu_superio_device_ec_get_param (FuSuperioDevice *self, guint8 param, guint8 *data, GError **error)
|
||||||
{
|
{
|
||||||
if (!fu_superio_device_ec_write1 (self, SIO_CMD_EC_READ, error))
|
if (!fu_superio_device_ec_write1 (self, SIO_CMD_EC_READ, error))
|
||||||
@ -253,23 +249,6 @@ fu_superio_device_ec_set_param (FuSuperioDevice *self, guint8 param, guint8 data
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static gchar *
|
|
||||||
fu_superio_device_ec_get_str (FuSuperioDevice *self, guint8 idx, GError **error)
|
|
||||||
{
|
|
||||||
GString *str = g_string_new (NULL);
|
|
||||||
if (!fu_superio_device_ec_write1 (self, idx, error))
|
|
||||||
return NULL;
|
|
||||||
for (guint i = 0; i < 0xff; i++) {
|
|
||||||
guint8 c = 0;
|
|
||||||
if (!fu_superio_device_ec_read (self, &c, error))
|
|
||||||
return NULL;
|
|
||||||
if (c == '$')
|
|
||||||
break;
|
|
||||||
g_string_append_c (str, c);
|
|
||||||
}
|
|
||||||
return g_string_free (str, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_superio_device_open (FuDevice *device, GError **error)
|
fu_superio_device_open (FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
@ -306,40 +285,6 @@ fu_superio_device_probe (FuDevice *device, GError **error)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
fu_superio_device_setup_it85xx (FuSuperioDevice *self, GError **error)
|
|
||||||
{
|
|
||||||
guint8 size_tmp = 0;
|
|
||||||
g_autofree gchar *name = NULL;
|
|
||||||
g_autofree gchar *version = NULL;
|
|
||||||
|
|
||||||
/* get EC size */
|
|
||||||
if (!fu_superio_device_ec_flush (self, error)) {
|
|
||||||
g_prefix_error (error, "failed to flush: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!fu_superio_device_ec_get_param (self, 0xe5, &size_tmp, error)) {
|
|
||||||
g_prefix_error (error, "failed to get EC size: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
fu_device_set_firmware_size (FU_DEVICE (self), ((guint32) size_tmp) << 10);
|
|
||||||
|
|
||||||
/* get EC strings */
|
|
||||||
name = fu_superio_device_ec_get_str (self, SIO_CMD_EC_GET_NAME_STR, error);
|
|
||||||
if (name == NULL) {
|
|
||||||
g_prefix_error (error, "failed to get EC name: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
fu_device_set_name (FU_DEVICE (self), name);
|
|
||||||
version = fu_superio_device_ec_get_str (self, SIO_CMD_EC_GET_VERSION_STR, error);
|
|
||||||
if (version == NULL) {
|
|
||||||
g_prefix_error (error, "failed to get EC version: ");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
fu_device_set_version (FU_DEVICE (self), version);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
fu_superio_device_it89xx_read_ec_register (FuSuperioDevice *self,
|
fu_superio_device_it89xx_read_ec_register (FuSuperioDevice *self,
|
||||||
guint16 addr,
|
guint16 addr,
|
||||||
@ -450,6 +395,7 @@ fu_superio_device_setup_it89xx (FuSuperioDevice *self, GError **error)
|
|||||||
static gboolean
|
static gboolean
|
||||||
fu_superio_device_setup (FuDevice *device, GError **error)
|
fu_superio_device_setup (FuDevice *device, GError **error)
|
||||||
{
|
{
|
||||||
|
FuSuperioDeviceClass *klass = FU_SUPERIO_DEVICE_GET_CLASS (device);
|
||||||
FuSuperioDevice *self = FU_SUPERIO_DEVICE (device);
|
FuSuperioDevice *self = FU_SUPERIO_DEVICE (device);
|
||||||
FuSuperioDevicePrivate *priv = GET_PRIVATE (self);
|
FuSuperioDevicePrivate *priv = GET_PRIVATE (self);
|
||||||
guint8 tmp = 0x0;
|
guint8 tmp = 0x0;
|
||||||
@ -506,11 +452,9 @@ fu_superio_device_setup (FuDevice *device, GError **error)
|
|||||||
fu_common_dump_raw (G_LOG_DOMAIN, "EC Registers", buf, 0x100);
|
fu_common_dump_raw (G_LOG_DOMAIN, "EC Registers", buf, 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IT85xx */
|
/* subclassed setup */
|
||||||
if (priv->id >> 8 == 0x85) {
|
if (klass->setup != NULL)
|
||||||
if (!fu_superio_device_setup_it85xx (self, error))
|
return klass->setup (self, error);
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* IT89xx */
|
/* IT89xx */
|
||||||
if (priv->id >> 8 == 0x89) {
|
if (priv->id >> 8 == 0x89) {
|
||||||
|
@ -16,8 +16,12 @@ G_DECLARE_DERIVABLE_TYPE (FuSuperioDevice, fu_superio_device, FU, SUPERIO_DEVICE
|
|||||||
struct _FuSuperioDeviceClass
|
struct _FuSuperioDeviceClass
|
||||||
{
|
{
|
||||||
FuDeviceClass parent_class;
|
FuDeviceClass parent_class;
|
||||||
|
gboolean (*setup) (FuSuperioDevice *self,
|
||||||
|
GError **error);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gboolean fu_superio_device_ec_flush (FuSuperioDevice *self,
|
||||||
|
GError **error);
|
||||||
gboolean fu_superio_device_ec_read (FuSuperioDevice *self,
|
gboolean fu_superio_device_ec_read (FuSuperioDevice *self,
|
||||||
guint8 *data,
|
guint8 *data,
|
||||||
GError **error);
|
GError **error);
|
||||||
@ -27,6 +31,10 @@ gboolean fu_superio_device_ec_write0 (FuSuperioDevice *self,
|
|||||||
gboolean fu_superio_device_ec_write1 (FuSuperioDevice *self,
|
gboolean fu_superio_device_ec_write1 (FuSuperioDevice *self,
|
||||||
guint8 data,
|
guint8 data,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
gboolean fu_superio_device_ec_get_param (FuSuperioDevice *self,
|
||||||
|
guint8 param,
|
||||||
|
guint8 *data,
|
||||||
|
GError **error);
|
||||||
gboolean fu_superio_device_regval (FuSuperioDevice *self,
|
gboolean fu_superio_device_regval (FuSuperioDevice *self,
|
||||||
guint8 addr,
|
guint8 addr,
|
||||||
guint8 *data,
|
guint8 *data,
|
||||||
|
80
plugins/superio/fu-superio-it85-device.c
Normal file
80
plugins/superio/fu-superio-it85-device.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2019 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "fu-chunk.h"
|
||||||
|
#include "fu-superio-common.h"
|
||||||
|
#include "fu-superio-it85-device.h"
|
||||||
|
|
||||||
|
struct _FuSuperioIt85Device {
|
||||||
|
FuSuperioDevice parent_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FuSuperioIt85Device, fu_superio_it85_device, FU_TYPE_SUPERIO_DEVICE)
|
||||||
|
|
||||||
|
static gchar *
|
||||||
|
fu_superio_it85_device_get_str (FuSuperioDevice *self, guint8 idx, GError **error)
|
||||||
|
{
|
||||||
|
GString *str = g_string_new (NULL);
|
||||||
|
if (!fu_superio_device_ec_write1 (self, idx, error))
|
||||||
|
return NULL;
|
||||||
|
for (guint i = 0; i < 0xff; i++) {
|
||||||
|
guint8 c = 0;
|
||||||
|
if (!fu_superio_device_ec_read (self, &c, error))
|
||||||
|
return NULL;
|
||||||
|
if (c == '$')
|
||||||
|
break;
|
||||||
|
g_string_append_c (str, c);
|
||||||
|
}
|
||||||
|
return g_string_free (str, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
fu_superio_it85_device_setup (FuSuperioDevice *self, GError **error)
|
||||||
|
{
|
||||||
|
guint8 size_tmp = 0;
|
||||||
|
g_autofree gchar *name = NULL;
|
||||||
|
g_autofree gchar *version = NULL;
|
||||||
|
|
||||||
|
/* get EC size */
|
||||||
|
if (!fu_superio_device_ec_flush (self, error)) {
|
||||||
|
g_prefix_error (error, "failed to flush: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!fu_superio_device_ec_get_param (self, 0xe5, &size_tmp, error)) {
|
||||||
|
g_prefix_error (error, "failed to get EC size: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fu_device_set_firmware_size (FU_DEVICE (self), ((guint32) size_tmp) << 10);
|
||||||
|
|
||||||
|
/* get EC strings */
|
||||||
|
name = fu_superio_it85_device_get_str (self, SIO_CMD_EC_GET_NAME_STR, error);
|
||||||
|
if (name == NULL) {
|
||||||
|
g_prefix_error (error, "failed to get EC name: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fu_device_set_name (FU_DEVICE (self), name);
|
||||||
|
version = fu_superio_it85_device_get_str (self, SIO_CMD_EC_GET_VERSION_STR, error);
|
||||||
|
if (version == NULL) {
|
||||||
|
g_prefix_error (error, "failed to get EC version: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
fu_device_set_version (FU_DEVICE (self), version);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_superio_it85_device_init (FuSuperioIt85Device *self)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_superio_it85_device_class_init (FuSuperioIt85DeviceClass *klass)
|
||||||
|
{
|
||||||
|
FuSuperioDeviceClass *klass_superio_device = FU_SUPERIO_DEVICE_CLASS (klass);
|
||||||
|
klass_superio_device->setup = fu_superio_it85_device_setup;
|
||||||
|
}
|
16
plugins/superio/fu-superio-it85-device.h
Normal file
16
plugins/superio/fu-superio-it85-device.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2019 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fu-superio-device.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define FU_TYPE_SUPERIO_IT85_DEVICE (fu_superio_it85_device_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (FuSuperioIt85Device, fu_superio_it85_device, FU, SUPERIO_IT85_DEVICE, FuSuperioDevice)
|
||||||
|
|
||||||
|
G_END_DECLS
|
@ -9,6 +9,7 @@ shared_module('fu_plugin_superio',
|
|||||||
sources : [
|
sources : [
|
||||||
'fu-plugin-superio.c',
|
'fu-plugin-superio.c',
|
||||||
'fu-superio-device.c',
|
'fu-superio-device.c',
|
||||||
|
'fu-superio-it85-device.c',
|
||||||
'fu-superio-common.c',
|
'fu-superio-common.c',
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
|
Loading…
Reference in New Issue
Block a user