Re: Modem creation/startup order
On Thu, Feb 16, 2017 at 1:31 PM, Colin Helliwellwrote: > > I'm back on this, trying to do it properly. I've removed by mod to > mm-plugin.c, and added a udev tag > > G_MODULE_EXPORT MMPlugin * > mm_plugin_create (void) > { > static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; > static const gchar *vendor_strings[] = { "cinterion", "siemens", NULL }; > static const guint16 vendor_ids[] = { 0x1e2d, 0x0681, 0 }; > static const gchar *drivers[] = { "linmux", NULL }; > static const MMAsyncMethod custom_init = { > .async = G_CALLBACK (cinterion_custom_init), > .finish = G_CALLBACK (cinterion_custom_init_finish), > }; > static const gchar *udev_tags[] = { > "ID_MM_CINT_LINMUX", > NULL > }; > > return MM_PLUGIN ( > g_object_new (MM_TYPE_PLUGIN_CINTERION, > MM_PLUGIN_NAME, "Cinterion", > MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, > MM_PLUGIN_ALLOWED_UDEV_TAGS, udev_tags, > MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings, > MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, > MM_PLUGIN_ALLOWED_DRIVERS,drivers, > MM_PLUGIN_ALLOWED_AT, TRUE, > MM_PLUGIN_ALLOWED_QMI,TRUE, > MM_PLUGIN_CUSTOM_INIT,_init, > NULL)); > } > > i.e. I've left in, for now, the MM_PLUGIN_ALLOWED_DRIVERS/drivers additions. > ENV{ID_MM_CINT_LINMUX}="1" is added to the udev rules, and everything > reloaded. > Which puts me back to getting > [src/mm-plugin.c:251] apply_pre_probing_filters(): (Cinterion) [ttyMux1] > filtered as couldn't retrieve drivers > What would be the neatest way to address this? Does it go on if you remove the MM_PLUGIN_ALLOWED_DRIVERS check? -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 15 February 2017 at 18:04 Aleksander Morgado> wrote: > ... > > The purpose of ID_MM_PHYSDEV_UID is to have the user provide a "unique > id" which may be used as name when referencing a modem, e.g. "mmcli -m > NAME"; but that also serves the purpose of binding together ports with > the same "unique id", as the default "unique id" being used right now > is the sysfs path of the physical device (the one that owns all > ports). > OK, I've added that and now - albeit with an ugly hack because of the 'parent' issue in the driver - have the two ports on the same modem. Might try again on the driver at some later date. Thanks for guidance. ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
On Wed, Feb 15, 2017 at 4:16 PM, Colin Helliwellwrote: >> On 15 February 2017 at 15:07 Colin Helliwell >> wrote: >> >> > On 15 February 2017 at 14:11 Aleksander Morgado >> > wrote: >> > >> > Is the logic stopping there? the ID_MM_PHYSDEV_UID should take >> > precedence to whatever parent sysfs path is set, e.g. you could set >> > each tty's own sysfs path as parent sysfs path and would (should) >> > still work. >> > ... >> >> On that assumption, I've been working through the code and can see that >> mm_kernel_device_get_physdev_uid() [which points to the udev >> kernel_device_get_physdev_uid()] is indeed called by device_added(), but >> *after* mm_kernel_device_is_candidate() is called [which points to the udev >> kernel_device_is_candidate()], and which 'errors' with the above message >> from line 458. I think! >> > > Not sure of the intended purpose of ID_MM_PHYSDEV_UID but, if it's there as > an override, would it be acceptable to allow its presence to override the > if (!self->priv->physdev) { > in kernel_device_is_candidate() ? Yes, I think that would be somewhat acceptable, you could try that. The purpose of ID_MM_PHYSDEV_UID is to have the user provide a "unique id" which may be used as name when referencing a modem, e.g. "mmcli -m NAME"; but that also serves the purpose of binding together ports with the same "unique id", as the default "unique id" being used right now is the sysfs path of the physical device (the one that owns all ports). -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 15 February 2017 at 15:07 Colin Helliwell> wrote: > > > On 15 February 2017 at 14:11 Aleksander Morgado > > wrote: > > > > Is the logic stopping there? the ID_MM_PHYSDEV_UID should take > > precedence to whatever parent sysfs path is set, e.g. you could set > > each tty's own sysfs path as parent sysfs path and would (should) > > still work. > ... > > On that assumption, I've been working through the code and can see that > mm_kernel_device_get_physdev_uid() [which points to the udev > kernel_device_get_physdev_uid()] is indeed called by device_added(), but > *after* mm_kernel_device_is_candidate() is called [which points to the udev > kernel_device_is_candidate()], and which 'errors' with the above message from > line 458. I think! > Not sure of the intended purpose of ID_MM_PHYSDEV_UID but, if it's there as an override, would it be acceptable to allow its presence to override the if (!self->priv->physdev) { in kernel_device_is_candidate() ? ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 15 February 2017 at 14:11 Aleksander Morgado> wrote: > > On Wed, Feb 15, 2017 at 10:46 AM, Colin Helliwell > > wrote: > > > > > 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, _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") > > Is the logic stopping there? the ID_MM_PHYSDEV_UID should take > precedence to whatever parent sysfs path is set, e.g. you could set > each tty's own sysfs path as parent sysfs path and would (should) > still work. > H. Not fully understanding this (I'm sure drivers used to be much easier on the 2.6 kernel lol). Following Dan's reply, I'm trying to modify the driver in order to set the parent. Not sure if this is what you also mean by the "parent sysfs path", but I think you're saying that using the ID_MM_PHYSDEV_UID should/might allow it to work anyway, without the parent stuff? That would be my preference, over modifying the 3rd party driver, if it's possible. On that assumption, I've been working through the code and can see that mm_kernel_device_get_physdev_uid() [which points to the udev kernel_device_get_physdev_uid()] is indeed called by device_added(), but *after* mm_kernel_device_is_candidate() is called [which points to the udev kernel_device_is_candidate()], and which 'errors' with the above message from line 458. I think! ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
On Wed, Feb 15, 2017 at 10:46 AM, Colin Helliwellwrote: >> > 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, _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") Is the logic stopping there? the ID_MM_PHYSDEV_UID should take precedence to whatever parent sysfs path is set, e.g. you could set each tty's own sysfs path as parent sysfs path and would (should) still work. -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 15 February 2017 at 09:18 Aleksander Morgado> wrote: > > On Wed, Feb 15, 2017 at 10:00 AM, Colin Helliwell > > wrote: > > > > On 14 February 2017 at 17:28 Dan Williams wrote: > > > > > > On Tue, 2017-02-14 at 15:16 +, Colin Helliwell wrote: > > > > > > > > On 14 February 2017 at 12:59 Aleksander Morgado > > > > 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/ 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/pci:00/: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(>port, > > > tty_drv, minor, >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 > > > ">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, _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")
Re: Modem creation/startup order
On Wed, Feb 15, 2017 at 10:00 AM, Colin Helliwellwrote: >> On 14 February 2017 at 17:28 Dan Williams wrote: >> >> On Tue, 2017-02-14 at 15:16 +, Colin Helliwell wrote: >> >> > > On 14 February 2017 at 12:59 Aleksander Morgado > > > 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/ 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/pci:00/: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(>port, >> tty_drv, minor, >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 >> ">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, _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. -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 14 February 2017 at 17:28 Dan Williamswrote: > > On Tue, 2017-02-14 at 15:16 +, Colin Helliwell wrote: > > > > On 14 February 2017 at 12:59 Aleksander Morgado > > 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/ 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/pci:00/: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(>port, > tty_drv, minor, >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 > ">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, _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!) ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
On Tue, 2017-02-14 at 15:16 +, Colin Helliwell wrote: > > On 14 February 2017 at 12:59 Aleksander Morgado> der.es> wrote: > > > > On Tue, Feb 14, 2017 at 12:54 PM, Colin Helliwell > > > > ... > > > > Yes, the idea is that both ports end up grabbed in the same > > > > modem. How > > > > are these ports exposed by the kernel? Not via the usb > > > > subsystem it > > > > seems? MM needs a way to find a common "physical device sysfs > > > > path" > > > > for both ttys. > > > > > > Indeed, not via USB but via my mux driver sitting on a plain > > > UART. The underlying real hardware port - i.e. the common > > > physical path - is /dev/ttymxc2, or (if this is the correct type > > > of path...) I believe it's /sys/devices/soc0/soc/210.aips- > > > bus/21ec000.serial/tty/ttymxc2 > > > In terms of the mux driver itself, there's > > > /sys/bus/platform/devices/linmux/ whose 'driver' symlink is to > > > /sys/bus/platform/drivers/LinMux > > > > > > Early on in working with MM, I found I 'needed' to do some > > > modifications to get the Cinterion plugin used. Albeit, I might > > > not have done this is a good way - might have done it in a poor > > > way that's now causing a problem with dual ports (?) > > > > Yeah, likely. > > > > > diff -Nu a/src/mm-base-manager.c b/src/mm-base-manager.c > > > --- a/src/mm-base-manager.c 2017-01-17 09:20:13.872328767 + > > > +++ b/src/mm-base-manager.c 2017-01-17 09:24:27.952329995 + > > > @@ -194,6 +194,9 @@ > > > name = g_udev_device_get_name (child); > > > if (name && strncmp (name, "rfcomm", 6) == 0) > > > return g_object_ref (child); > > > > > > * /* LinMux doesn't have a parent */ > > > * if (name && strncmp (name, "ttyMux", 6) == 0) > > > * return g_object_ref (child); > > > > 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/ directory. This TTY device has a 'device' link inside it: lrwxrwxrwx. 1 root root0 Feb 14 11:06 device -> ../../../2-2:1.0 which when we "cd -P ../../../2-2:1.0" we get: /sys/devices/pci:00/:00:14.0/usb2/2-2/2-2:1.0 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. 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(>port, tty_drv, minor, >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 ">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... Hope that's useful! Dan > > I'd suggest you work on this on git master, though, because this > > code > > changed already there (e.g. with the optional udev-less backend)... > > > > OK, will do. > > ... > > > > diff -Nur a/src/mm-plugin.c b/src/mm-plugin.c > > > --- a/src/mm-plugin.c 2016-11-15 10:07:40.0 + > > > +++ b/src/mm-plugin.c 2017-01-18 11:05:16.553578652 + > > > @@ -230,12 +231,19 @@ > > > !self->priv->mbim) { > > > static const gchar *virtual_drivers [] = { "virtual", NULL }; > > > const gchar **drivers; > > > > > > *
Re: Modem creation/startup order
> On 14 February 2017 at 12:59 Aleksander Morgado> wrote: > > On Tue, Feb 14, 2017 at 12:54 PM, Colin Helliwell > ... > > > Yes, the idea is that both ports end up grabbed in the same modem. How > > > are these ports exposed by the kernel? Not via the usb subsystem it > > > seems? MM needs a way to find a common "physical device sysfs path" > > > for both ttys. > > > > Indeed, not via USB but via my mux driver sitting on a plain UART. The > > underlying real hardware port - i.e. the common physical path - is > > /dev/ttymxc2, or (if this is the correct type of path...) I believe it's > > /sys/devices/soc0/soc/210.aips-bus/21ec000.serial/tty/ttymxc2 > > In terms of the mux driver itself, there's > > /sys/bus/platform/devices/linmux/ whose 'driver' symlink is to > > /sys/bus/platform/drivers/LinMux > > > > Early on in working with MM, I found I 'needed' to do some modifications to > > get the Cinterion plugin used. Albeit, I might not have done this is a good > > way - might have done it in a poor way that's now causing a problem with > > dual ports (?) > > Yeah, likely. > > > diff -Nu a/src/mm-base-manager.c b/src/mm-base-manager.c > > --- a/src/mm-base-manager.c 2017-01-17 09:20:13.872328767 + > > +++ b/src/mm-base-manager.c 2017-01-17 09:24:27.952329995 + > > @@ -194,6 +194,9 @@ > > name = g_udev_device_get_name (child); > > if (name && strncmp (name, "rfcomm", 6) == 0) > > return g_object_ref (child); > > > > * /* LinMux doesn't have a parent */ > > * if (name && strncmp (name, "ttyMux", 6) == 0) > > * return g_object_ref (child); > > 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...? > I'd suggest you work on this on git master, though, because this code > changed already there (e.g. with the optional udev-less backend)... > OK, will do. ... > > diff -Nur a/src/mm-plugin.c b/src/mm-plugin.c > > --- a/src/mm-plugin.c 2016-11-15 10:07:40.0 + > > +++ b/src/mm-plugin.c 2017-01-18 11:05:16.553578652 + > > @@ -230,12 +231,19 @@ > > !self->priv->mbim) { > > static const gchar *virtual_drivers [] = { "virtual", NULL }; > > const gchar **drivers; > > > > * static const gchar *linmux_drivers [] = { "linmux", NULL }; > > > > /* Detect any modems accessible through the list of virtual ports */ > > drivers = (is_virtual_port (g_udev_device_get_name (port)) ? > > virtual_drivers : > > mm_device_get_drivers (device)); > > > > * force_cinterion = g_udev_device_get_property_as_boolean (port, > > "ID_MM_FORCE_CINT"); // my own custom var for udev rule > > > > * if (force_cinterion) > > * { > > * drivers = linmux_drivers; > > * } > > I'm not totally sure why you would do this. What is the benefit of > hardcoding some driver string based on a udev tag in the generic code, > just to match then the driver in the Cinterion plugin? If you want a > given plugin to use a given modem, just tag the device as you did and > enable the "udev tag filter" in the plugin > (MM_PLUGIN_ALLOWED_UDEV_TAGS). See the 'mbm' plugin for example. > Just lack of understanding :) ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 14 February 2017 at 11:33 Aleksander Morgado> wrote: > > On Tue, Feb 14, 2017 at 11:39 AM, Colin Helliwell > > wrote: > > > > > Thanks. The question arises from needing to have monitoring & URCs etc > > > > on one port of my mux driver, and ppp on the other - I need to make > > > > sure that ppp doesn't get run on the 'monitoring' port i.e. the one > > > > that gets in first with having the URCs enabled. > > > > This all makes me think I need this 'primary'/'secondary' port stuff - > > > > after all that's more or less what the mux is doing too. > > > > Perhaps I can modify Cinterion's grab_port() to flag the ports as > > > > primary/secondary? (They're /dev/ttyMux0, /dev/ttyMux1). Does this > > > > sound feasible, or is there more to the dual-portness than that? > > > > > > Just setup new Cinterion-specific udev rules to flag ports as primary > > > or secondary, as done in other plugins; e.g. > > > ID_MM_SIMTECH_PORT_TYPE_MODEM (primary+ppp) or > > > ID_MM_SIMTECH_PORT_TYPE_AUX (secondary). > > > > I've made that change in grab_port() and in the udev rules and it seems to > > be doing the flagging. But is the idea that the two [virtual] ports should > > show up as a single modem? (mmcli -L) > > If so, then I reckon I need something more somewhere - the debug is > > showing, for both ports, messages including: > > [src/mm-plugin-manager.c:979] device_context_continue(): [plugin manager] > > task 0: no more ports to probe > > [src/mm-device.c:525] mm_device_create_modem(): Creating modem with plugin > > 'Cinterion' and '1' ports > > [plugins/cinterion/mm-plugin-cinterion.c:175] grab_port(): (tty/ttyMux0)' > > Port flagged as primary {or PPP on the other} > > [src/mm-base-modem.c:280] mm_base_modem_grab_port(): (ttyMux0) type 'at' > > claimed by /sys/devices/virtual/tty/ttyMux0 > > [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) > > tty/ttyMux0 at (primary) > > [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) > > tty/ttyMux0 data (primary) > > Yes, the idea is that both ports end up grabbed in the same modem. How > are these ports exposed by the kernel? Not via the usb subsystem it > seems? MM needs a way to find a common "physical device sysfs path" > for both ttys. > Indeed, not via USB but via my mux driver sitting on a plain UART. The underlying real hardware port - i.e. the common physical path - is /dev/ttymxc2, or (if this is the correct type of path...) I believe it's /sys/devices/soc0/soc/210.aips-bus/21ec000.serial/tty/ttymxc2 In terms of the mux driver itself, there's /sys/bus/platform/devices/linmux/ whose 'driver' symlink is to /sys/bus/platform/drivers/LinMux Early on in working with MM, I found I 'needed' to do some modifications to get the Cinterion plugin used. Albeit, I might not have done this is a good way - might have done it in a poor way that's now causing a problem with dual ports (?) diff -Nu a/src/mm-base-manager.c b/src/mm-base-manager.c --- a/src/mm-base-manager.c 2017-01-17 09:20:13.872328767 + +++ b/src/mm-base-manager.c 2017-01-17 09:24:27.952329995 + @@ -194,6 +194,9 @@ name = g_udev_device_get_name (child); if (name && strncmp (name, "rfcomm", 6) == 0) return g_object_ref (child); +/* LinMux doesn't have a parent */ +if (name && strncmp (name, "ttyMux", 6) == 0) +return g_object_ref (child); iter = g_object_ref (child); while (iter && i++ < 8) { diff -Nur a/plugins/cinterion/mm-plugin-cinterion.c b/plugins/cinterion/mm-plugin-cinterion.c --- a/plugins/cinterion/mm-plugin-cinterion.c 2016-11-15 10:07:40.0 + +++ b/plugins/cinterion/mm-plugin-cinterion.c 2017-01-18 10:00:30.0 + @@ -203,6 +203,7 @@ static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; static const gchar *vendor_strings[] = { "cinterion", "siemens", NULL }; static const guint16 vendor_ids[] = { 0x1e2d, 0x0681, 0 }; +static const gchar *drivers[] = { "linmux", NULL }; static const MMAsyncMethod custom_init = { .async = G_CALLBACK (cinterion_custom_init), .finish = G_CALLBACK (cinterion_custom_init_finish), @@ -214,6 +215,7 @@ MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings, MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, + MM_PLUGIN_ALLOWED_DRIVERS,drivers, MM_PLUGIN_ALLOWED_AT, TRUE, MM_PLUGIN_ALLOWED_QMI,TRUE, MM_PLUGIN_CUSTOM_INIT,_init, diff -Nur a/src/mm-plugin.c b/src/mm-plugin.c --- a/src/mm-plugin.c 2016-11-15 10:07:40.0 + +++ b/src/mm-plugin.c 2017-01-18 11:05:16.553578652 + @@ -200,6 +200,7 @@ gboolean product_filtered = FALSE;
Re: Modem creation/startup order
On Tue, Feb 14, 2017 at 11:39 AM, Colin Helliwellwrote: >> > Thanks. The question arises from needing to have monitoring & URCs etc on >> > one port of my mux driver, and ppp on the other - I need to make sure that >> > ppp doesn't get run on the 'monitoring' port i.e. the one that gets in >> > first with having the URCs enabled. >> > This all makes me think I need this 'primary'/'secondary' port stuff - >> > after all that's more or less what the mux is doing too. >> > Perhaps I can modify Cinterion's grab_port() to flag the ports as >> > primary/secondary? (They're /dev/ttyMux0, /dev/ttyMux1). Does this sound >> > feasible, or is there more to the dual-portness than that? >> >> Just setup new Cinterion-specific udev rules to flag ports as primary >> or secondary, as done in other plugins; e.g. >> ID_MM_SIMTECH_PORT_TYPE_MODEM (primary+ppp) or >> ID_MM_SIMTECH_PORT_TYPE_AUX (secondary). >> > > I've made that change in grab_port() and in the udev rules and it seems to be > doing the flagging. But is the idea that the two [virtual] ports should show > up as a single modem? (mmcli -L) > If so, then I reckon I need something more somewhere - the debug is showing, > for both ports, messages including: > [src/mm-plugin-manager.c:979] device_context_continue(): [plugin manager] > task 0: no more ports to probe > [src/mm-device.c:525] mm_device_create_modem(): Creating modem with plugin > 'Cinterion' and '1' ports > [plugins/cinterion/mm-plugin-cinterion.c:175] grab_port(): (tty/ttyMux0)' > Port flagged as primary {or PPP on the other} > [src/mm-base-modem.c:280] mm_base_modem_grab_port(): (ttyMux0) type 'at' > claimed by /sys/devices/virtual/tty/ttyMux0 > [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) > tty/ttyMux0 at (primary) > [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) > tty/ttyMux0 data (primary) Yes, the idea is that both ports end up grabbed in the same modem. How are these ports exposed by the kernel? Not via the usb subsystem it seems? MM needs a way to find a common "physical device sysfs path" for both ttys. -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 13 February 2017 at 13:40 Aleksander Morgado> wrote: > > On Mon, Feb 13, 2017 at 2:05 PM, Colin Helliwell > > wrote: > > > > > Thanks. The question arises from needing to have monitoring & URCs etc on > > one port of my mux driver, and ppp on the other - I need to make sure that > > ppp doesn't get run on the 'monitoring' port i.e. the one that gets in > > first with having the URCs enabled. > > This all makes me think I need this 'primary'/'secondary' port stuff - > > after all that's more or less what the mux is doing too. > > Perhaps I can modify Cinterion's grab_port() to flag the ports as > > primary/secondary? (They're /dev/ttyMux0, /dev/ttyMux1). Does this sound > > feasible, or is there more to the dual-portness than that? > > Just setup new Cinterion-specific udev rules to flag ports as primary > or secondary, as done in other plugins; e.g. > ID_MM_SIMTECH_PORT_TYPE_MODEM (primary+ppp) or > ID_MM_SIMTECH_PORT_TYPE_AUX (secondary). > I've made that change in grab_port() and in the udev rules and it seems to be doing the flagging. But is the idea that the two [virtual] ports should show up as a single modem? (mmcli -L) If so, then I reckon I need something more somewhere - the debug is showing, for both ports, messages including: [src/mm-plugin-manager.c:979] device_context_continue(): [plugin manager] task 0: no more ports to probe [src/mm-device.c:525] mm_device_create_modem(): Creating modem with plugin 'Cinterion' and '1' ports [plugins/cinterion/mm-plugin-cinterion.c:175] grab_port(): (tty/ttyMux0)' Port flagged as primary {or PPP on the other} [src/mm-base-modem.c:280] mm_base_modem_grab_port(): (ttyMux0) type 'at' claimed by /sys/devices/virtual/tty/ttyMux0 [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) tty/ttyMux0 at (primary) [src/mm-base-modem.c:864] log_port(): (/sys/devices/virtual/tty/ttyMux0) tty/ttyMux0 data (primary) ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
On Mon, Feb 13, 2017 at 2:05 PM, Colin Helliwellwrote: >> > I’ve got two ports whitelisted for use by MM. What determines which one of >> > them will be ‘Modem/0’ ? >> >> Just the first modem that finishes first probing all ports. >> >> > Is there a way to get MM to create/initialise 0 first, then 1 – as opposed >> > to doing both in *parallel*? >> >> Nope, no way, they will be done in parallel. Note, though, that you >> can "name" modems or refer to them directly using the physical device >> USB path, which won't change across reboots: >> https://sigquit.wordpress.com/2016/10/06/naming-devices-in-modemmanager/ >> > > Thanks. The question arises from needing to have monitoring & URCs etc on one > port of my mux driver, and ppp on the other - I need to make sure that ppp > doesn't get run on the 'monitoring' port i.e. the one that gets in first with > having the URCs enabled. > This all makes me think I need this 'primary'/'secondary' port stuff - after > all that's more or less what the mux is doing too. > Perhaps I can modify Cinterion's grab_port() to flag the ports as > primary/secondary? (They're /dev/ttyMux0, /dev/ttyMux1). Does this sound > feasible, or is there more to the dual-portness than that? Just setup new Cinterion-specific udev rules to flag ports as primary or secondary, as done in other plugins; e.g. ID_MM_SIMTECH_PORT_TYPE_MODEM (primary+ppp) or ID_MM_SIMTECH_PORT_TYPE_AUX (secondary). -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
> On 10 February 2017 at 17:47 Aleksander Morgado> wrote: > > On Fri, Feb 10, 2017 at 3:39 PM, wrote: > > > I’ve got two ports whitelisted for use by MM. What determines which one of > > them will be ‘Modem/0’ ? > > Just the first modem that finishes first probing all ports. > > > Is there a way to get MM to create/initialise 0 first, then 1 – as opposed > > to doing both in *parallel*? > > Nope, no way, they will be done in parallel. Note, though, that you > can "name" modems or refer to them directly using the physical device > USB path, which won't change across reboots: > https://sigquit.wordpress.com/2016/10/06/naming-devices-in-modemmanager/ > Thanks. The question arises from needing to have monitoring & URCs etc on one port of my mux driver, and ppp on the other - I need to make sure that ppp doesn't get run on the 'monitoring' port i.e. the one that gets in first with having the URCs enabled. This all makes me think I need this 'primary'/'secondary' port stuff - after all that's more or less what the mux is doing too. Perhaps I can modify Cinterion's grab_port() to flag the ports as primary/secondary? (They're /dev/ttyMux0, /dev/ttyMux1). Does this sound feasible, or is there more to the dual-portness than that? > > > > > > > I’m getting MM to use the Cinterion plugin for my modem, by adding > > > > ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_VENDOR_ID}="0x1e2d", > > ENV{ID_MODEL_ID}="0x0001” > > > > to the udev rule (the port is a tty); together with mods to the plugin code, > > to set its MM_PLUGIN_ALLOWED_DRIVERS to the modem’s driver name. > > > > However it’s also deciding to also try 3 other plugins (as well as Generic) > > – Via, Iridium, Nokia. It’s not a major problem because it does try > > Cinterion first, and decide it’s the best one. But why the other candidates? > > The plugin that has a VID:PID list and matches the VID:PID of your > modem will always be tested first. The additional plugins are plugins > that support RAW RS232 devices; i.e. plugins where in addition to a > VID:PID list we also do AT queries to load vendor and product strings, > and we match against them. Think of a RS232 modem behind a USB > adapter, there is no VID:PID match possible there, but the plugins > still query the modem to decide which is the best plugin. > > -- > Aleksander > https://aleksander.es > > ___ > ModemManager-devel mailing list > ModemManager-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Re: Modem creation/startup order
On Fri, Feb 10, 2017 at 3:39 PM,wrote: > I’ve got two ports whitelisted for use by MM. What determines which one of > them will be ‘Modem/0’ ? > Just the first modem that finishes first probing all ports. > Is there a way to get MM to create/initialise 0 first, then 1 – as opposed > to doing both in *parallel*? > Nope, no way, they will be done in parallel. Note, though, that you can "name" modems or refer to them directly using the physical device USB path, which won't change across reboots: https://sigquit.wordpress.com/2016/10/06/naming-devices-in-modemmanager/ > > > I’m getting MM to use the Cinterion plugin for my modem, by adding > > ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_VENDOR_ID}="0x1e2d", > ENV{ID_MODEL_ID}="0x0001” > > to the udev rule (the port is a tty); together with mods to the plugin code, > to set its MM_PLUGIN_ALLOWED_DRIVERS to the modem’s driver name. > > However it’s also deciding to also try 3 other plugins (as well as Generic) > – Via, Iridium, Nokia. It’s not a major problem because it does try > Cinterion first, and decide it’s the best one. But why the other candidates? The plugin that has a VID:PID list and matches the VID:PID of your modem will always be tested first. The additional plugins are plugins that support RAW RS232 devices; i.e. plugins where in addition to a VID:PID list we also do AT queries to load vendor and product strings, and we match against them. Think of a RS232 modem behind a USB adapter, there is no VID:PID match possible there, but the plugins still query the modem to decide which is the best plugin. -- Aleksander https://aleksander.es ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel
Modem creation/startup order
I've got two ports whitelisted for use by MM. What determines which one of them will be 'Modem/0' ? Is there a way to get MM to create/initialise 0 first, then 1 - as opposed to doing both in *parallel*? I'm getting MM to use the Cinterion plugin for my modem, by adding ENV{ID_MM_PLATFORM_DRIVER_PROBE}="1", ENV{ID_VENDOR_ID}="0x1e2d", ENV{ID_MODEL_ID}="0x0001" to the udev rule (the port is a tty); together with mods to the plugin code, to set its MM_PLUGIN_ALLOWED_DRIVERS to the modem's driver name. However it's also deciding to also try 3 other plugins (as well as Generic) - Via, Iridium, Nokia. It's not a major problem because it does try Cinterion first, and decide it's the best one. But why the other candidates? ___ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel