New driver writer

John Baldwin jhb at freebsd.org
Thu Apr 10 18:26:39 UTC 2008


On Tuesday 08 April 2008 03:29:07 pm Rick Hunnicutt wrote:
> Hello all,
>  
> I'm writing a BSD PCI character driver and have many questions. I have the 
architecture handbook and it answers some questions but leaves much 
unaddressed. For example, the parameters on the open/close/read/write calls 
don't seems to be address. Am I expected to dig around the code base to 
decipher their purpose or have I missed a vital area of documentation?
>  
> Thank you for your help.

Yeah, you'll have to dig for now. :(  The way you normally do cdev's though is 
something like this:

struct foo_softc {
	device_t	foo_dev;
	...
	struct cdev	*foo_cdev;
	...
};

static int
static int
foo_attach(device_t dev)
{
	struct foo_softc *sc;

	sc = device_get_softc(dev);
	....

	sc->foo_cdev = make_dev(&foo_cdevsw, unit2minor(device_get_unit(dev)),
	    UID_ROOT, GID_WHEEL, 0600, "foo%d", device_get_unit(dev));
	if (sc->foo_cdev == NULL)
		/* error handling */
	sc->foo_cdev->si_drv1 = sc;
	...
}

static int
foo_detach(device_t dev)
{

	...
	if (sc->foo_cdev)
		destroy_dev(sc->foo_cdev);
	...
}

static int
foo_open(struct cdev *dev, int flag, int mode, struct thread *td)
{
	struct foo_softc *sc;

	sc = dev->si_drv1;
	/* Now you have the foo_softc structure and can do whatever you want */
}

That is, the trick is for the driver to store a pointer to its softc structure 
in the 'si_drv1' member of the cdev when you create the cdev.  You can then 
get the softc pointer out of 'si_drv1' in your cdevsw routines.  There are 
also 'si_drv0' (u_int) and 'si_drv2' (another void * like 'si_drv1') fields 
in 'struct cdev' that the driver "owns" and is free to put whatever data is 
desired in.

-- 
John Baldwin


More information about the freebsd-drivers mailing list