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(;
{
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 **********/