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

📄 irq.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
	__save_flags(flags);	if ((flags & PSR_PIL) != PSR_PIL)		local_enabled = 1;	/* default to local */	retval = 2 + local_enabled;	/* check for global flags if we're not in an interrupt */	if (!local_irq_count(smp_processor_id())) {		if (local_enabled)			retval = 1;		if (global_irq_holder == (unsigned char) smp_processor_id())			retval = 0;	}	return retval;}void __global_restore_flags(unsigned long flags){	switch (flags) {	case 0:		__global_cli();		break;	case 1:		__global_sti();		break;	case 2:		__cli();		break;	case 3:		__sti();		break;	default:	{		unsigned long pc;		__asm__ __volatile__("mov %%i7, %0" : "=r" (pc));		printk("global_restore_flags: Bogon flags(%08lx) caller %08lx\n", flags, pc);	}	}}#endif /* CONFIG_SMP */void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs){        int i;	struct irqaction * action;	unsigned int cpu_irq;		cpu_irq = irq & NR_IRQS;	action = *(cpu_irq + irq_action);        printk("IO device interrupt, irq = %d\n", irq);        printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, 		    regs->npc, regs->u_regs[14]);	if (action) {		printk("Expecting: ");        	for (i = 0; i < 16; i++)                	if (action->handler)                        	prom_printf("[%s:%d:0x%x] ", action->name,				    (int) i, (unsigned int) action->handler);	}        printk("AIEEE\n");	panic("bogus interrupt received");}void handler_irq(int irq, struct pt_regs * regs){	struct irqaction * action;	int cpu = smp_processor_id();#ifdef CONFIG_SMP	extern void smp4m_irq_rotate(int cpu);#endif	irq_enter(cpu, irq);	disable_pil_irq(irq);#ifdef CONFIG_SMP	/* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */	if(irq < 10)		smp4m_irq_rotate(cpu);#endif	action = *(irq + irq_action);	kstat.irqs[cpu][irq]++;	do {		if (!action || !action->handler)			unexpected_irq(irq, 0, regs);		action->handler(irq, action->dev_id, regs);		action = action->next;	} while (action);	enable_pil_irq(irq);	irq_exit(cpu, irq);}#ifdef CONFIG_BLK_DEV_FDextern void floppy_interrupt(int irq, void *dev_id, struct pt_regs *regs);void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs){	int cpu = smp_processor_id();	disable_pil_irq(irq);	irq_enter(cpu, irq);	kstat.irqs[cpu][irq]++;	floppy_interrupt(irq, dev_id, regs);	irq_exit(cpu, irq);	enable_pil_irq(irq);}#endif/* Fast IRQ's on the Sparc can only have one routine attached to them, * thus no sharing possible. */int request_fast_irq(unsigned int irq,		     void (*handler)(int, void *, struct pt_regs *),		     unsigned long irqflags, const char *devname){	struct irqaction *action;	unsigned long flags;	unsigned int cpu_irq;#ifdef CONFIG_SMP	struct tt_entry *trap_table;	extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3;#endif		cpu_irq = irq & NR_IRQS;	if(cpu_irq > 14)		return -EINVAL;	if(!handler)		return -EINVAL;	action = *(cpu_irq + irq_action);	if(action) {		if(action->flags & SA_SHIRQ)			panic("Trying to register fast irq when already shared.\n");		if(irqflags & SA_SHIRQ)			panic("Trying to register fast irq as shared.\n");		/* Anyway, someone already owns it so cannot be made fast. */		printk("request_fast_irq: Trying to register yet already owned.\n");		return -EBUSY;	}	save_and_cli(flags);	/* If this is flagged as statically allocated then we use our	 * private struct which is never freed.	 */	if (irqflags & SA_STATIC_ALLOC) {	    if (static_irq_count < MAX_STATIC_ALLOC)		action = &static_irqaction[static_irq_count++];	    else		printk("Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",		       irq, devname);	}		if (action == NULL)	    action = (struct irqaction *)kmalloc(sizeof(struct irqaction),						 GFP_KERNEL);		if (!action) { 		restore_flags(flags);		return -ENOMEM;	}	/* Dork with trap table if we get this far. */#define INSTANTIATE(table) \	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \		SPARC_BRANCH((unsigned long) handler, \			     (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;	INSTANTIATE(sparc_ttable)#ifdef CONFIG_SMP	trap_table = &trapbase_cpu1; INSTANTIATE(trap_table)	trap_table = &trapbase_cpu2; INSTANTIATE(trap_table)	trap_table = &trapbase_cpu3; INSTANTIATE(trap_table)#endif#undef INSTANTIATE	/*	 * XXX Correct thing whould be to flush only I- and D-cache lines	 * which contain the handler in question. But as of time of the	 * writing we have no CPU-neutral interface to fine-grained flushes.	 */	flush_cache_all();	action->handler = handler;	action->flags = irqflags;	action->mask = 0;	action->name = devname;	action->dev_id = NULL;	action->next = NULL;	*(cpu_irq + irq_action) = action;	enable_irq(irq);	restore_flags(flags);	return 0;}int request_irq(unsigned int irq,		void (*handler)(int, void *, struct pt_regs *),		unsigned long irqflags, const char * devname, void *dev_id){	struct irqaction * action, *tmp = NULL;	unsigned long flags;	unsigned int cpu_irq;		if (sparc_cpu_model == sun4d) {		extern int sun4d_request_irq(unsigned int, 					     void (*)(int, void *, struct pt_regs *),					     unsigned long, const char *, void *);		return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);	}	cpu_irq = irq & NR_IRQS;	if(cpu_irq > 14)		return -EINVAL;	if (!handler)	    return -EINVAL;	    	action = *(cpu_irq + irq_action);	if (action) {		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) {			for (tmp = action; tmp->next; tmp = tmp->next);		} else {			return -EBUSY;		}		if ((action->flags & SA_INTERRUPT) ^ (irqflags & SA_INTERRUPT)) {			printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq);			return -EBUSY;		}   		action = NULL;		/* Or else! */	}	save_and_cli(flags);	/* If this is flagged as statically allocated then we use our	 * private struct which is never freed.	 */	if (irqflags & SA_STATIC_ALLOC) {	    if (static_irq_count < MAX_STATIC_ALLOC)		action = &static_irqaction[static_irq_count++];	    else		printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",irq, devname);	}		if (action == NULL)	    action = (struct irqaction *)kmalloc(sizeof(struct irqaction),						 GFP_KERNEL);		if (!action) { 		restore_flags(flags);		return -ENOMEM;	}	action->handler = handler;	action->flags = irqflags;	action->mask = 0;	action->name = devname;	action->next = NULL;	action->dev_id = dev_id;	if (tmp)		tmp->next = action;	else		*(cpu_irq + irq_action) = action;	enable_irq(irq);	restore_flags(flags);	return 0;}/* We really don't need these at all on the Sparc.  We only have * stubs here because they are exported to modules. */unsigned long probe_irq_on(void){	return 0;}int probe_irq_off(unsigned long mask){	return 0;}/* djhr * This could probably be made indirect too and assigned in the CPU * bits of the code. That would be much nicer I think and would also * fit in with the idea of being able to tune your kernel for your machine * by removing unrequired machine and device support. * */void __init init_IRQ(void){	extern void sun4c_init_IRQ( void );	extern void sun4m_init_IRQ( void );	extern void sun4d_init_IRQ( void );    	switch(sparc_cpu_model) {	case sun4c:	case sun4:		sun4c_init_IRQ();		break;	case sun4m:#ifdef CONFIG_PCI		pcic_probe();		if (pcic_present()) {			sun4m_pci_init_IRQ();			break;		}#endif		sun4m_init_IRQ();		break;			case sun4d:		sun4d_init_IRQ();		break;	default:		prom_printf("Cannot initialize IRQ's on this Sun machine...");		break;	}	btfixup();}void init_irq_proc(void){	/* For now, nothing... */}

⌨️ 快捷键说明

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