Merge remote-tracking branch 'char-misc/char-misc-next'
[deliverable/linux.git] / drivers / hv / hv_utils_transport.c
index 9a9983fa4531ad52a0f2918ffb51b42f9e8f2b89..c235a95152671104cd7042a451b16ccd0d0d06ab 100644 (file)
@@ -72,6 +72,10 @@ static ssize_t hvt_op_read(struct file *file, char __user *buf,
        hvt->outmsg = NULL;
        hvt->outmsg_len = 0;
 
+       if (hvt->on_read)
+               hvt->on_read();
+       hvt->on_read = NULL;
+
 out_unlock:
        mutex_unlock(&hvt->lock);
        return ret;
@@ -219,7 +223,8 @@ static void hvt_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
        mutex_unlock(&hvt->lock);
 }
 
-int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len)
+int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len,
+                         void (*on_read_cb)(void))
 {
        struct cn_msg *cn_msg;
        int ret = 0;
@@ -237,6 +242,13 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len)
                memcpy(cn_msg->data, msg, len);
                ret = cn_netlink_send(cn_msg, 0, 0, GFP_ATOMIC);
                kfree(cn_msg);
+               /*
+                * We don't know when netlink messages are delivered but unlike
+                * in CHARDEV mode we're not blocked and we can send next
+                * messages right away.
+                */
+               if (on_read_cb)
+                       on_read_cb();
                return ret;
        }
        /* HVUTIL_TRANSPORT_CHARDEV */
@@ -255,6 +267,7 @@ int hvutil_transport_send(struct hvutil_transport *hvt, void *msg, int len)
        if (hvt->outmsg) {
                memcpy(hvt->outmsg, msg, len);
                hvt->outmsg_len = len;
+               hvt->on_read = on_read_cb;
                wake_up_interruptible(&hvt->outmsg_q);
        } else
                ret = -ENOMEM;
This page took 0.024991 seconds and 5 git commands to generate.