Пример #1
0
static void isp_stat_buf_insert_magic(struct ispstat *stat,
				      struct ispstat_buffer *buf)
{
	const u32 buf_size = IS_H3A_AF(stat) ?
			     stat->buf_size + AF_EXTRA_DATA : stat->buf_size;

	isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);

	memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
	memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);

	isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
					   DMA_BIDIRECTIONAL);
}
Пример #2
0
static void isp_stat_buf_insert_magic(struct ispstat *stat,
				      struct ispstat_buffer *buf)
{
	const u32 buf_size = IS_H3A_AF(stat) ?
			     stat->buf_size + AF_EXTRA_DATA : stat->buf_size;

	isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);

	/*
	 * Inserting MAGIC_NUM at the beginning and end of the buffer.
	 * buf->buf_size is set only after the buffer is queued. For now the
	 * right buf_size for the current configuration is pointed by
	 * stat->buf_size.
	 */
	memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
	memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);

	isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
					   DMA_BIDIRECTIONAL);
}
Пример #3
0
static int isp_stat_buf_check_magic(struct ispstat *stat,
				    struct ispstat_buffer *buf)
{
	const u32 buf_size = IS_H3A_AF(stat) ?
			     buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
	u8 *w;
	u8 *end;
	int ret = -EINVAL;

	isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);

	/* Checking initial magic numbers. They shouldn't be here anymore. */
	for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
		if (likely(*w != MAGIC_NUM))
			ret = 0;

	if (ret) {
		dev_dbg(stat->isp->dev,
			"%s: beginning magic check does not match.\n",
			stat->subdev.name);
		return ret;
	}

	/* Checking magic numbers at the end. They must be still here. */
	for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
	     w < end; w++) {
		if (unlikely(*w != MAGIC_NUM)) {
			dev_dbg(stat->isp->dev,
				"%s: ending magic check does not match.\n",
				stat->subdev.name);
			return -EINVAL;
		}
	}

	isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
					   DMA_FROM_DEVICE);

	return 0;
}
Пример #4
0
static int isp_stat_buf_check_magic(struct ispstat *stat,
				    struct ispstat_buffer *buf)
{
	const u32 buf_size = IS_H3A_AF(stat) ?
			     buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
	u8 *w;
	u8 *end;
	int ret = -EINVAL;

	isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);

	
	for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
		if (likely(*w != MAGIC_NUM))
			ret = 0;

	if (ret) {
		dev_dbg(stat->isp->dev, "%s: beginning magic check does not "
					"match.\n", stat->subdev.name);
		return ret;
	}

	
	for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
	     w < end; w++) {
		if (unlikely(*w != MAGIC_NUM)) {
			dev_dbg(stat->isp->dev, "%s: endding magic check does "
				"not match.\n", stat->subdev.name);
			return -EINVAL;
		}
	}

	isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
					   DMA_FROM_DEVICE);

	return 0;
}
Пример #5
0
/*
 * omap3isp_stat_config - Receives new statistic engine configuration.
 * @new_conf: Pointer to config structure.
 *
 * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if
 * was unable to allocate memory for the buffer, or other errors if parameters
 * are invalid.
 */
int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
{
	int ret;
	unsigned long irqflags;
	struct ispstat_generic_config *user_cfg = new_conf;
	u32 buf_size = user_cfg->buf_size;

	if (!new_conf) {
		dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
			stat->subdev.name);
		return -EINVAL;
	}

	mutex_lock(&stat->ioctl_lock);

	dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
		"size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);

	ret = stat->ops->validate_params(stat, new_conf);
	if (ret) {
		mutex_unlock(&stat->ioctl_lock);
		dev_dbg(stat->isp->dev, "%s: configuration values are "
					"invalid.\n", stat->subdev.name);
		return ret;
	}

	if (buf_size != user_cfg->buf_size)
		dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
			"request to 0x%08lx\n", stat->subdev.name,
			(unsigned long)user_cfg->buf_size);

	/*
	 * Hack: H3A modules may need a doubled buffer size to avoid access
	 * to a invalid memory address after a SBL overflow.
	 * The buffer size is always PAGE_ALIGNED.
	 * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be
	 * inserted at the end to data integrity check purpose.
	 * Hack 3: AF module writes one paxel data more than it should, so
	 * the buffer allocation must consider it to avoid invalid memory
	 * access.
	 * Hack 4: H3A need to allocate extra space for the recover state.
	 */
	if (IS_H3A(stat)) {
		buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
		if (IS_H3A_AF(stat))
			/*
			 * Adding one extra paxel data size for each recover
			 * buffer + 2 regular ones.
			 */
			buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
		if (stat->recover_priv) {
			struct ispstat_generic_config *recover_cfg =
				stat->recover_priv;
			buf_size += recover_cfg->buf_size *
				    NUM_H3A_RECOVER_BUFS;
		}
		buf_size = PAGE_ALIGN(buf_size);
	} else { /* Histogram */
		buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
	}

	ret = isp_stat_bufs_alloc(stat, buf_size);
	if (ret) {
		mutex_unlock(&stat->ioctl_lock);
		return ret;
	}

	spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
	stat->ops->set_params(stat, new_conf);
	spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);

	/*
	 * Returning the right future config_counter for this setup, so
	 * userspace can *know* when it has been applied.
	 */
	user_cfg->config_counter = stat->config_counter + stat->inc_config;

	/* Module has a valid configuration. */
	stat->configured = 1;
	dev_dbg(stat->isp->dev, "%s: module has been successfully "
		"configured.\n", stat->subdev.name);

	mutex_unlock(&stat->ioctl_lock);

	return 0;
}
Пример #6
0
int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
{
	int ret;
	unsigned long irqflags;
	struct ispstat_generic_config *user_cfg = new_conf;
	u32 buf_size = user_cfg->buf_size;

	if (!new_conf) {
		dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
			stat->subdev.name);
		return -EINVAL;
	}

	mutex_lock(&stat->ioctl_lock);

	dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
		"size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);

	ret = stat->ops->validate_params(stat, new_conf);
	if (ret) {
		mutex_unlock(&stat->ioctl_lock);
		dev_dbg(stat->isp->dev, "%s: configuration values are "
					"invalid.\n", stat->subdev.name);
		return ret;
	}

	if (buf_size != user_cfg->buf_size)
		dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
			"request to 0x%08lx\n", stat->subdev.name,
			(unsigned long)user_cfg->buf_size);

	if (IS_H3A(stat)) {
		buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
		if (IS_H3A_AF(stat))
			buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
		if (stat->recover_priv) {
			struct ispstat_generic_config *recover_cfg =
				stat->recover_priv;
			buf_size += recover_cfg->buf_size *
				    NUM_H3A_RECOVER_BUFS;
		}
		buf_size = PAGE_ALIGN(buf_size);
	} else { 
		buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
	}

	ret = isp_stat_bufs_alloc(stat, buf_size);
	if (ret) {
		mutex_unlock(&stat->ioctl_lock);
		return ret;
	}

	spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
	stat->ops->set_params(stat, new_conf);
	spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);

	user_cfg->config_counter = stat->config_counter + stat->inc_config;

	
	stat->configured = 1;
	dev_dbg(stat->isp->dev, "%s: module has been successfully "
		"configured.\n", stat->subdev.name);

	mutex_unlock(&stat->ioctl_lock);

	return 0;
}