リソースの割り当てが正常に完了したら、デバイスをプログラミングする必要があります。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);