JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
デバイスドライバの記述     Oracle Solaris 10 8/11 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

パート I Solaris プラットフォーム用デバイスドライバの設計

1.  Solaris デバイスドライバの概要

2.  Solaris カーネルとデバイスツリー

3.  マルチスレッド

4.  プロパティー

5.  イベントの管理とタスクのキュー

6.  ドライバの自動設定

7.  デバイスアクセス: プログラム式入出力

8.  割り込みハンドラ

9.  ダイレクトメモリーアクセス (DMA)

10.  デバイスメモリーおよびカーネルメモリーのマッピング

11.  デバイスコンテキスト管理

12.  電源管理

電源管理システムのフレームワーク

デバイス電源管理

システム電源管理

デバイス電源管理モデル

電源管理の部品

複数の電源管理部品

電源管理状態

電源レベル

電源管理の依存関係

デバイスの自動電源管理

デバイス電源管理インタフェース

ビジーとアイドルの状態遷移

デバイスの電源状態の遷移

power() エントリポイント

システム電源管理モデル

自動停止しきい値

ビジー状態

ハードウェア状態

システムの自動電源管理

システム電源管理で使用されるエントリポイント

detach() エントリポイント

attach() エントリポイント

電源管理のデバイスアクセスの例

電源管理の制御フロー

電源管理インタフェースの変更点

13.  Solaris ドライバの強化

14.  階層化ドライバインタフェース (LDI)

パート II 特定の種類のデバイスドライバの設計

15.  文字デバイスのドライバ

16.  ブロックデバイスのドライバ

17.  SCSI ターゲットドライバ

18.  SCSI ホストバスアダプタドライバ

19.  ネットワークデバイスのドライバ

20.  USB ドライバ

パート III デバイスドライバの構築

21.  ドライバのコンパイル、ロード、パッケージ化、およびテスト

22.  デバイスドライバのデバッグ、テスト、およびチューニング

23.  推奨されるコーティング方法

パート IV 付録

A.  ハードウェアの概要

B.  Solaris DDI/DKI サービスの概要

C.  64 ビットデバイスドライバの準備

D.  コンソールフレームバッファードライバ

索引

システム電源管理モデル

ここでは、システム電源管理モデルについて詳しく説明します。このモデルには次の要素が含まれます。

自動停止しきい値

設定された時間にわたってアイドル状態が続いたあとに、システムを自動的にシャットダウンする、つまりシステムの電源を切ることができます。この時間のことを自動停止しきい値と呼びます。1995 年 10 月 1 日から 1999 年 6 月 30 日までの間に初回出荷された SPARC デスクトップシステムでは、この動作がデフォルトで有効です。詳細は、power.conf(4) のマニュアルページを参照してください。dtpower(1M) または power.conf(4) を使用すると自動停止機能をオーバーライドできます。

ビジー状態

システムのビジー状態は複数の方法で測定できます。現在サポートされている組み込みの基準値項目は、キーボード入力、マウス操作、tty 入力、平均負荷率、ディスク読み取り、および NFS 要求です。これらの項目のうち 1 つでもシステムをビジー状態にする可能性があります。組み込みの基準値に加えて、システムがビジー状態であることを示すことができるユーザー指定のプロセスを実行するためのインタフェースが定義されています。

ハードウェア状態

reg プロパティーをエクスポートするデバイスには、システムをシャットダウンする前に保存しなければならないハードウェア状態があるものとみなされます。reg プロパティーのないデバイスは状態なしとみなされます。ただし、デバイスドライバによってこの想定をオーバーライドできます。

値が needs-suspend-resumepm-hardware-state プロパティーをドライバがエクスポートする場合、状態を保存および復元するには、ハードウェア状態を持つが reg プロパティーは持たないデバイス (SCSI ドライバなど) を呼び出す必要があります。それ以外の場合、reg プロパティーがないことは、デバイスにハードウェア状態がないことを意味するものと解釈されます。デバイスのプロパティーの詳細は、第 4 章プロパティーを参照してください。

reg プロパティーを持ちハードウェア状態を持たないデバイスは、値が no-suspend-resumepm-hardware-state プロパティーをエクスポートできます。pm-hardware-state プロパティーの値として no-suspend-resume を使用すると、フレームワークがその状態を保存および復元するためにドライバを呼び出すことはありません。電源管理プロパティーの詳細は、pm-components(9P) のマニュアルページを参照してください。

システムの自動電源管理

次の条件に当てはまる場合、システムはシャットダウンされます。

システム電源管理で使用されるエントリポイント

デバイスのハードウェア状態の保存をドライバに要求するとき、システム電源管理はドライバの detach(9E) エントリポイントに DDI_SUSPEND コマンドを渡します。デバイスのハードウェア状態の復元をドライバに要求するとき、システム電源管理はドライバの attach(9E) エントリポイントに DDI_RESUME コマンドを渡します。

detach() エントリポイント

detach(9E) の構文は次のとおりです。

int detach(dev_info_t *dip, ddi_detach_cmd_t cmd);

reg プロパティーを持つデバイスと、pm-hardware-state プロパティーが needs-suspend-resume に設定されたデバイスは、デバイスのハードウェア状態を保存できる必要があります。フレームワークはドライバの detach(9E) エントリポイントを呼び出して、ドライバで状態を保存し、システムの電源が復旧したときに状態を復元できるようにします。DDI_SUSPEND コマンドを処理するために、detach(9E) は次のタスクを実行する必要があります。

デバイスをサスペンドしてその状態をメモリーに保存する処理をドライバで実行できない場合、ドライバは DDI_FAILURE を返す必要があります。フレームワークはそれ以降のシステム電源管理操作を中止します。

デバイスの電源を切ることに何らかのリスクを伴う場合があります。たとえば、テープが入った状態でテープドライブの電源を切ると、テープが損傷する可能性があります。そのような場合、attach(9E) で次の処理を実行する必要があります。

両方の可能性がある場合、DDI_SUSPEND 要求を拒否する必要があります。例 12-6 は、attach(9E) ルーチンで ddi_removing_power(9F) を使用して、DDI_SUSPEND コマンドが問題を引き起こすかどうかを調べる方法を示しています。

ダンプ要求は尊重される必要があります。フレームワークでは dump(9E) エントリポイントを使用して、メモリーの内容を格納した状態ファイルを書き出します。このエントリポイントの使用時にデバイスドライバに課せられる制限については、dump(9E) のマニュアルページを参照してください。

電源管理に対応した部品の detach(9E) エントリポイントを呼び出すとき、DDI_SUSPEND コマンドを使用すると、デバイスの電源が切れるときに状態が保存されます。ドライバは保留中のタイムアウトをキャンセルします。またドライバは、dump(9E) 要求を除いて、pm_raise_power(9F) の一切の呼び出しを抑制します。DDI_RESUME コマンドを使用した attach(9E) の呼び出しによってデバイスがレジュームされると、タイムアウトおよび pm_raise_power () の呼び出しもレジューム可能になります。このような可能性に適切に対処できるよう、ドライバはその状態の十分な追跡を継続する必要があります。次の例は、DDI_SUSPEND コマンドを実装した detach(9E) ルーチンを示しています。

例 12-6 DDI_SUSPEND を実装する detach(9E) ルーチン

int
xxdetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
    struct xxstate *xsp;
    int instance;

    instance = ddi_get_instance(dip);
    xsp = ddi_get_soft_state(statep, instance);

    switch (cmd) {
    case DDI_DETACH:
       /* ... */
    case DDI_SUSPEND:
       /*
        * We do not allow DDI_SUSPEND if power will be removed and
        * we have a device that damages tape when power is removed
        * We do support DDI_SUSPEND for Device Reconfiguration.
        */
        if (ddi_removing_power(dip) && xxdamages_tape(dip))
            return (DDI_FAILURE);
        mutex_enter(&xsp->mu);
        xsp->xx_suspended = 1;  /* stop new operations */
       /*
        * Sleep waiting for all the commands to be completed
        *
        * If a callback is outstanding which cannot be cancelled
        * then either wait for the callback to complete or fail the
        * suspend request
        *
        * This section is only needed if the driver maintains a
        * running timeout
        */
        if (xsp->xx_timeout_id) {
            timeout_id_t temp_timeout_id = xsp->xx_timeout_id;

            xsp->xx_timeout_id = 0;
            mutex_exit(&xsp->mu);
            untimeout(temp_timeout_id);
            mutex_enter(&xsp->mu);
        }
        if (!xsp->xx_state_saved) {
           /*
            * Save device register contents into
            * xsp->xx_device_state
            */
        }
        mutex_exit(&xsp->mu);
        return (DDI_SUCCESS);
    default:
        return (DDI_FAILURE);
}

attach() エントリポイント

attach(9E) の構文は次のとおりです。

int attach(dev_info_t *dip, ddi_attach_cmd_t cmd);

システムの電源が復旧すると、reg プロパティーを持つか、またはpm-hardware-state プロパティーの値が needs-suspend-resume である各デバイスの attach(9E) エントリポイントが、コマンド値 DDI_RESUME を使用して呼び出されます。システムのシャットダウンが中止された場合、電源が切れなかったにもかかわらず、サスペンドされた各ドライバがレジュームのために呼び出されます。したがって、attach(9E) のレジュームコードは、システムの電源が実際に切れたかどうかを想定しないものにする必要があります。

DDI_RESUME の時点で、電源管理フレームワークは部品の電源レベルを不明とみなします。デバイスの性質に応じて、ドライバの開発者には 2 つの選択肢があります。

次の例は、DDI_RESUME コマンドを使用した attach(9E) ルーチンを示します。

例 12-7 DDI_RESUME を実装する attach(9E) ルーチン

int
xxattach(devinfo_t *dip, ddi_attach_cmd_t cmd)
{
    struct xxstate *xsp;
    int    instance;

    instance = ddi_get_instance(dip);
    xsp = ddi_get_soft_state(statep, instance);

    switch (cmd) {
    case DDI_ATTACH:
    /* ... */
    case DDI_RESUME:
        mutex_enter(&xsp->mu);
        if (xsp->xx_pm_state_saved) {
            /*
             * Restore device register contents from
             * xsp->xx_device_state
             */
        }
       /*
        * This section is optional and only needed if the
        * driver maintains a running timeout
        */
        xsp->xx_timeout_id = timeout( /* ... */ );

        xsp->xx_suspended = 0;        /* allow new operations */
        cv_broadcast(&xsp->xx_suspend_cv);
       /* If it is possible to determine in a device-specific 
        * way what the power levels of components are without 
        * powering the components up,
        * then the following code is recommended
        */
        for (i = 0; i < num_components; i++) {
            xsp->xx_power_level[i] = xx_get_power_level(dip, i);
            if (xsp->xx_power_level[i] != XX_LEVEL_UNKNOWN)
                (void) pm_power_has_changed(dip, i, 
                    xsp->xx_power_level[i]);
        }
        mutex_exit(&xsp->mu);
        return(DDI_SUCCESS);
    default:
        return(DDI_FAILURE);
    }
}

注 - detach(9E) および attach(9E) インタフェースを使用すると、休止されているシステムをレジュームすることもできます。