<< Back to man.ChinaUnix.net

Chapter 11 PCI Devices

Table of Contents
11.1 Probe and Attach
11.2 Bus Resources

This chapter will talk about the FreeBSD mechanisms for writing a device driver for a device on a PCI bus.

11.1 Probe and Attach

Information here about how the PCI bus code iterates through the unattached devices and see if a newly loaded kld will attach to any of them.

/*
 * Simple KLD to play with the PCI functions.
 *
 * Murray Stokely
 */

#define MIN(a,b) (((a) < (b)) ? (a) : (b))

#include <sys/param.h>  /* defines used in kernel.h */
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/kernel.h> /* types used in module initialization */
#include <sys/conf.h>   /* cdevsw struct */
#include <sys/uio.h>    /* uio struct */
#include <sys/malloc.h>
#include <sys/bus.h>  /* structs, prototypes for pci bus stuff */

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

#include <dev/pci/pcivar.h> /* For get_pci macros! */
#include <dev/pci/pcireg.h>

/* Function prototypes */
d_open_t    mypci_open;
d_close_t   mypci_close;
d_read_t    mypci_read;
d_write_t   mypci_write;

/* Character device entry points */

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

/* vars */
static dev_t sdev;

/* We're more interested in probe/attach than with
   open/close/read/write at this point */

int
mypci_open(dev_t dev, int oflags, int devtype, d_thread_t *td)
{
    int err = 0;

    printf("Opened device \"mypci\" successfully.\n");
    return (err);
}

int
mypci_close(dev_t dev, int fflag, int devtype, d_thread_t *td)
{
    int err = 0;

    printf("Closing device \"mypci.\"\n");
    return (err);
}

int
mypci_read(dev_t dev, struct uio *uio, int ioflag)
{
    int err = 0;

    printf("mypci read!\n");
    return (err);
}

int
mypci_write(dev_t dev, struct uio *uio, int ioflag)
{
    int err = 0;

    printf("mypci write!\n");
    return (err);
}

/* PCI Support Functions */

/*
 * Return identification string if this is device is ours.
 */
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");
        return (0);
    }
    return (ENXIO);
}

/* Attach function is only called if the probe is successful */

static int
mypci_attach(device_t dev)
{

    printf("MyPCI Attach for : deviceID : 0x%x\n",pci_get_vendor(dev));
    sdev = make_dev(&mypci_cdevsw, 0, UID_ROOT,
        GID_WHEEL, 0600, "mypci");
    printf("Mypci device loaded.\n");
    return (ENXIO);
}

/* Detach device. */

static int
mypci_detach(device_t dev)
{

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

/* Called during system shutdown after sync. */

static int
mypci_shutdown(device_t dev)
{

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

/*
 * Device suspend routine.
 */
static int
mypci_suspend(device_t dev)
{

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

/*
 * Device resume routine.
 */

static int
mypci_resume(device_t dev)
{

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

static device_method_t mypci_methods[] = {
    /* Device interface */
    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 driver_t mypci_driver = {
    "mypci",
    mypci_methods,
    0,
    /*  sizeof(struct mypci_softc), */
};

static devclass_t mypci_devclass;

DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);

Additional Resources



This, and other documents, can be downloaded from ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

For questions about FreeBSD, read the documentation before contacting <questions@FreeBSD.org>.
For questions about this documentation, e-mail <doc@FreeBSD.org>.