Go to main content
Oracle® Solaris 11.3 デバイスドライバの記述

印刷ビューの終了

更新: 2016 年 11 月
 
 

割り込みハンドラの機能

ドライバのフレームワークとデバイスは、それぞれが割り込みハンドラに要求を提示します。すべての割り込みハンドラは、次のタスクを実行する必要があります。

  • デバイスが割り込みを行なっているかどうかを判定し、場合によっては割り込みを拒否する。

    割り込みハンドラは、まずデバイスを調べて、そのデバイスが割り込みを発行したかどうかを判定します。そのデバイスが割り込みを発行しなかった場合、ハンドラは DDI_INTR_UNCLAIMED を返す必要があります。この手順により、デバイスポーリングの実装が可能になります。指定された割り込み優先順位レベルのデバイスは、割り込みを発行した可能性があります。デバイスポーリングにより、デバイスが割り込みを発行したかどうかがシステムに通知されます。

  • デバイスが保守されていることをデバイスに通知する。

    保守についてデバイスに通知することは、大部分のデバイスに必要となる、デバイス固有の処理です。たとえば、SBus デバイスは、ドライバが SBus デバイスに停止を指示するまで割り込みを行う必要があります。この方法により、同じ優先順位レベルで割り込みを行うすべての SBus デバイスが保守されることが保証されます。

  • 任意の入出力リクエスト関連の処理を実行する。

    デバイスは、転送完了転送エラーなど、さまざまな理由で割り込みを行います。この手順は、必要に応じてデバイスのデータバッファーを読み取り、デバイスのエラーレジスタを調べ、データ構造体のステータスフィールドを設定するために、データアクセス関数の使用を伴うことがあります。割り込みのディスパッチや処理には比較的時間がかかります。

  • 別の割り込みを妨げる可能性のある追加の処理を行う。

    たとえば、デバイスから次のデータ項目を読み取ります。

  • DDI_INTR_CLAIMEDを返す

  • MSI 割り込みを常に取り込む必要がある。

    MSI-X 割り込みの場合、割り込みの取り込みは任意です。どちらの場合でも、割り込みの所有権を確認する必要はありません。これは、MSI 割り込みと MSI-X 割り込みはほかのデバイスと共有されないためです。

  • ホットプラグによる取り付けと複数の MSI または MSI-X 割り込みをサポートするドライバが、ホットプラグイベント用の別個の割り込みを保持し、その割り込み用の別個の ISR (割り込みサービスルーチン) を登録するようにする。

次の例は、mydev というデバイスの割り込みルーチンを示しています。

使用例 25  割り込みの例
static uint_t
mydev_intr(caddr_t arg1, caddr_t arg2)
{
    struct mydevstate *xsp = (struct mydevstate *)arg1;
    uint8_t     status; 
    volatile    uint8_t  temp;

    /*
     * Claim or reject the interrupt.This example assumes
     * that the device's CSR includes this information.
     */
    mutex_enter(&xsp->high_mu);

    /* use data access routines to read status */
    status = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
    if (!(status & INTERRUPTING)) {
        mutex_exit(&xsp->high_mu);
        return (DDI_INTR_UNCLAIMED); /* dev not interrupting */
    }
    /*
     * Inform the device that it is being serviced, and re-enable
     * interrupts. The example assumes that writing to the
     * CSR accomplishes this. The driver must ensure that this data
     * access operation makes it to the device before the interrupt
     * service routine returns. For example, using the data access
     * functions to read the CSR, if it does not result in unwanted
     * effects, can ensure this.
     */
    ddi_put8(xsp->data_access_handle, &xsp->regp->csr,
        CLEAR_INTERRUPT | ENABLE_INTERRUPTS);

    /* flush store buffers */
    temp = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
    
    mutex_exit(&xsp->mu);
    return (DDI_INTR_CLAIMED);
}

割り込みルーチンによって実行される手順のほとんどは、デバイス自体の詳細によって異なります。割り込みの原因の判定、エラー条件の検出、およびデバイスのデータレジスタへのアクセスについては、そのデバイスのハードウェアマニュアルを参照してください。