MAC_INIT_OPS(9F) Kernel Functions for Drivers MAC_INIT_OPS(9F)

mac_init_ops, mac_fini_ops
initialize and finalize driver support for the MAC framework

#include <sys/mac_provider.h>

void
mac_init_ops(struct dev_ops *ops, const char *name);

void
mac_fini_ops(struct dev_ops *ops);

illumos DDI specific

ops
A pointer to the driver's dev_ops(9S) structure.
name
A pointer to a null-terminated string of ASCII characters that contains the name of the driver.

The mac_init_ops() and mac_fini_ops() functions are used to initialize and finalize support for a device driver that implements the mac(9E) networking device framework.

The mac_init_ops() function should be called during the driver's _init(9E) entry point. As described in more detail in the Initializing MAC Support section of mac(9E), this must be called before the driver calls mod_install(9F). If this is not done, then the call to mac_register(9F) will fail.

When in the driver's _fini(9E) entry point, after the call to mod_remove(9F) has succeeded, then the driver must call the mac_fini_ops() function to finalize support and finish releasing any resources. If the call to mod_remove(9F) fails, then the device driver should not call mac_fini_ops() and should fail the call to _fini(9E).

In addition, if the call to mod_install(9F) in the driver's _init(9E) entry point fails, then the driver should also call mac_fini_ops(). See the example below for how this should be structured.

The mac_init_ops() function should only ever be called from the context of a driver's _init(9E) entry point.

The mac_fini_ops() function should only ever be called from the context of a driver's _init(9E) or _fini(9E) entry point.

The mac_init_ops() and mac_fini_ops() functions will always succeed. They do not have any kind of return value.

The following example shows how a driver would call mac_init_ops() and mac_fini_ops() correctly in the _init(9E) and _fini(9E) entry points of a driver.
#include <sys/modctl.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/mac_provider.h>

/*
 * When using this, replace mydrv with the name of the actual device
 * driver. In addition, the mydrv_ prefix that is used should be
 * replaced with the name of the device driver
 */
#define	MYDRV_NAME	"mydrv"

/*
 * The following dev_ops structure would need to be filled in by a
 * proper device driver.
 */
static struct dev_ops	mydrv_dev_ops;

static struct modldrv mydrv_modldrv = {
	&mod_driverops,
	MYDRV_NAME,
	&mydrv_dev_ops
};

static struct modlinkage mydrv_modlinkage = {
	MODREV_1,
	&mydrv_modldrv,
	NULL
};

int
_init(void)
{
	int ret;

	/* Perform other needed initialization */

	mac_init_ops(&mydrv_devops, MYDRV_NAME);

	ret = mod_install(&mydrv_modlinkage);
	if (ret != DDI_SUCCESS) {
		mac_fini_ops(&mydrv_devops);
		/* Perform other needed finalization */
	}

	return (ret);
}

int
_info(struct modinfo *modinfop)
{
	return (mod_info(&mydrv_modlinkage, modinfo));
}

int
_fini(void)
{
	int ret;

	ret = mod_remove(&mydrv_modlinkage);
	if (ret == DDI_SUCCESS) {
		mac_fini_ops(&mydrv_devops);
		/* Perform other needed finalization */
	}

	return (ret);
}

_fini(9E), _init(9E), mac(9E), mod_install(9F), mod_remove(9F), dev_ops(9S)
May 31, 2016 OmniOS