/** * * @returns 0 on success, errno on failure. * EBUSY if the device is used by someone else. * @param pDev The device node. * @param fOpen The open flags. * @param pTd The thread. * @param iDevType ??? */ static int vboxdrvFreeBSDOpenCommon(struct cdev *pDev, int fOpen, int iDevtype, struct thread *pTd, bool fUnrestricted) { PSUPDRVSESSION pSession; int rc; /* * Let's be a bit picky about the flags... */ if (fOpen != (FREAD | FWRITE /*=O_RDWR*/)) { Log(("VBoxDrvFreeBSDOpen: fOpen=%#x expected %#x\n", fOpen, O_RDWR)); return EINVAL; } /* * Create a new session. */ rc = supdrvCreateSession(&g_VBoxDrvFreeBSDDevExt, true /* fUser */, fUnrestricted, &pSession); if (RT_SUCCESS(rc)) { /** @todo get (r)uid and (r)gid. pSession->Uid = stuff; pSession->Gid = stuff; */ devfs_set_cdevpriv(pSession, VBoxDrvFreeBSDDtr); Log(("VBoxDrvFreeBSDOpen: pSession=%p\n", pSession)); ASMAtomicIncU32(&g_cUsers); return 0; } return RTErrConvertToErrno(rc); }
/* drm_open_helper is called whenever a process opens /dev/drm. */ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, struct drm_device *dev, struct file *fp) { struct drm_file *priv; int retcode; if (flags & O_EXCL) return EBUSY; /* No exclusive opens */ dev->flags = flags; DRM_DEBUG("pid = %d, device = %s\n", DRM_CURRENTPID, devtoname(kdev)); priv = kmalloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); if (priv == NULL) { return ENOMEM; } DRM_LOCK(dev); priv->dev = dev; priv->uid = p->td_proc->p_ucred->cr_svuid; priv->pid = p->td_proc->p_pid; priv->ioctl_count = 0; /* for compatibility root is always authenticated */ priv->authenticated = DRM_SUSER(p); INIT_LIST_HEAD(&priv->fbs); INIT_LIST_HEAD(&priv->event_list); init_waitqueue_head(&priv->event_wait); priv->event_space = 4096; /* set aside 4k for event buffer */ if (dev->driver->driver_features & DRIVER_GEM) drm_gem_open(dev, priv); if (dev->driver->open) { /* shared code returns -errno */ retcode = -dev->driver->open(dev, priv); if (retcode != 0) { drm_free(priv, DRM_MEM_FILES); DRM_UNLOCK(dev); return retcode; } } /* first opener automatically becomes master */ priv->master = list_empty(&dev->filelist); list_add(&priv->lhead, &dev->filelist); DRM_UNLOCK(dev); kdev->si_drv1 = dev; retcode = devfs_set_cdevpriv(fp, priv, &drm_cdevpriv_dtor); if (retcode != 0) drm_cdevpriv_dtor(priv); return retcode; }
/* drm_open_helper is called whenever a process opens /dev/drm. */ int drm_open_helper(struct cdev *kdev, int flags, int fmt, DRM_STRUCTPROC *p, struct drm_device *dev) { struct drm_file *priv; int m = dev2unit(kdev); int retcode; if (flags & O_EXCL) return EBUSY; /* No exclusive opens */ dev->flags = flags; DRM_DEBUG("pid = %d, minor = %d\n", DRM_CURRENTPID, m); priv = malloc(sizeof(*priv), DRM_MEM_FILES, M_NOWAIT | M_ZERO); if (priv == NULL) { return ENOMEM; } retcode = devfs_set_cdevpriv(priv, drm_close); if (retcode != 0) { free(priv, DRM_MEM_FILES); return retcode; } DRM_LOCK(); priv->dev = dev; priv->uid = p->td_ucred->cr_svuid; priv->pid = p->td_proc->p_pid; priv->minor = m; priv->ioctl_count = 0; /* for compatibility root is always authenticated */ priv->authenticated = DRM_SUSER(p); if (dev->driver->open) { /* shared code returns -errno */ retcode = -dev->driver->open(dev, priv); if (retcode != 0) { devfs_clear_cdevpriv(); free(priv, DRM_MEM_FILES); DRM_UNLOCK(); return retcode; } } /* first opener automatically becomes master */ priv->master = TAILQ_EMPTY(&dev->files); TAILQ_INSERT_TAIL(&dev->files, priv, link); DRM_UNLOCK(); kdev->si_drv1 = dev; return 0; }
/* * Resources are set up on a per-open basis */ static int fuse_device_open(struct cdev *dev, int oflags, int devtype, struct thread *td) { struct fuse_data *fdata; int error; SDT_PROBE2(fuse, , device, trace, 1, "device open"); fdata = fdata_alloc(dev, td->td_ucred); error = devfs_set_cdevpriv(fdata, fdata_dtor); if (error != 0) fdata_trydestroy(fdata); else SDT_PROBE2(fuse, , device, trace, 1, "device open success"); return (error); }
static int apmopen(struct cdev *dev, int flag, int fmt, struct thread *td) { struct acpi_softc *acpi_sc; struct apm_clone_data *clone; acpi_sc = devclass_get_softc(devclass_find("acpi"), 0); clone = apm_create_clone(dev, acpi_sc); devfs_set_cdevpriv(clone, apmdtor); /* If the device is opened for write, record that. */ if ((flag & FWRITE) != 0) clone->flags |= ACPI_EVF_WRITE; return (0); }
static int iicopen(struct cdev *dev, int flags, int fmt, struct thread *td) { struct iic_cdevpriv *priv; int error; priv = malloc(sizeof(*priv), M_IIC, M_WAITOK | M_ZERO); sx_init(&priv->lock, "iic"); priv->sc = dev->si_drv1; error = devfs_set_cdevpriv(priv, iicdtor); if (error != 0) free(priv, M_IIC); return (error); }
static int filemon_open(struct cdev *dev, int oflags __unused, int devtype __unused, struct thread *td) { int error; struct filemon *filemon; filemon = malloc(sizeof(*filemon), M_FILEMON, M_WAITOK | M_ZERO); sx_init(&filemon->lock, "filemon"); refcount_init(&filemon->refcnt, 1); filemon->cred = crhold(td->td_ucred); error = devfs_set_cdevpriv(filemon, filemon_dtr); if (error != 0) filemon_release(filemon); return (error); }
static int netmap_open(struct dev_open_args *ap) { struct netmap_priv_d *priv; int error; // XXX wait or nowait ? priv = kmalloc(sizeof(struct netmap_priv_d), M_DEVBUF, M_NOWAIT | M_ZERO); if (priv == NULL) return ENOMEM; error = devfs_set_cdevpriv(ap->a_fp, priv, netmap_dtor); if (error) return error; priv->np_refcount = 1; return 0; }
/* * USER DEVICE I/O FUNCTIONS */ static int cyapaopen(struct cdev *dev, int oflags, int devtype, struct thread *td) { struct cyapa_cdevpriv *priv; int error; priv = malloc(sizeof(*priv), M_CYAPA, M_WAITOK | M_ZERO); priv->sc = dev->si_drv1; error = devfs_set_cdevpriv(priv, cyapa_cdevpriv_dtor); if (error == 0) { cyapa_lock(priv->sc); priv->sc->count++; cyapa_unlock(priv->sc); } else free(priv, M_CYAPA); return (error); }