Go to main content
Oracle® Solaris 11.3 デバイスドライバの記述

印刷ビューの終了

更新: 2016 年 11 月
 
 

デバイスアクセス関数

ドライバは、ddi_get8(9F) および ddi_put8(9F) ルーチンファミリと、ddi_regs_map_setup(9F) から返されたハンドルとを組み合わせて使用することで、デバイス間でデータを転送します。DDI フレームワークは、ホストまたはデバイスのエンディアン形式に合わせるために必要なすべてのバイトスワップを自動的に処理するとともに、デバイスで発生する可能性のあるすべての格納順序付け制約を適用します。

DDI には、8 ビット、16 ビット、32 ビット、64 ビットの各サイズでデータを転送するためのインタフェースが用意されているほか、複数の値を繰り返し転送するためのインタフェースも用意されています。ddi_get8(9F)ddi_put8(9F)ddi_rep_get8(9F)、および ddi_rep_put8(9F) ルーチンファミリのマニュアルページで、一覧表やこれらのインタフェースの説明を参照してください。

次の例は、ドライバ内でデバイスの CSR レジスタとデータレジスタのマッピングを行った使用例 15 に基づいたものです。このドライバの write(9E) エントリポイントは、呼び出し時にデータバッファーを一度に 1 バイトずつデバイスに書き込みます。

使用例 16  マッピングの設定: バッファー
static  int
pio_write(dev_t dev, struct uio *uiop, cred_t *credp)
{
    int  retval;
    int  error = OK;
    Pio *pio_p = ddi_get_soft_state(pio_softstate, getminor(dev));

    if (pio_p == NULL)
        return (ENXIO);
    mutex_enter(&pio_p->mutex);
    /*
     * enable interrupts from the device by setting the Interrupt
     * Enable bit in the devices CSR register
     */
    ddi_put8(pio_p->csr_handle, pio_p->csr,
      (ddi_get8(pio_p->csr_handle, pio_p->csr) | PIO_INTR_ENABLE));

    while (uiop->uio_resid > 0) {
    /*
     * This device issues an IDLE interrupt when it is ready
     * to accept a character; the interrupt can be cleared
     * by setting PIO_INTR_CLEAR.  The interrupt is reasserted
     * after the next character is written or the next time
     * PIO_INTR_ENABLE is toggled on.
     *
     * wait for interrupt (see pio_intr)
     */
        cv_wait(&pio_p->cv, &pio_p->mutex);

    /*
     * get a character from the user's write request
     * fail the write request if any errors are encountered
     */
        if ((retval = uwritec(uiop)) == -1) {
            error = retval;
            break;
        }

    /*
     * pass the character to the device by writing it to
     * the device's data register
     */
        ddi_put8(pio_p->data_handle, pio_p->data, (uchar_t)retval);
    }

    /*
     * disable interrupts by clearing the Interrupt Enable bit
     * in the CSR
     */
    ddi_put8(pio_p->csr_handle, pio_p->csr,
      (ddi_get8(pio_p->csr_handle, pio_p->csr) & ~PIO_INTR_ENABLE));

    mutex_exit(&pio_p->mutex);
    return (error);
}

代替のデバイスアクセスインタフェース

Oracle Solaris OS には、ddi_get8(9F) and ddi_put8(9F) インタフェースファミリ経由ですべてのデバイスアクセスを実装する方法だけでなく、特定のバス実装に固有のインタフェースも用意されています。これらの関数は一部のプラットフォームで効率が高くなる可能性もありますが、これらのルーチンを使用すると、デバイスのさまざまなバスバージョンでのドライバの移植性が低下する可能性があります。

メモリー空間アクセス

メモリーマップアクセスでは、デバイスレジスタがメモリーアドレス空間に現れます。ddi_getX および ddi_putX ルーチンファミリが、標準のデバイスアクセスインタフェースの代替手段としてドライバから使用可能となっています。

入出力空間アクセス

入出力空間アクセスでは、デバイスレジスタが入出力空間に現れます。このとき、アドレス指定可能な各要素は入出力ポートと呼ばれます。ddi_io_get8(9F) および ddi_io_put8(9F) ルーチンが、標準のデバイスアクセスインタフェースの代替手段としてドライバから使用可能となっています。

PCI 構成空間アクセス

通常のデバイスアクセスインタフェースを使用しないで PCI 構成空間にアクセスするには、ドライバ内で、PCI 構成空間をマップするために、pci_config_setup(9F) の代わりに ddi_regs_map_setup(9F) を呼び出す必要があります。その後ドライバ内で、pci_config_get8(9F) および pci_config_put8(9F) インタフェースファミリを呼び出して PCI 構成空間にアクセスできます。