Linux PCI API -> QNX PCI API

Hi,

I got the Linux driver source for a PCI Board and would like to port
this
driver under QNX. I don’t have any experience doing such thing.
So any document, help, link, anything, … that can help me would be
very
appreciated.

The first thing, i have checked is the PCI api, and it seems that this
API
is very different under Linux.

Thanks for your help…

“Yasmine” <y.leroux@nospam.actris.com> wrote in message
news:a7f9uh$g5n$1@inn.qnx.com

Hi,

I got the Linux driver source for a PCI Board and would like to port
this
driver under QNX. I don’t have any experience doing such thing.
So any document, help, link, anything, … that can help me would be
very appreciated.

To my knowledge there is no such document. You can go on irc.qnxzone.com
#qnx
to ask for pointer or use this newsgroup.

Best advise is read the QNX doc!

The first thing, i have checked is the PCI api, and it seems that this
API
is very different under Linux.

Thanks for your help…

Yasmine…

Take a look at this code bellow, compare with the code you have, do read
the QNX functions documentation, and you should be in your way. I
should say that working in QNX will be much much much easier, intuitive
and rewarding than in Linux. Whence if you have some Linux code, you
are almost 90% there, but you still must do your homework and read the
online documentation. Youi may want to take a look at some of the
articles in:

http://qdn.qnx.com/articles/index.html

Regards…

Miguel.

P.S. the code bellow should compile as is.

=====================

/*

  • This program sets up a slave ram window on the Intel 21554 chip and
    maps the
  • window out in shared memory
    */
    #include <fcntl.h>
    #include <stdio.h>
    #include <hw/pci.h>
    #include <sys/mman.h>


    int
    main( int argc, char **argv )
    {
    #define LF 0x10
    #define MASTERSIZE 0x100000
    struct pci_dev_info intel21554;
    void *bridgeBase;
    void *bridgeHandle;
    int pci_handle;
    unsigned long BaseAddr;
    void *masterBase, *ptr;
    unsigned char *w;
    unsigned long tmp32;
    int ii;

if( pci_handle = pci_attach( 0 ) < 0 )
{
perror( “Error attaching to the PCI server” );
return ( -1 );
}

/*

  • Locate the PCI-PCI bridge chip and allocate resources
    */
    memset( &intel21554, 0, sizeof( intel21554 ) );
    intel21554.VendorId = 0x1011;
    intel21554.DeviceId = 0x46;

bridgeHandle = pci_attach_device( NULL, PCI_INIT_ALL, 0, &intel21554
);

if( NULL == bridgeHandle )
{
perror( “pci_attach_device” );
return ( -1 );
}

fprintf( stderr, “Bridge device found\n”
" Vendor Id = %x\n"
" Device Id = %x\n"
" Subsystem Id = %x\n"
" Subsystem Vendor Id = %x\n"
" Bus Number = %x\n"
" Device Function Number = %x\n"
" Revision = %x\n"
" Class = %x\n"
" IRQ = %x\n",
intel21554.VendorId, intel21554.DeviceId,
intel21554.SubsystemId,
intel21554.SubsystemVendorId, intel21554.BusNumber,
intel21554.DevFunc, intel21554.Revision, intel21554.Class,
intel21554.Irq );

/*

  • Get the address to transfer data to
    */
    if( argc < 2 )
    {
    printf( “usage: master address” );
    return ( -1 );
    }
    BaseAddr = strtol( argv[1], NULL, 0 );

/*

  • Set the upstream window translation
    */
    if( pci_write_config( bridgeHandle, 0xa8, 1, sizeof( BaseAddr ),
    &BaseAddr )
    != PCI_SUCCESS )
    {
    perror( “pci_write_config” );
    return ( -1 );
    }

/*

  • Write the memory setup registers
    /
    tmp32 = ~( MASTERSIZE - 1 ) | 0x8; /
    | 0x8 means read prefetch,
    this is
    required for 64bit transfers
    */
    if( pci_write_config( bridgeHandle, 0xc8, 1, sizeof( tmp32 ), &tmp32 )
    !=
    PCI_SUCCESS )
    {
    perror( “pci_write_config” );
    return ( -1 );
    }

/*

  • Dump the pertinent contents of configuration space
    */
    fprintf( stderr, “\n” );

for( ii = 0x10; ii <= 0x24; ii += 4 )
{
pci_read_config( bridgeHandle, ii, 1, sizeof( BaseAddr ),
&BaseAddr );
fprintf( stderr, " Register offset %x = %x\n", ii,
BaseAddr );
}

fprintf( stderr, “\n” );

for( ii = 0x50; ii <= 0x64; ii += 4 )
{
pci_read_config( bridgeHandle, ii, 1, sizeof( BaseAddr ),
&BaseAddr );
fprintf( stderr, " Register offset %x = %x\n", ii,
BaseAddr );
}

fprintf( stderr, “\n” );

for( ii = 0x90; ii <= 0xC8; ii += 4 )
{
pci_read_config( bridgeHandle, ii, 1, sizeof( BaseAddr ),
&BaseAddr );
fprintf( stderr, " Register offset %x = %x\n", ii,
BaseAddr );
}

/*

  • Map in the the upstream window
    */
    if( MAP_FAILED ==
    ( masterBase =
    mmap_device_memory( NULL, MASTERSIZE,
    PROT_READ | PROT_WRITE | PROT_NOCACHE, 0,
    0xe0000000 ) ) )
    {
    perror( “mmap” );
    return ( -1 );
    }

ptr = ( void * )malloc( 0x1000 );
memcpy( ptr, ( void * )masterBase, 0x1000 );

/*

  • Dump the contents of the slave window
    */
    w = ptr;
    for( ii = 0; ii < 0x1000; w++ )
    printf( “%.2x%c”, *w, ( ++ii % LF ) ? ’ ’ : ‘\n’ );

printf( “\n” );

/*

  • Fill the upstream window
    */
    w = ptr;
    for( ii = 0; ii < 0x1000; ++ii, ++w )
    *w = ii & 0xff;

memcpy( ( void * )masterBase, ptr, 0x1000 );

return ( 0 );
}

==========================

Yasmine wrote:

Hi,

I got the Linux driver source for a PCI Board and would like to port
this
driver under QNX. I don’t have any experience doing such thing.
So any document, help, link, anything, … that can help me would be
very
appreciated.

The first thing, i have checked is the PCI api, and it seems that this
API
is very different under Linux.

Thanks for your help…

my opinions are mine, only mine, solely mine, and they are not related
in any possible way to the institution(s) in which I study and work.

Miguel Simon
Research Engineer
School of Aerospace and Mechanical Engineering
University of Oklahoma
http://www.amerobotics.ou.edu/
http://www.saic.com