リソースの割り当てが正常に完了したら、デバイスをプログラミングする必要があります。DMA エンジンのプログラミングはデバイスごとに異なりますが、開始アドレスと転送カウントはすべての DMA エンジンに必要です。デバイスドライバはこれらの 2 つの値を、ddi_dma_addr_bind_handle(9F)、ddi_dma_buf_bind_handle(9F)、または ddi_dma_getwin(9F) の呼び出しが正常に行われた場合に返される DMA cookie から取得します。これらの関数はすべて、最初の DMA cookie と、DMA オブジェクトが複数の cookie で構成されているかどうかを示す cookie カウントを返します。cookie カウント N が 1 よりも大きければ、 ddi_dma_nextcookie(9F) を N-1 回だけ呼び出して残りの cookie をすべて取得します。
DMA cookie の型はddi_dma_cookie (9S) です。この型の cookie には次のフィールドがあります。
uint64_t _dmac_ll; /* 64-bit DMA address */ uint32_t _dmac_la[2]; /* 2 x 32-bit address */ size_t dmac_size; /* DMA cookie size */ uint_t dmac_type; /* bus specific type bits */
dmac_laddress フィールドには、デバイスの DMA エンジンのプログラミングに適した 64 ビットの入出力アドレスを指定します。デバイスに 64 ビットの DMA アドレスレジスタがある場合、ドライバはこのフィールドを使用して DMA エンジンをプログラミングします。dmac_address フィールドには、32 ビットの DMA アドレスレジスタを持つデバイスに使用される 32 ビットの入出力アドレスを指定します。dmac_size フィールドには、転送カウントが入ります。cookie の dmac_type フィールドがドライバで必要になるかどうかは、バスアーキテクチャーによって決まります。ドライバは、cookie に対して論理操作や算術操作などの操作は一切行いません。
使用例 9-4 ddi_dma_cookie(9S) の例ddi_dma_cookie_t cookie; if (ddi_dma_buf_bind_handle(xsp->handle,xsp->bp, flags, xxstart, (caddr_t)xsp, &cookie, &xsp->ccount) != DDI_DMA_MAPPED) { /* error handling */ } sglp = regp->sglist; for (cnt = 1; cnt <= SGLLEN; cnt++, sglp++) { /* store the cookie parms into the S/G list */ ddi_put32(xsp->access_hdl, &sglp->dma_size, (uint32_t)cookie.dmac_size); ddi_put32(xsp->access_hdl, &sglp->dma_addr, cookie.dmac_address); /* Check for end of cookie list */ if (cnt == xsp->ccount) break; /* Get next DMA cookie */ (void) ddi_dma_nextcookie(xsp->handle, &cookie); } /* start DMA transfer */ ddi_put8(xsp->access_hdl, ®p->csr, ENABLE_INTERRUPTS | START_TRANSFER);