Глава 9. Устройства PCI

Содержание
9.1. Обнаружение и подключение
9.2. Ресурсы шины

Эта глава посвящена механизмам FreeBSD по написанию драйверов устройств, работающих на шине PCI.

9.1. Обнаружение и подключение

Здесь находится информация о том, как код шины PCI проходит по не подключенным устройствам и распознает возможность загруженного драйвера kld выполнить подключение к какому-либо из них.

/*
 * 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, struct 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);

Дополнительная информация



Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.