このページを編集する際は、編集に関する方針に従ってください。

概要

引数

  • irq--アクションを設定したいIRQ番号
  • new--IRQへ登録するアクション

実装

/*

* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
*/

int setup_irq(unsigned int irq, struct irqaction * new) {

	struct irq_desc *desc = irq_desc + irq;
  • irqディスクリプタを取り出しdescへ設定
	struct irqaction *old, **p;
	unsigned long flags;
	int shared = 0;
	if (desc->handler == &no_irq_type)
		return -ENOSYS;
  • descのたハンドラがno_irq_typeである場合、-ENOSYS(38)を返して終了
	/*
	 * Some drivers like serial.c use request_irq() heavily,
	 * so we have to be careful not to interfere with a
	 * running system.
	 */
	if (new->flags & SA_SAMPLE_RANDOM) {
  • SA_SAMPLE_RANDOMのフラグが立っている場合、デバイスがランダムなイベントの発生源とすることができる
    • カーネルの乱数発生にも利用される(ユーザは、/dev/randomや/dev/urandomデバイスファイルから乱数を取得する際に、この機能を使用している)
		/*
		 * This function might sleep, we want to call it first,
		 * outside of the atomic block.
		 * Yes, this might clear the entropy pool if the wrong
		 * driver is attempted to be loaded, without actually
		 * installing a new handler, but is this really a problem,
		 * only the sysadmin is able to do this.
		 */
		rand_initialize_irq(irq);
	}
	/*
	 * The following block of code has to be executed atomically
	 */
	spin_lock_irqsave(&desc->lock,flags);
  • スピンロックdesc->lockの取得を試み、取得に成功した場合、外部割り込みを無効化しEFLAGSレジスタの値をflagsへ設定する
	p = &desc->action;
  • irqディスクリプタのアクションをpに設定する
	if ((old = *p) != NULL) {
  • actionが登録されている場合:
		/* Can't share interrupts unless both agree to */
		if (!(old->flags & new->flags & SA_SHIRQ)) {
  • 割り込みを共有できない場合:
    • SA_SHIRQが立っている場合は、他のデバイスとのIRQライン共有を許可する
  • SA_SHIRQは0x04000000と定義されている
    • SA_SHIRQはPCIとEISAに共有された割り込みサポートの有無
			spin_unlock_irqrestore(&desc->lock,flags);
  • スピンロックdesc->lockを開放し、flagsをEFLAGSへ書き戻し、可能であればプリエンプションする。
			return -EBUSY;
		}
		/* add new interrupt at end of irq queue */
		do {
			p = &old->next;
  • pをoldの後に追加する
			old = *p;
  • pをoldに設定する
		} while (old);
  • oldがnullになるまで繰り返す
    • irqキューの末尾に新たに割り込みを追加する
		shared = 1;
	}
	*p = new;
	if (!shared) {
  • 割り込みが共有されない場合:
		desc->depth = 0;
		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT |
				  IRQ_WAITING | IRQ_INPROGRESS);
		if (desc->handler->startup)
			desc->handler->startup(irq);
		else
			desc->handler->enable(irq);
	}
	spin_unlock_irqrestore(&desc->lock,flags);
  • スピンロックdesc->lockを開放し、flagsをEFLAGSへ書き戻し、可能であればプリエンプションする。
	new->irq = irq;
	register_irq_proc(irq);
	new->dir = NULL;
	register_handler_proc(irq, new);
	return 0;

}

呼出元


  • 1 -- 2016-01-19 (火) 22:25:58

履歴

  • 作者:ひら
  • 日付:2005/5/9
  • 対象:2.6.10
    更新日更新者更新内容

コメント

  • 1 -- 1? 2016-01-19 (火) 22:27:00
  • 1 -- -1'? 2016-01-19 (火) 22:27:02
    • 1' -- 1? 2016-01-19 (火) 22:27:03
  • 1 -- 1? 2016-01-19 (火) 22:27:05

  • 1 -- 1? 2016-01-19 (火) 22:26:59

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-19 (火) 22:27:05 (436d)