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>
This commit is contained in:
parent
5f858a61a8
commit
cdc293d589
@ -50,6 +50,11 @@ struct aim_channel {
|
|||||||
static struct list_head channel_list;
|
static struct list_head channel_list;
|
||||||
static spinlock_t ch_list_lock;
|
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)
|
static struct aim_channel *get_channel(struct most_interface *iface, int id)
|
||||||
{
|
{
|
||||||
struct aim_channel *channel, *tmp;
|
struct aim_channel *channel, *tmp;
|
||||||
@ -279,11 +284,6 @@ start_copy:
|
|||||||
return copied;
|
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)
|
static unsigned int aim_poll(struct file *filp, poll_table *wait)
|
||||||
{
|
{
|
||||||
struct aim_channel *c = filp->private_data;
|
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))
|
if (!kfifo_is_empty(&c->fifo))
|
||||||
mask |= POLLIN | POLLRDNORM;
|
mask |= POLLIN | POLLRDNORM;
|
||||||
} else {
|
} else {
|
||||||
if (!IS_ERR_OR_FALSE(channel_has_mbo(c->iface, c->channel_id)))
|
if (ch_has_mbo(c))
|
||||||
mask |= POLLOUT | POLLWRNORM;
|
mask |= POLLOUT | POLLWRNORM;
|
||||||
}
|
}
|
||||||
return mask;
|
return mask;
|
||||||
|
@ -1352,7 +1352,7 @@ most_c_obj *get_channel_by_iface(struct most_interface *iface, int id)
|
|||||||
return i->channel[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);
|
struct most_c_obj *c = get_channel_by_iface(iface, id);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@ -1361,6 +1361,11 @@ int channel_has_mbo(struct most_interface *iface, int id)
|
|||||||
if (unlikely(!c))
|
if (unlikely(!c))
|
||||||
return -EINVAL;
|
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);
|
spin_lock_irqsave(&c->fifo_lock, flags);
|
||||||
empty = list_empty(&c->fifo);
|
empty = list_empty(&c->fifo);
|
||||||
spin_unlock_irqrestore(&c->fifo_lock, flags);
|
spin_unlock_irqrestore(&c->fifo_lock, flags);
|
||||||
|
@ -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 mbo *most_get_mbo(struct most_interface *iface, int channel_idx,
|
||||||
struct most_aim *);
|
struct most_aim *);
|
||||||
void most_put_mbo(struct mbo *mbo);
|
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,
|
int most_start_channel(struct most_interface *iface, int channel_idx,
|
||||||
struct most_aim *);
|
struct most_aim *);
|
||||||
int most_stop_channel(struct most_interface *iface, int channel_idx,
|
int most_stop_channel(struct most_interface *iface, int channel_idx,
|
||||||
|
Loading…
Reference in New Issue
Block a user