Oracle® Solaris 11.2 デバイスドライバの記述

印刷ビューの終了

更新: 2014 年 9 月
 
 

ファームウェア互換性

デバイスが正常に機能するには、デバイスのファームウェアとデバイスドライバの互換性がなければなりません。デバイスドライバをインストールまたはアップグレードする前に、ファームウェアとの互換性をチェックする必要があります。互換性のあるファームウェアが見つからない場合は、デバイスドライバの実装によって、デバイスドライバがインストールまたはアップグレードされないように保証する必要があります。


注 -  IPS を使用してドライバをパッケージすれば、互換性のないファームウェアが見つかったとき、ドライバパケットがシステムにダウンロードされる前にユーザーに通知できます。詳細は、Driver Packagingを参照してください。

好ましいデバイスドライバの設計では、1 つ以上の ELF (実行可能リンク形式) モジュール内にファームウェアをカプセル化し、attach() 関数を使用してファームウェアのバージョンを管理します。ELF モジュール内にファームウェアをカプセル化するには、elfwrap(1) コマンドを使用します。ファームウェア ELF モジュールは、misc モジュールとしてモジュールリンケージスタブとリンクされます。ファームウェアモジュールは /kernel/misc ディレクトリに存在します。

次のフローチャートに、デバイスドライバの attach() 関数でファームウェアのバージョンを管理する方法を示します。

図 1-1  attach() 関数でのファームウェアのバージョン管理

image:attach() 関数でのファームウェアのバージョン管理

詳細は、 attach (9E) ddi_modopen (9F) ddi_modsym (9F) 、および ddi_modclose (9F) のマニュアルページを参照してください。


注 -  mwluath、および hwarc など、一部のデバイスには不揮発性メモリーが搭載されていません。このようなデバイスでは、デバイスドライバは条件を一切チェックせずにファームウェアをロードします。

ファームウェアのバージョンをチェックする attach() 関数の一般的な疑似コードは次のとおりです。

static int xxxx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
        .....
    ddi_modhandle_t modfn;
    int errno;
    uint32_t *fwvp;
       .....
    long fw_version;
    .....

    /* Check if firmware update is disabled. 
    *  If firmware update is disabled, return.
    *  The setting is stored in a config file.
    */
    if(dip->firmware_disable_update){
        return (0);  
    }

    /* Get the current firmware version. */
    fw_version = xxxx_get_firmware_version(dip,...);
   
     /* Check if the firmware version is correct and if force update is disabled. */
     if(fw_version == REQUIRED_FIRMWARE_VERSION){
        if(dip->firmware_force_update == 0){
        return (0);   
    }
        /* Even though the firmware version matches, update is forced. */
    }


    /* Open the firmware file by using ddi_modopen. */
    modfn = ddi_modopen(FIRMWARE_FILENAME, KRTLD_MODE_FIRST, &errno);
    if (errno){
    /* handle error */
    }

    /* locate the firmware */
    fwvp = ddi_modsym(modfn, FIRMWARE_VERSION_NAME, &errno);
    if (errno){
            /* handle error */
          (void) ddi_modclose(modfn);
    }
 
    /* Check if the firmware version in the module is correct. */
    if (*fwvp != REQUIRED_FIRMWARE_VERSION){
        if(dip->firmware_force_update == 0){
       
            /* close the firmware module file */
            (void) ddi_modclose(modfn);   
        return (0);   
    }
        /* Even tough the firmware version in the module does not match, 
         * update is forced.
         */
     }   
 
    /* Update the firmware. */
        xxx_update_firmware(dip,....);

    /* Close the FIRMWARE file */
    (void) ddi_modclose(modfn);
   
      .....
    // resume attach
}