Пример #1
0
/*
 * Read a single request into the userspace filesystem's buffer.  This
 * function waits until a request is available, then removes it from
 * the pending list and copies request data to userspace buffer.  If
 * no reply is needed (FORGET) or request has been aborted or there
 * was an error during the copying then it's finished by calling
 * request_end().  Otherwise add it to the processing list, and set
 * the 'sent' flag.
 */
static ssize_t fuse_dev_readv(struct file *file, const struct iovec *iov,
			      unsigned long nr_segs, loff_t *off)
{
	int err;
	struct fuse_req *req;
	struct fuse_in *in;
	struct fuse_copy_state cs;
	unsigned reqsize;
	struct fuse_conn *fc = fuse_get_conn(file);
	if (!fc)
		return -EPERM;

 restart:
	spin_lock(&fc->lock);
	err = -EAGAIN;
	if ((file->f_flags & O_NONBLOCK) && fc->connected &&
	    !request_pending(fc))
		goto err_unlock;

	request_wait(fc);
	err = -ENODEV;
	if (!fc->connected)
		goto err_unlock;
	err = -ERESTARTSYS;
	if (!request_pending(fc))
		goto err_unlock;

	if (!list_empty(&fc->interrupts)) {
		req = list_entry(fc->interrupts.next, struct fuse_req,
				 intr_entry);
		return fuse_read_interrupt(fc, req, iov, nr_segs);
	}
Пример #2
0
static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
		struct drm_file *file_priv, uint32_t handle,
		uint32_t width, uint32_t height)
{
	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
	struct mdp4_kms *mdp4_kms = get_kms(crtc);
	struct drm_device *dev = crtc->dev;
	struct drm_gem_object *cursor_bo, *old_bo;
	unsigned long flags;
	uint32_t iova;
	int ret;

	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
		dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
		return -EINVAL;
	}

	if (handle) {
		cursor_bo = drm_gem_object_lookup(dev, file_priv, handle);
		if (!cursor_bo)
			return -ENOENT;
	} else {
		cursor_bo = NULL;
	}

	if (cursor_bo) {
		ret = msm_gem_get_iova(cursor_bo, mdp4_kms->id, &iova);
		if (ret)
			goto fail;
	} else {
		iova = 0;
	}

	spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
	old_bo = mdp4_crtc->cursor.next_bo;
	mdp4_crtc->cursor.next_bo   = cursor_bo;
	mdp4_crtc->cursor.next_iova = iova;
	mdp4_crtc->cursor.width     = width;
	mdp4_crtc->cursor.height    = height;
	mdp4_crtc->cursor.stale     = true;
	spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);

	if (old_bo) {
		/* drop our previous reference: */
		msm_gem_put_iova(old_bo, mdp4_kms->id);
		drm_gem_object_unreference_unlocked(old_bo);
	}

	request_pending(crtc, PENDING_CURSOR);

	return 0;

fail:
	drm_gem_object_unreference_unlocked(cursor_bo);
	return ret;
}
Пример #3
0
static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
{
	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
	unsigned long flags;

	spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
	mdp4_crtc->cursor.x = x;
	mdp4_crtc->cursor.y = y;
	spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);

	crtc_flush(crtc);
	request_pending(crtc, PENDING_CURSOR);

	return 0;
}
Пример #4
0
static void pageflip_cb(struct msm_fence_cb *cb)
{
	struct mdp4_crtc *mdp4_crtc =
		container_of(cb, struct mdp4_crtc, pageflip_cb);
	struct drm_crtc *crtc = &mdp4_crtc->base;
	struct drm_framebuffer *fb = crtc->fb;

	if (!fb)
		return;

	mdp4_plane_set_scanout(mdp4_crtc->plane, fb);
	crtc_flush(crtc);

	/* enable vblank to complete flip: */
	request_pending(crtc, PENDING_FLIP);
}
Пример #5
0
/* Wait until a request is available on the pending list */
static void request_wait(struct fuse_conn *fc)
{
	DECLARE_WAITQUEUE(wait, current);

	add_wait_queue_exclusive(&fc->waitq, &wait);
	while (fc->connected && !request_pending(fc)) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (signal_pending(current))
			break;

		spin_unlock(&fc->lock);
		schedule();
		spin_lock(&fc->lock);
	}
	set_current_state(TASK_RUNNING);
	remove_wait_queue(&fc->waitq, &wait);
}
Пример #6
0
/* unlike update_fb(), take a ref to the new scanout fb *before* updating
 * plane, then call this.  Needed to ensure we don't unref the buffer that
 * is actually still being scanned out.
 *
 * Note that this whole thing goes away with atomic.. since we can defer
 * calling into driver until rendering is done.
 */
static void update_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
{
	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);

	/* flush updates, to make sure hw is updated to new scanout fb,
	 * so that we can safely queue unref to current fb (ie. next
	 * vblank we know hw is done w/ previous scanout_fb).
	 */
	crtc_flush(crtc);

	if (mdp4_crtc->scanout_fb)
		drm_flip_work_queue(&mdp4_crtc->unref_fb_work,
				mdp4_crtc->scanout_fb);

	mdp4_crtc->scanout_fb = fb;

	/* enable vblank to complete flip: */
	request_pending(crtc, PENDING_FLIP);
}