trivial: dell: move some dock lookup code into -common

This allows other plugins to compile in -common to be able look
up some dock related items.
This commit is contained in:
Mario Limonciello 2017-01-30 20:07:23 -06:00
parent 694bb60f2c
commit bae3a02348
5 changed files with 186 additions and 127 deletions

View File

@ -21,7 +21,6 @@
#include <appstream-glib.h>
#include "fu-dell-common.h"
#include "fu-plugin.h"
/* These are for dock query capabilities */
struct dock_count_in {
@ -151,6 +150,96 @@ fu_dell_detect_dock (FuDellSmiObj *smi_obj, guint32 *location)
return TRUE;
}
gboolean
fu_dell_query_dock (FuDellSmiObj *smi_obj, DOCK_UNION *buf)
{
gint result;
guint32 location;
guint buf_size;
if (!fu_dell_detect_dock (smi_obj, &location))
return FALSE;
fu_dell_clear_smi (smi_obj);
/* look up more information on dock */
if (smi_obj->fake_smbios)
buf->buf = smi_obj->fake_buffer;
else {
dell_smi_obj_set_class (smi_obj->smi, DACI_DOCK_CLASS);
dell_smi_obj_set_select (smi_obj->smi, DACI_DOCK_SELECT);
dell_smi_obj_set_arg (smi_obj->smi, cbARG1, DACI_DOCK_ARG_INFO);
dell_smi_obj_set_arg (smi_obj->smi, cbARG2, location);
buf_size = sizeof (DOCK_INFO_RECORD);
buf->buf = dell_smi_obj_make_buffer_frombios_auto (smi_obj->smi,
cbARG3,
buf_size);
if (!buf->buf) {
g_debug ("Failed to initialize buffer");
return FALSE;
}
}
if (!fu_dell_execute_smi (smi_obj))
return FALSE;
result = fu_dell_get_res (smi_obj, cbARG1);
if (result != SMI_SUCCESS) {
if (result == SMI_INVALID_BUFFER) {
g_debug ("Invalid buffer size, needed %" G_GUINT32_FORMAT,
fu_dell_get_res (smi_obj, cbARG2));
} else {
g_debug ("SMI execution returned error: %d",
result);
}
return FALSE;
}
return TRUE;
}
const gchar*
fu_dell_get_dock_type (guint8 type)
{
g_autoptr (FuDellSmiObj) smi_obj = NULL;
DOCK_UNION buf;
/* not yet initialized, look it up */
if (type == DOCK_TYPE_NONE) {
smi_obj = g_malloc0 (sizeof(FuDellSmiObj));
smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS);
if (!fu_dell_query_dock (smi_obj, &buf))
return NULL;
type = buf.record->dock_info_header.dock_type;
}
switch (type) {
case DOCK_TYPE_TB16:
return "TB16";
case DOCK_TYPE_WD15:
return "WD15";
default:
g_debug ("Dock type %d unknown",
type);
}
return NULL;
}
guint32
fu_dell_get_cable_type (guint8 type)
{
g_autoptr (FuDellSmiObj) smi_obj = NULL;
DOCK_UNION buf;
/* not yet initialized, look it up */
if (type == CABLE_TYPE_NONE) {
smi_obj = g_malloc0 (sizeof(FuDellSmiObj));
smi_obj->smi = dell_smi_factory (DELL_SMI_DEFAULTS);
if (!fu_dell_query_dock (smi_obj, &buf))
return 0;
type = (buf.record->dock_info).cable_type;
}
return type;
}
static gboolean
fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode,
guint32 dock_location, GError **error)
@ -167,8 +256,8 @@ fu_dell_toggle_dock_mode (FuDellSmiObj *smi_obj, guint32 new_mode,
return FALSE;
if (smi_obj->output[1] != 0) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
G_IO_ERROR,
G_IO_ERROR_INVALID_DATA,
"Failed to set dock flash mode: %u",
smi_obj->output[1]);
return FALSE;

View File

@ -35,6 +35,57 @@ typedef struct {
guint8 *fake_buffer;
} FuDellSmiObj;
/* Dock Info version 1 */
#pragma pack(1)
#define MAX_COMPONENTS 5
typedef struct _COMPONENTS {
gchar description[80];
guint32 fw_version; /* BCD format: 0x00XXYYZZ */
} COMPONENTS;
typedef struct _DOCK_INFO {
gchar dock_description[80];
guint32 flash_pkg_version; /* BCD format: 0x00XXYYZZ */
guint32 cable_type; /* bit0-7 cable type, bit7-31 set to 0 */
guint8 location; /* Location of the dock */
guint8 reserved;
guint8 component_count;
COMPONENTS components[MAX_COMPONENTS]; /* number of component_count */
} DOCK_INFO;
typedef struct _DOCK_INFO_HEADER {
guint8 dir_version; /* version 1, 2 … */
guint8 dock_type;
guint16 reserved;
} DOCK_INFO_HEADER;
typedef struct _DOCK_INFO_RECORD {
DOCK_INFO_HEADER dock_info_header; /* dock version specific definition */
DOCK_INFO dock_info;
} DOCK_INFO_RECORD;
typedef union _DOCK_UNION{
guint8 *buf;
DOCK_INFO_RECORD *record;
} DOCK_UNION;
#pragma pack()
typedef enum _DOCK_TYPE
{
DOCK_TYPE_NONE,
DOCK_TYPE_TB16,
DOCK_TYPE_WD15
} DOCK_TYPE;
typedef enum _CABLE_TYPE
{
CABLE_TYPE_NONE,
CABLE_TYPE_LEGACY,
CABLE_TYPE_UNIV,
CABLE_TYPE_TBT
} CABLE_TYPE;
gboolean
fu_dell_clear_smi (FuDellSmiObj *obj);
@ -50,6 +101,15 @@ fu_dell_execute_simple_smi (FuDellSmiObj *obj, guint16 class, guint16 select);
gboolean
fu_dell_detect_dock (FuDellSmiObj *obj, guint32 *location);
gboolean
fu_dell_query_dock (FuDellSmiObj *smi_obj, DOCK_UNION *buf);
const gchar*
fu_dell_get_dock_type (guint8 type);
guint32
fu_dell_get_cable_type (guint8 type);
gboolean
fu_dell_toggle_flash (FuDevice *device, GError **error, gboolean enable);

View File

@ -35,7 +35,6 @@
#include "fu-plugin-dell.h"
#include "fu-quirks.h"
#include "fu-plugin.h"
#include "fu-plugin-vfuncs.h"
/* These are used to indicate the status of a previous DELL flash */
@ -76,9 +75,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (FuDellSmiObj, _dell_smi_obj_free);
/* These are for matching the components */
#define WD15_EC_STR "2 0 2 2 0"
#define TB15_EC_STR "2 0 2 1 0"
#define TB15_PC2_STR "2 1 0 1 1"
#define TB15_PC1_STR "2 1 0 1 0"
#define TB16_EC_STR "2 0 2 1 0"
#define TB16_PC2_STR "2 1 0 1 1"
#define TB16_PC1_STR "2 1 0 1 0"
#define WD15_PC1_STR "2 1 0 2 0"
#define LEGACY_CBL_STR "2 2 2 1 0"
#define UNIV_CBL_STR "2 2 2 2 0"
@ -87,9 +86,9 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (FuDellSmiObj, _dell_smi_obj_free);
/* supported dock related GUIDs */
#define DOCK_FLASH_GUID EFI_GUID (0xE7CA1F36, 0xBF73, 0x4574, 0xAFE6, 0xA4, 0xCC, 0xAC, 0xAB, 0xF4, 0x79)
#define WD15_EC_GUID EFI_GUID (0xE8445370, 0x0211, 0x449D, 0x9FAA, 0x10, 0x79, 0x06, 0xAB, 0x18, 0x9F)
#define TB15_EC_GUID EFI_GUID (0x33CC8870, 0xB1FC, 0x4EC7, 0x948A, 0xC0, 0x74, 0x96, 0x87, 0x4F, 0xAF)
#define TB15_PC2_GUID EFI_GUID (0x1B52C630, 0x86F6, 0x4AEE, 0x9F0C, 0x47, 0x4D, 0xC6, 0xBE, 0x49, 0xB6)
#define TB15_PC1_GUID EFI_GUID (0x8FE183DA, 0xC94E, 0x4804, 0xB319, 0x0F, 0x1B, 0xA5, 0x45, 0x7A, 0x69)
#define TB16_EC_GUID EFI_GUID (0x33CC8870, 0xB1FC, 0x4EC7, 0x948A, 0xC0, 0x74, 0x96, 0x87, 0x4F, 0xAF)
#define TB16_PC2_GUID EFI_GUID (0x1B52C630, 0x86F6, 0x4AEE, 0x9F0C, 0x47, 0x4D, 0xC6, 0xBE, 0x49, 0xB6)
#define TB16_PC1_GUID EFI_GUID (0x8FE183DA, 0xC94E, 0x4804, 0xB319, 0x0F, 0x1B, 0xA5, 0x45, 0x7A, 0x69)
#define WD15_PC1_GUID EFI_GUID (0x8BA2B709, 0x6F97, 0x47FC, 0xB7E7, 0x6A, 0x87, 0xB5, 0x78, 0xFE, 0x25)
#define LEGACY_CBL_GUID EFI_GUID (0xFECE1537, 0xD683, 0x4EA8, 0xB968, 0x15, 0x45, 0x30, 0xBB, 0x6F, 0x73)
#define UNIV_CBL_GUID EFI_GUID (0xE2BF3AAD, 0x61A3, 0x44BF, 0x91EF, 0x34, 0x9B, 0x39, 0x51, 0x5D, 0x29)
@ -129,10 +128,10 @@ fu_plugin_dell_match_dock_component (const gchar *query_str,
{
const DOCK_DESCRIPTION list[] = {
{WD15_EC_GUID, WD15_EC_STR, EC_DESC},
{TB15_EC_GUID, TB15_EC_STR, EC_DESC},
{TB16_EC_GUID, TB16_EC_STR, EC_DESC},
{WD15_PC1_GUID, WD15_PC1_STR, PC1_DESC},
{TB15_PC1_GUID, TB15_PC1_STR, PC1_DESC},
{TB15_PC2_GUID, TB15_PC2_STR, PC2_DESC},
{TB16_PC1_GUID, TB16_PC1_STR, PC1_DESC},
{TB16_PC2_GUID, TB16_PC2_STR, PC2_DESC},
{TBT_CBL_GUID, TBT_CBL_STR, TBT_CBL_DESC},
{UNIV_CBL_GUID, UNIV_CBL_STR, UNIV_CBL_DESC},
{LEGACY_CBL_GUID, LEGACY_CBL_STR, LEGACY_CBL_DESC},
@ -243,16 +242,9 @@ fu_plugin_dock_node (FuPlugin *plugin, GUsbDevice *device,
g_autofree gchar *dock_key = NULL;
g_autofree gchar *dock_name = NULL;
switch (type) {
case DOCK_TYPE_TB15:
dock_type = "TB15/TB16";
break;
case DOCK_TYPE_WD15:
dock_type = "WD15";
break;
default:
g_debug ("Dock type %d unknown",
type);
dock_type = fu_dell_get_dock_type (type);
if (dock_type == NULL) {
g_debug ("Unknown dock type %d", type);
return FALSE;
}
@ -304,15 +296,11 @@ fu_plugin_dell_device_added_cb (GUsbContext *ctx,
guint16 vid;
const gchar *query_str;
const gchar *component_name = NULL;
INFO_UNION buf;
DOCK_UNION buf;
DOCK_INFO *dock_info;
guint buf_size;
gint result;
guint32 location;
efi_guid_t guid_raw;
efi_guid_t tmpguid;
gboolean old_ec = FALSE;
g_autofree gchar *fw_str = NULL;
/* don't look up immediately if a dock is connected as that would
@ -328,37 +316,10 @@ fu_plugin_dell_device_added_cb (GUsbContext *ctx,
/* we're going to match on the Realtek NIC in the dock */
if (vid != DOCK_NIC_VID || pid != DOCK_NIC_PID)
return;
if (!fu_dell_detect_dock (data->smi_obj, &location))
return;
fu_dell_clear_smi (data->smi_obj);
/* look up more information on dock */
if (!data->smi_obj->fake_smbios) {
dell_smi_obj_set_class (data->smi_obj->smi, DACI_DOCK_CLASS);
dell_smi_obj_set_select (data->smi_obj->smi, DACI_DOCK_SELECT);
dell_smi_obj_set_arg (data->smi_obj->smi, cbARG1, DACI_DOCK_ARG_INFO);
dell_smi_obj_set_arg (data->smi_obj->smi, cbARG2, location);
buf_size = sizeof (DOCK_INFO_RECORD);
buf.buf = dell_smi_obj_make_buffer_frombios_auto (data->smi_obj->smi, cbARG3, buf_size);
if (!buf.buf) {
g_debug ("Failed to initialize buffer");
return;
}
} else {
buf.buf = data->smi_obj->fake_buffer;
}
if (!fu_dell_execute_smi (data->smi_obj))
return;
result = fu_dell_get_res (data->smi_obj, cbARG1);
if (result != SMI_SUCCESS) {
if (result == SMI_INVALID_BUFFER) {
g_debug ("Invalid buffer size, needed %" G_GUINT32_FORMAT,
fu_dell_get_res (data->smi_obj, cbARG2));
} else {
g_debug ("SMI execution returned error: %d",
result);
}
buf.buf = NULL;
if (!fu_dell_query_dock (data->smi_obj, &buf)) {
g_debug ("No dock detected.");
return;
}
@ -447,8 +408,8 @@ fu_plugin_dell_device_removed_cb (GUsbContext *ctx,
FuPluginData *data = fu_plugin_get_data (plugin);
FuPluginDockItem *item;
g_autofree gchar *dock_key = NULL;
const efi_guid_t guids[] = { WD15_EC_GUID, TB15_EC_GUID, TB15_PC2_GUID,
TB15_PC1_GUID, WD15_PC1_GUID,
const efi_guid_t guids[] = { WD15_EC_GUID, TB16_EC_GUID, TB16_PC2_GUID,
TB16_PC1_GUID, WD15_PC1_GUID,
LEGACY_CBL_GUID, UNIV_CBL_GUID,
TBT_CBL_GUID, DOCK_FLASH_GUID};
const efi_guid_t *guid_raw;

View File

@ -66,55 +66,4 @@ struct tpm_status {
#define TPM_1_2_MODE 0x0001
#define TPM_2_0_MODE 0x0002
/* Dock Info version 1 */
#pragma pack(1)
#define MAX_COMPONENTS 5
typedef struct _COMPONENTS {
gchar description[80];
guint32 fw_version; /* BCD format: 0x00XXYYZZ */
} COMPONENTS;
typedef struct _DOCK_INFO {
gchar dock_description[80];
guint32 flash_pkg_version; /* BCD format: 0x00XXYYZZ */
guint32 cable_type; /* bit0-7 cable type, bit7-31 set to 0 */
guint8 location; /* Location of the dock */
guint8 reserved;
guint8 component_count;
COMPONENTS components[MAX_COMPONENTS]; /* number of component_count */
} DOCK_INFO;
typedef struct _DOCK_INFO_HEADER {
guint8 dir_version; /* version 1, 2 … */
guint8 dock_type;
guint16 reserved;
} DOCK_INFO_HEADER;
typedef struct _DOCK_INFO_RECORD {
DOCK_INFO_HEADER dock_info_header; /* dock version specific definition */
DOCK_INFO dock_info;
} DOCK_INFO_RECORD;
typedef union _INFO_UNION{
guint8 *buf;
DOCK_INFO_RECORD *record;
} INFO_UNION;
#pragma pack()
typedef enum _DOCK_TYPE
{
DOCK_TYPE_NONE,
DOCK_TYPE_TB15,
DOCK_TYPE_WD15
} DOCK_TYPE;
typedef enum _CABLE_TYPE
{
CABLE_TYPE_NONE,
CABLE_TYPE_LEGACY,
CABLE_TYPE_UNIV,
CABLE_TYPE_TBT
} CABLE_TYPE;
#endif /* __FU_PLUGIN_DELL_H */

View File

@ -235,7 +235,7 @@ fu_plugin_dell_dock_func (void)
gboolean ret;
guint cnt = 0;
guint32 out[4];
INFO_UNION buf;
DOCK_UNION buf;
DOCK_INFO *dock_info;
g_autoptr(GError) error = NULL;
g_autoptr(FuDevice) device = NULL;
@ -275,11 +275,11 @@ fu_plugin_dell_dock_func (void)
fu_plugin_dell_device_added_cb (NULL, NULL, plugin);
g_assert (device == NULL);
/* inject valid TB15 dock w/ invalid flash pkg version */
/* inject valid TB16 dock w/ invalid flash pkg version */
buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD));
dock_info = &buf.record->dock_info;
buf.record->dock_info_header.dir_version = 1;
buf.record->dock_info_header.dock_type = DOCK_TYPE_TB15;
buf.record->dock_info_header.dock_type = DOCK_TYPE_TB16;
memcpy (dock_info->dock_description,
"BME_Dock", 8);
dock_info->flash_pkg_version = 0x00ffffff;
@ -312,11 +312,11 @@ fu_plugin_dell_dock_func (void)
fu_plugin_dell_device_removed_cb (NULL, NULL,
plugin);
/* inject valid TB15 dock w/ older system EC */
/* inject valid TB16 dock w/ older system EC */
buf.record = g_malloc0 (sizeof(DOCK_INFO_RECORD));
dock_info = &buf.record->dock_info;
buf.record->dock_info_header.dir_version = 1;
buf.record->dock_info_header.dock_type = DOCK_TYPE_TB15;
buf.record->dock_info_header.dock_type = DOCK_TYPE_TB16;
memcpy (dock_info->dock_description,
"BME_Dock", 8);
dock_info->flash_pkg_version = 0x43;