⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kld.txt

📁 一个pci驱动程序的代码 与PCI函数进行交互的简单KLD
💻 TXT
字号:
/* 与PCI函数进行交互的简单KLD
*
* Murray Stokely
*/

#include <sys/param.h>        /* kernel.h中使用的定义 */
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/kernel.h>       /* 模块初始化中使用的类型 */
#include <sys/conf.h>     /* cdevsw结构 */
#include <sys/uio.h>      /* uio结构 */
#include <sys/malloc.h>
#include <sys/bus.h>      /* pci总线用到的结构、原型 */

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

#include <dev/pci/pcivar.h>   /* 为了使用get_pci宏! */
#include <dev/pci/pcireg.h>

/* softc保存我们每个实例的数据。 */
struct mypci_softc {
    device_t    my_dev;
    struct cdev *my_cdev;
};

/* 函数原型 */
static d_open_t     mypci_open;
static d_close_t    mypci_close;
static d_read_t     mypci_read;
static d_write_t    mypci_write;

/* 字符设备入口点 */

static struct cdevsw mypci_cdevsw = {
    .d_version =    D_VERSION,
    .d_open =   mypci_open,
    .d_close =  mypci_close,
    .d_read =   mypci_read,
    .d_write =  mypci_write,
    .d_name =   "mypci",
};

/*
* 在cdevsw例程中,我们通过结构体cdev中的成员si_drv1找出我们的softc。
* 当我们建立/dev项时,在我们的已附着的例程中,
* 我们设置这个变量指向我们的softc。
*/

int
mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
{
    struct mypci_softc *sc;

    /* Look up our softc. */
    sc = dev->si_drv1;
    device_printf(sc->my_dev, "Opened successfully.\n");
    return (0);
}

int
mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
{
    struct mypci_softc *sc;

    /* Look up our softc. */
    sc = dev->si_drv1;
    device_printf(sc->my_dev, "Closed.\n");
    return (0);
}

int
mypci_read(struct cdev *dev, struct uio *uio, int ioflag)
{
    struct mypci_softc *sc;

    /* Look up our softc. */
    sc = dev->si_drv1;
    device_printf(sc->my_dev, "Asked to read %d bytes.\n", uio->uio_resid);
    return (0);
}

int
mypci_write(struct cdev *dev, struct uio *uio, int ioflag)
{
    struct mypci_softc *sc;

    /* Look up our softc. */
    sc = dev->si_drv1;
    device_printf(sc->my_dev, "Asked to write %d bytes.\n", uio->uio_resid);
    return (0);
}

/* PCI支持函数 */

/*
* 将某个设置的标识与这个驱动程序支持的标识相比较。
* 如果相符,设置描述字符并返回成功。
*/
static int
mypci_probe(device_t dev)
{

    device_printf(dev, "MyPCI Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n",
        pci_get_vendor(dev), pci_get_device(dev));

    if (pci_get_vendor(dev) == 0x11c1) {
        printf("We've got the Winmodem, probe successful!\n");
        device_set_desc(dev, "WinModem");
        return (BUS_PROBE_DEFAULT);
    }
    return (ENXIO);
}

/* 只有当探测成功时才调用连接函数 */

static int
mypci_attach(device_t dev)
{
    struct mypci_softc *sc;

    printf("MyPCI Attach for : deviceID : 0x%x\n", pci_get_devid(dev));

    /* Look up our softc and initialize its fields. */
    sc = device_get_softc(dev);
    sc->my_dev = dev;

    /*
     * Create a /dev entry for this device.  The kernel will assign us
     * a major number automatically.  We use the unit number of this
     * device as the minor number and name the character device
     * "mypci<unit>".
     */
    sc->my_cdev = make_dev(&mypci_cdevsw, device_get_unit(dev),
        UID_ROOT, GID_WHEEL, 0600, "mypci%u", device_get_unit(dev));
    sc->my_cdev->si_drv1 = sc;
    printf("Mypci device loaded.\n");
    return (0);
}

/* 分离设备。 */

static int
mypci_detach(device_t dev)
{
    struct mypci_softc *sc;

    /* Teardown the state in our softc created in our attach routine. */
    sc = device_get_softc(dev);
    destroy_dev(sc->my_cdev);
    printf("Mypci detach!\n");
    return (0);
}

/* 系统关闭期间在sync之后调用。 */

static int
mypci_shutdown(device_t dev)
{

    printf("Mypci shutdown!\n");
    return (0);
}

/*
* 设备挂起例程。
*/
static int
mypci_suspend(device_t dev)
{

    printf("Mypci suspend!\n");
    return (0);
}

/*
* 设备恢复(重新开始)例程。
*/
static int
mypci_resume(device_t dev)
{

    printf("Mypci resume!\n");
    return (0);
}

static device_method_t mypci_methods[] = {
    /* 设备接口 */
    DEVMETHOD(device_probe,     mypci_probe),
    DEVMETHOD(device_attach,    mypci_attach),
    DEVMETHOD(device_detach,    mypci_detach),
    DEVMETHOD(device_shutdown,  mypci_shutdown),
    DEVMETHOD(device_suspend,   mypci_suspend),
    DEVMETHOD(device_resume,    mypci_resume),

    { 0, 0 }
};

static devclass_t mypci_devclass;

DEFINE_CLASS_0(mypci, mypci_driver, mypci_methods, sizeof(struct mypci_softc));
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -