Date: Sun, 02 Dec 2001 18:28:00 -0700 From: Warner Losh <imp@harmony.village.org> To: "Dragon Fire" <dragonfire820@mediaone.net> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: device object, driver object, cdevsw Message-ID: <200112030128.fB31S0M62172@harmony.village.org> In-Reply-To: Your message of "Sun, 02 Dec 2001 14:56:48 EST." <000601c17b6b$7a89c190$037d6041@gandalf> References: <000601c17b6b$7a89c190$037d6041@gandalf>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <000601c17b6b$7a89c190$037d6041@gandalf> "Dragon Fire" writes:
: I'm writing a PCI character device driver and need some clairification.
:
: As I see the FreeBSD driver structure there are really two components to a
: device driver, there is the KLD component which contains the device methods
: for probe, attach, detach, etc and handles the dynamic componet of the
: driver. Then there is the traditional Unix cdevsw structure which handles
: the read, write, ioctl etc.
:
: The few places the KLD is documented really doesn't cover the link between
: the two elements KLD and cdevsw. I understand that if successsfully probed
: the attach creates the dev_t using the cdevw table. But I'm having
: difficulty seeing the relationship.
:
: Would it be fair to say the KLD components represent the dynamics kernel
: facilities and the cdevsw implments what we consider the "traditional" Unix
: device driver. Could somebody shed light on this subject.
The matter is actually fairly simple.
Your make_dev() calls assocaite the cdevsw to use with the device
nodes you create (which also must be created using mknod in -stable or
current w/o devfs).
Typically, you won't have to worry too much about the link between the
two. It just happens.
I typically have something like:
...
static d_open_t xxx_open;
static d_close_t xxx_close;
static d_ioctl_t xxx_ioctl;
static d_read_t xxx_read;
static d_write_t xxx_write;
static d_mmap_t xxx_mmap;
static devclass_t xxx_devclass;
#if __FreeBSD_version < 500023
typedef struct proc d_thread_t;
#endif
#define CDEV_MAJOR 238 /* Must match dev entries in /dev */
static struct cdevsw xxx_cdevsw = {
/* open */ xxx_open,
/* close */ xxx_close,
/* read */ xxx_read,
/* write */ xxx_write,
/* ioctl */ xxx_ioctl,
/* poll */ nopoll,
/* mmap */ xxx_mmap,
/* strategy */ nostrategy,
/* name */ "tscpci",
/* maj */ CDEV_MAJOR,
/* dump */ nodump,
/* psize */ nopsize,
/* flags */ 0,
/* bmaj */ -1
};
static int xxx_probe(device_t dev);
static int xxx_attach(device_t dev);
static int xxx_detach(device_t dev);
static device_method_t xxx_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, xxx_probe),
DEVMETHOD(device_attach, xxx_attach),
DEVMETHOD(device_detach, xxx_detach),
{ 0, 0 }
};
static driver_t xxx_driver = {
"tscpci",
xxx_methods,
sizeof(xxx_softc),
};
DRIVER_MODULE(tscpci, pci, xxx_driver, xxx_devclass, 0, 0);
<definitions for the xxx_* routines>
In xxx_attach, I have:
sc->d = make_dev(&xxx_cdevsw, unit, 0, 0, 0666, "xxx%d", unit);
where sc is a softc pointer (which you have to define, by convention
it is xxx_softc or something similar).
That's all it takes to do the association.
Warner
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200112030128.fB31S0M62172>
