Exemple #1
0
static int isp_fill_channel_info(struct fthd_private *dev_priv, int offset, int num_channels)
{
	struct isp_channel_info info;
	struct fw_channel *chan;
	int i;

	if (!num_channels)
		return -EINVAL;

	dev_priv->channels = kzalloc(num_channels * sizeof(struct fw_channel *), GFP_KERNEL);
	if (!dev_priv->channels)
		goto out;

	dev_priv->num_channels = num_channels;

	for(i = 0; i < num_channels; i++) {
		FTHD_S2_MEMCPY_FROMIO(&info, offset + i * 256, sizeof(info));

		chan = kzalloc(sizeof(struct fw_channel), GFP_KERNEL);
		if (!chan)
			goto out;

		dev_priv->channels[i] = chan;

		pr_debug("Channel %d: %s, type %d, source %d, size %d, offset %x\n",
			 i, info.name, info.type, info.source, info.size, info.offset);

		chan->name = kstrdup(info.name, GFP_KERNEL);
		if (!chan->name)
			goto out;

		chan->type = info.type;
		chan->source = info.source;
		chan->size = info.size;
		chan->offset = info.offset;
		spin_lock_init(&chan->lock);
		init_waitqueue_head(&chan->wq);
	}

	dev_priv->channel_terminal = isp_get_chan_index(dev_priv, "TERMINAL");
	dev_priv->channel_debug = isp_get_chan_index(dev_priv, "DEBUG");
	dev_priv->channel_shared_malloc = isp_get_chan_index(dev_priv, "SHAREDMALLOC");
	dev_priv->channel_io = isp_get_chan_index(dev_priv, "IO");
	dev_priv->channel_buf_h2t = isp_get_chan_index(dev_priv, "BUF_H2T");
	dev_priv->channel_buf_t2h = isp_get_chan_index(dev_priv, "BUF_T2H");
	dev_priv->channel_io_t2h = isp_get_chan_index(dev_priv, "IO_T2H");

	if (!dev_priv->channel_terminal || !dev_priv->channel_debug
	    || !dev_priv->channel_shared_malloc || !dev_priv->channel_io
	    || !dev_priv->channel_buf_h2t || !dev_priv->channel_buf_t2h
	    || !dev_priv->channel_io_t2h) {
		dev_err(&dev_priv->pdev->dev, "did not find all of the required channels\n");
		goto out;
	}
	return 0;
out:
	isp_free_channel_info(dev_priv);
	return -ENOMEM;
}
Exemple #2
0
void fthd_buffer_return_handler(struct fthd_private *dev_priv, u32 offset, int size)
{
	struct dma_descriptor_list list;
	struct h2t_buf_ctx *ctx;
	int i;

	FTHD_S2_MEMCPY_FROMIO(&list, offset, sizeof(list));

	for(i = 0; i < list.count; i++) {
		ctx = (struct h2t_buf_ctx *)list.desc[i].tag;
		pr_debug("%d: field0: %d, count %d, pool %d, addr0 0x%08x, addr1 0x%08x tag 0x%08llx vb = %p, ctx = %p\n", i, list.field0,
			 list.desc[i].count, list.desc[i].pool, list.desc[i].addr0, list.desc[i].addr1, list.desc[i].tag, ctx->vb, ctx);

		if (ctx->state == BUF_HW_QUEUED || ctx->state == BUF_DRV_QUEUED) {
			ctx->state = BUF_ALLOC;
			vb2_buffer_done(ctx->vb, VB2_BUF_STATE_DONE);
		}

	}
}
Exemple #3
0
int fthd_isp_debug_cmd(struct fthd_private *dev_priv, enum fthd_isp_cmds command, void *buf,
			int request_len, int *response_len)
{
	struct isp_mem_obj *request;
	struct isp_cmd_hdr cmd;
	u32 address, request_size, response_size;
	u32 entry;
	int len, ret;

	memset(&cmd, 0, sizeof(cmd));

	if (response_len) {
		len = max(request_len, *response_len);
	} else {
		len = request_len;
	}
	len += sizeof(struct isp_cmd_hdr);

	pr_debug("sending debug cmd %d to firmware\n", command);

	request = isp_mem_create(dev_priv, FTHD_MEM_CMD, len);
	if (!request) {
		dev_err(&dev_priv->pdev->dev, "failed to allocate cmd memory object\n");
		return -ENOMEM;
	}

	cmd.opcode = command;

	FTHD_S2_MEMCPY_TOIO(request->offset, &cmd, sizeof(struct isp_cmd_hdr));
	if (request_len)
		FTHD_S2_MEMCPY_TOIO(request->offset + sizeof(struct isp_cmd_hdr), buf, request_len);

	ret = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_debug,
					  request->offset, request_len + 8, (response_len ? *response_len : 0) + 8, &entry);
	if (ret)
		goto out;

	if (entry == (u32)-1) {
		ret = -EIO;
		goto out;
	}

        ret = fthd_channel_wait_ready(dev_priv, dev_priv->channel_debug, entry, 20000);
	if (ret) {
		if (response_len)
			*response_len = 0;
		goto out;
	}

	FTHD_S2_MEMCPY_FROMIO(&cmd, request->offset, sizeof(struct isp_cmd_hdr));
	address = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS);
	request_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_REQUEST_SIZE);
	response_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_RESPONSE_SIZE);

	/* XXX: response size in the ringbuf is zero after command completion, how is buffer size
	        verification done? */
	if (response_len && *response_len)
		FTHD_S2_MEMCPY_FROMIO(buf, (address & ~3) + sizeof(struct isp_cmd_hdr),
				     *response_len);

	pr_info("status %04x, request_len %d response len %d address_flags %x\n", cmd.status,
		request_size, response_size, address);

	ret = 0;
out:
	isp_mem_destroy(request);
	return ret;
}