void* area parameter of InterruptAttach()

Hello all,
I have a problem with InterruptAttach(). The ISR is not generating the
required pulses because it is not able to correctly access the device’s
memory( i am pretty sure that this is the problem). I am wondering what
value should I pass for the void* area parameter of InterruptAttach() (look
below for a detailed description).
I have a driver in C++ for a PCI device, namely class deviceName. The
device memory is mapped into the calling process address space as static
unsigned int s_localBus = (unsigned int) mmap_device_memory(0, 4096,
flags, 0, offset). The ISR should read the device’s registers and determines
which of the several interrupts (DMA, FIFO, HW interrupts) have been raised
and clears those interrupts alarms by writing to those device registers and
then sends a pulse with an appropriate code value that reflects which of the
interrupts has occured. The code in the ISR looks as follows:-

const struct sigevent* deviceName::isr(void* , int)
{
if(s_localBus[e_intConStat] & 0x00008000)
{
// Device Local interrupt input is active. See which one we have:
if(s_localBus[e_con2] & 0x00020000)
{
// DMA interrupt. Which channel?
if(s_localBus[e_intConStat] & 0x00200000)
{
// DMA channel 0; clear the interrupt status
s_localBus[e_dmaComStat] = s_localBus[e_dmaComStat] |
0x00000008;
// Return the pulse
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_dmaInt], 0);
return(&s_sigEvent);
}
else if(s_localBus[e_con2] & 0x00040000)
{
// FIFO interrupt
s_localBus[e_con4] = (s_localBus[e_con4] & 0xFFFFFF9F) |
0x00000020;
s_localBus[e_con2] = s_localBus[e_con2] & 0xFFFBFFFF;
s_localBus[e_con4] = s_localBus[e_con4] & 0xFFFFFF9F;
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_fifoInt], 0);
return(&s_sigEvent);
}
return(0);
}

The ISR is attached as follows
d_interruptId = InterruptAttach( d_pciRegs.Interrupt_Line, &isr, s_localBus,
4096, 0);

All the variables are declared private static data members of the class
deviceName as:-
static unsigned int *s_localBus;
static int d_channelId, d_connectionId, d_interruptCodes[e_numberOfIntTypes]
;
static struct sigevent s_sigEvent;

Can anybody point to the mistake I am making. Your help will be appreciated.
Thanks,
Tray.

“Tray Karra” <tkarra@ces.clemson.edu> wrote in message
news:ar0tar$c2$1@inn.qnx.com

Hello all,
I have a problem with InterruptAttach(). The ISR is not generating the
required pulses because it is not able to correctly access the device’s
memory( i am pretty sure that this is the problem).

You should be able to at least get 1 interrupt. Make sure the interrupt
isn’t shared with other device and check if you at least get one interrupt.
If you do at least you know the settup of the ISR is ok. If you don’t get
at least one interrupt, the device is probably not configured properly.


I am wondering what
value should I pass for the void* area parameter of InterruptAttach()
(look
below for a detailed description).

In the ISR you can pass what ever value you want (it could be a pointer the
the class object reducing the number of static variable you are using)

I have a driver in C++ for a PCI device, namely class deviceName. The
device memory is mapped into the calling process address space as static
unsigned int s_localBus = (unsigned int) mmap_device_memory(0, 4096,
flags, 0, offset). The ISR should read the device’s registers and
determines
which of the several interrupts (DMA, FIFO, HW interrupts) have been
raised
and clears those interrupts alarms by writing to those device registers
and
then sends a pulse with an appropriate code value that reflects which of
the
interrupts has occured. The code in the ISR looks as follows:-

const struct sigevent* deviceName::isr(void* , int)
{
if(s_localBus[e_intConStat] & 0x00008000)
{
// Device Local interrupt input is active. See which one we
have:
if(s_localBus[e_con2] & 0x00020000)
{
// DMA interrupt. Which channel?
if(s_localBus[e_intConStat] & 0x00200000)
{
// DMA channel 0; clear the interrupt status
s_localBus[e_dmaComStat] = s_localBus[e_dmaComStat] |
0x00000008;
// Return the pulse
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_dmaInt], 0);
return(&s_sigEvent);
}
else if(s_localBus[e_con2] & 0x00040000)
{
// FIFO interrupt
s_localBus[e_con4] = (s_localBus[e_con4] & 0xFFFFFF9F) |
0x00000020;
s_localBus[e_con2] = s_localBus[e_con2] & 0xFFFBFFFF;
s_localBus[e_con4] = s_localBus[e_con4] & 0xFFFFFF9F;
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_fifoInt], 0);
return(&s_sigEvent);
}
return(0);
}

