diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2010-07-24 15:49:13 (GMT) |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2010-07-24 15:49:13 (GMT) |
commit | 4e4f62bf7396fca48efe61513640ee399a6046e3 (patch) | |
tree | 42a503af02d9806bcc05e5fcc2cd53f9bd45b0c2 /drivers/staging/hv/channel_mgmt.c | |
parent | 9e3288dc9a94fab5ea87db42177d3a9e0345a614 (diff) | |
parent | b37fa16e78d6f9790462b3181602a26b5af36260 (diff) | |
download | linux-fsl-qoriq-4e4f62bf7396fca48efe61513640ee399a6046e3.tar.xz |
Merge commit 'v2.6.35-rc6' into devicetree/next
Conflicts:
arch/sparc/kernel/prom_64.c
Diffstat (limited to 'drivers/staging/hv/channel_mgmt.c')
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 3f53b4d..12db555 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -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" @@ -293,6 +294,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 @@ -373,22 +393,21 @@ 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); |