diff options
author | Christian Gromm <christian.gromm@microchip.com> | 2016-01-12 13:00:03 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-02-08 01:34:58 (GMT) |
commit | cdc293d58945527f36b13771822be69277c21bd6 (patch) | |
tree | bd20a7a458ccc59c0ec561c55ac0c1ee602e2d20 | |
parent | 5f858a61a8b4f5fec7b3c0618646ed6f7bfcd3a7 (diff) | |
download | linux-cdc293d58945527f36b13771822be69277c21bd6.tar.xz |
staging: most: fix retrieval of buffer availability
This patch fixes the function channel_has_mbo that delivers the false
information in case two AIMs are using the same tx channel.
Signed-off-by: Christian Gromm <christian.gromm@microchip.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/most/aim-cdev/cdev.c | 12 | ||||
-rw-r--r-- | drivers/staging/most/mostcore/core.c | 7 | ||||
-rw-r--r-- | drivers/staging/most/mostcore/mostcore.h | 3 |
3 files changed, 14 insertions, 8 deletions
diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index 533e290..c4bbf7d 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -50,6 +50,11 @@ struct aim_channel { static struct list_head channel_list; static spinlock_t ch_list_lock; +static inline bool ch_has_mbo(struct aim_channel *c) +{ + return channel_has_mbo(c->iface, c->channel_id, &cdev_aim) > 0; +} + static struct aim_channel *get_channel(struct most_interface *iface, int id) { struct aim_channel *channel, *tmp; @@ -279,11 +284,6 @@ start_copy: return copied; } -static inline bool __must_check IS_ERR_OR_FALSE(int x) -{ - return x <= 0; -} - static unsigned int aim_poll(struct file *filp, poll_table *wait) { struct aim_channel *c = filp->private_data; @@ -295,7 +295,7 @@ static unsigned int aim_poll(struct file *filp, poll_table *wait) if (!kfifo_is_empty(&c->fifo)) mask |= POLLIN | POLLRDNORM; } else { - if (!IS_ERR_OR_FALSE(channel_has_mbo(c->iface, c->channel_id))) + if (ch_has_mbo(c)) mask |= POLLOUT | POLLWRNORM; } return mask; diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c index b085f0a..09a5a1a 100644 --- a/drivers/staging/most/mostcore/core.c +++ b/drivers/staging/most/mostcore/core.c @@ -1352,7 +1352,7 @@ most_c_obj *get_channel_by_iface(struct most_interface *iface, int id) return i->channel[id]; } -int channel_has_mbo(struct most_interface *iface, int id) +int channel_has_mbo(struct most_interface *iface, int id, struct most_aim *aim) { struct most_c_obj *c = get_channel_by_iface(iface, id); unsigned long flags; @@ -1361,6 +1361,11 @@ int channel_has_mbo(struct most_interface *iface, int id) if (unlikely(!c)) return -EINVAL; + if (c->aim0.refs && c->aim1.refs && + ((aim == c->aim0.ptr && c->aim0.num_buffers <= 0) || + (aim == c->aim1.ptr && c->aim1.num_buffers <= 0))) + return 0; + spin_lock_irqsave(&c->fifo_lock, flags); empty = list_empty(&c->fifo); spin_unlock_irqrestore(&c->fifo_lock, flags); diff --git a/drivers/staging/most/mostcore/mostcore.h b/drivers/staging/most/mostcore/mostcore.h index bda3850..60e018e 100644 --- a/drivers/staging/most/mostcore/mostcore.h +++ b/drivers/staging/most/mostcore/mostcore.h @@ -310,7 +310,8 @@ int most_deregister_aim(struct most_aim *aim); struct mbo *most_get_mbo(struct most_interface *iface, int channel_idx, struct most_aim *); void most_put_mbo(struct mbo *mbo); -int channel_has_mbo(struct most_interface *iface, int channel_idx); +int channel_has_mbo(struct most_interface *iface, int channel_idx, + struct most_aim *aim); int most_start_channel(struct most_interface *iface, int channel_idx, struct most_aim *); int most_stop_channel(struct most_interface *iface, int channel_idx, |