深く分析してrequest_irqのdev_idパラメータの作用回転


0-11-03 23:22
深く分析してrequest_irqのdev_idパラメータ作用
 
Author:Dongas
Data:08-07-12
 
注:ケネルの中断処理モデルがよく分からない場合(例えば、irqactionの役割)この文書を参考にしてもいいです.
http://blog.chinaunix.net/u2/60011/showart.php?id=1079281
ここでは主にrequest_を話します.irqのパラメータdev_idの役割は、上の文書の内容に少し触れます.
 
Request_IRQの使用を申請し、割込み処理プログラムを登録するのがIRLQの役割です.
request_irq()関数のプロトタイプは以下の通りです./* kernel/irq/manage.c */
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
    const char *devname,
    void *dev_id);
 
我々は、カーネル共有を使用して中断すると、request_を知る.irqはdev_を提供しなければなりません.idパラメータ、dev_IDの値は一意でなければならない.ここで唯一のdev_を提供します.IDの値は一体何をするものですか?
 
最初はdev_と思っていましたIDの値は、共有中の断線上のどの機器が中断したかを判定するためにケネルに供給され、該当する中断処理関数を実行します.実際には違います.『Linux Kernel Development–Second Edition』第六章のShared Handlersという一節を見に来ました.その中にまとめられた文字は以下の通りです.
 
When the kersnel receives an interrupt,it invokes sequentially each registed handler on the line.The refore,アイアイアイアイティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティティアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアアハハハハハハダダダダダダダダダダダダダダダダダダダダダダch a feature.
 
この話の大体の意味は、中断が発生した時、カーネルは共有中の断線上のどの設備が中断されたかを判断していません.その中の断線上に登録されているすべての中断処理関数(つまり、Iqiaction->hander関数を循環的に実行します.したがって、irqaction->handler関数は、自分のハードウェアデバイスが中断されたかどうかを識別してから、この中断処理関数を実行する責任があります.通常は、このハードウェア装置が提供する割り込みフラグビットを読み取ることによって判断される.
 
この中の断線上に登録されているすべてのirqaction->handler関数をケネルループで実行する以上、どのハードウェアデバイスが中断したのかを識別することを中断処理関数自身に任せます.irqのdev_IDパラメータは一体何をするものですか?
 
まとめましたが、実はdev_.idの役割は主に2つあります.
一.処理プログラムの中断解放時にdev_に使用する.id
When your driver unloads,you need to unregister your interrupt handler and potentally disable the interrupt line.To do this,cal
void free_irq(unsigned int irq,void*devuid)
……
The fifth parameter、dev_id,is used prmarity for shared interrupt lineas.When n n n n n n interrupt handled is freed(discussed later)、dev_id provides a unique cookie to allow the removal of only the desired interrupt handler from the interrupt line.without this parameter,it would be impossible for the kersnel to knowhich handler movent moven.givent.inpt
 
ここの《LKD 2》ははっきり言って、free_を呼び出します.Iqが割り込み処理関数をキャンセルした場合(通常はアンインストール駆動時にその中断処理関数もキャンセルされます)、dev_IDは唯一なので、共有中の断線上の複数の割り込み処理プログラムから指定された一つを削除すると判断できます.このパラメータがないと、ケネルは与えられた断線上でどの処理プログラムを削除するかを知ることができません.
 
free_を見に来ます.irqのコード:void free_irq(unsigned int irq, void *dev_id)
{
    struct irq_desc *desc;
struct irqaction **p;
unsigned long flags;

WARN_ON(in_interrupt());
if (irq >= NR_IRQS)
return;

desc = irq_desc + irq;    /* irq_desc */
spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;        /* irq irqaction */
for (;;) {
struct irqaction *action = *p;

if (action) {
struct irqaction **pp = p;

p = &action->next;
if (action->dev_id != dev_id)
continue; /* , dev_id irqaction */

/* Found it - now remove it from the list of entries */
*pp = action->next; /* irqaction */

/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
if (desc->chip->release)
desc->chip->release(irq, dev_id);
#endif

if (!desc->action) {
desc->status |= IRQ_DISABLED;
if (desc->chip->shutdown)
desc->chip->shutdown(irq);
else
desc->chip->disable(irq);
}
recalculate_desc_flags(desc);
spin_unlock_irqrestore(&desc->lock, flags);
unregister_handler_proc(irq, action);

/* Make sure it's not being used on another CPU */
synchronize_irq(irq);
kfree(action);        /* (dev_id) irqaction */
return;
}
printk(KERN_ERR "Trying to free already-free IRQ %d
", irq);
spin_unlock_irqrestore(&desc->lock, flags);
return;
}
}

 
二.この割り込み処理プログラムを用いたデバイス構造体をこの割り込み処理プログラムに渡す.
まず二つの基礎条件を見ます.
1) カーネルの中の各設備の構造体はきっと唯一です.だからdev_を満足します.idの唯一のこの要求
2) dev_idパラメータは中断が発生したときに中断されたサービスプログラムに伝えられます.
典型的な中断サービスプログラムの定義は以下の通りである.
static irqreturn_t intr_handler(int irq、void*devuid、struct pturgs*regs)
 
すなわちrequest_irqのdev_IDパラメータは、この中断サービスプログラムのdev_に伝達されます.idそのため、ドライバのデバイス構造体をdev_に通すこともできます.idは中断サービスプログラムに伝えます.
このようにする作用は主に二つあります.
1) 中断サービスプログラムは、デバイス構造体の情報を使用することができます.
s 3 c 2410のiisオーディオ駆動のように、DMA Chanel構造体をdev_に通す.IDを中断サービスプログラムに渡す/* arch/arm/mach-s3c2410/dma.c */
int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client,void *dev)
{
err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
client->name, (void *)chan);
……
}
 
中断処理関数s 3 c 2410_を目的としています.dma_irq内ではchan構造体のdufメンバーとロード_が必要です.スターメンバーなど
使用方法は以下の通りです./* arch/arm/mach-s3c2410/dma.c */
static irqreturn_t
s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs)
{
struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw; /* request_irq dev_id , s3c2410_dma_chan , */
struct s3c2410_dma_buf *buf;
buf = chan->curr;
……
}
 
したがって,我々は装置構造をrequest_に渡すことができる.irqのdev_このようなIDパラメータの機構は、このデバイス構造体を割り込み処理関数で使用しており、これは大部分のドライバ共通の手法である.
 
2)前に述べたように、共有が中断されたら、中断処理関数自体は自分の設備産かどうかを識別する必要があるということです.
中断が生じた.通常、このハードウェア装置が提供する中断フラグビットを読み取ることによって判断される.
しばしばドライバで定義されているデバイス構造体には、このデバイスのIOアドレスが含まれています.オフセットを加えると、割り込み状態レジスタと割込みフラグビットのIOアドレス情報が算出されます.したがって、デバイス構造体をdev_に通す.IDがデバイス割込み処理プログラムに渡される別の役割は、共有割り込みを使用する場合、割り込み処理関数内で、そのデバイス構造(devuid)から提供された割込みFlagGフラグビットアドレス情報を読み取ることによって判断することができ、このデバイスが中断されたかどうかである.さらに、下の実行を続けるか、それとも次のirqaction->handler関数にジャンプして実行を判断します.もちろん、このデバイスが中断状態レジスタのIOアドレスを元々知っていれば、直接readlのアドレス情報を選択して判断することもできる.