From bae3a02348baaff4d3c3eebb5e1c88643b081b51 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 30 Jan 2017 20:07:23 -0600 Subject: [PATCH] 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. --- plugins/dell/fu-dell-common.c | 95 +++++++++++++++++++++++++++++++++-- plugins/dell/fu-dell-common.h | 60 ++++++++++++++++++++++ plugins/dell/fu-plugin-dell.c | 75 +++++++-------------------- plugins/dell/fu-plugin-dell.h | 51 ------------------- plugins/dell/fu-self-test.c | 32 ++++++------ 5 files changed, 186 insertions(+), 127 deletions(-) diff --git a/plugins/dell/fu-dell-common.c b/plugins/dell/fu-dell-common.c index 6f1cb6684..306d4112a 100644 --- a/plugins/dell/fu-dell-common.c +++ b/plugins/dell/fu-dell-common.c @@ -21,7 +21,6 @@ #include #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; diff --git a/plugins/dell/fu-dell-common.h b/plugins/dell/fu-dell-common.h index cc1f0d05a..dae37fe7d 100644 --- a/plugins/dell/fu-dell-common.h +++ b/plugins/dell/fu-dell-common.h @@ -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); diff --git a/plugins/dell/fu-plugin-dell.c b/plugins/dell/fu-plugin-dell.c index 1fb7501c7..aa39095ab 100644 --- a/plugins/dell/fu-plugin-dell.c +++ b/plugins/dell/fu-plugin-dell.c @@ -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; diff --git a/plugins/dell/fu-plugin-dell.h b/plugins/dell/fu-plugin-dell.h index c45bb4333..8b9943a9e 100644 --- a/plugins/dell/fu-plugin-dell.h +++ b/plugins/dell/fu-plugin-dell.h @@ -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 */ diff --git a/plugins/dell/fu-self-test.c b/plugins/dell/fu-self-test.c index d0da3cedb..35b2b015d 100644 --- a/plugins/dell/fu-self-test.c +++ b/plugins/dell/fu-self-test.c @@ -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 */ - buf.record = g_malloc0(sizeof(DOCK_INFO_RECORD)); + /* 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 */ - buf.record = g_malloc0(sizeof(DOCK_INFO_RECORD)); + /* 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; @@ -351,7 +351,7 @@ fu_plugin_dell_dock_func (void) /* inject valid WD15 dock w/ invalid flash pkg version */ - buf.record = g_malloc0(sizeof(DOCK_INFO_RECORD)); + 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_WD15; @@ -386,7 +386,7 @@ fu_plugin_dell_dock_func (void) /* inject valid WD15 dock w/ older system EC */ - buf.record = g_malloc0(sizeof(DOCK_INFO_RECORD)); + 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_WD15; @@ -408,9 +408,9 @@ fu_plugin_dell_dock_func (void) out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, - (guint32 *) &out, - DOCK_NIC_VID, DOCK_NIC_PID, - buf.buf); + (guint32 *) &out, + DOCK_NIC_VID, DOCK_NIC_PID, + buf.buf); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device != NULL); @@ -420,7 +420,7 @@ fu_plugin_dell_dock_func (void) plugin); /* inject an invalid future dock */ - buf.record = g_malloc0(sizeof(DOCK_INFO_RECORD)); + 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 = 50; @@ -436,9 +436,9 @@ fu_plugin_dell_dock_func (void) out[0] = 0; out[1] = 1; fu_plugin_dell_inject_fake_data (plugin, - (guint32 *) &out, - DOCK_NIC_VID, DOCK_NIC_PID, - buf.buf); + (guint32 *) &out, + DOCK_NIC_VID, DOCK_NIC_PID, + buf.buf); fu_plugin_dell_device_added_cb (NULL, NULL, plugin); g_assert (device == NULL);