Commit Graph

79 Commits

Author SHA1 Message Date
Richard Hughes
566f8e27c2 Do not check wait_removed as multiple devices can be WAIT_FOR_REPLUG
This makes devices that come back in bootloader mode with no children
timeout, which is bad UX. We don't even need the feature now that we
can WAIT_FOR_REPLUG on multiple devices now.
2021-08-31 12:47:46 +01:00
Mario Limonciello
55de39c077 trivial: reformat the whole tree to match new format 2021-08-24 11:18:40 -05:00
Richard Hughes
944ba87b59 Set the update state and error in more cases
If we swap from runtime -> bootloader -> runtime we need to copy the
update state in each step even if we're just switching the swapping the
runtime device.

This regressed, as we optimized away the call to fu_device_list_replace.
2021-07-30 16:35:24 +01:00
Richard Hughes
640a3dbfb8 trivial: Add some more debugging when failing the wait-for-replug 2021-07-29 14:04:05 +01:00
Richard Hughes
9a4997e42b trivial: Always clear timeout when replacing in the devicelist 2021-07-13 09:31:53 +01:00
Richard Hughes
6578fb13e7 trivial: Add some sanity checks to the device list 2021-07-12 23:17:03 -05:00
Richard Hughes
73b9f8bd53 Allow multiple devices to set WAIT_FOR_REPLUG
This also means we no longer pass in just one device to the
fu_device_list_wait_for_replug() function, but we rather wait for *all*
of the active devices.

This also cleans up the confusion on whether the engine should wait for
the 'root' device or the child device as either (or both) can be set as
required.

This makes the replug far more predictable for devices that have
children even in bootloader mode.
2021-07-12 19:02:19 +01:00
Richard Hughes
f89cb3850b Add a device flag to control child removal
At the moment the device list auto-removes children when the parent is
removed. This was originally working around the bug that the child
devices had no backend ID, and thus were not matched like the parent
in fu_engine_backend_device_removed_cb() and removed automatically.

Using the workaround means that the children are potentially removed
before the parent depending on the order of the device list -- which
might be modified by replug events.

I think the old cleanup is probably an anti-pattern, and going forward
composite devices should probably define _NO_AUTO_REMOVE_CHILDREN but
we don't want to change this behaviour for plugins already expecting
the old flow, or for devices with no parent backend IDs.
2021-07-09 19:46:41 +01:00
Richard Hughes
24eec8c533 Copy the device update state when replugging
At the moment we saving the new state as 'unknown' which explains why
we're getting so few LVFS reports uploaded for USB devices that perform
a replug...

Tested with a ColorHug2.
2021-07-02 21:28:22 +01:00
Richard Hughes
aaa77c6f51 Allow adding and removing custom flags on devices
The CustomFlags feature is a bit of a hack where we just join the flags
and store in the device metadata section as a string. This makes it
inefficient to check if just one flag exists as we have to split the
string to a temporary array each time.

Rather than adding to the hack by splitting, appending (if not exists)
then joining again, store the flags in the plugin privdata directly.

This allows us to support negating custom properties (e.g. ~hint) and
also allows quirks to append custom values without duplicating them on
each GUID match, e.g.

[USB\VID_17EF&PID_307F]
Plugin = customflag1
[USB\VID_17EF&PID_307F&HUB_0002]
Flags = customflag2

...would result in customflag1,customflag2 which is the same as you'd
get from an enumerated device flag doing the same thing.
2021-06-23 07:59:15 +01:00
Mario Limonciello
1e17457b16 Allow building the documentation with gi-docgen and gtk-doc
Until gi-docgen is declared stable support either of them.
This effectively means that hand builds and CI builds will use
gi-docgen, but distro builds use gtk-doc-tools.
2021-06-09 22:21:53 +01:00
Richard Hughes
20ef071b3c trivial: Style fixes to lots of gtk-doc 2021-05-10 14:35:10 +01:00
Richard Hughes
89d45a0d91 trivial: Standardize on introspection for @error and @cancellable
Also standarize on `Returns:` for the result.
2021-04-28 16:19:50 +01:00
Richard Hughes
078beafb2d Add a new internal flag to opt-in to GUID matching
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
2021-02-25 15:47:25 +00:00
Richard Hughes
eddaed0c11 Allow specifying more than one VendorID for a device
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.
2021-01-04 22:30:20 +00:00
Richard Hughes
e98845d6cf Revert "Fix regression when filtering different priorities"
This reverts commit f630678b6f.
2020-10-29 14:01:25 +00:00
Richard Hughes
f630678b6f Fix regression when filtering different priorities
We need to check if the device is in the remove timeout before unconditionally
replacing a device on insert.

Fixes https://github.com/fwupd/fwupd/issues/2510
2020-10-26 08:43:27 +00:00
Richard Hughes
f2a3e01f96 Simplify fu_device_list_wait_for_replug() for sanity
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
2020-10-18 07:35:46 +01:00
Richard Hughes
a350198f53 Quit the replug loop on idle
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
2020-09-29 13:43:45 +01:00
Richard Hughes
1d633a58fe trivial: Show the device GType when deduping
This allows us to make sense of the case where the same plugin has multiple
possible GTypes.
2020-09-14 16:19:45 +01:00
Richard Hughes
81f9552095 Correctly order devices when using logical parents
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.
2020-09-14 10:13:33 -05:00
Benson Leung
8b9f9ab47a Save custom flags on device replace
New instances of a device may be interested in custom flags. Copy them
over on fu_device_list_replace.

fixes #2298
2020-08-03 18:02:43 +01:00
Richard Hughes
aae22e4df5 trivial: Always clear the mutex before clearing the thing it protects 2020-06-22 21:55:50 +01:00
Richard Hughes
86ae91c144 Add a device quirk that forces an explicit device-id match
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.
2020-04-17 21:48:59 +01:00
Richard Hughes
a89a70cc24 trivial: Do not set the device parent when already set to the client
This can happen if the devices swap roles, and if the parent is set as itself
then fwupdmgr refuses to show the child device.
2020-04-16 18:01:20 +01:00
Richard Hughes
327621beef trivial: Remove double call to g_source_remove()
The fu_device_list_replace() function does this automatically.
2020-04-16 08:50:12 -05:00
Richard Hughes
9c1829bf36 trivial: Allow plugins to add the same physical device with different priorities
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.
2020-04-15 14:11:06 +01:00
Richard Hughes
f6b4d92dae Revert "Fix a crash when removing device parents"
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.
2020-04-09 15:46:41 +01:00
Richard Hughes
6c0e3d4efa Do not crash the daemon if a plugin does something dumb
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.
2020-04-08 17:40:08 +01:00
Richard Hughes
02b588c035 Fix a crash when removing device parents
This was missed for the conversion of 1e571730d0
2020-04-08 15:29:12 +01:00
Richard Hughes
cddf5b5b89 Only auto-add counterpart GUIDs when required
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.
2020-04-08 13:55:39 +01:00
Richard Hughes
949af578ea Fix devices that use CounterpartGuid when more than one device is installed
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.
2020-04-07 14:44:06 +01:00
Richard Hughes
66dc7362e8 Use the GUID as a fallback rather than the connection ID
Prefer a removed device with the same physical and logitcal connection than a
GUID fallback.
2020-04-07 14:44:06 +01:00
Richard Hughes
2c9445281a Fix a difficult-to-trigger daemon hang when replugging devices
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.
2020-03-17 13:02:54 +00:00
Richard Hughes
1e571730d0 Fix a daemon crash when removing children
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.
2020-03-10 17:09:13 +00:00
Richard Hughes
f50ff2c27e Decouple the version format from the version itself
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.
2020-02-25 14:00:09 +00:00
Mario Limonciello
99eb3f06b6 fu-device-list: Check protocol before de-duping devices
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.
2020-02-21 14:39:06 -06:00
Mario Limonciello
e1b4d8ebcd Add a new device flag for indicating device won't come back
Devices like this can't be verified that the version was updated
until they're manually put into the correct mode by the user.
2019-10-12 14:07:34 -05:00
Mario Limonciello
da55c48b7d Remove replug flag after the device comes back from reboot
This prevents errors like this from happening:

```
failed to get device after update: failed to wait for detach replug: device did not come back
```
2019-08-28 09:24:31 +01:00
Richard Hughes
161e9b531b Use the newer features of GRWLock rather than reinventing it
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.
2019-06-12 15:20:27 +01:00
Richard Hughes
5079f26f0e Never guess the version format from the version string
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
2019-04-30 09:25:41 +01:00
Richard Hughes
dce91204c9 Fix some typos spotted using codespell 2019-04-08 12:47:53 +01:00
Richard Hughes
5297678d3c Allow a plugin to set _ANOTHER_WRITE_REQUIRED to run more than one plugin
For this to work with different plugins the device IDs must match.
2019-02-04 14:54:54 +00:00
Richard Hughes
58bf3674e9 trivial: Show a critical warning rather than crashing
Found when constructing devices manually in the self tests, it's not possible
to hit this during normal runtime.
2018-10-02 11:03:12 +01:00
Mario Limonciello
8a45acb806 fu-device-list: Use delayed device removal when removing the tree
If a parent device being removed causes child devices to be removed,
take into account all of the delays for children.
2018-09-27 09:18:31 -05:00
Mario Limonciello
ccd5fd0088 trivial: device-list: Correct a minor logic error
If one of the child devices has gone away, this potentially will
cause the daemon to segfault while accessing it.
2018-09-26 07:56:12 -05:00
Richard Hughes
37d0943844 Add FuMutex helper to make various parts of the daemon thread-safe 2018-09-12 16:10:38 +01:00
Richard Hughes
5a9a6bd479 trivial: Return reference counted devices from FuDeviceList 2018-09-12 16:10:38 +01:00
Richard Hughes
b08e7bc7aa trivial: Set a log domain for each file
This allows us to do something like:

G_MESSAGES_DEBUG=FuEngine ./src/fwupd
2018-09-11 18:59:05 +01:00
Richard Hughes
841c1807e1 trivial: Copy the parent if set for the repluged device
Based on a patch from Mario Limonciello, many thanks.
2018-09-07 15:32:32 +01:00