kernels/linux-2.4.0/arch/m68k/atari/ataints.c
/*
 * atari_request_irq : add an interrupt service routine for a particular
 *                     machine specific interrupt source.
 *                     If the addition was successful, it returns 0.
 */
atari_request_irq : add an interrupt service routine for a particular
machine specific interrupt source.
If the addition was successful, it returns 0.
atari_request_irq : add an interrupt service routine for a particular machine specific interrupt source . If the addition was successful it returns 0 .
int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
                      unsigned long flags, const char *devname, void *dev_id)
{
	int vector;
	unsigned long oflags = flags;
	flags &= ~SA_SHIRQ;
	if (flags == SA_INTERRUPT) {
		printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n",
			__FUNCTION__, devname);
		flags = IRQ_TYPE_SLOW;
	}
	if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) {
		printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n",
		        __FUNCTION__, flags, oflags, devname);
		return -EINVAL;
	}
	if (!IS_VALID_INTNO(irq)) {
		printk ("%s: Unknown irq %d requested from %s\n",
		        __FUNCTION__, irq, devname);
		return -ENXIO;
	}
	vector = IRQ_SOURCE_TO_VECTOR(irq);
	if (flags == IRQ_TYPE_SLOW &&
		(irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE)) {
		printk ("%s: Slow irq requested for non-MFP source %d from %s\n",
		        __FUNCTION__, irq, devname);
		return -EINVAL;
	}
	if (vectors[vector] == bad_interrupt) {
		irq_handler[irq].handler = handler;
		irq_handler[irq].dev_id  = dev_id;
		irq_param[irq].flags   = flags;
		irq_param[irq].devname = devname;
		vectors[vector] =
			(flags == IRQ_TYPE_SLOW) ? slow_handlers[irq-STMFP_SOURCE_BASE] :
			(flags == IRQ_TYPE_FAST) ? atari_fast_irq_handler :
			                          atari_prio_irq_handler;
		atari_turnon_irq(irq);
		atari_enable_irq(irq);
		return 0;
	}
	else if (irq_param[irq].flags == flags) {
		irq_node_t *node;
		unsigned long flags;
		save_flags(flags);
		cli();
		if (irq_handler[irq].handler != atari_call_irq_list) {
			if (!(node = new_irq_node()))
				return -ENOMEM;
			node->handler = irq_handler[irq].handler;
			node->dev_id  = irq_handler[irq].dev_id;
			node->devname = irq_param[irq].devname;
			node->next = NULL;
			irq_handler[irq].handler = atari_call_irq_list;
			irq_handler[irq].dev_id  = node;
			irq_param[irq].devname   = "chained";
		}
		if (!(node = new_irq_node()))
			return -ENOMEM;
		node->handler = handler;
		node->dev_id  = dev_id;
		node->devname = devname;
		node->next = irq_handler[irq].dev_id;
		irq_handler[irq].dev_id = node;
		restore_flags(flags);
		return 0;
	} else {
		printk ("%s: Irq %d allocated by other type int (call from %s)\n",
		        __FUNCTION__, irq, devname);
		return -EBUSY;
	}
}
int atari_request_irq ( unsigned int irq , void ( * handler ) ( int , void * , struct pt_regs * ) , unsigned long flags , const char * devname , void * dev_id ) { int vector ; unsigned long oflags = flags ; flags &= ~ SA_SHIRQ ; if ( flags == SA_INTERRUPT ) { printk ( " \n " , __FUNCTION__ , devname ) ; flags = IRQ_TYPE_SLOW ; } if ( flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO ) { printk ( " \n " , __FUNCTION__ , flags , oflags , devname ) ; return - EINVAL ; } if ( ! IS_VALID_INTNO ( irq ) ) { printk ( " \n " , __FUNCTION__ , irq , devname ) ; return - ENXIO ; } vector = IRQ_SOURCE_TO_VECTOR ( irq ) ; if ( flags == IRQ_TYPE_SLOW && ( irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE ) ) { printk ( " \n " , __FUNCTION__ , irq , devname ) ; return - EINVAL ; } if ( vectors [ vector ] == bad_interrupt ) { irq_handler [ irq ] . handler = handler ; irq_handler [ irq ] . dev_id = dev_id ; irq_param [ irq ] . flags = flags ; irq_param [ irq ] . devname = devname ; vectors [ vector ] = ( flags == IRQ_TYPE_SLOW ) ? slow_handlers [ irq - STMFP_SOURCE_BASE ] : ( flags == IRQ_TYPE_FAST ) ? atari_fast_irq_handler : atari_prio_irq_handler ; atari_turnon_irq ( irq ) ; atari_enable_irq ( irq ) ; return 0 ; } else if ( irq_param [ irq ] . flags == flags ) { irq_node_t * node ; unsigned long flags ; save_flags ( flags ) ; cli ( ) ; if ( irq_handler [ irq ] . handler != atari_call_irq_list ) { if ( ! ( node = new_irq_node ( ) ) ) return - ENOMEM ; node -> handler = irq_handler [ irq ] . handler ; node -> dev_id = irq_handler [ irq ] . dev_id ; node -> devname = irq_param [ irq ] . devname ; node -> next = NULL ; irq_handler [ irq ] . handler = atari_call_irq_list ; irq_handler [ irq ] . dev_id = node ; irq_param [ irq ] . devname = " " ; } if ( ! ( node = new_irq_node ( ) ) ) return - ENOMEM ; node -> handler = handler ; node -> dev_id = dev_id ; node -> devname = devname ; node -> next = irq_handler [ irq ] . dev_id ; irq_handler [ irq ] . dev_id = node ; restore_flags ( flags ) ; return 0 ; } else { printk ( " \n " , __FUNCTION__ , irq , devname ) ; return - EBUSY ; } }
atari_request_irq : add an interrupt service routine for a particular
                     machine specific interrupt source.
atari_request_irq : add an interrupt service routine for a particular machine specific interrupt source .
/*
	 * The following is a hack to make some PCI card drivers work,
	 * which set the SA_SHIRQ flag.
	 */ /*
	 * Check type/source combination: slow ints are (currently)
	 * only possible for MFP-interrupts.
	 */ /* int has no handler yet */ /* If MFP int, also enable and umask it */ /* old handler is of same type -> handlers can be chained */ /* Only one handler yet, make a node for this first one */ /* new handlers are put in front of the queue */