Starting io-sock and Driver Management

QNX SDP8.0High-Performance Networking Stack (io-sock) User's GuideAPIArchitecture

You can start io-sock with or without a driver. For example:

io-sock

The io-sock command creates the following resources by default:

/dev/socket 
/dev/io-sock
/dev/pf
/dev/bpf

You can also load one or more drivers when you start io-sock. Because all io-sock drivers default to Plug and Play, you can load them without having interfaces present. For example, the following command loads the driver for PCI bus devices (mods-pci.so) and one for an Intel PRO/1000 Gigabit Ethernet adapter (devs-em.so) (devs-em.so requires mods-pci.so):

io-sock -m mods-pci.so -d devs-em.so

(A description of the driver resources that this command creates is provided below, with the command for loading a driver later.)

For x86_64 targets, which are usually not resource limited, you can choose to start all drivers (including the general drivers for Ethernet PHY, PCI bus, and USB bus devices) when you start io-sock. For example, when you use the following command, io-sock discovers all the interfaces it supports with the currently loaded drivers and creates them (you can specify a driver without the mods-* or devs-* prefix and .so extension).

io-sock -m fdt -m phy -m phy_fdt -d ffec -m pci -d em -d igc -d ix -d re -m usb \
    -d axe -d axge -d cdce -d smsc

Loading a driver after starting io-sock

You can start io-sock and load a driver later. For example, the following command starts the Intel E1000 Ethernet device driver (devs-em.so) with io-sock already running. (If the driver for PCI bus devices is not already running, start it as well.):

mount -T io-sock pci
mount -T io-sock em

This example assumes that the search path for the drivers is in LD_LIBRARY_PATH. The search path for the driver is the LD_LIBRARY_PATH that io-sock has in its environment (i.e., what it was when io-sock started, not the environment of mount).

If you do not specify the mods-* or devs-* prefix, io-sock searches for a matching devs-* driver first, then a mods-* one.

You can also provide the path explicitly. For example:

mount -T io-sock /lib/dll/devs-em.so

This command creates the following resources:

/dev/io-sock/devs-em.so
/dev/io-sock/devs-em.so/em0
/dev/io-sock/devs-em.so/em1
...
/dev/io-sock/devs-em.so/emn

where n is the number of devices found.

The filenames under the driver directory (in this example, /dev/io-sock/devs-em.so/emn) are device names, not interface names. In some cases, the directory names and the names that ifconfig displays may not match the driver name.

Use cat to see the corresponding ifconfig interface for a device. For example:

# cat /dev/io-sock/devs-em.so/em*
device=em0,interface=em0,options=""
device=em1,interface=em1,options=""

To unmount, you remove all the devices that the mount process created first. For example:

umount /dev/io-sock/devs-em.so/em0
umount /dev/io-sock/devs-em.so/em1
umount /dev/io-sock/devs-em.so/emn
...
umount /dev/io-sock/devs-em.so 

Creating and starting an alternative stack

The io-sock networking stack allows you to create multiple instances of the stack (e.g., to provide one stack for external users and one for internal use).

To create an alternative io-sock stack, use prefix=path, which specifies a path to prepend to the default stack location (e.g., /dev/socket). For example:

io-sock -o prefix=/alt -m phy -m pci

This io-sock command creates the following resources:

/alt/dev/socket
/alt/dev/io-sock
/alt/dev/pf
/alt/dev/bpf

To mount the alternative stack, match the prefix string. For example:

mount -T io-sock -o prefix=/alt devs-em.so

This command creates the following resources:

/alt/dev/io-sock/devs-em.so
/alt/dev/io-sock/devs-em.so/em0
/alt/dev/io-sock/devs-em.so/em1
...
/alt/dev/io-sock/devs-em.so/emn

where n is the number of interfaces found.

Include the prefix when you umount. For example:

umount /alt/dev/io-sock/devs-em.so/em0
umount /alt/dev/io-sock/devs-em.so/em1
umount /alt/dev/io-sock/devs-em.so/emn
...
umount /alt/dev/io-sock/devs-em.so 
Applications use one of the following methods to select the alternative stack:
  • Specify the appropriate SOCK environment variable. For example:
    • SOCK=/alt ifconfig
    • SOCK=/alt netstat -in
    • SOCK=/alt sysctl -a
    • SOCK=/alt pfctl -f /etc/pf_alt.conf
  • For each thread that uses the alternative stack, use setsockprefix() to add the appropriate prefix to the networking stack path (e.g., add the prefix alt to the default path of /dev/socket). For more information, go to the setsockprefix() entry in the QNX OS C Library Reference.
If you don't specify SOCK or a prefix, the original instance of the stack is used.

Running multiple stacks with network interface controllers of the same type

In io-sock, Plug and Play is enabled by default. With Plug and Play, an interface is automatically attached after it is inserted into the bus, provided there is a driver loaded that supports the interface.

In some cases, to run multiple instances of the stack with multiple NICs of the same type, Plug and Play should be disabled. You can then identify each interface (e.g., using the Bus:Device:Function numbers) and specify the stack it should attach to.

