FreeBSD/sys/dev/drm2/drm_fops.c
/**
 * Called whenever a process opens /dev/drm.
 *
 * \param inode device inode.
 * \param filp file pointer.
 * \param dev device.
 * \return zero on success or a negative number on failure.
 *
 * Creates and initializes a drm_file structure for the file private data in \p
 * filp and add it into the double linked list in \p dev.
 */
Called whenever a process opens /dev/drm.
\param inode device inode.
\param filp file pointer.
\param dev device.
\return zero on success or a negative number on failure.

Creates and initializes a drm_file structure for the file private data in \p
filp and add it into the double linked list in \p dev.
Called whenever a process opens / dev / drm . \ param inode device inode . \ param filp file pointer . \ param dev device . \ return zero on success or a negative number on failure . Creates and initializes a drm_file structure for the file private data in \ p filp and add it into the double linked list in \ p dev .
static int drm_open_helper(struct cdev *kdev, int flags, int fmt,
			   DRM_STRUCTPROC *p, struct drm_device *dev)
{
	struct drm_file *priv;
	int ret;
	if (flags & O_EXCL)
		return -EBUSY;	
	if (dev->switch_power_state != DRM_SWITCH_POWER_ON)
		return -EINVAL;
	DRM_DEBUG("pid = %d, device = %s\n", DRM_CURRENTPID, devtoname(kdev));
	priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO);
	if (!priv)
		return -ENOMEM;
	priv->uid = p->td_ucred->cr_svuid;
	priv->pid = p->td_proc->p_pid;
	priv->minor = kdev->si_drv1;
	priv->ioctl_count = 0;
	priv->authenticated = DRM_SUSER(p);
	priv->lock_count = 0;
	INIT_LIST_HEAD(&priv->lhead);
	INIT_LIST_HEAD(&priv->fbs);
	INIT_LIST_HEAD(&priv->event_list);
	priv->event_space = 4096; 
	if (dev->driver->driver_features & DRIVER_GEM)
		drm_gem_open(dev, priv);
#ifdef FREEBSD_NOTYET
	if (drm_core_check_feature(dev, DRIVER_PRIME))
		drm_prime_init_file_private(&priv->prime);
