第 1 部分针对 Oracle Solaris 平台设计设备驱动程序
9. 直接内存访问 (Direct Memory Access, DMA)
attach(9E) 例程应执行所有设备需要的常见初始化任务,例如:
分配每个实例的状态结构
注册设备中断
映射设备寄存器
初始化互斥变量和条件变量
创建可进行电源管理的组件
创建次要节点
有关这些任务的代码示例,请参见attach() 入口点。
字符设备驱动程序将创建类型为 S_IFCHR 的次要节点。类型为 S_IFCHR 的次要节点会使代表节点的字符特殊文件最终出现在 /devices 分层结构中。
以下示例显示了字符驱动程序的典型 attach(9E) 例程。与设备有关的属性通常在 attach() 例程中声明。该示例使用了预定义的 Size 属性。在获取块设备的分区大小时,Size 与 Nblocks 属性是等效的。举例来说,如果要在磁盘设备上执行字符 I/O,就可以使用 Size 来获取分区大小。因为 Size 是 64 位属性,所以必须使用 64 位属性接口。在本例中,使用 ddi_prop_update_int64(9F)。有关属性的更多信息,请参见设备属性。
示例 15-1 字符驱动程序 attach() 例程
static int xxattach(dev_info_t *dip, ddi_attach_cmd_t cmd) { int instance = ddi_get_instance(dip); switch (cmd) { case DDI_ATTACH: /* * Allocate a state structure and initialize it. * Map the device's registers. * Add the device driver's interrupt handler(s). * Initialize any mutexes and condition variables. * Create power manageable components. * * Create the device's minor node. Note that the node_type * argument is set to DDI_NT_TAPE. */ if (ddi_create_minor_node(dip, minor_name, S_IFCHR, instance, DDI_NT_TAPE, 0) == DDI_FAILURE) { /* Free resources allocated so far. */ /* Remove any previously allocated minor nodes. */ ddi_remove_minor_node(dip, NULL); return (DDI_FAILURE); } /* * Create driver properties like "Size." Use "Size" * instead of "size" to ensure the property works * for large bytecounts. */ xsp->Size = size_of_device_in_bytes; maj_number = ddi_driver_major(dip); if (ddi_prop_update_int64(makedevice(maj_number, instance), dip, "Size", xsp->Size) != DDI_PROP_SUCCESS) { cmn_err(CE_CONT, "%s: cannot create Size property\n", ddi_get_name(dip)); /* Free resources allocated so far. */ return (DDI_FAILURE); } /* ... */ return (DDI_SUCCESS); case DDI_RESUME: /* See the "Power Management" chapter in this book. */ default: return (DDI_FAILURE); } }