Depending on the type of device and how it is used, it may or may not be essential to disable Plug and Play.

PCI: Stacks connect to PCI devices via the PCI server. After it is created, the connection is exclusive, and the devices are rarely inserted and removed. With Plug and Play enabled, you can start the first stack with both NICs and umount one NIC before you start the second stack. That NIC can then be attached when starting the second stack. However, if a new device is inserted, the two stacks race to connect to it. You must disable Plug and Play if you want to control which stack connects to the device.

USB: USB devices are also connected to a stack exclusively and you can use the umount method described for multiple PCI NICs with USB NICs. However, because USB devices are inserted and removed more often, the race to connect also happens more often. You must disable Plug and Play if you want to avoid it.

OFW (Open Firmware Bus): OFW devices are not connected exclusively. Plug and Play must be disabled to work with NICs of the same type with two or more stacks. If Plug and Play is not disabled, the stacks overwrite each other’s values. This overwriting could cause the io-sock instances to crash.

Disabling Plug and Play

To disable Plug and Play, use the sysctl tunable that corresponds to the device interface type. You set the tunable either in the configuration file that is applied when you start io-sock (specified by the config option), or using sysctl. For example, to disable Plug and Play for PCI devices:

sysctl qnx.pnp.pci=0 

For more information, see the sysctl entry in the Utilities Reference.

Attaching devices to specific stacks

After creating an alternative stack (see Creating and starting an alternative stack), you need to:

  • mount the correct drivers (if they have not already been loaded)
  • indicate prefix of the desired stack, or no prefix to use the default stack
  • use the qnxdev option to identify the device to attach
mount -T io-sock -o prefix=/alt  qnxdev=pci0:0:25:0 devs-em.so

In this example, the driver is devs-em.so, stack prefix is /alt , and qnxdev string is pci0:0:25:0. The driver for PCI bus devices was started earlier, with io-sock.

Determining the qnxdev string

If io-sock is running, you can use devinfo to find the qnxdev string for your device (see Displaying device information).

If io-sock is not running, you can use server-specific tools to construct the qnxdev string.

PCI: You can construct the qnxdev string using pci-tool. From the pci-tool output, you can find the Bus:Device:Function numbers for the PCI device. For example, this is some sample output of pci-tool with the -v option:
B00:D05:F00 @ idx 0
        vid/did: 8086/7190
                Intel Corporation, 82443BX/ZX 440BX/ZX AGPset Host Bridge
        class/subclass/reg: 06/00/00
                Host-to-PCI Bridge Device
In this example, the qnxdev string is qnxdev=pci0:0:5:0. The pci0 represents the first instance of the PCI server (pci-server).
USB: You can construct the qnxdev string using usb. From the usb output, you can find the USB hub index, device address, and interface index for the USB device. For example, this is some sample output of usb -vv:
USB 0 (XHCI) v1.11, v1.01 DDK, v2.00 HCD, DLL: Active    ***This is the USB hub index ***
Device Address             : 1
Upstream Host Controller   : 0
Upstream Device Address    : 0
Upstream Port              : 4
Upstream Port Speed        : Full
Vendor                     : 0x0557
Product                    : 0x7000
Device Release             : r1.00
USB Spec Release           : v1.10
Serial Number              : N/A
Class                      : 0x09 (Hub)
Subclass                   : 0x00
Protocol                   : 0x00
Max PacketSize0            : 8
Languages                  : No string descriptors
Hub Number Ports           : 4
Hub Characteristics        : 0x0009 (Individual power, Individual over-current)
Hub Power On->Good         : 100 ms
Hub Power Requirements     : 100 mA
Configurations             : 1
  Configuration            : 1
    Attributes             : 0xe0 (Self-powered, Remote-wakeup)
    Max Power              : 100 mA
    Interfaces             : 1
      Interface            : 0 / 0
        Class              : 0x09 (Hub)
        Subclass           : 0x00
        Protocol           : 0x00            
In this example, the qnxdev string is qnxdev=iousb0:0:1:0. The iousb0 represents the first instance of the USB server (io-usb-otg).

OFW: To construct the qnxdev string, you need to specify the bus location and hardware address of the OFW device. You can get this information from the device tree blob (DTB). For example, this is some sample DTS output:

/dts-v1/;

/ {
    interrupt-parent = <0x8001>;
        #size-cells = <0x02>;
        #address-cells = <0x02>;     
        compatible = "example,dummy";     
    
    some_bus {          
        compatible = "simple-bus";         
        #address-cells = <0x02>;          
        #size-cells = <0x02>;    
        
        ethernet@1c130400 {              
            interrupts = <0x00 0x2a 0x01>;              
            reg = <0x00 0x1c130400 0x00 0x200>;             
            compatible = "net,target";          
        };      
    };      
    
    another_bus {          
        compatible = "simple-bus";     
        #address-cells = <0x02>;          
        #size-cells = <0x02>;          
        
        ethernet@1c130000 {             
            interrupts = <0x00 0x28 0x01>;             
            reg = <0x00 0x1c130000 0x00 0x200>;            
            compatible = "net,target";         
        };      
    };     
    
    intc@8000000 {          
        phandle = <0x8001>;          
        reg = <0x00 0x8000000 0x00 0x10000 0x00 0x8010000 0x00 0x10000>;          
        compatible = "arm,cortex-a15-gic";          
        ranges;          
        #size-cells = <0x02>;          
        #address-cells = <0x02>;         
        interrupt-controller;         
        #interrupt-cells = <0x03>;          
        
        v2m@8020000 {
            phandle = <0x8002>;
            reg = <0x00 0x8020000 0x00 0x1000>;
            msi-controller;
            compatible = "arm,gic-v2m-frame";
        };
     };
  };  
