dfu: Use FuQuirk to map the chip ID to the AVR32 UM0424 alt-name

This commit is contained in:
Richard Hughes 2017-10-31 19:14:51 +00:00
parent adeefcd4e0
commit 674ed347d2
3 changed files with 34 additions and 31 deletions

View File

@ -29,6 +29,7 @@
#include "dfu-sector.h"
#include "dfu-target-avr.h"
#include "dfu-target-private.h"
#include "dfu-device-private.h"
#include "fwupd-error.h"
@ -229,21 +230,15 @@ dfu_target_avr_read_memory (DfuTarget *target,
static gboolean
dfu_target_avr_setup (DfuTarget *target, GCancellable *cancellable, GError **error)
{
DfuDevice *device;
DfuTargetAvr *target_avr = DFU_TARGET_AVR (target);
DfuTargetAvrPrivate *priv = GET_PRIVATE (target_avr);
const gchar *quirk_str;
const guint8 *buf;
gsize sz;
guint32 device_id_be;
g_autofree gchar *chip_id = NULL;
g_autoptr(GBytes) chunk_tmp = NULL;
struct {
guint32 id;
const gchar *name;
const gchar *alt_name;
} device_ids[] = {
{ 0x58200204, "AT32UC3A3", "@Flash/0x2000/1*248Kg" }, /* BL @0x2000, Size: 0x40000 */
{ 0x00000000, NULL, NULL }
};
/* already done */
if (priv->device_id > 0x0)
@ -281,39 +276,26 @@ dfu_target_avr_setup (DfuTarget *target, GCancellable *cancellable, GError **err
memcpy (&device_id_be, buf, 4);
priv->device_id = GINT32_FROM_BE (device_id_be);
/* set something suitable on the parent device */
chip_id = g_strdup_printf ("AVR:0x%08x", (guint) priv->device_id);
/* set the alt-name using the device ID */
chip_id = g_strdup_printf ("0x%08x", (guint) priv->device_id);
dfu_device_set_chip_id (dfu_target_get_device (target), chip_id);
/* match the device ID to actual hardware */
for (guint i = 0; device_ids[i].id != 0x0; i++) {
if (priv->device_id == device_ids[i].id) {
g_debug ("got a %s", device_ids[i].name);
dfu_target_set_alt_name (target, device_ids[i].alt_name);
break;
}
}
/* we don't support this chip */
if (dfu_target_get_alt_name (target, NULL) == NULL) {
g_autoptr(GString) devstr = g_string_new (NULL);
device = dfu_target_get_device (target);
quirk_str = fu_quirks_lookup_by_id (dfu_device_get_system_quirks (device),
FU_QUIRKS_DFU_AVR_CHIP_ID,
chip_id);
if (quirk_str == NULL) {
dfu_device_remove_attribute (dfu_target_get_device (target),
DFU_DEVICE_ATTRIBUTE_CAN_DOWNLOAD);
dfu_device_remove_attribute (dfu_target_get_device (target),
DFU_DEVICE_ATTRIBUTE_CAN_UPLOAD);
for (guint i = 0; device_ids[i].id != 0x0; i++) {
g_string_append_printf (devstr, "%s,",
device_ids[i].name);
}
if (devstr->len > 1)
g_string_truncate (devstr, devstr->len - 1);
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_NOT_SUPPORTED,
"DeviceID 0x%08x is not supported, known: %s",
(guint) priv->device_id, devstr->str);
"DeviceID 0x%08x is not supported",
(guint) priv->device_id);
return FALSE;
}
dfu_target_set_alt_name (target, quirk_str);
return TRUE;
}

View File

@ -68,3 +68,8 @@ USB\VID_0B0E&PID_0412=0B0E0411
USB\VID_0B0E&PID_0420=0B0E0421
USB\VID_0B0E&PID_2475=0B0E0982
USB\VID_0B0E&PID_2456=0B0E0971
[fwupd-dfu-avr-chip-id]
# AT32UC3A3 is BL @0x2000, Size: 0x40000
0x58200204=@Flash/0x2000/1*248Kg

View File

@ -128,6 +128,22 @@ const gchar *fu_quirks_lookup_by_usb_device (FuQuirks *self,
*/
#define FU_QUIRKS_DFU_ALTERNATE_VIDPID "fwupd-dfu-alternate-vidpid"
/**
* FU_QUIRKS_DFU_AVR_CHIP_ID:
* @key: the AVR chip ID, e.g. `0x58200204`
* @value: the UM0424 sector description, e.g. `@Flash/0x2000/1*248Kg`
*
* Assigns a sector description for the chip ID. This is required so fwupd can
* program the user firmware avoiding the bootloader and for checking the total
* element size.
*
* The chip ID can be found from a datasheet or using `dfu-tool list` when the
* hardware is connected and in bootloader mode.
*
* Since: 1.0.1
*/
#define FU_QUIRKS_DFU_AVR_CHIP_ID "fwupd-dfu-avr-chip-id"
G_END_DECLS
#endif /* __FU_QUIRKS_H */