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

退出打印视图

更新时间: 2014 年 9 月
 
 

中断处理程序功能

驱动程序框架和设备各自将要求置于中断处理程序上。所有中断处理程序均要求执行以下任务:

  • 确定设备是否会中断并可能相应地拒绝此中断。

    中断处理程序首先会检查设备,确定其是否发出了中断。如果设备未发出中断,则处理程序必须返回 DDI_INTR_UNCLAIMED。通过此步骤可实现设备轮询。在给定中断优先级别的任何设备都可能发出了中断。设备轮询将通知系统此设备是否已发出了中断。

  • 通知设备正在对其进行服务。

    通知设备服务是大多数设备所需的特定于设备的操作。例如,需要将 S 总线设备中断,直到驱动程序通知 S 总线设备停止。此方法可保证对在同一优先级别中断的所有 S 总线设备都进行服务。

  • 执行任何与 I/O 请求有关的处理。

    设备会由于不同原因而发生中断,如传送完成传送错误。此步骤可涉及使用数据访问函数来读取设备的数据缓冲区,检查设备的错误寄存器,以及在数据结构中相应地设置状态字段。中断分发和处理相对比较耗时。

  • 执行可以防止其他中断的任何附加处理。

    例如,从设备中读取数据的下一项。

  • 返回 DDI_INTR_CLAIMED

  • 必须始终声明 MSI 中断。

    对于 MSI-X 中断,声明中断是可选的。在任一情况下都无需检查中断的拥有权,因为 MSI 和 MSI-X 中断不是与其他设备共享的。

  • 支持热插拔和多个 MSI 或 MSI-X 中断的驱动程序应针对热插拔事件保留单独的中断,并针对此中断注册单独的 ISR(interrupt service routine,中断服务例程)。

以下示例说明了名为 mydev 的设备的中断例程。

示例 8-9  中断示例
static uint_t
mydev_intr(caddr_t arg1, caddr_t arg2)
{
    struct mydevstate *xsp = (struct mydevstate *)arg1;
    uint8_t     status; 
    volatile    uint8_t  temp;

    /*
     * Claim or reject the interrupt.This example assumes
     * that the device's CSR includes this information.
     */
    mutex_enter(&xsp->high_mu);

    /* use data access routines to read status */
    status = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
    if (!(status & INTERRUPTING)) {
        mutex_exit(&xsp->high_mu);
        return (DDI_INTR_UNCLAIMED); /* dev not interrupting */
    }
    /*
     * Inform the device that it is being serviced, and re-enable
     * interrupts. The example assumes that writing to the
     * CSR accomplishes this. The driver must ensure that this data
     * access operation makes it to the device before the interrupt
     * service routine returns. For example, using the data access
     * functions to read the CSR, if it does not result in unwanted
     * effects, can ensure this.
     */
    ddi_put8(xsp->data_access_handle, &xsp->regp->csr,
        CLEAR_INTERRUPT | ENABLE_INTERRUPTS);

    /* flush store buffers */
    temp = ddi_get8(xsp->data_access_handle, &xsp->regp->csr);
    
    mutex_exit(&xsp->mu);
    return (DDI_INTR_CLAIMED);
}

中断例程执行的大多数步骤都依赖于设备本身的特定信息。查询设备的硬件手册可确定中断原因,检测错误状态并访问设备数据寄存器。