<!--
     The FreeBSD Russian Documentation Project

     $FreeBSD: doc/ru_RU.KOI8-R/books/developers-handbook/pci/chapter.sgml,v 1.1 2001/03/11 16:40:33 phantom Exp $
     $FreeBSDru: frdp/doc/ru_RU.KOI8-R/books/developers-handbook/pci/chapter.sgml,v 1.1 2001/02/19 06:50:23 andy Exp $

     Original revision: 1.1
-->

<chapter id="pci">
  <title>Устройства PCI</title>

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

  <sect1><title>Обнаружение и подключение</title>

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

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

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

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

#include &lt;pci/pcivar.h&gt; /* For get_pci macros! */

/* 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 = {
  mypci_open,
  mypci_close,
  mypci_read,
  mypci_write,
  noioctl,
  nopoll,
  nommap,
  nostrategy,
  "mypci",
  36,                   /* reserved for lkms - /usr/src/sys/conf/majors */
  nodump,
  nopsize,
  D_TTY,
  -1
};

/* 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, struct proc *p)
{
  int err = 0;

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

int
mypci_close(dev_t dev, int fflag, int devtype, struct proc *p)
{
  int err=0;

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

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

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

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

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

/* PCI Support Functions */

/*
 * Return identification string if this is device is ours.
 */
static int
mypci_probe(device_t dev)
{
  uprintf("MyPCI Probe\n"
          "Vendor ID : 0x%x\n"
          "Device ID : 0x%x\n",pci_get_vendor(dev),pci_get_device(dev));

  if (pci_get_vendor(dev) == 0x11c1) {
    uprintf("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)
{
  uprintf("MyPCI Attach for : deviceID : 0x%x\n",pci_get_vendor(dev));
  sdev = make_dev(<literal>&</literal>mypci_cdevsw,
                  0,
                  UID_ROOT,
                  GID_WHEEL,
                  0600,
                  "mypci");
  uprintf("Mypci device loaded.\n");
  return ENXIO;
}

/* Detach device. */

static int
mypci_detach(device_t dev)
{
  uprintf("Mypci detach!\n");
  return 0;
}

/* Called during system shutdown after sync. */

static int
mypci_shutdown(device_t dev)
{
  uprintf("Mypci shutdown!\n");
  return 0;
}

/*
 * Device suspend routine.
 */
static int
mypci_suspend(device_t dev)
{
  uprintf("Mypci suspend!\n");
  return 0;
}

/*
 * Device resume routine.
 */

static int
mypci_resume(device_t dev)
{
  uprintf("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);
  </programlisting>

  <para>Дополнительная информация
    <itemizedlist>
      <listitem><simpara><ulink
        url="http://www.pcisig.org">PCI Special Interest
        Group</ulink></simpara>
      </listitem>
      <listitem><simpara>PCI System Architecture, Fourth Edition by
        Tom Shanley, et al.</simpara></listitem>
    </itemizedlist>
  </para>
</sect1>
</chapter>