FreeBSD 系统结构手册
上一页 | 第10章 　ISA设备驱动程序 | 下一页

# 10.2 基本信息

典型的ISA驱动程序需要以下包含文件：

    #include <sys/module.h>
    #include <sys/bus.h>
    #include <machine/bus.h>
    #include <machine/resource.h>
    #include <sys/rman.h>

    #include <isa/isavar.h>
    #include <isa/pnpvar.h>

它们描述了针对ISA和通用总线子系统的东西。

总线子系统是以面向对象的方式实现的，其主要结构通过相关联的 方法函数来访问。

ISA驱动程序实现的总线方法的列表与任何其他总线的很相似。 对于名字为“xxx”的假想驱动程序，它们将是：

- `static void xxx_isa_identify (driver_t *, device_t);` 通常用于总线驱动程序而不是设备驱动程序。 但对于ISA设备，这个方法有特殊用途：如果设备提供某些设备特定的 （非PnP）方法自动侦测设备，这个例程可以实现它。

- `static int xxx_isa_probe (device_t dev);` 在已知（或PnP）位置探测设备。对于已经部分配置的 设备，这个例程也能够提供设备特定的对某些参数的自动侦测。

- `static int xxx_isa_attach (device_t dev);` 挂接和初始化设备。

- `static int xxx_isa_detach (device_t dev);` 卸载设备驱动模块前解挂设备。

- `static int xxx_isa_shutdown (device_t dev);` 系统关闭前执行设备的关闭。

- `static int xxx_isa_suspend (device_t dev);` 系统进入节能状态前挂起设备。也可以中止 切换到节能状态。

- `static int xxx_isa_resume (device_t dev);` 从节能状态返回后恢复设备的活动状态。

`xxx_isa_probe()`和 `xxx_isa_attach()`是必须提供的，其余例程根据设备的 需要可以有选择地实现。

使用下面一组描述符将设备驱动链接到系统。

        /* 支持的总线方法表 */
        static device_method_t xxx_isa_methods[] = {
            /* 列出驱动程序支持的所有总线方法函数 */
            /* 略去不支持的函数 */
            DEVMETHOD(device_identify,  xxx_isa_identify),
            DEVMETHOD(device_probe,     xxx_isa_probe),
            DEVMETHOD(device_attach,    xxx_isa_attach),
            DEVMETHOD(device_detach,    xxx_isa_detach),
            DEVMETHOD(device_shutdown,  xxx_isa_shutdown),
            DEVMETHOD(device_suspend,   xxx_isa_suspend),
            DEVMETHOD(device_resume,    xxx_isa_resume),

        { 0, 0 }
        };

        static driver_t xxx_isa_driver = {
            "xxx",
            xxx_isa_methods,
            sizeof(struct xxx_softc),
        };

        static devclass_t xxx_devclass;

        DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass,
            load_function, load_argument);

此处的结构`xxx_softc`是一个设备 特定的结构，它包含私有的驱动程序数据和驱动程序资源的描述符。 总线代码会自动按需要为每个设备分配一个softc描述符。

如果驱动程序作为可加载模块实现，当驱动程序被加载或卸载时， 会调用`load_function()`函数进行驱动程序特定的 初始化或清理工作，并将load_argument作为函数的一个参量传递进去。 如果驱动程序不支持动态加载（换句话说，它必须被链接到内核中），则 这些值应当被设置为0，最后的定义将看起来如下所示：

     DRIVER_MODULE(xxx, isa, xxx_isa_driver,
           xxx_devclass, 0, 0);

如果驱动程序是为支持PnP的设备而写的，那么就必须定义一个包含 所有支持的PnP ID的表。这个表由此驱动程序所支持的PnP ID的列表 和以人可读的形式给出的、与这些ID对应的硬件类型和型号的描述 组成。看起来如下：

        static struct isa_pnp_id xxx_pnp_ids[] = {
            /* 每个所支持的PnP ID占一行 */
            { 0x12345678,   "Our device model 1234A" },
            { 0x12345679,   "Our device model 1234B" },
            { 0,        NULL }, /* 表结束 */
        };

如果驱动程序不支持PnP设备，它仍然需要一个空的PnP ID表， 如下所示：

        static struct isa_pnp_id xxx_pnp_ids[] = {
            { 0,        NULL }, /* 表结束 */
        };

上一页 | 起始页 | 下一页
ISA设备驱动程序 | 上一级 | Device_t指针

本文档和其它文档可从这里下载：ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

如果对于FreeBSD有问题，请先阅读文档，如不能解决再联系<questions@FreeBSD.org>.
关于本文档的问题请发信联系 <doc@FreeBSD.org>.