manager: make sure we don't reset the modem twice in a row

This patch adds a 3s delay when resetting the modem during which we 
avoid triggering a new reset. This makes sure we don't trigger a reset 
twice in a row.

It also disables any related running timer to avoid being re-triggered 
unnecessarily.
This commit is contained in:
Arnaud Ferraris
2020-12-18 00:45:58 +01:00
parent c39000bf93
commit 74b91c7d58
4 changed files with 34 additions and 8 deletions

View File

@@ -110,10 +110,27 @@ void modem_configure(struct EG25Manager *manager)
at_sequence_configure(manager);
}
static gboolean modem_reset_done(struct EG25Manager* manager)
{
manager->modem_state = EG25_STATE_RESUMING;
manager->reset_timer = 0;
return FALSE;
}
void modem_reset(struct EG25Manager *manager)
{
int fd, ret, len = strlen(manager->modem_usb_id);
if (manager->reset_timer)
return;
if (manager->suspend_source) {
g_source_remove(manager->suspend_source);
manager->suspend_source = 0;
}
manager->modem_state = EG25_STATE_RESETTING;
fd = open("/sys/bus/usb/drivers/usb/unbind", O_WRONLY);
if (fd < 0)
goto error;
@@ -127,16 +144,20 @@ void modem_reset(struct EG25Manager *manager)
goto error;
ret = write(fd, manager->modem_usb_id, len);
if (ret < len)
g_warning("Couldn't unbind modem: wrote %d/%d bytes", ret, len);
g_warning("Couldn't bind modem: wrote %d/%d bytes", ret, len);
close(fd);
/*
* 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);
return;
error:
// Everything else failed, reset the modem
at_sequence_reset(manager);
manager->modem_state = EG25_STATE_RESETTING;
}
void modem_suspend(struct EG25Manager *manager)

View File

@@ -26,6 +26,11 @@ enum EG25State {
struct EG25Manager {
GMainLoop *loop;
guint reset_timer;
int at_fd;
guint at_source;
GList *at_cmds;
enum EG25State modem_state;
gchar *modem_usb_id;
@@ -40,10 +45,6 @@ struct EG25Manager {
guint suspend_source;
int at_fd;
guint at_source;
GList *at_cmds;
struct gpiod_chip *gpiochip[2];
struct gpiod_line *gpio_out[5];
struct gpiod_line *gpio_in[2];

View File

@@ -35,7 +35,10 @@ static void add_modem(struct EG25Manager *manager, GDBusObject *object)
g_assert(manager->mm_modem != NULL);
if (manager->modem_state == EG25_STATE_RESUMING) {
if (manager->suspend_source) {
g_source_remove(manager->suspend_source);
manager->suspend_source = 0;
}
modem_resume_post(manager);
manager->modem_state = EG25_STATE_CONFIGURED;
}

View File

@@ -20,6 +20,7 @@
static gboolean check_modem_resume(struct EG25Manager *manager)
{
g_message("Modem wasn't probed in time, restart it!");
manager->suspend_source = 0;
modem_reset(manager);
return FALSE;