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

印刷ビューの終了

更新: 2014 年 9 月
 
 

GLDv3 の MAC 登録

GLDv3 は、MAC_PLUGIN_IDENT_ETHER タイプのプラグインに登録するドライバ用のドライバ API を定義します。

GLDv3 の MAC 登録プロセス

    GLDv3 デバイスドライバは、次の手順を実行して MAC 層に登録する必要があります。

  • sys/mac_ether.hsys/mac_provider.h の 2 つの MAC ヘッダーファイルをインクルードします。その他の MAC 関連ヘッダーファイルはドライバにインクルードしないでください。

  • mac_callbacks 構造体を生成します。

  • mac_init_ops() 関数をその _init() エントリポイントで呼び出します。

  • mac_alloc() 関数をその attach() エントリポイントで呼び出し、mac_register 構造体を割り当てます。

  • mac_register 構造体を生成し、mac_register() 関数をその attach() エントリポイントで呼び出します。

  • mac_unregister() 関数をその detach() エントリポイントで呼び出します。

  • mac_fini_ops() 関数をその _fini() エントリポイントで呼び出します。

  • misc/mac への依存性とリンクします。

    # ld -N"misc/mac" xx.o -o xx

GLDv3 の MAC 登録関数

GLDv3 インタフェースには、MAC 層への登録中に通知されるドライバエントリポイントと、ドライバによって呼び出される MAC エントリポイントが含まれています。

mac_init_ops() および mac_fini_ops() 関数
void mac_init_ops(struct dev_ops *ops, const char *name);

GLDv3 デバイスドライバは mod_install(9F) を呼び出す前に、mac_init_ops(9F) 関数をその _init(9E) エントリポイントで呼び出す必要があります。

void mac_fini_ops(struct dev_ops *ops);

GLDv3 デバイスドライバは mod_remove(9F) を呼び出したあとに、mac_fini_ops(9F) 関数をその _fini(9E) エントリポイントで呼び出す必要があります。

使用例 19-1  mac_init_ops() および mac_fini_ops() 関数
int
_init(void)
{
        int     rv;
        mac_init_ops(&xx_devops, "xx");
        if ((rv = mod_install(&xx_modlinkage)) != DDI_SUCCESS) {
                mac_fini_ops(&xx_devops);
        }
        return (rv);
}

int
_fini(void)
{
        int     rv;
        if ((rv = mod_remove(&xx_modlinkage)) == DDI_SUCCESS) {
                mac_fini_ops(&xx_devops);
        }
        return (rv);
}
mac_alloc() および mac_free() 関数
mac_register_t *mac_alloc(uint_t version);

mac_alloc(9F) 関数は新しい mac_register 構造体を割り当て、この構造体へのポインタを返します。新しい構造体を mac_register() に渡す前に構造体のメンバーを初期化してください。mac_alloc() が戻る前に、MAC 専用要素が MAC 層によって初期化されます。version の値は MAC_VERSION_V1 である必要があります。

void mac_free(mac_register_t *mregp);

mac_free(9F) 関数は、以前に mac_alloc() によって割り当てられた mac_register 構造体を解放します。

mac_register() および mac_unregister() 関数
int mac_register(mac_register_t *mregp, mac_handle_t *mhp);

新しいインスタンスを MAC 層に登録するために、GLDv3 ドライバは mac_register(9F) 関数をその attach (9E) エントリポイントで呼び出す必要があります。mregp 引数は、mac_register 登録情報構造体へのポインタです。成功した場合、mhp 引数は新しい MAC インスタンスの MAC ハンドルへのポインタです。このハンドルは、mac_tx_update()mac_link_update()mac_rx() などのほかのルーチンで必要になります。

使用例 19-2  mac_alloc()mac_register()、および mac_free() 関数と mac_register 構造体
int
xx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
        mac_register_t        *macp;

/* ... */

        if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
                xx_error(dip, "mac_alloc failed");
                goto failed;
        }

        macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
        macp->m_driver = xxp;
        macp->m_dip = dip;
        macp->m_src_addr = xxp->xx_curraddr;
        macp->m_callbacks = &xx_m_callbacks;
        macp->m_min_sdu = 0;
        macp->m_max_sdu = ETHERMTU;
        macp->m_margin = VLAN_TAGSZ;

        if (mac_register(macp, &xxp->xx_mh) == DDI_SUCCESS) {
                mac_free(macp);
                return (DDI_SUCCESS);
        }

/* failed to register with MAC */
        mac_free(macp);
failed:
        /* ... */
}
int mac_unregister(mac_handle_t mh);

mac_unregister(9F) 関数は、以前に mac_register() によって登録された MAC インスタンスを登録解除します。mh 引数は、mac_register() によって割り当てられた MAC ハンドルです。mac_unregister()detach (9E) エントリポイントから呼び出してください。

使用例 19-3  mac_unregister() 関数
int
xx_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
{
        xx_t        *xxp; /* driver soft state */

        /* ... */

        switch (cmd) {
        case DDI_DETACH:

                if (mac_unregister(xxp->xx_mh) != 0) {
                        return (DDI_FAILURE);
                }
        /* ... */
}

GLDv3 の MAC 登録データ構造体

このセクションで説明する構造体は、sys/mac_provider.h ヘッダーファイルで定義されます。sys/mac_ether.h および sys/mac_provider.h MAC ヘッダーファイルを GLDv3 ドライバにインクルードします。その他の MAC 関連ヘッダーファイルはインクルードしないでください。

mac_register (9S) データ構造体は、mac_alloc() によって割り当てられ、mac_register() に渡される MAC 登録情報構造体です。新しい構造体を mac_register() に渡す前に構造体のメンバーを初期化してください。mac_alloc() が戻る前に、MAC 専用要素が MAC 層によって初期化されます。構造体の m_version メンバーは MAC バージョンです。MAC バージョンを変更しないでください。構造体の m_type_ident メンバーは MAC タイプ識別子です。MAC タイプ識別子は MAC_PLUGIN_IDENT_ETHER に設定してください。mac_register 構造体の m_callbacks メンバーは、mac_callbacks 構造体のインスタンスへのポインタです。

mac_callbacks(9S) データ構造体は、デバイスドライバがそのエントリポイントを MAC 層に公開するために使用する構造体です。これらのエントリポイントは、ドライバを制御するために MAC 層によって使用されます。これらのエントリポイントは、アダプタの起動と停止、マルチキャストアドレスの管理、プロミスキュアス (promiscuous) モードの設定、アダプタの機能の照会、プロパティーの取得と設定などのタスクを実行するために使用されます。すべての必須およびオプション GLDv3 エントリポイントの一覧については、Table 19–1 を参照してください。mac_register 構造体の m_callbacks フィールドには、mac_callbacks 構造体へのポインタを指定します。

mac_callbacks 構造体の mc_callbacks メンバーは、次のフラグを組み合わせたビットマスクであり、ドライバで実装されるオプションエントリポイントを指定します。mac_callbacks 構造体のほかのメンバーは、ドライバの各エントリポイントへのポインタです。

MC_IOCTL

mc_ioctl() エントリポイントが存在します。

MC_GETCAPAB

mc_getcapab() エントリポイントが存在します。

MC_SETPROP

mc_setprop() エントリポイントが存在します。

MC_GETPROP

mc_getprop() エントリポイントが存在します。

MC_PROPINFO

mc_propinfo() エントリポイントが存在します。

MC_PROPERTIES

すべてのプロパティーエントリポイントが存在します。MC_PROPERTIES を設定すると、MC_SETPROPMC_GETPROP、および MC_PROPINFO の 3 つのフラグすべてを設定したことになります。

使用例 19-4  mac_callbacks 構造体
#define XX_M_CALLBACK_FLAGS \
    (MC_IOCTL | MC_GETCAPAB | MC_PROPERTIES)

static mac_callbacks_t xx_m_callbacks = {
        XX_M_CALLBACK_FLAGS,
        xx_m_getstat,     /* mc_getstat() */
        xx_m_start,       /* mc_start() */
        xx_m_stop,        /* mc_stop() */
        xx_m_promisc,     /* mc_setpromisc() */
        xx_m_multicst,    /* mc_multicst() */
        xx_m_unicst,      /* mc_unicst() */
        xx_m_tx,          /* mc_tx() */
        NULL,             /* Reserved, do not use */
        xx_m_ioctl,       /* mc_ioctl() */
        xx_m_getcapab,    /* mc_getcapab() */
        NULL,             /* Reserved, do not use */
        NULL,             /* Reserved, do not use */
        xx_m_setprop,     /* mc_setprop() */
        xx_m_getprop,     /* mc_getprop() */
        xx_m_propinfo     /* mc_propinfo() */
};