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:
Linus Torvalds
2011-10-26 15:39:02 +02:00
725 changed files with 104276 additions and 180820 deletions
+13 -1
View File
@@ -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>
+1
View File
@@ -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
+2
View File
@@ -132,6 +132,8 @@ source "drivers/iommu/Kconfig"
source "drivers/virt/Kconfig"
source "drivers/hv/Kconfig"
source "drivers/devfreq/Kconfig"
endmenu
+1
View File
@@ -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/
-613
View File
File diff suppressed because it is too large Load Diff
+14
View File
@@ -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.
+7
View File
@@ -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;
}
/*
+8 -17
View File
@@ -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 = &timesync_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
+2 -2
View File
@@ -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"
+1 -2
View File
@@ -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/
+2 -1
View File
@@ -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