NIC on PCI-Interrupts problem

I’m trying to make an ATM NIC work under QNX4. The NIC is on the PCI
bus.The card is properly recognized when the machine boots . (under the
pci-devices list which appears during start-up I see the specific
device -device ID,vendor ID- and the IRQ assigned to it).I’ve also been able
to wrtite to and read from the NIC’s registers using both the in*(),out*()
functions and memory read-write (the card is memory mapped).By reading some
of the device’s registers (counters) I saw cells coming to my card (send
from another ATM adapter or an ATM switch,depending on where I connect it
to).

The problem is that I never get an interrupt although I am positive that I
have properly configured the NIC to generate interrupts on reception of
cells (or when some other events occur i.e timer’s overflow etc).I ve used
the qnx_hint_attach() to associate the card’s IRQ with my source code (ISR)

Any ideas what could be preventing an interrupt from taking place?Is it a
BIOS problem?Could it be that somehow certain interrupts have been masked?If
so…is there a way to check that?Is there something I should check in the
BIOS “PCI PnP Settings”?

Could that be because of the fact that I haven’t used in my source code
(pseudo-driver) the qnx_device_attach() , qnx_prefix_attach() functions?Is
this necessary so that QNX recognizes the card and adopts it as a system’s
device?Is it also necessary to adopt the card under the Net manager in order
to simply receive and send some cells from and to another card?

Any help would be really valuable…I 've spent many many hours trying to
figure this out!

Thank you very much in advance.

PS. I apologise fo the extension of my post

PS 2 When “talking” to a PCI device which is memory mapped ,what is the
practical difference between using the in(), out() functions and writing to
the memory locations in which the device is mapped to?

“Akis” <romeoita@yahoo.com> wrote in message
news:9uomfd$a5n$1@inn.qnx.com

I’m trying to make an ATM NIC work under QNX4. The NIC is on the PCI
bus.The card is properly recognized when the machine boots . (under the
pci-devices list which appears during start-up I see the specific
device -device ID,vendor ID- and the IRQ assigned to it).I’ve also been
able
to wrtite to and read from the NIC’s registers using both the in*(),out*()
functions and memory read-write (the card is memory mapped).By reading
some
of the device’s registers (counters) I saw cells coming to my card (send
from another ATM adapter or an ATM switch,depending on where I connect it
to).

The problem is that I never get an interrupt although I am positive that I
have properly configured the NIC to generate interrupts on reception of
cells (or when some other events occur i.e timer’s overflow etc).I ve used
the qnx_hint_attach() to associate the card’s IRQ with my source code
(ISR)

qnx_hint_attach and setting up the NIC is all that should be required.

Did you use the CA_PCI_… fonction to get the info about the card.
Are you sure you are using the right IRQ.

Any ideas what could be preventing an interrupt from taking place?

Is it a BIOS problem?

Unlikely

Could it be that somehow certain interrupts have been masked?

When you call qnx_hint_attach the interrupt are enable at the interrupt
controler level.

…is there a way to check that?

Can you probe the interrupt line on the PCI bus, to see if the
card generates the interrupt (watch for shared interrupt)

Is there something I should check in the BIOS “PCI PnP Settings”?

Make sure BIOS is set to “non plug & play OS”.
If possible make sure all PCI card use a different interrupt.

Could that be because of the fact that I haven’t used in my source code
(pseudo-driver) the qnx_device_attach() , qnx_prefix_attach() functions?

No that’s totaly unrelated.

Is this necessary so that QNX recognizes the card and adopts it as a
system’s
device?

Absolutely not.

Is it also necessary to adopt the card under the Net manager in order
to simply receive and send some cells from and to another card?

No.

However to be able to use the card to do TCP/IP or QNX networking
is a different story. This is a lot more work? Do you need to
do that.

Any help would be really valuable…I 've spent many many hours trying to
figure this out!

Thank you very much in advance.

PS. I apologise fo the extension of my post

More is usually better :wink:

PS 2 When “talking” to a PCI device which is memory mapped ,what is the
practical difference between using the in(), out() functions and writing
to
the memory locations in which the device is mapped to?

in() and out() are use to talk to device that are IO mapped. On x86 familly
IO space and memory space are two different things. You can’t use one to
access the other. You mention the board is memory mapped that means you
should not have to use in()/out() calls. Maybe that is where your problem
lies.

You don’t need to register with Net or Dev or anyone else to be able to talk
to your hardware. Calling qnx_hint_attach() to set up your interrupt
handler is the only thing you really need. However, interrupt handlers are
a bit “special”. Maybe you could post your code here, along with any
compiler options you use.

“Akis” <romeoita@yahoo.com> wrote in message
news:9uomfd$a5n$1@inn.qnx.com

I’m trying to make an ATM NIC work under QNX4. The NIC is on the PCI
bus.The card is properly recognized when the machine boots . (under the
pci-devices list which appears during start-up I see the specific
device -device ID,vendor ID- and the IRQ assigned to it).I’ve also been
able
to wrtite to and read from the NIC’s registers using both the in*(),out*()
functions and memory read-write (the card is memory mapped).By reading
some
of the device’s registers (counters) I saw cells coming to my card (send
from another ATM adapter or an ATM switch,depending on where I connect it
to).

The problem is that I never get an interrupt although I am positive that I
have properly configured the NIC to generate interrupts on reception of
cells (or when some other events occur i.e timer’s overflow etc).I ve used
the qnx_hint_attach() to associate the card’s IRQ with my source code
(ISR)

Any ideas what could be preventing an interrupt from taking place?Is it a
BIOS problem?Could it be that somehow certain interrupts have been
masked?If
so…is there a way to check that?Is there something I should check in the
BIOS “PCI PnP Settings”?

Could that be because of the fact that I haven’t used in my source code
(pseudo-driver) the qnx_device_attach() , qnx_prefix_attach() functions?Is
this necessary so that QNX recognizes the card and adopts it as a system’s
device?Is it also necessary to adopt the card under the Net manager in
order
to simply receive and send some cells from and to another card?

Any help would be really valuable…I 've spent many many hours trying to
figure this out!

Thank you very much in advance.

PS. I apologise fo the extension of my post

PS 2 When “talking” to a PCI device which is memory mapped ,what is the
practical difference between using the in(), out() functions and writing
to
the memory locations in which the device is mapped to?

“Mario Charest” <mcharest@clipzinformatic.com> wrote in message
news:9uqgnh$hpr$1@inn.qnx.com

“Akis” <> romeoita@yahoo.com> > wrote in message
news:9uomfd$a5n$> 1@inn.qnx.com> …
I’m trying to make an ATM NIC work under QNX4. The NIC is on the PCI
bus.The card is properly recognized when the machine boots . (under the
pci-devices list which appears during start-up I see the specific
device -device ID,vendor ID- and the IRQ assigned to it).I’ve also been
able
to wrtite to and read from the NIC’s registers using both the
in*(),out*()
functions and memory read-write (the card is memory mapped).By reading
some
of the device’s registers (counters) I saw cells coming to my card (send
from another ATM adapter or an ATM switch,depending on where I connect
it
to).

The problem is that I never get an interrupt although I am positive that
I
have properly configured the NIC to generate interrupts on reception of
cells (or when some other events occur i.e timer’s overflow etc).I ve
used
the qnx_hint_attach() to associate the card’s IRQ with my source code
(ISR)

qnx_hint_attach and setting up the NIC is all that should be required.

Did you use the CA_PCI_… fonction to get the info about the card.
Are you sure you are using the right IRQ.

Any ideas what could be preventing an interrupt from taking place?

Is it a BIOS problem?

Unlikely

Could it be that somehow certain interrupts have been masked?

When you call qnx_hint_attach the interrupt are enable at the interrupt
controler level.

…is there a way to check that?

Can you probe the interrupt line on the PCI bus, to see if the
card generates the interrupt (watch for shared interrupt)

Is there something I should check in the BIOS “PCI PnP Settings”?

Make sure BIOS is set to “non plug & play OS”.
If possible make sure all PCI card use a different interrupt.


Could that be because of the fact that I haven’t used in my source code
(pseudo-driver) the qnx_device_attach() , qnx_prefix_attach() functions?

No that’s totaly unrelated.

Is this necessary so that QNX recognizes the card and adopts it as a
system’s
device?

Absolutely not.

Is it also necessary to adopt the card under the Net manager in order
to simply receive and send some cells from and to another card?

No.

However to be able to use the card to do TCP/IP or QNX networking
is a different story. This is a lot more work? Do you need to
do that.


Any help would be really valuable…I 've spent many many hours trying
to
figure this out!

Thank you very much in advance.

PS. I apologise fo the extension of my post


More is usually better > :wink:

PS 2 When “talking” to a PCI device which is memory mapped ,what is the
practical difference between using the in(), out() functions and writing
to
the memory locations in which the device is mapped to?

in() and out() are use to talk to device that are IO mapped. On x86
familly
IO space and memory space are two different things. You can’t use one to
access the other. You mention the board is memory mapped that means you
should not have to use in()/out() calls. Maybe that is where your problem
lies.

The card is both I/O and memory mapped and I 've been able to talk to it
both by accessing memory and by using in() out() functions.I was just

wandering whether there is a specific reason it has been mapped this way
(I/O+memory mapped).

The card is both I/O and memory mapped and I 've been able to talk to it
both by accessing memory and by using in() out() functions.I was just
wandering whether there is a specific reason it has been mapped this way
(I/O+memory mapped).

Some PCI card still use I/O to keep compability with existing sofware.
I’ve never seen a card that use I/O and memory to control to same
fonctionnailty. All card I’ve seen use I/O for some stuff and memory
for other. Most of the time the I/O part is for legacy support.

Changing’s the card PCI slot causes the QNX to assign a different IRQ to
it.(11).The only difference made by this initiative of mine is that now,a
NIC’s timer overflow,which is suposed to post an interrupt to the
CPU,causes the system to crash (the screen freezes an no keystroke has any
effect).I still get no itnerrupt on reception of cells although by reading
registers-counters I see cells coming to me.
There is a specific counter that indicates the number of cells rejected by
the NIC,because it was unable to tranfer them from the on-chip FIFO memory
to host (system) memory locations indicated by pointers passed from the
driver to the card.I always get an indication when accesing this
counter,fact that makes me believe that the NIC never gets to be a PCI bus
master (that is the mode used during transfer of received ATM cells from tha
ATM card to the system;s memory)
Running a downloaded (not from the official QNX site) application (irqmon)
which is supposed to monitor and graphically display an-screen the
interrupts caused on each IRQ,never shows an interrupt an the cards IRQ.
The show_pci utility , indicates that my IRQ ,is also passed to the Serial
Bus Controller .I could suppose that there is an IRQ conflict problem,but
moving the card to a different slot and obtaining by the operating system an
IRQ not used by any ither device does not solve the problem.
Questions.
1)Is there something that could be permenantly preventing the NIC from
requesting (and be granted with) PCI bus control?
2)What is the sysmon tool/application?Is it somehow related to my problem?If
so,in what way could it be useful to me?
3)Are you aware of any PCI bus(or generally hardware) related newsgroups I
could address to?
I would really appreciate any kind of help!
Source code follows (main function and isr)
compilation options
cc -T1 -zu -Wc,-s -c isr.c
cc -T1 main.c isr.o file1.c file2.c…filen.c -o receive (receive for the
name of my executable)

/********************** MAIN **********************************/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <i86.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/seginfo.h>
#include <sys/types.h>
#include <sys/irqinfo.h>
#include <sys/proxy.h>
#include <sys/kernel.h>
#include <sys/sched.h>
#include <sys/fd.h>
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18 /* I/O adress of status register */


struct nic_registers nicstar;
struct small_buffer small_buffers[SMALL_NUM];
struct large_buffer large_buffers[LARGE_NUM];
paddr_t rsq_dmaddr,raw_header;
int interrupt_id,*ptr,*rsq_virtaddr;
unsigned mem;
pid_t proxy,sender;
char *msg;
FILE *check,*raw;

pid_t far intHandler(void);

main()

{

setuid(0); /* Setting the uid to 0 (root) */

mem=shm_open(“Physical”,O_RDWR,0777);
if(mem==-1){
printf(“Error opening physical memory:%s\n”,strerror(errno));
exit(1);
}
ptr=mmap(0,SIZE,PROT_FLAGS,MAP_SHARED,mem,BASE_ADDRESS);
if(ptr==(void *) -1){
printf(“Error mapping memory at main process:%s\n”,strerror(errno));
close(mem);
exit(1);
}

nicstar.data_reg0 = ptr;
nicstar.data_reg1 = ptr + 1;
nicstar.data_reg2 = ptr + 2;
nicstar.data_reg3 = ptr + 3;
nicstar.com_reg = ptr + 4;
nicstar.config_reg = ptr + 5;
nicstar.status_reg = ptr + 6;
nicstar.rsq_base_reg = ptr + 7;
nicstar.rsq_tail_reg = ptr + 8;
nicstar.rsq_head_reg = ptr + 9;
nicstar.cell_drop_count_reg = ptr + 10;
nicstar.vpi_vci_error_reg = ptr + 11;
nicstar.inv_cell_count_reg = ptr + 12;
nicstar.raw_cell_tail_reg = ptr + 13;
nicstar.timer_reg = ptr + 14;
nicstar.tst_base_reg = ptr + 15;
nicstar.tsq_base_reg = ptr + 16;
nicstar.tsq_tail_reg = ptr + 17;
nicstar.tsq_head_reg = ptr + 18;
nicstar.general_reg = ptr + 19;
nicstar.vpi_vci_mask_reg = ptr + 20;



/* Checkinq if the receive structures were allocated */


if((!(alloc_smallbufs())) && (!(alloc_largebufs())))
printf(“Small and large buffers succesfully allocated and passed to
NICStAR\n”);
else
{
printf(“Error 1…exiting the program…\n”);
exit(1);
}

if(!alloc_rsq())
printf(“Receive Status Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 2…exiting the program…\n”);
exit(1);
}

