主要讲下两个结构体及其关系和在系统中所处的位置:
每一个中断线或者叫中断向量都对应一个desc结构体,系统中所有的desc组成一个结构体数组。
struct irq_desc { unsigned int irq; struct timer_rand_state *timer_rand_state; unsigned int *kstat_irqs; #ifdef CONFIG_INTR_REMAP struct irq_2_iommu *irq_2_iommu; #endif irq_flow_handler_t handle_irq; //每个中断线都有一个中断处理程序 struct irq_chip *chip; //包含一些中断开关 屏蔽等工作 struct msi_desc *msi_desc; void *handler_data; void *chip_data; struct irqaction *action; /* IRQ action list */ //中断子程序链表 unsigned int status; /* IRQ status */ //说明这个中断线是否可以被共享 unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ unsigned int irq_count; /* For detecting broken IRQs */ unsigned long last_unhandled; /* Aging timer for unhandled count */ unsigned int irqs_unhandled; spinlock_t lock; #ifdef CONFIG_SMP cpumask_var_t affinity; unsigned int node; #ifdef CONFIG_GENERIC_PENDING_IRQ cpumask_var_t pending_mask; #endif #endif atomic_t threads_active; //这里的线程是怎么回事呢? wait_queue_head_t wait_for_threads; #ifdef CONFIG_PROC_FS struct proc_dir_entry *dir; #endif const char *name; } ____cacheline_internodealigned_in_smp;
struct irq_chip { const char *name; unsigned int (*startup)(unsigned int irq); void (*shutdown)(unsigned int irq); void (*enable)(unsigned int irq); void (*disable)(unsigned int irq); void (*ack)(unsigned int irq); void (*mask)(unsigned int irq); void (*mask_ack)(unsigned int irq); void (*unmask)(unsigned int irq); void (*eoi)(unsigned int irq); void (*end)(unsigned int irq); int (*set_affinity)(unsigned int irq, const struct cpumask *dest); int (*retrigger)(unsigned int irq); int (*set_type)(unsigned int irq, unsigned int flow_type); int (*set_wake)(unsigned int irq, unsigned int on); void (*bus_lock)(unsigned int irq); void (*bus_sync_unlock)(unsigned int irq); /* Currently used only by UML, might disappear one day.*/ #ifdef CONFIG_IRQ_RELEASE_METHOD void (*release)(unsigned int irq, void *dev_id); #endif /* * For compatibility, ->typename is copied into ->name. * Will disappear. */ const char *typename; };
struct irqaction { //每一个中断例程对应一个irqaction,都放在链表中 irq_handler_t handler; //这个结构体里面应该有指向中断子程序的指针 unsigned long flags; const char *name; void *dev_id; //在中断共享时用与区分中断子程序的 struct irqaction *next; //链表中指向下一个例程 int irq; //中断号 struct proc_dir_entry *dir; irq_handler_t thread_fn; //好奇怪 这里也有线程相关 struct task_struct *thread; unsigned long thread_flags; };