mirror of
https://github.com/patjak/facetimehd.git
synced 2026-04-09 19:10:01 +02:00
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.
This commit is contained in:
29
fthd_drv.c
29
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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
11
fthd_v4l2.c
11
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) {
|
||||
|
||||
Reference in New Issue
Block a user