if(!initial_rct())
printf(“Receive Connection Table succesfully allocated in NICStAR’s
local SRAM\n”);
else
{
printf(“Error 3…exiting the program…\n”);
exit(1);
}

sleep(1);

if(!initial_rcq())
printf(“Raw Cell Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 4…bye bye!!!..\n”);
exit(1);
}

if(fork()>0)
exit(0);

/* Attaching the interrupt handler */

interrupt_id = qnx_hint_attach(11,&intHandler,FP_SEG(&interrupt_id));
if(interrupt_id==-1){
printf(“Error …Unable to attach interrupt handler to PCI IRQ
11:%s\n”,strerror(errno));
exit(1);
}

/* Attaching the proxy that will notify our process when an interrupt
occurs */

proxy = qnx_proxy_attach(0,NULL,0,0);
if(proxy==-1){
printf(“Error …Unable to attach proxy:%s\n”,strerror(errno));
exit(1);
}

/* Opening the file where the received data will be written to for
validation */
check = fopen(“testfile”,“w+a”);

/* Opening the file where the raw cells will be copied for validation */
raw = fopen(“rawfile”,“w+a”);

/* Opening the connections by calling the opencon() function /
/
opencon(); */
connect();

/* Now we just wait for a proxy to arrive,and then call the respective
function to service the interrupt */




for(;:wink:
{
sender=Receive(0,msg,1);
if(sender==proxy)
{
printf(“HALLELUJAH!!!We 've just got a mother-f&$%#ng
proxy!\n”);
switch(inpd(STATUS_REG)){
case END_OF_PDU:
service_pdu();
case RAW_CELL:
service_rcq();
default:
printf(“Unknown cause of interrupt\n”);
break;
}
}

}

}




/************************** ISR ******************************************/

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <i86.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/seginfo.h>
#include <sys/types.h>
#include <sys/irqinfo.h>
#include <sys/proxy.h>
#include <sys/kernel.h>
#include <sys/sched.h>
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18

extern pid_t proxy;


/* **************** I S R *************** */

#pragma off (check_stack)

pid_t far intHandler(void)
{
volatile int status_dword; /* The double-word (32 bit) read from
status register to determine the source of the interrupt */

status_dword=inpd(STATUS_REG);
if(status_dword){
outpd(STATUS_REG,0x0000);
return (proxy);
}
else
return (0);

}

#pragma on (check_stack)

/* ******* End of ISR source code which has been compiled with stack
checking off **********/

“Akis” <romeoita@yahoo.com> wrote in message
news:9vt4k4$pui$1@inn.qnx.com

Changing’s the card PCI slot causes the QNX to assign a different IRQ to
it.(11).

PCI resources are assigned by the PCI BIOS not by QNX.

The only difference made by this initiative of mine is that now,a
NIC’s timer overflow,which is suposed to post an interrupt to the
CPU,causes the system to crash (the screen freezes an no keystroke has any
effect).I still get no itnerrupt on reception of cells although by reading
registers-counters I see cells coming to me.

There is a specific counter that indicates the number of cells rejected by
the NIC,because it was unable to tranfer them from the on-chip FIFO memory
to host (system) memory locations indicated by pointers passed from the
driver to the card.I always get an indication when accesing this
counter,fact that makes me believe that the NIC never gets to be a PCI bus
master (that is the mode used during transfer of received ATM cells from
tha
ATM card to the system;s memory)

Running a downloaded (not from the official QNX site) application (irqmon)
which is supposed to monitor and graphically display an-screen the
interrupts caused on each IRQ,never shows an interrupt an the cards IRQ.
The show_pci utility , indicates that my IRQ ,is also passed to the
Serial
Bus Controller .I could suppose that there is an IRQ conflict problem,but
moving the card to a different slot and obtaining by the operating system
an
IRQ not used by any ither device does not solve the problem.