#endif 
	if (dev->driver->open) {
		ret = dev->driver->open(dev, priv);
		if (ret < 0)
			goto out_free;
	}
	DRM_LOCK(dev);
	if (!priv->minor->master) {
		priv->minor->master = drm_master_create(priv->minor);
		if (!priv->minor->master) {
			DRM_UNLOCK(dev);
			ret = -ENOMEM;
			goto out_free;
		}
		priv->is_master = 1;
		priv->master = drm_master_get(priv->minor->master);
		priv->authenticated = 1;
		DRM_UNLOCK(dev);
		if (dev->driver->master_create) {
			ret = dev->driver->master_create(dev, priv->master);
			if (ret) {
				DRM_LOCK(dev);
				drm_master_put(&priv->minor->master);
				drm_master_put(&priv->master);
				DRM_UNLOCK(dev);
				goto out_free;
			}
		}
		DRM_LOCK(dev);
		if (dev->driver->master_set) {
			ret = dev->driver->master_set(dev, priv, true);
			if (ret) {
				drm_master_put(&priv->minor->master);
				drm_master_put(&priv->master);
				DRM_UNLOCK(dev);
				goto out_free;
			}
		}
		DRM_UNLOCK(dev);
	} else {
		priv->master = drm_master_get(priv->minor->master);
		DRM_UNLOCK(dev);
	}
	DRM_LOCK(dev);
	list_add(&priv->lhead, &dev->filelist);
	DRM_UNLOCK(dev);
	mtx_lock(&Giant); 
	device_busy(dev->dev);
	mtx_unlock(&Giant);
	ret = devfs_set_cdevpriv(priv, drm_release);
	if (ret != 0)
		drm_release(priv);
	return ret;
      out_free:
	free(priv, DRM_MEM_FILES);
	return ret;
}
static int drm_open_helper ( struct cdev * kdev , int flags , int fmt , DRM_STRUCTPROC * p , struct drm_device * dev ) { struct drm_file * priv ; int ret ; if ( flags & O_EXCL ) return - EBUSY ; if ( dev -> switch_power_state != DRM_SWITCH_POWER_ON ) return - EINVAL ; DRM_DEBUG ( " \n " , DRM_CURRENTPID , devtoname ( kdev ) ) ; priv = malloc ( sizeof ( * priv ) , DRM_MEM_FILES , M_NOWAIT | M_ZERO ) ; if ( ! priv ) return - ENOMEM ; priv -> uid = p -> td_ucred -> cr_svuid ; priv -> pid = p -> td_proc -> p_pid ; priv -> minor = kdev -> si_drv1 ; priv -> ioctl_count = 0 ; priv -> authenticated = DRM_SUSER ( p ) ; priv -> lock_count = 0 ; INIT_LIST_HEAD ( & priv -> lhead ) ; INIT_LIST_HEAD ( & priv -> fbs ) ; INIT_LIST_HEAD ( & priv -> event_list ) ; priv -> event_space = 4096 ; if ( dev -> driver -> driver_features & DRIVER_GEM ) drm_gem_open ( dev , priv ) ; #ifdef FREEBSD_NOTYET if ( drm_core_check_feature ( dev , DRIVER_PRIME ) ) drm_prime_init_file_private ( & priv -> prime ) ; #endif if ( dev -> driver -> open ) { ret = dev -> driver -> open ( dev , priv ) ; if ( ret < 0 ) goto out_free ; } DRM_LOCK ( dev ) ; if ( ! priv -> minor -> master ) { priv -> minor -> master = drm_master_create ( priv -> minor ) ; if ( ! priv -> minor -> master ) { DRM_UNLOCK ( dev ) ; ret = - ENOMEM ; goto out_free ; } priv -> is_master = 1 ; priv -> master = drm_master_get ( priv -> minor -> master ) ; priv -> authenticated = 1 ; DRM_UNLOCK ( dev ) ; if ( dev -> driver -> master_create ) { ret = dev -> driver -> master_create ( dev , priv -> master ) ; if ( ret ) { DRM_LOCK ( dev ) ; drm_master_put ( & priv -> minor -> master ) ; drm_master_put ( & priv -> master ) ; DRM_UNLOCK ( dev ) ; goto out_free ; } } DRM_LOCK ( dev ) ; if ( dev -> driver -> master_set ) { ret = dev -> driver -> master_set ( dev , priv , true ) ; if ( ret ) { drm_master_put ( & priv -> minor -> master ) ; drm_master_put ( & priv -> master ) ; DRM_UNLOCK ( dev ) ; goto out_free ; } } DRM_UNLOCK ( dev ) ; } else { priv -> master = drm_master_get ( priv -> minor -> master ) ; DRM_UNLOCK ( dev ) ; } DRM_LOCK ( dev ) ; list_add ( & priv -> lhead , & dev -> filelist ) ; DRM_UNLOCK ( dev ) ; mtx_lock ( & Giant ) ; device_busy ( dev -> dev ) ; mtx_unlock ( & Giant ) ; ret = devfs_set_cdevpriv ( priv , drm_release ) ; if ( ret != 0 ) drm_release ( priv ) ; return ret ; out_free : free ( priv , DRM_MEM_FILES ) ; return ret ; }
Called whenever a process opens /dev/drm.
Called whenever a process opens / dev / drm .
/* No exclusive opens */ /* for compatibility root is always authenticated */ /* set aside 4k for event buffer */ /* FREEBSD_NOTYET */ /* if there is no current master make this fd it */ /* create a new master */ /* take another reference for the copy in the local file priv */ /* drop both references if this fails */ /* drop both references if this fails */ /* get a reference to the master */ /* FIXME: Giant required? */