Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 846 → Rev 847

/shark/trunk/drivers/linuxc26/int.c
6,39 → 6,134
 
extern void *int_arg_table[MAX_INT_TABLE];
extern void *int_func_table[MAX_INT_TABLE];
int intr_count = 0;
 
#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.
*/
* Generic Linux interrupt handler.
*/
void linux_intr(int irq)
{
struct pt_regs regs;
intr_count++;
if (int_func_table[irq] != NULL)
(* (void (*)(int, void *dev_id, struct pt_regs *))int_func_table[irq])(irq, int_arg_table[irq], &regs);
intr_count--;
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, &regs);
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.
*/
* 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)
{
shark_handler_set(irq, (void *)(handler), 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 *a)
* Deallocate an irq
*/
void free_irq(unsigned int irq, void *dev_id)
{
struct int_handler **headp, *ihp;
 
shark_handler_remove(irq);
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;
}