Questions.
1)Is there something that could be permenantly preventing the NIC from
requesting (and be granted with) PCI bus control?

Don’t know enough about PCI bus master to answer that.

2)What is the sysmon tool/application?Is it somehow related to my
problem?If
so,in what way could it be useful to me?

3)Are you aware of any PCI bus(or generally hardware) related newsgroups I
could address to?
I would really appreciate any kind of help!
Source code follows (main function and isr)
compilation options
cc -T1 -zu -Wc,-s -c isr.c
cc -T1 main.c isr.o file1.c file2.c…filen.c -o receive (receive for the
name of my executable)

Looking at the source code I see you are not using any of the _CA_PCI

function
to obtain info about IRQ and memory assignement done by the BIOS.
If the info you hardcode is ok I beleive it should not matter, but you
should definitely
use CA_PCI* function. Typical there is no guaranty the BIOS will assign
the same resource (irq, memory) at every boot.

/********************** MAIN **********************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include <sys/fd.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18 /* I/O adress of status register */


struct nic_registers nicstar;
struct small_buffer small_buffers[SMALL_NUM];
struct large_buffer large_buffers[LARGE_NUM];
paddr_t rsq_dmaddr,raw_header;
int interrupt_id,*ptr,*rsq_virtaddr;
unsigned mem;
pid_t proxy,sender;
char *msg;
FILE *check,*raw;

pid_t far intHandler(void);

main()

{

setuid(0); /* Setting the uid to 0 (root) */

mem=shm_open(“Physical”,O_RDWR,0777);
if(mem==-1){
printf(“Error opening physical memory:%s\n”,strerror(errno));
exit(1);
}
ptr=mmap(0,SIZE,PROT_FLAGS,MAP_SHARED,mem,BASE_ADDRESS);
if(ptr==(void *) -1){
printf(“Error mapping memory at main process:%s\n”,strerror(errno));
close(mem);
exit(1);
}

nicstar.data_reg0 = ptr;
nicstar.data_reg1 = ptr + 1;
nicstar.data_reg2 = ptr + 2;
nicstar.data_reg3 = ptr + 3;
nicstar.com_reg = ptr + 4;
nicstar.config_reg = ptr + 5;
nicstar.status_reg = ptr + 6;
nicstar.rsq_base_reg = ptr + 7;
nicstar.rsq_tail_reg = ptr + 8;
nicstar.rsq_head_reg = ptr + 9;
nicstar.cell_drop_count_reg = ptr + 10;
nicstar.vpi_vci_error_reg = ptr + 11;
nicstar.inv_cell_count_reg = ptr + 12;
nicstar.raw_cell_tail_reg = ptr + 13;
nicstar.timer_reg = ptr + 14;
nicstar.tst_base_reg = ptr + 15;
nicstar.tsq_base_reg = ptr + 16;
nicstar.tsq_tail_reg = ptr + 17;
nicstar.tsq_head_reg = ptr + 18;
nicstar.general_reg = ptr + 19;
nicstar.vpi_vci_mask_reg = ptr + 20;



/* Checkinq if the receive structures were allocated */


if((!(alloc_smallbufs())) && (!(alloc_largebufs())))
printf(“Small and large buffers succesfully allocated and passed to
NICStAR\n”);
else
{
printf(“Error 1…exiting the program…\n”);
exit(1);
}

if(!alloc_rsq())
printf(“Receive Status Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 2…exiting the program…\n”);
exit(1);
}

if(!initial_rct())
printf(“Receive Connection Table succesfully allocated in NICStAR’s
local SRAM\n”);
else
{
printf(“Error 3…exiting the program…\n”);
exit(1);
}

sleep(1);

if(!initial_rcq())
printf(“Raw Cell Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 4…bye bye!!!..\n”);
exit(1);
}

if(fork()>0)
exit(0);

/* Attaching the interrupt handler */

interrupt_id = qnx_hint_attach(11,&intHandler,FP_SEG(&interrupt_id));
if(interrupt_id==-1){
printf(“Error …Unable to attach interrupt handler to PCI IRQ
11:%s\n”,strerror(errno));
exit(1);
}

/* Attaching the proxy that will notify our process when an interrupt
occurs */

proxy = qnx_proxy_attach(0,NULL,0,0);
if(proxy==-1){
printf(“Error …Unable to attach proxy:%s\n”,strerror(errno));
exit(1);
}

/* Opening the file where the received data will be written to for
validation */
check = fopen(“testfile”,“w+a”);

