I had some strange things like that because (but I was using RTAI) a irq_ack
is needed in irq routine, otherwise the irq routine was called twice(!).
Perhaps you try to disable interrupts (maybe only you interrupt) during the
routine or add a code to avoid this. In fact it seems that your code is not
"reentrant" (it means that it is interrupted by itself during the
execution).
To know if this happen just try to add this code:
int in_irq=0; //as global
int double_irq=0; // counter for debug
unsigned int PII_intr_handler(unsigned int irq, struct pt_regs *regs)
{
u8 * buff;
u8 * ptr;
u32 part;
int i;
if(in_irq==0) /* if not entered yet */
{
in_irq=1; /* sign that i'm in */
......... /* do everything */
in_irq=0; /* sign finished everything */
}
else
{
double_irq++; /* for debugging purpose only */
}
}
I hope this helps,
Raffaele
Frederic Cazenave wrote:
> In my module, most of my variables are set by a dsp on a pci board. This
> variables are on a Dual Port Ram (dpram) and I access them with a
> pointer on a structure (piraq).
>
> An handler of interrupt uses 2 pointers to know where to get the data on
> dpram (piraq->bufptr[], piraq->flag) and one to know the amount of data
> to transfer (piraq->size).
>
> unsigned int PII_intr_handler(unsigned int irq, struct pt_regs *regs)
> {
> u8 * buff;
> u8 * ptr;
> u32 part;
> int i;
>
> buff = (u8 *) piraq->bufptr[1-(*(piraq->flag)&1)];
>
> *Pos= Pos_next;
>
> for (i=0;i<2;i++) {
> ptr = (u8 *)shm + sizeof(u32)+ Pos_next;
> part = Pos_next + *(piraq->size);
> if ( part > BUFF_SIZE ) {
> part = BUFF_SIZE - Pos_next;
> memcpy_fromio(ptr,buff + (OFFSET_DPRAM_U8 * i) ,part);
> ptr = (u8 *)shm + sizeof(u32);
> memcpy_fromio(ptr,buff + (OFFSET_DPRAM_U8 * i)
> ,*(piraq->size)-part);
> Pos_next = *(piraq->size) - part;
> }else {
> memcpy_fromio(ptr,buff + (OFFSET_DPRAM_U8 * i), *(piraq->size));
> Pos_next += *(piraq->size);
> }
> }
> #ifdef DEBUG
> state ^= 0x800;
> writew(state,STATUS);
> #endif
>
> outl(0x01000000,INTCSR); /* reset control register */
> outl(0x00000000,INTCSR); /* reset control register */
> rtl_hard_enable_irq(PII_Intr);
>
> return 0;
> }
>
> piraq->bufptr, piraq->flag, piraq->size are defined as following :
> (u32 *) piraq->bufptr[0] = (u32 *)(PII_DPRAM + BUFFER0);
> (u32 *) piraq->bufptr[1] = (u32 *)(PII_DPRAM + BUFFER1);
> (u32 *) piraq->flag = (u32 *)(PII_DPRAM + FLAG);
> (u32 *) piraq->size = (u32 *)(PII_DPRAM + SIZE);
>
> where PII_DPRAM is the virtual address of the dpram and BUFFER0,
> BUFFER1, FLAG and SIZE are the position of the variables in the DPRAM
>
> the line "(u32 *) piraq->size = (u32 *)(PII_DPRAM + SIZE);" causes my
> module to crash sometime if my interrupt handler is installed, EVEN IF
> MY HANDLER IS NOT CALLED, sometimes is happened during insmod or when I
> want to perform a memset_io on pci memory
>
> I can read write to piraq->size but sometime I've got the following
> message :
>
> Unable to handle kernel paging request at virtual address d0a91000
> current->tss.cr3 = 05527000, %cr3 = 05527000
> *pde = 05521063
> *pte = 00000000
> Oops: 0000
> CPU: 0
> EIP: 0010:[aic7xxx:__insmod_aic7xxx_S.bss_L256+285476/294155188]
> EFLAGS: 00210006
> eax: 00000000 ebx: d0a79a00 ecx: 0027a27f edx: 009ffffc
> esi: d0a91000 edi: d0087604 ebp: c5529df8 esp: c5529de8
> ds: 0018 es: 0018 ss: 0018
> Process memtest (pid: 1078, process nr: 62, stackpage=c5529000)
> Stack: 0000000a 00000000 00000000 d0a79a00 c5529e54 d00464c6 0000000a
> c5529e5c
> 00200096 00000000 00000000 00000028 00200096 d00554c4 0000174d 00000000
> 00000000 c5529e94 00000001 d0050018 c5520018 ffffff0a d004c648 00000010
> Call Trace: [aic7xxx:__insmod_aic7xxx_S.bss_L256+151238/294289426]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+212676/294227988]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+191000/294249664]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+176200/294264464]
> [ret_from_intr+0/32]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+212676/294227988]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+191000/294249664]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+176200/294264464]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+151238/294289426]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+287573/294153091]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+291125/294149539]
> [ret_from_intr+0/32]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+287573/294153091]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+291125/294149539]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+289610/294151054]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+234901/294205763]
> [sys_write+219/256]
> [aic7xxx:__insmod_aic7xxx_S.bss_L256+234380/294206284]
> [system_call+52/56]
> Code: f3 a5 f6 c2 02 74 02 66 a5 f6 c2 01 74 01 a4 8b 3d 80 8c 06
>
> If I comment this line or if I change my code to :
> int size; // as global
> .
> .
> .
> (u32 *) piraq->size = &size;
>
> everything is fine.
>
> Is there some restrictions concerning pointers in handler ???
>
> Thanks
>
> Fred
>
> --
>
> _________________________________________________________
> | |
> | Frederic CAZENAVE |
> | _/\_ /^= McGill Radar |
> | \_/ \// Box 198, MacDonald College |
> | | /-\ | Ste Anne de Bellevue |
> | || || Quebec, Canada H9X 3V9 |
> | Tel (514) 398 7733 fax (514) 398 7755 |
> | mailto:[EMAIL PROTECTED] |
> | http://www.mpl.orstom.fr/hydrologie/catch/ |
> |__________________________________________________________|
> -- [rtl] ---
> To unsubscribe:
> echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
> echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
> --
> For more information on Real-Time Linux see:
> http://www.rtlinux.org/rtlinux/
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
--
For more information on Real-Time Linux see:
http://www.rtlinux.org/rtlinux/