编写适用于 Oracle® Solaris 11.2 的设备驱动程序

退出打印视图

更新时间: 2014 年 9 月
 
 

设备访问函数

驱动程序结合使用 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) 系列例程的手册页。

以下示例建立在Example 7–1 的基础上,其中,驱动程序映射了设备的 CSR 寄存器和数据寄存器。在本示例中,调用驱动程序的 write(9E) 入口点时,会将数据缓冲区写入(每次一个字节)设备。

示例 7-2  映射设置:缓冲区
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);
}