/* Opening the file where the raw cells will be copied for validation */
raw = fopen(“rawfile”,“w+a”);

/* Opening the connections by calling the opencon() function /
/
opencon(); */
connect();

/* Now we just wait for a proxy to arrive,and then call the respective
function to service the interrupt */




for(;:wink:
{
sender=Receive(0,msg,1);
if(sender==proxy)
{
printf(“HALLELUJAH!!!We 've just got a mother-f&$%#ng
proxy!\n”);
switch(inpd(STATUS_REG)){
case END_OF_PDU:
service_pdu();
case RAW_CELL:
service_rcq();
default:
printf(“Unknown cause of interrupt\n”);
break;
}
}

}

}




/************************** ISR
******************************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18

extern pid_t proxy;


/* **************** I S R *************** */

#pragma off (check_stack)

pid_t far intHandler(void)
{
volatile int status_dword; /* The double-word (32 bit) read from
status register to determine the source of the interrupt */

status_dword=inpd(STATUS_REG);
if(status_dword){
outpd(STATUS_REG,0x0000);
return (proxy);
}
else
return (0);

}

#pragma on (check_stack)

/* ******* End of ISR source code which has been compiled with stack
checking off **********/

Looking at the source code I see you are not using any of the _CA_PCI
function
to obtain info about IRQ and memory assignement done by the BIOS.
If the info you hardcode is ok I beleive it should not matter, but you
should definitely
use CA_PCI* function. Typical there is no guaranty the BIOS will assign
the same resource (irq, memory) at every boot.

Before execution of the program , I run the show_pci utility which makes use

of CA_PCI* function to obtain the necessary info to talk to my hardware
(I/O and memory base address etc.).If somehow a change has been made by the
PCI BIOS i alter the respective parameters on my source code,recompile it
and then execute it.So it is not there where the problem lies.
***************** MAIN **********************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include <sys/fd.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18 /* I/O adress of status register */


struct nic_registers nicstar;
struct small_buffer small_buffers[SMALL_NUM];
struct large_buffer large_buffers[LARGE_NUM];
paddr_t rsq_dmaddr,raw_header;
int interrupt_id,*ptr,*rsq_virtaddr;
unsigned mem;
pid_t proxy,sender;
char *msg;
FILE *check,*raw;

pid_t far intHandler(void);

main()

{

setuid(0); /* Setting the uid to 0 (root) */

mem=shm_open(“Physical”,O_RDWR,0777);
if(mem==-1){
printf(“Error opening physical memory:%s\n”,strerror(errno));
exit(1);
}
ptr=mmap(0,SIZE,PROT_FLAGS,MAP_SHARED,mem,BASE_ADDRESS);
if(ptr==(void *) -1){
printf(“Error mapping memory at main
process:%s\n”,strerror(errno));
close(mem);
exit(1);
}

nicstar.data_reg0 = ptr;
nicstar.data_reg1 = ptr + 1;
nicstar.data_reg2 = ptr + 2;
nicstar.data_reg3 = ptr + 3;
nicstar.com_reg = ptr + 4;
nicstar.config_reg = ptr + 5;
nicstar.status_reg = ptr + 6;
nicstar.rsq_base_reg = ptr + 7;
nicstar.rsq_tail_reg = ptr + 8;
nicstar.rsq_head_reg = ptr + 9;
nicstar.cell_drop_count_reg = ptr + 10;
nicstar.vpi_vci_error_reg = ptr + 11;
nicstar.inv_cell_count_reg = ptr + 12;
nicstar.raw_cell_tail_reg = ptr + 13;
nicstar.timer_reg = ptr + 14;
nicstar.tst_base_reg = ptr + 15;
nicstar.tsq_base_reg = ptr + 16;
nicstar.tsq_tail_reg = ptr + 17;
nicstar.tsq_head_reg = ptr + 18;
nicstar.general_reg = ptr + 19;
nicstar.vpi_vci_mask_reg = ptr + 20;



/* Checkinq if the receive structures were allocated */


if((!(alloc_smallbufs())) && (!(alloc_largebufs())))
printf(“Small and large buffers succesfully allocated and passed to
NICStAR\n”);
else
{
printf(“Error 1…exiting the program…\n”);
exit(1);
}

if(!alloc_rsq())
printf(“Receive Status Queue succesfully allocated in host
memory\n”);
else
{
printf(“Error 2…exiting the program…\n”);
exit(1);
}

if(!initial_rct())
printf(“Receive Connection Table succesfully allocated in NICStAR’s
local SRAM\n”);
else
{
printf(“Error 3…exiting the program…\n”);
exit(1);
}

sleep(1);

if(!initial_rcq())
printf(“Raw Cell Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 4…bye bye!!!..\n”);
exit(1);
}

