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 [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to