diff options
Diffstat (limited to 'drivers/staging/hv/channel_mgmt.c')
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c | 168 |
1 files changed, 87 insertions, 81 deletions
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index d44d5c39f68b..bc0393a41d29 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -19,12 +19,14 @@ * Hank Janssen <hjanssen@microsoft.com> */ #include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/wait.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/list.h> #include <linux/module.h> #include <linux/completion.h> -#include "osd.h" +#include "hv_api.h" #include "logging.h" #include "vmbus_private.h" #include "utils.h" @@ -34,8 +36,8 @@ struct vmbus_channel_message_table_entry { void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 3 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 7 +#define MAX_MSG_TYPES 4 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 static const struct hv_guid gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { @@ -98,6 +100,15 @@ static const struct hv_guid 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d } }, + /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ + /* KVP */ + { + .data = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 + } + }, + }; @@ -185,7 +196,7 @@ void chn_cb_negotiate(void *context) vmbus_sendpacket(channel, buf, recvlen, requestid, - VmbusPacketTypeDataInBand, 0); + VM_PKT_DATA_INBAND, 0); } kfree(buf); @@ -231,6 +242,16 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { .callback = chn_cb_negotiate, .log_msg = "Heartbeat channel functionality initialized" }, + /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ + /* KVP */ + { + .data = { + 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 + }, + .callback = chn_cb_negotiate, + .log_msg = "KVP channel functionality initialized" + }, }; EXPORT_SYMBOL(hv_cb_utils); @@ -289,7 +310,7 @@ void free_channel(struct vmbus_channel *channel) * ie we can't destroy ourselves. */ INIT_WORK(&channel->work, release_channel); - queue_work(gVmbusConnection.WorkQueue, &channel->work); + queue_work(vmbus_connection.work_queue, &channel->work); } @@ -304,10 +325,10 @@ static void count_hv_channel(void) static int counter; unsigned long flags; - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); if (++counter == MAX_MSG_TYPES) complete(&hv_channel_ready); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); } /* @@ -342,14 +363,14 @@ static void vmbus_process_offer(struct work_struct *work) INIT_WORK(&newchannel->work, vmbus_process_rescind_offer); /* Make sure this is a new offer */ - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) { - if (!memcmp(&channel->offermsg.offer.InterfaceType, - &newchannel->offermsg.offer.InterfaceType, + list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { + if (!memcmp(&channel->offermsg.offer.if_type, + &newchannel->offermsg.offer.if_type, sizeof(struct hv_guid)) && - !memcmp(&channel->offermsg.offer.InterfaceInstance, - &newchannel->offermsg.offer.InterfaceInstance, + !memcmp(&channel->offermsg.offer.if_instance, + &newchannel->offermsg.offer.if_instance, sizeof(struct hv_guid))) { fnew = false; break; @@ -358,9 +379,9 @@ static void vmbus_process_offer(struct work_struct *work) if (fnew) list_add_tail(&newchannel->listentry, - &gVmbusConnection.ChannelList); + &vmbus_connection.chn_list); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); if (!fnew) { DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", @@ -372,11 +393,11 @@ static void vmbus_process_offer(struct work_struct *work) /* * Start the process of binding this offer to the driver * We need to set the DeviceObject field before calling - * VmbusChildDeviceAdd() + * vmbus_child_dev_add() */ newchannel->device_obj = vmbus_child_device_create( - &newchannel->offermsg.offer.InterfaceType, - &newchannel->offermsg.offer.InterfaceInstance, + &newchannel->offermsg.offer.if_type, + &newchannel->offermsg.offer.if_instance, newchannel); DPRINT_DBG(VMBUS, "child device object allocated - %p", @@ -387,15 +408,15 @@ static void vmbus_process_offer(struct work_struct *work) * binding which eventually invokes the device driver's AddDevice() * method. */ - ret = VmbusChildDeviceAdd(newchannel->device_obj); + ret = vmbus_child_device_register(newchannel->device_obj); if (ret != 0) { DPRINT_ERR(VMBUS, "unable to add child device object (relid %d)", newchannel->offermsg.child_relid); - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_del(&newchannel->listentry); - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); free_channel(newchannel); } else { @@ -408,7 +429,7 @@ static void vmbus_process_offer(struct work_struct *work) /* Open IC channels */ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { - if (memcmp(&newchannel->offermsg.offer.InterfaceType, + if (memcmp(&newchannel->offermsg.offer.if_type, &hv_cb_utils[cnt].data, sizeof(struct hv_guid)) == 0 && vmbus_open(newchannel, 2 * PAGE_SIZE, @@ -442,7 +463,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) offer = (struct vmbus_channel_offer_channel *)hdr; for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (memcmp(&offer->offer.InterfaceType, + if (memcmp(&offer->offer.if_type, &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) { fsupported = 1; break; @@ -455,8 +476,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) return; } - guidtype = &offer->offer.InterfaceType; - guidinstance = &offer->offer.InterfaceInstance; + guidtype = &offer->offer.if_type; + guidinstance = &offer->offer.if_instance; DPRINT_INFO(VMBUS, "Channel offer notification - " "child relid %d monitor id %d allocated %d, " @@ -513,7 +534,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) struct vmbus_channel *channel; rescind = (struct vmbus_channel_rescind_offer *)hdr; - channel = GetChannelFromRelId(rescind->child_relid); + channel = relid2channel(rescind->child_relid); if (channel == NULL) { DPRINT_DBG(VMBUS, "channel not found for relId %d", rescind->child_relid); @@ -546,7 +567,6 @@ static void vmbus_onoffers_delivered( static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_open_result *result; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_open_channel *openmsg; @@ -558,11 +578,10 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) /* * Find the open msg, copy the result and signal/unblock the wait event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -574,12 +593,13 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.open_result, result, sizeof(struct vmbus_channel_open_result)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -592,7 +612,6 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_gpadl_created *gpadlcreated; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_gpadl_header *gpadlheader; @@ -606,11 +625,10 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) * Find the establish msg, copy the result and signal/unblock the wait * event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -624,12 +642,13 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.gpadl_created, gpadlcreated, sizeof(struct vmbus_channel_gpadl_created)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -643,7 +662,6 @@ static void vmbus_ongpadl_torndown( struct vmbus_channel_message_header *hdr) { struct vmbus_channel_gpadl_torndown *gpadl_torndown; - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_gpadl_teardown *gpadl_teardown; @@ -654,11 +672,10 @@ static void vmbus_ongpadl_torndown( /* * Find the open msg, copy the result and signal/unblock the wait event */ - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -670,12 +687,13 @@ static void vmbus_ongpadl_torndown( memcpy(&msginfo->response.gpadl_torndown, gpadl_torndown, sizeof(struct vmbus_channel_gpadl_torndown)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); break; } } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* @@ -688,7 +706,6 @@ static void vmbus_ongpadl_torndown( static void vmbus_onversion_response( struct vmbus_channel_message_header *hdr) { - struct list_head *curr; struct vmbus_channel_msginfo *msginfo; struct vmbus_channel_message_header *requestheader; struct vmbus_channel_initiate_contact *initiate; @@ -696,11 +713,10 @@ static void vmbus_onversion_response( unsigned long flags; version_response = (struct vmbus_channel_version_response *)hdr; - spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_for_each(curr, &gVmbusConnection.ChannelMsgList) { -/* FIXME: this should probably use list_entry() instead */ - msginfo = (struct vmbus_channel_msginfo *)curr; + list_for_each_entry(msginfo, &vmbus_connection.chn_msg_list, + msglistentry) { requestheader = (struct vmbus_channel_message_header *)msginfo->msg; @@ -711,10 +727,11 @@ static void vmbus_onversion_response( memcpy(&msginfo->response.version_response, version_response, sizeof(struct vmbus_channel_version_response)); - osd_waitevent_set(msginfo->waitevent); + msginfo->wait_condition = 1; + wake_up(&msginfo->waitevent); } } - spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); } /* Channel message dispatch table */ @@ -786,44 +803,33 @@ int vmbus_request_offers(void) if (!msginfo) return -ENOMEM; - msginfo->waitevent = osd_waitevent_create(); - if (!msginfo->waitevent) { - kfree(msginfo); - return -ENOMEM; - } + init_waitqueue_head(&msginfo->waitevent); msg = (struct vmbus_channel_message_header *)msginfo->msg; msg->msgtype = CHANNELMSG_REQUESTOFFERS; - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, - &msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ - ret = VmbusPostMessage(msg, + ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_message_header)); if (ret != 0) { DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ + goto cleanup; + } - goto Cleanup; + msginfo->wait_condition = 0; + wait_event_timeout(msginfo->waitevent, msginfo->wait_condition, + msecs_to_jiffies(1000)); + if (msginfo->wait_condition == 0) { + ret = -ETIMEDOUT; + goto cleanup; } - /* osd_waitevent_wait(msgInfo->waitEvent); */ - /*SpinlockAcquire(gVmbusConnection.channelMsgLock); - REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); - SpinlockRelease(gVmbusConnection.channelMsgLock);*/ -Cleanup: - if (msginfo) { - kfree(msginfo->waitevent); - kfree(msginfo); - } +cleanup: + kfree(msginfo); return ret; } @@ -838,14 +844,14 @@ void vmbus_release_unattached_channels(void) struct vmbus_channel *start = NULL; unsigned long flags; - spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); + spin_lock_irqsave(&vmbus_connection.channel_lock, flags); - list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList, + list_for_each_entry_safe(channel, pos, &vmbus_connection.chn_list, listentry) { if (channel == start) break; - if (!channel->device_obj->Driver) { + if (!channel->device_obj->drv) { list_del(&channel->listentry); DPRINT_INFO(VMBUS, "Releasing unattached device object %p", @@ -859,7 +865,7 @@ void vmbus_release_unattached_channels(void) } } - spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); + spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); } /* eof */ |