共用 EEH プログラミング・モデル

共用 EEH プログラミング・モデルの場合、EEH カーネル・サービスは、以下の状態マシンをドライバーに提示します。

  1. スロットは NORMAL 状態で開始します。
  2. EEH イベントが発生すると、ドライバーはすべての F を MMIO ロードから受け取ります。 すべての F がドライバーの正しい値である可能性があるため、ドライバーは eeh_read_slot_state() を呼び出してイベントを確認する必要があります。
  3. eeh_read_slot_state () は、スロットが凍結されていることを検出すると、すべての登録済みドライバーに EEH_DD_SUSPEND メッセージをブロードキャストし、スロット状態は SUSPEND に移行します。 このようなカーネル・メッセージは、コールバック・ルーチンを順次呼び出すことによってブロードキャストされます。 メッセージは INTIODONE 優先順位でブロードキャストされます。
  4. ドライバーは、EEH_DD_SUSPEND メッセージを受け取ると、以下のいずれかを行うことができます。
    1. アダプターからデバッグ・データを収集し、スロットのリセットに進みます。

      デバッグ・データの収集は、リカバリー・プロセスのオプションのステップです。ドライバーは、最初に EEH イベントの原因を理解するために、アダプター上の特定のレジスターを読み取ることを選択できます。

      デバッグ・データを収集するには、ドライバーがアダプターに対して PIO を有効にする必要があります。 EEH イベントが発生すると、PIO は凍結されます。 PIO を有効にするには:
      1. マスター・ドライバーは eeh_enable_pio()を呼び出す必要があります。 マスター・ドライバーは EEH カーネル・サービスによって選出されます。 これは、コールバック・ルーチンに設定された EEH_MASTER フラグを持ち、コールバック・チェーンで呼び出される最後のドライバーです。 これにより、共用 EEH ドメイン内の他のすべてのドライバーがリカバリーの最後のステップを完了し、マスター・ドライバーが次のステップ (PIO の使用可能化など) に進むことができるようになります。

        eeh_enable_pio() が呼び出されると、PIO が有効になっていることを示す EEH_DD_DEBUG メッセージがドライバーに送信され、スロットの状態が DEBUG に移行します。

      2. その後、ドライバーがデータを収集します。

        eeh_enable_pio () は複数回呼び出すことができます。 呼び出されるたびに、別の EEH_DD_DEBUG メッセージがブロードキャストされます。

      3. ドライバーは、EEH_DD_SUSPEND または EEH_DD_DEBUG メッセージを受け取ると、eh_slot_error () を呼び出して、ハードウェア・デバッグ・データを含む AIX® エラー・ログ・エントリーを作成します。 このステップは、EEH イベントの理由を判別するために必要です。
      4. マスター・ドライバーは、eeh_reset_slot () を呼び出してスロットをリセットする必要があります。 スロットを複数回リセットする必要がないため、リセットされるドライバー呼び出しは 1 つだけです。
    2. スロットをリセットするには、直接続行してください。
  5. PCI バス上のリセット・ラインは、スロットをリセットするために、活動化と非活動化の間で 100 ミリ秒の遅延で切り替えられます。 遅延はデバイス・ドライバーには表示されず、eeh_reset_slot () カーネル・サービスによって内部的に強制されます。 スロットは、ACTIVATE 状態と DEACTIVATE 状態の間を内部的に移動します。
  6. 中間ブリッジ (アダプター上のブリッジなど) が存在する場合、リセットが正常に終了すると、EEH カーネル・サービスは eeh_configure_bridge () サービスを使用してブリッジを構成します。 また、カーネル・サービスは、リセット回線の非活動化とブリッジの構成の間に一定の遅延を強制します。

    デバイス・ドライバーは、eh_configure_bridge () を直接呼び出す必要はありません。

  7. すべてが正常に行われると、スロット・リカバリーが完了したことを示す EEH_DD_RESUME メッセージがドライバーに送信されます。
  8. この時点で、ほとんどのドライバーは、通常の操作を再開する前にアダプターを再初期化する必要があります。 通常、再初期化には、構成スペース (BAR やキャッシュ・ラインなど) の部分的なリストアが必要です。 リストアする構成スペース・レジスターの決定は、デバイスによって異なります。
    注: これは通常のリカバリー・シーケンスです。 いずれかのサービスが失敗すると、EEH_DD_DEAD メッセージがブロードキャストされ、アダプターに使用不可のマークを付けるようにドライバーに要求します (例えば、ドライバーが何らかのクリーンアップ作業を実行し、内部状態に適切なマークを付ける必要がある場合があります)。 マスター・ドライバーは、eeh_slot_error () を呼び出して AIX® エラー・ログを作成し、アダプターに永続的に使用不可のマークを付ける必要があります。
ドライバー開発者は、以下の 2 つの特別なシナリオに注意する必要があります。
  1. ドライバーは、 EEH_DD_SUSPEND メッセージまたは EEH_DD_DEAD メッセージのいずれかを受け取ると、 EEH_SUCC 戻りコードの代わりに、コールバック・ルーチンから EEH_BUSY 戻りコードを返すことができます。 EEH カーネル・サービスが EEH_BUSY メッセージを受信すると、EEH カーネル・サービスはしばらく待機してから、同じドライバーを再度呼び出します。 このプロセスは、EEH カーネル・サービスが別の戻りコードを受け取るまで続きます。 この処理が繰り返されるのは、一部のドライバーがリカバリーを続行する前にクリーンアップする時間が長くなるためです。 クリーンアップには、kproc の強制終了やユーザー・レベル・アプリへの通知などのアクティビティーが含まれます。
  2. プラットフォーム状態の制限のために eeh_enable_dma() および eeh_enable_pio() が成功しない場合、アクションを実行しない限り、サービスは EEH_FAIL 戻りコードとそれに続く EEH_DD_DEAD メッセージを返します。 EEH_FAIL 戻りコードを受け取らないようにするには、 eeh_init_multifunc() カーネル・サービスの開始時にドライバーが EEH_ENABLE_NO_SUPPORT_RC フラグを指定する必要があります。 EEH_ENABLE_NO_SUPPORT_RC フラグが指定されている場合、 eeh_enable_pio() および eeh_enable_dma() は、ドライバーがデバッグ・データを収集できないが、リカバリーの次のステップに進むことができることをドライバーに示す EEH_NO_SUPPORT 戻りコードを返します。 詳しくは、 eeh_read_slot_stateを参照してください。

以下の表に、使用できる EEH カーネル・サービスをリストします。

エクスポートされるカーネル・サービスは、 注: eeh_init () および eeh_init_multifunc () のみです。 他のすべてのカーネル・サービスは、eeh_handle カーネル・サービスで関数ポインターを使用して呼び出されます。
カーネル・サービス 単一関数 共用 EEH プロセス環境 環境の中断
eeh_init Y N Y N
eeh_init_multifunc N Y Y N
eeh_clear Y Y Y N
eeh_read_slot_state Y Y Y Y
eeh_enable_pio Y Y Y Y
eeh_enable_dma Y Y Y Y
eeh_enable_slot Y N Y Y
eeh_disable_slot Y N Y Y
eh_reset_slot Y Y Y Y
EH スロット・エラー Y Y Y Y
EH ブロードキャスト N Y Y Y