diff options
author | Greg Kroah-Hartman | 2010-05-21 21:48:55 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2010-05-21 21:48:55 +0200 |
commit | c8d1a126924fcbc1d61ceb830226e0c7afdcc841 (patch) | |
tree | d3f3c850481c33b7f433175e83a189f958b1b868 /drivers/staging/hv | |
parent | Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ryu... (diff) | |
parent | Staging: ramzswap: Handler for swap slot free callback (diff) | |
download | kernel-qcow2-linux-c8d1a126924fcbc1d61ceb830226e0c7afdcc841.tar.gz kernel-qcow2-linux-c8d1a126924fcbc1d61ceb830226e0c7afdcc841.tar.xz kernel-qcow2-linux-c8d1a126924fcbc1d61ceb830226e0c7afdcc841.zip |
Merge staging-next tree into Linus's latest version
Conflicts:
drivers/staging/arlan/arlan-main.c
drivers/staging/comedi/drivers/cb_das16_cs.c
drivers/staging/cx25821/cx25821-alsa.c
drivers/staging/dt3155/dt3155_drv.c
drivers/staging/hv/hv.c
drivers/staging/netwave/netwave_cs.c
drivers/staging/wavelan/wavelan.c
drivers/staging/wavelan/wavelan_cs.c
drivers/staging/wlags49_h2/wl_cs.c
This required a bit of hand merging due to the conflicts
that happened in the later .34-rc releases, as well as
some staging driver changing coming in through other trees
(v4l and pcmcia).
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv')
-rw-r--r-- | drivers/staging/hv/Kconfig | 8 | ||||
-rw-r--r-- | drivers/staging/hv/Makefile | 11 | ||||
-rw-r--r-- | drivers/staging/hv/TODO | 3 | ||||
-rw-r--r-- | drivers/staging/hv/blkvsc.c (renamed from drivers/staging/hv/BlkVsc.c) | 4 | ||||
-rw-r--r-- | drivers/staging/hv/blkvsc_drv.c | 45 | ||||
-rw-r--r-- | drivers/staging/hv/channel.c (renamed from drivers/staging/hv/Channel.c) | 195 | ||||
-rw-r--r-- | drivers/staging/hv/channel.h (renamed from drivers/staging/hv/Channel.h) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/channel_interface.c (renamed from drivers/staging/hv/ChannelInterface.c) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/channel_interface.h (renamed from drivers/staging/hv/ChannelInterface.h) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c (renamed from drivers/staging/hv/ChannelMgmt.c) | 228 | ||||
-rw-r--r-- | drivers/staging/hv/channel_mgmt.h (renamed from drivers/staging/hv/ChannelMgmt.h) | 6 | ||||
-rw-r--r-- | drivers/staging/hv/connection.c (renamed from drivers/staging/hv/Connection.c) | 31 | ||||
-rw-r--r-- | drivers/staging/hv/hv.c (renamed from drivers/staging/hv/Hv.c) | 28 | ||||
-rw-r--r-- | drivers/staging/hv/hv.h (renamed from drivers/staging/hv/Hv.h) | 0 | ||||
-rw-r--r-- | drivers/staging/hv/hv_utils.c | 295 | ||||
-rw-r--r-- | drivers/staging/hv/logging.h | 7 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc.c (renamed from drivers/staging/hv/NetVsc.c) | 104 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc.h (renamed from drivers/staging/hv/NetVsc.h) | 7 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc_api.h (renamed from drivers/staging/hv/NetVscApi.h) | 9 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc_drv.c | 243 | ||||
-rw-r--r-- | drivers/staging/hv/osd.c | 70 | ||||
-rw-r--r-- | drivers/staging/hv/ring_buffer.c (renamed from drivers/staging/hv/RingBuffer.c) | 16 | ||||
-rw-r--r-- | drivers/staging/hv/ring_buffer.h (renamed from drivers/staging/hv/RingBuffer.h) | 0 | ||||
-rw-r--r-- | drivers/staging/hv/rndis.h | 2 | ||||
-rw-r--r-- | drivers/staging/hv/rndis_filter.c (renamed from drivers/staging/hv/RndisFilter.c) | 56 | ||||
-rw-r--r-- | drivers/staging/hv/rndis_filter.h (renamed from drivers/staging/hv/RndisFilter.h) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/storvsc.c (renamed from drivers/staging/hv/StorVsc.c) | 54 | ||||
-rw-r--r-- | drivers/staging/hv/storvsc_api.h (renamed from drivers/staging/hv/StorVscApi.h) | 2 | ||||
-rw-r--r-- | drivers/staging/hv/storvsc_drv.c | 54 | ||||
-rw-r--r-- | drivers/staging/hv/utils.h | 119 | ||||
-rw-r--r-- | drivers/staging/hv/version_info.h (renamed from drivers/staging/hv/VersionInfo.h) | 7 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus.c (renamed from drivers/staging/hv/Vmbus.c) | 33 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus.h | 2 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_api.h (renamed from drivers/staging/hv/VmbusApi.h) | 18 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_channel_interface.h (renamed from drivers/staging/hv/VmbusChannelInterface.h) | 0 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_drv.c | 96 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_packet_format.h (renamed from drivers/staging/hv/VmbusPacketFormat.h) | 1 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_private.h (renamed from drivers/staging/hv/VmbusPrivate.h) | 12 | ||||
-rw-r--r-- | drivers/staging/hv/vstorage.h | 2 |
39 files changed, 1301 insertions, 475 deletions
diff --git a/drivers/staging/hv/Kconfig b/drivers/staging/hv/Kconfig index 40447020a790..97480f5c6599 100644 --- a/drivers/staging/hv/Kconfig +++ b/drivers/staging/hv/Kconfig @@ -17,7 +17,7 @@ config HYPERV_STORAGE config HYPERV_BLOCK tristate "Microsoft Hyper-V virtual block driver" - depends on BLOCK && SCSI + depends on BLOCK && SCSI && LBDAF default HYPERV help Select this option to enable the Hyper-V virtual block driver. @@ -29,4 +29,10 @@ config HYPERV_NET help Select this option to enable the Hyper-V virtual network driver. +config HYPERV_UTILS + tristate "Microsoft Hyper-V Utilities driver" + default HYPERV + help + Select this option to enable the Hyper-V Utilities. + endif diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index 27ebae8a9185..1866f80a45d3 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -2,10 +2,11 @@ obj-$(CONFIG_HYPERV) += hv_vmbus.o obj-$(CONFIG_HYPERV_STORAGE) += hv_storvsc.o obj-$(CONFIG_HYPERV_BLOCK) += hv_blkvsc.o obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o +obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-objs := vmbus_drv.o osd.o \ - Vmbus.o Hv.o Connection.o Channel.o \ - ChannelMgmt.o ChannelInterface.o RingBuffer.o -hv_storvsc-objs := storvsc_drv.o StorVsc.o -hv_blkvsc-objs := blkvsc_drv.o BlkVsc.o -hv_netvsc-objs := netvsc_drv.o NetVsc.o RndisFilter.o + vmbus.o hv.o connection.o channel.o \ + channel_mgmt.o channel_interface.o ring_buffer.o +hv_storvsc-objs := storvsc_drv.o storvsc.o +hv_blkvsc-objs := blkvsc_drv.o blkvsc.o +hv_netvsc-objs := netvsc_drv.o netvsc.o rndis_filter.o diff --git a/drivers/staging/hv/TODO b/drivers/staging/hv/TODO index dbfbde937a66..66a89c809dd3 100644 --- a/drivers/staging/hv/TODO +++ b/drivers/staging/hv/TODO @@ -1,7 +1,5 @@ TODO: - fix remaining checkpatch warnings and errors - - use of /** when it is not a kerneldoc header - - remove RingBuffer.c to us in-kernel ringbuffer functions instead. - audit the vmbus to verify it is working properly with the driver model - convert vmbus driver interface function pointer tables @@ -9,7 +7,6 @@ TODO: - see if the vmbus can be merged with the other virtual busses in the kernel - audit the network driver - - use existing net_device_stats struct in network device - checking for carrier inside open is wrong, network device API confusion?? - audit the block driver diff --git a/drivers/staging/hv/BlkVsc.c b/drivers/staging/hv/blkvsc.c index a48ee3a12646..0daebc472e63 100644 --- a/drivers/staging/hv/BlkVsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -23,7 +23,7 @@ #include <linux/kernel.h> #include <linux/mm.h> #include "osd.h" -#include "StorVsc.c" +#include "storvsc.c" static const char *gBlkDriverName = "blkvsc"; @@ -78,7 +78,7 @@ int BlkVscInitialize(struct hv_driver *Driver) storDriver = (struct storvsc_driver_object *)Driver; /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ Driver->name = gBlkDriverName; memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 8f1fda3256ad..61bd0be5fb18 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -32,9 +32,9 @@ #include <scsi/scsi_dbg.h> #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" -#include "StorVscApi.h" +#include "storvsc_api.h" #define BLKVSC_MINORS 64 @@ -149,13 +149,14 @@ static int blkvsc_do_flush(struct block_device_context *blkdev); static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev); static int blkvsc_do_pending_reqs(struct block_device_context *blkdev); - static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE; +module_param(blkvsc_ringbuffer_size, int, S_IRUGO); +MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)"); /* The one and only one */ static struct blkvsc_driver_context g_blkvsc_drv; -static struct block_device_operations block_ops = { +static const struct block_device_operations block_ops = { .owner = THIS_MODULE, .open = blkvsc_open, .release = blkvsc_release, @@ -165,7 +166,7 @@ static struct block_device_operations block_ops = { .ioctl = blkvsc_ioctl, }; -/** +/* * blkvsc_drv_init - BlkVsc driver initialization. */ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) @@ -245,7 +246,7 @@ static void blkvsc_drv_exit(void) return; } -/** +/* * blkvsc_probe - Add a new device for this driver */ static int blkvsc_probe(struct device *device) @@ -288,8 +289,8 @@ static int blkvsc_probe(struct device *device) /* Initialize what we can here */ spin_lock_init(&blkdev->lock); - ASSERT(sizeof(struct blkvsc_request_group) <= - sizeof(struct blkvsc_request)); + /* ASSERT(sizeof(struct blkvsc_request_group) <= */ + /* sizeof(struct blkvsc_request)); */ blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device), sizeof(struct blkvsc_request) + @@ -555,7 +556,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkdev->device_type = UNKNOWN_DEV_TYPE; } - DPRINT_DBG(BLKVSC_DRV, "device type %d \n", device_type); + DPRINT_DBG(BLKVSC_DRV, "device type %d\n", device_type); blkdev->device_id_len = buf[7]; if (blkdev->device_id_len > 64) @@ -733,7 +734,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) return 0; } -/** +/* * blkvsc_remove() - Callback when our device is removed */ static int blkvsc_remove(struct device *device) @@ -808,8 +809,8 @@ static int blkvsc_remove(struct device *device) static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req) { - ASSERT(blkvsc_req->req); - ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8)); + /* ASSERT(blkvsc_req->req); */ + /* ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8)); */ blkvsc_req->cmd_len = 16; @@ -940,7 +941,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, int pending = 0; struct blkvsc_request_group *group = NULL; - DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu \n", blkdev, req, + DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu\n", blkdev, req, (unsigned long)blk_rq_pos(req)); /* Create a group to tie req to list of blkvsc_reqs */ @@ -1116,7 +1117,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) unsigned long flags; struct blkvsc_request *comp_req, *tmp; - ASSERT(blkvsc_req->group); + /* ASSERT(blkvsc_req->group); */ DPRINT_DBG(BLKVSC_DRV, "blkdev %p blkvsc_req %p group %p type %s " "sect_start %lu sect_count %ld len %d group outstd %d " @@ -1144,7 +1145,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) &blkvsc_req->group->blkvsc_req_list, req_entry) { DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p " - "sect_start %lu sect_count %ld \n", + "sect_start %lu sect_count %ld\n", comp_req, (unsigned long)comp_req->sector_start, comp_req->sector_count); @@ -1198,7 +1199,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) &pend_req->group->blkvsc_req_list, req_entry) { DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p " - "sect_start %lu sect_count %ld \n", + "sect_start %lu sect_count %ld\n", comp_req, (unsigned long) comp_req->sector_start, comp_req->sector_count); @@ -1213,7 +1214,10 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) (!comp_req->request.Status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size); - ASSERT(ret != 0); + + /* FIXME: shouldn't this do more than return? */ + if (ret) + goto out; } kmem_cache_free(blkdev->request_pool, comp_req); @@ -1245,6 +1249,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) kmem_cache_free(blkdev->request_pool, pend_req); } +out: return ret; } @@ -1276,7 +1281,7 @@ static void blkvsc_request(struct request_queue *queue) struct request *req; int ret = 0; - DPRINT_DBG(BLKVSC_DRV, "- enter \n"); + DPRINT_DBG(BLKVSC_DRV, "- enter\n"); while ((req = blk_peek_request(queue)) != NULL) { DPRINT_DBG(BLKVSC_DRV, "- req %p\n", req); @@ -1485,7 +1490,7 @@ static int __init blkvsc_init(void) { int ret; - ASSERT(sizeof(sector_t) == 8); /* Make sure CONFIG_LBD is set */ + BUILD_BUG_ON(sizeof(sector_t) != 8); DPRINT_ENTER(BLKVSC_DRV); @@ -1507,6 +1512,6 @@ static void __exit blkvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -module_param(blkvsc_ringbuffer_size, int, S_IRUGO); +MODULE_DESCRIPTION("Microsoft Hyper-V virtual block driver"); module_init(blkvsc_init); module_exit(blkvsc_exit); diff --git a/drivers/staging/hv/Channel.c b/drivers/staging/hv/channel.c index e69e9ee704ac..f047c5a7f64c 100644 --- a/drivers/staging/hv/Channel.c +++ b/drivers/staging/hv/channel.c @@ -21,9 +21,10 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/slab.h> +#include <linux/module.h> #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" /* Internal routines */ static int VmbusChannelCreateGpadlHeader( @@ -65,8 +66,9 @@ static void DumpMonitorPage(struct hv_monitor_page *MonitorPage) } #endif -/** - * VmbusChannelSetEvent - Trigger an event notification on the specified channel. +/* + * VmbusChannelSetEvent - Trigger an event notification on the specified + * channel. */ static void VmbusChannelSetEvent(struct vmbus_channel *Channel) { @@ -120,7 +122,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) } #endif -/** +/* * VmbusChannelGetDebugInfo -Retrieve various channel debug info */ void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, @@ -165,7 +167,7 @@ void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel, RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound); } -/** +/* * VmbusChannelOpen - Open the specified channel. */ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, @@ -173,16 +175,16 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, void (*OnChannelCallback)(void *context), void *Context) { struct vmbus_channel_open_channel *openMsg; - struct vmbus_channel_msginfo *openInfo; + struct vmbus_channel_msginfo *openInfo = NULL; void *in, *out; unsigned long flags; - int ret; + int ret, err = 0; DPRINT_ENTER(VMBUS); /* Aligned to page size */ - ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); - ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); + /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */ + /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */ NewChannel->OnChannelCallback = OnChannelCallback; NewChannel->ChannelCallbackContext = Context; @@ -190,8 +192,10 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, /* Allocate the ring buffer */ out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT); - ASSERT(out); - ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); + if (!out) + return -ENOMEM; + + /* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */ in = (void *)((unsigned long)out + SendRingBufferSize); @@ -199,9 +203,18 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, NewChannel->RingBufferPageCount = (SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT; - RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); + ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize); + if (ret != 0) { + err = ret; + goto errorout; + } + + ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); + if (ret != 0) { + err = ret; + goto errorout; + } - RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize); /* Establish the gpadl for the ring buffer */ DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", @@ -215,6 +228,11 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, RecvRingBufferSize, &NewChannel->RingBufferGpadlHandle); + if (ret != 0) { + err = ret; + goto errorout; + } + DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p " "size %d recv ring %p size %d, downstreamoffset %d>", NewChannel, NewChannel->OfferMsg.ChildRelId, @@ -229,21 +247,31 @@ int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize, openInfo = kmalloc(sizeof(*openInfo) + sizeof(struct vmbus_channel_open_channel), GFP_KERNEL); - ASSERT(openInfo != NULL); + if (!openInfo) { + err = -ENOMEM; + goto errorout; + } openInfo->WaitEvent = osd_WaitEventCreate(); + if (!openInfo->WaitEvent) { + err = -ENOMEM; + goto errorout; + } openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg; openMsg->Header.MessageType = ChannelMessageOpenChannel; openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */ openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId; openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle; - ASSERT(openMsg->RingBufferGpadlHandle); openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >> PAGE_SHIFT; openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ - ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES); + if (UserDataLen > MAX_USER_DEFINED_BYTES) { + err = -EINVAL; + goto errorout; + } + if (UserDataLen) memcpy(openMsg->UserData, UserData, UserDataLen); @@ -281,10 +309,19 @@ Cleanup: DPRINT_EXIT(VMBUS); return 0; + +errorout: + RingBufferCleanup(&NewChannel->Outbound); + RingBufferCleanup(&NewChannel->Inbound); + osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize) + >> PAGE_SHIFT); + kfree(openInfo); + return err; } -/** - * DumpGpadlBody - Dump the gpadl body message to the console for debugging purposes. +/* + * DumpGpadlBody - Dump the gpadl body message to the console for + * debugging purposes. */ static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) { @@ -300,8 +337,9 @@ static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len) i, Gpadl->Pfn[i]); } -/** - * DumpGpadlHeader - Dump the gpadl header message to the console for debugging purposes. +/* + * DumpGpadlHeader - Dump the gpadl header message to the console for + * debugging purposes. */ static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) { @@ -325,7 +363,7 @@ static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl) } } -/** +/* * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer */ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, @@ -338,13 +376,13 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, struct vmbus_channel_gpadl_header *gpaHeader; struct vmbus_channel_gpadl_body *gpadlBody; struct vmbus_channel_msginfo *msgHeader; - struct vmbus_channel_msginfo *msgBody; + struct vmbus_channel_msginfo *msgBody = NULL; u32 msgSize; int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize; /* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */ - ASSERT((Size & (PAGE_SIZE-1)) == 0); + /* ASSERT((Size & (PAGE_SIZE-1)) == 0); */ pageCount = Size >> PAGE_SHIFT; pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT; @@ -362,6 +400,8 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, sizeof(struct vmbus_channel_gpadl_header) + sizeof(struct gpa_range) + pfnCount * sizeof(u64); msgHeader = kzalloc(msgSize, GFP_KERNEL); + if (!msgHeader) + goto nomem; INIT_LIST_HEAD(&msgHeader->SubMsgList); msgHeader->MessageSize = msgSize; @@ -396,7 +436,9 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, sizeof(struct vmbus_channel_gpadl_body) + pfnCurr * sizeof(u64); msgBody = kzalloc(msgSize, GFP_KERNEL); - ASSERT(msgBody); + /* FIXME: we probably need to more if this fails */ + if (!msgBody) + goto nomem; msgBody->MessageSize = msgSize; (*MessageCount)++; gpadlBody = @@ -439,9 +481,13 @@ static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size, } return 0; +nomem: + kfree(msgHeader); + kfree(msgBody); + return -ENOMEM; } -/** +/* * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer * * @Channel: a channel @@ -455,24 +501,29 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, struct vmbus_channel_gpadl_header *gpadlMsg; struct vmbus_channel_gpadl_body *gpadlBody; /* struct vmbus_channel_gpadl_created *gpadlCreated; */ - struct vmbus_channel_msginfo *msgInfo; + struct vmbus_channel_msginfo *msgInfo = NULL; struct vmbus_channel_msginfo *subMsgInfo; u32 msgCount; struct list_head *curr; u32 nextGpadlHandle; unsigned long flags; - int ret; + int ret = 0; DPRINT_ENTER(VMBUS); nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle); atomic_inc(&gVmbusConnection.NextGpadlHandle); - VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); - ASSERT(msgInfo != NULL); - ASSERT(msgCount > 0); + ret = VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount); + if (ret) + return ret; msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg; gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader; gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId; @@ -518,7 +569,9 @@ int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer, ret = VmbusPostMessage(gpadlBody, subMsgInfo->MessageSize - sizeof(*subMsgInfo)); - ASSERT(ret == 0); + if (ret != 0) + goto Cleanup; + } } osd_WaitEventWait(msgInfo->WaitEvent); @@ -545,7 +598,7 @@ Cleanup: return ret; } -/** +/* * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle */ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) @@ -557,13 +610,18 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) DPRINT_ENTER(VMBUS); - ASSERT(GpadlHandle != 0); + /* ASSERT(GpadlHandle != 0); */ info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); - ASSERT(info != NULL); + if (!info) + return -ENOMEM; info->WaitEvent = osd_WaitEventCreate(); + if (!info->WaitEvent) { + kfree(info); + return -ENOMEM; + } msg = (struct vmbus_channel_gpadl_teardown *)info->Msg; @@ -598,7 +656,7 @@ int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle) return ret; } -/** +/* * VmbusChannelClose - Close the specified channel */ void VmbusChannelClose(struct vmbus_channel *Channel) @@ -617,7 +675,10 @@ void VmbusChannelClose(struct vmbus_channel *Channel) /* Send a closing message */ info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_close_channel), GFP_KERNEL); - ASSERT(info != NULL); + /* FIXME: can't do anything other than return here because the + * function is void */ + if (!info) + return; /* info->waitEvent = osd_WaitEventCreate(); */ @@ -664,7 +725,18 @@ void VmbusChannelClose(struct vmbus_channel *Channel) } /** - * VmbusChannelSendPacket - Send the specified buffer on the given channel + * VmbusChannelSendPacket() - Send the specified buffer on the given channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @RequestId: Identifier of the request + * @vmbus_packet_type: Type of packet that is being send e.g. negotiate, time + * packet etc. + * + * Sends data in @Buffer directly to hyper-v via the vmbus + * This will send the data unparsed to hyper-v. + * + * Mainly used by Hyper-V drivers. */ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, u32 BufferLen, u64 RequestId, @@ -683,7 +755,7 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, DumpVmbusChannel(Channel); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = Type; /* VmbusPacketTypeDataInBand; */ @@ -708,9 +780,11 @@ int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer, return ret; } +EXPORT_SYMBOL(VmbusChannelSendPacket); -/** - * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer packets using a GPADL Direct packet type. +/* + * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer + * packets using a GPADL Direct packet type. */ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, struct hv_page_buffer PageBuffers[], @@ -728,7 +802,8 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, DPRINT_ENTER(VMBUS); - ASSERT(PageCount <= MAX_PAGE_BUFFER_COUNT); + if (PageCount > MAX_PAGE_BUFFER_COUNT) + return -EINVAL; DumpVmbusChannel(Channel); @@ -742,7 +817,7 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, packetLen = descSize + BufferLen; packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = VmbusPacketTypeDataUsingGpaDirect; @@ -774,8 +849,9 @@ int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel, return ret; } -/** - * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet using a GPADL Direct packet type. +/* + * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet + * using a GPADL Direct packet type. */ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, struct hv_multipage_buffer *MultiPageBuffer, @@ -798,8 +874,8 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u", MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount); - ASSERT(PfnCount > 0); - ASSERT(PfnCount <= MAX_MULTIPAGE_BUFFER_COUNT); + if ((PfnCount < 0) || (PfnCount > MAX_MULTIPAGE_BUFFER_COUNT)) + return -EINVAL; /* * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is @@ -811,7 +887,7 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, packetLen = descSize + BufferLen; packetLenAligned = ALIGN_UP(packetLen, sizeof(u64)); - ASSERT((packetLenAligned - packetLen) < sizeof(u64)); + /* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */ /* Setup the descriptor */ desc.Type = VmbusPacketTypeDataUsingGpaDirect; @@ -843,10 +919,20 @@ int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel, return ret; } + /** - * VmbusChannelRecvPacket - Retrieve the user packet on the specified channel + * VmbusChannelRecvPacket() - Retrieve the user packet on the specified channel + * @Channel: Pointer to vmbus_channel structure. + * @Buffer: Pointer to the buffer you want to receive the data into. + * @BufferLen: Maximum size of what the the buffer will hold + * @BufferActualLen: The actual size of the data after it was received + * @RequestId: Identifier of the request + * + * Receives directly from the hyper-v vmbus and puts the data it received + * into Buffer. This will receive the data unparsed from hyper-v. + * + * Mainly used by Hyper-V drivers. */ -/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, u32 BufferLen, u32 *BufferActualLen, u64 *RequestId) { @@ -908,8 +994,9 @@ int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer, return 0; } +EXPORT_SYMBOL(VmbusChannelRecvPacket); -/** +/* * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel */ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, @@ -972,20 +1059,20 @@ int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer, return 0; } -/** +/* * VmbusChannelOnChannelEvent - Channel event callback */ void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel) { DumpVmbusChannel(Channel); - ASSERT(Channel->OnChannelCallback); + /* ASSERT(Channel->OnChannelCallback); */ Channel->OnChannelCallback(Channel->ChannelCallbackContext); mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100)); } -/** +/* * VmbusChannelOnTimer - Timer event callback */ void VmbusChannelOnTimer(unsigned long data) @@ -996,7 +1083,7 @@ void VmbusChannelOnTimer(unsigned long data) channel->OnChannelCallback(channel->ChannelCallbackContext); } -/** +/* * DumpVmbusChannel - Dump vmbus channel info to the console */ static void DumpVmbusChannel(struct vmbus_channel *Channel) diff --git a/drivers/staging/hv/Channel.h b/drivers/staging/hv/channel.h index 6b283edcae68..acb2c556369b 100644 --- a/drivers/staging/hv/Channel.h +++ b/drivers/staging/hv/channel.h @@ -25,7 +25,7 @@ #ifndef _CHANNEL_H_ #define _CHANNEL_H_ -#include "ChannelMgmt.h" +#include "channel_mgmt.h" /* The format must be the same as struct vmdata_gpa_direct */ struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER { diff --git a/drivers/staging/hv/ChannelInterface.c b/drivers/staging/hv/channel_interface.c index 019b064f7cb3..d9f51ac75eaa 100644 --- a/drivers/staging/hv/ChannelInterface.c +++ b/drivers/staging/hv/channel_interface.c @@ -23,7 +23,7 @@ #include <linux/kernel.h> #include <linux/mm.h> #include "osd.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" static int IVmbusChannelOpen(struct hv_device *device, u32 SendBufferSize, u32 RecvRingBufferSize, void *UserData, diff --git a/drivers/staging/hv/ChannelInterface.h b/drivers/staging/hv/channel_interface.h index 27b7a253b711..6acaf6ce2c48 100644 --- a/drivers/staging/hv/ChannelInterface.h +++ b/drivers/staging/hv/channel_interface.h @@ -25,7 +25,7 @@ #ifndef _CHANNEL_INTERFACE_H_ #define _CHANNEL_INTERFACE_H_ -#include "VmbusApi.h" +#include "vmbus_api.h" void GetChannelInterface(struct vmbus_channel_interface *ChannelInterface); diff --git a/drivers/staging/hv/ChannelMgmt.c b/drivers/staging/hv/channel_mgmt.c index 5f92c2102ab4..3f53b4d1e4cf 100644 --- a/drivers/staging/hv/ChannelMgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -22,18 +22,22 @@ #include <linux/mm.h> #include <linux/slab.h> #include <linux/list.h> +#include <linux/module.h> #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" +#include "utils.h" struct vmbus_channel_message_table_entry { enum vmbus_channel_message_type messageType; void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 4 +#define MAX_MSG_TYPES 3 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 7 + static const struct hv_guid - gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { + gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ /* Storage - SCSI */ { @@ -69,9 +73,167 @@ static const struct hv_guid 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 } }, + /* 0E0B6031-5213-4934-818B-38D90CED39DB */ + /* Shutdown */ + { + .data = { + 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB + } + }, + /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ + /* TimeSync */ + { + .data = { + 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf + } + }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .data = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + } + }, }; + /** + * 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 + * + * @icmsghdrp is of type &struct icmsg_hdr. + * @negop is of type &struct icmsg_negotiate. + * Set up and fill in default negotiate response message. This response can + * come from both the vmbus driver and the hv_utils driver. The current api + * will respond properly to both Windows 2008 and Windows 2008-R2 operating + * systems. + * + * Mainly used by Hyper-V drivers. + */ +void prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, + struct icmsg_negotiate *negop, + u8 *buf) +{ + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + icmsghdrp->icmsgsize = 0x10; + + negop = (struct icmsg_negotiate *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + if (negop->icframe_vercnt == 2 && + negop->icversion_data[1].major == 3) { + negop->icversion_data[0].major = 3; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 3; + negop->icversion_data[1].minor = 0; + } else { + negop->icversion_data[0].major = 1; + negop->icversion_data[0].minor = 0; + negop->icversion_data[1].major = 1; + negop->icversion_data[1].minor = 0; + } + + negop->icframe_vercnt = 1; + 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 gracefull 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; + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(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; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 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 + }, + .callback = chn_cb_negotiate, + .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 + }, + .callback = chn_cb_negotiate, + .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 + }, + .callback = chn_cb_negotiate, + .log_msg = "Heartbeat channel functionality initialized" + }, +}; +EXPORT_SYMBOL(hv_cb_utils); + +/* * AllocVmbusChannel - Allocate and initialize a vmbus channel object */ struct vmbus_channel *AllocVmbusChannel(void) @@ -97,7 +259,7 @@ struct vmbus_channel *AllocVmbusChannel(void) return channel; } -/** +/* * ReleaseVmbusChannel - Release the vmbus channel object itself */ static inline void ReleaseVmbusChannel(void *context) @@ -115,7 +277,7 @@ static inline void ReleaseVmbusChannel(void *context) DPRINT_EXIT(VMBUS); } -/** +/* * FreeVmbusChannel - Release the resources used by the vmbus channel object */ void FreeVmbusChannel(struct vmbus_channel *Channel) @@ -131,8 +293,9 @@ void FreeVmbusChannel(struct vmbus_channel *Channel) Channel); } -/** - * VmbusChannelProcessOffer - Process the offer by creating a channel/device associated with this offer +/* + * VmbusChannelProcessOffer - Process the offer by creating a channel/device + * associated with this offer */ static void VmbusChannelProcessOffer(void *context) { @@ -140,6 +303,7 @@ static void VmbusChannelProcessOffer(void *context) struct vmbus_channel *channel; bool fNew = true; int ret; + int cnt; unsigned long flags; DPRINT_ENTER(VMBUS); @@ -209,11 +373,28 @@ static void VmbusChannelProcessOffer(void *context) * can cleanup properly */ newChannel->State = CHANNEL_OPEN_STATE; + cnt = 0; + + while (cnt != MAX_MSG_TYPES) { + if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType, + &hv_cb_utils[cnt].data, + sizeof(struct hv_guid)) == 0) { + DPRINT_INFO(VMBUS, "%s", + hv_cb_utils[cnt].log_msg); + + if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE, + 2 * PAGE_SIZE, NULL, 0, + hv_cb_utils[cnt].callback, + newChannel) == 0) + hv_cb_utils[cnt].channel = newChannel; + } + cnt++; + } } DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal */ static void VmbusChannelProcessRescindOffer(void *context) @@ -225,7 +406,7 @@ static void VmbusChannelProcessRescindOffer(void *context) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition. * * We ignore all offers except network and storage offers. For each network and @@ -308,7 +489,7 @@ static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOfferRescind - Rescind offer handler. * * We queue a work item to process this offer synchronously @@ -335,7 +516,7 @@ static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered. * * Nothing to do here. @@ -347,7 +528,7 @@ static void VmbusChannelOnOffersDelivered( DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnOpenResult - Open result handler. * * This is invoked when we received a response to our channel open request. @@ -395,7 +576,7 @@ static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnGpadlCreated - GPADL created handler. * * This is invoked when we received a response to our gpadl create request. @@ -447,7 +628,7 @@ static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnGpadlTorndown - GPADL torndown handler. * * This is invoked when we received a response to our gpadl teardown request. @@ -495,7 +676,7 @@ static void VmbusChannelOnGpadlTorndown( DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelOnVersionResponse - Version response handler * * This is invoked when we received a response to our initiate contact request. @@ -558,7 +739,7 @@ static struct vmbus_channel_message_table_entry {ChannelMessageUnload, NULL}, }; -/** +/* * VmbusOnChannelMessage - Handler for channel protocol messages. * * This is invoked in the vmbus worker thread context. @@ -597,7 +778,7 @@ void VmbusOnChannelMessage(void *Context) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusChannelRequestOffers - Send a request to get all our pending offers. */ int VmbusChannelRequestOffers(void) @@ -611,9 +792,15 @@ int VmbusChannelRequestOffers(void) msgInfo = kmalloc(sizeof(*msgInfo) + sizeof(struct vmbus_channel_message_header), GFP_KERNEL); - ASSERT(msgInfo != NULL); + if (!msgInfo) + return -ENOMEM; msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + kfree(msgInfo); + return -ENOMEM; + } + msg = (struct vmbus_channel_message_header *)msgInfo->Msg; msg->MessageType = ChannelMessageRequestOffers; @@ -651,8 +838,9 @@ Cleanup: return ret; } -/** - * VmbusChannelReleaseUnattachedChannels - Release channels that are unattached/unconnected ie (no drivers associated) +/* + * VmbusChannelReleaseUnattachedChannels - Release channels that are + * unattached/unconnected ie (no drivers associated) */ void VmbusChannelReleaseUnattachedChannels(void) { diff --git a/drivers/staging/hv/ChannelMgmt.h b/drivers/staging/hv/channel_mgmt.h index fa973d86b624..5908b81d3e9c 100644 --- a/drivers/staging/hv/ChannelMgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -27,9 +27,9 @@ #include <linux/list.h> #include <linux/timer.h> -#include "RingBuffer.h" -#include "VmbusChannelInterface.h" -#include "VmbusPacketFormat.h" +#include "ring_buffer.h" +#include "vmbus_channel_interface.h" +#include "vmbus_packet_format.h" /* Version 1 messages */ enum vmbus_channel_message_type { diff --git a/drivers/staging/hv/Connection.c b/drivers/staging/hv/connection.c index e0ea9cf90f03..e8824dadffc3 100644 --- a/drivers/staging/hv/Connection.c +++ b/drivers/staging/hv/connection.c @@ -26,7 +26,7 @@ #include <linux/vmalloc.h> #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" struct VMBUS_CONNECTION gVmbusConnection = { @@ -34,7 +34,7 @@ struct VMBUS_CONNECTION gVmbusConnection = { .NextGpadlHandle = ATOMIC_INIT(0xE1E10), }; -/** +/* * VmbusConnect - Sends a connect request on the partition service connection */ int VmbusConnect(void) @@ -93,11 +93,16 @@ int VmbusConnect(void) sizeof(struct vmbus_channel_initiate_contact), GFP_KERNEL); if (msgInfo == NULL) { - ret = -1; + ret = -ENOMEM; goto Cleanup; } msgInfo->WaitEvent = osd_WaitEventCreate(); + if (!msgInfo->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } + msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg; msg->Header.MessageType = ChannelMessageInitiateContact; @@ -180,7 +185,7 @@ Cleanup: return ret; } -/** +/* * VmbusDisconnect - Sends a disconnect request on the partition service connection */ int VmbusDisconnect(void) @@ -195,6 +200,8 @@ int VmbusDisconnect(void) return -1; msg = kzalloc(sizeof(struct vmbus_channel_message_header), GFP_KERNEL); + if (!msg) + return -ENOMEM; msg->MessageType = ChannelMessageUnload; @@ -218,7 +225,7 @@ Cleanup: return ret; } -/** +/* * GetChannelFromRelId - Get the channel object given its child relative id (ie channel id) */ struct vmbus_channel *GetChannelFromRelId(u32 relId) @@ -239,7 +246,7 @@ struct vmbus_channel *GetChannelFromRelId(u32 relId) return foundChannel; } -/** +/* * VmbusProcessChannelEvent - Process a channel event notification */ static void VmbusProcessChannelEvent(void *context) @@ -247,7 +254,7 @@ static void VmbusProcessChannelEvent(void *context) struct vmbus_channel *channel; u32 relId = (u32)(unsigned long)context; - ASSERT(relId > 0); + /* ASSERT(relId > 0); */ /* * Find the channel based on this relid and invokes the @@ -259,15 +266,15 @@ static void VmbusProcessChannelEvent(void *context) VmbusChannelOnChannelEvent(channel); /* * WorkQueueQueueWorkItem(channel->dataWorkQueue, - * VmbusChannelOnChannelEvent, - * (void*)channel); + * VmbusChannelOnChannelEvent, + * (void*)channel); */ } else { DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId); } } -/** +/* * VmbusOnEvents - Handler for events */ void VmbusOnEvents(void) @@ -308,7 +315,7 @@ void VmbusOnEvents(void) return; } -/** +/* * VmbusPostMessage - Send a msg on the vmbus's message connection */ int VmbusPostMessage(void *buffer, size_t bufferLen) @@ -320,7 +327,7 @@ int VmbusPostMessage(void *buffer, size_t bufferLen) return HvPostMessage(connId, 1, buffer, bufferLen); } -/** +/* * VmbusSetEvent - Send an event notification to the parent */ int VmbusSetEvent(u32 childRelId) diff --git a/drivers/staging/hv/Hv.c b/drivers/staging/hv/hv.c index 3a1112d29aeb..6c77e64027f0 100644 --- a/drivers/staging/hv/Hv.c +++ b/drivers/staging/hv/hv.c @@ -25,7 +25,7 @@ #include <linux/vmalloc.h> #include "osd.h" #include "logging.h" -#include "VmbusPrivate.h" +#include "vmbus_private.h" /* The one and only */ struct hv_context gHvContext = { @@ -35,7 +35,7 @@ struct hv_context gHvContext = { .SignalEventBuffer = NULL, }; -/** +/* * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor */ static int HvQueryHypervisorPresence(void) @@ -56,7 +56,7 @@ static int HvQueryHypervisorPresence(void) return ecx & HV_PRESENT_BIT; } -/** +/* * HvQueryHypervisorInfo - Get version info of the windows hypervisor */ static int HvQueryHypervisorInfo(void) @@ -125,7 +125,7 @@ static int HvQueryHypervisorInfo(void) return maxLeaf; } -/** +/* * HvDoHypercall - Invoke the specified hypercall */ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) @@ -180,7 +180,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) #endif /* !x86_64 */ } -/** +/* * HvInit - Main initialization routine. * * This routine must be called before any other routines in here are called @@ -294,7 +294,7 @@ Cleanup: return ret; } -/** +/* * HvCleanup - Cleanup routine. * * This routine is called normally during driver unloading or exiting. @@ -305,11 +305,9 @@ void HvCleanup(void) DPRINT_ENTER(VMBUS); - if (gHvContext.SignalEventBuffer) { - kfree(gHvContext.SignalEventBuffer); - gHvContext.SignalEventBuffer = NULL; - gHvContext.SignalEventParam = NULL; - } + kfree(gHvContext.SignalEventBuffer); + gHvContext.SignalEventBuffer = NULL; + gHvContext.SignalEventParam = NULL; if (gHvContext.HypercallPage) { hypercallMsr.AsUINT64 = 0; @@ -321,7 +319,7 @@ void HvCleanup(void) DPRINT_EXIT(VMBUS); } -/** +/* * HvPostMessage - Post a message using the hypervisor message IPC. * * This involves a hypercall. @@ -362,7 +360,7 @@ u16 HvPostMessage(union hv_connection_id connectionId, } -/** +/* * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC. * * This involves a hypercall. @@ -376,7 +374,7 @@ u16 HvSignalEvent(void) return status; } -/** +/* * HvSynicInit - Initialize the Synthethic Interrupt Controller. * * If it is already initialized by another entity (ie x2v shim), we need to @@ -482,7 +480,7 @@ Cleanup: return; } -/** +/* * HvSynicCleanup - Cleanup routine for HvSynicInit(). */ void HvSynicCleanup(void *arg) diff --git a/drivers/staging/hv/Hv.h b/drivers/staging/hv/hv.h index 41f5ebb86e17..41f5ebb86e17 100644 --- a/drivers/staging/hv/Hv.h +++ b/drivers/staging/hv/hv.h diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c new file mode 100644 index 000000000000..8a49aafea37a --- /dev/null +++ b/drivers/staging/hv/hv_utils.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2010, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang <haiyangz@microsoft.com> + * Hank Janssen <hjanssen@microsoft.com> + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/sysctl.h> +#include <linux/reboot.h> + +#include "logging.h" +#include "osd.h" +#include "vmbus.h" +#include "vmbus_packet_format.h" +#include "vmbus_channel_interface.h" +#include "version_info.h" +#include "channel.h" +#include "vmbus_private.h" +#include "vmbus_api.h" +#include "utils.h" + + +static void shutdown_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + u8 execute_shutdown = false; + + struct shutdown_msg_data *shutdown_msg; + + struct icmsg_hdr *icmsghdrp; + struct icmsg_negotiate *negop = NULL; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, negop, buf); + } else { + shutdown_msg = (struct shutdown_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + switch (shutdown_msg->flags) { + case 0: + case 1: + icmsghdrp->status = HV_S_OK; + execute_shutdown = true; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " gracefull shutdown initiated"); + break; + default: + icmsghdrp->status = HV_E_FAIL; + execute_shutdown = false; + + DPRINT_INFO(VMBUS, "Shutdown request received -" + " Invalid request"); + break; + }; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); + + if (execute_shutdown == true) + orderly_poweroff(false); +} + +/* + * Set guest time to host UTC time. + */ +static inline void do_adj_guesttime(u64 hosttime) +{ + s64 host_tns; + struct timespec host_ts; + + host_tns = (hosttime - WLTIMEDELTA) * 100; + host_ts = ns_to_timespec(host_tns); + + do_settimeofday(&host_ts); +} + +/* + * Synchronize time with host after reboot, restore, etc. + * + * ICTIMESYNCFLAG_SYNC flag bit indicates reboot, restore events of the VM. + * After reboot the flag ICTIMESYNCFLAG_SYNC is included in the first time + * message after the timesync channel is opened. Since the hv_utils module is + * loaded after hv_vmbus, the first message is usually missed. The other + * thing is, systime is automatically set to emulated hardware clock which may + * not be UTC time or in the same time zone. So, to override these effects, we + * use the first 50 time samples for initial system time setting. + */ +static inline void adj_guesttime(u64 hosttime, u8 flags) +{ + static s32 scnt = 50; + + if ((flags & ICTIMESYNCFLAG_SYNC) != 0) { + do_adj_guesttime(hosttime); + return; + } + + if ((flags & ICTIMESYNCFLAG_SAMPLE) != 0 && scnt > 0) { + scnt--; + do_adj_guesttime(hosttime); + } +} + +/* + * Time Sync Channel message handler. + */ +static void timesync_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct ictimesync_data *timedatap; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + timedatap = (struct ictimesync_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + adj_guesttime(timedatap->parenttime, timedatap->flags); + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} + +/* + * Heartbeat functionality. + * Every two seconds, Hyper-V send us a heartbeat request message. + * we respond to this message, and Hyper-V knows we are alive. + */ +static void heartbeat_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct heartbeat_msg_data *heartbeat_msg; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + heartbeat_msg = (struct heartbeat_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + DPRINT_DBG(VMBUS, "heartbeat seq = %lld", + heartbeat_msg->seq_num); + + heartbeat_msg->seq_num += 1; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} + +static int __init init_hyperv_utils(void) +{ + printk(KERN_INFO "Registering HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &shutdown_onchannelcallback; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + ×ync_onchannelcallback; + hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &heartbeat_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; + + return 0; +} + +static void exit_hyperv_utils(void) +{ + printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); + + hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; +} + +module_init(init_hyperv_utils); +module_exit(exit_hyperv_utils); + +MODULE_DESCRIPTION("Hyper-V Utilities"); +MODULE_VERSION(HV_DRV_VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/hv/logging.h b/drivers/staging/hv/logging.h index 9e55617bd670..ad4cfcfb7b11 100644 --- a/drivers/staging/hv/logging.h +++ b/drivers/staging/hv/logging.h @@ -61,13 +61,6 @@ extern unsigned int vmbus_loglevel; -#define ASSERT(expr) \ - if (!(expr)) { \ - printk(KERN_CRIT "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr, __FILE__, __func__, __LINE__); \ - __asm__ __volatile__("int3"); \ - } - #define DPRINT(mod, lvl, fmt, args...) do {\ if ((mod & (HIWORD(vmbus_loglevel))) && \ (lvl <= LOWORD(vmbus_loglevel))) \ diff --git a/drivers/staging/hv/NetVsc.c b/drivers/staging/hv/netvsc.c index e4bf82297504..ba15059c45b2 100644 --- a/drivers/staging/hv/NetVsc.c +++ b/drivers/staging/hv/netvsc.c @@ -25,8 +25,8 @@ #include <linux/slab.h> #include "osd.h" #include "logging.h" -#include "NetVsc.h" -#include "RndisFilter.h" +#include "netvsc.h" +#include "rndis_filter.h" /* Globals */ @@ -92,7 +92,7 @@ static struct netvsc_device *AllocNetDevice(struct hv_device *Device) static void FreeNetDevice(struct netvsc_device *Device) { - ASSERT(atomic_read(&Device->RefCount) == 0); + WARN_ON(atomic_read(&Device->RefCount) == 0); Device->Device->Extension = NULL; kfree(Device); } @@ -131,7 +131,7 @@ static void PutNetDevice(struct hv_device *Device) struct netvsc_device *netDevice; netDevice = Device->Extension; - ASSERT(netDevice); + /* ASSERT(netDevice); */ atomic_dec(&netDevice->RefCount); } @@ -167,7 +167,7 @@ static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) return netDevice; } -/** +/* * NetVscInitialize - Main entry point */ int NetVscInitialize(struct hv_driver *drv) @@ -184,14 +184,15 @@ int NetVscInitialize(struct hv_driver *drv) sizeof(struct vmtransfer_page_packet_header)); /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ drv->name = gDriverName; memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); /* Make sure it is set by the caller */ - ASSERT(driver->OnReceiveCallback); - ASSERT(driver->OnLinkStatusChanged); + /* FIXME: These probably should still be tested in some way */ + /* ASSERT(driver->OnReceiveCallback); */ + /* ASSERT(driver->OnLinkStatusChanged); */ /* Setup the dispatch table */ driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; @@ -222,9 +223,9 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) DPRINT_EXIT(NETVSC); return -1; } - ASSERT(netDevice->ReceiveBufferSize > 0); + /* ASSERT(netDevice->ReceiveBufferSize > 0); */ /* page-size grandularity */ - ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); + /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->ReceiveBuffer = osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); @@ -236,8 +237,8 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } /* page-aligned buffer */ - ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == - 0); + /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ + /* 0); */ DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL..."); @@ -294,8 +295,8 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) } /* Parse the response */ - ASSERT(netDevice->ReceiveSectionCount == 0); - ASSERT(netDevice->ReceiveSections == NULL); + /* ASSERT(netDevice->ReceiveSectionCount == 0); */ + /* ASSERT(netDevice->ReceiveSections == NULL); */ netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; @@ -353,9 +354,13 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) DPRINT_EXIT(NETVSC); return -1; } - ASSERT(netDevice->SendBufferSize > 0); + if (netDevice->SendBufferSize <= 0) { + ret = -EINVAL; + goto Cleanup; + } + /* page-size grandularity */ - ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); + /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->SendBuffer = osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); @@ -366,7 +371,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } /* page-aligned buffer */ - ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); + /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL..."); @@ -705,7 +710,7 @@ static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) DPRINT_EXIT(NETVSC); } -/** +/* * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added */ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) @@ -749,6 +754,10 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) &netDevice->ReceivePacketList); } netDevice->ChannelInitEvent = osd_WaitEventCreate(); + if (!netDevice->ChannelInitEvent) { + ret = -ENOMEM; + goto Cleanup; + } /* Open the channel */ ret = Device->Driver->VmbusChannelInterface.Open(Device, @@ -807,7 +816,7 @@ Cleanup: return ret; } -/** +/* * NetVscOnDeviceRemove - Callback when the root bus device is removed */ static int NetVscOnDeviceRemove(struct hv_device *Device) @@ -864,7 +873,7 @@ static int NetVscOnDeviceRemove(struct hv_device *Device) return 0; } -/** +/* * NetVscOnCleanup - Perform any cleanup when the driver is removed */ static void NetVscOnCleanup(struct hv_driver *drv) @@ -908,7 +917,7 @@ static void NetVscOnSendCompletion(struct hv_device *Device, NvspMessage1TypeSendRNDISPacketComplete) { /* Get the send context */ nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; - ASSERT(nvscPacket); + /* ASSERT(nvscPacket); */ /* Notify the layer above us */ nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); @@ -1087,13 +1096,13 @@ static void NetVscOnReceive(struct hv_device *Device, } /* Remove the 1st packet to represent the xfer page packet itself */ - xferpagePacket = (struct xferpage_packet*)listHead.next; + xferpagePacket = (struct xferpage_packet *)listHead.next; list_del(&xferpagePacket->ListEntry); /* This is how much we can satisfy */ xferpagePacket->Count = count - 1; - ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= - vmxferpagePacket->RangeCount); + /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ + /* vmxferpagePacket->RangeCount); */ if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " @@ -1103,7 +1112,7 @@ static void NetVscOnReceive(struct hv_device *Device, /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ for (i = 0; i < (count - 1); i++) { - netvscPacket = (struct hv_netvsc_packet*)listHead.next; + netvscPacket = (struct hv_netvsc_packet *)listHead.next; list_del(&netvscPacket->ListEntry); /* Initialize the netvsc packet */ @@ -1121,9 +1130,9 @@ static void NetVscOnReceive(struct hv_device *Device, vmxferpagePacket->Ranges[i].ByteCount; netvscPacket->PageBufferCount = 1; - ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + - vmxferpagePacket->Ranges[i].ByteCount < - netDevice->ReceiveBufferSize); + /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ + /* vmxferpagePacket->Ranges[i].ByteCount < */ + /* netDevice->ReceiveBufferSize); */ netvscPacket->PageBuffers[0].Length = vmxferpagePacket->Ranges[i].ByteCount; @@ -1161,7 +1170,7 @@ static void NetVscOnReceive(struct hv_device *Device, if (bytesRemain == 0) break; } - ASSERT(bytesRemain == 0); + /* ASSERT(bytesRemain == 0); */ } DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " "(pfn %llx, offset %u, len %u)", i, @@ -1177,7 +1186,7 @@ static void NetVscOnReceive(struct hv_device *Device, NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); } - ASSERT(list_empty(&listHead)); + /* ASSERT(list_empty(&listHead)); */ PutNetDevice(Device); DPRINT_EXIT(NETVSC); @@ -1241,7 +1250,7 @@ static void NetVscOnReceiveCompletion(void *Context) DPRINT_ENTER(NETVSC); - ASSERT(packet->XferPagePacket); + /* ASSERT(packet->XferPagePacket); */ /* * Even though it seems logical to do a GetOutboundNetDevice() here to @@ -1259,7 +1268,7 @@ static void NetVscOnReceiveCompletion(void *Context) /* Overloading use of the lock. */ spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - ASSERT(packet->XferPagePacket->Count > 0); + /* ASSERT(packet->XferPagePacket->Count > 0); */ packet->XferPagePacket->Count--; /* @@ -1286,30 +1295,35 @@ static void NetVscOnReceiveCompletion(void *Context) DPRINT_EXIT(NETVSC); } -void NetVscOnChannelCallback(void *Context) +static void NetVscOnChannelCallback(void *Context) { - const int netPacketSize = 2048; int ret; struct hv_device *device = Context; struct netvsc_device *netDevice; u32 bytesRecvd; u64 requestId; - unsigned char packet[netPacketSize]; + unsigned char *packet; struct vmpacket_descriptor *desc; - unsigned char *buffer = packet; - int bufferlen = netPacketSize; + unsigned char *buffer; + int bufferlen = NETVSC_PACKET_SIZE; DPRINT_ENTER(NETVSC); - ASSERT(device); + /* ASSERT(device); */ + + packet = kzalloc(NETVSC_PACKET_SIZE * sizeof(unsigned char), + GFP_KERNEL); + if (!packet) + return; + buffer = packet; netDevice = GetInboundNetDevice(device); if (!netDevice) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." "ignoring inbound packets", netDevice); DPRINT_EXIT(NETVSC); - return; + goto out; } do { @@ -1341,17 +1355,17 @@ void NetVscOnChannelCallback(void *Context) } /* reset */ - if (bufferlen > netPacketSize) { + if (bufferlen > NETVSC_PACKET_SIZE) { kfree(buffer); buffer = packet; - bufferlen = netPacketSize; + bufferlen = NETVSC_PACKET_SIZE; } } else { /* reset */ - if (bufferlen > netPacketSize) { + if (bufferlen > NETVSC_PACKET_SIZE) { kfree(buffer); buffer = packet; - bufferlen = netPacketSize; + bufferlen = NETVSC_PACKET_SIZE; } break; @@ -1368,12 +1382,12 @@ void NetVscOnChannelCallback(void *Context) } bufferlen = bytesRecvd; - } else { - ASSERT(0); } } while (1); PutNetDevice(device); DPRINT_EXIT(NETVSC); +out: + kfree(buffer); return; } diff --git a/drivers/staging/hv/NetVsc.h b/drivers/staging/hv/netvsc.h index 6e0e03494126..c71dce5b3f7c 100644 --- a/drivers/staging/hv/NetVsc.h +++ b/drivers/staging/hv/netvsc.h @@ -26,9 +26,9 @@ #define _NETVSC_H_ #include <linux/list.h> -#include "VmbusPacketFormat.h" -#include "VmbusChannelInterface.h" -#include "NetVscApi.h" +#include "vmbus_packet_format.h" +#include "vmbus_channel_interface.h" +#include "netvsc_api.h" #define NVSP_INVALID_PROTOCOL_VERSION ((u32)0xFFFFFFFF) @@ -289,6 +289,7 @@ struct nvsp_message { /* Preallocated receive packets */ #define NETVSC_RECEIVE_PACKETLIST_COUNT 256 +#define NETVSC_PACKET_SIZE 2048 /* Per netvsc channel-specific */ struct netvsc_device { diff --git a/drivers/staging/hv/NetVscApi.h b/drivers/staging/hv/netvsc_api.h index 95d7a32b12f2..4b5b3ac458c8 100644 --- a/drivers/staging/hv/NetVscApi.h +++ b/drivers/staging/hv/netvsc_api.h @@ -25,11 +25,7 @@ #ifndef _NETVSC_API_H_ #define _NETVSC_API_H_ -#include "VmbusApi.h" - -/* Defines */ -#define NETVSC_DEVICE_RING_BUFFER_SIZE (64*PAGE_SIZE) -#define HW_MACADDR_LEN 6 +#include "vmbus_api.h" /* Fwd declaration */ struct hv_netvsc_packet; @@ -93,9 +89,6 @@ struct netvsc_driver { u32 RingBufferSize; u32 RequestExtSize; - /* Additional num of page buffers to allocate */ - u32 AdditionalRequestPageBufferCount; - /* * This is set by the caller to allow us to callback when we * receive a packet from the "wire" diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index ab27d9a4446d..55b993298ff4 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -30,20 +30,22 @@ #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> #include <net/pkt_sched.h> #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" -#include "NetVscApi.h" +#include "netvsc_api.h" struct net_device_context { /* point back to our device context */ struct vm_device *device_ctx; - struct net_device_stats stats; + unsigned long avail; }; struct netvsc_driver_context { @@ -53,18 +55,17 @@ struct netvsc_driver_context { struct netvsc_driver drv_obj; }; -static int netvsc_ringbuffer_size = NETVSC_DEVICE_RING_BUFFER_SIZE; +#define PACKET_PAGES_LOWATER 8 +/* Need this many pages to handle worst case fragmented packet */ +#define PACKET_PAGES_HIWATER (MAX_SKB_FRAGS + 2) + +static int ring_size = roundup_pow_of_two(2*MAX_SKB_FRAGS+1); +module_param(ring_size, int, S_IRUGO); +MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); /* The one and only one */ static struct netvsc_driver_context g_netvsc_drv; -static struct net_device_stats *netvsc_get_stats(struct net_device *net) -{ - struct net_device_context *net_device_ctx = netdev_priv(net); - - return &net_device_ctx->stats; -} - static void netvsc_set_multicast_list(struct net_device *net) { } @@ -78,9 +79,6 @@ static int netvsc_open(struct net_device *net) DPRINT_ENTER(NETVSC_DRV); if (netif_carrier_ok(net)) { - memset(&net_device_ctx->stats, 0, - sizeof(struct net_device_stats)); - /* Open up the device */ ret = RndisFilterOnOpen(device_obj); if (ret != 0) { @@ -122,22 +120,20 @@ static void netvsc_xmit_completion(void *context) struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; struct sk_buff *skb = (struct sk_buff *) (unsigned long)packet->Completion.Send.SendCompletionTid; - struct net_device *net; DPRINT_ENTER(NETVSC_DRV); kfree(packet); if (skb) { - net = skb->dev; - dev_kfree_skb_any(skb); + struct net_device *net = skb->dev; + struct net_device_context *net_device_ctx = netdev_priv(net); + unsigned int num_pages = skb_shinfo(skb)->nr_frags + 2; - if (netif_queue_stopped(net)) { - DPRINT_INFO(NETVSC_DRV, "net device (%p) waking up...", - net); + dev_kfree_skb_any(skb); - netif_wake_queue(net); - } + if ((net_device_ctx->avail += num_pages) >= PACKET_PAGES_HIWATER) + netif_wake_queue(net); } DPRINT_EXIT(NETVSC_DRV); @@ -152,65 +148,58 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) (struct netvsc_driver_context *)driver_ctx; struct netvsc_driver *net_drv_obj = &net_drv_ctx->drv_obj; struct hv_netvsc_packet *packet; - int i; int ret; - int num_frags; - int retries = 0; + unsigned int i, num_pages; DPRINT_ENTER(NETVSC_DRV); - /* Support only 1 chain of frags */ - ASSERT(skb_shinfo(skb)->frag_list == NULL); - ASSERT(skb->dev == net); - DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d", skb->len, skb->data_len); - /* Add 1 for skb->data and any additional ones requested */ - num_frags = skb_shinfo(skb)->nr_frags + 1 + - net_drv_obj->AdditionalRequestPageBufferCount; + /* Add 1 for skb->data and additional one for RNDIS */ + num_pages = skb_shinfo(skb)->nr_frags + 1 + 1; + if (num_pages > net_device_ctx->avail) + return NETDEV_TX_BUSY; /* Allocate a netvsc packet based on # of frags. */ packet = kzalloc(sizeof(struct hv_netvsc_packet) + - (num_frags * sizeof(struct hv_page_buffer)) + + (num_pages * sizeof(struct hv_page_buffer)) + net_drv_obj->RequestExtSize, GFP_ATOMIC); if (!packet) { + /* out of memory, silently drop packet */ DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet"); - return -1; + + dev_kfree_skb(skb); + net->stats.tx_dropped++; + return NETDEV_TX_OK; } packet->Extension = (void *)(unsigned long)packet + sizeof(struct hv_netvsc_packet) + - (num_frags * sizeof(struct hv_page_buffer)); + (num_pages * sizeof(struct hv_page_buffer)); /* Setup the rndis header */ - packet->PageBufferCount = num_frags; + packet->PageBufferCount = num_pages; /* TODO: Flush all write buffers/ memory fence ??? */ /* wmb(); */ /* Initialize it from the skb */ - ASSERT(skb->data); packet->TotalDataBufferLength = skb->len; - /* - * Start filling in the page buffers starting at - * AdditionalRequestPageBufferCount offset - */ - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Offset = (unsigned long)skb->data & (PAGE_SIZE - 1); - packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Length = skb->len - skb->data_len; - - ASSERT((skb->len - skb->data_len) <= PAGE_SIZE); - - for (i = net_drv_obj->AdditionalRequestPageBufferCount + 1; - i < num_frags; i++) { - packet->PageBuffers[i].Pfn = - page_to_pfn(skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page); - packet->PageBuffers[i].Offset = - skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].page_offset; - packet->PageBuffers[i].Length = - skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].size; + /* Start filling in the page buffers starting after RNDIS buffer. */ + packet->PageBuffers[1].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; + packet->PageBuffers[1].Offset + = (unsigned long)skb->data & (PAGE_SIZE - 1); + packet->PageBuffers[1].Length = skb_headlen(skb); + + /* Additional fragments are after SKB data */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *f = &skb_shinfo(skb)->frags[i]; + + packet->PageBuffers[i+2].Pfn = page_to_pfn(f->page); + packet->PageBuffers[i+2].Offset = f->page_offset; + packet->PageBuffers[i+2].Length = f->size; } /* Set the completion routine */ @@ -218,55 +207,29 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) packet->Completion.Send.SendCompletionContext = packet; packet->Completion.Send.SendCompletionTid = (unsigned long)skb; -retry_send: ret = net_drv_obj->OnSend(&net_device_ctx->device_ctx->device_obj, packet); - if (ret == 0) { - ret = NETDEV_TX_OK; - net_device_ctx->stats.tx_bytes += skb->len; - net_device_ctx->stats.tx_packets++; - } else { - retries++; - if (retries < 4) { - DPRINT_ERR(NETVSC_DRV, "unable to send..." - "retrying %d...", retries); - udelay(100); - goto retry_send; - } - - /* no more room or we are shutting down */ - DPRINT_ERR(NETVSC_DRV, "unable to send (%d)..." - "marking net device (%p) busy", ret, net); - DPRINT_INFO(NETVSC_DRV, "net device (%p) stopping", net); + net->stats.tx_bytes += skb->len; + net->stats.tx_packets++; - ret = NETDEV_TX_BUSY; - net_device_ctx->stats.tx_dropped++; + DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", + net->stats.tx_packets, + net->stats.tx_bytes); - netif_stop_queue(net); - - /* - * Null it since the caller will free it instead of the - * completion routine - */ - packet->Completion.Send.SendCompletionTid = 0; - - /* - * Release the resources since we will not get any send - * completion - */ - netvsc_xmit_completion((void *)packet); + if ((net_device_ctx->avail -= num_pages) < PACKET_PAGES_LOWATER) + netif_stop_queue(net); + } else { + /* we are shutting down or bus overloaded, just drop packet */ + net->stats.tx_dropped++; + netvsc_xmit_completion(packet); } - DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu", - net_device_ctx->stats.tx_packets, - net_device_ctx->stats.tx_bytes); - DPRINT_EXIT(NETVSC_DRV); - return ret; + return NETDEV_TX_OK; } -/** +/* * netvsc_linkstatus_callback - Link up/down notification */ static void netvsc_linkstatus_callback(struct hv_device *device_obj, @@ -293,18 +256,17 @@ static void netvsc_linkstatus_callback(struct hv_device *device_obj, DPRINT_EXIT(NETVSC_DRV); } -/** - * netvsc_recv_callback - Callback when we receive a packet from the "wire" on the specified device. +/* + * netvsc_recv_callback - Callback when we receive a packet from the + * "wire" on the specified device. */ static int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet) { struct vm_device *device_ctx = to_vm_device(device_obj); struct net_device *net = dev_get_drvdata(&device_ctx->device); - struct net_device_context *net_device_ctx; struct sk_buff *skb; void *data; - int ret; int i; unsigned long flags; @@ -316,14 +278,12 @@ static int netvsc_recv_callback(struct hv_device *device_obj, return 0; } - net_device_ctx = netdev_priv(net); - - /* Allocate a skb - TODO preallocate this */ - /* Pad 2-bytes to align IP header to 16 bytes */ - skb = dev_alloc_skb(packet->TotalDataBufferLength + 2); - ASSERT(skb); - skb_reserve(skb, 2); - skb->dev = net; + /* Allocate a skb - TODO direct I/O to pages? */ + skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength); + if (unlikely(!skb)) { + ++net->stats.rx_dropped; + return 0; + } /* for kmap_atomic */ local_irq_save(flags); @@ -348,39 +308,45 @@ static int netvsc_recv_callback(struct hv_device *device_obj, local_irq_restore(flags); skb->protocol = eth_type_trans(skb, net); - skb->ip_summed = CHECKSUM_NONE; + net->stats.rx_packets++; + net->stats.rx_bytes += skb->len; + /* * Pass the skb back up. Network stack will deallocate the skb when it - * is done + * is done. + * TODO - use NAPI? */ - ret = netif_rx(skb); - - switch (ret) { - case NET_RX_DROP: - net_device_ctx->stats.rx_dropped++; - break; - default: - net_device_ctx->stats.rx_packets++; - net_device_ctx->stats.rx_bytes += skb->len; - break; + netif_rx(skb); - } DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu", - net_device_ctx->stats.rx_packets, - net_device_ctx->stats.rx_bytes); + net->stats.rx_packets, net->stats.rx_bytes); DPRINT_EXIT(NETVSC_DRV); return 0; } +static void netvsc_get_drvinfo(struct net_device *net, + struct ethtool_drvinfo *info) +{ + strcpy(info->driver, "hv_netvsc"); + strcpy(info->version, HV_DRV_VERSION); + strcpy(info->fw_version, "N/A"); +} + +static const struct ethtool_ops ethtool_ops = { + .get_drvinfo = netvsc_get_drvinfo, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_link = ethtool_op_get_link, +}; + static const struct net_device_ops device_ops = { .ndo_open = netvsc_open, .ndo_stop = netvsc_close, .ndo_start_xmit = netvsc_start_xmit, - .ndo_get_stats = netvsc_get_stats, .ndo_set_multicast_list = netvsc_set_multicast_list, }; @@ -413,6 +379,7 @@ static int netvsc_probe(struct device *device) net_device_ctx = netdev_priv(net); net_device_ctx->device_ctx = device_ctx; + net_device_ctx->avail = ring_size; dev_set_drvdata(device, net); /* Notify the netvsc driver of the new device */ @@ -442,6 +409,10 @@ static int netvsc_probe(struct device *device) net->netdev_ops = &device_ops; + /* TODO: Add GSO and Checksum offload */ + net->features = NETIF_F_SG; + + SET_ETHTOOL_OPS(net, ðtool_ops); SET_NETDEV_DEV(net, device); ret = register_netdev(net); @@ -559,7 +530,7 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) vmbus_get_interface(&net_drv_obj->Base.VmbusChannelInterface); - net_drv_obj->RingBufferSize = netvsc_ringbuffer_size; + net_drv_obj->RingBufferSize = ring_size * PAGE_SIZE; net_drv_obj->OnReceiveCallback = netvsc_recv_callback; net_drv_obj->OnLinkStatusChanged = netvsc_linkstatus_callback; @@ -581,6 +552,20 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) return ret; } +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_init(void) { int ret; @@ -588,6 +573,9 @@ static int __init netvsc_init(void) DPRINT_ENTER(NETVSC_DRV); DPRINT_INFO(NETVSC_DRV, "Netvsc initializing...."); + if (!dmi_check_system(hv_netvsc_dmi_table)) + return -ENODEV; + ret = netvsc_drv_init(NetVscInitialize); DPRINT_EXIT(NETVSC_DRV); @@ -602,9 +590,16 @@ static void __exit netvsc_exit(void) DPRINT_EXIT(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_param(netvsc_ringbuffer_size, int, S_IRUGO); +MODULE_DESCRIPTION("Microsoft Hyper-V network driver"); module_init(netvsc_init); module_exit(netvsc_exit); diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index 9aea31067295..8c3eb278a81f 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -59,6 +59,15 @@ void *osd_VirtualAllocExec(unsigned int size) #endif } +/** + * osd_PageAlloc() - Allocate pages + * @count: Total number of Kernel pages you want to allocate + * + * Tries to allocate @count number of consecutive free kernel pages. + * And if successful, it will set the pages to 0 before returning. + * If successfull it will return pointer to the @count pages. + * Mainly used by Hyper-V drivers. + */ void *osd_PageAlloc(unsigned int count) { void *p; @@ -78,6 +87,14 @@ void *osd_PageAlloc(unsigned int count) } EXPORT_SYMBOL_GPL(osd_PageAlloc); +/** + * osd_PageFree() - Free pages + * @page: Pointer to the first page to be freed + * @count: Total number of Kernel pages you free + * + * Frees the pages allocated by osd_PageAlloc() + * Mainly used by Hyper-V drivers. + */ void osd_PageFree(void *page, unsigned int count) { free_pages((unsigned long)page, get_order(count * PAGE_SIZE)); @@ -86,6 +103,17 @@ void osd_PageFree(void *page, unsigned int count) } EXPORT_SYMBOL_GPL(osd_PageFree); +/** + * osd_WaitEventCreate() - Create the event queue + * + * Allocates memory for a &struct osd_waitevent. And then calls + * init_waitqueue_head to set up the wait queue for the event. + * This structure is usually part of a another structure that contains + * the actual Hyper-V device driver structure. + * + * Returns pointer to &struct osd_waitevent + * Mainly used by Hyper-V drivers. + */ struct osd_waitevent *osd_WaitEventCreate(void) { struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent), @@ -99,6 +127,19 @@ struct osd_waitevent *osd_WaitEventCreate(void) } EXPORT_SYMBOL_GPL(osd_WaitEventCreate); + +/** + * osd_WaitEventSet() - Wake up the process + * @waitEvent: Structure to event to be woken up + * + * @waitevent is of type &struct osd_waitevent + * + * Wake up the sleeping process so it can do some work. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a woken state. + * + * Only used by Network and Storage Hyper-V drivers. + */ void osd_WaitEventSet(struct osd_waitevent *waitEvent) { waitEvent->condition = 1; @@ -106,6 +147,20 @@ void osd_WaitEventSet(struct osd_waitevent *waitEvent) } EXPORT_SYMBOL_GPL(osd_WaitEventSet); +/** + * osd_WaitEventWait() - Wait for event till condition is true + * @waitEvent: Structure to event to be put to sleep + * + * @waitevent is of type &struct osd_waitevent + * + * Set up the process to sleep until waitEvent->condition get true. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a sleeping state. + * + * Returns the status of 'wait_event_interruptible()' system call + * + * Mainly used by Hyper-V drivers. + */ int osd_WaitEventWait(struct osd_waitevent *waitEvent) { int ret = 0; @@ -117,6 +172,21 @@ int osd_WaitEventWait(struct osd_waitevent *waitEvent) } EXPORT_SYMBOL_GPL(osd_WaitEventWait); +/** + * osd_WaitEventWaitEx() - Wait for event or timeout for process wakeup + * @waitEvent: Structure to event to be put to sleep + * @TimeoutInMs: Total number of Milliseconds to wait before waking up + * + * @waitevent is of type &struct osd_waitevent + * Set up the process to sleep until @waitEvent->condition get true or + * @TimeoutInMs (Time out in Milliseconds) has been reached. + * And set condition indicator in &struct osd_waitevent to indicate + * the process is in a sleeping state. + * + * Returns the status of 'wait_event_interruptible_timeout()' system call + * + * Mainly used by Hyper-V drivers. + */ int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs) { int ret = 0; diff --git a/drivers/staging/hv/RingBuffer.c b/drivers/staging/hv/ring_buffer.c index 80b8a2c7784f..ae2a10e24d92 100644 --- a/drivers/staging/hv/RingBuffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -25,14 +25,14 @@ #include <linux/mm.h> #include "osd.h" #include "logging.h" -#include "RingBuffer.h" +#include "ring_buffer.h" /* #defines */ /* 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)) /*++ @@ -72,7 +72,7 @@ GetNextWriteLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->WriteIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ return next; } @@ -106,7 +106,7 @@ GetNextReadLocation(RING_BUFFER_INFO *RingInfo) { u32 next = RingInfo->RingBuffer->ReadIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ return next; } @@ -126,7 +126,7 @@ GetNextReadLocationWithOffset(RING_BUFFER_INFO *RingInfo, u32 Offset) { u32 next = RingInfo->RingBuffer->ReadIndex; - ASSERT(next < RingInfo->RingDataSize); + /* ASSERT(next < RingInfo->RingDataSize); */ next += Offset; next %= RingInfo->RingDataSize; @@ -301,7 +301,8 @@ Description: --*/ int RingBufferInit(RING_BUFFER_INFO *RingInfo, void *Buffer, u32 BufferLen) { - ASSERT(sizeof(RING_BUFFER) == PAGE_SIZE); + if (sizeof(RING_BUFFER) != PAGE_SIZE) + return -EINVAL; memset(RingInfo, 0, sizeof(RING_BUFFER_INFO)); @@ -489,7 +490,8 @@ int RingBufferRead(RING_BUFFER_INFO *InRingInfo, void *Buffer, u64 prevIndices = 0; unsigned long flags; - ASSERT(BufferLen > 0); + if (BufferLen <= 0) + return -EINVAL; spin_lock_irqsave(&InRingInfo->ring_lock, flags); diff --git a/drivers/staging/hv/RingBuffer.h b/drivers/staging/hv/ring_buffer.h index 6202157e145d..6202157e145d 100644 --- a/drivers/staging/hv/RingBuffer.h +++ b/drivers/staging/hv/ring_buffer.h diff --git a/drivers/staging/hv/rndis.h b/drivers/staging/hv/rndis.h index 7c73277c1f9a..723e1f15b90d 100644 --- a/drivers/staging/hv/rndis.h +++ b/drivers/staging/hv/rndis.h @@ -622,7 +622,7 @@ struct rndis_message { /* get the size of an RNDIS message. Pass in the message type, */ /* struct rndis_set_request, struct rndis_packet for example */ #define RNDIS_MESSAGE_SIZE(Message) \ - (sizeof(Message) + (sizeof(struct rndis_message) - \ + (sizeof(Message) + (sizeof(struct rndis_message) - \ sizeof(union rndis_message_container))) /* get pointer to info buffer with message pointer */ diff --git a/drivers/staging/hv/RndisFilter.c b/drivers/staging/hv/rndis_filter.c index 6704f64c93f0..5edf0853c6af 100644 --- a/drivers/staging/hv/RndisFilter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -22,10 +22,12 @@ #include <linux/highmem.h> #include <linux/slab.h> #include <linux/io.h> +#include <linux/if_ether.h> + #include "osd.h" #include "logging.h" -#include "NetVscApi.h" -#include "RndisFilter.h" +#include "netvsc_api.h" +#include "rndis_filter.h" /* Data types */ struct rndis_filter_driver_object { @@ -50,7 +52,7 @@ struct rndis_device { spinlock_t request_lock; struct list_head RequestList; - unsigned char HwMacAddr[HW_MACADDR_LEN]; + unsigned char HwMacAddr[ETH_ALEN]; }; struct rndis_request { @@ -354,8 +356,8 @@ static void RndisFilterReceiveData(struct rndis_device *Device, DPRINT_ENTER(NETVSC); /* empty ethernet frame ?? */ - ASSERT(Packet->PageBuffers[0].Length > - RNDIS_MESSAGE_SIZE(struct rndis_packet)); + /* ASSERT(Packet->PageBuffers[0].Length > */ + /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ rndisPacket = &Message->Message.Packet; @@ -389,7 +391,9 @@ static int RndisFilterOnReceive(struct hv_device *Device, DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + /* Make sure the rndis device state is initialized */ if (!netDevice->Extension) { DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." @@ -490,7 +494,8 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, DPRINT_ENTER(NETVSC); - ASSERT(Result); + if (!Result) + return -EINVAL; *ResultSize = 0; request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, @@ -538,7 +543,7 @@ Cleanup: static int RndisFilterQueryDeviceMac(struct rndis_device *Device) { - u32 size = HW_MACADDR_LEN; + u32 size = ETH_ALEN; return RndisFilterQueryDevice(Device, RNDIS_OID_802_3_PERMANENT_ADDRESS, @@ -565,8 +570,8 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device, DPRINT_ENTER(NETVSC); - ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= - sizeof(struct rndis_message)); + /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ + /* sizeof(struct rndis_message)); */ request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + @@ -622,7 +627,6 @@ int RndisFilterInit(struct netvsc_driver *Driver) sizeof(struct rndis_filter_packet)); Driver->RequestExtSize = sizeof(struct rndis_filter_packet); - Driver->AdditionalRequestPageBufferCount = 1; /* For rndis header */ /* Driver->Context = rndisDriver; */ @@ -639,8 +643,8 @@ int RndisFilterInit(struct netvsc_driver *Driver) Driver->Base.OnDeviceRemove; gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup; - ASSERT(Driver->OnSend); - ASSERT(Driver->OnReceiveCallback); + /* ASSERT(Driver->OnSend); */ + /* ASSERT(Driver->OnReceiveCallback); */ gRndisFilter.InnerDriver.OnSend = Driver->OnSend; gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback; gRndisFilter.InnerDriver.OnLinkStatusChanged = @@ -811,8 +815,8 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, /* Initialize the rndis device */ netDevice = Device->Extension; - ASSERT(netDevice); - ASSERT(netDevice->Device); + /* ASSERT(netDevice); */ + /* ASSERT(netDevice->Device); */ netDevice->Extension = rndisDevice; rndisDevice->NetDevice = netDevice; @@ -834,16 +838,10 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, */ } - DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x", - rndisDevice, - rndisDevice->HwMacAddr[0], - rndisDevice->HwMacAddr[1], - rndisDevice->HwMacAddr[2], - rndisDevice->HwMacAddr[3], - rndisDevice->HwMacAddr[4], - rndisDevice->HwMacAddr[5]); + DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", + rndisDevice, rndisDevice->HwMacAddr); - memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, HW_MACADDR_LEN); + memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN); RndisFilterQueryDeviceLinkStatus(rndisDevice); @@ -891,7 +889,9 @@ int RndisFilterOnOpen(struct hv_device *Device) DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + ret = RndisFilterOpenDevice(netDevice->Extension); DPRINT_EXIT(NETVSC); @@ -906,7 +906,9 @@ int RndisFilterOnClose(struct hv_device *Device) DPRINT_ENTER(NETVSC); - ASSERT(netDevice); + if (!netDevice) + return -EINVAL; + ret = RndisFilterCloseDevice(netDevice->Extension); DPRINT_EXIT(NETVSC); @@ -927,7 +929,7 @@ static int RndisFilterOnSend(struct hv_device *Device, /* Add the rndis header */ filterPacket = (struct rndis_filter_packet *)Packet->Extension; - ASSERT(filterPacket); + /* ASSERT(filterPacket); */ memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); diff --git a/drivers/staging/hv/RndisFilter.h b/drivers/staging/hv/rndis_filter.h index fa7dd79ddebf..764b9bf3e5dc 100644 --- a/drivers/staging/hv/RndisFilter.h +++ b/drivers/staging/hv/rndis_filter.h @@ -27,7 +27,7 @@ #define __struct_bcount(x) -#include "NetVsc.h" +#include "netvsc.h" #include "rndis.h" diff --git a/drivers/staging/hv/StorVsc.c b/drivers/staging/hv/storvsc.c index e426a23ca537..27a276e08ee9 100644 --- a/drivers/staging/hv/StorVsc.c +++ b/drivers/staging/hv/storvsc.c @@ -25,8 +25,8 @@ #include <linux/delay.h> #include "osd.h" #include "logging.h" -#include "StorVscApi.h" -#include "VmbusPacketFormat.h" +#include "storvsc_api.h" +#include "vmbus_packet_format.h" #include "vstorage.h" @@ -100,7 +100,7 @@ static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) static inline void FreeStorDevice(struct storvsc_device *Device) { - ASSERT(atomic_read(&Device->RefCount) == 0); + /* ASSERT(atomic_read(&Device->RefCount) == 0); */ kfree(Device); } @@ -137,10 +137,10 @@ static inline void PutStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ atomic_dec(&storDevice->RefCount); - ASSERT(atomic_read(&storDevice->RefCount)); + /* ASSERT(atomic_read(&storDevice->RefCount)); */ } /* Drop ref count to 1 to effectively disable GetStorDevice() */ @@ -149,7 +149,7 @@ static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 2, then set it to 1 */ while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2) @@ -165,7 +165,7 @@ static inline struct storvsc_device *FinalReleaseStorDevice( struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - ASSERT(storDevice); + /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 1, then set it to 0 */ while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1) @@ -199,6 +199,10 @@ static int StorVscChannelInit(struct hv_device *Device) */ memset(request, 0, sizeof(struct storvsc_request_extension)); request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto nomem; + } vstorPacket->Operation = VStorOperationBeginInitialization; vstorPacket->Flags = REQUEST_COMPLETION_FLAG; @@ -338,7 +342,7 @@ static int StorVscChannelInit(struct hv_device *Device) Cleanup: kfree(request->WaitEvent); request->WaitEvent = NULL; - +nomem: PutStorDevice(Device); DPRINT_EXIT(STORVSC); @@ -366,12 +370,12 @@ static void StorVscOnIOCompletion(struct hv_device *Device, "completed bytes xfer %u", RequestExt, VStorPacket->VmSrb.DataTransferLength); - ASSERT(RequestExt != NULL); - ASSERT(RequestExt->Request != NULL); + /* ASSERT(RequestExt != NULL); */ + /* ASSERT(RequestExt->Request != NULL); */ request = RequestExt->Request; - ASSERT(request->OnIOCompletion != NULL); + /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ request->Status = VStorPacket->VmSrb.ScsiStatus; @@ -391,8 +395,8 @@ static void StorVscOnIOCompletion(struct hv_device *Device, "valid - len %d\n", RequestExt, VStorPacket->VmSrb.SenseInfoLength); - ASSERT(VStorPacket->VmSrb.SenseInfoLength <= - request->SenseBufferSize); + /* ASSERT(VStorPacket->VmSrb.SenseInfoLength <= */ + /* request->SenseBufferSize); */ memcpy(request->SenseBuffer, VStorPacket->VmSrb.SenseData, VStorPacket->VmSrb.SenseInfoLength); @@ -447,7 +451,7 @@ static void StorVscOnChannelCallback(void *context) DPRINT_ENTER(STORVSC); - ASSERT(device); + /* ASSERT(device); */ storDevice = MustGetStorDevice(device); if (!storDevice) { @@ -470,7 +474,7 @@ static void StorVscOnChannelCallback(void *context) request = (struct storvsc_request_extension *) (unsigned long)requestId; - ASSERT(request); + /* ASSERT(request);c */ /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ if ((request == &storDevice->InitRequest) || @@ -533,7 +537,7 @@ static int StorVscConnectToVsp(struct hv_device *Device) return ret; } -/** +/* * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added */ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) @@ -554,7 +558,7 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) /* Save the channel properties to our storvsc channel */ /* props = (struct vmstorage_channel_properties *) - * channel->offerMsg.Offer.u.Standard.UserDefined; */ + * channel->offerMsg.Offer.u.Standard.UserDefined; */ /* FIXME: */ /* @@ -585,7 +589,7 @@ Cleanup: return ret; } -/** +/* * StorVscOnDeviceRemove - Callback when the our device is being removed */ static int StorVscOnDeviceRemove(struct hv_device *Device) @@ -649,6 +653,10 @@ int StorVscOnHostReset(struct hv_device *Device) vstorPacket = &request->VStorPacket; request->WaitEvent = osd_WaitEventCreate(); + if (!request->WaitEvent) { + ret = -ENOMEM; + goto Cleanup; + } vstorPacket->Operation = VStorOperationResetBus; vstorPacket->Flags = REQUEST_COMPLETION_FLAG; @@ -683,7 +691,7 @@ Cleanup: return ret; } -/** +/* * StorVscOnIORequest - Callback to initiate an I/O request */ static int StorVscOnIORequest(struct hv_device *Device, @@ -717,7 +725,7 @@ static int StorVscOnIORequest(struct hv_device *Device, } /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, - * Request->CdbLen); */ + * Request->CdbLen); */ requestExtension->Request = Request; requestExtension->Device = Device; @@ -783,7 +791,7 @@ static int StorVscOnIORequest(struct hv_device *Device, return ret; } -/** +/* * StorVscOnCleanup - Perform any cleanup when the driver is removed */ static void StorVscOnCleanup(struct hv_driver *Driver) @@ -792,7 +800,7 @@ static void StorVscOnCleanup(struct hv_driver *Driver) DPRINT_EXIT(STORVSC); } -/** +/* * StorVscInitialize - Main entry point */ int StorVscInitialize(struct hv_driver *Driver) @@ -813,7 +821,7 @@ int StorVscInitialize(struct hv_driver *Driver) sizeof(struct vmscsi_request)); /* Make sure we are at least 2 pages since 1 page is used for control */ - ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); + /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ Driver->name = gDriverName; memcpy(&Driver->deviceType, &gStorVscDeviceType, diff --git a/drivers/staging/hv/StorVscApi.h b/drivers/staging/hv/storvsc_api.h index 126a8588edb1..0063bde9a4b2 100644 --- a/drivers/staging/hv/StorVscApi.h +++ b/drivers/staging/hv/storvsc_api.h @@ -25,7 +25,7 @@ #ifndef _STORVSC_API_H_ #define _STORVSC_API_H_ -#include "VmbusApi.h" +#include "vmbus_api.h" /* Defines */ #define STORVSC_RING_BUFFER_SIZE (10*PAGE_SIZE) diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 8a58272b8039..d22e35f598ba 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -33,9 +33,9 @@ #include <scsi/scsi_dbg.h> #include "osd.h" #include "logging.h" -#include "VersionInfo.h" +#include "version_info.h" #include "vmbus.h" -#include "StorVscApi.h" +#include "storvsc_api.h" struct host_device_context { @@ -97,6 +97,8 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev, 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)"); /* The one and only one */ static struct storvsc_driver_context g_storvsc_drv; @@ -112,7 +114,7 @@ static struct scsi_host_template scsi_driver = { .slave_configure = storvsc_device_configure, .cmd_per_lun = 1, /* 64 max_queue * 1 target */ - .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, + .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, .this_id = -1, /* no use setting to 0 since ll_blk_rw reset it to 1 */ /* currently 32 */ @@ -130,7 +132,7 @@ static struct scsi_host_template scsi_driver = { }; -/** +/* * storvsc_drv_init - StorVsc driver initialization. */ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) @@ -223,7 +225,7 @@ static void storvsc_drv_exit(void) return; } -/** +/* * storvsc_probe - Add a new device for this driver */ static int storvsc_probe(struct device *device) @@ -319,7 +321,7 @@ static int storvsc_probe(struct device *device) return ret; } -/** +/* * storvsc_remove - Callback when our device is removed */ static int storvsc_remove(struct device *device) @@ -372,7 +374,7 @@ static int storvsc_remove(struct device *device) return ret; } -/** +/* * storvsc_commmand_completion - Command completion processing */ static void storvsc_commmand_completion(struct hv_storvsc_request *request) @@ -385,11 +387,11 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) void (*scsi_done_fn)(struct scsi_cmnd *); struct scsi_sense_hdr sense_hdr; - ASSERT(request == &cmd_request->request); - ASSERT((unsigned long)scmnd->host_scribble == - (unsigned long)cmd_request); - ASSERT(scmnd); - ASSERT(scmnd->scsi_done); + /* ASSERT(request == &cmd_request->request); */ + /* ASSERT(scmnd); */ + /* ASSERT((unsigned long)scmnd->host_scribble == */ + /* (unsigned long)cmd_request); */ + /* ASSERT(scmnd->scsi_done); */ DPRINT_ENTER(STORVSC_DRV); @@ -413,7 +415,7 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) scsi_print_sense_hdr("storvsc", &sense_hdr); } - ASSERT(request->BytesXfer <= request->DataBuffer.Length); + /* ASSERT(request->BytesXfer <= request->DataBuffer.Length); */ scsi_set_resid(scmnd, request->DataBuffer.Length - request->BytesXfer); scsi_done_fn = scmnd->scsi_done; @@ -522,7 +524,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, src = src_addr; srclen = orig_sgl[i].length; - ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); + /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ if (j == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); @@ -583,7 +585,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, KM_IRQ0) + orig_sgl[i].offset; dest = dest_addr; destlen = orig_sgl[i].length; - ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); + /* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */ if (j == 0) bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0); @@ -623,7 +625,7 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, return total_copied; } -/** +/* * storvsc_queuecommand - Initiate command processing */ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, @@ -655,7 +657,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, /* If retrying, no need to prep the cmd */ if (scmnd->host_scribble) { - ASSERT(scmnd->scsi_done != NULL); + /* ASSERT(scmnd->scsi_done != NULL); */ cmd_request = (struct storvsc_cmd_request *)scmnd->host_scribble; @@ -665,8 +667,8 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, goto retry_request; } - ASSERT(scmnd->scsi_done == NULL); - ASSERT(scmnd->host_scribble == NULL); + /* ASSERT(scmnd->scsi_done == NULL); */ + /* ASSERT(scmnd->host_scribble == NULL); */ scmnd->scsi_done = done; @@ -717,7 +719,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request->TargetId = scmnd->device->id; request->LunId = scmnd->device->lun; - ASSERT(scmnd->cmd_len <= 16); + /* ASSERT(scmnd->cmd_len <= 16); */ request->CdbLen = scmnd->cmd_len; request->Cdb = scmnd->cmnd; @@ -767,19 +769,17 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request->DataBuffer.Offset = sgl[0].offset; for (i = 0; i < scsi_sg_count(scmnd); i++) { - DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d \n", + DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); request->DataBuffer.PfnArray[i] = page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { - ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); + /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ request->DataBuffer.Offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); request->DataBuffer.PfnArray[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; - } else { - ASSERT(scsi_bufflen(scmnd) == 0); } retry_request: @@ -824,7 +824,7 @@ static int storvsc_merge_bvec(struct request_queue *q, return bvec->bv_len; } -/** +/* * storvsc_device_configure - Configure the specified scsi device */ static int storvsc_device_alloc(struct scsi_device *sdevice) @@ -863,7 +863,7 @@ static int storvsc_device_configure(struct scsi_device *sdevice) return 0; } -/** +/* * storvsc_host_reset_handler - Reset the scsi HBA */ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) @@ -993,6 +993,6 @@ static void __exit storvsc_exit(void) MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); -module_param(storvsc_ringbuffer_size, int, S_IRUGO); +MODULE_DESCRIPTION("Microsoft Hyper-V virtual storage driver"); module_init(storvsc_init); module_exit(storvsc_exit); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h new file mode 100644 index 000000000000..7c0749999a6f --- /dev/null +++ b/drivers/staging/hv/utils.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2009, Microsoft Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Authors: + * Haiyang Zhang <haiyangz@microsoft.com> + * Hank Janssen <hjanssen@microsoft.com> + */ +#ifndef __HV_UTILS_H_ +#define __HV_UTILS_H_ + +/* + * Common header for Hyper-V ICs + */ +#define ICMSGTYPE_NEGOTIATE 0 +#define ICMSGTYPE_HEARTBEAT 1 +#define ICMSGTYPE_KVPEXCHANGE 2 +#define ICMSGTYPE_SHUTDOWN 3 +#define ICMSGTYPE_TIMESYNC 4 +#define ICMSGTYPE_VSS 5 + +#define ICMSGHDRFLAG_TRANSACTION 1 +#define ICMSGHDRFLAG_REQUEST 2 +#define ICMSGHDRFLAG_RESPONSE 4 + +#define HV_S_OK 0x00000000 +#define HV_E_FAIL 0x80004005 +#define HV_ERROR_NOT_SUPPORTED 0x80070032 +#define HV_ERROR_MACHINE_LOCKED 0x800704F7 + +struct vmbuspipe_hdr { + u32 flags; + u32 msgsize; +} __attribute__((packed)); + +struct ic_version { + u16 major; + u16 minor; +} __attribute__((packed)); + +struct icmsg_hdr { + struct ic_version icverframe; + u16 icmsgtype; + struct ic_version icvermsg; + u16 icmsgsize; + u32 status; + u8 ictransaction_id; + u8 icflags; + u8 reserved[2]; +} __attribute__((packed)); + +struct icmsg_negotiate { + u16 icframe_vercnt; + u16 icmsg_vercnt; + u32 reserved; + struct ic_version icversion_data[1]; /* any size array */ +} __attribute__((packed)); + +struct shutdown_msg_data { + u32 reason_code; + u32 timeout_seconds; + u32 flags; + u8 display_message[2048]; +} __attribute__((packed)); + +struct heartbeat_msg_data { + u64 seq_num; + u32 reserved[8]; +} __attribute__((packed)); + +/* Time Sync IC defs */ +#define ICTIMESYNCFLAG_PROBE 0 +#define ICTIMESYNCFLAG_SYNC 1 +#define ICTIMESYNCFLAG_SAMPLE 2 + +#ifdef __x86_64__ +#define WLTIMEDELTA 116444736000000000L /* in 100ns unit */ +#else +#define WLTIMEDELTA 116444736000000000LL +#endif + +struct ictimesync_data{ + u64 parenttime; + u64 childtime; + u64 roundtriptime; + u8 flags; +} __attribute__((packed)); + +/* Index for each IC struct in array hv_cb_utils[] */ +#define HV_SHUTDOWN_MSG 0 +#define HV_TIMESYNC_MSG 1 +#define HV_HEARTBEAT_MSG 2 + +struct hyperv_service_callback { + u8 msg_type; + char *log_msg; + unsigned char data[16]; + struct vmbus_channel *channel; + void (*callback) (void *context); +}; + +extern void prep_negotiate_resp(struct icmsg_hdr *, + struct icmsg_negotiate *, u8 *); +extern void chn_cb_negotiate(void *); +extern struct hyperv_service_callback hv_cb_utils[]; + +#endif /* __HV_UTILS_H_ */ diff --git a/drivers/staging/hv/VersionInfo.h b/drivers/staging/hv/version_info.h index 10d7b19a485f..35178f2c7967 100644 --- a/drivers/staging/hv/VersionInfo.h +++ b/drivers/staging/hv/version_info.h @@ -29,19 +29,20 @@ * * Definition of versioning is as follows; * - * Major Number Changes for these scenarios; + * Major Number Changes for these scenarios; * 1. When a new version of Windows Hyper-V * is released. * 2. A Major change has occurred in the - * Linux IC's. + * Linux IC's. * (For example the merge for the first time * into the kernel) Every time the Major Number * changes, the Revision number is reset to 0. * Minor Number Changes when new functionality is added * to the Linux IC's that is not a bug fix. * + * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync */ -#define HV_DRV_VERSION "3.0" +#define HV_DRV_VERSION "3.1" #endif diff --git a/drivers/staging/hv/Vmbus.c b/drivers/staging/hv/vmbus.c index 2f84bf7c0a9f..007543bdb410 100644 --- a/drivers/staging/hv/Vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -24,8 +24,8 @@ #include <linux/slab.h> #include "osd.h" #include "logging.h" -#include "VersionInfo.h" -#include "VmbusPrivate.h" +#include "version_info.h" +#include "vmbus_private.h" static const char *gDriverName = "vmbus"; @@ -52,7 +52,7 @@ static const struct hv_guid gVmbusDeviceId = { static struct hv_driver *gDriver; /* vmbus driver object */ static struct hv_device *gDevice; /* vmbus root device */ -/** +/* * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition */ static void VmbusGetChannelOffers(void) @@ -62,7 +62,7 @@ static void VmbusGetChannelOffers(void) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusGetChannelInterface - Get the channel interface */ static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) @@ -70,7 +70,7 @@ static void VmbusGetChannelInterface(struct vmbus_channel_interface *Interface) GetChannelInterface(Interface); } -/** +/* * VmbusGetChannelInfo - Get the device info for the specified device object */ static void VmbusGetChannelInfo(struct hv_device *DeviceObject, @@ -79,7 +79,7 @@ static void VmbusGetChannelInfo(struct hv_device *DeviceObject, GetChannelInfo(DeviceObject, DeviceInfo); } -/** +/* * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer */ struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, @@ -92,7 +92,7 @@ struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, Context); } -/** +/* * VmbusChildDeviceAdd - Registers the child device with the vmbus */ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) @@ -102,7 +102,7 @@ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); } -/** +/* * VmbusChildDeviceRemove Unregisters the child device from the vmbus */ void VmbusChildDeviceRemove(struct hv_device *ChildDevice) @@ -112,7 +112,7 @@ void VmbusChildDeviceRemove(struct hv_device *ChildDevice) vmbusDriver->OnChildDeviceRemove(ChildDevice); } -/** +/* * VmbusOnDeviceAdd - Callback when the root bus device is added */ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) @@ -141,7 +141,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) return ret; } -/** +/* * VmbusOnDeviceRemove - Callback when the root bus device is removed */ static int VmbusOnDeviceRemove(struct hv_device *dev) @@ -157,7 +157,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) return ret; } -/** +/* * VmbusOnCleanup - Perform any cleanup when the driver is removed */ static void VmbusOnCleanup(struct hv_driver *drv) @@ -169,7 +169,7 @@ static void VmbusOnCleanup(struct hv_driver *drv) DPRINT_EXIT(VMBUS); } -/** +/* * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior */ static void VmbusOnMsgDPC(struct hv_driver *drv) @@ -185,11 +185,10 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) /* no msg */ break; } else { - copied = kmalloc(sizeof(*copied), GFP_ATOMIC); + copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); if (copied == NULL) continue; - memcpy(copied, msg, sizeof(*copied)); osd_schedule_callback(gVmbusConnection.WorkQueue, VmbusOnChannelMessage, (void *)copied); @@ -217,7 +216,7 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) } } -/** +/* * VmbusOnEventDPC - DPC routine to handle events from the hypervisior */ static void VmbusOnEventDPC(struct hv_driver *drv) @@ -226,7 +225,7 @@ static void VmbusOnEventDPC(struct hv_driver *drv) VmbusOnEvents(); } -/** +/* * VmbusOnISR - ISR routine */ static int VmbusOnISR(struct hv_driver *drv) @@ -264,7 +263,7 @@ static int VmbusOnISR(struct hv_driver *drv) return ret; } -/** +/* * VmbusInitialize - Main entry point */ int VmbusInitialize(struct hv_driver *drv) diff --git a/drivers/staging/hv/vmbus.h b/drivers/staging/hv/vmbus.h index 6404b8424bef..0c6ee0f487f3 100644 --- a/drivers/staging/hv/vmbus.h +++ b/drivers/staging/hv/vmbus.h @@ -26,7 +26,7 @@ #define _VMBUS_H_ #include <linux/device.h> -#include "VmbusApi.h" +#include "vmbus_api.h" struct driver_context { struct hv_guid class_id; diff --git a/drivers/staging/hv/VmbusApi.h b/drivers/staging/hv/vmbus_api.h index d089bb193e7d..4275be3292ce 100644 --- a/drivers/staging/hv/VmbusApi.h +++ b/drivers/staging/hv/vmbus_api.h @@ -84,6 +84,24 @@ struct hv_device_info { struct hv_dev_port_info Outbound; }; +/** + * struct vmbus_channel_interface - Contains member functions for vmbus channel + * @Open: Open the channel + * @Close: Close the channel + * @SendPacket: Send a packet over the channel + * @SendPacketPageBuffer: Send a single page buffer over the channel + * @SendPacketMultiPageBuffer: Send a multiple page buffers + * @RecvPacket: Receive packet + * @RecvPacketRaw: Receive Raw packet + * @EstablishGpadl: Set up GPADL for ringbuffer + * @TeardownGpadl: Teardown GPADL for ringbuffer + * @GetInfo: Get info about the channel + * + * This structure contains function pointer to control vmbus channel + * behavior. None of these functions is externally callable, but they + * are used for normal vmbus channel internal behavior. + * Only used by Hyper-V drivers. + */ struct vmbus_channel_interface { int (*Open)(struct hv_device *Device, u32 SendBufferSize, u32 RecvRingBufferSize, void *UserData, u32 UserDataLen, diff --git a/drivers/staging/hv/VmbusChannelInterface.h b/drivers/staging/hv/vmbus_channel_interface.h index 26742823748d..26742823748d 100644 --- a/drivers/staging/hv/VmbusChannelInterface.h +++ b/drivers/staging/hv/vmbus_channel_interface.h diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3397ef08e0aa..c21731a12ca7 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -27,7 +27,7 @@ #include <linux/pci.h> #include <linux/dmi.h> #include <linux/slab.h> -#include "VersionInfo.h" +#include "version_info.h" #include "osd.h" #include "logging.h" #include "vmbus.h" @@ -129,7 +129,7 @@ static struct vmbus_driver_context g_vmbus_drv = { .bus.dev_attrs = vmbus_device_attrs, }; -/** +/* * vmbus_show_device_attr - Show the device attribute in sysfs. * * This is invoked when user does a @@ -233,17 +233,17 @@ static ssize_t vmbus_show_device_attr(struct device *dev, } } -/** +/* * vmbus_bus_init -Main vmbus driver initialization routine. * * Here, we - * - initialize the vmbus driver context - * - setup various driver entry points - * - invoke the vmbus hv main init routine - * - get the irq resource - * - invoke the vmbus to add the vmbus root device - * - setup the vmbus root device - * - retrieve the channel offers + * - initialize the vmbus driver context + * - setup various driver entry points + * - invoke the vmbus hv main init routine + * - get the irq resource + * - invoke the vmbus to add the vmbus root device + * - setup the vmbus root device + * - retrieve the channel offers */ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) { @@ -362,7 +362,7 @@ cleanup: return ret; } -/** +/* * vmbus_bus_exit - Terminate the vmbus driver. * * This routine is opposite of vmbus_bus_init() @@ -398,8 +398,18 @@ static void vmbus_bus_exit(void) return; } + /** - * vmbus_child_driver_register - Register a vmbus's child driver + * vmbus_child_driver_register() - Register a vmbus's child driver + * @driver_ctx: Pointer to driver structure you want to register + * + * @driver_ctx is of type &struct driver_context + * + * Registers the given driver with Linux through the 'driver_register()' call + * 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 driver_context *driver_ctx) { @@ -425,7 +435,15 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx) EXPORT_SYMBOL(vmbus_child_driver_register); /** - * vmbus_child_driver_unregister Unregister a vmbus's child driver + * vmbus_child_driver_unregister() - Unregister a vmbus's child driver + * @driver_ctx: Pointer to driver structure you want to un-register + * + * @driver_ctx is of type &struct driver_context + * + * 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. */ void vmbus_child_driver_unregister(struct driver_context *driver_ctx) { @@ -443,9 +461,15 @@ void vmbus_child_driver_unregister(struct driver_context *driver_ctx) EXPORT_SYMBOL(vmbus_child_driver_unregister); /** - * vmbus_get_interface - Get the vmbus channel interface. + * vmbus_get_interface() - Get the vmbus channel interface. + * @interface: Pointer to channel interface structure + * + * Get the Hyper-V channel used for the driver. + * + * @interface is of type &struct vmbus_channel_interface + * This is invoked by child/client driver that sits above vmbus. * - * This is invoked by child/client driver that sits above vmbus + * Mainly used by Hyper-V drivers. */ void vmbus_get_interface(struct vmbus_channel_interface *interface) { @@ -455,7 +479,7 @@ void vmbus_get_interface(struct vmbus_channel_interface *interface) } EXPORT_SYMBOL(vmbus_get_interface); -/** +/* * vmbus_child_device_get_info - Get the vmbus child device info. * * This is invoked to display various device attributes in sysfs. @@ -468,8 +492,9 @@ static void vmbus_child_device_get_info(struct hv_device *device_obj, vmbus_drv_obj->GetChannelInfo(device_obj, device_info); } -/** - * vmbus_child_device_create - Creates and registers a new child device on the vmbus. +/* + * vmbus_child_device_create - Creates and registers a new child device + * on the vmbus. */ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, struct hv_guid *instance, @@ -523,7 +548,7 @@ static struct hv_device *vmbus_child_device_create(struct hv_guid *type, return child_device_obj; } -/** +/* * vmbus_child_device_register - Register the child device on the specified bus */ static int vmbus_child_device_register(struct hv_device *root_device_obj, @@ -571,8 +596,9 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, return ret; } -/** - * vmbus_child_device_unregister - Remove the specified child device from the vmbus. +/* + * vmbus_child_device_unregister - Remove the specified child device + * from the vmbus. */ static void vmbus_child_device_unregister(struct hv_device *device_obj) { @@ -595,7 +621,7 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_child_device_destroy - Destroy the specified child device on the vmbus. */ static void vmbus_child_device_destroy(struct hv_device *device_obj) @@ -605,7 +631,7 @@ static void vmbus_child_device_destroy(struct hv_device *device_obj) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_uevent - add uevent for our device * * This routine is invoked when a device is added or removed on the vmbus to @@ -684,7 +710,7 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) return 0; } -/** +/* * vmbus_match - Attempt to match the specified device to the specified driver */ static int vmbus_match(struct device *device, struct device_driver *driver) @@ -719,7 +745,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) return match; } -/** +/* * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe() * * We need a callback because we cannot invoked device_unregister() inside @@ -742,7 +768,7 @@ static void vmbus_probe_failed_cb(struct work_struct *context) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_probe - Add the new vmbus's child device */ static int vmbus_probe(struct device *child_device) @@ -778,7 +804,7 @@ static int vmbus_probe(struct device *child_device) return ret; } -/** +/* * vmbus_remove - Remove a vmbus device */ static int vmbus_remove(struct device *child_device) @@ -820,7 +846,7 @@ static int vmbus_remove(struct device *child_device) return 0; } -/** +/* * vmbus_shutdown - Shutdown a vmbus device */ static void vmbus_shutdown(struct device *child_device) @@ -856,7 +882,7 @@ static void vmbus_shutdown(struct device *child_device) return; } -/** +/* * vmbus_bus_release - Final callback release of the vmbus root device */ static void vmbus_bus_release(struct device *device) @@ -870,7 +896,7 @@ static void vmbus_bus_release(struct device *device) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_device_release - Final callback release of the vmbus child device */ static void vmbus_device_release(struct device *device) @@ -888,7 +914,7 @@ static void vmbus_device_release(struct device *device) return; } -/** +/* * vmbus_msg_dpc - Tasklet routine to handle hypervisor messages */ static void vmbus_msg_dpc(unsigned long data) @@ -897,7 +923,7 @@ static void vmbus_msg_dpc(unsigned long data) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); + /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */ /* Call to bus driver to handle interrupt */ vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base); @@ -905,7 +931,7 @@ static void vmbus_msg_dpc(unsigned long data) DPRINT_EXIT(VMBUS_DRV); } -/** +/* * vmbus_msg_dpc - Tasklet routine to handle hypervisor events */ static void vmbus_event_dpc(unsigned long data) @@ -914,7 +940,7 @@ static void vmbus_event_dpc(unsigned long data) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_drv_obj->OnEventDpc != NULL); + /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */ /* Call to bus driver to handle interrupt */ vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base); @@ -929,7 +955,7 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) DPRINT_ENTER(VMBUS_DRV); - ASSERT(vmbus_driver_obj->OnIsr != NULL); + /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */ /* Call to bus driver to handle interrupt */ ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base); diff --git a/drivers/staging/hv/VmbusPacketFormat.h b/drivers/staging/hv/vmbus_packet_format.h index 79120bc742dc..f9f6b4bf6fb1 100644 --- a/drivers/staging/hv/VmbusPacketFormat.h +++ b/drivers/staging/hv/vmbus_packet_format.h @@ -22,6 +22,7 @@ */ #ifndef _VMBUSPACKETFORMAT_H_ +#define _VMBUSPACKETFORMAT_H_ struct vmpacket_descriptor { u16 Type; diff --git a/drivers/staging/hv/VmbusPrivate.h b/drivers/staging/hv/vmbus_private.h index 05ad2c9380d5..588c667a7f6b 100644 --- a/drivers/staging/hv/VmbusPrivate.h +++ b/drivers/staging/hv/vmbus_private.h @@ -25,12 +25,12 @@ #ifndef _VMBUS_PRIVATE_H_ #define _VMBUS_PRIVATE_H_ -#include "Hv.h" -#include "VmbusApi.h" -#include "Channel.h" -#include "ChannelMgmt.h" -#include "ChannelInterface.h" -#include "RingBuffer.h" +#include "hv.h" +#include "vmbus_api.h" +#include "channel.h" +#include "channel_mgmt.h" +#include "channel_interface.h" +#include "ring_buffer.h" #include <linux/list.h> diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h index 6d160a53914e..4ea597d7a7d7 100644 --- a/drivers/staging/hv/vstorage.h +++ b/drivers/staging/hv/vstorage.h @@ -28,7 +28,7 @@ #define REVISION_STRING(REVISION_) #REVISION_ #define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \ { \ - char *revisionString = REVISION_STRING($Revision: 6 $) + 11; \ + char *revisionString = REVISION_STRING($Revision : 6 $) + 11; \ RESULT_LVALUE_ = 0; \ while (*revisionString >= '0' && *revisionString <= '9') { \ RESULT_LVALUE_ *= 10; \ |