if(fork()>0)
exit(0);

/* Attaching the interrupt handler */

interrupt_id = qnx_hint_attach(11,&intHandler,FP_SEG(&interrupt_id));
if(interrupt_id==-1){
printf(“Error …Unable to attach interrupt handler to PCI IRQ
11:%s\n”,strerror(errno));
exit(1);
}

/* Attaching the proxy that will notify our process when an interrupt
occurs */

proxy = qnx_proxy_attach(0,NULL,0,0);
if(proxy==-1){
printf(“Error …Unable to attach proxy:%s\n”,strerror(errno));
exit(1);
}

/* Opening the file where the received data will be written to for
validation */
check = fopen(“testfile”,“w+a”);

/* Opening the file where the raw cells will be copied for validation */
raw = fopen(“rawfile”,“w+a”);

/* Opening the connections by calling the opencon() function /
/
opencon(); */
connect();

/* Now we just wait for a proxy to arrive,and then call the respective
function to service the interrupt */




for(;:wink:
{
sender=Receive(0,msg,1);
if(sender==proxy)
{
printf(“HALLELUJAH!!!We 've just got a mother-f&$%#ng
proxy!\n”);
switch(inpd(STATUS_REG)){
case END_OF_PDU:
service_pdu();
case RAW_CELL:
service_rcq();
default:
printf(“Unknown cause of interrupt\n”);
break;
}
}

}

}




/************************** ISR
******************************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18

extern pid_t proxy;


/* **************** I S R *************** */

#pragma off (check_stack)

pid_t far intHandler(void)
{
volatile int status_dword; /* The double-word (32 bit) read from
status register to determine the source of the interrupt */

status_dword=inpd(STATUS_REG);
if(status_dword){
outpd(STATUS_REG,0x0000);
return (proxy);
}
else
return (0);

}

#pragma on (check_stack)

/* ******* End of ISR source code which has been compiled with stack
checking off **********/

\

“Akis” <romeoita@yahoo.com> wrote in message news:9vtb1i$u1$1@inn.qnx.com

Looking at the source code I see you are not using any of the _CA_PCI
function
to obtain info about IRQ and memory assignement done by the BIOS.
If the info you hardcode is ok I beleive it should not matter, but you
should definitely
use CA_PCI* function. Typical there is no guaranty the BIOS will
assign
the same resource (irq, memory) at every boot.

Before execution of the program , I run the show_pci utility which makes
use
of CA_PCI* function to obtain the necessary info to talk to my hardware
(I/O and memory base address etc.).If somehow a change has been made by
the
PCI BIOS i alter the respective parameters on my source code,recompile it
and then execute it.So it is not there where the problem lies.

In my experience when I’m looking for a hard to find bug I like
to not take an
My gut feeling tells me the hardware (nic) isn’t program right. OS wise
your code
is functionnaly doing what is required.

Is this a custom made board? It’s the first time I see a board where all
registers are 32 bits wide.

Does writting to the STATUS_REG clear the interrupt?


***************** MAIN **********************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include <sys/fd.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18 /* I/O adress of status register */


struct nic_registers nicstar;
struct small_buffer small_buffers[SMALL_NUM];
struct large_buffer large_buffers[LARGE_NUM];
paddr_t rsq_dmaddr,raw_header;
int interrupt_id,*ptr,*rsq_virtaddr;
unsigned mem;
pid_t proxy,sender;
char *msg;
FILE *check,*raw;

pid_t far intHandler(void);

main()

