aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/hv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/hv')
-rw-r--r--drivers/staging/hv/blkvsc_drv.c48
-rw-r--r--drivers/staging/hv/channel.c100
-rw-r--r--drivers/staging/hv/channel_mgmt.c50
-rw-r--r--drivers/staging/hv/connection.c20
-rw-r--r--drivers/staging/hv/hv.c19
-rw-r--r--drivers/staging/hv/hv_mouse.c315
-rw-r--r--drivers/staging/hv/hv_util.c63
-rw-r--r--drivers/staging/hv/hyperv.h45
-rw-r--r--drivers/staging/hv/hyperv_net.h1
-rw-r--r--drivers/staging/hv/hyperv_vmbus.h8
-rw-r--r--drivers/staging/hv/netvsc.c60
-rw-r--r--drivers/staging/hv/netvsc_drv.c60
-rw-r--r--drivers/staging/hv/ring_buffer.c6
-rw-r--r--drivers/staging/hv/rndis_filter.c49
-rw-r--r--drivers/staging/hv/storvsc.c42
-rw-r--r--drivers/staging/hv/storvsc_drv.c75
-rw-r--r--drivers/staging/hv/tools/hv_kvp_daemon.c19
-rw-r--r--drivers/staging/hv/vmbus_drv.c227
18 files changed, 480 insertions, 727 deletions
diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c
index d286b2223181..2b41eb677b2f 100644
--- a/drivers/staging/hv/blkvsc_drv.c
+++ b/drivers/staging/hv/blkvsc_drv.c
@@ -109,15 +109,6 @@ struct block_device_context {
int users;
};
-static const char *drv_name = "blkvsc";
-
-/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
-static const struct hv_guid dev_type = {
- .data = {
- 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
- 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
- }
-};
/*
* There is a circular dependency involving blkvsc_request_completion()
@@ -155,13 +146,13 @@ static int blkvsc_device_add(struct hv_device *device,
* id. For IDE devices, the device instance id is formatted as
* <bus id> * - <device id> - 8899 - 000000000000.
*/
- device_info->path_id = device->dev_instance.data[3] << 24 |
- device->dev_instance.data[2] << 16 |
- device->dev_instance.data[1] << 8 |
- device->dev_instance.data[0];
+ device_info->path_id = device->dev_instance.b[3] << 24 |
+ device->dev_instance.b[2] << 16 |
+ device->dev_instance.b[1] << 8 |
+ device->dev_instance.b[0];
- device_info->target_id = device->dev_instance.data[5] << 8 |
- device->dev_instance.data[4];
+ device_info->target_id = device->dev_instance.b[5] << 8 |
+ device->dev_instance.b[4];
return ret;
}
@@ -734,7 +725,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev,
} else {
ret = blkvsc_submit_request(blkvsc_req,
blkvsc_request_completion);
- if (ret == -1) {
+ if (ret == -EAGAIN) {
pending = 1;
list_add_tail(&blkvsc_req->pend_entry,
&blkdev->pending_list);
@@ -802,10 +793,19 @@ static void blkvsc_request(struct request_queue *queue)
}
}
+static const struct hv_vmbus_device_id id_table[] = {
+ /* IDE guid */
+ { VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+ 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) },
+ { },
+};
+MODULE_DEVICE_TABLE(vmbus, id_table);
/* The one and only one */
static struct hv_driver blkvsc_drv = {
+ .name = "blkvsc",
+ .id_table = id_table,
.probe = blkvsc_probe,
.remove = blkvsc_remove,
.shutdown = blkvsc_shutdown,
@@ -824,25 +824,13 @@ static const struct block_device_operations block_ops = {
*/
static int blkvsc_drv_init(void)
{
- struct hv_driver *drv = &blkvsc_drv;
- int ret;
-
BUILD_BUG_ON(sizeof(sector_t) != 8);
-
- memcpy(&drv->dev_type, &dev_type, sizeof(struct hv_guid));
- drv->driver.name = drv_name;
-
- /* The driver belongs to vmbus */
- ret = vmbus_child_driver_register(&drv->driver);
-
- return ret;
+ return vmbus_driver_register(&blkvsc_drv);
}
-
static void blkvsc_drv_exit(void)
{
-
- vmbus_child_driver_unregister(&blkvsc_drv.driver);
+ vmbus_driver_unregister(&blkvsc_drv);
}
/*
diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c
index 455f47a891f1..ac92c1f99261 100644
--- a/drivers/staging/hv/channel.c
+++ b/drivers/staging/hv/channel.c
@@ -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,57 +233,12 @@ 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
*/
static int create_gpadl_header(void *kbuffer, u32 size,
@@ -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)
@@ -863,7 +811,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer,
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;
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c
index bf011f3fb851..11beb41c373e 100644
--- a/drivers/staging/hv/channel_mgmt.c
+++ b/drivers/staging/hv/channel_mgmt.c
@@ -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
}
@@ -231,7 +231,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
/* Shutdown */
{
.msg_type = HV_SHUTDOWN_MSG,
- .data = {
+ .data.b = {
0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
},
@@ -242,7 +242,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
/* TimeSync */
{
.msg_type = HV_TIMESYNC_MSG,
- .data = {
+ .data.b = {
0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
},
@@ -252,7 +252,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
/* Heartbeat */
{
.msg_type = HV_HEARTBEAT_MSG,
- .data = {
+ .data.b = {
0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
},
@@ -261,7 +261,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = {
/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
/* KVP */
{
- .data = {
+ .data.b = {
0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6
},
@@ -358,12 +358,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;
}
@@ -416,9 +414,8 @@ static void vmbus_process_offer(struct work_struct *work)
/* Open IC channels */
for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
- if (memcmp(&newchannel->offermsg.offer.if_type,
- &hv_cb_utils[cnt].data,
- sizeof(struct hv_guid)) == 0 &&
+ if (!uuid_le_cmp(newchannel->offermsg.offer.if_type,
+ hv_cb_utils[cnt].data) &&
vmbus_open(newchannel, 2 * PAGE_SIZE,
2 * PAGE_SIZE, NULL, 0,
chn_cb_negotiate,
@@ -444,16 +441,15 @@ 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;
}
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c
index e6b40392e08d..a88ad7072566 100644
--- a/drivers/staging/hv/connection.c
+++ b/drivers/staging/hv/connection.c
@@ -25,6 +25,7 @@
#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>
@@ -215,8 +216,6 @@ static void process_chn_event(u32 relid)
{
struct vmbus_channel *channel;
- /* ASSERT(relId > 0); */
-
/*
* Find the channel based on this relid and invokes the
* channel callback to process the event
@@ -270,10 +269,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;
}
/*
diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c
index 824f81679ae8..736794ef7872 100644
--- a/drivers/staging/hv/hv.c
+++ b/drivers/staging/hv/hv.c
@@ -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;
}
/*
diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c
index d957fc228019..090736af8dff 100644
--- a/drivers/staging/hv/hv_mouse.c
+++ b/drivers/staging/hv/hv_mouse.c
@@ -22,8 +22,6 @@
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/hiddev.h>
-#include <linux/pci.h>
-#include <linux/dmi.h>
#include "hyperv.h"
@@ -54,7 +52,7 @@ struct hv_input_dev_info {
(SYNTHHID_INPUT_VERSION_MAJOR << 16))
-#pragma pack(push,1)
+#pragma pack(push, 1)
/*
* Message types in the synthetic input protocol
*/
@@ -120,8 +118,8 @@ struct synthhid_input_report {
#pragma pack(pop)
-#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE
-#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE
+#define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE)
+#define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE)
#define NBITS(x) (((x)/BITS_PER_LONG)+1)
@@ -175,19 +173,13 @@ struct mousevsc_dev {
struct hv_input_dev_info hid_dev_info;
};
-
-static const char *driver_name = "mousevsc";
-
-/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
-static const struct hv_guid mouse_guid = {
- .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
- 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}
+struct input_device_context {
+ struct hv_device *device_ctx;
+ struct hid_device *hid_device;
+ struct hv_input_dev_info device_info;
+ int connected;
};
-static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info);
-static void inputreport_callback(struct hv_device *dev, void *packet, u32 len);
-static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len);
-
static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
{
struct mousevsc_dev *input_dev;
@@ -344,7 +336,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (!input_device->hid_desc) {
pr_err("unable to allocate hid descriptor - size %d", desc->bLength);
- goto Cleanup;
+ goto cleanup;
}
memcpy(input_device->hid_desc, desc, desc->bLength);
@@ -357,7 +349,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (!input_device->report_desc) {
pr_err("unable to allocate report descriptor - size %d",
input_device->report_desc_size);
- goto Cleanup;
+ goto cleanup;
}
memcpy(input_device->report_desc,
@@ -384,7 +376,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
if (ret != 0) {
pr_err("unable to send synthhid device info ack - ret %d",
ret);
- goto Cleanup;
+ goto cleanup;
}
input_device->device_wait_condition = 1;
@@ -392,7 +384,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
return;
-Cleanup:
+cleanup:
kfree(input_device->hid_desc);
input_device->hid_desc = NULL;
@@ -408,6 +400,7 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device,
struct synthhid_input_report *input_report)
{
struct hv_driver *input_drv;
+ struct input_device_context *input_dev_ctx;
if (!input_device->init_complete) {
pr_info("Initialization incomplete...ignoring input_report msg");
@@ -416,9 +409,11 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device,
input_drv = drv_to_hv_drv(input_device->device->device.driver);
- inputreport_callback(input_device->device,
- input_report->buffer,
- input_report->header.size);
+ input_dev_ctx = dev_get_drvdata(&input_device->device->device);
+
+ hid_input_report(input_dev_ctx->hid_device,
+ HID_INPUT_REPORT, input_report->buffer, input_report->header.size, 1);
+
}
static void mousevsc_on_receive(struct hv_device *device,
@@ -509,22 +504,22 @@ static void mousevsc_on_channel_callback(void *context)
desc = (struct vmpacket_descriptor *)buffer;
switch (desc->type) {
- case VM_PKT_COMP:
- mousevsc_on_send_completion(
- device, desc);
- break;
-
- case VM_PKT_DATA_INBAND:
- mousevsc_on_receive(
- device, desc);
- break;
-
- default:
- pr_err("unhandled packet type %d, tid %llx len %d\n",
- desc->type,
- req_id,
- bytes_recvd);
- break;
+ case VM_PKT_COMP:
+ mousevsc_on_send_completion(
+ device, desc);
+ break;
+
+ case VM_PKT_DATA_INBAND:
+ mousevsc_on_receive(
+ device, desc);
+ break;
+
+ default:
+ pr_err("unhandled packet type %d, tid %llx len %d\n",
+ desc->type,
+ req_id,
+ bytes_recvd);
+ break;
}
/* reset */
@@ -547,7 +542,7 @@ static void mousevsc_on_channel_callback(void *context)
}
break;
}
- } else if (ret == -2) {
+ } else if (ret == -ENOBUFS) {
/* Handle large packet */
bufferlen = bytes_recvd;
buffer = kzalloc(bytes_recvd, GFP_KERNEL);
@@ -611,7 +606,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
if (ret != 0) {
pr_err("unable to send synthhid protocol request.");
- goto Cleanup;
+ goto cleanup;
}
input_dev->protocol_wait_condition = 0;
@@ -619,7 +614,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
input_dev->protocol_wait_condition, msecs_to_jiffies(1000));
if (input_dev->protocol_wait_condition == 0) {
ret = -ETIMEDOUT;
- goto Cleanup;
+ goto cleanup;
}
response = &input_dev->protocol_resp;
@@ -628,7 +623,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
pr_err("synthhid protocol request failed (version %d)",
SYNTHHID_INPUT_VERSION);
ret = -1;
- goto Cleanup;
+ goto cleanup;
}
input_dev->device_wait_condition = 0;
@@ -636,7 +631,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
input_dev->device_wait_condition, msecs_to_jiffies(1000));
if (input_dev->device_wait_condition == 0) {
ret = -ETIMEDOUT;
- goto Cleanup;
+ goto cleanup;
}
/*
@@ -648,12 +643,74 @@ static int mousevsc_connect_to_vsp(struct hv_device *device)
else
ret = -1;
-Cleanup:
+cleanup:
put_input_device(device);
return ret;
}
+static int mousevsc_hid_open(struct hid_device *hid)
+{
+ return 0;
+}
+
+static void mousevsc_hid_close(struct hid_device *hid)
+{
+}
+
+static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
+{
+ struct input_device_context *input_device_ctx =
+ dev_get_drvdata(&dev->device);
+ struct hid_device *hid_dev;
+
+ /* hid_debug = -1; */
+ hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL);
+
+ if (hid_parse_report(hid_dev, packet, len)) {
+ DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report");
+ return;
+ }
+
+ if (hid_dev) {
+ DPRINT_INFO(INPUTVSC_DRV, "hid_device created");
+
+ hid_dev->ll_driver->open = mousevsc_hid_open;
+ hid_dev->ll_driver->close = mousevsc_hid_close;
+
+ hid_dev->bus = BUS_VIRTUAL;
+ hid_dev->vendor = input_device_ctx->device_info.vendor;
+ hid_dev->product = input_device_ctx->device_info.product;
+ hid_dev->version = input_device_ctx->device_info.version;
+ hid_dev->dev = dev->device;
+
+ sprintf(hid_dev->name, "%s",
+ input_device_ctx->device_info.name);
+
+ /*
+ * HJ Do we want to call it with a 0
+ */
+ if (!hidinput_connect(hid_dev, 0)) {
+ hid_dev->claimed |= HID_CLAIMED_INPUT;
+
+ input_device_ctx->connected = 1;
+
+ DPRINT_INFO(INPUTVSC_DRV,
+ "HID device claimed by input\n");
+ }
+
+ if (!hid_dev->claimed) {
+ DPRINT_ERR(INPUTVSC_DRV,
+ "HID device not claimed by "
+ "input or hiddev\n");
+ }
+
+ input_device_ctx->hid_device = hid_dev;
+ }
+
+ kfree(hid_dev);
+}
+
static int mousevsc_on_device_add(struct hv_device *device,
void *additional_info)
{
@@ -661,12 +718,13 @@ static int mousevsc_on_device_add(struct hv_device *device,
struct mousevsc_dev *input_dev;
struct hv_driver *input_drv;
struct hv_input_dev_info dev_info;
+ struct input_device_context *input_device_ctx;
input_dev = alloc_input_device(device);
if (!input_dev) {
ret = -1;
- goto Cleanup;
+ goto cleanup;
}
input_dev->init_complete = false;
@@ -707,7 +765,9 @@ static int mousevsc_on_device_add(struct hv_device *device,
strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse");
/* Send the device info back up */
- deviceinfo_callback(device, &dev_info);
+ input_device_ctx = dev_get_drvdata(&device->device);
+ memcpy(&input_device_ctx->device_info, &dev_info,
+ sizeof(struct hv_input_dev_info));
/* Send the report desc back up */
/* workaround SA-167 */
@@ -719,7 +779,7 @@ static int mousevsc_on_device_add(struct hv_device *device,
input_dev->init_complete = true;
-Cleanup:
+cleanup:
return ret;
}
@@ -762,50 +822,6 @@ static int mousevsc_on_device_remove(struct hv_device *device)
}
-/*
- * Data types
- */
-struct input_device_context {
- struct hv_device *device_ctx;
- struct hid_device *hid_device;
- struct hv_input_dev_info device_info;
- int connected;
-};
-
-
-static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info)
-{
- struct input_device_context *input_device_ctx =
- dev_get_drvdata(&dev->device);
-
- memcpy(&input_device_ctx->device_info, info,
- sizeof(struct hv_input_dev_info));
-
- DPRINT_INFO(INPUTVSC_DRV, "%s", __func__);
-}
-
-static void inputreport_callback(struct hv_device *dev, void *packet, u32 len)
-{
- int ret = 0;
-
- struct input_device_context *input_dev_ctx =
- dev_get_drvdata(&dev->device);
-
- ret = hid_input_report(input_dev_ctx->hid_device,
- HID_INPUT_REPORT, packet, len, 1);
-
- DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret);
-}
-
-static int mousevsc_hid_open(struct hid_device *hid)
-{
- return 0;
-}
-
-static void mousevsc_hid_close(struct hid_device *hid)
-{
-}
-
static int mousevsc_probe(struct hv_device *dev)
{
int ret = 0;
@@ -831,15 +847,10 @@ static int mousevsc_probe(struct hv_device *dev)
static int mousevsc_remove(struct hv_device *dev)
{
- int ret = 0;
-
struct input_device_context *input_dev_ctx;
+ int ret;
- input_dev_ctx = kmalloc(sizeof(struct input_device_context),
- GFP_KERNEL);
-
- dev_set_drvdata(&dev->device, input_dev_ctx);
-
+ input_dev_ctx = dev_get_drvdata(&dev->device);
if (input_dev_ctx->connected) {
hidinput_disconnect(input_dev_ctx->hid_device);
input_dev_ctx->connected = 0;
@@ -850,7 +861,6 @@ static int mousevsc_remove(struct hv_device *dev)
* is being removed
*/
ret = mousevsc_on_device_remove(dev);
-
if (ret != 0) {
DPRINT_ERR(INPUTVSC_DRV,
"unable to remove vsc device (ret %d)", ret);
@@ -861,112 +871,35 @@ static int mousevsc_remove(struct hv_device *dev)
return ret;
}
-static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len)
-{
- struct input_device_context *input_device_ctx =
- dev_get_drvdata(&dev->device);
- struct hid_device *hid_dev;
-
- /* hid_debug = -1; */
- hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL);
-
- if (hid_parse_report(hid_dev, packet, len)) {
- DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report");
- return;
- }
-
- if (hid_dev) {
- DPRINT_INFO(INPUTVSC_DRV, "hid_device created");
-
- hid_dev->ll_driver->open = mousevsc_hid_open;
- hid_dev->ll_driver->close = mousevsc_hid_close;
-
- hid_dev->bus = BUS_VIRTUAL;
- hid_dev->vendor = input_device_ctx->device_info.vendor;
- hid_dev->product = input_device_ctx->device_info.product;
- hid_dev->version = input_device_ctx->device_info.version;
- hid_dev->dev = dev->device;
-
- sprintf(hid_dev->name, "%s",
- input_device_ctx->device_info.name);
-
- /*
- * HJ Do we want to call it with a 0
- */
- if (!hidinput_connect(hid_dev, 0)) {
- hid_dev->claimed |= HID_CLAIMED_INPUT;
-
- input_device_ctx->connected = 1;
-
- DPRINT_INFO(INPUTVSC_DRV,
- "HID device claimed by input\n");
- }
-
- if (!hid_dev->claimed) {
- DPRINT_ERR(INPUTVSC_DRV,
- "HID device not claimed by "
- "input or hiddev\n");
- }
-
- input_device_ctx->hid_device = hid_dev;
- }
-
- kfree(hid_dev);
-}
+static const struct hv_vmbus_device_id id_table[] = {
+ /* Mouse guid */
+ { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
+ 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) },
+ { },
+};
+/*
+ * The mouse driver is not functional; do not auto-load it.
+ */
+/* MODULE_DEVICE_TABLE(vmbus, id_table); */
static struct hv_driver mousevsc_drv = {
+ .name = "mousevsc",
+ .id_table = id_table,
.probe = mousevsc_probe,
.remove = mousevsc_remove,
};
-static void mousevsc_drv_exit(void)
-{
- vmbus_child_driver_unregister(&mousevsc_drv.driver);
-}
-
static int __init mousevsc_init(void)
{
- struct hv_driver *drv = &mousevsc_drv;
-
- DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing.");
-
- memcpy(&drv->dev_type, &mouse_guid,
- sizeof(struct hv_guid));
-
- drv->driver.name = driver_name;
-
- /* The driver belongs to vmbus */
- vmbus_child_driver_register(&drv->driver);
-
- return 0;
+ return vmbus_driver_register(&mousevsc_drv);
}
static void __exit mousevsc_exit(void)
{
- mousevsc_drv_exit();
+ vmbus_driver_unregister(&mousevsc_drv);
}
-/*
- * We don't want to automatically load this driver just yet, it's quite
- * broken. It's safe if you want to load it yourself manually, but
- * don't inflict it on unsuspecting users, that's just mean.
- */
-#if 0
-
-/*
- * We use a PCI table to determine if we should autoload this driver This is
- * needed by distro tools to determine if the hyperv drivers should be
- * installed and/or configured. We don't do anything else with the table, but
- * it needs to be present.
- */
-const static struct pci_device_id microsoft_hv_pci_table[] = {
- { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
-#endif
-
MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
module_init(mousevsc_init);
diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c
index c164b54b4cd7..f2f456f5e444 100644
--- a/drivers/staging/hv/hv_util.c
+++ b/drivers/staging/hv/hv_util.c
@@ -26,8 +26,6 @@
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/reboot.h>
-#include <linux/dmi.h>
-#include <linux/pci.h>
#include "hyperv.h"
#include "hv_kvp.h"
@@ -210,28 +208,45 @@ 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 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"),
- },
- },
+/*
+ * The devices managed by the util driver don't need any additional
+ * setup.
+ */
+static int util_probe(struct hv_device *dev)
+{
+ return 0;
+}
+
+static int util_remove(struct hv_device *dev)
+{
+ 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) },
+ /* Time synch guid */
+ { VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
+ 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) },
+ /* Heartbeat guid */
+ { VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
+ 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) },
+ /* KVP guid */
+ { VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
+ 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6) },
{ },
};
-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)
{
@@ -241,9 +256,6 @@ static int __init init_hyperv_utils(void)
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);
@@ -264,7 +276,7 @@ static int __init init_hyperv_utils(void)
hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
- return 0;
+ return vmbus_driver_register(&util_drv);
}
static void exit_hyperv_utils(void)
@@ -296,6 +308,7 @@ static void exit_hyperv_utils(void)
kfree(shut_txf_buf);
kfree(time_txf_buf);
kfree(hbeat_txf_buf);
+ vmbus_driver_unregister(&util_drv);
}
module_init(init_hyperv_utils);
diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h
index 1747a2404f6c..c24981198b1b 100644
--- a/drivers/staging/hv/hyperv.h
+++ b/drivers/staging/hv/hyperv.h
@@ -27,17 +27,16 @@
#include <linux/scatterlist.h>
#include <linux/list.h>
+#include <linux/uuid.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <linux/device.h>
+#include <linux/mod_devicetable.h>
#include <asm/hyperv.h>
-struct hv_guid {
- unsigned char data[16];
-};
#define MAX_PAGE_BUFFER_COUNT 16
#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
@@ -156,8 +155,8 @@ struct hv_ring_buffer_debug_info {
* struct contains the fundamental information about an offer.
*/
struct vmbus_channel_offer {
- struct hv_guid if_type;
- struct hv_guid if_instance;
+ uuid_le if_type;
+ uuid_le if_instance;
u64 int_latency; /* in 100ns units */
u32 if_revision;
u32 server_ctx_size; /* in bytes */
@@ -526,8 +525,8 @@ enum vmbus_channel_state {
struct vmbus_channel_debug_info {
u32 relid;
enum vmbus_channel_state state;
- struct hv_guid interfacetype;
- struct hv_guid interface_instance;
+ uuid_le interfacetype;
+ uuid_le interface_instance;
u32 monitorid;
u32 servermonitor_pending;
u32 servermonitor_latency;
@@ -786,8 +785,8 @@ struct hv_dev_port_info {
struct hv_device_info {
u32 chn_id;
u32 chn_state;
- struct hv_guid chn_type;
- struct hv_guid chn_instance;
+ uuid_le chn_type;
+ uuid_le chn_instance;
u32 monitor_id;
u32 server_monitor_pending;
@@ -806,7 +805,8 @@ struct hv_driver {
const char *name;
/* the device type supported by this driver */
- struct hv_guid dev_type;
+ uuid_le dev_type;
+ const struct hv_vmbus_device_id *id_table;
struct device_driver driver;
@@ -819,10 +819,10 @@ struct hv_driver {
/* Base device object */
struct hv_device {
/* the device type id of this device */
- struct hv_guid dev_type;
+ uuid_le dev_type;
/* the device instance id of this device */
- struct hv_guid dev_instance;
+ uuid_le dev_instance;
struct device device;
@@ -845,8 +845,23 @@ static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
/* Vmbus interface */
-int vmbus_child_driver_register(struct device_driver *drv);
-void vmbus_child_driver_unregister(struct device_driver *drv);
+#define vmbus_driver_register(driver) \
+ __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+int __must_check __vmbus_driver_register(struct hv_driver *hv_driver,
+ struct module *owner,
+ const char *mod_name);
+void vmbus_driver_unregister(struct hv_driver *hv_driver);
+
+/**
+ * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
+ *
+ * This macro is used to create a struct hv_vmbus_device_id that matches a
+ * specific device.
+ */
+#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \
+ g8, g9, ga, gb, gc, gd, ge, gf) \
+ .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \
+ g8, g9, ga, gb, gc, gd, ge, gf },
/*
* Common header for Hyper-V ICs
@@ -935,7 +950,7 @@ struct ictimesync_data {
struct hyperv_service_callback {
u8 msg_type;
char *log_msg;
- unsigned char data[16];
+ uuid_le data;
struct vmbus_channel *channel;
void (*callback) (void *context);
};
diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h
index 27f987b48dfe..5782fea9a17a 100644
--- a/drivers/staging/hv/hyperv_net.h
+++ b/drivers/staging/hv/hyperv_net.h
@@ -96,7 +96,6 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
unsigned int status);
int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet);
-int netvsc_initialize(struct hv_driver *drv);
int rndis_filter_open(struct hv_device *dev);
int rndis_filter_close(struct hv_device *dev);
int rndis_filter_device_add(struct hv_device *dev,
diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h
index 349ad80ce328..16ca90d9ac24 100644
--- a/drivers/staging/hv/hyperv_vmbus.h
+++ b/drivers/staging/hv/hyperv_vmbus.h
@@ -451,8 +451,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
},
@@ -601,8 +601,8 @@ 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_child_device_create(uuid_le *type,
+ uuid_le *instance,
struct vmbus_channel *channel);
int vmbus_child_device_register(struct hv_device *child_device_obj);
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c
index dc5e5c488e3b..b6e1fb988d23 100644
--- a/drivers/staging/hv/netvsc.c
+++ b/drivers/staging/hv/netvsc.c
@@ -32,18 +32,6 @@
#include "hyperv_net.h"
-/* Globals */
-static const char *driver_name = "netvsc";
-
-/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
-static const struct hv_guid netvsc_device_type = {
- .data = {
- 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
- 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
- }
-};
-
-
static struct netvsc_device *alloc_net_device(struct hv_device *device)
{
struct netvsc_device *net_device;
@@ -172,7 +160,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
if (ret != 0) {
dev_err(&net_device->dev->device, "unable to send "
"revoke receive buffer to netvsp");
- return -1;
+ return ret;
}
}
@@ -187,7 +175,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
if (ret != 0) {
dev_err(&net_device->dev->device,
"unable to teardown receive buffer's gpadl");
- return -1;
+ return -ret;
}
net_device->recv_buf_gpadl_handle = 0;
}
@@ -219,7 +207,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
if (!net_device) {
dev_err(&device->device, "unable to get net device..."
"device being destroyed?");
- return -1;
+ return -ENODEV;
}
net_device->recv_buf =
@@ -228,7 +216,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
if (!net_device->recv_buf) {
dev_err(&device->device, "unable to allocate receive "
"buffer of size %d", net_device->recv_buf_size);
- ret = -1;
+ ret = -ENOMEM;
goto cleanup;
}
@@ -281,7 +269,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
"initialzation with NetVsp - status %d",
init_packet->msg.v1_msg.
send_recv_buf_complete.status);
- ret = -1;
+ ret = -EINVAL;
goto cleanup;
}
@@ -293,7 +281,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
net_device->recv_section = kmalloc(net_device->recv_section_cnt
* sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL);
if (net_device->recv_section == NULL) {
- ret = -1;
+ ret = -EINVAL;
goto cleanup;
}
@@ -309,7 +297,7 @@ static int netvsc_init_recv_buf(struct hv_device *device)
*/
if (net_device->recv_section_cnt != 1 ||
net_device->recv_section->offset != 0) {
- ret = -1;
+ ret = -EINVAL;
goto cleanup;
}
@@ -335,7 +323,7 @@ static int netvsc_connect_vsp(struct hv_device *device)
if (!net_device) {
dev_err(&device->device, "unable to get net device..."
"device being destroyed?");
- return -1;
+ return -ENODEV;
}
init_packet = &net_device->channel_init_pkt;
@@ -366,13 +354,13 @@ static int netvsc_connect_vsp(struct hv_device *device)
if (init_packet->msg.init_msg.init_complete.status !=
NVSP_STAT_SUCCESS) {
- ret = -1;
+ ret = -EINVAL;
goto cleanup;
}
if (init_packet->msg.init_msg.init_complete.
negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
- ret = -1;
+ ret = -EPROTO;
goto cleanup;
}
/* Send the ndis version */
@@ -393,10 +381,8 @@ static int netvsc_connect_vsp(struct hv_device *device)
sizeof(struct nvsp_message),
(unsigned long)init_packet,
VM_PKT_DATA_INBAND, 0);
- if (ret != 0) {
- ret = -1;
+ if (ret != 0)
goto cleanup;
- }
/* Post the big receive buffer to NetVSP */
ret = netvsc_init_recv_buf(device);
@@ -423,7 +409,7 @@ int netvsc_device_remove(struct hv_device *device)
net_device = release_outbound_net_device(device);
if (!net_device) {
dev_err(&device->device, "No net device present!!");
- return -1;
+ return -ENODEV;
}
/* Wait for all send completions */
@@ -513,7 +499,7 @@ int netvsc_send(struct hv_device *device,
if (!net_device) {
dev_err(&device->device, "net device (%p) shutting down..."
"ignoring outbound packets", net_device);
- return -2;
+ return -ENODEV;
}
sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT;
@@ -577,7 +563,7 @@ retry_send_cmplt:
if (ret == 0) {
/* success */
/* no-op */
- } else if (ret == -1) {
+ } else if (ret == -EAGAIN) {
/* no more room...wait a bit and attempt to retry 3 times */
retries++;
dev_err(&device->device, "unable to send receive completion pkt"
@@ -896,7 +882,7 @@ static void netvsc_channel_cb(void *context)
break;
}
- } else if (ret == -2) {
+ } else if (ret == -ENOBUFS) {
/* Handle large packet */
buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
if (buffer == NULL) {
@@ -932,7 +918,7 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
net_device = alloc_net_device(device);
if (!net_device) {
- ret = -1;
+ ret = -ENOMEM;
goto cleanup;
}
@@ -961,7 +947,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
if (ret != 0) {
dev_err(&device->device, "unable to open channel: %d", ret);
- ret = -1;
goto cleanup;
}
@@ -973,7 +958,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
if (ret != 0) {
dev_err(&device->device,
"unable to connect to NetVSP - %d", ret);
- ret = -1;
goto close;
}
@@ -1001,15 +985,3 @@ cleanup:
return ret;
}
-
-/*
- * netvsc_initialize - Main entry point
- */
-int netvsc_initialize(struct hv_driver *drv)
-{
-
- drv->name = driver_name;
- memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
-
- return 0;
-}
diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c
index 61989f0d9f0d..90a3198c9978 100644
--- a/drivers/staging/hv/netvsc_drv.c
+++ b/drivers/staging/hv/netvsc_drv.c
@@ -33,8 +33,6 @@
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/slab.h>
-#include <linux/dmi.h>
-#include <linux/pci.h>
#include <net/arp.h>
#include <net/route.h>
#include <net/sock.h>
@@ -340,7 +338,7 @@ static int netvsc_probe(struct hv_device *dev)
net = alloc_etherdev(sizeof(struct net_device_context));
if (!net)
- return -1;
+ return -ENOMEM;
/* Set initial state */
netif_carrier_off(net);
@@ -357,8 +355,6 @@ static int netvsc_probe(struct hv_device *dev)
if (ret != 0) {
free_netdev(net);
dev_set_drvdata(&dev->device, NULL);
-
- netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
return ret;
}
@@ -413,61 +409,33 @@ static int netvsc_remove(struct hv_device *dev)
return 0;
}
+static const struct hv_vmbus_device_id id_table[] = {
+ /* Network guid */
+ { VMBUS_DEVICE(0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
+ 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E) },
+ { },
+};
+
+MODULE_DEVICE_TABLE(vmbus, id_table);
+
/* The one and only one */
static struct hv_driver netvsc_drv = {
+ .name = "netvsc",
+ .id_table = id_table,
.probe = netvsc_probe,
.remove = netvsc_remove,
};
static void __exit netvsc_drv_exit(void)
{
- vmbus_child_driver_unregister(&netvsc_drv.driver);
+ vmbus_driver_unregister(&netvsc_drv);
}
-
-static const struct dmi_system_id __initconst
-hv_netvsc_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"),
- },
- },
- { },
-};
-MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table);
-
static int __init netvsc_drv_init(void)
{
- struct hv_driver *drv = &netvsc_drv;
- int ret;
-
- pr_info("initializing....");
-
- if (!dmi_check_system(hv_netvsc_dmi_table))
- return -ENODEV;
-
-
- /* Callback to client driver to complete the initialization */
- netvsc_initialize(drv);
-
- drv->driver.name = drv->name;
-
- /* The driver belongs to vmbus */
- ret = vmbus_child_driver_register(&drv->driver);
-
- return ret;
+ return vmbus_driver_register(&netvsc_drv);
}
-static const struct pci_device_id __initconst
-hv_netvsc_pci_table[] __maybe_unused = {
- { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, hv_netvsc_pci_table);
-
MODULE_LICENSE("GPL");
MODULE_VERSION(HV_DRV_VERSION);
MODULE_DESCRIPTION("Microsoft Hyper-V network driver");
diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c
index 42f76728429a..9212699a6632 100644
--- a/drivers/staging/hv/ring_buffer.c
+++ b/drivers/staging/hv/ring_buffer.c
@@ -390,7 +390,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 +450,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 +496,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 =
diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c
index dbb520199756..6db48b92fe98 100644
--- a/drivers/staging/hv/rndis_filter.c
+++ b/drivers/staging/hv/rndis_filter.c
@@ -358,14 +358,14 @@ int rndis_filter_receive(struct hv_device *dev,
if (!net_dev->extension) {
dev_err(&dev->device, "got rndis message but no rndis device - "
"dropping this message!\n");
- return -1;
+ return -ENODEV;
}
rndis_dev = (struct rndis_device *)net_dev->extension;
if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
dev_err(&dev->device, "got rndis message but rndis device "
"uninitialized...dropping this message!\n");
- return -1;
+ return -ENODEV;
}
rndis_hdr = (struct rndis_message *)kmap_atomic(
@@ -437,8 +437,8 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG,
RNDIS_MESSAGE_SIZE(struct rndis_query_request));
if (!request) {
- ret = -1;
- goto Cleanup;
+ ret = -ENOMEM;
+ goto cleanup;
}
/* Setup the rndis query */
@@ -450,12 +450,12 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
ret = rndis_filter_send_request(dev, request);
if (ret != 0)
- goto Cleanup;
+ goto cleanup;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0) {
ret = -ETIMEDOUT;
- goto Cleanup;
+ goto cleanup;
}
/* Copy the response back */
@@ -463,7 +463,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
if (query_complete->info_buflen > inresult_size) {
ret = -1;
- goto Cleanup;
+ goto cleanup;
}
memcpy(result,
@@ -473,7 +473,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
*result_size = query_complete->info_buflen;
-Cleanup:
+cleanup:
if (request)
put_rndis_request(dev, request);
@@ -511,8 +511,8 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
sizeof(u32));
if (!request) {
- ret = -1;
- goto Cleanup;
+ ret = -ENOMEM;
+ goto cleanup;
}
/* Setup the rndis set */
@@ -526,30 +526,27 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
ret = rndis_filter_send_request(dev, request);
if (ret != 0)
- goto Cleanup;
+ goto cleanup;
t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
if (t == 0) {
- ret = -1;
dev_err(&dev->net_dev->dev->device,
"timeout before we got a set response...\n");
/*
* We can't deallocate the request since we may still receive a
* send completion for it.
*/
- goto Exit;
+ goto exit;
} else {
- if (ret > 0)
- ret = 0;
set_complete = &request->response_msg.msg.set_complete;
status = set_complete->status;
}
-Cleanup:
+cleanup:
if (request)
put_rndis_request(dev, request);
-Exit:
+exit:
return ret;
}
@@ -565,8 +562,8 @@ static int rndis_filter_init_device(struct rndis_device *dev)
request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG,
RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
if (!request) {
- ret = -1;
- goto Cleanup;
+ ret = -ENOMEM;
+ goto cleanup;
}
/* Setup the rndis set */
@@ -581,7 +578,7 @@ static int rndis_filter_init_device(struct rndis_device *dev)
ret = rndis_filter_send_request(dev, request);
if (ret != 0) {
dev->state = RNDIS_DEV_UNINITIALIZED;
- goto Cleanup;
+ goto cleanup;
}
@@ -589,7 +586,7 @@ static int rndis_filter_init_device(struct rndis_device *dev)
if (t == 0) {
ret = -ETIMEDOUT;
- goto Cleanup;
+ goto cleanup;
}
init_complete = &request->response_msg.msg.init_complete;
@@ -599,10 +596,10 @@ static int rndis_filter_init_device(struct rndis_device *dev)
ret = 0;
} else {
dev->state = RNDIS_DEV_UNINITIALIZED;
- ret = -1;
+ ret = -EINVAL;
}
-Cleanup:
+cleanup:
if (request)
put_rndis_request(dev, request);
@@ -618,7 +615,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG,
RNDIS_MESSAGE_SIZE(struct rndis_halt_request));
if (!request)
- goto Cleanup;
+ goto cleanup;
/* Setup the rndis set */
halt = &request->request_msg.msg.halt_req;
@@ -629,7 +626,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev)
dev->state = RNDIS_DEV_UNINITIALIZED;
-Cleanup:
+cleanup:
if (request)
put_rndis_request(dev, request);
return;
@@ -676,7 +673,7 @@ int rndis_filter_device_add(struct hv_device *dev,
rndisDevice = get_rndis_device();
if (!rndisDevice)
- return -1;
+ return -ENODEV;
/*
* Let the inner driver handle this first to create the netvsc channel
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c
index 302978611943..827b6a307eff 100644
--- a/drivers/staging/hv/storvsc.c
+++ b/drivers/staging/hv/storvsc.c
@@ -111,7 +111,7 @@ static int storvsc_channel_init(struct hv_device *device)
stor_device = get_stor_device(device);
if (!stor_device)
- return -1;
+ return -ENODEV;
request = &stor_device->init_request;
vstor_packet = &request->vstor_packet;
@@ -125,8 +125,6 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
- DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION...");
-
ret = vmbus_sendpacket(device->channel, vstor_packet,
sizeof(struct vstor_packet),
(unsigned long)request,
@@ -145,7 +143,6 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet->status != 0)
goto cleanup;
- DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
/* reuse the packet for version range supported */
memset(vstor_packet, 0, sizeof(struct vstor_packet));
@@ -169,13 +166,10 @@ static int storvsc_channel_init(struct hv_device *device)
goto cleanup;
}
- /* TODO: Check returned version */
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
goto cleanup;
- /* Query channel properties */
- DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES;
@@ -198,7 +192,6 @@ static int storvsc_channel_init(struct hv_device *device)
goto cleanup;
}
- /* TODO: Check returned version */
if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
vstor_packet->status != 0)
goto cleanup;
@@ -207,8 +200,6 @@ static int storvsc_channel_init(struct hv_device *device)
stor_device->target_id
= vstor_packet->storage_channel_properties.target_id;
- DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
-
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
vstor_packet->flags = REQUEST_COMPLETION_FLAG;
@@ -232,7 +223,6 @@ static int storvsc_channel_init(struct hv_device *device)
vstor_packet->status != 0)
goto cleanup;
- DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****");
cleanup:
put_stor_device(device);
@@ -305,13 +295,8 @@ static void storvsc_on_receive(struct hv_device *device,
storvsc_on_io_completion(device, vstor_packet, request);
break;
case VSTOR_OPERATION_REMOVE_DEVICE:
- DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION");
- /* TODO: */
- break;
default:
- DPRINT_INFO(STORVSC, "Unknown operation received - %d",
- vstor_packet->operation);
break;
}
}
@@ -376,7 +361,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
storvsc_on_channel_callback, device);
if (ret != 0)
- return -1;
+ return ret;
ret = storvsc_channel_init(device);
@@ -392,28 +377,29 @@ int storvsc_dev_add(struct hv_device *device,
device_info = (struct storvsc_device_info *)additional_info;
stor_device = alloc_stor_device(device);
- if (!stor_device) {
- ret = -1;
- goto cleanup;
- }
+ if (!stor_device)
+ return -ENOMEM;
/* Save the channel properties to our storvsc channel */
- /* FIXME: */
/*
* If we support more than 1 scsi channel, we need to set the
* port number here to the scsi channel but how do we get the
- * scsi channel prior to the bus scan
+ * scsi channel prior to the bus scan.
+ *
+ * The host does not support this.
*/
stor_device->port_number = device_info->port_number;
/* Send it back up */
ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size);
-
+ if (ret) {
+ free_stor_device(stor_device);
+ return ret;
+ }
device_info->path_id = stor_device->path_id;
device_info->target_id = stor_device->target_id;
-cleanup:
return ret;
}
@@ -421,9 +407,6 @@ int storvsc_dev_remove(struct hv_device *device)
{
struct storvsc_device *stor_device;
- DPRINT_INFO(STORVSC, "disabling storage device (%p)...",
- device->ext);
-
stor_device = release_stor_device(device);
/*
@@ -454,7 +437,7 @@ int storvsc_do_io(struct hv_device *device,
stor_device = get_stor_device(device);
if (!stor_device)
- return -2;
+ return -ENODEV;
request->device = device;
@@ -561,4 +544,3 @@ int storvsc_get_major_info(struct storvsc_device_info *device_info,
return -ENODEV;
}
-
diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c
index 7effaf32e25f..faa8d5760876 100644
--- a/drivers/staging/hv/storvsc_drv.c
+++ b/drivers/staging/hv/storvsc_drv.c
@@ -24,7 +24,6 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/blkdev.h>
-#include <linux/dmi.h>
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h>
@@ -42,16 +41,6 @@ static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
-static const char *driver_name = "storvsc";
-
-/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
-static const struct hv_guid stor_vsci_device_type = {
- .data = {
- 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
- 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
- }
-};
-
struct hv_host_device {
struct hv_device *dev;
struct kmem_cache *request_pool;
@@ -357,7 +346,7 @@ static int storvsc_host_reset(struct hv_device *device)
stor_device = get_stor_device(device);
if (!stor_device)
- return -1;
+ return -ENODEV;
request = &stor_device->reset_request;
vstor_packet = &request->vstor_packet;
@@ -589,7 +578,7 @@ retry_request:
/* Invokes the vsc to start an IO */
ret = storvsc_do_io(dev, &cmd_request->request);
- if (ret == -1) {
+ if (ret == -EAGAIN) {
/* no more space */
if (cmd_request->bounce_sgl_count) {
@@ -646,7 +635,14 @@ static struct scsi_host_template scsi_driver = {
.dma_boundary = PAGE_SIZE-1,
};
+static const struct hv_vmbus_device_id id_table[] = {
+ /* SCSI guid */
+ { VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
+ 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) },
+ { },
+};
+MODULE_DEVICE_TABLE(vmbus, id_table);
/*
* storvsc_probe - Add a new device for this driver
*/
@@ -689,7 +685,7 @@ static int storvsc_probe(struct hv_device *device)
if (ret != 0) {
kmem_cache_destroy(host_dev->request_pool);
scsi_host_put(host);
- return -1;
+ return -ENODEV;
}
host_dev->path = device_info.path_id;
@@ -710,7 +706,7 @@ static int storvsc_probe(struct hv_device *device)
kmem_cache_destroy(host_dev->request_pool);
scsi_host_put(host);
- return -1;
+ return -ENODEV;
}
scsi_scan_host(host);
@@ -720,35 +716,14 @@ static int storvsc_probe(struct hv_device *device)
/* The one and only one */
static struct hv_driver storvsc_drv = {
+ .name = "storvsc",
+ .id_table = id_table,
.probe = storvsc_probe,
.remove = storvsc_remove,
};
-/*
- * We use a DMI table to determine if we should autoload this driver This is
- * needed by distro tools to determine if the hyperv drivers should be
- * installed and/or configured. We don't do anything else with the table, but
- * it needs to be present.
- */
-
-static const struct dmi_system_id __initconst
-hv_stor_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"),
- },
- },
- { },
-};
-MODULE_DEVICE_TABLE(dmi, hv_stor_dmi_table);
-
static int __init storvsc_drv_init(void)
{
- int ret;
- struct hv_driver *drv = &storvsc_drv;
u32 max_outstanding_req_per_channel;
/*
@@ -757,32 +732,22 @@ static int __init storvsc_drv_init(void)
* the ring buffer indices) by the max request size (which is
* vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
*/
-
max_outstanding_req_per_channel =
- ((storvsc_ringbuffer_size - PAGE_SIZE) /
- ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
- sizeof(struct vstor_packet) + sizeof(u64),
- sizeof(u64)));
-
- memcpy(&drv->dev_type, &stor_vsci_device_type,
- sizeof(struct hv_guid));
+ ((storvsc_ringbuffer_size - PAGE_SIZE) /
+ ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
+ sizeof(struct vstor_packet) + sizeof(u64),
+ sizeof(u64)));
if (max_outstanding_req_per_channel <
STORVSC_MAX_IO_REQUESTS)
- return -1;
-
- drv->driver.name = driver_name;
-
+ return -EINVAL;
- /* The driver belongs to vmbus */
- ret = vmbus_child_driver_register(&drv->driver);
-
- return ret;
+ return vmbus_driver_register(&storvsc_drv);
}
static void __exit storvsc_drv_exit(void)
{
- vmbus_child_driver_unregister(&storvsc_drv.driver);
+ vmbus_driver_unregister(&storvsc_drv);
}
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c
index a4a407f7052a..11224eddcdc2 100644
--- a/drivers/staging/hv/tools/hv_kvp_daemon.c
+++ b/drivers/staging/hv/tools/hv_kvp_daemon.c
@@ -116,7 +116,16 @@ void kvp_get_os_info(void)
uname(&uts_buf);
os_build = uts_buf.release;
- processor_arch= uts_buf.machine;
+ processor_arch = uts_buf.machine;
+
+ /*
+ * The current windows host (win7) expects the build
+ * string to be of the form: x.y.z
+ * Strip additional information we may have.
+ */
+ p = strchr(os_build, '-');
+ if (p)
+ *p = '\0';
file = fopen("/etc/SuSE-release", "r");
if (file != NULL)
@@ -264,22 +273,20 @@ static int
kvp_get_domain_name(char *buffer, int length)
{
struct addrinfo hints, *info ;
- gethostname(buffer, length);
int error = 0;
+ gethostname(buffer, length);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
- error = getaddrinfo(buffer, "http", &hints, &info);
+ error = getaddrinfo(buffer, NULL, &hints, &info);
if (error != 0) {
strcpy(buffer, "getaddrinfo failed\n");
- error = 1;
- goto get_domain_done;
+ return error;
}
strcpy(buffer, info->ai_canonname);
-get_domain_done:
freeaddrinfo(info);
return error;
}
diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c
index 1c949f5fb716..be62b6244e39 100644
--- a/drivers/staging/hv/vmbus_drv.c
+++ b/drivers/staging/hv/vmbus_drv.c
@@ -28,8 +28,6 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/sysctl.h>
-#include <linux/pci.h>
-#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
@@ -46,8 +44,6 @@ static struct tasklet_struct event_dpc;
unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
EXPORT_SYMBOL(vmbus_loglevel);
- /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
- /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
static struct completion probe_event;
static int irq;
@@ -65,9 +61,9 @@ static void get_channel_info(struct hv_device *device,
info->chn_id = debug_info.relid;
info->chn_state = debug_info.state;
memcpy(&info->chn_type, &debug_info.interfacetype,
- sizeof(struct hv_guid));
+ sizeof(uuid_le));
memcpy(&info->chn_instance, &debug_info.interface_instance,
- sizeof(struct hv_guid));
+ sizeof(uuid_le));
info->monitor_id = debug_info.monitorid;
@@ -117,41 +113,41 @@ static ssize_t vmbus_show_device_attr(struct device *dev,
if (!strcmp(dev_attr->attr.name, "class_id")) {
return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x%02x%02x%02x%02x%02x%02x}\n",
- device_info.chn_type.data[3],
- device_info.chn_type.data[2],
- device_info.chn_type.data[1],
- device_info.chn_type.data[0],
- device_info.chn_type.data[5],
- device_info.chn_type.data[4],
- device_info.chn_type.data[7],
- device_info.chn_type.data[6],
- device_info.chn_type.data[8],
- device_info.chn_type.data[9],
- device_info.chn_type.data[10],
- device_info.chn_type.data[11],
- device_info.chn_type.data[12],
- device_info.chn_type.data[13],
- device_info.chn_type.data[14],
- device_info.chn_type.data[15]);
+ device_info.chn_type.b[3],
+ device_info.chn_type.b[2],
+ device_info.chn_type.b[1],
+ device_info.chn_type.b[0],
+ device_info.chn_type.b[5],
+ device_info.chn_type.b[4],
+ device_info.chn_type.b[7],
+ device_info.chn_type.b[6],
+ device_info.chn_type.b[8],
+ device_info.chn_type.b[9],
+ device_info.chn_type.b[10],
+ device_info.chn_type.b[11],
+ device_info.chn_type.b[12],
+ device_info.chn_type.b[13],
+ device_info.chn_type.b[14],
+ device_info.chn_type.b[15]);
} else if (!strcmp(dev_attr->attr.name, "device_id")) {
return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x%02x%02x%02x%02x%02x%02x}\n",
- device_info.chn_instance.data[3],
- device_info.chn_instance.data[2],
- device_info.chn_instance.data[1],
- device_info.chn_instance.data[0],
- device_info.chn_instance.data[5],
- device_info.chn_instance.data[4],
- device_info.chn_instance.data[7],
- device_info.chn_instance.data[6],
- device_info.chn_instance.data[8],
- device_info.chn_instance.data[9],
- device_info.chn_instance.data[10],
- device_info.chn_instance.data[11],
- device_info.chn_instance.data[12],
- device_info.chn_instance.data[13],
- device_info.chn_instance.data[14],
- device_info.chn_instance.data[15]);
+ device_info.chn_instance.b[3],
+ device_info.chn_instance.b[2],
+ device_info.chn_instance.b[1],
+ device_info.chn_instance.b[0],
+ device_info.chn_instance.b[5],
+ device_info.chn_instance.b[4],
+ device_info.chn_instance.b[7],
+ device_info.chn_instance.b[6],
+ device_info.chn_instance.b[8],
+ device_info.chn_instance.b[9],
+ device_info.chn_instance.b[10],
+ device_info.chn_instance.b[11],
+ device_info.chn_instance.b[12],
+ device_info.chn_instance.b[13],
+ device_info.chn_instance.b[14],
+ device_info.chn_instance.b[15]);
} else if (!strcmp(dev_attr->attr.name, "state")) {
return sprintf(buf, "%d\n", device_info.chn_state);
} else if (!strcmp(dev_attr->attr.name, "id")) {
@@ -238,58 +234,31 @@ static struct device_attribute vmbus_device_attrs[] = {
* This routine is invoked when a device is added or removed on the vmbus to
* generate a uevent to udev in the userspace. The udev will then look at its
* rule and the uevent generated here to load the appropriate driver
+ *
+ * The alias string will be of the form vmbus:guid where guid is the string
+ * representation of the device guid (each byte of the guid will be
+ * represented with two hex characters.
*/
static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
{
struct hv_device *dev = device_to_hv_device(device);
- int ret;
+ int i, ret;
+ char alias_name[((sizeof((struct hv_vmbus_device_id *)0)->guid) + 1) * 2];
- ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
- "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
- "%02x%02x%02x%02x%02x%02x%02x%02x}",
- dev->dev_type.data[3],
- dev->dev_type.data[2],
- dev->dev_type.data[1],
- dev->dev_type.data[0],
- dev->dev_type.data[5],
- dev->dev_type.data[4],
- dev->dev_type.data[7],
- dev->dev_type.data[6],
- dev->dev_type.data[8],
- dev->dev_type.data[9],
- dev->dev_type.data[10],
- dev->dev_type.data[11],
- dev->dev_type.data[12],
- dev->dev_type.data[13],
- dev->dev_type.data[14],
- dev->dev_type.data[15]);
+ for (i = 0; i < ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2); i += 2)
+ sprintf(&alias_name[i], "%02x", dev->dev_type.b[i/2]);
- if (ret)
- return ret;
+ ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name);
+ return ret;
+}
- ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
- "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
- "%02x%02x%02x%02x%02x%02x%02x%02x}",
- dev->dev_instance.data[3],
- dev->dev_instance.data[2],
- dev->dev_instance.data[1],
- dev->dev_instance.data[0],
- dev->dev_instance.data[5],
- dev->dev_instance.data[4],
- dev->dev_instance.data[7],
- dev->dev_instance.data[6],
- dev->dev_instance.data[8],
- dev->dev_instance.data[9],
- dev->dev_instance.data[10],
- dev->dev_instance.data[11],
- dev->dev_instance.data[12],
- dev->dev_instance.data[13],
- dev->dev_instance.data[14],
- dev->dev_instance.data[15]);
- if (ret)
- return ret;
+static uuid_le null_guid;
- return 0;
+static inline bool is_null_guid(const __u8 *guid)
+{
+ if (memcmp(guid, &null_guid, sizeof(uuid_le)))
+ return false;
+ return true;
}
@@ -298,16 +267,16 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
*/
static int vmbus_match(struct device *device, struct device_driver *driver)
{
- int match = 0;
struct hv_driver *drv = drv_to_hv_drv(driver);
struct hv_device *hv_dev = device_to_hv_device(device);
+ const struct hv_vmbus_device_id *id_array = drv->id_table;
- /* We found our driver ? */
- if (memcmp(&hv_dev->dev_type, &drv->dev_type,
- sizeof(struct hv_guid)) == 0)
- match = 1;
+ for (; !is_null_guid(id_array->guid); id_array++)
+ if (!memcmp(&id_array->guid, &hv_dev->dev_type.b,
+ sizeof(struct hv_vmbus_device_id)))
+ return 1;
- return match;
+ return 0;
}
/*
@@ -581,58 +550,57 @@ static int vmbus_bus_init(int irq)
}
/**
- * vmbus_child_driver_register() - Register a vmbus's child driver
- * @drv: Pointer to driver structure you want to register
- *
+ * __vmbus_child_driver_register - Register a vmbus's driver
+ * @drv: Pointer to driver structure you want to register
+ * @owner: owner module of the drv
+ * @mod_name: module name string
*
* Registers the given driver with Linux through the 'driver_register()' call
- * And sets up the hyper-v vmbus handling for this driver.
+ * and sets up the hyper-v vmbus handling for this driver.
* It will return the state of the 'driver_register()' call.
*
- * Mainly used by Hyper-V drivers.
*/
-int vmbus_child_driver_register(struct device_driver *drv)
+int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name)
{
int ret;
- pr_info("child driver registering - name %s\n", drv->name);
+ pr_info("registering driver %s\n", hv_driver->name);
- /* The child driver on this vmbus */
- drv->bus = &hv_bus;
+ hv_driver->driver.name = hv_driver->name;
+ hv_driver->driver.owner = owner;
+ hv_driver->driver.mod_name = mod_name;
+ hv_driver->driver.bus = &hv_bus;
- ret = driver_register(drv);
+ ret = driver_register(&hv_driver->driver);
vmbus_request_offers();
return ret;
}
-EXPORT_SYMBOL(vmbus_child_driver_register);
+EXPORT_SYMBOL_GPL(__vmbus_driver_register);
/**
- * vmbus_child_driver_unregister() - Unregister a vmbus's child driver
- * @drv: Pointer to driver structure you want to un-register
- *
+ * vmbus_driver_unregister() - Unregister a vmbus's driver
+ * @drv: Pointer to driver structure you want to un-register
*
- * Un-register the given driver with Linux through the 'driver_unregister()'
- * call. And ungegisters the driver from the Hyper-V vmbus handler.
- *
- * Mainly used by Hyper-V drivers.
+ * Un-register the given driver that was previous registered with a call to
+ * vmbus_driver_register()
*/
-void vmbus_child_driver_unregister(struct device_driver *drv)
+void vmbus_driver_unregister(struct hv_driver *hv_driver)
{
- pr_info("child driver unregistering - name %s\n", drv->name);
+ pr_info("unregistering driver %s\n", hv_driver->name);
- driver_unregister(drv);
+ driver_unregister(&hv_driver->driver);
}
-EXPORT_SYMBOL(vmbus_child_driver_unregister);
+EXPORT_SYMBOL_GPL(vmbus_driver_unregister);
/*
* vmbus_child_device_create - Creates and registers a new child device
* on the vmbus.
*/
-struct hv_device *vmbus_child_device_create(struct hv_guid *type,
- struct hv_guid *instance,
+struct hv_device *vmbus_child_device_create(uuid_le *type,
+ uuid_le *instance,
struct vmbus_channel *channel)
{
struct hv_device *child_device_obj;
@@ -645,9 +613,9 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type,
}
child_device_obj->channel = channel;
- memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid));
+ memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le));
memcpy(&child_device_obj->dev_instance, instance,
- sizeof(struct hv_guid));
+ sizeof(uuid_le));
return child_device_obj;
@@ -754,21 +722,9 @@ static struct acpi_driver vmbus_acpi_driver = {
},
};
-/*
- * We use a PCI table to determine if we should autoload this driver This is
- * needed by distro tools to determine if the hyperv drivers should be
- * installed and/or configured. We don't do anything else with the table, but
- * it needs to be present.
- */
-static const struct pci_device_id microsoft_hv_pci_table[] = {
- { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
-
static int __init hv_acpi_init(void)
{
- int ret;
+ int ret, t;
init_completion(&probe_event);
@@ -781,16 +737,25 @@ static int __init hv_acpi_init(void)
if (ret)
return ret;
- wait_for_completion(&probe_event);
+ t = wait_for_completion_timeout(&probe_event, 5*HZ);
+ if (t == 0) {
+ ret = -ETIMEDOUT;
+ goto cleanup;
+ }
if (irq <= 0) {
- acpi_bus_unregister_driver(&vmbus_acpi_driver);
- return -ENODEV;
+ ret = -ENODEV;
+ goto cleanup;
}
ret = vmbus_bus_init(irq);
if (ret)
- acpi_bus_unregister_driver(&vmbus_acpi_driver);
+ goto cleanup;
+
+ return 0;
+
+cleanup:
+ acpi_bus_unregister_driver(&vmbus_acpi_driver);
return ret;
}