In this example, the qnxdev string could be ofwbus0:0x1c130400 or ofwbus1:0x1c130000.

Displaying driver information

Use ls to display which drivers are loaded. For example:

ls /dev/io-sock/
devs-axe.so        devs-cdce.so       devs-re.so
devs-axge.so       devs-em.so         mods-pci.so
mods-phy.so        mods-phy_fdt.so    mods-usb.so

Alternatively, use find. For example:

find /dev/io-sock/
/dev/io-sock/
/dev/io-sock/devs-cdce.so
/dev/io-sock/devs-axge.so
/dev/io-sock/devs-axe.so
/dev/io-sock/devs-re.so
/dev/io-sock/devs-em.so
/dev/io-sock/devs-em.so/em1
/dev/io-sock/devs-em.so/em0
/dev/io-sock/mods-pci.so
/dev/io-sock/mods-phy.so
/dev/io-sock/mods-phy_fdt.so
/dev/io-sock/mods-usb.so

Displaying device information

Use cat to retrieve information about the devices in the driver directories. For example:

cat /dev/io-sock/devs-em.so/em0
device=em0,interface=em0,options="" 

Alternatively, you can display information for the entire directory. For example:

cat /dev/io-sock/*/*
device=em0,interface=em0,options=""
device=em1,interface=em1,options=""
device=axe0,interface=axe0,options="" 

You can use devinfo to display more detailed information about devices, which is useful for attaching specific interfaces when Plug and Play is disabled. For example:

devinfo -v  
nexus0 
   pci0 
     unknown pnpinfo vendor=0x8086 device=0x153a subvendor=0x17aa subdevice=0x3097 revid=0x04 class=0x020000 at pci0:0:25:0 
     unknown pnpinfo vendor=0x8086 device=0x15d1 subvendor=0x8086 subdevice=0x0002 revid=0x01 class=0x020000 at pci0:1:0:0 
     unknown pnpinfo vendor=0x10ec device=0x8168 subvendor=0x10ec subdevice=0x0123 revid=0x06 class=0x020000 at pci0:3:0:0 
     unknown pnpinfo vendor=0x168c device=0x0013 subvendor=0x1186 subdevice=0x3a13 revid=0x01 class=0x020000 at pci0:5:0:0 
     em0 pnpinfo vendor=0x8086 device=0x105e subvendor=0x103c subdevice=0x7044 revid=0x06 class=0x020000 at pci0:6:0:0 
     em1 pnpinfo vendor=0x8086 device=0x105e subvendor=0x103c subdevice=0x7044 revid=0x06 class=0x020000 at pci0:6:0:1 
   iousb0 
     uhub0 at iousb0 (default path) 
       unknown pnpinfo vendor=0x0557 product=0x7000 class=0x09 subclass=0x00 at iousb0:0:1:0 
       unknown pnpinfo vendor=0x046d product=0xc31c class=0x00 subclass=0x00 at iousb0:0:2:0 
       unknown pnpinfo vendor=0x046d product=0xc31c class=0x00 subclass=0x00 at iousb0:0:2:1 
     uhub1 at iousb0 (default path) 
       unknown pnpinfo vendor=0x8087 product=0x8008 class=0x09 subclass=0x00 at iousb0:1:1:0 
     uhub2 at iousb0 (default path) 
       unknown pnpinfo vendor=0x8087 product=0x8000 class=0x09 subclass=0x00 at iousb0:2:1:0

Additional interface information is available using ifconfig. For example:

ifconfig 
enc0: flags=0<> metric 0 mtu 1536 
     groups: enc 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384 
     options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6> 
     inet 127.0.0.1 netmask 0xff000000 
     inet6 ::1 prefixlen 128 
     inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2 
     groups: lo 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
pfsync0: flags=0<> metric 0 mtu 1500 
     syncpeer: 0.0.0.0 maxupd: 128 defer: off 
     groups: pfsync 
pflog0: flags=0<> metric 0 mtu 33144 
     groups: pflog 
em0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 
     options=81049b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,VLAN_HWFILTER> 
     ether 00:26:55:db:1b:0e 
     media: Ethernet autoselect 
     status: no carrier 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL> 
em1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500 
     options=81049b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,VLAN_HWFILTER> 
     ether 00:26:55:db:1b:0f 
     media: Ethernet autoselect 
     status: no carrier 
     nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
Page updated: