diff --git a/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml b/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml index 76e5730f42..3c4ab5c395 100644 --- a/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml +++ b/en_US.ISO8859-1/books/arch-handbook/pci/chapter.sgml @@ -19,40 +19,48 @@ the unattached devices and see if a newly loaded kld will attach to any of them. + + Sample Driver Source (<filename>mypci.c</filename>) + /* * 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/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/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 <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/pcivar.h> /* For pci_get macros! */ #include <dev/pci/pcireg.h> +/* The softc holds our per-instance data. */ +struct mypci_softc { + device_t my_dev; + struct cdev *my_cdev; +}; + /* Function prototypes */ -d_open_t mypci_open; -d_close_t mypci_close; -d_read_t mypci_read; -d_write_t mypci_write; +static d_open_t mypci_open; +static d_close_t mypci_close; +static d_read_t mypci_read; +static d_write_t mypci_write; /* Character device entry points */ static struct cdevsw mypci_cdevsw = { + .d_version = D_VERSION, .d_open = mypci_open, .d_close = mypci_close, .d_read = mypci_read, @@ -60,62 +68,73 @@ static struct cdevsw mypci_cdevsw = { .d_name = "mypci", }; -/* vars */ -static dev_t sdev; - -/* We're more interested in probe/attach than with - open/close/read/write at this point */ +/* + * In the cdevsw routines, we find our softc by using the si_drv1 member + * of struct cdev. We set this variable to point to our softc in our + * attach routine when we create the /dev entry. + */ int -mypci_open(dev_t dev, int oflags, int devtype, d_thread_t *td) +mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td) { - int err = 0; + struct mypci_softc *sc; - printf("Opened device \"mypci\" successfully.\n"); - return (err); + /* Look up our softc. */ + sc = dev->si_drv1; + device_printf(sc->my_dev, "Opened successfully.\n"); + return (0); } int -mypci_close(dev_t dev, int fflag, int devtype, d_thread_t *td) +mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td) { - int err = 0; + struct mypci_softc *sc; - printf("Closing device \"mypci.\"\n"); - return (err); + /* Look up our softc. */ + sc = dev->si_drv1; + device_printf(sc->my_dev, "Closed.\n"); + return (0); } int -mypci_read(dev_t dev, struct uio *uio, int ioflag) +mypci_read(struct cdev *dev, struct uio *uio, int ioflag) { - int err = 0; + struct mypci_softc *sc; - printf("mypci read!\n"); - return (err); + /* 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(dev_t dev, struct uio *uio, int ioflag) +mypci_write(struct cdev *dev, struct uio *uio, int ioflag) { - int err = 0; + struct mypci_softc *sc; - printf("mypci write!\n"); + /* Look up our softc. */ + sc = dev->si_drv1; + device_printf(sc->my_dev, "Asked to write %d bytes.\n", uio->uio_resid); return (err); } /* PCI Support Functions */ /* - * Return identification string if this is device is ours. + * Compare the device ID of this device against the IDs that this driver + * supports. If there is a match, set the description and return success. */ 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); + device_set_desc(dev, "WinModem"); + return (BUS_PROBE_DEFAULT); } return (ENXIO); } @@ -125,10 +144,22 @@ mypci_probe(device_t dev) static int mypci_attach(device_t dev) { + struct mypci_softc *sc; printf("MyPCI Attach for : deviceID : 0x%x\n",pci_get_vendor(dev)); - sdev = make_dev(&mypci_cdevsw, 0, UID_ROOT, - GID_WHEEL, 0600, "mypci"); + + /* 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)); printf("Mypci device loaded.\n"); return (ENXIO); } @@ -138,7 +169,11 @@ mypci_attach(device_t dev) 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); } @@ -167,7 +202,6 @@ mypci_suspend(device_t dev) /* * Device resume routine. */ - static int mypci_resume(device_t dev) { @@ -188,27 +222,43 @@ static device_method_t mypci_methods[] = { { 0, 0 } }; -static driver_t mypci_driver = { - "mypci", - mypci_methods, - 0, - /* sizeof(struct mypci_softc), */ -}; - 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); + - Additional Resources - - PCI - Special Interest Group + + <filename>Makefile</filename> for Sample Driver - PCI System Architecture, Fourth Edition by - Tom Shanley, et al. +# Makefile for mypci driver - - +KMOD= mypci +SRCS= mypci.c +SRCS+= device_if.h bus_if.h pci_if.h + +.include <bsd.kmod.mk> + + If you place the above source file and + Makefile into a directory, you may run + make to compile the sample driver. + Additionally, you may run make load to load + the driver into the currently running kernel and make + unload to unload the driver after it is + loaded. + + + + Additional Resources + + PCI + Special Interest Group + + PCI System Architecture, Fourth Edition by + Tom Shanley, et al. + + +