Rev 526 |
Rev 956 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
#include <linuxcomp.h>
#include <asm/ptrace.h>
#include <asm-generic/errno-base.h>
#include <linux/kernel.h>
extern void *int_arg_table
[MAX_INT_TABLE
];
extern void *int_func_table
[MAX_INT_TABLE
];
#define MAX_IRQS 16
#ifndef NIL
#define NIL -1 /*+ integer unvalid value +*/
#endif
struct int_handler
{
void (*func
)(int, void *dev_id
, struct pt_regs
*);
void *data
;
int flags
;
struct int_handler
*next
;
};
static struct irq_handler_list
{
struct int_handler
*handlers
;
} irq_list
[MAX_IRQS
];
void init_linux_irq
();
extern void fast_call_intr
(int no
);
extern void* malloc(int size
);
extern void free(void *ptr
);
extern int handler_set
(int no
, void (*fast
)(int), int pi
, BYTE lock
);
extern int handler_remove
(int no
);
unsigned long intr_count
= 0;
static int init
= 0;
/*
* Generic Linux interrupt handler.
*/
void linux_intr
(int irq
)
{
struct pt_regs regs
;
struct int_handler
*ihp
;
// irq_mask(irq);
intr_count
++;
ihp
=irq_list
[irq
].
handlers;
while (ihp
) {
(*ihp
->func
)(irq
, ihp
->data
, ®s
);
ihp
=ihp
->next
;
}
intr_count
--;
// irq_unmask(irq);
}
void add_list
(struct int_handler
** headp
, struct int_handler
*ihp
)
{
if (*headp
== NULL
) {
*headp
=ihp
;
return;
}
ihp
->next
=*headp
;
*headp
=ihp
;
}
#define USE_IRQ_SERVER
/*
* Attach a handler to an IRQ.
*/
int request_irq
(unsigned int irq
, void (*handler
)(int, void *dev_id
, struct pt_regs
*), unsigned long flags
, const char *device
, void *dev_id
)
{
struct int_handler
*ihp
;
if (init
== 0)
init_linux_irq
();
ihp
=malloc(sizeof(struct int_handler
));
if (ihp
== NULL
)
return -ENOMEM
;
if (irq_list
[irq
].
handlers == NULL
)
{
//* Warning: check if irq is used from somebody that doesn't share!
#ifdef USE_IRQ_SERVER
shark_handler_set
(irq
, NULL
, NULL
);
#else
handler_set
(irq
, linux_intr
, NIL
, TRUE
);
#endif
}
ihp
->func
= handler
;
ihp
->flags
= flags
;
ihp
->data
= dev_id
;
ihp
->next
= NULL
;
add_list
(&irq_list
[irq
].
handlers, ihp
);
return 0;
}
/*
* Deallocate an irq
*/
void free_irq
(unsigned int irq
, void *dev_id
)
{
struct int_handler
**headp
, *ihp
;
headp
=&irq_list
[irq
].
handlers;
while (*headp
)
{
ihp
=*headp
;
if (ihp
->data
== dev_id
)
{
*headp
=ihp
->next
;
free(ihp
);
break;
}
headp
=&ihp
->next
;
}
if (irq_list
[irq
].
handlers == NULL
)
{
handler_remove
(irq
);
}
}
void init_linux_irq
()
{
int i
;
for (i
=0; i
<MAX_IRQS
; i
++)
{
irq_list
[i
].
handlers = NULL
;
}
init
=1;
}