udev: cancel reset if modem is already back

Cancel reset if modem is back before reset sequence is started.
When upgrading the modem through fwupd, it will enter fastboot.
Therefore, it disappears from the USB bus for a few ms.
However, the eg25-manager considers this as an issue and
resets the modem a bit later during the upgrade process.
To avoid this, cancel the reset sequence if the modem is already
back before the reset sequence is started. This will take less than 3
seconds.
This commit is contained in:
Dylan Van Assche
2021-12-20 14:07:15 +01:00
committed by Arnaud Ferraris
parent 9cf51b9529
commit 61c89a003a
3 changed files with 25 additions and 12 deletions

View File

@@ -141,7 +141,7 @@ void modem_configure(struct EG25Manager *manager)
static gboolean modem_reset_done(struct EG25Manager* manager)
{
manager->modem_state = EG25_STATE_RESUMING;
manager->reset_timer = 0;
manager->complete_reset_timer = 0;
return FALSE;
}
@@ -149,7 +149,10 @@ gboolean modem_reset(struct EG25Manager *manager)
{
int fd, ret, len;
if (manager->reset_timer) {
/* reset sequence started, cannot be canceled anymore */
manager->schedule_reset_timer = 0;
if (manager->complete_reset_timer) {
g_message("modem_reset: timer already setup, skipping...");
return G_SOURCE_REMOVE;
}
@@ -210,7 +213,7 @@ gboolean modem_reset(struct EG25Manager *manager)
* 3s is long enough to make sure the modem has been bound back and
* short enough to ensure it hasn't been acquired by ModemManager
*/
manager->reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset_done), manager);
manager->complete_reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset_done), manager);
return G_SOURCE_REMOVE;
@@ -228,7 +231,7 @@ error:
at_sequence_reset(manager);
// Setup timer for making sure we don't queue other reset commands
manager->reset_timer = g_timeout_add_seconds(30, G_SOURCE_FUNC(modem_reset_done), manager);
manager->complete_reset_timer = g_timeout_add_seconds(30, G_SOURCE_FUNC(modem_reset_done), manager);
return G_SOURCE_REMOVE;
}

View File

@@ -70,7 +70,8 @@ enum EG25Config {
struct EG25Manager {
GMainLoop *loop;
guint reset_timer;
guint complete_reset_timer;
guint schedule_reset_timer;
gboolean use_libusb;
guint usb_vid;
guint usb_pid;

View File

@@ -12,17 +12,26 @@ static void udev_event_cb(GUdevClient *client, gchar *action, GUdevDevice *devic
{
struct EG25Manager *manager = data;
if (strcmp(action, "unbind") != 0 ||
manager->modem_state == EG25_STATE_RESETTING ||
!manager->modem_usb_id) {
if (!manager->modem_usb_id)
return;
}
if (strcmp(g_udev_device_get_name(device), manager->modem_usb_id) == 0 &&
manager->reset_timer == 0) {
g_message("Lost modem, resetting...");
g_timeout_add_seconds(2, G_SOURCE_FUNC(modem_reset), manager);
strcmp(action, "add") == 0 && manager->schedule_reset_timer != 0) {
g_message("Modem recovered before reset sequence was triggered, cancel reset.");
g_source_remove(manager->schedule_reset_timer);
manager->schedule_reset_timer = 0;
return;
}
if (strcmp(action, "unbind") != 0 ||
manager->modem_state == EG25_STATE_RESETTING ||
manager->complete_reset_timer != 0 ||
strcmp(g_udev_device_get_name(device), manager->modem_usb_id) != 0) {
return;
}
g_message("Lost modem, resetting...");
manager->schedule_reset_timer = g_timeout_add_seconds(3, G_SOURCE_FUNC(modem_reset), manager);
}
void udev_init (struct EG25Manager *manager, toml_table_t *config[])