mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
* 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (1519 commits)
staging: et131x: Remove redundant check and return statement
staging: et131x: Mainly whitespace changes to appease checkpatch
staging: et131x: Remove last of the forward declarations
staging: et131x: Remove even more forward declarations
staging: et131x: Remove yet more forward declarations
staging: et131x: Remove more forward declarations
staging: et131x: Remove forward declaration of et131x_adapter_setup
staging: et131x: Remove some forward declarations
staging: et131x: Remove unused rx_ring.recv_packet_pool
staging: et131x: Remove call to find pci pm capability
staging: et131x: Remove redundant et131x_reset_recv() call
staging: et131x: Remove unused rx_ring.recv_buffer_pool
Staging: bcm: Fix three initialization errors in InterfaceDld.c
Staging: bcm: Fix coding style issues in InterfaceDld.c
staging:iio:dac: Add AD5360 driver
staging:iio:trigger:bfin-timer: Fix compile error
Staging: vt6655: add some range checks before memcpy()
Staging: vt6655: whitespace fixes to iotcl.c
Staging: vt6656: add some range checks before memcpy()
Staging: vt6656: whitespace cleanups in ioctl.c
...
Fix up conflicts in:
- drivers/{Kconfig,Makefile}, drivers/staging/{Kconfig,Makefile}:
vg driver movement
- drivers/staging/brcm80211/brcmfmac/{dhd_linux.c,mac80211_if.c}:
driver removal vs now stale changes
- drivers/staging/rtl8192e/r8192E_core.c:
driver removal vs now stale changes
- drivers/staging/et131x/et131*:
driver consolidation into one file, tried to do fixups
This commit is contained in:
+13
-1
@@ -6171,7 +6171,7 @@ S: Maintained
|
||||
|
||||
STAGING SUBSYSTEM
|
||||
M: Greg Kroah-Hartman <gregkh@suse.de>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
|
||||
L: devel@driverdev.osuosl.org
|
||||
S: Maintained
|
||||
F: drivers/staging/
|
||||
@@ -6212,6 +6212,11 @@ M: David Rowe <david@rowetel.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/echo/
|
||||
|
||||
STAGING - ET131X NETWORK DRIVER
|
||||
M: Mark Einon <mark.einon@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/et131x/
|
||||
|
||||
STAGING - FLARION FT1000 DRIVERS
|
||||
M: Marek Belisko <marek.belisko@gmail.com>
|
||||
S: Odd Fixes
|
||||
@@ -6240,6 +6245,13 @@ W: http://www.lirc.org/
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/lirc/
|
||||
|
||||
STAGING - NVIDIA COMPLIANT EMBEDDED CONTROLLER INTERFACE (nvec)
|
||||
M: Julian Andres Klode <jak@jak-linux.org>
|
||||
M: Marc Dietrich <marvin24@gmx.de>
|
||||
L: ac100@lists.launchpad.net (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: drivers/staging/nvec/
|
||||
|
||||
STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON)
|
||||
M: Andres Salomon <dilinger@queued.net>
|
||||
M: Chris Ball <cjb@laptop.org>
|
||||
|
||||
@@ -189,5 +189,6 @@
|
||||
#define HV_STATUS_INVALID_HYPERCALL_CODE 2
|
||||
#define HV_STATUS_INVALID_HYPERCALL_INPUT 3
|
||||
#define HV_STATUS_INVALID_ALIGNMENT 4
|
||||
#define HV_STATUS_INSUFFICIENT_BUFFERS 19
|
||||
|
||||
#endif
|
||||
|
||||
@@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig"
|
||||
|
||||
source "drivers/virt/Kconfig"
|
||||
|
||||
source "drivers/hv/Kconfig"
|
||||
|
||||
source "drivers/devfreq/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -129,5 +129,6 @@ obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
|
||||
|
||||
# Virtualization drivers
|
||||
obj-$(CONFIG_VIRT_DRIVERS) += virt/
|
||||
obj-$(CONFIG_HYPERV) += hv/
|
||||
|
||||
obj-$(CONFIG_PM_DEVFREQ) += devfreq/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
config HYPERV
|
||||
tristate "Microsoft Hyper-V client drivers"
|
||||
depends on X86 && ACPI && PCI
|
||||
help
|
||||
Select this option to run Linux as a Hyper-V client operating
|
||||
system.
|
||||
|
||||
config HYPERV_UTILS
|
||||
tristate "Microsoft Hyper-V Utilities driver"
|
||||
depends on HYPERV && CONNECTOR && NLS
|
||||
help
|
||||
Select this option to enable the Hyper-V Utilities.
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
obj-$(CONFIG_HYPERV) += hv_vmbus.o
|
||||
obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
|
||||
|
||||
hv_vmbus-y := vmbus_drv.o \
|
||||
hv.o connection.o channel.o \
|
||||
channel_mgmt.o ring_buffer.o
|
||||
hv_utils-y := hv_util.o hv_kvp.o
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
#define NUM_PAGES_SPANNED(addr, len) \
|
||||
@@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel,
|
||||
struct hv_monitor_page *monitorpage;
|
||||
u8 monitor_group = (u8)channel->offermsg.monitorid / 32;
|
||||
u8 monitor_offset = (u8)channel->offermsg.monitorid % 32;
|
||||
/* u32 monitorBit = 1 << monitorOffset; */
|
||||
|
||||
debuginfo->relid = channel->offermsg.child_relid;
|
||||
debuginfo->state = channel->state;
|
||||
memcpy(&debuginfo->interfacetype,
|
||||
&channel->offermsg.offer.if_type, sizeof(struct hv_guid));
|
||||
&channel->offermsg.offer.if_type, sizeof(uuid_le));
|
||||
memcpy(&debuginfo->interface_instance,
|
||||
&channel->offermsg.offer.if_instance,
|
||||
sizeof(struct hv_guid));
|
||||
sizeof(uuid_le));
|
||||
|
||||
monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages;
|
||||
|
||||
@@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
u32 recv_ringbuffer_size, void *userdata, u32 userdatalen,
|
||||
void (*onchannelcallback)(void *context), void *context)
|
||||
{
|
||||
struct vmbus_channel_open_channel *openMsg;
|
||||
struct vmbus_channel_msginfo *openInfo = NULL;
|
||||
struct vmbus_channel_open_channel *open_msg;
|
||||
struct vmbus_channel_msginfo *open_info = NULL;
|
||||
void *in, *out;
|
||||
unsigned long flags;
|
||||
int ret, t, err = 0;
|
||||
@@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
}
|
||||
|
||||
/* Create and init the channel open message */
|
||||
openInfo = kmalloc(sizeof(*openInfo) +
|
||||
open_info = kmalloc(sizeof(*open_info) +
|
||||
sizeof(struct vmbus_channel_open_channel),
|
||||
GFP_KERNEL);
|
||||
if (!openInfo) {
|
||||
if (!open_info) {
|
||||
err = -ENOMEM;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
init_completion(&openInfo->waitevent);
|
||||
init_completion(&open_info->waitevent);
|
||||
|
||||
openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
|
||||
openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
|
||||
openMsg->openid = newchannel->offermsg.child_relid;
|
||||
openMsg->child_relid = newchannel->offermsg.child_relid;
|
||||
openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
|
||||
openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
|
||||
open_msg = (struct vmbus_channel_open_channel *)open_info->msg;
|
||||
open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL;
|
||||
open_msg->openid = newchannel->offermsg.child_relid;
|
||||
open_msg->child_relid = newchannel->offermsg.child_relid;
|
||||
open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle;
|
||||
open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >>
|
||||
PAGE_SHIFT;
|
||||
openMsg->server_contextarea_gpadlhandle = 0;
|
||||
open_msg->server_contextarea_gpadlhandle = 0;
|
||||
|
||||
if (userdatalen > MAX_USER_DEFINED_BYTES) {
|
||||
err = -EINVAL;
|
||||
@@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size,
|
||||
}
|
||||
|
||||
if (userdatalen)
|
||||
memcpy(openMsg->userdata, userdata, userdatalen);
|
||||
memcpy(open_msg->userdata, userdata, userdatalen);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_add_tail(&openInfo->msglistentry,
|
||||
list_add_tail(&open_info->msglistentry,
|
||||
&vmbus_connection.chn_msg_list);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
ret = vmbus_post_msg(openMsg,
|
||||
ret = vmbus_post_msg(open_msg,
|
||||
sizeof(struct vmbus_channel_open_channel));
|
||||
|
||||
if (ret != 0)
|
||||
goto cleanup;
|
||||
|
||||
t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
|
||||
t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ);
|
||||
if (t == 0) {
|
||||
err = -ETIMEDOUT;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
|
||||
if (openInfo->response.open_result.status)
|
||||
err = openInfo->response.open_result.status;
|
||||
if (open_info->response.open_result.status)
|
||||
err = open_info->response.open_result.status;
|
||||
|
||||
cleanup:
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_del(&openInfo->msglistentry);
|
||||
list_del(&open_info->msglistentry);
|
||||
spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
|
||||
|
||||
kfree(openInfo);
|
||||
kfree(open_info);
|
||||
return err;
|
||||
|
||||
errorout:
|
||||
@@ -234,56 +233,11 @@ errorout:
|
||||
hv_ringbuffer_cleanup(&newchannel->inbound);
|
||||
free_pages((unsigned long)out,
|
||||
get_order(send_ringbuffer_size + recv_ringbuffer_size));
|
||||
kfree(openInfo);
|
||||
kfree(open_info);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_open);
|
||||
|
||||
/*
|
||||
* dump_gpadl_body - Dump the gpadl body message to the console for
|
||||
* debugging purposes.
|
||||
*/
|
||||
static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len)
|
||||
{
|
||||
int i;
|
||||
int pfncount;
|
||||
|
||||
pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
|
||||
sizeof(u64);
|
||||
|
||||
DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
|
||||
|
||||
for (i = 0; i < pfncount; i++)
|
||||
DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu",
|
||||
i, gpadl->pfn[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* dump_gpadl_header - Dump the gpadl header message to the console for
|
||||
* debugging purposes.
|
||||
*/
|
||||
static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl)
|
||||
{
|
||||
int i, j;
|
||||
int pagecount;
|
||||
|
||||
DPRINT_DBG(VMBUS,
|
||||
"gpadl header - relid %d, range count %d, range buflen %d",
|
||||
gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen);
|
||||
for (i = 0; i < gpadl->rangecount; i++) {
|
||||
pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT;
|
||||
pagecount = (pagecount > 26) ? 26 : pagecount;
|
||||
|
||||
DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
|
||||
"page count %d", i, gpadl->range[i].byte_count,
|
||||
gpadl->range[i].byte_offset, pagecount);
|
||||
|
||||
for (j = 0; j < pagecount; j++)
|
||||
DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
|
||||
gpadl->range[i].pfn_array[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* create_gpadl_header - Creates a gpadl for the specified buffer
|
||||
*/
|
||||
@@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
{
|
||||
struct vmbus_channel_gpadl_header *gpadlmsg;
|
||||
struct vmbus_channel_gpadl_body *gpadl_body;
|
||||
/* struct vmbus_channel_gpadl_created *gpadlCreated; */
|
||||
struct vmbus_channel_msginfo *msginfo = NULL;
|
||||
struct vmbus_channel_msginfo *submsginfo;
|
||||
u32 msgcount;
|
||||
@@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
gpadlmsg->child_relid = channel->offermsg.child_relid;
|
||||
gpadlmsg->gpadl = next_gpadl_handle;
|
||||
|
||||
dump_gpadl_header(gpadlmsg);
|
||||
|
||||
spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
|
||||
list_add_tail(&msginfo->msglistentry,
|
||||
@@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
|
||||
CHANNELMSG_GPADL_BODY;
|
||||
gpadl_body->gpadl = next_gpadl_handle;
|
||||
|
||||
dump_gpadl_body(gpadl_body, submsginfo->msgsize -
|
||||
sizeof(*submsginfo));
|
||||
ret = vmbus_post_msg(gpadl_body,
|
||||
submsginfo->msgsize -
|
||||
sizeof(*submsginfo));
|
||||
@@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle)
|
||||
unsigned long flags;
|
||||
int ret, t;
|
||||
|
||||
/* ASSERT(gpadl_handle != 0); */
|
||||
|
||||
info = kmalloc(sizeof(*info) +
|
||||
sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
|
||||
if (!info)
|
||||
@@ -565,9 +513,12 @@ void vmbus_close(struct vmbus_channel *channel)
|
||||
{
|
||||
struct vmbus_channel_close_channel *msg;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
/* Stop callback and cancel the timer asap */
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
channel->onchannel_callback = NULL;
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
/* Send a closing message */
|
||||
|
||||
@@ -787,19 +738,15 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
u32 packetlen;
|
||||
u32 userlen;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
*buffer_actual_len = 0;
|
||||
*requestid = 0;
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
|
||||
ret = hv_ringbuffer_peek(&channel->inbound, &desc,
|
||||
sizeof(struct vmpacket_descriptor));
|
||||
if (ret != 0) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
packetlen = desc.len8 << 3;
|
||||
userlen = packetlen - (desc.offset8 << 3);
|
||||
@@ -807,7 +754,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
*buffer_actual_len = userlen;
|
||||
|
||||
if (userlen > bufferlen) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
pr_err("Buffer too small - got %d needs %d\n",
|
||||
bufferlen, userlen);
|
||||
@@ -820,7 +766,6 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer,
|
||||
ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
|
||||
(desc.offset8 << 3));
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -837,19 +782,15 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
u32 packetlen;
|
||||
u32 userlen;
|
||||
int ret;
|
||||
unsigned long flags;
|
||||
|
||||
*buffer_actual_len = 0;
|
||||
*requestid = 0;
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
|
||||
ret = hv_ringbuffer_peek(&channel->inbound, &desc,
|
||||
sizeof(struct vmpacket_descriptor));
|
||||
if (ret != 0) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
packetlen = desc.len8 << 3;
|
||||
@@ -858,12 +799,10 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
*buffer_actual_len = packetlen;
|
||||
|
||||
if (packetlen > bufferlen) {
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
|
||||
pr_err("Buffer too small - needed %d bytes but "
|
||||
"got space for only %d bytes\n",
|
||||
packetlen, bufferlen);
|
||||
return -2;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
*requestid = desc.trans_id;
|
||||
@@ -871,7 +810,6 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
|
||||
/* Copy over the entire packet to the user buffer */
|
||||
ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vmbus_recvpacket_raw);
|
||||
@@ -28,8 +28,8 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
struct vmbus_channel_message_table_entry {
|
||||
@@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry {
|
||||
#define MAX_MSG_TYPES 4
|
||||
#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
|
||||
|
||||
static const struct hv_guid
|
||||
static const uuid_le
|
||||
supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
|
||||
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
|
||||
/* Storage - SCSI */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
|
||||
0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
|
||||
}
|
||||
@@ -54,7 +54,7 @@ static const struct hv_guid
|
||||
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
|
||||
/* Network */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
|
||||
0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
|
||||
}
|
||||
@@ -63,7 +63,7 @@ static const struct hv_guid
|
||||
/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
|
||||
/* Input */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
|
||||
0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
|
||||
}
|
||||
@@ -72,7 +72,7 @@ static const struct hv_guid
|
||||
/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
|
||||
/* IDE */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
|
||||
0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
|
||||
}
|
||||
@@ -80,7 +80,7 @@ static const struct hv_guid
|
||||
/* 0E0B6031-5213-4934-818B-38D90CED39DB */
|
||||
/* Shutdown */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
|
||||
}
|
||||
@@ -88,7 +88,7 @@ static const struct hv_guid
|
||||
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
|
||||
/* TimeSync */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
|
||||
}
|
||||
@@ -96,7 +96,7 @@ static const struct hv_guid
|
||||
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
|
||||
/* Heartbeat */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
|
||||
}
|
||||
@@ -104,7 +104,7 @@ static const struct hv_guid
|
||||
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
|
||||
/* KVP */
|
||||
{
|
||||
.data = {
|
||||
.b = {
|
||||
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
|
||||
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
|
||||
}
|
||||
@@ -114,7 +114,7 @@ static const struct hv_guid
|
||||
|
||||
|
||||
/**
|
||||
* prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||
* vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message
|
||||
* @icmsghdrp: Pointer to msg header structure
|
||||
* @icmsg_negotiate: Pointer to negotiate message structure
|
||||
* @buf: Raw buffer channel data
|
||||
@@ -128,9 +128,8 @@ static const struct hv_guid
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
struct icmsg_negotiate *negop,
|
||||
u8 *buf)
|
||||
void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
struct icmsg_negotiate *negop, u8 *buf)
|
||||
{
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
icmsghdrp->icmsgsize = 0x10;
|
||||
@@ -156,119 +155,7 @@ void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
|
||||
negop->icmsg_vercnt = 1;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(prep_negotiate_resp);
|
||||
|
||||
/**
|
||||
* chn_cb_negotiate() - Default handler for non IDE/SCSI/NETWORK
|
||||
* Hyper-V requests
|
||||
* @context: Pointer to argument structure.
|
||||
*
|
||||
* Set up the default handler for non device driver specific requests
|
||||
* from Hyper-V. This stub responds to the default negotiate messages
|
||||
* that come in for every non IDE/SCSI/Network request.
|
||||
* This behavior is normally overwritten in the hv_utils driver. That
|
||||
* driver handles requests like graceful shutdown, heartbeats etc.
|
||||
*
|
||||
* Mainly used by Hyper-V drivers.
|
||||
*/
|
||||
void chn_cb_negotiate(void *context)
|
||||
{
|
||||
struct vmbus_channel *channel = context;
|
||||
u8 *buf;
|
||||
u32 buflen, recvlen;
|
||||
u64 requestid;
|
||||
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
if (channel->util_index >= 0) {
|
||||
/*
|
||||
* This is a properly initialized util channel.
|
||||
* Route this callback appropriately and setup state
|
||||
* so that we don't need to reroute again.
|
||||
*/
|
||||
if (hv_cb_utils[channel->util_index].callback != NULL) {
|
||||
/*
|
||||
* The util driver has established a handler for
|
||||
* this service; do the magic.
|
||||
*/
|
||||
channel->onchannel_callback =
|
||||
hv_cb_utils[channel->util_index].callback;
|
||||
(hv_cb_utils[channel->util_index].callback)(channel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buflen = PAGE_SIZE;
|
||||
buf = kmalloc(buflen, GFP_ATOMIC);
|
||||
|
||||
vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid);
|
||||
|
||||
if (recvlen > 0) {
|
||||
icmsghdrp = (struct icmsg_hdr *)&buf[
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
prep_negotiate_resp(icmsghdrp, negop, buf);
|
||||
|
||||
icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
|
||||
| ICMSGHDRFLAG_RESPONSE;
|
||||
|
||||
vmbus_sendpacket(channel, buf,
|
||||
recvlen, requestid,
|
||||
VM_PKT_DATA_INBAND, 0);
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
EXPORT_SYMBOL(chn_cb_negotiate);
|
||||
|
||||
/*
|
||||
* Function table used for message responses for non IDE/SCSI/Network type
|
||||
* messages. (Such as KVP/Shutdown etc)
|
||||
*/
|
||||
struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
|
||||
/* 0E0B6031-5213-4934-818B-38D90CED39DB */
|
||||
/* Shutdown */
|
||||
{
|
||||
.msg_type = HV_SHUTDOWN_MSG,
|
||||
.data = {
|
||||
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
|
||||
},
|
||||
.log_msg = "Shutdown channel functionality initialized"
|
||||
},
|
||||
|
||||
/* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */
|
||||
/* TimeSync */
|
||||
{
|
||||
.msg_type = HV_TIMESYNC_MSG,
|
||||
.data = {
|
||||
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
|
||||
},
|
||||
.log_msg = "Timesync channel functionality initialized"
|
||||
},
|
||||
/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
|
||||
/* Heartbeat */
|
||||
{
|
||||
.msg_type = HV_HEARTBEAT_MSG,
|
||||
.data = {
|
||||
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
|
||||
},
|
||||
.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
|
||||
},
|
||||
.log_msg = "KVP channel functionality initialized"
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(hv_cb_utils);
|
||||
EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
|
||||
|
||||
/*
|
||||
* alloc_channel - Allocate and initialize a vmbus channel object
|
||||
@@ -309,7 +196,7 @@ static void release_channel(struct work_struct *work)
|
||||
/*
|
||||
* free_channel - Release the resources used by the vmbus channel object
|
||||
*/
|
||||
void free_channel(struct vmbus_channel *channel)
|
||||
static void free_channel(struct vmbus_channel *channel)
|
||||
{
|
||||
|
||||
/*
|
||||
@@ -333,7 +220,7 @@ static void vmbus_process_rescind_offer(struct work_struct *work)
|
||||
struct vmbus_channel,
|
||||
work);
|
||||
|
||||
vmbus_child_device_unregister(channel->device_obj);
|
||||
vmbus_device_unregister(channel->device_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -348,7 +235,6 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
struct vmbus_channel *channel;
|
||||
bool fnew = true;
|
||||
int ret;
|
||||
int cnt;
|
||||
unsigned long flags;
|
||||
|
||||
/* The next possible work is rescind handling */
|
||||
@@ -358,12 +244,10 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
|
||||
|
||||
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.if_instance,
|
||||
&newchannel->offermsg.offer.if_instance,
|
||||
sizeof(struct hv_guid))) {
|
||||
if (!uuid_le_cmp(channel->offermsg.offer.if_type,
|
||||
newchannel->offermsg.offer.if_type) &&
|
||||
!uuid_le_cmp(channel->offermsg.offer.if_instance,
|
||||
newchannel->offermsg.offer.if_instance)) {
|
||||
fnew = false;
|
||||
break;
|
||||
}
|
||||
@@ -385,7 +269,7 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* We need to set the DeviceObject field before calling
|
||||
* vmbus_child_dev_add()
|
||||
*/
|
||||
newchannel->device_obj = vmbus_child_device_create(
|
||||
newchannel->device_obj = vmbus_device_create(
|
||||
&newchannel->offermsg.offer.if_type,
|
||||
&newchannel->offermsg.offer.if_instance,
|
||||
newchannel);
|
||||
@@ -395,7 +279,7 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* binding which eventually invokes the device driver's AddDevice()
|
||||
* method.
|
||||
*/
|
||||
ret = vmbus_child_device_register(newchannel->device_obj);
|
||||
ret = vmbus_device_register(newchannel->device_obj);
|
||||
if (ret != 0) {
|
||||
pr_err("unable to add child device object (relid %d)\n",
|
||||
newchannel->offermsg.child_relid);
|
||||
@@ -412,48 +296,26 @@ static void vmbus_process_offer(struct work_struct *work)
|
||||
* can cleanup properly
|
||||
*/
|
||||
newchannel->state = CHANNEL_OPEN_STATE;
|
||||
newchannel->util_index = -1; /* Invalid index */
|
||||
|
||||
/* Open IC channels */
|
||||
for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
|
||||
if (memcmp(&newchannel->offermsg.offer.if_type,
|
||||
&hv_cb_utils[cnt].data,
|
||||
sizeof(struct hv_guid)) == 0 &&
|
||||
vmbus_open(newchannel, 2 * PAGE_SIZE,
|
||||
2 * PAGE_SIZE, NULL, 0,
|
||||
chn_cb_negotiate,
|
||||
newchannel) == 0) {
|
||||
hv_cb_utils[cnt].channel = newchannel;
|
||||
newchannel->util_index = cnt;
|
||||
|
||||
pr_info("%s\n", hv_cb_utils[cnt].log_msg);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* vmbus_onoffer - Handler for channel offers from vmbus in parent partition.
|
||||
*
|
||||
* We ignore 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 object to process the offer synchronously
|
||||
*/
|
||||
static void vmbus_onoffer(struct vmbus_channel_message_header *hdr)
|
||||
{
|
||||
struct vmbus_channel_offer_channel *offer;
|
||||
struct vmbus_channel *newchannel;
|
||||
struct hv_guid *guidtype;
|
||||
struct hv_guid *guidinstance;
|
||||
uuid_le *guidtype;
|
||||
uuid_le *guidinstance;
|
||||
int i;
|
||||
int fsupported = 0;
|
||||
|
||||
offer = (struct vmbus_channel_offer_channel *)hdr;
|
||||
for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
|
||||
if (memcmp(&offer->offer.if_type,
|
||||
&supported_device_classes[i],
|
||||
sizeof(struct hv_guid)) == 0) {
|
||||
if (!uuid_le_cmp(offer->offer.if_type,
|
||||
supported_device_classes[i])) {
|
||||
fsupported = 1;
|
||||
break;
|
||||
}
|
||||
@@ -25,11 +25,12 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
#include <asm/hyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
|
||||
@@ -49,10 +50,6 @@ int vmbus_connect(void)
|
||||
struct vmbus_channel_initiate_contact *msg;
|
||||
unsigned long flags;
|
||||
|
||||
/* Make sure we are not connecting or connected */
|
||||
if (vmbus_connection.conn_state != DISCONNECTED)
|
||||
return -EISCONN;
|
||||
|
||||
/* Initialize the vmbus connection */
|
||||
vmbus_connection.conn_state = CONNECTING;
|
||||
vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
|
||||
@@ -214,8 +211,7 @@ struct vmbus_channel *relid2channel(u32 relid)
|
||||
static void process_chn_event(u32 relid)
|
||||
{
|
||||
struct vmbus_channel *channel;
|
||||
|
||||
/* ASSERT(relId > 0); */
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Find the channel based on this relid and invokes the
|
||||
@@ -223,11 +219,27 @@ static void process_chn_event(u32 relid)
|
||||
*/
|
||||
channel = relid2channel(relid);
|
||||
|
||||
if (channel) {
|
||||
channel->onchannel_callback(channel->channel_callback_context);
|
||||
} else {
|
||||
if (!channel) {
|
||||
pr_err("channel not found for relid - %u\n", relid);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* A channel once created is persistent even when there
|
||||
* is no driver handling the device. An unloading driver
|
||||
* sets the onchannel_callback to NULL under the
|
||||
* protection of the channel inbound_lock. Thus, checking
|
||||
* and invoking the driver specific callback takes care of
|
||||
* orderly unloading of the driver.
|
||||
*/
|
||||
|
||||
spin_lock_irqsave(&channel->inbound_lock, flags);
|
||||
if (channel->onchannel_callback != NULL)
|
||||
channel->onchannel_callback(channel->channel_callback_context);
|
||||
else
|
||||
pr_err("no channel callback for relid - %u\n", relid);
|
||||
|
||||
spin_unlock_irqrestore(&channel->inbound_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -248,16 +260,17 @@ void vmbus_on_event(unsigned long data)
|
||||
if (!recv_int_page[dword])
|
||||
continue;
|
||||
for (bit = 0; bit < 32; bit++) {
|
||||
if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) {
|
||||
if (sync_test_and_clear_bit(bit,
|
||||
(unsigned long *)&recv_int_page[dword])) {
|
||||
relid = (dword << 5) + bit;
|
||||
|
||||
if (relid == 0) {
|
||||
if (relid == 0)
|
||||
/*
|
||||
* Special case - vmbus
|
||||
* channel protocol msg
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
process_chn_event(relid);
|
||||
}
|
||||
}
|
||||
@@ -270,10 +283,25 @@ void vmbus_on_event(unsigned long data)
|
||||
int vmbus_post_msg(void *buffer, size_t buflen)
|
||||
{
|
||||
union hv_connection_id conn_id;
|
||||
int ret = 0;
|
||||
int retries = 0;
|
||||
|
||||
conn_id.asu32 = 0;
|
||||
conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID;
|
||||
return hv_post_message(conn_id, 1, buffer, buflen);
|
||||
|
||||
/*
|
||||
* hv_post_message() can have transient failures because of
|
||||
* insufficient resources. Retry the operation a couple of
|
||||
* times before giving up.
|
||||
*/
|
||||
while (retries < 3) {
|
||||
ret = hv_post_message(conn_id, 1, buffer, buflen);
|
||||
if (ret != HV_STATUS_INSUFFICIENT_BUFFERS)
|
||||
return ret;
|
||||
retries++;
|
||||
msleep(100);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -25,8 +25,8 @@
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
#include <asm/hyperv.h>
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
/* The one and only */
|
||||
@@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
u64 hv_status = 0;
|
||||
u64 input_address = (input) ? virt_to_phys(input) : 0;
|
||||
u64 output_address = (output) ? virt_to_phys(output) : 0;
|
||||
volatile void *hypercall_page = hv_context.hypercall_page;
|
||||
void *hypercall_page = hv_context.hypercall_page;
|
||||
|
||||
__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
|
||||
__asm__ __volatile__("call *%3" : "=a" (hv_status) :
|
||||
@@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
u64 output_address = (output) ? virt_to_phys(output) : 0;
|
||||
u32 output_address_hi = output_address >> 32;
|
||||
u32 output_address_lo = output_address & 0xFFFFFFFF;
|
||||
volatile void *hypercall_page = hv_context.hypercall_page;
|
||||
void *hypercall_page = hv_context.hypercall_page;
|
||||
|
||||
__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
|
||||
"=a"(hv_status_lo) : "d" (control_hi),
|
||||
@@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output)
|
||||
*/
|
||||
int hv_init(void)
|
||||
{
|
||||
int ret = 0;
|
||||
int max_leaf;
|
||||
union hv_x64_msr_hypercall_contents hypercall_msr;
|
||||
void *virtaddr = NULL;
|
||||
@@ -164,11 +163,7 @@ int hv_init(void)
|
||||
goto cleanup;
|
||||
|
||||
max_leaf = query_hypervisor_info();
|
||||
/* HvQueryHypervisorFeatures(maxLeaf); */
|
||||
|
||||
/*
|
||||
* We only support running on top of Hyper-V
|
||||
*/
|
||||
rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
|
||||
|
||||
if (hv_context.guestid != 0)
|
||||
@@ -181,10 +176,6 @@ int hv_init(void)
|
||||
/* See if the hypercall page is already set */
|
||||
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
|
||||
|
||||
/*
|
||||
* Allocate the hypercall page memory
|
||||
* virtaddr = osd_page_alloc(1);
|
||||
*/
|
||||
virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
|
||||
|
||||
if (!virtaddr)
|
||||
@@ -222,7 +213,7 @@ int hv_init(void)
|
||||
hv_context.signal_event_param->flag_number = 0;
|
||||
hv_context.signal_event_param->rsvdz = 0;
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
if (virtaddr) {
|
||||
@@ -233,8 +224,8 @@ cleanup:
|
||||
|
||||
vfree(virtaddr);
|
||||
}
|
||||
ret = -1;
|
||||
return ret;
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -378,7 +369,7 @@ void hv_synic_init(void *irqarg)
|
||||
shared_sint.as_uint64 = 0;
|
||||
shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
|
||||
shared_sint.masked = false;
|
||||
shared_sint.auto_eoi = true;
|
||||
shared_sint.auto_eoi = false;
|
||||
|
||||
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <linux/nls.h>
|
||||
#include <linux/connector.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hv_kvp.h"
|
||||
|
||||
|
||||
@@ -44,21 +44,24 @@
|
||||
static struct {
|
||||
bool active; /* transaction status - active or not */
|
||||
int recv_len; /* number of bytes received. */
|
||||
int index; /* current index */
|
||||
struct vmbus_channel *recv_channel; /* chn we got the request */
|
||||
u64 recv_req_id; /* request ID. */
|
||||
} kvp_transaction;
|
||||
|
||||
static int kvp_send_key(int index);
|
||||
static void kvp_send_key(struct work_struct *dummy);
|
||||
|
||||
#define TIMEOUT_FIRED 1
|
||||
|
||||
static void kvp_respond_to_host(char *key, char *value, int error);
|
||||
static void kvp_work_func(struct work_struct *dummy);
|
||||
static void kvp_register(void);
|
||||
|
||||
static DECLARE_DELAYED_WORK(kvp_work, kvp_work_func);
|
||||
static DECLARE_WORK(kvp_sendkey_work, kvp_send_key);
|
||||
|
||||
static struct cb_id kvp_id = { CN_KVP_IDX, CN_KVP_VAL };
|
||||
static const char kvp_name[] = "kvp_kernel_module";
|
||||
static int timeout_fired;
|
||||
static u8 *recv_buffer;
|
||||
/*
|
||||
* Register the kernel component with the user-level daemon.
|
||||
@@ -90,8 +93,7 @@ kvp_work_func(struct work_struct *dummy)
|
||||
* If the timer fires, the user-mode component has not responded;
|
||||
* process the pending transaction.
|
||||
*/
|
||||
kvp_respond_to_host("Unknown key", "Guest timed out", timeout_fired);
|
||||
timeout_fired = 1;
|
||||
kvp_respond_to_host("Unknown key", "Guest timed out", TIMEOUT_FIRED);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -121,10 +123,11 @@ kvp_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kvp_send_key(int index)
|
||||
static void
|
||||
kvp_send_key(struct work_struct *dummy)
|
||||
{
|
||||
struct cn_msg *msg;
|
||||
int index = kvp_transaction.index;
|
||||
|
||||
msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
|
||||
|
||||
@@ -136,9 +139,8 @@ kvp_send_key(int index)
|
||||
msg->len = sizeof(struct hv_ku_msg);
|
||||
cn_netlink_send(msg, 0, GFP_ATOMIC);
|
||||
kfree(msg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -177,6 +179,15 @@ kvp_respond_to_host(char *key, char *value, int error)
|
||||
channel = kvp_transaction.recv_channel;
|
||||
req_id = kvp_transaction.recv_req_id;
|
||||
|
||||
kvp_transaction.active = false;
|
||||
|
||||
if (channel->onchannel_callback == NULL)
|
||||
/*
|
||||
* We have raced with util driver being unloaded;
|
||||
* silently return.
|
||||
*/
|
||||
return;
|
||||
|
||||
icmsghdrp = (struct icmsg_hdr *)
|
||||
&recv_buffer[sizeof(struct vmbuspipe_hdr)];
|
||||
kvp_msg = (struct hv_kvp_msg *)
|
||||
@@ -217,7 +228,6 @@ response_done:
|
||||
vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
|
||||
VM_PKT_DATA_INBAND, 0);
|
||||
|
||||
kvp_transaction.active = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -243,10 +253,6 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
struct icmsg_negotiate *negop = NULL;
|
||||
|
||||
|
||||
if (kvp_transaction.active)
|
||||
return;
|
||||
|
||||
|
||||
vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
|
||||
|
||||
if (recvlen > 0) {
|
||||
@@ -254,7 +260,7 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer);
|
||||
} else {
|
||||
kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
@@ -282,6 +288,7 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
kvp_transaction.recv_channel = channel;
|
||||
kvp_transaction.recv_req_id = requestid;
|
||||
kvp_transaction.active = true;
|
||||
kvp_transaction.index = kvp_data->index;
|
||||
|
||||
/*
|
||||
* Get the information from the
|
||||
@@ -292,8 +299,8 @@ void hv_kvp_onchannelcallback(void *context)
|
||||
* Set a timeout to deal with
|
||||
* user-mode not responding.
|
||||
*/
|
||||
kvp_send_key(kvp_data->index);
|
||||
schedule_delayed_work(&kvp_work, 100);
|
||||
schedule_work(&kvp_sendkey_work);
|
||||
schedule_delayed_work(&kvp_work, 5*HZ);
|
||||
|
||||
return;
|
||||
|
||||
@@ -312,16 +319,14 @@ callback_done:
|
||||
}
|
||||
|
||||
int
|
||||
hv_kvp_init(void)
|
||||
hv_kvp_init(struct hv_util_service *srv)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = cn_add_callback(&kvp_id, kvp_name, kvp_cn_callback);
|
||||
if (err)
|
||||
return err;
|
||||
recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!recv_buffer)
|
||||
return -ENOMEM;
|
||||
recv_buffer = srv->recv_buffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -330,5 +335,5 @@ void hv_kvp_deinit(void)
|
||||
{
|
||||
cn_del_callback(&kvp_id);
|
||||
cancel_delayed_work_sync(&kvp_work);
|
||||
kfree(recv_buffer);
|
||||
cancel_work_sync(&kvp_sendkey_work);
|
||||
}
|
||||
@@ -175,7 +175,7 @@ struct hv_kvp_msg {
|
||||
struct hv_kvp_msg_enumerate kvp_data;
|
||||
};
|
||||
|
||||
int hv_kvp_init(void);
|
||||
int hv_kvp_init(struct hv_util_service *);
|
||||
void hv_kvp_deinit(void);
|
||||
void hv_kvp_onchannelcallback(void *);
|
||||
|
||||
@@ -26,15 +26,31 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hv_kvp.h"
|
||||
|
||||
static u8 *shut_txf_buf;
|
||||
static u8 *time_txf_buf;
|
||||
static u8 *hbeat_txf_buf;
|
||||
|
||||
static void shutdown_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_shutdown = {
|
||||
.util_cb = shutdown_onchannelcallback,
|
||||
};
|
||||
|
||||
static void timesync_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_timesynch = {
|
||||
.util_cb = timesync_onchannelcallback,
|
||||
};
|
||||
|
||||
static void heartbeat_onchannelcallback(void *context);
|
||||
static struct hv_util_service util_heartbeat = {
|
||||
.util_cb = heartbeat_onchannelcallback,
|
||||
};
|
||||
|
||||
static struct hv_util_service util_kvp = {
|
||||
.util_cb = hv_kvp_onchannelcallback,
|
||||
.util_init = hv_kvp_init,
|
||||
.util_deinit = hv_kvp_deinit,
|
||||
};
|
||||
|
||||
static void shutdown_onchannelcallback(void *context)
|
||||
{
|
||||
@@ -42,6 +58,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
u32 recvlen;
|
||||
u64 requestid;
|
||||
u8 execute_shutdown = false;
|
||||
u8 *shut_txf_buf = util_shutdown.recv_buffer;
|
||||
|
||||
struct shutdown_msg_data *shutdown_msg;
|
||||
|
||||
@@ -56,7 +73,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf);
|
||||
} else {
|
||||
shutdown_msg =
|
||||
(struct shutdown_msg_data *)&shut_txf_buf[
|
||||
@@ -91,7 +108,7 @@ static void shutdown_onchannelcallback(void *context)
|
||||
}
|
||||
|
||||
if (execute_shutdown == true)
|
||||
orderly_poweroff(false);
|
||||
orderly_poweroff(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -108,6 +125,24 @@ static inline void do_adj_guesttime(u64 hosttime)
|
||||
do_settimeofday(&host_ts);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the host time in a process context.
|
||||
*/
|
||||
|
||||
struct adj_time_work {
|
||||
struct work_struct work;
|
||||
u64 host_time;
|
||||
};
|
||||
|
||||
static void hv_set_host_time(struct work_struct *work)
|
||||
{
|
||||
struct adj_time_work *wrk;
|
||||
|
||||
wrk = container_of(work, struct adj_time_work, work);
|
||||
do_adj_guesttime(wrk->host_time);
|
||||
kfree(wrk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Synchronize time with host after reboot, restore, etc.
|
||||
*
|
||||
@@ -121,17 +156,26 @@ static inline void do_adj_guesttime(u64 hosttime)
|
||||
*/
|
||||
static inline void adj_guesttime(u64 hosttime, u8 flags)
|
||||
{
|
||||
struct adj_time_work *wrk;
|
||||
static s32 scnt = 50;
|
||||
|
||||
wrk = kmalloc(sizeof(struct adj_time_work), GFP_ATOMIC);
|
||||
if (wrk == NULL)
|
||||
return;
|
||||
|
||||
wrk->host_time = hosttime;
|
||||
if ((flags & ICTIMESYNCFLAG_SYNC) != 0) {
|
||||
do_adj_guesttime(hosttime);
|
||||
INIT_WORK(&wrk->work, hv_set_host_time);
|
||||
schedule_work(&wrk->work);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) {
|
||||
scnt--;
|
||||
do_adj_guesttime(hosttime);
|
||||
}
|
||||
INIT_WORK(&wrk->work, hv_set_host_time);
|
||||
schedule_work(&wrk->work);
|
||||
} else
|
||||
kfree(wrk);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,6 +188,7 @@ static void timesync_onchannelcallback(void *context)
|
||||
u64 requestid;
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct ictimesync_data *timedatap;
|
||||
u8 *time_txf_buf = util_timesynch.recv_buffer;
|
||||
|
||||
vmbus_recvpacket(channel, time_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@@ -153,7 +198,7 @@ static void timesync_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf);
|
||||
} else {
|
||||
timedatap = (struct ictimesync_data *)&time_txf_buf[
|
||||
sizeof(struct vmbuspipe_hdr) +
|
||||
@@ -182,6 +227,7 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
u64 requestid;
|
||||
struct icmsg_hdr *icmsghdrp;
|
||||
struct heartbeat_msg_data *heartbeat_msg;
|
||||
u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
|
||||
|
||||
vmbus_recvpacket(channel, hbeat_txf_buf,
|
||||
PAGE_SIZE, &recvlen, &requestid);
|
||||
@@ -191,7 +237,7 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
sizeof(struct vmbuspipe_hdr)];
|
||||
|
||||
if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
|
||||
prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
|
||||
vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf);
|
||||
} else {
|
||||
heartbeat_msg =
|
||||
(struct heartbeat_msg_data *)&hbeat_txf_buf[
|
||||
@@ -210,92 +256,94 @@ static void heartbeat_onchannelcallback(void *context)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pci_device_id __initconst
|
||||
hv_utils_pci_table[] __maybe_unused = {
|
||||
{ PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
|
||||
{ 0 }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
|
||||
static int util_probe(struct hv_device *dev,
|
||||
const struct hv_vmbus_device_id *dev_id)
|
||||
{
|
||||
struct hv_util_service *srv =
|
||||
(struct hv_util_service *)dev_id->driver_data;
|
||||
int ret;
|
||||
|
||||
srv->recv_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (!srv->recv_buffer)
|
||||
return -ENOMEM;
|
||||
if (srv->util_init) {
|
||||
ret = srv->util_init(srv);
|
||||
if (ret) {
|
||||
ret = -ENODEV;
|
||||
goto error1;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct dmi_system_id __initconst
|
||||
hv_utils_dmi_table[] __maybe_unused = {
|
||||
{
|
||||
.ident = "Hyper-V",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
|
||||
},
|
||||
},
|
||||
ret = vmbus_open(dev->channel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0,
|
||||
srv->util_cb, dev->channel);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
hv_set_drvdata(dev, srv);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (srv->util_deinit)
|
||||
srv->util_deinit();
|
||||
error1:
|
||||
kfree(srv->recv_buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int util_remove(struct hv_device *dev)
|
||||
{
|
||||
struct hv_util_service *srv = hv_get_drvdata(dev);
|
||||
|
||||
vmbus_close(dev->channel);
|
||||
if (srv->util_deinit)
|
||||
srv->util_deinit();
|
||||
kfree(srv->recv_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct hv_vmbus_device_id id_table[] = {
|
||||
/* Shutdown guid */
|
||||
{ VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
|
||||
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB)
|
||||
.driver_data = (unsigned long)&util_shutdown },
|
||||
/* Time synch guid */
|
||||
{ VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
|
||||
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf)
|
||||
.driver_data = (unsigned long)&util_timesynch },
|
||||
/* Heartbeat guid */
|
||||
{ VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
|
||||
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d)
|
||||
.driver_data = (unsigned long)&util_heartbeat },
|
||||
/* KVP guid */
|
||||
{ VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
|
||||
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6)
|
||||
.driver_data = (unsigned long)&util_kvp },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
|
||||
|
||||
MODULE_DEVICE_TABLE(vmbus, id_table);
|
||||
|
||||
/* The one and only one */
|
||||
static struct hv_driver util_drv = {
|
||||
.name = "hv_util",
|
||||
.id_table = id_table,
|
||||
.probe = util_probe,
|
||||
.remove = util_remove,
|
||||
};
|
||||
|
||||
static int __init init_hyperv_utils(void)
|
||||
{
|
||||
pr_info("Registering HyperV Utility Driver\n");
|
||||
|
||||
if (hv_kvp_init())
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
if (!dmi_check_system(hv_utils_dmi_table))
|
||||
return -ENODEV;
|
||||
|
||||
shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
|
||||
if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
|
||||
pr_info("Unable to allocate memory for receive buffer\n");
|
||||
kfree(shut_txf_buf);
|
||||
kfree(time_txf_buf);
|
||||
kfree(hbeat_txf_buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
|
||||
|
||||
hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
|
||||
|
||||
return 0;
|
||||
return vmbus_driver_register(&util_drv);
|
||||
}
|
||||
|
||||
static void exit_hyperv_utils(void)
|
||||
{
|
||||
pr_info("De-Registered HyperV Utility Driver\n");
|
||||
|
||||
if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
|
||||
|
||||
if (hv_cb_utils[HV_KVP_MSG].channel != NULL)
|
||||
hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
|
||||
&chn_cb_negotiate;
|
||||
hv_cb_utils[HV_KVP_MSG].callback = NULL;
|
||||
|
||||
hv_kvp_deinit();
|
||||
|
||||
kfree(shut_txf_buf);
|
||||
kfree(time_txf_buf);
|
||||
kfree(hbeat_txf_buf);
|
||||
vmbus_driver_unregister(&util_drv);
|
||||
}
|
||||
|
||||
module_init(init_hyperv_utils);
|
||||
@@ -28,8 +28,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <asm/sync_bitops.h>
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
/*
|
||||
* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
|
||||
@@ -451,8 +450,8 @@ enum {
|
||||
/* #define VMBUS_PORT_ID 11 */
|
||||
|
||||
/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
|
||||
static const struct hv_guid VMBUS_SERVICE_ID = {
|
||||
.data = {
|
||||
static const uuid_le VMBUS_SERVICE_ID = {
|
||||
.b = {
|
||||
0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
|
||||
0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
|
||||
},
|
||||
@@ -530,8 +529,6 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
|
||||
|
||||
u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
|
||||
|
||||
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
|
||||
|
||||
void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
|
||||
struct hv_ring_buffer_debug_info *debug_info);
|
||||
|
||||
@@ -601,12 +598,12 @@ extern struct vmbus_connection vmbus_connection;
|
||||
|
||||
/* General vmbus interface */
|
||||
|
||||
struct hv_device *vmbus_child_device_create(struct hv_guid *type,
|
||||
struct hv_guid *instance,
|
||||
struct hv_device *vmbus_device_create(uuid_le *type,
|
||||
uuid_le *instance,
|
||||
struct vmbus_channel *channel);
|
||||
|
||||
int vmbus_child_device_register(struct hv_device *child_device_obj);
|
||||
void vmbus_child_device_unregister(struct hv_device *device_obj);
|
||||
int vmbus_device_register(struct hv_device *child_device_obj);
|
||||
void vmbus_device_unregister(struct hv_device *device_obj);
|
||||
|
||||
/* static void */
|
||||
/* VmbusChildDeviceDestroy( */
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include "hyperv.h"
|
||||
#include "hyperv_vmbus.h"
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
|
||||
|
||||
/* Amount of space to write to */
|
||||
#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
|
||||
#define BYTES_AVAIL_TO_WRITE(r, w, z) \
|
||||
((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
|
||||
|
||||
|
||||
/*
|
||||
@@ -171,37 +172,6 @@ hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
|
||||
return (u64)ring_info->ring_buffer->write_index << 32;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hv_dump_ring_info()
|
||||
*
|
||||
* Dump out to console the ring buffer info
|
||||
*
|
||||
*/
|
||||
void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
|
||||
{
|
||||
u32 bytes_avail_towrite;
|
||||
u32 bytes_avail_toread;
|
||||
|
||||
hv_get_ringbuffer_availbytes(ring_info,
|
||||
&bytes_avail_toread,
|
||||
&bytes_avail_towrite);
|
||||
|
||||
DPRINT(VMBUS,
|
||||
DEBUG_RING_LVL,
|
||||
"%s <<ringinfo %p buffer %p avail write %u "
|
||||
"avail read %u read idx %u write idx %u>>",
|
||||
prefix,
|
||||
ring_info,
|
||||
ring_info->ring_buffer->buffer,
|
||||
bytes_avail_towrite,
|
||||
bytes_avail_toread,
|
||||
ring_info->ring_buffer->read_index,
|
||||
ring_info->ring_buffer->write_index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* hv_copyfrom_ringbuffer()
|
||||
@@ -390,7 +360,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
|
||||
/* is empty since the read index == write index */
|
||||
if (bytes_avail_towrite <= totalbytes_towrite) {
|
||||
spin_unlock_irqrestore(&outring_info->ring_lock, flags);
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Write to the ring buffer */
|
||||
@@ -450,7 +420,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
|
||||
|
||||
spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
|
||||
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Convert to byte offset */
|
||||
@@ -496,7 +466,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
|
||||
if (bytes_avail_toread < buflen) {
|
||||
spin_unlock_irqrestore(&inring_info->ring_lock, flags);
|
||||
|
||||
return -1;
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
next_read_location =
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,8 +46,6 @@ source "drivers/staging/wlan-ng/Kconfig"
|
||||
|
||||
source "drivers/staging/echo/Kconfig"
|
||||
|
||||
|
||||
|
||||
source "drivers/staging/comedi/Kconfig"
|
||||
|
||||
source "drivers/staging/olpc_dcon/Kconfig"
|
||||
@@ -66,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig"
|
||||
|
||||
source "drivers/staging/rts_pstor/Kconfig"
|
||||
|
||||
source "drivers/staging/rts5139/Kconfig"
|
||||
|
||||
source "drivers/staging/frontier/Kconfig"
|
||||
|
||||
source "drivers/staging/pohmelfs/Kconfig"
|
||||
|
||||
@@ -15,8 +15,6 @@ obj-$(CONFIG_USBIP_CORE) += usbip/
|
||||
obj-$(CONFIG_W35UND) += winbond/
|
||||
obj-$(CONFIG_PRISM2_USB) += wlan-ng/
|
||||
obj-$(CONFIG_ECHO) += echo/
|
||||
|
||||
|
||||
obj-$(CONFIG_COMEDI) += comedi/
|
||||
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
|
||||
obj-$(CONFIG_ASUS_OLED) += asus_oled/
|
||||
@@ -26,6 +24,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
|
||||
obj-$(CONFIG_RTL8192E) += rtl8192e/
|
||||
obj-$(CONFIG_R8712U) += rtl8712/
|
||||
obj-$(CONFIG_RTS_PSTOR) += rts_pstor/
|
||||
obj-$(CONFIG_RTS5139) += rts5139/
|
||||
obj-$(CONFIG_SPECTRA) += spectra/
|
||||
obj-$(CONFIG_TRANZPORT) += frontier/
|
||||
obj-$(CONFIG_POHMELFS) += pohmelfs/
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include "altera.h"
|
||||
#include "altera-exprt.h"
|
||||
#include "altera-jtag.h"
|
||||
@@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p,
|
||||
act_proc_attribute =
|
||||
(p[proc_table + (13 * act_proc_id) + 8] & 0x03);
|
||||
|
||||
procptr = (struct altera_procinfo *)
|
||||
procptr =
|
||||
kzalloc(sizeof(struct altera_procinfo),
|
||||
GFP_KERNEL);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user