]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/staging/hv/channel_mgmt.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[karo-tx-linux.git] / drivers / staging / hv / channel_mgmt.c
index 3f53b4d1e4cffcf09552871b30f5c9d6f98ce8a3..6ccf505e802d6f8d5b063b12112fab3e459d1a2b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/completion.h>
 #include "osd.h"
 #include "logging.h"
 #include "vmbus_private.h"
@@ -266,15 +267,11 @@ static inline void ReleaseVmbusChannel(void *context)
 {
        struct vmbus_channel *channel = context;
 
-       DPRINT_ENTER(VMBUS);
-
        DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
        destroy_workqueue(channel->ControlWQ);
        DPRINT_DBG(VMBUS, "channel released (%p)", channel);
 
        kfree(channel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -293,6 +290,25 @@ void FreeVmbusChannel(struct vmbus_channel *Channel)
                              Channel);
 }
 
+
+DECLARE_COMPLETION(hv_channel_ready);
+
+/*
+ * Count initialized channels, and ensure all channels are ready when hv_vmbus
+ * module loading completes.
+ */
+static void count_hv_channel(void)
+{
+       static int counter;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
+       if (++counter == MAX_MSG_TYPES)
+               complete(&hv_channel_ready);
+       spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
+}
+
+
 /*
  * VmbusChannelProcessOffer - Process the offer by creating a channel/device
  * associated with this offer
@@ -306,8 +322,6 @@ static void VmbusChannelProcessOffer(void *context)
        int cnt;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        /* Make sure this is a new offer */
        spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
 
@@ -333,7 +347,6 @@ static void VmbusChannelProcessOffer(void *context)
                DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
                           newChannel->OfferMsg.ChildRelId);
                FreeVmbusChannel(newChannel);
-               DPRINT_EXIT(VMBUS);
                return;
        }
 
@@ -373,25 +386,23 @@ static void VmbusChannelProcessOffer(void *context)
                 * can cleanup properly
                 */
                newChannel->State = CHANNEL_OPEN_STATE;
-               cnt = 0;
 
-               while (cnt != MAX_MSG_TYPES) {
+               /* Open IC channels */
+               for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
                        if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType,
                                   &hv_cb_utils[cnt].data,
-                                  sizeof(struct hv_guid)) == 0) {
+                                  sizeof(struct hv_guid)) == 0 &&
+                               VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
+                                                2 * PAGE_SIZE, NULL, 0,
+                                                hv_cb_utils[cnt].callback,
+                                                newChannel) == 0) {
+                               hv_cb_utils[cnt].channel = newChannel;
                                DPRINT_INFO(VMBUS, "%s",
-                                           hv_cb_utils[cnt].log_msg);
-
-                               if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
-                                                   2 * PAGE_SIZE, NULL, 0,
-                                                   hv_cb_utils[cnt].callback,
-                                                   newChannel) == 0)
-                                       hv_cb_utils[cnt].channel = newChannel;
+                                               hv_cb_utils[cnt].log_msg);
+                               count_hv_channel();
                        }
-                       cnt++;
                }
        }
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -401,9 +412,7 @@ static void VmbusChannelProcessRescindOffer(void *context)
 {
        struct vmbus_channel *channel = context;
 
-       DPRINT_ENTER(VMBUS);
        VmbusChildDeviceRemove(channel->DeviceObject);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -422,8 +431,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        int i;
        int fSupported = 0;
 
-       DPRINT_ENTER(VMBUS);
-
        offer = (struct vmbus_channel_offer_channel *)hdr;
        for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
                if (memcmp(&offer->Offer.InterfaceType,
@@ -436,7 +443,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        if (!fSupported) {
                DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
                           "child relid %d", offer->ChildRelId);
-               DPRINT_EXIT(VMBUS);
                return;
        }
 
@@ -485,8 +491,6 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
        /* TODO: Make sure the offer comes from our parent partition */
        osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer,
                              newChannel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -499,8 +503,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_rescind_offer *rescind;
        struct vmbus_channel *channel;
 
-       DPRINT_ENTER(VMBUS);
-
        rescind = (struct vmbus_channel_rescind_offer *)hdr;
        channel = GetChannelFromRelId(rescind->ChildRelId);
        if (channel == NULL) {
@@ -512,8 +514,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
        osd_schedule_callback(channel->ControlWQ,
                              VmbusChannelProcessRescindOffer,
                              channel);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -524,8 +524,6 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
 static void VmbusChannelOnOffersDelivered(
                        struct vmbus_channel_message_header *hdr)
 {
-       DPRINT_ENTER(VMBUS);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -544,8 +542,6 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_open_channel *openMsg;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        result = (struct vmbus_channel_open_result *)hdr;
        DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);
 
@@ -572,8 +568,6 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -592,8 +586,6 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
        struct vmbus_channel_gpadl_header *gpadlHeader;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr;
        DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
                   gpadlCreated->CreationStatus);
@@ -624,8 +616,6 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -645,8 +635,6 @@ static void VmbusChannelOnGpadlTorndown(
        struct vmbus_channel_gpadl_teardown *gpadlTeardown;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr;
 
        /*
@@ -672,8 +660,6 @@ static void VmbusChannelOnGpadlTorndown(
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -693,8 +679,6 @@ static void VmbusChannelOnVersionResponse(
        struct vmbus_channel_version_response *versionResponse;
        unsigned long flags;
 
-       DPRINT_ENTER(VMBUS);
-
        versionResponse = (struct vmbus_channel_version_response *)hdr;
        spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
 
@@ -713,8 +697,6 @@ static void VmbusChannelOnVersionResponse(
                }
        }
        spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
-
-       DPRINT_EXIT(VMBUS);
 }
 
 /* Channel message dispatch table */
@@ -750,8 +732,6 @@ void VmbusOnChannelMessage(void *Context)
        struct vmbus_channel_message_header *hdr;
        int size;
 
-       DPRINT_ENTER(VMBUS);
-
        hdr = (struct vmbus_channel_message_header *)msg->u.Payload;
        size = msg->Header.PayloadSize;
 
@@ -775,7 +755,6 @@ void VmbusOnChannelMessage(void *Context)
 
        /* Free the msg that was allocated in VmbusOnMsgDPC() */
        kfree(msg);
-       DPRINT_EXIT(VMBUS);
 }
 
 /*
@@ -787,8 +766,6 @@ int VmbusChannelRequestOffers(void)
        struct vmbus_channel_msginfo *msgInfo;
        int ret;
 
-       DPRINT_ENTER(VMBUS);
-
        msgInfo = kmalloc(sizeof(*msgInfo) +
                          sizeof(struct vmbus_channel_message_header),
                          GFP_KERNEL);
@@ -834,7 +811,6 @@ Cleanup:
                kfree(msgInfo);
        }
 
-       DPRINT_EXIT(VMBUS);
        return ret;
 }