Split off PCI chapter.
Submitted by: murray
This commit is contained in:
parent
fc669e67ec
commit
e1fe303667
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=8431
6 changed files with 660 additions and 636 deletions
|
@ -1,7 +1,7 @@
|
||||||
<!--
|
<!--
|
||||||
The FreeBSD Documentation Project
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.8 2000/11/28 18:31:02 asmodai Exp $
|
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.9 2000/11/28 19:04:02 asmodai Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
||||||
|
@ -313,217 +313,7 @@
|
||||||
<title>Device Drivers</title>
|
<title>Device Drivers</title>
|
||||||
|
|
||||||
&chap.driverbasics;
|
&chap.driverbasics;
|
||||||
|
&chap.pci;
|
||||||
<chapter id="pci">
|
|
||||||
<title>PCI Devices</title>
|
|
||||||
|
|
||||||
<para>This chapter will talk about the FreeBSD mechanisms for
|
|
||||||
writing a device driver for a device on a PCI bus.</para>
|
|
||||||
|
|
||||||
<sect1><title>Probe and Attach</title>
|
|
||||||
|
|
||||||
<para>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.</para>
|
|
||||||
<programlisting>
|
|
||||||
/*
|
|
||||||
* Simple KLD to play with the PCI functions.
|
|
||||||
*
|
|
||||||
* Murray Stokely
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/module.h>
|
|
||||||
#include <sys/systm.h> /* uprintf */
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<chapter id="usb">
|
<chapter id="usb">
|
||||||
<title>USB Devices</title>
|
<title>USB Devices</title>
|
||||||
|
|
218
en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml
Normal file
218
en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<!--
|
||||||
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
|
$FreeBSD:$
|
||||||
|
-->
|
||||||
|
|
||||||
|
<chapter id="pci">
|
||||||
|
<title>PCI Devices</title>
|
||||||
|
|
||||||
|
<para>This chapter will talk about the FreeBSD mechanisms for
|
||||||
|
writing a device driver for a device on a PCI bus.</para>
|
||||||
|
|
||||||
|
<sect1><title>Probe and Attach</title>
|
||||||
|
|
||||||
|
<para>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.</para>
|
||||||
|
<programlisting>
|
||||||
|
/*
|
||||||
|
* Simple KLD to play with the PCI functions.
|
||||||
|
*
|
||||||
|
* Murray Stokely
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/systm.h> /* uprintf */
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
||||||
|
<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>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!--
|
<!--
|
||||||
The FreeBSD Documentation Project
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.8 2000/11/28 18:31:02 asmodai Exp $
|
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.9 2000/11/28 19:04:02 asmodai Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
||||||
|
@ -313,217 +313,7 @@
|
||||||
<title>Device Drivers</title>
|
<title>Device Drivers</title>
|
||||||
|
|
||||||
&chap.driverbasics;
|
&chap.driverbasics;
|
||||||
|
&chap.pci;
|
||||||
<chapter id="pci">
|
|
||||||
<title>PCI Devices</title>
|
|
||||||
|
|
||||||
<para>This chapter will talk about the FreeBSD mechanisms for
|
|
||||||
writing a device driver for a device on a PCI bus.</para>
|
|
||||||
|
|
||||||
<sect1><title>Probe and Attach</title>
|
|
||||||
|
|
||||||
<para>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.</para>
|
|
||||||
<programlisting>
|
|
||||||
/*
|
|
||||||
* Simple KLD to play with the PCI functions.
|
|
||||||
*
|
|
||||||
* Murray Stokely
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/module.h>
|
|
||||||
#include <sys/systm.h> /* uprintf */
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<chapter id="usb">
|
<chapter id="usb">
|
||||||
<title>USB Devices</title>
|
<title>USB Devices</title>
|
||||||
|
|
218
en_US.ISO8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
218
en_US.ISO8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<!--
|
||||||
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
|
$FreeBSD:$
|
||||||
|
-->
|
||||||
|
|
||||||
|
<chapter id="pci">
|
||||||
|
<title>PCI Devices</title>
|
||||||
|
|
||||||
|
<para>This chapter will talk about the FreeBSD mechanisms for
|
||||||
|
writing a device driver for a device on a PCI bus.</para>
|
||||||
|
|
||||||
|
<sect1><title>Probe and Attach</title>
|
||||||
|
|
||||||
|
<para>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.</para>
|
||||||
|
<programlisting>
|
||||||
|
/*
|
||||||
|
* Simple KLD to play with the PCI functions.
|
||||||
|
*
|
||||||
|
* Murray Stokely
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/systm.h> /* uprintf */
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
||||||
|
<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>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!--
|
<!--
|
||||||
The FreeBSD Documentation Project
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.8 2000/11/28 18:31:02 asmodai Exp $
|
$FreeBSD: doc/en_US.ISO_8859-1/books/developers-handbook/book.sgml,v 1.9 2000/11/28 19:04:02 asmodai Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
<!DOCTYPE BOOK PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN" [
|
||||||
|
@ -313,217 +313,7 @@
|
||||||
<title>Device Drivers</title>
|
<title>Device Drivers</title>
|
||||||
|
|
||||||
&chap.driverbasics;
|
&chap.driverbasics;
|
||||||
|
&chap.pci;
|
||||||
<chapter id="pci">
|
|
||||||
<title>PCI Devices</title>
|
|
||||||
|
|
||||||
<para>This chapter will talk about the FreeBSD mechanisms for
|
|
||||||
writing a device driver for a device on a PCI bus.</para>
|
|
||||||
|
|
||||||
<sect1><title>Probe and Attach</title>
|
|
||||||
|
|
||||||
<para>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.</para>
|
|
||||||
<programlisting>
|
|
||||||
/*
|
|
||||||
* Simple KLD to play with the PCI functions.
|
|
||||||
*
|
|
||||||
* Murray Stokely
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/module.h>
|
|
||||||
#include <sys/systm.h> /* uprintf */
|
|
||||||
#include <sys/errno.h>
|
|
||||||
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<chapter id="usb">
|
<chapter id="usb">
|
||||||
<title>USB Devices</title>
|
<title>USB Devices</title>
|
||||||
|
|
218
en_US.ISO_8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
218
en_US.ISO_8859-1/books/developers-handbook/pci/chapter.sgml
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
<!--
|
||||||
|
The FreeBSD Documentation Project
|
||||||
|
|
||||||
|
$FreeBSD:$
|
||||||
|
-->
|
||||||
|
|
||||||
|
<chapter id="pci">
|
||||||
|
<title>PCI Devices</title>
|
||||||
|
|
||||||
|
<para>This chapter will talk about the FreeBSD mechanisms for
|
||||||
|
writing a device driver for a device on a PCI bus.</para>
|
||||||
|
|
||||||
|
<sect1><title>Probe and Attach</title>
|
||||||
|
|
||||||
|
<para>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.</para>
|
||||||
|
<programlisting>
|
||||||
|
/*
|
||||||
|
* Simple KLD to play with the PCI functions.
|
||||||
|
*
|
||||||
|
* Murray Stokely
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/systm.h> /* uprintf */
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <sys/param.h> /* defines used in kernel.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 <pci/pcivar.h> /* 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>Additional Resources
|
||||||
|
<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>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue