Asking the user for the UID mapping isn't working very well, as it requires lots
of manual handholding. It also doesn't work very well when the device vendor
does not actually have a PCI ID or if the vendor has split into two entities.
Just use the OUI address as an additional VendorID and match any of the device
IDs against any of the metadata-supplied values.
Rather than using a recursive GMainLoop, just run a single iteration of the
mainloop every 1ms while we're waiting.
This simplifies the device lifecycle dramatically as we don't have to worry
about reentrant removals. It's also a lot simpler to debug as we know the only
way to return is the timeout elapsing or FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG being
unset.
If multiple devices got removed and we're waiting for one to re-appear, also
wait for all devices to come back before returning to the main loop.
In the worst case, this causes the device list to wait the full removal_delay
for the device rather than returning when the first device matches. This allows
us to simplify the hub update when we reboot the entire device and various
devices from different plugins come back in an unpredictable order.
Fixes the other half of https://github.com/fwupd/fwupd/issues/2376
If we wait for the child of a composite device to reappear and *then* go on to
update the replugged parent in the same transaction then we still use the old
GUsbDevice as the add event is still pending when we quit the replug loop.
Just schedule an idle action to quit the loop to allow the child *and* parent
to be added on replug.
Fixes https://github.com/fwupd/fwupd/issues/2376
If the device parent is added using fu_device_add_parent_guid() or ParentGuid
from a quirk file then the child is not returned in fu_device_get_children() by
design as the physical ID will be likely different.
This means we cannot reliably 'depsolve' the order in FuDevice as we need the
full list of devices that might be parents. The existing algorithm had several
logical problems when dealing with more than a single parent and child.
The FuDeviceList object is the right place to do this as it knows about all
added devices on the system.
This means the addition of a logical device causes the root logical device
(and all it's children, and grandchildren) to be re-ordered. This allows
firmware on deeply nested composite devices like hubs to be installed in the
correct order.
This means we do not do the GUID or counterpart GUID matching when adding
devices. Only an exact device-id match or when both the physical and logical
IDs match will the device be considered the 'same'.
This is to handle devices that could share the same GUIDs in both child and
parent modes where the logical ID differs.
Some plugins are just simple wrappers around custom GType creators and which
specific plugin created is not a good way to make a policy decision.
If this was added to work around a bug, we need to find a better solution or
fix the root cause.
We add the child devices using fu_plugin_device_add() so we have to remove them
the same way. The original fix is wrong, as it leaves child devices when the
parent is removed.
This reverts commit 02b588c035.
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.