⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ataints.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Returns:	Nothing * * This function should be called during kernel startup to initialize * the atari IRQ handling routines. */void __init atari_init_IRQ(void){	int i;	/* initialize the vector table */	for (i = 0; i < NUM_INT_SOURCES; ++i) {		vectors[IRQ_SOURCE_TO_VECTOR(i)] = bad_interrupt;	}	/* Initialize the MFP(s) */#ifdef ATARI_USE_SOFTWARE_EOI	mfp.vec_adr  = 0x48;	/* Software EOI-Mode */#else	mfp.vec_adr  = 0x40;	/* Automatic EOI-Mode */#endif	mfp.int_en_a = 0x00;	/* turn off MFP-Ints */	mfp.int_en_b = 0x00;	mfp.int_mk_a = 0xff;	/* no Masking */	mfp.int_mk_b = 0xff;	if (ATARIHW_PRESENT(TT_MFP)) {#ifdef ATARI_USE_SOFTWARE_EOI		tt_mfp.vec_adr  = 0x58;		/* Software EOI-Mode */#else		tt_mfp.vec_adr  = 0x50;		/* Automatic EOI-Mode */#endif		tt_mfp.int_en_a = 0x00;		/* turn off MFP-Ints */		tt_mfp.int_en_b = 0x00;		tt_mfp.int_mk_a = 0xff;		/* no Masking */		tt_mfp.int_mk_b = 0xff;	}	if (ATARIHW_PRESENT(SCC) && !atari_SCC_reset_done) {		scc.cha_a_ctrl = 9;		MFPDELAY();		scc.cha_a_ctrl = (char) 0xc0; /* hardware reset */	}	if (ATARIHW_PRESENT(SCU)) {		/* init the SCU if present */		tt_scu.sys_mask = 0x10;		/* enable VBL (for the cursor) and									 * disable HSYNC interrupts (who									 * needs them?)  MFP and SCC are									 * enabled in VME mask									 */		tt_scu.vme_mask = 0x60;		/* enable MFP and SCC ints */	}	else {		/* If no SCU and no Hades, the HSYNC interrupt needs to be		 * disabled this way. (Else _inthandler in kernel/sys_call.S		 * gets overruns)		 */		if (!MACH_IS_HADES)			vectors[VEC_INT2] = falcon_hblhandler;	}	if (ATARIHW_PRESENT(PCM_8BIT) && ATARIHW_PRESENT(MICROWIRE)) {		/* Initialize the LM1992 Sound Controller to enable		   the PSG sound.  This is misplaced here, it should		   be in an atasound_init(), that doesn't exist yet. */		atari_microwire_cmd(MW_LM1992_PSG_HIGH);	}		stdma_init();	/* Initialize the PSG: all sounds off, both ports output */	sound_ym.rd_data_reg_sel = 7;	sound_ym.wd_data = 0xff;}static void atari_call_irq_list( int irq, void *dev_id, struct pt_regs *fp ){	irq_node_t *node;	for (node = (irq_node_t *)dev_id; node; node = node->next)		node->handler(irq, node->dev_id, fp);}/* * 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;	/*	 * The following is a hack to make some PCI card drivers work,	 * which set the SA_SHIRQ flag.	 */	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);	/*	 * Check type/source combination: slow ints are (currently)	 * only possible for MFP-interrupts.	 */	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) {		/* int has no handler yet */		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;		/* If MFP int, also enable and umask it */		atari_turnon_irq(irq);		atari_enable_irq(irq);		return 0;	}	else if (irq_param[irq].flags == flags) {		/* old handler is of same type -> handlers can be chained */		irq_node_t *node;		unsigned long flags;		save_flags(flags);		cli();		if (irq_handler[irq].handler != atari_call_irq_list) {			/* Only one handler yet, make a node for this first one */			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;		/* new handlers are put in front of the queue */		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;	}}void atari_free_irq(unsigned int irq, void *dev_id){	unsigned long flags;	int vector;	irq_node_t **list, *node;	if (!IS_VALID_INTNO(irq)) {		printk("%s: Unknown irq %d\n", __FUNCTION__, irq);		return;	}	vector = IRQ_SOURCE_TO_VECTOR(irq);	if (vectors[vector] == bad_interrupt)		goto not_found;	save_flags(flags);	cli();	if (irq_handler[irq].handler != atari_call_irq_list) {		/* It's the only handler for the interrupt */		if (irq_handler[irq].dev_id != dev_id) {			restore_flags(flags);			goto not_found;		}		irq_handler[irq].handler = NULL;		irq_handler[irq].dev_id  = NULL;		irq_param[irq].devname   = NULL;		vectors[vector] = bad_interrupt;		/* If MFP int, also disable it */		atari_disable_irq(irq);		atari_turnoff_irq(irq);		restore_flags(flags);		return;	}	/* The interrupt is chained, find the irq on the list */	for(list = (irq_node_t **)&irq_handler[irq].dev_id; *list; list = &(*list)->next) {		if ((*list)->dev_id == dev_id) break;	}	if (!*list) {		restore_flags(flags);		goto not_found;	}	(*list)->handler = NULL; /* Mark it as free for reallocation */	*list = (*list)->next;	/* If there's now only one handler, unchain the interrupt, i.e. plug in	 * the handler directly again and omit atari_call_irq_list */	node = (irq_node_t *)irq_handler[irq].dev_id;	if (node && !node->next) {		irq_handler[irq].handler = node->handler;		irq_handler[irq].dev_id  = node->dev_id;		irq_param[irq].devname   = node->devname;		node->handler = NULL; /* Mark it as free for reallocation */	}	restore_flags(flags);	return;not_found:	printk("%s: tried to remove invalid irq\n", __FUNCTION__);	return;}/* * atari_register_vme_int() returns the number of a free interrupt vector for * hardware with a programmable int vector (probably a VME board). */unsigned long atari_register_vme_int(void){	int i;	for(i = 0; i < 32; i++)		if((free_vme_vec_bitmap & (1 << i)) == 0)			break;		if(i == 16)		return 0;	free_vme_vec_bitmap |= 1 << i;	return (VME_SOURCE_BASE + i);}void atari_unregister_vme_int(unsigned long irq){	if(irq >= VME_SOURCE_BASE && irq < VME_SOURCE_BASE + VME_MAX_SOURCES) {		irq -= VME_SOURCE_BASE;		free_vme_vec_bitmap &= ~(1 << irq);	}}int atari_get_irq_list(char *buf){	int i, len = 0;	for (i = 0; i < NUM_INT_SOURCES; ++i) {		if (vectors[IRQ_SOURCE_TO_VECTOR(i)] == bad_interrupt)			continue;		if (i < STMFP_SOURCE_BASE)			len += sprintf(buf+len, "auto %2d: %10u ",				       i, kstat.irqs[0][i]);		else			len += sprintf(buf+len, "vec $%02x: %10u ",				       IRQ_SOURCE_TO_VECTOR(i),				       kstat.irqs[0][i]);		if (irq_handler[i].handler != atari_call_irq_list) {			len += sprintf(buf+len, "%s\n", irq_param[i].devname);		}		else {			irq_node_t *p;			for( p = (irq_node_t *)irq_handler[i].dev_id; p; p = p->next ) {				len += sprintf(buf+len, "%s\n", p->devname);				if (p->next)					len += sprintf( buf+len, "                    " );			}		}	}	if (num_spurious)		len += sprintf(buf+len, "spurio.: %10u\n", num_spurious);		return len;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -