diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-01-02 11:59:42 +0100 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2020-01-06 20:46:06 +0000 |
commit | fbc1e3f89e89ba980417a77df8987425a654ec55 (patch) | |
tree | efeec9036e6ec9e1627aafd303520ced443ee545 /src/mm-device.c | |
parent | 941879b43af4848b444fd299ec18fb4d92729642 (diff) |
device: don't reprobe if device is gone
When a QMI/MBIM device is unplugged, we first get the notification
from the proxy that the communication is broken, and then we get the
kernel event reporting that the cdc-wdm port is gone.
If we reprobe the device as soon as the proxy notifies us that the
communication is broken, we would end up trying to reprobe the cdc-wdm
port when it's already gone, and we end up trying to create a modem
object when we shouldn't:
<debug> [1577963152.429386] (ttyUSB0) unexpected port hangup!
<debug> [1577963152.429506] (ttyUSB0) forced to close port
<debug> [1577963152.429546] (ttyUSB0) device open count is 0 (close)
<debug> [1577963152.429582] (ttyUSB0) closing serial port...
<debug> [1577963152.429653] (ttyUSB0) serial port closed
<debug> [1577963152.430340] (ttyUSB2) unexpected port hangup!
<debug> [1577963152.430391] (ttyUSB2) forced to close port
<debug> [1577963152.430418] (ttyUSB2) device open count is 0 (close)
<debug> [1577963152.430451] (ttyUSB2) closing serial port...
<debug> [1577963152.430517] (ttyUSB2) serial port closed
<info> [1577963152.436932] (tty/ttyUSB0): released by device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
<info> [1577963152.439176] (tty/ttyUSB1): released by device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
<info> [1577963152.440409] (tty/ttyUSB2): released by device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
<info> [1577963152.447977] (net/wwan1): released by device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
Cannot read from istream: connection broken
<info> [1577963152.458878] Connection to qmi-proxy for /dev/cdc-wdm1 lost, reprobing
<debug> [1577963152.459144] [device /sys/devices/pci0000:00/0000:00:14.0/usb2/2-3] unexported modem from path '/org/freedesktop/ModemManager1/Modem/1'
<debug> [1577963152.460151] (ttyUSB1) forced to close port
<info> [1577963152.460182] [device /sys/devices/pci0000:00/0000:00:14.0/usb2/2-3] creating modem with plugin 'Sierra' and '1' ports
<debug> [1577963152.460199] QMI-powered Sierra modem found...
<debug> [1577963152.460382] (cdc-wdm1) type 'qmi' claimed by /sys/devices/pci0000:00/0000:00:14.0/usb2/2-3
<debug> [1577963152.460417] Modem (Sierra) '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3' completely disposed
<warn> [1577963152.460431] Could not recreate modem for device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3': Failed to find a net port in the QMI modem
<debug> [1577963152.460526] Modem (Sierra) '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3' completely disposed
<info> [1577963152.460627] (usbmisc/cdc-wdm1): released by device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
<debug> [1577963152.460666] Removing empty device '/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3'
Fix this by delaying the reprobing attempt some time, and make sure we
cancel the reprobing if the device detects that all ports are gone.
Diffstat (limited to 'src/mm-device.c')
-rw-r--r-- | src/mm-device.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/mm-device.c b/src/mm-device.c index 55c51186..86baf7c7 100644 --- a/src/mm-device.c +++ b/src/mm-device.c @@ -86,6 +86,9 @@ struct _MMDevicePrivate { /* Virtual ports */ gchar **virtual_ports; + + /* Scheduled reprobe */ + guint reprobe_id; }; /*****************************************************************************/ @@ -327,6 +330,24 @@ mm_device_remove_modem (MMDevice *self) /*****************************************************************************/ +#define REPROBE_SECS 2 + +static gboolean +reprobe (MMDevice *self) +{ + GError *error = NULL; + + if (!mm_device_create_modem (self, &error)) { + mm_warn ("Could not recreate modem for device '%s': %s", + self->priv->uid, + error ? error->message : "unknown"); + g_error_free (error); + } else + mm_dbg ("Modem recreated for device '%s'", self->priv->uid); + + return G_SOURCE_REMOVE; +} + static void modem_valid (MMBaseModem *modem, GParamSpec *pspec, @@ -335,19 +356,8 @@ modem_valid (MMBaseModem *modem, if (!mm_base_modem_get_valid (modem)) { /* Modem no longer valid */ mm_device_remove_modem (self); - - if (mm_base_modem_get_reprobe (modem)) { - GError *error = NULL; - - if (!mm_device_create_modem (self, &error)) { - mm_warn ("Could not recreate modem for device '%s': %s", - self->priv->uid, - error ? error->message : "unknown"); - g_error_free (error); - } else { - mm_dbg ("Modem recreated for device '%s'", self->priv->uid); - } - } + if (mm_base_modem_get_reprobe (modem)) + self->priv->reprobe_id = g_timeout_add_seconds (REPROBE_SECS, (GSourceFunc)reprobe, self); } else { /* Modem now valid, export it, but only if we really have it around. * It may happen that the initialization sequence fails because the @@ -734,6 +744,10 @@ dispose (GObject *object) { MMDevice *self = MM_DEVICE (object); + if (self->priv->reprobe_id) { + g_source_remove (self->priv->reprobe_id); + self->priv->reprobe_id = 0; + } g_clear_object (&(self->priv->object_manager)); g_clear_object (&(self->priv->plugin)); g_list_free_full (self->priv->port_probes, g_object_unref); |