Add support for the new kernel API for force power #245
Conversation
I've only got single controller configurations available to me. Here are the tests I've done so far:
Those both work correct for me in my tests. I still need to test that the update stuff works properly. |
g_list_free (devices); | ||
|
||
if (built_path) | ||
return g_strdup (built_path); |
ybernat
Sep 12, 2017
Contributor
g_steal_pointer() maybe?
g_steal_pointer() maybe?
ybernat
Sep 12, 2017
Contributor
IIUC, we don't need the if
in this case
IIUC, we don't need the if
in this case
superm1
Sep 12, 2017
Author
Collaborator
Yep, using that thanks!
Yep, using that thanks!
"force_power", NULL); | ||
if (g_file_test (built_path, G_FILE_TEST_IS_REGULAR)) | ||
break; | ||
built_path = NULL; |
ybernat
Sep 12, 2017
Contributor
Is this triggers the free from g_autofree
? I assume not. So an explicit g_free()
is needed here.
Maybe you want to have a local g_autofree
instead and if the path test succeeded to find the file, g_steal_pointer()
it to the outer pointer.
Is this triggers the free from g_autofree
? I assume not. So an explicit g_free()
is needed here.
Maybe you want to have a local g_autofree
instead and if the path test succeeded to find the file, g_steal_pointer()
it to the outer pointer.
hughsie
Sep 12, 2017
Collaborator
I also think this is a confusing function. Maybe we could just use G_DEFINE_AUTOPTR_CLEANUP_FUNC
to define a function that frees the list and unrefs the contents. Then you could just do g_steal_pointer (&built_path)
in the exists case and rely on the autofree otherwise.
I also think this is a confusing function. Maybe we could just use G_DEFINE_AUTOPTR_CLEANUP_FUNC
to define a function that frees the list and unrefs the contents. Then you could just do g_steal_pointer (&built_path)
in the exists case and rely on the autofree otherwise.
superm1
Sep 12, 2017
Author
Collaborator
Take a look what I did in the commit I just pushed. I think this should be clearer and take care of the potential memory leak.
Take a look what I did in the commit I just pushed. I think this should be clearer and take care of the potential memory leak.
devices = g_udev_client_query_by_subsystem (data->udev, "wmi"); | ||
for (GList *l = devices; l != NULL; l = l->next) { | ||
GUdevDevice *device = l->data; | ||
basepath = g_udev_device_get_sysfs_path (device); |
ybernat
Sep 12, 2017
Contributor
Do we need to check for NULL
here?
Do we need to check for NULL
here?
hughsie
Sep 12, 2017
Collaborator
g_strcmp0 does that, it's the 0
bit at the end :)
g_strcmp0 does that, it's the 0
bit at the end :)
ybernat
Sep 12, 2017
Contributor
Not sure I understood your comment. If g_build_path
gets basepath
which is NULL
, will it return an empty path or "/"
?
If the latter, the g_file_test
will succeed but for the wrong path.
Not sure I understood your comment. If g_build_path
gets basepath
which is NULL
, will it return an empty path or "/"
?
If the latter, the g_file_test
will succeed but for the wrong path.
superm1
Sep 12, 2017
Author
Collaborator
I think may as well add an extra guard to this to test for NULL. The glib documentation isn't very clear about what happens in the case of a null string (only an empty one).
I think may as well add an extra guard to this to test for NULL. The glib documentation isn't very clear about what happens in the case of a null string (only an empty one).
if (enable) | ||
ret = write (fd, "1", 1); | ||
else | ||
ret = write (fd, "0", 1); |
ybernat
Sep 12, 2017
Contributor
or ret = write (fd, enable ? "1" : "0", 1);
Really a matter of taste.
or ret = write (fd, enable ? "1" : "0", 1);
Really a matter of taste.
hughsie
Sep 12, 2017
Collaborator
I prefer the trigraph too.
I prefer the trigraph too.
superm1
Sep 12, 2017
Author
Collaborator
Adjusted
Adjusted
g_io_error_from_errno (errno), | ||
"could not write to force_power': %s", | ||
g_strerror (errno)); | ||
g_close (fd, error); |
ybernat
Sep 12, 2017
Contributor
NULL
instead of error
as error
is already set?
NULL
instead of error
as error
is already set?
hughsie
Sep 12, 2017
Collaborator
Agree
Agree
superm1
Sep 12, 2017
Author
Collaborator
Adjusted
Adjusted
@@ -729,6 +817,13 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) | |||
fu_plugin_thunderbolt_add (plugin, device); | |||
} | |||
|
|||
if (g_list_length (devices) == 0) { | |||
fu_plugin_thunderbolt_set_force_power (plugin, TRUE, error); |
ybernat
Sep 12, 2017
Contributor
Check for error?
Check for error?
superm1
Sep 12, 2017
Author
Collaborator
Adjusted (in coldplug of new plugin)
Adjusted (in coldplug of new plugin)
devpath); | ||
return FALSE; | ||
if (fu_plugin_thunderbolt_can_force_power (plugin)) { | ||
fu_plugin_thunderbolt_set_force_power (plugin, TRUE, error); |
ybernat
Sep 12, 2017
Contributor
Check for error?
Check for error?
superm1
Sep 12, 2017
Author
Collaborator
Checked in new plugin
Checked in new plugin
|
||
if (udevice == NULL) { | ||
if (force_powered) | ||
fu_plugin_thunderbolt_set_force_power (plugin, FALSE, error); |
ybernat
Sep 12, 2017
Contributor
Check for error? Especially as it can fail the next set error.
Check for error? Especially as it can fail the next set error.
superm1
Sep 12, 2017
Author
Collaborator
Checked in new plugin
Checked in new plugin
I don't think there is a multiple-controller configuration available right now besides things like Mac Pro (which this work isn't relevant to, as much as I understand). |
@@ -326,13 +325,12 @@ fu_dell_toggle_flash (FuDevice *device, GError **error, gboolean enable) | |||
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_UPDATABLE)) | |||
return TRUE; | |||
tmp = fu_device_get_plugin (device); | |||
if (!((g_strcmp0 (tmp, "thunderbolt") == 0) || |
hughsie
Sep 12, 2017
Collaborator
What happens if we're using new fwupd on an old kernel?
What happens if we're using new fwupd on an old kernel?
superm1
Sep 12, 2017
Author
Collaborator
I keep going back and forth on this. The way the dell plugin works to force power is too unconditional and does't fit in the safely designed logic used here. I'd like to have the dell plugin to fall back upon if possible. If I do come up with a way to split this up to thunderbolt/thunderbolt-power with an intra-plugin API I'll retrofit the Dell plugin the same way instead.
I keep going back and forth on this. The way the dell plugin works to force power is too unconditional and does't fit in the safely designed logic used here. I'd like to have the dell plugin to fall back upon if possible. If I do come up with a way to split this up to thunderbolt/thunderbolt-power with an intra-plugin API I'll retrofit the Dell plugin the same way instead.
superm1
Sep 12, 2017
Author
Collaborator
Since all of the (smarter) logic around when to force power and when not to lives in thunderbolt-power, what do you think about #ifdef(HAVE_DELL) in the new plugin to allow a fallback?
Otherwise I think the the way to go is some sort of inter-plugin API with thunderbolt <-thunderbolt-power-> dell and duplicating most of the logic in thunderbolt-power in the dell plugin too.
Since all of the (smarter) logic around when to force power and when not to lives in thunderbolt-power, what do you think about #ifdef(HAVE_DELL) in the new plugin to allow a fallback?
Otherwise I think the the way to go is some sort of inter-plugin API with thunderbolt <-thunderbolt-power-> dell and duplicating most of the logic in thunderbolt-power in the dell plugin too.
hughsie
Sep 12, 2017
Collaborator
I'd much rather avoid HAVE_DELL
if at all possible. What would you need to duplicate? I was under the impression that the dell plugin would be doing less, not more...
I'd much rather avoid HAVE_DELL
if at all possible. What would you need to duplicate? I was under the impression that the dell plugin would be doing less, not more...
hughsie
Sep 12, 2017
Collaborator
Wild idea: could you use the new CONFLICTS
thing and split out a dell_legacy plugin that does the tbt force power stuff on old kernels? Maybe we're just okay with requiring a new kernel for thunderbolt flashing things to work, but I've also got a neuron wired to the RHEL process too.
Wild idea: could you use the new CONFLICTS
thing and split out a dell_legacy plugin that does the tbt force power stuff on old kernels? Maybe we're just okay with requiring a new kernel for thunderbolt flashing things to work, but I've also got a neuron wired to the RHEL process too.
superm1
Sep 12, 2017
Author
Collaborator
Well the dell plugin really should have been following this approach (only power on when it's needed to rather than all the time). I'm leaning on since you need a new kernel for thunderbolt flashing, one newer kernel version for thunderbolt at bootup working right, what's one newer one for thunderbolt force power?
Fedora & Ubuntu will quickly pick up a new kernel.
I think with RHEL the driver is contained enough that it should be backportable.
I'm gonna go with kill the TBT force power from Dell plugin and say require this kernel interface instead.
Well the dell plugin really should have been following this approach (only power on when it's needed to rather than all the time). I'm leaning on since you need a new kernel for thunderbolt flashing, one newer kernel version for thunderbolt at bootup working right, what's one newer one for thunderbolt force power?
Fedora & Ubuntu will quickly pick up a new kernel.
I think with RHEL the driver is contained enough that it should be backportable.
I'm gonna go with kill the TBT force power from Dell plugin and say require this kernel interface instead.
hughsie
Sep 12, 2017
Collaborator
Works for me.
Works for me.
|
||
path = fu_plugin_thunderbolt_get_force_power_path (plugin); | ||
if (path == NULL) { | ||
return FALSE; |
hughsie
Sep 12, 2017
Collaborator
If we're returning FALSE we need to set a GError.
If we're returning FALSE we need to set a GError.
superm1
Sep 12, 2017
Author
Collaborator
In the way this commit was done this didn't work well (since it was an implicit test for support). In the new plugin approach I moved this over to have an explicit test for support and set the GError in this path.
In the way this commit was done this didn't work well (since it was an implicit test for support). In the new plugin approach I moved this over to have an explicit test for support and set the GError in this path.
|
||
/* resets force power to disabled on g_timeout */ | ||
static gboolean | ||
fu_plugin_thunderbolt_reset_force_power (gpointer data) |
hughsie
Sep 12, 2017
Collaborator
If this is a callback, the convention I've used elsewhere is ending the function name with _cb
.
If this is a callback, the convention I've used elsewhere is ending the function name with _cb
.
superm1
Sep 12, 2017
Author
Collaborator
Adjusted
Adjusted
static gboolean | ||
fu_plugin_thunderbolt_reset_force_power (gpointer data) | ||
{ | ||
fu_plugin_thunderbolt_set_force_power ((FuPlugin *) data, FALSE, NULL); |
hughsie
Sep 12, 2017
Collaborator
Not FU_PLUGIN()
? That way you get a typecheck.
Not FU_PLUGIN()
? That way you get a typecheck.
hughsie
Sep 12, 2017
Collaborator
You also probably want to g_warning
the error too.
You also probably want to g_warning
the error too.
superm1
Sep 12, 2017
Author
Collaborator
Added both.
Added both.
On a more general note, would it be clearer to move all this functionality to a new plugin, perhaps |
Yes and no. The set of logic that we discussed to make this work is very prescriptive about when to force power and it's not unconditional. It will require some thought how to map to the existing intra-plugin API.
|
Are the registered callbacks not fired on coldplug? If we could guarantee the thunderbolt plugin was coldplugged before thunderbolt-power (i.e. we enforce a plugin order), would that work? |
Oh I think I see what you mean. Rather than look for the registered callback, look for the lack of a registered callback. If plugin order is enforced and no callback has come through the thunderbolt-power plugin will know to run during it's coldplug routine. |
Exactly that. I can have a go at defining plugin deps, it'll be very similar for what I did in gnome-software. |
That would be great. I'll retrofit this over to a new plugin and apply all your guys' comments. Thanks! |
Would #247 do? |
|
||
devices = g_udev_client_query_by_subsystem (data->udev, "wmi"); | ||
for (GList* l = devices; l != NULL; l = l->next) { | ||
g_autoptr(GUdevDevice) device = l->data; |
hughsie
Sep 12, 2017
Collaborator
that works too! :)
that works too! :)
hughsie
Sep 12, 2017
Collaborator
Nope, forget that, it doesn't work. If you break out of thefor
early the remaining GUdevDevice's are not unref'd.
Nope, forget that, it doesn't work. If you break out of thefor
early the remaining GUdevDevice's are not unref'd.
"failed to open %s", path); | ||
return FALSE; | ||
} | ||
ret = write (fd, enable ? "1" : "0", 1); |
hughsie
Sep 12, 2017
Collaborator
spaces?
spaces?
superm1
Sep 12, 2017
Author
Collaborator
Ah that's what I get for copying and pasting from you guys. My editor didn't fixup, I'll fix in another commit.
Ah that's what I get for copying and pasting from you guys. My editor didn't fixup, I'll fix in another commit.
b06ae1d
to
fa5d5c8
OK so other than what to do with the old Dell way to do this, this passes all my unit tests (including flashing an update with nothing plugged in). |
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) | ||
#endif | ||
|
||
#define TBT_NEW_DEVICE_TIMEOUT 2 |
hughsie
Sep 12, 2017
Collaborator
maybe a comment explaining what unit this number is, and what it means?
maybe a comment explaining what unit this number is, and what it means?
superm1
Sep 12, 2017
Author
Collaborator
Added
Added
fu_plugin_thunderbolt_power_supported (FuPlugin *plugin) | ||
{ | ||
g_autofree gchar *path = NULL; | ||
path = fu_plugin_thunderbolt_power_get_path (plugin); |
hughsie
Sep 12, 2017
Collaborator
I thought the idea was to move the path to the plugin FuPluginData
struct?
I thought the idea was to move the path to the plugin FuPluginData
struct?
superm1
Sep 12, 2017
Author
Collaborator
Ah right, I forgot about that. Adjusted it, by doing that no longer store a boolean object and calculate the path every usage.
Ah right, I forgot about that. Adjusted it, by doing that no longer store a boolean object and calculate the path every usage.
} | ||
|
||
/* driver went away */ | ||
if (data->force_path) |
ybernat
Sep 12, 2017
Contributor
I'm not sure I get it.
The only place this is set is line 72 above and then we don't reach this.
If this is from a previous run of this method, then line 72 need to g_free
force_path
before assigning to it.
I'm not sure I get it.
The only place this is set is line 72 above and then we don't reach this.
If this is from a previous run of this method, then line 72 need to g_free
force_path
before assigning to it.
superm1
Sep 12, 2017
Author
Collaborator
There's two ways to enter the function:
- plugin initialization
- intel-wmi-thunderbolt module change event
If you initialize with the module loaded this gets set during init, and then you unload the module it needs to be unset when it's called again. If the module gets loaded again, you would have another change event and it would get set again.
If you initialize without the module loaded this hasn't yet been set. You load the module and it gets set. If you unload again it needs to get unset.
There's two ways to enter the function:
- plugin initialization
- intel-wmi-thunderbolt module change event
If you initialize with the module loaded this gets set during init, and then you unload the module it needs to be unset when it's called again. If the module gets loaded again, you would have another change event and it would get set again.
If you initialize without the module loaded this hasn't yet been set. You load the module and it gets set. If you unload again it needs to get unset.
ybernat
Sep 12, 2017
Contributor
I still think it's better to move this before the loop, otherwise, if the module generates change event for any other reason (or got removed and reloaded before this had a chance to run) there is still a leak.
I still think it's better to move this before the loop, otherwise, if the module generates change event for any other reason (or got removed and reloaded before this had a chance to run) there is still a leak.
superm1
Sep 12, 2017
Author
Collaborator
That's true. I'll move it.
That's true. I'll move it.
"force_power", NULL); | ||
if (g_file_test (built_path, G_FILE_TEST_IS_REGULAR)) { | ||
data->force_path = g_steal_pointer (&built_path); | ||
return; |
ybernat
Sep 12, 2017
Contributor
And then what with the rest of the devices in the list? Leak?
And then what with the rest of the devices in the list? Leak?
superm1
Sep 12, 2017
Author
Collaborator
The rest of the devices should free automatically from g_autofree and g_autoptr usage. I adjusted the scope for the g_autofree to be within the for loop. It should free when the for loop is exited (and function exited).
The rest of the devices should free automatically from g_autofree and g_autoptr usage. I adjusted the scope for the g_autofree to be within the for loop. It should free when the for loop is exited (and function exited).
ybernat
Sep 12, 2017
Contributor
devices
, the list itself, has g_autoptr
guard, but here we are talking about each of the l->data
inside it. If freeing the list frees the inside pointers too, the issue is much worse where it auto free device
on each iteration without setting the original l->data
to NULL
.
devices
, the list itself, has g_autoptr
guard, but here we are talking about each of the l->data
inside it. If freeing the list frees the inside pointers too, the issue is much worse where it auto free device
on each iteration without setting the original l->data
to NULL
.
superm1
Sep 12, 2017
Author
Collaborator
Oh I think I finally understand you. Good eye with this.
g_object_unref
needs to be called on every element in devices. If the for loop bails early this won't happen.
I had this right before calling g_list_foreach
previously and convinced myself that wasn't needed.
Oh I think I finally understand you. Good eye with this.
g_object_unref
needs to be called on every element in devices. If the for loop bails early this won't happen.
I had this right before calling g_list_foreach
previously and convinced myself that wasn't needed.
This is replaced by the WMI force power interface.
18fda40
to
9573ed0
{ | ||
if (!fu_plugin_thunderbolt_power_set (FU_PLUGIN (data), FALSE, NULL)) | ||
g_warning ("failed to reset thunderbolt power"); | ||
return FALSE; |
ybernat
Sep 12, 2017
Contributor
Always FALSE
? I'd think always TRUE
if it must return anything or using the result of set
.
Always FALSE
? I'd think always TRUE
if it must return anything or using the result of set
.
superm1
Sep 12, 2017
Author
Collaborator
For the g_timeout
to go away on the reset callback you have to return FALSE
. It's for g_timeout
's to call repeatedly on an interval instead of just once when you return TRUE
.
For the g_timeout
to go away on the reset callback you have to return FALSE
. It's for g_timeout
's to call repeatedly on an interval instead of just once when you return TRUE
.
ybernat
Sep 12, 2017
Contributor
Oh, sorry. Next time I'll look it up myself before asking...
Thanks!
Oh, sorry. Next time I'll look it up myself before asking...
Thanks!
hughsie
Sep 12, 2017
Collaborator
Note, you can use G_SOURCE_REMOVE
which makes it a bit clearer in this kind of situation. I'm bad at using it myself.
Note, you can use G_SOURCE_REMOVE
which makes it a bit clearer in this kind of situation. I'm bad at using it myself.
if (g_str_equal (action, "change")) { | ||
fu_plugin_thunderbolt_power_get_path (plugin); | ||
fu_plugin_set_enabled (plugin, TRUE); | ||
fu_plugin_recoldplug (plugin); |
ybernat
Sep 12, 2017
Contributor
And Dell-force-power plugin will be disabled by this?
And Dell-force-power plugin will be disabled by this?
superm1
Sep 12, 2017
Author
Collaborator
Currently; yes. I'd like to find a way to have it fall back to Dell interface (my preference if #ifdef (HAVE_DELL) and code living in this plugin), but thinking about ways to let the 3 plugins work together.
The dell approach should really follow the exact same logic we discussed for this (only force powering on when it needs to - not every time).
Currently; yes. I'd like to find a way to have it fall back to Dell interface (my preference if #ifdef (HAVE_DELL) and code living in this plugin), but thinking about ways to let the 3 plugins work together.
The dell approach should really follow the exact same logic we discussed for this (only force powering on when it needs to - not every time).
hughsie
Sep 12, 2017
Collaborator
Can't the existing dell plugin just do the "dumb" algorithm like it's doing now?
Can't the existing dell plugin just do the "dumb" algorithm like it's doing now?
41888dc
to
95f1c9b
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GUdevDevice, g_object_unref) | ||
#endif | ||
|
||
/* empirically mesaured amount of time for the TBT device to come and go */ |
hughsie
Sep 12, 2017
Collaborator
sp: mesaured, also need to specify it's seconds somewhere. I think in other places of the code it just has TIMEOUT 2 /* s */
sp: mesaured, also need to specify it's seconds somewhere. I think in other places of the code it just has TIMEOUT 2 /* s */
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
|
||
/* in case driver went away */ | ||
if (data->force_path != NULL) | ||
g_free (data->force_path); |
hughsie
Sep 12, 2017
Collaborator
you need to do data->force_path = NULL
as well I think otherwise you're pointing to free'd memory if the list below doesn't match.
you need to do data->force_path = NULL
as well I think otherwise you're pointing to free'd memory if the list below doesn't match.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
fu_plugin_thunderbolt_power_supported (FuPlugin *plugin) | ||
{ | ||
FuPluginData *data = fu_plugin_get_data (plugin); | ||
return (data->force_path != NULL); |
hughsie
Sep 12, 2017
Collaborator
No brackets reqd.
No brackets reqd.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
FuPluginData *data = fu_plugin_get_data (plugin); | ||
g_object_unref (data->udev); | ||
if (data->force_path) | ||
g_free (data->force_path); |
hughsie
Sep 12, 2017
Collaborator
you don't need the if
here, g_free(NULL)
is explicitly okay.
you don't need the if
here, g_free(NULL)
is explicitly okay.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
if (g_strcmp0 (fu_device_get_plugin (device), "thunderbolt") == 0 && | ||
fu_plugin_thunderbolt_power_supported (plugin)) { | ||
if (data->needs_forcepower) | ||
data->needs_forcepower = FALSE; |
hughsie
Sep 12, 2017
Collaborator
Does it need the if here? All paths lead to FALSE
, right?
Does it need the if here? All paths lead to FALSE
, right?
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
return FALSE; | ||
|
||
data->needs_forcepower = TRUE; | ||
g_usleep (TBT_NEW_DEVICE_TIMEOUT * G_USEC_PER_SEC); |
hughsie
Sep 12, 2017
Collaborator
Can you add a comment here explaining why the sleep is required please.
Can you add a comment here explaining why the sleep is required please.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
|
||
if (data->needs_forcepower && | ||
!fu_plugin_thunderbolt_power_set (plugin, FALSE, error)) | ||
return FALSE; |
hughsie
Sep 12, 2017
Collaborator
Weird indent here.
Weird indent here.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
if (data->needs_forcepower) { | ||
if (!fu_plugin_thunderbolt_power_set (plugin, TRUE, error)) | ||
return FALSE; | ||
g_timeout_add (TBT_NEW_DEVICE_TIMEOUT * 10000, |
hughsie
Sep 12, 2017
Collaborator
No saving the return value here worries me a bit. I think it might be safer to do data->timeout_id = g_timeout_add(
and then in destroy do if (data->timeout_id != 0) g_source_remove (data->timeout_id)
-- this way if we unload the plugin after doing coldplug but before doing the callback we don't explode. I think you might also need to do the g_source_remove
thing in this function too for the recoldplug stuff too.
No saving the return value here worries me a bit. I think it might be safer to do data->timeout_id = g_timeout_add(
and then in destroy do if (data->timeout_id != 0) g_source_remove (data->timeout_id)
-- this way if we unload the plugin after doing coldplug but before doing the callback we don't explode. I think you might also need to do the g_source_remove
thing in this function too for the recoldplug stuff too.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
@@ -0,0 +1,19 @@ | |||
cargs = ['-DG_LOG_DOMAIN="FuPluginThunderboltpower"'] |
hughsie
Sep 12, 2017
Collaborator
Probably FuPluginThunderboltPower
for convention here.
Probably FuPluginThunderboltPower
for convention here.
superm1
Sep 12, 2017
Author
Collaborator
Fixed
Fixed
/* intel-wmi-thunderbolt has been loaded/unloaded */ | ||
if (g_str_equal (action, "change")) { | ||
fu_plugin_thunderbolt_power_get_path (plugin); | ||
fu_plugin_set_enabled (plugin, TRUE); |
ybernat
Sep 12, 2017
Contributor
TRUE
or only if get_path
succeeded finding it? I mean, it needs to be disabled for unload, isn't it?
TRUE
or only if get_path
succeeded finding it? I mean, it needs to be disabled for unload, isn't it?
superm1
Sep 12, 2017
Author
Collaborator
It should get disabled from the recoldplug, but you're right may as well not schedule a re-coldplug if it's not going to be supported.
It should get disabled from the recoldplug, but you're right may as well not schedule a re-coldplug if it's not going to be supported.
Once rebased, LGTM. |
When available on a system this module will allow force powering a TBT device with nothing plugged in.
2f1ce8e
to
0f821d6
OK, i'll give one more last test with recent changes and merge then. |
This is a WIP with more testing still needed. Early feedback welcome however.
It wraps around this API being introduced in kernel 4.14:
http://git.infradead.org/linux-platform-drivers-x86.git/commit/d08e3b522bdaccde031a394039b299bfd8c18492