Writing Device Drivers

ioctl(9E)

In a 32-bit system, the ioctl(9E) entry point takes an int as the argument to pass a 32-bit value or user address to the device driver. In a 64-bit system, this argument must handle 64-bit values and addresses. Therefore, the ioctl(9E) function prototype has changed from:

	int (*cb_ioctl)(dev_t dev, int cmd, int arg, int mode,
 							cred_t *credp, int *rvalp);

to:

	int (*cb_ioctl)(dev_t dev, int cmd, intptr_t arg, int mode,
 							cred_t *credp, int *rvalp);

Note that intptr_t arg remains 32-bits when compiled in the ILP32 kernel.

To determine whether there is a model mismatch between the application and the driver, the driver uses the FMODELS mask to determine the model type from the ioctl(9E) mode argument. The following values are passed in mode to identify the application data model:

The driver passes the data model type to ddi_model_convert_from(9F), which determines if adjustments are needed to the application data structures.

Example F-1 demonstrates the use of the _MULTI_DATAMODEL macro and the ddi_model_convert_from(9F) function.


Example F-1 ioctl(9E)

struct passargs {
	int		len;
	caddr_t		addr
} pa;

xxioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t
*credp,
			int *rvalp)
{
	...
#ifdef _MULTI_DATAMODEL
	switch (ddi_model_convert_from(mode & FMODELS)) {
	case DDI_MODEL_ILP32:
	{
	  	struct passargs32 {
			int			len;
			uint32_t			*addr;
	  	} pa32;

		(void) ddi_copyin((void *)arg, &pa32,
					sizeof (struct passargs32), mode);
		pa.len = pa32.len;
		pa.addr = pa32.address;
		break;
	}
	case DDI_MODEL_NONE:
		(void) ddi_copyin((void *)arg, &pa,
					sizeof (struct passargs), mode);
		break;
	}
#else /* ! _MULTI_DATAMODEL */
	(void) ddi_copyin((void *)arg, &pa,
				sizeof (struct passargs), mode);
#endif /* ! _MULTI_DATAMODEL */
	do_ioctl(&pa);
	...
}

Data structure macros are another method of referring to the data structure from the user application. The macros effectively hide the difference between the data model of the user application and the driver. For more information see "Data Structure Macros".