Modem creation/startup order

Colin Helliwell colin.helliwell at ln-systems.com
Wed Feb 15 09:46:41 UTC 2017


> On 15 February 2017 at 09:18 Aleksander Morgado <aleksander at aleksander.es> wrote:
> 
> On Wed, Feb 15, 2017 at 10:00 AM, Colin Helliwell
> 
> <colin.helliwell at ln-systems.com> wrote:
> 
> > > On 14 February 2017 at 17:28 Dan Williams <dcbw at redhat.com> wrote:
> > > 
> > > On Tue, 2017-02-14 at 15:16 +0000, Colin Helliwell wrote:
> > > 
> > > > > On 14 February 2017 at 12:59 Aleksander Morgado <aleksander at aleksan der.es> wrote:
> > > > > 
> > > > > This is it. You're saying here that the "physical device" that owns
> > > > > this port is the port device itself. And for each TTY exposed in
> > > > > the
> > > > > same way, the same will happen, so none of the TTYs will share a
> > > > > parent physical device object. You need a way to return a common
> > > > > object for all your TTYs.
> > > > 
> > > > Any tips on how to get started with that...?
> > > 
> > > Your modem is obviously hardware, somewhere down the line. Your mux
> > > driver binds to that hardware, so it clearly knows what the parent
> > > hardware is. Ideally your mux driver can expose that in sysfs with a
> > > 'device' symlink that points back to the physical device.
> > > 
> > > For example, a USB modem that uses CDC-ACM exposes:
> > > 
> > > /sys/class/tty/ttyACM0
> > > 
> > > your mux driver (if it uses the kernel's TTY layer) will also have a
> > > /sys/class/tty/XXXX directory.
> > > 
> > > This TTY device has a 'device' link inside it:
> > > 
> > > lrwxrwxrwx. 1 root root 0 Feb 14 11:06 device -> ../../../2-2:1.0
> > > 
> > > which when we "cd -P ../../../2-2:1.0" we get:
> > > 
> > > /sys/devices/pci0000:00/0000:00:14.0/usb2/2-2/2-2:1.0
> > 
> > Yep, as you'd imagine from my lack of parent found, there is node 'device' link in the /sys/class/tty/ttyMuxN directory.
> > 
> > > which is what ModemManager actually uses to figure out which TTYs are
> > > part of the same mode. It's a very similar process for other bus types
> > > too, as long as they are hotpluggable (like USB, PCI, PCMCIA, etc).
> > > Now if it's an embedded serial UART or something, it gets a bit more
> > > dicey.
> > 
> > Yes, it's an on-chip serial UART
> > 
> > > But your MUX driver should have some way to bind the physical device
> > > unless this is like MUX-over-UDP to a remote modem. Typically the
> > > driver gets a "kobject" (really "struct device") it can use from the
> > > kernel in its bind() function. For example, in the 'hso' driver:
> > > 
> > > ttydev = tty_port_register_device_attr(&serial->port,
> > >  tty_drv, minor, &serial->parent->interface->dev,
> > >  serial->parent, hso_serial_dev_groups);
> > > 
> > > where the args are:
> > > 
> > > /**
> > > 
> > > *   tty_port_register_device_attr - register tty device
> > > *   @port: tty_port of the device
> > > *   @driver: tty_driver for this device
> > > *   @index: index of the tty
> > > *   @device: parent if exists, otherwise NULL
> > > *   @drvdata: Driver data to be set to device.
> > > *   @attr_grp: Attribute group to be set on device.
> > > 
> > > notice the @device parameter, which in the case of 'hso' is passed as
> > > "&serial->parent->interface->dev" which is the 'struct device' of the
> > > USB interface this TTY is getting created for. The kernel copies that
> > > into the tty's 'parent' pointer, and that eventually ends up in sysfs
> > > as the /sys/class/tty/ttyXXX/device link.
> > > 
> > > So apologies if you know all this already... but if you're not passing
> > > the 'struct device' from the hardware you got in your MUXs bind()
> > > routine (or whatever actually calls the mux) to the kernel when
> > > creating your TTY, you probably should be...
> > 
> > Trying to examine 'my' mux driver to figure out how to do that. It's not actually mine, it's from Gemalto (Cinterion) - so not easy.
> > I get the feeling its written with nearly-but-not-quite up to date methods, or just different ones. Certainly it's not easy to compare against USB-based drivers. From what I can make out, the three virtual ports are created with calls such as:
> >  pDriver = alloc_tty_driver()
> >  tty_set_operations(pDriver, &if_mux_ops) [after setting termios etc in pDriver, and *not* using TTY_DRIVER_DYNAMIC_DEV]
> >  tty_register_driver(pDriver)
> > if_mux_ops.install is a function which mallocs a struct tty_struct and then just tty_port_init(tty->port)
> > All in all, hard to correlate against other drivers to identify where to bind to the physical device :S
> > (Appreciate this isn't entirely a MM issue!)
> 
> Could you add udev rules for the two TTYs that you want to bind in the
> same device and set the same ID_MM_PHYSDEV_UID udev tag for both? IIRC
> that should also work even if the physical device paths stored are
> different.
> 

Given that a try, but I think there's still the key problem that the TTY's physical device isn't being set?  ("[src/kerneldevice/mm-kernel-device-udev.c:458] kernel_device_is_candidate(): (tty/ttyMux0): could not get port's parent device")


More information about the ModemManager-devel mailing list