The ISR is attached as follows
d_interruptId = InterruptAttach( d_pciRegs.Interrupt_Line, &isr,
s_localBus,
4096, 0);

All the variables are declared private static data members of the class
deviceName as:-
static unsigned int *s_localBus;
static int d_channelId, d_connectionId,
d_interruptCodes[e_numberOfIntTypes]
;
static struct sigevent s_sigEvent;

Can anybody point to the mistake I am making. Your help will be
appreciated.
Thanks,
Tray.

I believe with interrupt handlers, you shouldn’t pass the member function of
an object unless it’s static. Otherwise, depending on inheritance, you
can’t know the location of the function until runtime via a vtable.

I’m not sure if that is your issue, (Mario’s suggestions are also valid),
but more of an “watch out” when mixing C++ and interrupt handlers.

Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>


Mario Charest postmaster@127.0.0.1 wrote in message
news:ar34t1$fev$1@inn.qnx.com

“Tray Karra” <> tkarra@ces.clemson.edu> > wrote in message
news:ar0tar$c2$> 1@inn.qnx.com> …
Hello all,
I have a problem with InterruptAttach(). The ISR is not generating
the
required pulses because it is not able to correctly access the device’s
memory( i am pretty sure that this is the problem).

You should be able to at least get 1 interrupt. Make sure the interrupt
isn’t shared with other device and check if you at least get one
interrupt.
If you do at least you know the settup of the ISR is ok. If you don’t get
at least one interrupt, the device is probably not configured properly.


I am wondering what
value should I pass for the void* area parameter of InterruptAttach()
(look
below for a detailed description).

In the ISR you can pass what ever value you want (it could be a pointer
the
the class object reducing the number of static variable you are using)

I have a driver in C++ for a PCI device, namely class deviceName.
The
device memory is mapped into the calling process address space as static
unsigned int s_localBus = (unsigned int) mmap_device_memory(0, 4096,
flags, 0, offset). The ISR should read the device’s registers and
determines
which of the several interrupts (DMA, FIFO, HW interrupts) have been
raised
and clears those interrupts alarms by writing to those device registers
and
then sends a pulse with an appropriate code value that reflects which of
the
interrupts has occured. The code in the ISR looks as follows:-

const struct sigevent* deviceName::isr(void* , int)
{
if(s_localBus[e_intConStat] & 0x00008000)
{
// Device Local interrupt input is active. See which one we
have:
if(s_localBus[e_con2] & 0x00020000)
{
// DMA interrupt. Which channel?
if(s_localBus[e_intConStat] & 0x00200000)
{
// DMA channel 0; clear the interrupt status
s_localBus[e_dmaComStat] = s_localBus[e_dmaComStat]
|
0x00000008;
// Return the pulse
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_dmaInt], 0);
return(&s_sigEvent);
}
else if(s_localBus[e_con2] & 0x00040000)
{
// FIFO interrupt
s_localBus[e_con4] = (s_localBus[e_con4] & 0xFFFFFF9F) |
0x00000020;
s_localBus[e_con2] = s_localBus[e_con2] & 0xFFFBFFFF;
s_localBus[e_con4] = s_localBus[e_con4] & 0xFFFFFF9F;
SIGEV_PULSE_INIT(&s_sigEvent, d_connectionId,
SIGEV_PULSE_PRIO_INHERIT, d_interruptCodes[e_fifoInt], 0);
return(&s_sigEvent);
}
return(0);
}

The ISR is attached as follows
d_interruptId = InterruptAttach( d_pciRegs.Interrupt_Line, &isr,
s_localBus,
4096, 0);

All the variables are declared private static data members of the class
deviceName as:-
static unsigned int *s_localBus;
static int d_channelId, d_connectionId,
d_interruptCodes[e_numberOfIntTypes]
;
static struct sigevent s_sigEvent;

Can anybody point to the mistake I am making. Your help will be
appreciated.
Thanks,
Tray.
\