From aebaf60c074d36d2e764cae9337b33e137a9b335 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Sat, 28 Nov 2015 21:18:22 +0100 Subject: [PATCH] facetimehd: change fthd_channel_ringbuf_send() error handling In the current implementation it returns -1 on error, an offset value otherwise. Change it to return a negative error value, and add a pointer to an u32 for receiving the entry offset as an extra argument. This makes the ugly (u32)-1 return code comparision obsolete, and we can return a more detailed error code like EAGAIN if all ringbuffer slots are busy. --- fthd_drv.c | 29 ++++++++++++++++++++++------- fthd_isp.c | 6 ++++-- fthd_ringbuf.c | 15 +++++++++++---- fthd_ringbuf.h | 4 ++-- fthd_v4l2.c | 11 ++++++----- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/fthd_drv.c b/fthd_drv.c index 0acf8cd..510ed33 100644 --- a/fthd_drv.c +++ b/fthd_drv.c @@ -104,6 +104,7 @@ static void sharedmalloc_handler(struct fthd_private *dev_priv, { u32 request_size, response_size, address; struct isp_mem_obj *obj; + int ret; request_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_REQUEST_SIZE); response_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_RESPONSE_SIZE); @@ -114,7 +115,9 @@ static void sharedmalloc_handler(struct fthd_private *dev_priv, FTHD_S2_MEMCPY_FROMIO(&obj, address - 64, sizeof(obj)); isp_mem_destroy(obj); - fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0); + ret = fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0, NULL); + if (ret) + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); } else { if (!request_size) return; @@ -126,7 +129,10 @@ static void sharedmalloc_handler(struct fthd_private *dev_priv, response_size >> 24,response_size >> 16, response_size >> 8, response_size); FTHD_S2_MEMCPY_TOIO(obj->offset, &obj, sizeof(obj)); - fthd_channel_ringbuf_send(dev_priv, chan, obj->offset + 64, 0, 0); + ret = fthd_channel_ringbuf_send(dev_priv, chan, obj->offset + 64, 0, 0, NULL); + if (ret) + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); + } } @@ -157,7 +163,7 @@ static void buf_t2h_handler(struct fthd_private *dev_priv, u32 entry) { u32 request_size, response_size, address; - + int ret; request_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_REQUEST_SIZE); response_size = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_RESPONSE_SIZE); address = FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS); @@ -167,15 +173,21 @@ static void buf_t2h_handler(struct fthd_private *dev_priv, fthd_buffer_return_handler(dev_priv, address & ~3, request_size); - fthd_channel_ringbuf_send(dev_priv, chan, (response_size & 0x10000000) ? address : 0, - 0, 0x80000000); + ret = fthd_channel_ringbuf_send(dev_priv, chan, (response_size & 0x10000000) ? address : 0, + 0, 0x80000000, NULL); + if (ret) + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); + } static void io_t2h_handler(struct fthd_private *dev_priv, struct fw_channel *chan, u32 entry) { - fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0); + int ret = fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0, NULL); + if (ret) + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); + } static void buf_h2t_handler(struct fthd_private *dev_priv, @@ -188,6 +200,7 @@ static void buf_h2t_handler(struct fthd_private *dev_priv, static void fthd_handle_irq(struct fthd_private *dev_priv, struct fw_channel *chan) { u32 entry; + int ret; while((entry = fthd_channel_ringbuf_receive(dev_priv, chan)) != (u32)-1) { pr_debug("channel %s: message available, address %08x\n", chan->name, FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS)); @@ -195,7 +208,9 @@ static void fthd_handle_irq(struct fthd_private *dev_priv, struct fw_channel *ch sharedmalloc_handler(dev_priv, chan, entry); } else if (chan == dev_priv->channel_terminal) { terminal_handler(dev_priv, chan, entry); - fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0); + ret = fthd_channel_ringbuf_send(dev_priv, chan, 0, 0, 0, NULL); + if (ret) + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); } else if (chan == dev_priv->channel_buf_t2h) { buf_t2h_handler(dev_priv, chan, entry); } else if (chan == dev_priv->channel_io) { diff --git a/fthd_isp.c b/fthd_isp.c index 6b0ff32..fece39e 100644 --- a/fthd_isp.c +++ b/fthd_isp.c @@ -296,8 +296,10 @@ static int fthd_isp_cmd(struct fthd_private *dev_priv, enum fthd_isp_cmds comman if (request_len) FTHD_S2_MEMCPY_TOIO(request->offset + sizeof(struct isp_cmd_hdr), buf, request_len); - entry = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_io, - request->offset, request_len + 8, (response_len ? *response_len : 0) + 8); + ret = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_io, + request->offset, request_len + 8, (response_len ? *response_len : 0) + 8, &entry); + if (ret) + goto out; if (entry == (u32)-1) { ret = -EIO; diff --git a/fthd_ringbuf.c b/fthd_ringbuf.c index 5617041..f77de0c 100644 --- a/fthd_ringbuf.c +++ b/fthd_ringbuf.c @@ -76,8 +76,8 @@ void fthd_channel_ringbuf_init(struct fthd_private *dev_priv, struct fw_channel } } -u32 fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *chan, - u32 data_offset, u32 request_size, u32 response_size) +int fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *chan, + u32 data_offset, u32 request_size, u32 response_size, u32 *entryp) { u32 entry; @@ -88,12 +88,17 @@ u32 fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel * if (chan->tx_lock) { spin_unlock_irq(&chan->lock); - return (u32)-1; + return -EBUSY; } if (chan->type != FW_CHAN_TYPE_OUT && ++chan->ringbuf.idx >= chan->size) chan->ringbuf.idx = 0; + if (!(FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS) & 1) ^ (chan->type != 0)) { + spin_unlock_irq(&chan->lock); + return -EAGAIN; + } + chan->tx_lock = 1; chan->rx_lock = 0; @@ -107,7 +112,9 @@ u32 fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel * spin_lock_irq(&dev_priv->io_lock); FTHD_ISP_REG_WRITE(0x10 << chan->source, ISP_REG_41020); spin_unlock_irq(&dev_priv->io_lock); - return entry; + if (entryp) + *entryp = entry; + return 0; } u32 fthd_channel_ringbuf_receive(struct fthd_private *dev_priv, diff --git a/fthd_ringbuf.h b/fthd_ringbuf.h index 06783fa..ffe0625 100644 --- a/fthd_ringbuf.h +++ b/fthd_ringbuf.h @@ -42,8 +42,8 @@ struct fthd_private; extern void fthd_channel_ringbuf_dump(struct fthd_private *dev_priv, struct fw_channel *chan); extern void fthd_channel_ringbuf_init(struct fthd_private *dev_priv, struct fw_channel *chan); extern u32 fthd_channel_ringbuf_get_entry(struct fthd_private *, struct fw_channel *); -extern u32 fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *chan, - u32 data_offset, u32 request_size, u32 response_size); +extern int fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *chan, + u32 data_offset, u32 request_size, u32 response_size, u32 *entry); extern u32 fthd_channel_ringbuf_receive(struct fthd_private *dev_priv, struct fw_channel *chan); diff --git a/fthd_v4l2.c b/fthd_v4l2.c index 4c5077a..5050a1d 100644 --- a/fthd_v4l2.c +++ b/fthd_v4l2.c @@ -126,15 +126,16 @@ static void fthd_buffer_cleanup(struct vb2_buffer *vb) static int fthd_send_h2t_buffer(struct fthd_private *dev_priv, struct h2t_buf_ctx *ctx) { u32 entry; + int ret; pr_debug("sending buffer %p size %ld, ctx %p\n", ctx->vb, sizeof(ctx->dma_desc_list), ctx); FTHD_S2_MEMCPY_TOIO(ctx->dma_desc_obj->offset, &ctx->dma_desc_list, sizeof(ctx->dma_desc_list)); - entry = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_buf_h2t, - ctx->dma_desc_obj->offset, 0x180, 0x30000000); + ret = fthd_channel_ringbuf_send(dev_priv, dev_priv->channel_buf_h2t, + ctx->dma_desc_obj->offset, 0x180, 0x30000000, &entry); - if (entry == (u32)-1) { - pr_debug("send failed\n"); - return -EIO; + if (ret) { + pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret); + return ret; } if (wait_event_interruptible_timeout(ctx->wq, ctx->done, HZ) <= 0) {