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

ドキュメントの情報

はじめに

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

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

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

3.  マルチスレッド

4.  プロパティー

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

6.  ドライバの自動構成

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

8.  割り込みハンドラ

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

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

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

12.  電源管理

13.  Oracle Solaris ドライバの強化

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

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

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

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

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

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

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

20.  USB ドライバ

21.  SR-IOV ドライバ

SR-IOV の概要

SR-IOV の利点

サポートされるプラットフォーム

用語

SR-IOV デバイスドライバの概要

物理機能 (PF) ドライバ

仮想機能 (VF) ドライバ

デバイス構成パラメータ

pci.conf ファイル

デバイス構成パラメータの設定

Sparc OVM プラットフォームでの SR-IOV 構成

基本的なプラットフォームでの SR-IOV 構成

ブート構成シーケンス

SR-IOV インタフェースのサマリー

ドライバの ioctl

SR-IOV ドライバのインタフェース

pci_param_get() インタフェース

pci_param_get_ioctl() インタフェース

pci_plist_get() インタフェース

pci_plist_getvf() インタフェース

pciv_vf_config() インタフェース

pci_plist_lookup() インタフェース

pci_param_free() インタフェース

pciv_send() インタフェース

SR-IOV ドライバの ioctl

データ構造体

iov_param_ver_info 構造体

iov_param_validate 構造体

iov_param_desc 構造体

IOV_GET_VER_INFO ioctl

IOV_GET_PARAM_INFO Ioctl

IOV_VALIDATE_PARAM ioctl

ドライバのコールバック

ドライバ ioctl のサンプルコード

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

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

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

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

パート IV 付録

A.  ハードウェアの概要

B.  Oracle Solaris DDI/DKI サービスのサマリー

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

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

E.  pci.conf ファイル

索引

ドキュメントの品質向上のためのご意見をください
簡潔すぎた
読みづらかった、または難し過ぎた
重要な情報が欠けていた
内容が間違っていた
翻訳版が必要
その他
Your rating has been updated
貴重なご意見を有り難うございました!

あなたの貴重なご意見はより良いドキュメント作成の手助けとなります 内容の品質向上と追加コメントのためのアンケートに参加されますか?

SR-IOV ドライバの ioctl

SR-IOV ドライバの ioctl は、管理者が構成できるデバイス固有のパラメータを特定したり、特定の構成を適用する前にその構成を検証したりする場合に使用されます。次の各セクションでは、ioctl のデータ構造体やインタフェースについて説明します。

データ構造体

次の各セクションでは、ioctl を実装する前に PF ドライバで定義および初期化しておくべきデータ構造体を示します。

iov_param_ver_info 構造体

iov_param_ver_info 構造体は次のように定義されています。

#define IOV_IOCTL (('I' << 24) | ('O' << 16) | ('V' << 8))
#define IOV_GET_VER_INFO (IOV_IOCTL | 0)
#define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)
#define IOV_VALIDATE_PARAM (IOV_IOCTL | 2)
#define IOV_PARAM_DESC_VERSION  1

iov_param_ver_info 構造体には次のフィールドが含まれています。

typedef struct iov_param_ver_info {
uint32_t version; 
uint32_t num_params; 
} iov_param_ver_info_t;

各表記の意味は次のとおりです。

version

バージョン情報

num_params

パラメータの数

iov_param_validate 構造体

iov_param_validate 構造体は次のように定義されています。

  #define IOV_IOCTL (('I' << 24) | ('O' << 16) | ('V' << 8))
  #define IOV_GET_VER_INFO (IOV_IOCTL | 0)
  #define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)
  #define IOV_VALIDATE_PARAM  (IOV_IOCTL | 2)
  #define IOV_PARAM_DESC_VERSION  1

iov_param_validate には次のフィールドが含まれています。

typedef struct iov_param_validate {
     char pv_reason[MAX_REASON_LEN + 1];
     int32_t pv_buflen;
     /* encoded buffer containing params */
    char pv_buf[1];  /* size of buf is pv_buflen */          
} iov_param_validate_t;

各表記の意味は次のとおりです。

pv_reason

ioctl コールが失敗した場合の失敗理由を説明する ASCII 文字列。

pv_buflen

バッファー pv_buf の長さ

pv_buf

パラメータを含むバッファー

iov_param_desc 構造体

iov_param_desc 構造体は次のように定義されています。

     #define IOV_IOCTL  (('I' << 24) | ('O' << 16) | ('V' << 8))
  #define IOV_GET_VER_INFO (IOV_IOCTL | 0)
  #define IOV_GET_PARAM_INFO (IOV_IOCTL | 1)
  #define IOV_VALIDATE_PARAM (IOV_IOCTL | 2)
  #define IOV_PARAM_DESC_VERSION  1

構造体 iov_param_desc には次のフィールドが含まれています。

typedef struct iov_param_desc {
char pd_name[MAX_PARAM_NAME_SIZE];
char pd_desc[MAX_PARAM_DESC_SIZE];
int32_t pd_flag;   /* applicable for PF or VF or both */
int32_t pd_data_type; /* integer, string, plist */
/* Following 3 are applicable for integer data types */
uint64_t pd_default_value;
uint64_t pd_min64;    
uint64_t pd_max64;
char pd_default_string [MAX_PARAM_DEFAULT_STRING_SIZE];
} iov_param_desc_t; 

各表記の意味は次のとおりです。

pd_name

ldm(1M) コマンド内または pci.conf ファイル内で、パラメータに値を割り当てるために使用されます。

pd_desc

パラメータの簡易説明。

pd_flag

パラメータの適用対象が、PF のみ、VF のみ、PF と VF の両方のいずれであるかを示します。

pd_default_value

ldm() コマンドや pci.conf ファイルでパラメータが指定されていない場合にドライバによって割り当てられる値。

pd_min64

整数パラメータの値の最小範囲を指定します。

pd_max64

整数パラメータの値の最大範囲を指定します。

pd_default_string

パラメータが文字列の場合に使用されるデフォルト文字列を指定します。

IOV_GET_VER_INFO ioctl

IOV_GET_VER_INFO IOCTL() ioctl を実装する SR-IOV デバイスドライバは、iov_param_ver_info 構造体の version および num_params フィールドを設定し、その値を呼び出し元の関数に返すべきです。続いて呼び出し元の関数は、IOV_GET_PARAM_INFO() ioctl コールを使ってパラメータの記述を取得する際に必要となるバッファーのサイズを、version および num_params パラメータを使用して決定します。

IOV_GET_PARAM_INFO Ioctl

IOV_GET_PARAM_INFO() ioctl を呼び出すドライバの一般的な制御フローは次のようになります。

  1. iov_param_desc_t 構造体でサポートされる構成可能パラメータのそれぞれの記述を含む、この構造体の配列を保持します。この構造体の説明については、iov_param_desc 構造体を参照してください。

  2. iov_param_desc_t 構造体の配列をコピーして arg パラメータに出力します。iov_param_desc_t 構造体のフィールドは静的であり、コンパイル時に定義できます。

    配列の要素数は、IOV_GET_VER_INFO() ioctl コールから返された num_params 値になります。バッファーのサイズは sizeof (iov_param_desc_t) * num_params になります

IOV_VALIDATE_PARAM ioctl

IOV_VALIDATE_PARAM() を呼び出すドライバの一般的な制御フローは次のようになります。

  1. arg パラメータを pci_param_get_ioctl() インタフェースに送信し、pci_param_t 構造体へのポインタを取得します。

  2. param 検証が失敗した場合は、pv_reason 配列に説明文字列を書き込みます。

  3. pci_get_plist() インタフェースに続いて pci_plist_lookup() インタフェースを呼び出すことで、デバイスパラメータを取得します。

  4. この構成の検証用として構成すべき VF の数を取得するために、PF plist 内で vfs 名前-値ペアを検索します。ドライバは、16 ビット以上の整数データ型を使って vfs 名前-値ペアの検索を行うべきです。pciv_plist_getvf() インタフェースを使って VF デバイスの plist パラメータを取得します。

  5. デバイスにパラメータを実際に適用せずにパラメータを検証します。

  6. 有効な構成が見つかった場合は 0 を返します。


注意

注意 - 上の手順で検証されるパラメータは、デバイスの現在の構成とは一切関係ありません。それらは、将来の構成になる可能性があると仮定して、個別に検証する必要があります。そうでない場合、ドライバは不適切な構成を示す DDI_EINVAL を返すべきです。さらに、無効な構成が見つかった場合は、ドライバは iov_param_validate 構造体の pv_reason フィールドに説明文字列を提供すべきです。この文字列は、構成が失敗した理由を管理者に伝えます。


ドライバのコールバック

コールバックを登録するには、DDI インタフェース ddi_cb_register()ddi_cb_unregister() を使用します。コールバックはイベント通知および着信データトラフィックに使用されます。コールバックは、送信時の各イベントのイベントハンドラとしての役割を果たします。

SR-IOV ドライバは、VF の構成または構成解除の前後に PF ドライバに通知するための追加コールバックを実装すべきです。

ドライバでコールバックを実装するには、次の DDI コールバック登録メカニズムインタフェースを使用します。


注 - SR-IOV に対応している PF ドライバは必ず、ddi_cb_flags_t DDI_CB_FLAG_SRIOV を使用することで、PF ドライバが SR-IOV に対応していることを Oracle Solaris IOV フレームワークに知らせる必要があります。


ドライバ ioctl のサンプルコード

enum ioc_reply
igb_ioctl(igb_t *igb, struct iocblk *iocp, mblk_t *mp)
{
        int rval = 0;
        iov_param_ver_info_t *iov_param_ver;
        iov_param_validate_t pvalidate;
        pci_param_t my_params;
        char reason[81];

if (mp->b_cont == NULL)
        return (IOC_INVAL);
if ((int)iocp->ioc_count < 0)
        return (IOC_INVAL);
switch (iocp->ioc_cmd) {
        case IOV_GET_PARAM_VER_INFO:
            if (iocp->ioc_count < sizeof (iov_param_ver_info_t))
                return (IOC_INVAL);
            iov_param_ver = (iov_param_ver_info_t *)(mp->b_cont->b_rptr);
            iov_param_ver->version = IOV_PARAM_DESC_VERSION;
            iov_param_ver->num_params = NUM_OF_PARAMS;
        return (IOC_REPLY);
        case IOV_GET_PARAM_INFO:
            if (iocp->ioc_count < sizeof (pci_list))
                return (IOC_INVAL);
            memcpy((caddr_t)(mp->b_cont->b_rptr), &pci_list,sizeof (pci_list));
            return (IOC_REPLY);
        case IOV_VALIDATE_PARAM:
            if (iocp->ioc_count <= 0)
                return (IOC_INVAL);
            strcpy(reason, "Failed to read params sent\n");
            rval = pci_param_get_ioctl(igb->dip,(uintptr_t)(mp->b_cont->b_rptr),
                     iocp->ioc_flag | FKIOCTL,&my_params );
            if (rval == 0) {
                rval = validate_params(igb->dip, my_params, reason);
            pci_param_free(my_params);
    }
if (rval) {
        memcpy(mp->b_cont->b_rptr, reason, sizeof (reason));
        iocp->ioc_count = sizeof (reason);
        return (IOC_REPLY);
}
iocp->ioc_count = 0;
return (IOC_REPLY);
iov_param_ver_info_t iov_param_ver;
iov_param_validate_t pvalidate;
pci_param_t    my_params;

switch (cmd) {
case IOV_GET_PARAM_VER_INFO:
        iov_param_ver.version = IOV_PARAM_DESC_VERSION;
        iov_param_ver.num_params = NUM_OF_PARAMS;
        if (ddi_copyout(&iov_param_ver, (caddr_t)arg,
            sizeof (iov_param_ver_info_t), mode) != DDI_SUCCESS)
        return (DEFAULT);
        return (0);
case IOV_GET_PARAM_INFO:
        if (ddi_copyout(&pci_list, (caddr_t)arg,param_list_size, mode) != DDI_SUCCESS)
        return (DEFAULT);
        return (0);
case IOV_VALIDATE_PARAM:
        strcpy(reason, "Failed to read params sent\n");
        rv = pci_param_get_ioctl(state->dip, arg, mode, &my_params);
        if (rv == 0)
            rv = validate_params(state->dip, my_params, reason); 
        else
            return (rv);
        pci_param_free(my_params);
    if (rv) {
        if (ddi_copyout(reason,iov_param_validate_t *)arg)->pv_reason,
             sizeof (reason), mode) != DDI_SUCCESS)
        return (DEFAULT);
 return (rv);
    }
return (0);