Modem creation/startup order

Aleksander Morgado aleksander at
Wed Feb 15 09:18:22 UTC 2017

On Wed, Feb 15, 2017 at 10:00 AM, Colin Helliwell
<colin.helliwell at> wrote:
>> On 14 February 2017 at 17:28 Dan Williams <dcbw at> 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> 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


More information about the ModemManager-devel mailing list