Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
Show All 34 Lines | |||||
#include <dev/hyperv/vmbus/hv_vmbus_priv.h> | #include <dev/hyperv/vmbus/hv_vmbus_priv.h> | ||||
#include <dev/hyperv/vmbus/vmbus_reg.h> | #include <dev/hyperv/vmbus/vmbus_reg.h> | ||||
#include <dev/hyperv/vmbus/vmbus_var.h> | #include <dev/hyperv/vmbus/vmbus_var.h> | ||||
/* | /* | ||||
* Internal functions | * Internal functions | ||||
*/ | */ | ||||
typedef void (*vmbus_msg_handler)(hv_vmbus_channel_msg_header *msg); | typedef void (*vmbus_msg_handler)(const hv_vmbus_channel_msg_header *msg); | ||||
typedef struct hv_vmbus_channel_msg_table_entry { | typedef struct hv_vmbus_channel_msg_table_entry { | ||||
hv_vmbus_channel_msg_type messageType; | hv_vmbus_channel_msg_type messageType; | ||||
vmbus_msg_handler messageHandler; | vmbus_msg_handler messageHandler; | ||||
} hv_vmbus_channel_msg_table_entry; | } hv_vmbus_channel_msg_table_entry; | ||||
static void vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_offer_internal(void* context); | static void vmbus_channel_on_offer_internal(void *context); | ||||
static void vmbus_channel_on_open_result(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_offer_rescind(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_offer_rescind_internal(void* context); | static void vmbus_channel_on_offer_rescind_internal(void *context); | ||||
static void vmbus_channel_on_gpadl_created(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr); | |||||
static void vmbus_channel_on_offer(const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_open_result( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_offer_rescind( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_gpadl_created( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_gpadl_torndown( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_offers_delivered( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
static void vmbus_channel_on_version_response( | |||||
const hv_vmbus_channel_msg_header *hdr); | |||||
/** | /** | ||||
* Channel message dispatch table | * Channel message dispatch table | ||||
*/ | */ | ||||
static const hv_vmbus_channel_msg_table_entry | static const hv_vmbus_channel_msg_table_entry | ||||
g_channel_message_table[HV_CHANNEL_MESSAGE_COUNT] = { | g_channel_message_table[HV_CHANNEL_MESSAGE_COUNT] = { | ||||
{ HV_CHANNEL_MESSAGE_INVALID, | { HV_CHANNEL_MESSAGE_INVALID, | ||||
NULL }, | NULL }, | ||||
{ HV_CHANNEL_MESSAGE_OFFER_CHANNEL, | { HV_CHANNEL_MESSAGE_OFFER_CHANNEL, | ||||
▲ Show 20 Lines • Show All 318 Lines • ▼ Show 20 Lines | |||||
* @brief Handler for channel offers from Hyper-V/Azure | * @brief Handler for channel offers from Hyper-V/Azure | ||||
* | * | ||||
* Handler for channel offers from vmbus in parent partition. We ignore | * Handler for channel offers from vmbus in parent partition. We ignore | ||||
* all offers except network and storage offers. For each network and storage | * all offers except network and storage offers. For each network and storage | ||||
* offers, we create a channel object and queue a work item to the channel | * offers, we create a channel object and queue a work item to the channel | ||||
* object to process the offer synchronously | * object to process the offer synchronously | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_offer(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_offer(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_offer_channel* offer; | const hv_vmbus_channel_offer_channel *offer; | ||||
hv_vmbus_channel_offer_channel* copied; | hv_vmbus_channel_offer_channel *copied; | ||||
offer = (hv_vmbus_channel_offer_channel*) hdr; | offer = (const hv_vmbus_channel_offer_channel *)hdr; | ||||
// copy offer data | // copy offer data | ||||
copied = malloc(sizeof(*copied), M_DEVBUF, M_NOWAIT); | copied = malloc(sizeof(*copied), M_DEVBUF, M_NOWAIT); | ||||
if (copied == NULL) { | if (copied == NULL) { | ||||
printf("fail to allocate memory\n"); | printf("fail to allocate memory\n"); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* @brief Rescind offer handler. | * @brief Rescind offer handler. | ||||
* | * | ||||
* We queue a work item to process this offer | * We queue a work item to process this offer | ||||
* synchronously | * synchronously | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_offer_rescind(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_offer_rescind(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_rescind_offer* rescind; | const hv_vmbus_channel_rescind_offer *rescind; | ||||
hv_vmbus_channel* channel; | hv_vmbus_channel* channel; | ||||
rescind = (hv_vmbus_channel_rescind_offer*) hdr; | rescind = (const hv_vmbus_channel_rescind_offer *)hdr; | ||||
channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; | channel = hv_vmbus_g_connection.channels[rescind->child_rel_id]; | ||||
if (channel == NULL) | if (channel == NULL) | ||||
return; | return; | ||||
hv_queue_work_item(vmbus_channel_on_offer_rescind_internal, channel); | hv_queue_work_item(vmbus_channel_on_offer_rescind_internal, channel); | ||||
hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; | hv_vmbus_g_connection.channels[rescind->child_rel_id] = NULL; | ||||
} | } | ||||
Show All 10 Lines | vmbus_channel_on_offer_rescind_internal(void *context) | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* | * | ||||
* @brief Invoked when all offers have been delivered. | * @brief Invoked when all offers have been delivered. | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_offers_delivered(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_offers_delivered( | ||||
const hv_vmbus_channel_msg_header *hdr __unused) | |||||
{ | { | ||||
mtx_lock(&vmbus_chwait_lock); | mtx_lock(&vmbus_chwait_lock); | ||||
vmbus_chancnt |= VMBUS_CHANCNT_DONE; | vmbus_chancnt |= VMBUS_CHANCNT_DONE; | ||||
mtx_unlock(&vmbus_chwait_lock); | mtx_unlock(&vmbus_chwait_lock); | ||||
wakeup(&vmbus_chancnt); | wakeup(&vmbus_chancnt); | ||||
} | } | ||||
/** | /** | ||||
* @brief Open result handler. | * @brief Open result handler. | ||||
* | * | ||||
* This is invoked when we received a response | * This is invoked when we received a response | ||||
* to our channel open request. Find the matching request, copy the | * to our channel open request. Find the matching request, copy the | ||||
* response and signal the requesting thread. | * response and signal the requesting thread. | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_open_result(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_open_result(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_open_result* result; | const hv_vmbus_channel_open_result *result; | ||||
hv_vmbus_channel_msg_info* msg_info; | hv_vmbus_channel_msg_info* msg_info; | ||||
hv_vmbus_channel_msg_header* requestHeader; | hv_vmbus_channel_msg_header* requestHeader; | ||||
hv_vmbus_channel_open_channel* openMsg; | hv_vmbus_channel_open_channel* openMsg; | ||||
result = (hv_vmbus_channel_open_result*) hdr; | result = (const hv_vmbus_channel_open_result *)hdr; | ||||
/* | /* | ||||
* Find the open msg, copy the result and signal/unblock the wait event | * Find the open msg, copy the result and signal/unblock the wait event | ||||
*/ | */ | ||||
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | ||||
TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | ||||
msg_list_entry) { | msg_list_entry) { | ||||
Show All 18 Lines | |||||
/** | /** | ||||
* @brief GPADL created handler. | * @brief GPADL created handler. | ||||
* | * | ||||
* This is invoked when we received a response | * This is invoked when we received a response | ||||
* to our gpadl create request. Find the matching request, copy the | * to our gpadl create request. Find the matching request, copy the | ||||
* response and signal the requesting thread. | * response and signal the requesting thread. | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_gpadl_created(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_gpadl_created(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_gpadl_created* gpadl_created; | const hv_vmbus_channel_gpadl_created *gpadl_created; | ||||
hv_vmbus_channel_msg_info* msg_info; | hv_vmbus_channel_msg_info* msg_info; | ||||
hv_vmbus_channel_msg_header* request_header; | hv_vmbus_channel_msg_header* request_header; | ||||
hv_vmbus_channel_gpadl_header* gpadl_header; | hv_vmbus_channel_gpadl_header* gpadl_header; | ||||
gpadl_created = (hv_vmbus_channel_gpadl_created*) hdr; | gpadl_created = (const hv_vmbus_channel_gpadl_created *)hdr; | ||||
/* Find the establish msg, copy the result and signal/unblock | /* Find the establish msg, copy the result and signal/unblock | ||||
* the wait event | * the wait event | ||||
*/ | */ | ||||
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | ||||
TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | ||||
msg_list_entry) { | msg_list_entry) { | ||||
request_header = (hv_vmbus_channel_msg_header*) msg_info->msg; | request_header = (hv_vmbus_channel_msg_header*) msg_info->msg; | ||||
Show All 18 Lines | |||||
/** | /** | ||||
* @brief GPADL torndown handler. | * @brief GPADL torndown handler. | ||||
* | * | ||||
* This is invoked when we received a respons | * This is invoked when we received a respons | ||||
* to our gpadl teardown request. Find the matching request, copy the | * to our gpadl teardown request. Find the matching request, copy the | ||||
* response and signal the requesting thread | * response and signal the requesting thread | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_gpadl_torndown(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_gpadl_torndown(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_gpadl_torndown* gpadl_torndown; | const hv_vmbus_channel_gpadl_torndown *gpadl_torndown; | ||||
hv_vmbus_channel_msg_info* msg_info; | hv_vmbus_channel_msg_info* msg_info; | ||||
hv_vmbus_channel_msg_header* requestHeader; | hv_vmbus_channel_msg_header* requestHeader; | ||||
hv_vmbus_channel_gpadl_teardown* gpadlTeardown; | hv_vmbus_channel_gpadl_teardown* gpadlTeardown; | ||||
gpadl_torndown = (hv_vmbus_channel_gpadl_torndown*)hdr; | gpadl_torndown = (const hv_vmbus_channel_gpadl_torndown *)hdr; | ||||
/* | /* | ||||
* Find the open msg, copy the result and signal/unblock the | * Find the open msg, copy the result and signal/unblock the | ||||
* wait event. | * wait event. | ||||
*/ | */ | ||||
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | ||||
Show All 21 Lines | |||||
/** | /** | ||||
* @brief Version response handler. | * @brief Version response handler. | ||||
* | * | ||||
* This is invoked when we received a response | * This is invoked when we received a response | ||||
* to our initiate contact request. Find the matching request, copy th | * to our initiate contact request. Find the matching request, copy th | ||||
* response and signal the requesting thread. | * response and signal the requesting thread. | ||||
*/ | */ | ||||
static void | static void | ||||
vmbus_channel_on_version_response(hv_vmbus_channel_msg_header* hdr) | vmbus_channel_on_version_response(const hv_vmbus_channel_msg_header *hdr) | ||||
{ | { | ||||
hv_vmbus_channel_msg_info* msg_info; | hv_vmbus_channel_msg_info* msg_info; | ||||
hv_vmbus_channel_msg_header* requestHeader; | hv_vmbus_channel_msg_header* requestHeader; | ||||
hv_vmbus_channel_initiate_contact* initiate; | hv_vmbus_channel_initiate_contact* initiate; | ||||
hv_vmbus_channel_version_response* versionResponse; | const hv_vmbus_channel_version_response *versionResponse; | ||||
versionResponse = (hv_vmbus_channel_version_response*)hdr; | versionResponse = (const hv_vmbus_channel_version_response *)hdr; | ||||
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); | ||||
TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor, | ||||
msg_list_entry) { | msg_list_entry) { | ||||
requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg; | requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg; | ||||
if (requestHeader->message_type | if (requestHeader->message_type | ||||
== HV_CHANNEL_MESSAGE_INITIATED_CONTACT) { | == HV_CHANNEL_MESSAGE_INITIATED_CONTACT) { | ||||
initiate = | initiate = | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | |||||
void | void | ||||
vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt __unused) | vmbus_rel_subchan(struct hv_vmbus_channel **subchan, int subchan_cnt __unused) | ||||
{ | { | ||||
free(subchan, M_TEMP); | free(subchan, M_TEMP); | ||||
} | } | ||||
void | void | ||||
vmbus_chan_msgproc(struct vmbus_softc *sc, volatile struct vmbus_message *msg) | vmbus_chan_msgproc(struct vmbus_softc *sc, const struct vmbus_message *msg) | ||||
{ | { | ||||
const hv_vmbus_channel_msg_table_entry *entry; | const hv_vmbus_channel_msg_table_entry *entry; | ||||
hv_vmbus_channel_msg_header *hdr; | const hv_vmbus_channel_msg_header *hdr; | ||||
hv_vmbus_channel_msg_type msg_type; | hv_vmbus_channel_msg_type msg_type; | ||||
/* XXX: update messageHandler interface */ | hdr = (const hv_vmbus_channel_msg_header *)msg->msg_data; | ||||
hdr = __DEVOLATILE(hv_vmbus_channel_msg_header *, msg->msg_data); | |||||
msg_type = hdr->message_type; | msg_type = hdr->message_type; | ||||
if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) { | if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) { | ||||
device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", | device_printf(sc->vmbus_dev, "unknown message type 0x%x\n", | ||||
msg_type); | msg_type); | ||||
return; | return; | ||||
} | } | ||||
entry = &g_channel_message_table[msg_type]; | entry = &g_channel_message_table[msg_type]; | ||||
if (entry->messageHandler) | if (entry->messageHandler) | ||||
entry->messageHandler(hdr); | entry->messageHandler(hdr); | ||||
} | } |