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.
This commit is contained in:

committed by
Dan Williams

parent
941879b43a
commit
fbc1e3f89e
@@ -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);
|
||||
|
Reference in New Issue
Block a user