Multiplexer example

This example illustrates how to use the PCI multiplexer APIs.

/*
 * $QNXLicenseC:
 * Copyright (c) 2024 QNX Software Systems. All Rights Reserved.
 *
 * You must obtain a written license from and pay applicable license fees to QNX
 * Software Systems before you may reproduce, modify or distribute this software,
 * or any work that includes all or part of this software. Free development
 * licenses are available for evaluation and non-commercial purposes. For more
 * information visit http://licensing.qnx.com or email licensing@qnx.com.
 *
 * This file may contain contributions from others. Please review this entire
 * file for other proprietary rights or license notices, as well as the QNX
 * Development Suite License Guide at http://licensing.qnx.com/license-guide/
 * for other information.
 * $
 */

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <sys/neutrino.h>
#include <errno.h>

#include <pci/pci_mux.h>

static pci_mux_connection_t *mux_connection;


int main( int argc, char *argv[] )
{
    char *pathname = NULL;
    int opt;
    int ret;
    unsigned int server_id = 0;
    unsigned int pindex = 0;
    uint32_t     class_code = PCIMUX_CCODE_ANY;



    while( ( opt = getopt( argc, argv, "n:s:p:c:" ) ) != -1 ) {
        switch( opt ) {
            case 'n': {
                // name of multiplexer or direct connect
                pathname = strdup( optarg );
                break;
            }

            case 's': {
                server_id = ( unsigned int ) strtoul( optarg, NULL, 0 );
                break;
            }

            case 'p': {
                pindex = ( unsigned int ) strtoul( optarg, NULL, 0 );
                break;
            }

            case 'c': {
                class_code = ( unsigned int ) strtoul( optarg, NULL, 0 );
                break;
            }

            default:
                break;
        }
    }

    if( pathname == NULL ) {
        printf( "FAIL - must specify pathname\n" );
    }

    mux_connection = pci_mux_init( pathname );

    if( mux_connection == NULL ) {
        printf( "FAIL - pci_mux_init\n" );
        return -1;
    }

    ret = pci_mux_direct_connect( mux_connection );

    if( ret != EOK ) {
        printf( "FAIL - pci_mux_direct_connect %s\n", strerror( ret )  );
        return -1;
    }

    req_device_find_t req;
    pci_mux_reply_t *reply;
    ret = build_mux_command_device_find( &req, server_id, pindex, PCIMUX_VID_ANY, PCIMUX_DID_ANY, class_code );
    pci_mux_command( mux_connection, &req, &reply );

    if( reply )
        printf( "found device bdf = 0x%x\n", reply->result.bdf );

    else
        return -1;

    req_attach_t attach_req;
    reply_attach_t *attach_reply;
    ret = build_mux_command_attach( &attach_req, reply->result.bdf, ATTACH_DEFAULT );
    pci_mux_command( mux_connection, &attach_req, &attach_reply );

    if( attach_reply )
        printf( "attached device return code %d, hdl %d\n", attach_reply->err, attach_reply->hdl );

    else
        return -1;

    req_detach_t detach_req;
    pcimux_devhdl_t hdl = attach_reply->hdl;
    ret = build_mux_command_detach( &detach_req, hdl );
    pci_mux_command( mux_connection, &detach_req, &reply );

    if( reply )
        printf( "detached device return code %d, hdl %d\n", reply->err, hdl );

    else
        return -1;

    printf( "PASS - find_attach_detach\n" );
    free( pathname );
    return 0;
}
Page updated: