キューへの登録を実装しているデバイスドライバは通常、start() ルーチンを備えています。start() は次の要求をキューから取り出し、デバイスとの間のデータ転送を開始します。この例では、start() はデバイスの状態 (ビジー状態か空いているか) には関係なく、すべての要求を処理します。
start() は、アイドルのデバイスを起動できるように strategy() が要求をキューに入れるたびに strategy(9E) によって呼び出されます。デバイスがビジー状態の場合、start() はただちに復帰します。
start() はまた、取り込まれた割り込みから割り込みハンドラが復帰する前に、その割り込みハンドラからも呼び出されるため、空でないキューを処理できます。キューが空の場合、start() はただちに復帰します。
start() は非公開のドライバルーチンであるため、start() は任意の引数を取り、任意の型を返すことができます。次のコーディング例は、DMA コールバックとして使用するために記述されています (ただし、その部分は示されていません)。したがって、この例では caddr_t を引数として取り、int を返す必要があります。DMA コールバックルーチンの詳細については、Handling Resource Allocation Failuresを参照してください。
使用例 16-6 ブロックドライバに対する最初のデータ要求の開始static int
xxstart(caddr_t arg)
{
struct xxstate *xsp = (struct xxstate *)arg;
struct buf *bp;
mutex_enter(&xsp->mu);
/*
* If there is nothing more to do, or the device is
* busy, return.
*/
if (xsp->list_head == NULL || xsp->busy) {
mutex_exit(&xsp->mu);
return (0);
}
xsp->busy = 1;
/* Get the first buffer off the transfer list */
bp = xsp->list_head;
/* Update the head and tail pointer */
xsp->list_head = xsp->list_head->av_forw;
if (xsp->list_head == NULL)
xsp->list_tail = NULL;
bp->av_forw = NULL;
mutex_exit(&xsp->mu);
/*
* If the device has power manageable components,
* mark the device busy with pm_busy_components(9F),
* and then ensure that the device
* is powered up by calling pm_raise_power(9F).
*
* Set up DMA resources with ddi_dma_alloc_handle(9F) and
* ddi_dma_buf_bind_handle(9F).
*/
xsp->bp = bp;
ddi_put32(xsp->data_access_handle, &xsp->regp->dma_addr,
cookie.dmac_address);
ddi_put32(xsp->data_access_handle, &xsp->regp->dma_size,
(uint32_t)cookie.dmac_size);
ddi_put8(xsp->data_access_handle, &xsp->regp->csr,
ENABLE_INTERRUPTS | START_TRANSFER);
return (0);
}