FreeBSD/sys/dev/drm/drm_drv.c
/* drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
 */
drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
drm_ioctl is called whenever a process performs an ioctl on / dev / drm .
int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags, 
    DRM_STRUCTPROC *p)
{
	struct drm_device *dev = drm_get_device_from_kdev(kdev);
	int retcode = 0;
	drm_ioctl_desc_t *ioctl;
	int (*func)(struct drm_device *dev, void *data, struct drm_file *file_priv);
	int nr = DRM_IOCTL_NR(cmd);
	int is_driver_ioctl = 0;
	struct drm_file *file_priv;
	retcode = devfs_get_cdevpriv((void **)&file_priv);
	if (retcode != 0) {
		DRM_ERROR("can't find authenticator\n");
		return EINVAL;
	}
	atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
	++file_priv->ioctl_count;
	DRM_DEBUG("pid=%d, cmd=0x%02lx, nr=0x%02x, dev 0x%lx, auth=%d\n",
	    DRM_CURRENTPID, cmd, nr, (long)dev->device,
	    file_priv->authenticated);
	switch (cmd) {
	case FIONBIO:
	case FIOASYNC:
		return 0;
	case FIOSETOWN:
		return fsetown(*(int *)data, &dev->buf_sigio);
	case FIOGETOWN:
		*(int *) data = fgetown(&dev->buf_sigio);
		return 0;
	}
	if (IOCGROUP(cmd) != DRM_IOCTL_BASE) {
		DRM_DEBUG("Bad ioctl group 0x%x\n", (int)IOCGROUP(cmd));
		return EINVAL;
	}
	ioctl = &drm_ioctls[nr];
	if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) {
		nr -= DRM_COMMAND_BASE;
		if (nr > dev->driver->max_ioctl) {
			DRM_DEBUG("Bad driver ioctl number, 0x%x (of 0x%x)\n",
			    nr, dev->driver->max_ioctl);
			return EINVAL;
		}
		ioctl = &dev->driver->ioctls[nr];
		is_driver_ioctl = 1;
	}
	func = ioctl->func;
	if (func == NULL) {
		DRM_DEBUG("no function\n");
		return EINVAL;
	}
	if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) ||
	    ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
	    ((ioctl->flags & DRM_MASTER) && !file_priv->master))
		return EACCES;
	if (is_driver_ioctl) {
		DRM_LOCK();
		retcode = -func(dev, data, file_priv);
		DRM_UNLOCK();
	} else {
		retcode = func(dev, data, file_priv);
	}
	if (retcode != 0)
		DRM_DEBUG("    returning %d\n", retcode);
	return retcode;
}
int drm_ioctl ( struct cdev * kdev , u_long cmd , caddr_t data , int flags , DRM_STRUCTPROC * p ) { struct drm_device * dev = drm_get_device_from_kdev ( kdev ) ; int retcode = 0 ; drm_ioctl_desc_t * ioctl ; int ( * func ) ( struct drm_device * dev , void * data , struct drm_file * file_priv ) ; int nr = DRM_IOCTL_NR ( cmd ) ; int is_driver_ioctl = 0 ; struct drm_file * file_priv ; retcode = devfs_get_cdevpriv ( ( void * * ) & file_priv ) ; if ( retcode != 0 ) { DRM_ERROR ( " \n " ) ; return EINVAL ; } atomic_inc ( & dev -> counts [ _DRM_STAT_IOCTLS ] ) ; ++ file_priv -> ioctl_count ; DRM_DEBUG ( " \n " , DRM_CURRENTPID , cmd , nr , ( long ) dev -> device , file_priv -> authenticated ) ; switch ( cmd ) { case FIONBIO : case FIOASYNC : return 0 ; case FIOSETOWN : return fsetown ( * ( int * ) data , & dev -> buf_sigio ) ; case FIOGETOWN : * ( int * ) data = fgetown ( & dev -> buf_sigio ) ; return 0 ; } if ( IOCGROUP ( cmd ) != DRM_IOCTL_BASE ) { DRM_DEBUG ( " \n " , ( int ) IOCGROUP ( cmd ) ) ; return EINVAL ; } ioctl = & drm_ioctls [ nr ] ; if ( ioctl -> func == NULL && nr >= DRM_COMMAND_BASE ) { nr -= DRM_COMMAND_BASE ; if ( nr > dev -> driver -> max_ioctl ) { DRM_DEBUG ( " \n " , nr , dev -> driver -> max_ioctl ) ; return EINVAL ; } ioctl = & dev -> driver -> ioctls [ nr ] ; is_driver_ioctl = 1 ; } func = ioctl -> func ; if ( func == NULL ) { DRM_DEBUG ( " \n " ) ; return EINVAL ; } if ( ( ( ioctl -> flags & DRM_ROOT_ONLY ) && ! DRM_SUSER ( p ) ) || ( ( ioctl -> flags & DRM_AUTH ) && ! file_priv -> authenticated ) || ( ( ioctl -> flags & DRM_MASTER ) && ! file_priv -> master ) ) return EACCES ; if ( is_driver_ioctl ) { DRM_LOCK ( ) ; retcode = - func ( dev , data , file_priv ) ; DRM_UNLOCK ( ) ; } else { retcode = func ( dev , data , file_priv ) ; } if ( retcode != 0 ) DRM_DEBUG ( " \n " , retcode ) ; return retcode ; }
drm_ioctl is called whenever a process performs an ioctl on /dev/drm.
drm_ioctl is called whenever a process performs an ioctl on / dev / drm .
/* It's not a core DRM ioctl, try driver-specific. */ /* The array entries begin at DRM_COMMAND_BASE ioctl nr */ /* shared code returns -errno */