outbuf == NULL is a valid condition in fu_cros_ec_usb_device_do_xfer. That's
how we use this function to specify a read with no outbound buffer, like the
reply at the end of sending a block.
Since 9b11af985f ("Add fu_memdup_safe()"), however, the call to fu_memdup_safe
always fails if outbuf, the dst, is NULL.
Fix this by moving this into the if (outbuf != NULL && outlen > 0) block below.
Fixes: 9b11af985f ("Add fu_memdup_safe()")
fixes#3064
The RO partition's USB endpoint has been observed to occasionally hiccup
(usb disconnect and reenumeration) upon reboot and initial attach, causing a
failure to update a section. Rather that making this fatal, let's set
ANOTHER_WRITE_REQUIRED and allow us to handle the new USB device after
this event.
fixes#3012
Devices may want to support more than one protocol, and for some devices
(e.g. Unifying peripherals stuck in bootloader mode) you might not even be able
to query for the correct protocol anyway.
It is far too easy to forget to set FWUPD_DEVICE_FLAG_NO_GUID_MATCHING for new
plugins, and without it it all works really well *until* a user has two devices
of the same type installed at the same time and then one 'disappears' for hard
to explain reasons. Typically we only need it for replug anyway!
Explicitly opt-in to this rarely-required behaviour, with the default to just
use the physical and logical IDs. Also document the update behavior for each
plugin to explain why the flag is being used.
This allows you to have two identical Unifying plugged in without one of them
being hidden from the user, at the same time allowing a HIDRAW<->USB transition
when going to and from bootloader and runtime modes.
This removes the workaround added in 99eb3f06b6.
Fixes https://github.com/fwupd/fwupd/issues/2915
This allows a device subclass to call the parent method after doing an initial
action, or even deliberately not call the *generic* parent method at all.
It also simplifies the plugins; you no longer have to remember what the plugin
is deriving from and accidentally clobber the wrong superclass method.
At the moment FuChunks are sometimes mutable, and sometimes immutable, and it's
all a bit too low level for comfort.
Before we can do any kind of optimisation or verification we need plugins to
stop reading directly from the C structure. The aim here is to make FuChunk
optionally mutable without making assumptions about the memory model, and also
to be able to introspect it for the docs.
This is a safer version of g_bytes_new_from_bytes() which returns a GError
if the offsets are invalid rather than emitting a critical warning.
This prevents a critical warning and potential crash when parsing invalid
bcm57xx firmware.
Our update flow prior to this was:
1. On detach, reboot to RO.
2. From Old RO, Update RW.
3. Reboot to New RW
4. From New RW, Update RO.
5. Reboot to finish
This flow has a flaw, which is that the Old RO may be buggy (especially
during development, before it's actually locked down and actually Read-Only).
This change will do the following instead:
1. On detach, do not reboot to RO if RO is writeable, and we are in RW
2. From old RW, Update RO
3. Reboot to new RO
4. From New RO, update RW
5. Reboot to finish.
This has a speed advantage as well, as we save one reboot cycle (2 vs 3).
As a result of the previous change, where we send an immediate reset to
devices in order to transition back to rw, we will end up reenumerating
as RO briefly, although the destination we wanted to get to was RW.
In that case, basically skip the write firmware step, set another write
required and allow the RO firmware to complete rw_sig and jump to the rw
partition.
Previously, we sent a 'stay-in-ro' subcommand when we are in
fu_cros_ec_usb_device_reset_to_ro, which is called from the detach phase,
in other words, we are currently sitting in RW.
This is incorrect, since stay-in-ro only interrupts an RO's
rw_sig process if it is in progress.
Instead, 'stay-in-ro' must be issued when the device reenumerates in RO,
immediately before the writing sequence starts. On devices that implement
rw_sig, they will briefly enumerate as RO before self-issuing a jump to RW
on the signature check being valid. In order to stay in RO to perform a RW
partition update, we must interrupt it as soon as we see the RO version
enumerate.
This implements the following simple state machine:
1. Reboot to RO, Update RW first, set ANOTHER_WRITE_REQUIRED
2. Second time around, don't reboot into RO. Stay in RW.
3. Update RO.
4. Done.
Write the firmware to the usb device, first finding which section to
write to, then breaking into blocks (based on maximum pdu size),
and then into chunks, which are transferred to the device using bulk transfers.
Provide the following metadata:
"Dirty firmware" bit
Protocol version
Header type
Maximum PDU Size
Flash protection status
Raw version string
Key Version
Minimum rollback
This should do the bulk transfers using protocol 6.
The output here is now equivalent to the output of
usb_updater2 -d 18d1:501a -f
fwupdtool --plugin-whitelist cros_ec get-devices --verbose
Servo Micro
DeviceId: 84d0e3f2a0f8b2328f7995767b23ebb40494723f
Guid: 8e2f7625-a164-55d7-8f09-f193c8ec33f1 <- USB\VID_18D1&PID_501A&REV_0100
Guid: 13564257-c649-586d-b4e4-4f048d480f36 <- USB\VID_18D1&PID_501A
Serial: CMO653-00166-040491U00771
Summary: Servo Micro (aka "uServo") Debug Board
Plugin: cros_ec_usb
Flags: registered
Vendor: Google Inc.
VendorId: USB:0x18D1
Version: servo_micro_v2.4.17-df61092c3
VersionFormat: plain
Created: 2020-05-20
PhysicalId: usb:03:00:02