mirror of
https://github.com/patjak/facetimehd.git
synced 2026-04-09 11:02:31 +02:00
facetimehd: add channel waitqueue
add a per channel waitqueue to be able to have more than one ringbuffer entry in flight. Signed-off-by: Sven Schnelle <svens@stackframe.org>
This commit is contained in:
27
fthd_drv.c
27
fthd_drv.c
@@ -190,18 +190,26 @@ static void io_t2h_handler(struct fthd_private *dev_priv,
|
||||
|
||||
}
|
||||
|
||||
static void buf_h2t_handler(struct fthd_private *dev_priv,
|
||||
struct fw_channel *chan,
|
||||
u32 entry)
|
||||
{
|
||||
fthd_buffer_queued_handler(dev_priv, FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS) & ~3);
|
||||
}
|
||||
|
||||
static void fthd_handle_irq(struct fthd_private *dev_priv, struct fw_channel *chan)
|
||||
{
|
||||
u32 entry;
|
||||
int ret;
|
||||
|
||||
if (chan == dev_priv->channel_io) {
|
||||
pr_debug("IO channel ready\n");
|
||||
wake_up_interruptible(&chan->wq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan == dev_priv->channel_buf_h2t) {
|
||||
pr_debug("H2T channel ready\n");
|
||||
wake_up_interruptible(&chan->wq);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan == dev_priv->channel_debug)
|
||||
return;
|
||||
|
||||
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));
|
||||
if (chan == dev_priv->channel_shared_malloc) {
|
||||
@@ -213,12 +221,8 @@ static void fthd_handle_irq(struct fthd_private *dev_priv, struct fw_channel *ch
|
||||
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) {
|
||||
wake_up_interruptible(&dev_priv->cmd_wq);
|
||||
} else if (chan == dev_priv->channel_io_t2h) {
|
||||
io_t2h_handler(dev_priv, chan, entry);
|
||||
} else if (chan == dev_priv->channel_buf_h2t) {
|
||||
buf_h2t_handler(dev_priv, chan, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -456,7 +460,6 @@ static int fthd_pci_probe(struct pci_dev *pdev,
|
||||
mutex_init(&dev_priv->vb2_queue_lock);
|
||||
|
||||
mutex_init(&dev_priv->ioctl_lock);
|
||||
init_waitqueue_head(&dev_priv->cmd_wq);
|
||||
INIT_LIST_HEAD(&dev_priv->buffer_queue);
|
||||
INIT_WORK(&dev_priv->irq_work, fthd_irq_work);
|
||||
|
||||
|
||||
@@ -56,11 +56,10 @@ struct fw_channel {
|
||||
u32 size;
|
||||
u32 source;
|
||||
u32 type;
|
||||
int tx_lock;
|
||||
int rx_lock;
|
||||
struct fthd_ringbuf ringbuf;
|
||||
spinlock_t lock;
|
||||
|
||||
/* waitqueue for signaling completion */
|
||||
wait_queue_head_t wq;
|
||||
char *name;
|
||||
};
|
||||
|
||||
@@ -75,9 +74,6 @@ struct fthd_private {
|
||||
/* lock for synchronizing with irq/workqueue */
|
||||
spinlock_t io_lock;
|
||||
|
||||
/* waitqueue for signaling command completion */
|
||||
wait_queue_head_t cmd_wq;
|
||||
|
||||
/* Mapped PCI resources */
|
||||
void __iomem *s2_io;
|
||||
u32 s2_io_len;
|
||||
|
||||
12
fthd_isp.c
12
fthd_isp.c
@@ -236,11 +236,8 @@ static int isp_fill_channel_info(struct fthd_private *dev_priv, int offset, int
|
||||
chan->source = info.source;
|
||||
chan->size = info.size;
|
||||
chan->offset = info.offset;
|
||||
if (chan->type == FW_CHAN_TYPE_OUT)
|
||||
chan->rx_lock = 1;
|
||||
if (chan->type == FW_CHAN_TYPE_IN)
|
||||
chan->tx_lock = 1;
|
||||
spin_lock_init(&chan->lock);
|
||||
init_waitqueue_head(&chan->wq);
|
||||
}
|
||||
|
||||
dev_priv->channel_terminal = isp_get_chan_index(dev_priv, "TERMINAL");
|
||||
@@ -312,13 +309,10 @@ static int fthd_isp_cmd(struct fthd_private *dev_priv, enum fthd_isp_cmds comman
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (wait_event_interruptible_timeout(dev_priv->cmd_wq,
|
||||
FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS) & 1, HZ) <= 0) {
|
||||
dev_err(&dev_priv->pdev->dev, "timeout wait for command %d\n", cmd.opcode);
|
||||
fthd_channel_ringbuf_dump(dev_priv, dev_priv->channel_io);
|
||||
ret = fthd_channel_wait_ready(dev_priv, dev_priv->channel_io, entry, 2000);
|
||||
if (ret) {
|
||||
if (response_len)
|
||||
*response_len = 0;
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,7 @@ int fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *
|
||||
spin_lock_irq(&chan->lock);
|
||||
entry = get_entry_addr(dev_priv, chan, chan->ringbuf.idx);
|
||||
|
||||
if (chan->tx_lock) {
|
||||
spin_unlock_irq(&chan->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
if (chan->type != FW_CHAN_TYPE_OUT && ++chan->ringbuf.idx >= chan->size)
|
||||
if (++chan->ringbuf.idx >= chan->size)
|
||||
chan->ringbuf.idx = 0;
|
||||
|
||||
if (!(FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS) & 1) ^ (chan->type != 0)) {
|
||||
@@ -99,9 +94,6 @@ int fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_channel *
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
chan->tx_lock = 1;
|
||||
chan->rx_lock = 0;
|
||||
|
||||
FTHD_S2_MEM_WRITE(request_size, entry + FTHD_RINGBUF_REQUEST_SIZE);
|
||||
FTHD_S2_MEM_WRITE(response_size, entry + FTHD_RINGBUF_RESPONSE_SIZE);
|
||||
wmb();
|
||||
@@ -123,8 +115,6 @@ u32 fthd_channel_ringbuf_receive(struct fthd_private *dev_priv,
|
||||
u32 entry, ret = (u32)-1;
|
||||
|
||||
spin_lock_irq(&chan->lock);
|
||||
if (chan->rx_lock)
|
||||
goto out;
|
||||
|
||||
entry = get_entry_addr(dev_priv, chan, chan->ringbuf.idx);
|
||||
|
||||
@@ -137,9 +127,19 @@ u32 fthd_channel_ringbuf_receive(struct fthd_private *dev_priv,
|
||||
if (chan->type == FW_CHAN_TYPE_OUT && ++chan->ringbuf.idx >= chan->size)
|
||||
chan->ringbuf.idx = 0;
|
||||
|
||||
chan->rx_lock = 1;
|
||||
chan->tx_lock = 0;
|
||||
out:
|
||||
spin_unlock_irq(&chan->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fthd_channel_wait_ready(struct fthd_private *dev_priv, struct fw_channel *chan, u32 entry, int timeout)
|
||||
{
|
||||
if (wait_event_interruptible_timeout(chan->wq,
|
||||
(FTHD_S2_MEM_READ(entry + FTHD_RINGBUF_ADDRESS_FLAGS) & 1) ^ (chan->type != 0),
|
||||
msecs_to_jiffies(timeout)) <= 0) {
|
||||
dev_err(&dev_priv->pdev->dev, "%s: timeout\n", chan->name);
|
||||
fthd_channel_ringbuf_dump(dev_priv, chan);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -48,4 +48,5 @@ extern int fthd_channel_ringbuf_send(struct fthd_private *dev_priv, struct fw_ch
|
||||
extern u32 fthd_channel_ringbuf_receive(struct fthd_private *dev_priv,
|
||||
struct fw_channel *chan);
|
||||
|
||||
extern int fthd_channel_wait_ready(struct fthd_private *dev_priv, struct fw_channel *chan, u32 entry, int timeout);
|
||||
#endif
|
||||
|
||||
24
fthd_v4l2.c
24
fthd_v4l2.c
@@ -137,29 +137,7 @@ static int fthd_send_h2t_buffer(struct fthd_private *dev_priv, struct h2t_buf_ct
|
||||
pr_err("%s: fthd_channel_ringbuf_send: %d\n", __FUNCTION__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (wait_event_interruptible_timeout(ctx->wq, ctx->done, HZ) <= 0) {
|
||||
dev_err(&dev_priv->pdev->dev, "timeout wait for buffer %p\n", ctx->vb);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
ctx->done = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fthd_buffer_queued_handler(struct fthd_private *dev_priv, u32 offset)
|
||||
{
|
||||
|
||||
struct dma_descriptor_list list;
|
||||
struct h2t_buf_ctx *ctx;
|
||||
|
||||
|
||||
FTHD_S2_MEMCPY_FROMIO(&list, offset, sizeof(list));
|
||||
|
||||
ctx = (struct h2t_buf_ctx *)list.desc[0].tag;
|
||||
pr_debug("vb %p, ctx = %p\n", ctx->vb, ctx);
|
||||
memcpy(&ctx->dma_desc_list, &list, sizeof(ctx->dma_desc_list));
|
||||
ctx->done = 1;
|
||||
wake_up_interruptible(&ctx->wq);
|
||||
return fthd_channel_wait_ready(dev_priv, dev_priv->channel_buf_h2t, entry, 2000);
|
||||
}
|
||||
|
||||
static void fthd_buffer_queue(struct vb2_buffer *vb)
|
||||
|
||||
Reference in New Issue
Block a user