Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/hyperv/vmbus/hv_connection.c
Show All 27 Lines | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/malloc.h> | #include <sys/malloc.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <machine/atomic.h> | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include "hv_vmbus_priv.h" | #include "hv_vmbus_priv.h" | ||||
/* | /* | ||||
* Globals | * Globals | ||||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | hv_vmbus_on_events(int cpu) | ||||
event = (hv_vmbus_synic_event_flags *) | event = (hv_vmbus_synic_event_flags *) | ||||
page_addr + HV_VMBUS_MESSAGE_SINT; | page_addr + HV_VMBUS_MESSAGE_SINT; | ||||
if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || | if ((hv_vmbus_protocal_version == HV_VMBUS_VERSION_WS2008) || | ||||
(hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { | (hv_vmbus_protocal_version == HV_VMBUS_VERSION_WIN7)) { | ||||
maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5; | maxdword = HV_MAX_NUM_CHANNELS_SUPPORTED >> 5; | ||||
/* | /* | ||||
* receive size is 1/2 page and divide that by 4 bytes | * receive size is 1/2 page and divide that by 4 bytes | ||||
*/ | */ | ||||
if (synch_test_and_clear_bit(0, &event->flags32[0])) { | if (atomic_testandclear_int(&event->flags32[0], 0)) { | ||||
recv_interrupt_page = | recv_interrupt_page = | ||||
hv_vmbus_g_connection.recv_interrupt_page; | hv_vmbus_g_connection.recv_interrupt_page; | ||||
} else { | } else { | ||||
return; | return; | ||||
} | } | ||||
} else { | } else { | ||||
/* | /* | ||||
* On Host with Win8 or above, the event page can be | * On Host with Win8 or above, the event page can be | ||||
* checked directly to get the id of the channel | * checked directly to get the id of the channel | ||||
* that has the pending interrupt. | * that has the pending interrupt. | ||||
*/ | */ | ||||
maxdword = HV_EVENT_FLAGS_DWORD_COUNT; | maxdword = HV_EVENT_FLAGS_DWORD_COUNT; | ||||
recv_interrupt_page = event->flags32; | recv_interrupt_page = event->flags32; | ||||
} | } | ||||
/* | /* | ||||
* Check events | * Check events | ||||
*/ | */ | ||||
for (dword = 0; dword < maxdword; dword++) { | for (dword = 0; dword < maxdword; dword++) { | ||||
if (recv_interrupt_page[dword] == 0) | if (recv_interrupt_page[dword] == 0) | ||||
continue; | continue; | ||||
for (bit = 0; bit < HV_CHANNEL_DWORD_LEN; bit++) { | for (bit = 0; bit < HV_CHANNEL_DWORD_LEN; bit++) { | ||||
if (synch_test_and_clear_bit(bit, | if (atomic_testandclear_int( | ||||
(uint32_t *)&recv_interrupt_page[dword])) { | &recv_interrupt_page[dword], bit)) { | ||||
struct hv_vmbus_channel *channel; | struct hv_vmbus_channel *channel; | ||||
rel_id = (dword << 5) + bit; | rel_id = (dword << 5) + bit; | ||||
channel = | channel = | ||||
hv_vmbus_g_connection.channels[rel_id]; | hv_vmbus_g_connection.channels[rel_id]; | ||||
/* if channel is closed or closing */ | /* if channel is closed or closing */ | ||||
if (channel == NULL || channel->rxq == NULL) | if (channel == NULL || channel->rxq == NULL) | ||||
▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines |