int drm_read(struct dev_read_args *ap) { struct cdev *kdev = ap->a_head.a_dev; struct uio *uio = ap->a_uio; int ioflag = ap->a_ioflag; struct drm_file *file_priv; struct drm_device *dev; struct drm_pending_event *e; int error; error = devfs_get_cdevpriv(ap->a_fp, (void **)&file_priv); if (error != 0) { DRM_ERROR("can't find authenticator\n"); return (EINVAL); } dev = drm_get_device_from_kdev(kdev); lockmgr(&dev->event_lock, LK_EXCLUSIVE); while (list_empty(&file_priv->event_list)) { if ((ioflag & O_NONBLOCK) != 0) { error = EAGAIN; goto out; } error = lksleep(&file_priv->event_space, &dev->event_lock, PCATCH, "drmrea", 0); if (error != 0) goto out; } while (drm_dequeue_event(dev, file_priv, uio, &e)) { lockmgr(&dev->event_lock, LK_RELEASE); error = uiomove((caddr_t)e->event, e->event->length, uio); e->destroy(e); if (error != 0) return (error); lockmgr(&dev->event_lock, LK_EXCLUSIVE); } out: lockmgr(&dev->event_lock, LK_RELEASE); return (error); }
int drm_read(struct cdev *kdev, struct uio *uio, int ioflag) { struct drm_file *file_priv; struct drm_device *dev; struct drm_pending_event *e; int error; error = devfs_get_cdevpriv((void **)&file_priv); if (error != 0) { DRM_ERROR("can't find authenticator\n"); return (EINVAL); } dev = drm_get_device_from_kdev(kdev); mtx_lock(&dev->event_lock); while (list_empty(&file_priv->event_list)) { if ((ioflag & O_NONBLOCK) != 0) { error = EAGAIN; goto out; } error = msleep(&file_priv->event_space, &dev->event_lock, PCATCH, "drmrea", 0); if (error != 0) goto out; } while (drm_dequeue_event(dev, file_priv, uio, &e)) { mtx_unlock(&dev->event_lock); error = uiomove(e->event, e->event->length, uio); CTR3(KTR_DRM, "drm_event_dequeued %d %d %d", curproc->p_pid, e->event->type, e->event->length); e->destroy(e); if (error != 0) return (error); mtx_lock(&dev->event_lock); } out: mtx_unlock(&dev->event_lock); return (error); }