キューへの登録を実装しているデバイスドライバは通常、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); }