In this case, a plugin was doing:
g_autoptr(FuDevice) parent = fu_device_get_parent (device);
Which is not valid as it is `(transfer none)` but that shouldn't be enough to
get the daemon to crash. If the FuDevice refcount drops to zero just print
a critical warning with the pointer (no FuDevice details are available) and
remove the FuDeviceItem from the device list.
Using `G_DEBUG=fatal-criticals` it is very easy to backtrace at the right place
and find out which naughty plugin needs to go on the thinking spot.
Doing this unconditionally means we accidentally 'bleed' one device mode into
another in a non-obvious way. For instance, a device might have two operating
modes with different GUIDs. If firmware is supplied for both modes in the same
cabinet archive then we might accidentally match the 'wrong' firmware when
the daemon has observed a mode switch and added the counterpart GUIDs.
We only really need the counterpart GUIDs when switching between Jabra, 8bitdo
and DFU devices where the DFU bootloader VID:PID is not manually tagged with
`CounterpartGuid` in a quirk file. In the general case lets keep it simple to
avoid difficult to find bugs.
Rather than return the first device with a matching counterpart GUID, and then
check to see if it was removed -- instead just return any item that matches and
has been removed.
This fixes updating the Logitech unifying receiver when more than one type of
device (e.g. RQR12 and RQR24) are connected.
Use only one GMainLoop in FuDeviceList; we can only iterate one loop at a time
anyway, and having the mainloops per-item complicates the lifecycle of the
fu_device_list_wait_for_replug() functionality considerably.
If the device has a child with a longer remove_delay we actually crash because
the FuDeviceList tries to remove the child device twice. Just remove all the
children when the parent remove delay elapsed rather than set up each device
with a unique timeout.
If we say that the version format should be the same for the `version_lowest`
and the `version_bootloader` then it does not always make sense to set it at
the same time.
Moving the `version_format` to a standalone first-class property also means it
can be typically be set in the custom device `_init()` function, which means we
don't need to worry about *changing* ther version format as set by the USB and
UDev superclass helpers.
Some Dell devices offer the exact same GUID in UEFI as well as in NVME
plugins. These devices can be flashed in either way, but the payload
for them is different.
The UEFI payload includes relevant headers and metadata to be acceptable
from a capsule. The NVME payload is raw data that the drive will process.
Since baa9e75ca8, fwupd should enforce that
the correct device is flashed with the correct protocol.
The debug features the object provides are not useful and are much too verbose
to be useful.
Backport the new reader/writer g_autoptr defines to avoid bumping the GLib dep.
Most of the work was done by Kalev Lember <klember@redhat.com>, many thanks.
This leads to madness, as some formats are supersets of the detected types,
e.g. 'intel-me' is detected as 'quad' and 'bcd' is detected as 'pair'.
Where the version format is defined in a specification or hardcoded in the
source use a hardcoded enum value, otherwise use a quirk override.
Additionally, warn if the version does not match the defined version format
It wasn't hugely clear what the platform ID was actually meant to represent. In
some cases it was being used like a physical ID, in others it was a logical ID,
and in others it was both. In some cases it was even used as a sysfs path.
Clear up all the confusion by splitting the platform ID into two parts, an
optional *physical* ID to represent the electrical connection, and an optional
*logical* ID to disambiguate composite devices with the same physical ID.
Also create an explicit sysfs_path getter for FuUdevDevice to make this clear.
This allows WAIT_FOR_REPLUG to always work, rather than depending on the order
that the GUIDs were added, and that the kernel would always return the same
sysfs path (which it doesn't have to do, especially for hidraw devices).
This caused errors of mismatching devices that didn't have platform
ID's set.
Example:
18:40:24:0555 Fu ignoring device 370e10407b1f04ade798a9f1d3e1fa57c67750c3 [uefi] existing device 088df415cdee883ec89563e41e6d495924250174 [amt] already exists
Fixes: 3a8d5328 ("Allow the device list to take care of waiting for the device replug")
These are GUIDs that are related to the main device, but should not be used for
quirk matching. For instance, we might want to list the GUIDs for a bootloader
mode, but we don't want to import all the quirks for the bootloader when in the
runtime mode.
In this instance, we define the 'same device' to be a FuDevice that has at
least one matching GUID. We allow the plugins to define which one is 'better'
than other plugins, and use this to only have one FuDevice for the physical
device.
Alternative to https://github.com/hughsie/fwupd/pull/604
We were looking for 'active' and 'old' devices with a specific ID. Due to a
copy and paste thinko we were actually matching the active list twice,
triggering the 'device ID was not unique' failure.
Fixes half of https://github.com/hughsie/fwupd/issues/565
This allows us to find out the logical parent device, for instance in composite
devices with more than one firmware image for a single device.
We also allow lazily specifying the device parent using a GUID and the engine
then automatically sets the parent object when the GUIDs match, which allows
children and parents to exist in different plugins.
Some devices like the Nitrokey use a generic DFU bootloader that reports a
version number unrelated to the version number of the runtime. Add a flag so
that we can set the correct version when switching plugins during detach and
attach.
Deduplicate based on the ID, without assuming the devices will be the same
in-memory object. Also, only emit the changed signal if the device is waiting
for a replug.
Fixes https://github.com/hughsie/fwupd/issues/364
This ensures we get progress events when replugging a device. Also, remove the
callbacks on the 'old' device to avoid causing multiple events on a 2nd-replug.
When changing from runtime->bootloader->runtime the usual way of handling this
in a fwupd plugin is to:
* reset the device and wait for a replug
* flash the hardware
* reset the device and wait for a replug
This works well when the runtime and bootloader modes are handled by the same
plugin. For situations like the Nitrokey device, where one plugin handles the
runtime (nitrokey), and another handles the bootloader (dfu) we have to have
the ability to 'ignore' the device removal and just issue a 'changed' signal
so the client refreshes the properties.
In the case where we can trigger the replug automatically we can have to wait
for a USB re-enumeration (typically a few hundred ms) but when the user is
requred to unplug, and then replug we have to wait a bit longer.
The 'remove delay' allows us to modify per-device the removal delay. In the
case the device does not show back up in the correct time the device will be
auto-removed and the session will get a DeviceRemoved signal. In the case where
the device in bootloader mode shows up within the timeout the session just gets
a DeviceChanged event.
For the duration of the delayed removal the flags for the device are set to
zero to ensure the session does not try to interact with the device whilst
re-enumerating.