{

setuid(0); /* Setting the uid to 0 (root) */

mem=shm_open(“Physical”,O_RDWR,0777);
if(mem==-1){
printf(“Error opening physical memory:%s\n”,strerror(errno));
exit(1);
}
ptr=mmap(0,SIZE,PROT_FLAGS,MAP_SHARED,mem,BASE_ADDRESS);
if(ptr==(void *) -1){
printf(“Error mapping memory at main
process:%s\n”,strerror(errno));
close(mem);
exit(1);
}

nicstar.data_reg0 = ptr;
nicstar.data_reg1 = ptr + 1;
nicstar.data_reg2 = ptr + 2;
nicstar.data_reg3 = ptr + 3;
nicstar.com_reg = ptr + 4;
nicstar.config_reg = ptr + 5;
nicstar.status_reg = ptr + 6;
nicstar.rsq_base_reg = ptr + 7;
nicstar.rsq_tail_reg = ptr + 8;
nicstar.rsq_head_reg = ptr + 9;
nicstar.cell_drop_count_reg = ptr + 10;
nicstar.vpi_vci_error_reg = ptr + 11;
nicstar.inv_cell_count_reg = ptr + 12;
nicstar.raw_cell_tail_reg = ptr + 13;
nicstar.timer_reg = ptr + 14;
nicstar.tst_base_reg = ptr + 15;
nicstar.tsq_base_reg = ptr + 16;
nicstar.tsq_tail_reg = ptr + 17;
nicstar.tsq_head_reg = ptr + 18;
nicstar.general_reg = ptr + 19;
nicstar.vpi_vci_mask_reg = ptr + 20;



/* Checkinq if the receive structures were allocated */


if((!(alloc_smallbufs())) && (!(alloc_largebufs())))
printf(“Small and large buffers succesfully allocated and passed
to
NICStAR\n”);
else
{
printf(“Error 1…exiting the program…\n”);
exit(1);
}

if(!alloc_rsq())
printf(“Receive Status Queue succesfully allocated in host
memory\n”);
else
{
printf(“Error 2…exiting the program…\n”);
exit(1);
}

if(!initial_rct())
printf(“Receive Connection Table succesfully allocated in
NICStAR’s
local SRAM\n”);
else
{
printf(“Error 3…exiting the program…\n”);
exit(1);
}

sleep(1);

if(!initial_rcq())
printf(“Raw Cell Queue succesfully allocated in host memory\n”);
else
{
printf(“Error 4…bye bye!!!..\n”);
exit(1);
}

if(fork()>0)
exit(0);

/* Attaching the interrupt handler */

interrupt_id =
qnx_hint_attach(11,&intHandler,FP_SEG(&interrupt_id));
if(interrupt_id==-1){
printf(“Error …Unable to attach interrupt handler to PCI IRQ
11:%s\n”,strerror(errno));
exit(1);
}

/* Attaching the proxy that will notify our process when an interrupt
occurs */

proxy = qnx_proxy_attach(0,NULL,0,0);
if(proxy==-1){
printf(“Error …Unable to attach proxy:%s\n”,strerror(errno));
exit(1);
}

/* Opening the file where the received data will be written to for
validation */
check = fopen(“testfile”,“w+a”);

/* Opening the file where the raw cells will be copied for validation
*/
raw = fopen(“rawfile”,“w+a”);

/* Opening the connections by calling the opencon() function /
/
opencon(); */
connect();

/* Now we just wait for a proxy to arrive,and then call the respective
function to service the interrupt */




for(;:wink:
{
sender=Receive(0,msg,1);
if(sender==proxy)
{
printf(“HALLELUJAH!!!We 've just got a mother-f&$%#ng
proxy!\n”);
switch(inpd(STATUS_REG)){
case END_OF_PDU:
service_pdu();
case RAW_CELL:
service_rcq();
default:
printf(“Unknown cause of interrupt\n”);
break;
}
}

}

}




/************************** ISR
******************************************/

#include <stdio.h
#include <string.h
#include <unistd.h
#include <fcntl.h
#include <i86.h
#include <errno.h
#include <sys/mman.h
#include <sys/seginfo.h
#include <sys/types.h
#include <sys/irqinfo.h
#include <sys/proxy.h
#include <sys/kernel.h
#include <sys/sched.h
#include “nicinfo.h”
#include “rxfuncs.h”
#include “confinfo.h”

#define STATUS_REG 0x6100+0x18

extern pid_t proxy;


/* **************** I S R *************** */

#pragma off (check_stack)

pid_t far intHandler(void)
{
volatile int status_dword; /* The double-word (32 bit) read from
status register to determine the source of the interrupt */

status_dword=inpd(STATUS_REG);
if(status_dword){
outpd(STATUS_REG,0x0000);
return (proxy);
}
else
return (0);

}

#pragma on (check_stack)

/* ******* End of ISR source code which has been compiled with stack
checking off **********/



\

“Akis” <romeoita@yahoo.com> wrote in message
news:9vt4k4$pui$1@inn.qnx.com

[ … lots of snips … ]

1)Is there something that could be permenantly preventing the NIC from
requesting (and be granted with) PCI bus control?

Have you checked BIOS settings on the computer? Some BIOS’s have an option
to enable/disable PCI bus mastering.


Bert Menkveld
Engineer
Corman Technologies Inc.