Re: Modem Manager gets into a funny state with CDMA modems



On Wed, 2010-03-17 at 20:34 -0400, Jason Glasgow wrote:
> Dan, No problem.  I'm happy to rebuild the kernel module and I'm
> familiar with the process.)  I'm using a 2.6.31 kernel.
> 
> 
> Do you suggest that I just try removing the code below?

Nah, just put something like:

    if (tty && !C_CLOCAL(tty)) {
+       printk(KERN_INFO "%s: about to call tty_hangup!", __func__);
        tty_hangup(tty);
    }

in that if statement and lets see if that gets printed in 'dmesg' when
the problem occurs.  If not, then it's something else in the stack
that's sending the SIGHUP I think.

Dan

> 
> 
>      if (old_dcd_state && !portdata->dcd_state) {
>                                 struct tty_struct *tty =
> 
>  tty_port_tty_get(&port->port);
>                                 if (tty && !C_CLOCAL(tty))
>                                         tty_hangup(tty);
>                                 tty_kref_put(tty);
>                         }
> 
> 
> -Jason
> 
> 
> On Wed, Mar 17, 2010 at 8:04 PM, Dan Williams <dcbw redhat com> wrote:
>         On Wed, 2010-03-17 at 17:48 -0400, Jason Glasgow wrote:
>         > Dan,
>         > I tried the patch below, but it had no effect.
>         
>         
>         Are you comfortable with rebuilding a single kernel driver
>         (don't need
>         to do the whole kernel)?  If so, we could put some code into
>         the
>         'option' driver to see if the tty_hangup() call in
>         option_instat_callback() is causing your problem or not.  It's
>         actually
>         pretty easy, if you have the option.c file and kernel headers
>         from your
>         kernel version.  If you're not familiar with the process I can
>         give you
>         some tips.
>         
>         
>         Dan
>         
>         > -Jason
>         >
>         >
>         >
>         >
>         > diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c
>         >
>         >
>         > index 07010e1..0ed57f9 100644
>         >
>         >
>         > --- a/src/mm-serial-port.c
>         >
>         >
>         > +++ b/src/mm-serial-port.c
>         >
>         >
>         > @@ -358,7 +358,7 @@ config_fd (MMSerialPort *self, GError
>         **error)
>         >
>         >
>         >      stbuf.c_cc[VEOF] = 1;
>         >
>         >
>         >
>         >
>         >
>         >      stbuf.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL |
>         PARENB);
>         >
>         >
>         > -    stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity |
>         stopbits);
>         >
>         >
>         > +    stbuf.c_cflag |= (speed | bits | CREAD | 0 | parity |
>         stopbits |
>         > CLOCAL);
>         >
>         >
>         >
>         >
>         >      if (ioctl (priv->fd, TCSETA, &stbuf) < 0) {
>         >
>         >
>         >          g_set_error (error,
>         >
>         >
>         >
>         >
>         > jglasgow visitor-1950-269a-x600:modemmanager$
>         >
>         >
>         >
>         > On Mon, Mar 15, 2010 at 8:22 PM, Jason Glasgow
>         <jglasgow google com>
>         > wrote:
>         >         Sure, I'll give that a try and let you know what
>         happens.
>         >          Thanks, -Jason
>         >
>         >
>         >
>         >         On Mon, Mar 15, 2010 at 7:13 PM, Dan Williams
>         >         <dcbw redhat com> wrote:
>         >                 On Fri, 2010-03-12 at 12:50 -0500, Jason
>         Glasgow
>         >                 wrote:
>         >                 > Dan,
>         >                 >
>         >                 >
>         >                 > Novatel U760.  The modem appears to be
>         fine (not
>         >                 sure what you mean
>         >                 > drop off the bus.  If I reopen the device
>         all is
>         >                 fine).  I hacked up
>         >                 > my version of the code (mm-generic-cdma.c)
>         to always
>         >                 call
>         >                 > mm_serial_port_open() before using the
>         file
>         >                 descriptor, and it works
>         >                 > great.  But I don't think this is a good
>         solution.
>         >
>         >
>         >                 It looks like this device actually cares
>         about DCD
>         >                 state, or at least
>         >                 it's sending messages that make 'option'
>         think it
>         >                 does.  Can you try
>         >                 adding CLOCAL to the c_cflags in
>         mm-serial-port.c's
>         >                 config_fd()
>         >                 function?  Just logical OR it together with
>         the rest
>         >                 of the flags there
>         >                 and let us know if that helps things.
>         >
>         >                 I've been meaning to add CLOCAL for a while,
>         since for
>         >                 most 3G modems
>         >                 the control lines are completely ignored by
>         either the
>         >                 driver or the
>         >                 device anyway, but I've shied away from it
>         because
>         >                 it's a change that
>         >                 could potentially break stuff that I have no
>         way to
>         >                 test.  There's a lot
>         >                 of odd hardware out there.  Now that we're
>         on the
>         >                 track to MM 0.4
>         >                 though, we may want to revisit that.
>         >
>         >                 Dan
>         >
>         >
>         >                 >
>         >                 > -Jason
>         >                 >
>         >                 >
>         >                 > diff --git a/src/mm-generic-cdma.c
>         >                 b/src/mm-generic-cdma.c
>         >                 > index 50cd86c..7f44775 100644
>         >                 > --- a/src/mm-generic-cdma.c
>         >                 > +++ b/src/mm-generic-cdma.c
>         >                 > @@ -598,6 +598,10 @@ connect (MMModem
>         *modem,
>         >                 >
>         >                 >      info = mm_callback_info_new (modem,
>         callback,
>         >                 user_data);
>         >                 >      command = g_strconcat ("DT", number,
>         NULL);
>         >                 > +    if (!mm_serial_port_open
>         (priv->primary,
>         >                 &info->error)) {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 >      mm_serial_port_queue_command
>         (priv->primary,
>         >                 command, 90,
>         >                 > dial_done, info);
>         >                 >      g_free (command);
>         >                 >  }
>         >                 > @@ -620,7 +624,9 @@ disconnect_flash_done
>         >                 (MMSerialPort *port,
>         >                 >
>         >                  MM_MODEM_STATE_REASON_NONE);
>         >                 >          }
>         >                 >      } else {
>         >                 > -        mm_port_set_connected
>         >                 (MM_GENERIC_CDMA_GET_PRIVATE
>         >                 > (info->modem)->data, FALSE);
>         >                 > +        MMGenericCdmaPrivate *priv =
>         >                 MM_GENERIC_CDMA_GET_PRIVATE
>         >                 > (info->modem);
>         >                 > +
>         >                 > +        mm_port_set_connected
>         (priv->data, FALSE);
>         >                 >          update_enabled_state
>         (MM_GENERIC_CDMA
>         >                 (info->modem), FALSE,
>         >                 > MM_MODEM_STATE_REASON_NONE);
>         >                 >      }
>         >                 >
>         >                 > @@ -753,6 +759,10 @@ get_card_info
>         (MMModem *modem,
>         >                 >          port = priv->secondary;
>         >                 >      }
>         >                 >
>         >                 > +    if (!mm_serial_port_open (port,
>         &info->error))
>         >                 {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 >      mm_serial_port_queue_command_cached
>         (port,
>         >                 "+GMI", 3,
>         >                 > get_manufacturer_done, info);
>         >                 >      mm_serial_port_queue_command_cached
>         (port,
>         >                 "+GMM", 3,
>         >                 > get_model_done, info);
>         >                 >      mm_serial_port_queue_command_cached
>         (port,
>         >                 "+GMR", 3,
>         >                 > get_version_done, info);
>         >                 > @@ -867,6 +877,10 @@ get_signal_quality
>         (MMModemCdma
>         >                 *modem,
>         >                 >      }
>         >                 >
>         >                 >      info = mm_callback_info_uint_new
>         (MM_MODEM
>         >                 (modem), callback,
>         >                 > user_data);
>         >                 > +    if (!mm_serial_port_open (port,
>         &info->error))
>         >                 {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 >      mm_serial_port_queue_command (port,
>         "+CSQ", 3,
>         >                 > get_signal_quality_done, info);
>         >                 >  }
>         >                 >
>         >                 > @@ -913,6 +927,10 @@ get_esn (MMModemCdma
>         *modem,
>         >                 >      }
>         >                 >
>         >                 >      info = mm_callback_info_string_new
>         (MM_MODEM
>         >                 (modem), callback,
>         >                 > user_data);
>         >                 > +    if (!mm_serial_port_open (port,
>         &info->error))
>         >                 {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 >      mm_serial_port_queue_command_cached
>         (port,
>         >                 "+GSN", 3,
>         >                 > get_string_done, info);
>         >                 >  }
>         >                 >
>         >                 > @@ -1136,6 +1154,11 @@ get_serving_system
>         >                 (MMModemCdma *modem,
>         >                 >
>          G_CALLBACK
>         >                 (callback),
>         >                 >
>          user_data);
>         >                 >
>         >                 > +    if (!mm_serial_port_open (port,
>         &info->error))
>         >                 {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 > +
>         >                 >      mm_serial_port_queue_command (port,
>         "+CSS?", 3,
>         >                 > serving_system_done, info);
>         >                 >  }
>         >                 >
>         >                 > @@ -1380,6 +1403,12 @@
>         get_registration_state
>         >                 (MMModemCdma *modem,
>         >                 >      }
>         >                 >
>         >                 >      info =
>         >
>         mm_generic_cdma_query_reg_state_callback_info_new
>         >                 > (MM_GENERIC_CDMA (modem), callback,
>         user_data);
>         >                 > +
>         >                 > +    if (!mm_serial_port_open (port,
>         &info->error))
>         >                 {
>         >                 > +        g_assert (info->error);
>         >                 > +        /* TODO(jglasgow): what should we
>         do? */
>         >                 > +    }
>         >                 > +
>         >                 >      mm_serial_port_queue_command (port,
>         "+CAD?", 3,
>         >                 > get_analog_digital_done, info);
>         >                 >  }
>         >                 >
>         >                 > On Thu, Mar 11, 2010 at 6:46 PM, Dan
>         Williams
>         >                 <dcbw redhat com> wrote:
>         >                 >         On Wed, 2010-03-10 at 18:03 -0500,
>         Jason
>         >                 Glasgow wrote:
>         >                 >         > I've been working with a Novatel
>         Modem on
>         >                 a 2.6.31 kernel
>         >                 >         using the
>         >                 >         > generic CDMA driver.   If I
>         enable the
>         >                 modem via
>         >                 >         ModemManager and then
>         >                 >         > connect, everything works fine.
>          But if I
>         >                 disconnect the
>         >                 >         modem using
>         >                 >         > the DBUS API, and shut down ppp,
>         >                 ModemManager gets
>         >                 >         confused.  The
>         >                 >         > internal modem state indicates
>         that the
>         >                 modem is now
>         >                 >         REGISTERED, but
>         >                 >         > the kernel appears to have sent
>         a hangup
>         >                 (G_IO_HUP) to the
>         >                 >         usb port,
>         >                 >         > so mm-serial-port.c has closed
>         the port
>         >                 (->fd == -1).
>         >                 >
>         >                 >
>         >                 >         Does the modem crash at that
>         point, or drop
>         >                 off the bus?  This
>         >                 >         may
>         >                 >         indicate a USB driver problem or
>         just a bug
>         >                 in ModemManager.
>         >                 >          But
>         >                 >         normally with serial ports, when
>         you get a
>         >                 hangup, you're
>         >                 >         done.
>         >                 >
>         >                 >         Also, what specific novatel
>         device?
>         >                 >
>         >                 >         Dan
>         >                 >
>         >                 >         >
>         >                 >         > Other than Disable(), no command
>         works
>         >                 because the ->fd is
>         >                 >         now -1.
>         >                 >         >
>         >                 >         >
>         >                 >         > Do you have any thoughts on the
>         best way
>         >                 to fix this?  And
>         >                 >         what the
>         >                 >         > semantics of receiving a HUP on
>         the modem
>         >                 port should be.
>         >                 >          My thought
>         >                 >         > is that disconnect() should
>         leave the
>         >                 modem in a registered
>         >                 >         (or
>         >                 >         > enabled) state, and that fp
>         should still
>         >                 be valid.
>         >                 >         >       * Might it be reasonable
>         to ignore
>         >                 the G_IO_HUP?
>         >                 >         >       * Should we automatically
>         reopen
>         >                 then port for all
>         >                 >         commands that
>         >                 >         >         are issued?  Seems like
>         a bad
>         >                 idea.
>         >                 >         >       * Should we automatically
>         reopen the
>         >                 port if
>         >                 >         >         mm_modem_get_state() >
>         >                 MM_MODEM_STATE_ENABLED?
>         >                 >         >       * Maybe the most logical
>         is to have
>         >                 G_IO_HUP invoke a
>         >                 >         callback
>         >                 >         >         to notify the code that
>         originally
>         >                 opened the serial
>         >                 >         port that
>         >                 >         >         it has been closed.  It
>         then can
>         >                 update the state of
>         >                 >         the modem
>         >                 >         >         appropriately.
>         >                 >         > Thanks for your thoughts,
>         >                 >         > Jason
>         >                 >
>         
>         
>         
> 
> 




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]