English French (fr_FR)
/* table of supported bus methods */
static device_method_t xxx_isa_methods[] = {
/* list all the bus method functions supported by the driver */
/* omit the unsupported methods */
DEVMETHOD(device_identify, xxx_isa_identify),
DEVMETHOD(device_probe, xxx_isa_probe),
DEVMETHOD(device_attach, xxx_isa_attach),
DEVMETHOD(device_detach, xxx_isa_detach),
DEVMETHOD(device_shutdown, xxx_isa_shutdown),
DEVMETHOD(device_suspend, xxx_isa_suspend),
DEVMETHOD(device_resume, xxx_isa_resume),
static driver_t xxx_isa_driver = {
sizeof(struct xxx_softc),
static devclass_t xxx_devclass;
DRIVER_MODULE(xxx, isa, xxx_isa_driver, xxx_devclass,
load_function, load_argument);
Here struct `xxx_softc` is a device-specific structure that contains private driver data and descriptors for the driver's resources. The bus code automatically allocates one softc descriptor per device as needed.
If the driver is implemented as a loadable module then `load_function()` is called to do driver-specific initialization or clean-up when the driver is loaded or unloaded and load_argument is passed as one of its arguments. If the driver does not support dynamic loading (in other words it must always be linked into the kernel) then these values should be set to 0 and the last definition would look like:
DRIVER_MODULE(xxx, isa, xxx_isa_driver,
xxx_devclass, 0, 0);
If the driver is for a device which supports PnP then a table of supported PnP IDs must be defined. The table consists of a list of PnP IDs supported by this driver and human-readable descriptions of the hardware types and models having these IDs. It looks like:
static struct isa_pnp_id xxx_pnp_ids[] = {
/* a line for each supported PnP ID */
{ 0x12345678, "Our device model 1234A" },
{ 0x12345679, "Our device model 1234B" },
{ 0, NULL }, /* end of table */
If the driver does not support PnP devices it still needs an empty PnP ID table, like:
static struct isa_pnp_id xxx_pnp_ids[] = {
{ 0, NULL }, /* end of table */
`device_t` Pointer
`device_t` is the pointer type for the device structure. Here we consider only the methods interesting from the device driver writer's standpoint. The methods to manipulate values in the device structure are:
`device_t device_get_parent(dev)` Get the parent bus of a device.
`driver_t device_get_driver(dev)` Get pointer to its driver structure.
`char *device_get_name(dev)` Get the driver name, such as `"xxx"` for our example.
`int device_get_unit(dev)` Get the unit number (units are numbered from 0 for the devices associated with each driver).
`char *device_get_nameunit(dev)` Get the device name including the unit number, such as "xxx0", "xxx1" and so on.
`char *device_get_desc(dev)` Get the device description. Normally it describes the exact model of device in human-readable form.