示例#1
0
/* Called under the mutex to grab exclusive access to a drive */
static int grab_drive(struct floppy_state *fs, enum swim_state state,
		      int interruptible)
{
	unsigned long flags;

	swim3_dbg("%s", "-> grab drive\n");

	spin_lock_irqsave(&swim3_lock, flags);
	if (fs->state != idle && fs->state != available) {
		++fs->wanted;
		/* this will enable irqs in order to sleep */
		if (!interruptible)
			wait_event_lock_irq(fs->wait,
                                        fs->state == available,
                                        swim3_lock);
		else if (wait_event_interruptible_lock_irq(fs->wait,
					fs->state == available,
					swim3_lock)) {
			--fs->wanted;
			spin_unlock_irqrestore(&swim3_lock, flags);
			return -EINTR;
		}
		--fs->wanted;
	}
	fs->state = state;
	spin_unlock_irqrestore(&swim3_lock, flags);

	return 0;
}
示例#2
0
static ssize_t crtc_crc_read(struct file *filep, char __user *user_buf,
			     size_t count, loff_t *pos)
{
	struct drm_crtc *crtc = filep->f_inode->i_private;
	struct drm_crtc_crc *crc = &crtc->crc;
	struct drm_crtc_crc_entry *entry;
	char buf[MAX_LINE_LEN];
	int ret, i;

	spin_lock_irq(&crc->lock);

	if (!crc->source) {
		spin_unlock_irq(&crc->lock);
		return 0;
	}

	/* Nothing to read? */
	while (crtc_crc_data_count(crc) == 0) {
		if (filep->f_flags & O_NONBLOCK) {
			spin_unlock_irq(&crc->lock);
			return -EAGAIN;
		}

		ret = wait_event_interruptible_lock_irq(crc->wq,
							crtc_crc_data_count(crc),
							crc->lock);
		if (ret) {
			spin_unlock_irq(&crc->lock);
			return ret;
		}
	}

	/* We know we have an entry to be read */
	entry = &crc->entries[crc->tail];

	if (count < LINE_LEN(crc->values_cnt)) {
		spin_unlock_irq(&crc->lock);
		return -EINVAL;
	}

	BUILD_BUG_ON_NOT_POWER_OF_2(DRM_CRC_ENTRIES_NR);
	crc->tail = (crc->tail + 1) & (DRM_CRC_ENTRIES_NR - 1);

	spin_unlock_irq(&crc->lock);

	if (entry->has_frame_counter)
		sprintf(buf, "0x%08x", entry->frame);
	else
		sprintf(buf, "XXXXXXXXXX");

	for (i = 0; i < crc->values_cnt; i++)
		sprintf(buf + 10 + i * 11, " 0x%08x", entry->crcs[i]);
	sprintf(buf + 10 + crc->values_cnt * 11, "\n");

	if (copy_to_user(user_buf, buf, LINE_LEN(crc->values_cnt)))
		return -EFAULT;

	return LINE_LEN(crc->values_cnt);
}
示例#3
0
static ssize_t
i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
		   loff_t *pos)
{
	struct pipe_crc_info *info = filep->private_data;
	struct drm_i915_private *dev_priv = info->dev_priv;
	struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
	char buf[PIPE_CRC_BUFFER_LEN];
	int n_entries;
	ssize_t bytes_read;

	/*
	 * Don't allow user space to provide buffers not big enough to hold
	 * a line of data.
	 */
	if (count < PIPE_CRC_LINE_LEN)
		return -EINVAL;

	if (pipe_crc->source == INTEL_PIPE_CRC_SOURCE_NONE)
		return 0;

	/* nothing to read */
	spin_lock_irq(&pipe_crc->lock);
	while (pipe_crc_data_count(pipe_crc) == 0) {
		int ret;

		if (filep->f_flags & O_NONBLOCK) {
			spin_unlock_irq(&pipe_crc->lock);
			return -EAGAIN;
		}

		ret = wait_event_interruptible_lock_irq(pipe_crc->wq,
				pipe_crc_data_count(pipe_crc), pipe_crc->lock);
		if (ret) {
			spin_unlock_irq(&pipe_crc->lock);
			return ret;
		}
	}

	/* We now have one or more entries to read */
	n_entries = count / PIPE_CRC_LINE_LEN;

	bytes_read = 0;
	while (n_entries > 0) {
		struct intel_pipe_crc_entry *entry =
			&pipe_crc->entries[pipe_crc->tail];

		if (CIRC_CNT(pipe_crc->head, pipe_crc->tail,
			     INTEL_PIPE_CRC_ENTRIES_NR) < 1)
			break;

		BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
		pipe_crc->tail = (pipe_crc->tail + 1) &
				 (INTEL_PIPE_CRC_ENTRIES_NR - 1);

		bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN,
				       "%8u %8x %8x %8x %8x %8x\n",
				       entry->frame, entry->crc[0],
				       entry->crc[1], entry->crc[2],
				       entry->crc[3], entry->crc[4]);

		spin_unlock_irq(&pipe_crc->lock);

		if (copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN))
			return -EFAULT;

		user_buf += PIPE_CRC_LINE_LEN;
		n_entries--;

		spin_lock_irq(&pipe_crc->lock);
	}

	spin_unlock_irq(&pipe_crc->lock);

	return bytes_read;
}
示例#4
0
static int crtc_crc_open(struct inode *inode, struct file *filep)
{
	struct drm_crtc *crtc = inode->i_private;
	struct drm_crtc_crc *crc = &crtc->crc;
	struct drm_crtc_crc_entry *entries = NULL;
	size_t values_cnt;
	int ret = 0;

	if (drm_drv_uses_atomic_modeset(crtc->dev)) {
		ret = drm_modeset_lock_single_interruptible(&crtc->mutex);
		if (ret)
			return ret;

		if (!crtc->state->active)
			ret = -EIO;
		drm_modeset_unlock(&crtc->mutex);

		if (ret)
			return ret;
	}

	spin_lock_irq(&crc->lock);
	if (!crc->opened)
		crc->opened = true;
	else
		ret = -EBUSY;
	spin_unlock_irq(&crc->lock);

	if (ret)
		return ret;

	ret = crtc->funcs->set_crc_source(crtc, crc->source, &values_cnt);
	if (ret)
		goto err;

	if (WARN_ON(values_cnt > DRM_MAX_CRC_NR)) {
		ret = -EINVAL;
		goto err_disable;
	}

	if (WARN_ON(values_cnt == 0)) {
		ret = -EINVAL;
		goto err_disable;
	}

	entries = kcalloc(DRM_CRC_ENTRIES_NR, sizeof(*entries), GFP_KERNEL);
	if (!entries) {
		ret = -ENOMEM;
		goto err_disable;
	}

	spin_lock_irq(&crc->lock);
	crc->entries = entries;
	crc->values_cnt = values_cnt;

	/*
	 * Only return once we got a first frame, so userspace doesn't have to
	 * guess when this particular piece of HW will be ready to start
	 * generating CRCs.
	 */
	ret = wait_event_interruptible_lock_irq(crc->wq,
						crtc_crc_data_count(crc),
						crc->lock);
	spin_unlock_irq(&crc->lock);

	if (ret)
		goto err_disable;

	return 0;

err_disable:
	crtc->funcs->set_crc_source(crtc, NULL, &values_cnt);
err:
	spin_lock_irq(&crc->lock);
	crtc_crc_cleanup(crc);
	spin_unlock_irq(&crc->lock);
	return ret;
}