summaryrefslogtreecommitdiff
path: root/drivers/staging/unisys
diff options
context:
space:
mode:
authorNeil Horman <nhorman@redhat.com>2015-08-01 01:56:32 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-08-04 03:45:02 +0300
commitfdc792cd1b5c86cb34770707aa1b04edce5288cf (patch)
tree4a47e45329aa668ed914812fbfa7a15b9f20d011 /drivers/staging/unisys
parentfd93b8059294146a1c3dc9cf6b5616c22b7b47f7 (diff)
downloadlinux-fdc792cd1b5c86cb34770707aa1b04edce5288cf.tar.xz
staging: unisys: visorchannel: Add peek function
According to unisys, the s_par hypervisor has a bug in which it never triggers an interrupt. That makes the visornic effectively a 2ms poll loop. In order to just have the rx thread shceduling a napi poll every 2ms, lets instead give it the chance to check the response queue for data before we schedule. This helper provides that functionality Signed-off-by: Neil Horman <nhorman@redhat.com> Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/unisys')
-rw-r--r--drivers/staging/unisys/include/visorbus.h2
-rw-r--r--drivers/staging/unisys/visorbus/visorchannel.c21
2 files changed, 23 insertions, 0 deletions
diff --git a/drivers/staging/unisys/include/visorbus.h b/drivers/staging/unisys/include/visorbus.h
index a0144c6a8ad1..9235536fa75f 100644
--- a/drivers/staging/unisys/include/visorbus.h
+++ b/drivers/staging/unisys/include/visorbus.h
@@ -201,6 +201,8 @@ bool visorchannel_signalremove(struct visorchannel *channel, u32 queue,
void *msg);
bool visorchannel_signalinsert(struct visorchannel *channel, u32 queue,
void *msg);
+bool visorchannel_signalempty(struct visorchannel *channel, u32 queue);
+
int visorchannel_signalqueue_slots_avail(struct visorchannel *channel,
u32 queue);
int visorchannel_signalqueue_max_slots(struct visorchannel *channel, u32 queue);
diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c
index 242246492b7a..6da7e49a6627 100644
--- a/drivers/staging/unisys/visorbus/visorchannel.c
+++ b/drivers/staging/unisys/visorbus/visorchannel.c
@@ -430,6 +430,27 @@ visorchannel_signalremove(struct visorchannel *channel, u32 queue, void *msg)
}
EXPORT_SYMBOL_GPL(visorchannel_signalremove);
+bool
+visorchannel_signalempty(struct visorchannel *channel, u32 queue)
+{
+ unsigned long flags = 0;
+ struct signal_queue_header sig_hdr;
+ bool rc = false;
+
+ if (channel->needs_lock)
+ spin_lock_irqsave(&channel->remove_lock, flags);
+
+ if (!sig_read_header(channel, queue, &sig_hdr))
+ rc = true;
+ if (sig_hdr.head == sig_hdr.tail)
+ rc = true;
+ if (channel->needs_lock)
+ spin_unlock_irqrestore(&channel->remove_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(visorchannel_signalempty);
+
static bool
signalinsert_inner(struct visorchannel *channel, u32 queue, void *msg)
{