JavaScript is required to for searching.
跳过导航链接
退出打印视图
编写设备驱动程序     Oracle Solaris 10 1/13 Information Library (简体中文)
search filter icon
search icon

文档信息

前言

第 1 部分针对 Oracle Solaris 平台设计设备驱动程序

1.  Oracle Solaris 设备驱动程序概述

2.  Oracle Solaris 内核和设备树

3.  多线程

4.  属性

5.  管理事件和排队任务

6.  驱动程序自动配置

7.  设备访问:程控 I/O

设备内存

管理设备和主机字节序之间的差别

管理数据排序要求

ddi_device_acc_attr 结构

映射设备内存

映射设置示例

设备访问函数

备用设备访问接口

访问内存空间

访问 I/O 空间

PCI 配置空间访问

8.  中断处理程序

9.  直接内存访问 (Direct Memory Access, DMA)

10.  映射设备和内核内存

11.  设备上下文管理

12.  电源管理

13.  强化 Oracle Solaris 驱动程序

14.  分层驱动程序接口 (Layered Driver Interface, LDI)

第 2 部分设计特定种类的设备驱动程序

15.  字符设备驱动程序

16.  块设备驱动程序

17.  SCSI 目标驱动程序

18.  SCSI 主机总线适配器驱动程序

19.  网络设备驱动程序

20.  USB 驱动程序

21.  SR-IOV 驱动程序

第 3 部分生成设备驱动程序

22.  编译、装入、打包和测试驱动程序

23.  调试、测试和调优设备驱动程序

24.  推荐的编码方法

第 4 部分附录

A.  硬件概述

B.  Solaris DDI/DKI 服务汇总

C.  使设备驱动程序支持 64 位

D.  控制台帧缓存器驱动程序

E.  pci.conf 文件

索引

设备访问函数

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

以下示例建立在示例 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);
}

备用设备访问接口

除通过 ddi_get8(9F)ddi_put8(9F) 接口系列实现所有设备访问之外,Oracle Solaris OS 还提供特定于特殊总线实现的接口。虽然在某些平台上这些函数会更加有效,但使用这些例程会限制驱动程序在设备的各总线版本间保持可移植的能力。

访问内存空间

对于内存映射访问,设备寄存器会出现在内存地址空间中。驱动程序可以将 ddi_getX 系列例程和 ddi_putX 系列用作标准设备访问接口的备用接口。

访问 I/O 空间

对于 I/O 空间访问,设备寄存器会出现在 I/O 空间中,其中每个可寻址元素都称为 I/O 端口。驱动程序可以将 ddi_io_get8(9F)ddi_io_put8(9F) 例程用作标准设备访问接口的备用接口。

PCI 配置空间访问

要在不使用常规设备访问接口的情况下访问 PCI 配置空间,驱动程序需要通过调用 pci_config_setup(9F)(而非 ddi_regs_map_setup(9F))来映射 PCI 配置空间。然后,驱动程序可以调用 pci_config_get8(9F)pci_config_put8(9F) 接口系列,以访问 PCI 配置空间。