diff options
-rw-r--r-- | drivers/hv/channel.c | 42 | ||||
-rw-r--r-- | drivers/hv/hyperv_vmbus.h | 4 | ||||
-rw-r--r-- | drivers/hv/ring_buffer.c | 17 | ||||
-rw-r--r-- | include/linux/hyperv.h | 2 |
4 files changed, 33 insertions, 32 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 69ea36f07b4d..602ca86a6488 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/hyperv.h> | 29 | #include <linux/hyperv.h> |
30 | #include <linux/uio.h> | ||
30 | 31 | ||
31 | #include "hyperv_vmbus.h" | 32 | #include "hyperv_vmbus.h" |
32 | 33 | ||
@@ -554,14 +555,14 @@ EXPORT_SYMBOL_GPL(vmbus_close); | |||
554 | * | 555 | * |
555 | * Mainly used by Hyper-V drivers. | 556 | * Mainly used by Hyper-V drivers. |
556 | */ | 557 | */ |
557 | int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, | 558 | int vmbus_sendpacket(struct vmbus_channel *channel, void *buffer, |
558 | u32 bufferlen, u64 requestid, | 559 | u32 bufferlen, u64 requestid, |
559 | enum vmbus_packet_type type, u32 flags) | 560 | enum vmbus_packet_type type, u32 flags) |
560 | { | 561 | { |
561 | struct vmpacket_descriptor desc; | 562 | struct vmpacket_descriptor desc; |
562 | u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen; | 563 | u32 packetlen = sizeof(struct vmpacket_descriptor) + bufferlen; |
563 | u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64)); | 564 | u32 packetlen_aligned = ALIGN(packetlen, sizeof(u64)); |
564 | struct scatterlist bufferlist[3]; | 565 | struct kvec bufferlist[3]; |
565 | u64 aligned_data = 0; | 566 | u64 aligned_data = 0; |
566 | int ret; | 567 | int ret; |
567 | bool signal = false; | 568 | bool signal = false; |
@@ -575,11 +576,12 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, | |||
575 | desc.len8 = (u16)(packetlen_aligned >> 3); | 576 | desc.len8 = (u16)(packetlen_aligned >> 3); |
576 | desc.trans_id = requestid; | 577 | desc.trans_id = requestid; |
577 | 578 | ||
578 | sg_init_table(bufferlist, 3); | 579 | bufferlist[0].iov_base = &desc; |
579 | sg_set_buf(&bufferlist[0], &desc, sizeof(struct vmpacket_descriptor)); | 580 | bufferlist[0].iov_len = sizeof(struct vmpacket_descriptor); |
580 | sg_set_buf(&bufferlist[1], buffer, bufferlen); | 581 | bufferlist[1].iov_base = buffer; |
581 | sg_set_buf(&bufferlist[2], &aligned_data, | 582 | bufferlist[1].iov_len = bufferlen; |
582 | packetlen_aligned - packetlen); | 583 | bufferlist[2].iov_base = &aligned_data; |
584 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | ||
583 | 585 | ||
584 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 586 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); |
585 | 587 | ||
@@ -605,7 +607,7 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, | |||
605 | u32 descsize; | 607 | u32 descsize; |
606 | u32 packetlen; | 608 | u32 packetlen; |
607 | u32 packetlen_aligned; | 609 | u32 packetlen_aligned; |
608 | struct scatterlist bufferlist[3]; | 610 | struct kvec bufferlist[3]; |
609 | u64 aligned_data = 0; | 611 | u64 aligned_data = 0; |
610 | bool signal = false; | 612 | bool signal = false; |
611 | 613 | ||
@@ -637,11 +639,12 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, | |||
637 | desc.range[i].pfn = pagebuffers[i].pfn; | 639 | desc.range[i].pfn = pagebuffers[i].pfn; |
638 | } | 640 | } |
639 | 641 | ||
640 | sg_init_table(bufferlist, 3); | 642 | bufferlist[0].iov_base = &desc; |
641 | sg_set_buf(&bufferlist[0], &desc, descsize); | 643 | bufferlist[0].iov_len = descsize; |
642 | sg_set_buf(&bufferlist[1], buffer, bufferlen); | 644 | bufferlist[1].iov_base = buffer; |
643 | sg_set_buf(&bufferlist[2], &aligned_data, | 645 | bufferlist[1].iov_len = bufferlen; |
644 | packetlen_aligned - packetlen); | 646 | bufferlist[2].iov_base = &aligned_data; |
647 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | ||
645 | 648 | ||
646 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 649 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); |
647 | 650 | ||
@@ -665,7 +668,7 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, | |||
665 | u32 descsize; | 668 | u32 descsize; |
666 | u32 packetlen; | 669 | u32 packetlen; |
667 | u32 packetlen_aligned; | 670 | u32 packetlen_aligned; |
668 | struct scatterlist bufferlist[3]; | 671 | struct kvec bufferlist[3]; |
669 | u64 aligned_data = 0; | 672 | u64 aligned_data = 0; |
670 | bool signal = false; | 673 | bool signal = false; |
671 | u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, | 674 | u32 pfncount = NUM_PAGES_SPANNED(multi_pagebuffer->offset, |
@@ -700,11 +703,12 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, | |||
700 | memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array, | 703 | memcpy(desc.range.pfn_array, multi_pagebuffer->pfn_array, |
701 | pfncount * sizeof(u64)); | 704 | pfncount * sizeof(u64)); |
702 | 705 | ||
703 | sg_init_table(bufferlist, 3); | 706 | bufferlist[0].iov_base = &desc; |
704 | sg_set_buf(&bufferlist[0], &desc, descsize); | 707 | bufferlist[0].iov_len = descsize; |
705 | sg_set_buf(&bufferlist[1], buffer, bufferlen); | 708 | bufferlist[1].iov_base = buffer; |
706 | sg_set_buf(&bufferlist[2], &aligned_data, | 709 | bufferlist[1].iov_len = bufferlen; |
707 | packetlen_aligned - packetlen); | 710 | bufferlist[2].iov_base = &aligned_data; |
711 | bufferlist[2].iov_len = (packetlen_aligned - packetlen); | ||
708 | 712 | ||
709 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); | 713 | ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3, &signal); |
710 | 714 | ||
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index e05517616a06..1544609881fe 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h | |||
@@ -559,8 +559,8 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, | |||
559 | void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); | 559 | void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); |
560 | 560 | ||
561 | int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, | 561 | int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info, |
562 | struct scatterlist *sglist, | 562 | struct kvec *kv_list, |
563 | u32 sgcount, bool *signal); | 563 | u32 kv_count, bool *signal); |
564 | 564 | ||
565 | int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, | 565 | int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, |
566 | u32 buflen); | 566 | u32 buflen); |
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 26c93cf9f6be..15db66b74141 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
28 | #include <linux/hyperv.h> | 28 | #include <linux/hyperv.h> |
29 | #include <linux/uio.h> | ||
29 | 30 | ||
30 | #include "hyperv_vmbus.h" | 31 | #include "hyperv_vmbus.h" |
31 | 32 | ||
@@ -387,23 +388,20 @@ void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) | |||
387 | * | 388 | * |
388 | */ | 389 | */ |
389 | int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, | 390 | int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, |
390 | struct scatterlist *sglist, u32 sgcount, bool *signal) | 391 | struct kvec *kv_list, u32 kv_count, bool *signal) |
391 | { | 392 | { |
392 | int i = 0; | 393 | int i = 0; |
393 | u32 bytes_avail_towrite; | 394 | u32 bytes_avail_towrite; |
394 | u32 bytes_avail_toread; | 395 | u32 bytes_avail_toread; |
395 | u32 totalbytes_towrite = 0; | 396 | u32 totalbytes_towrite = 0; |
396 | 397 | ||
397 | struct scatterlist *sg; | ||
398 | u32 next_write_location; | 398 | u32 next_write_location; |
399 | u32 old_write; | 399 | u32 old_write; |
400 | u64 prev_indices = 0; | 400 | u64 prev_indices = 0; |
401 | unsigned long flags; | 401 | unsigned long flags; |
402 | 402 | ||
403 | for_each_sg(sglist, sg, sgcount, i) | 403 | for (i = 0; i < kv_count; i++) |
404 | { | 404 | totalbytes_towrite += kv_list[i].iov_len; |
405 | totalbytes_towrite += sg->length; | ||
406 | } | ||
407 | 405 | ||
408 | totalbytes_towrite += sizeof(u64); | 406 | totalbytes_towrite += sizeof(u64); |
409 | 407 | ||
@@ -427,12 +425,11 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, | |||
427 | 425 | ||
428 | old_write = next_write_location; | 426 | old_write = next_write_location; |
429 | 427 | ||
430 | for_each_sg(sglist, sg, sgcount, i) | 428 | for (i = 0; i < kv_count; i++) { |
431 | { | ||
432 | next_write_location = hv_copyto_ringbuffer(outring_info, | 429 | next_write_location = hv_copyto_ringbuffer(outring_info, |
433 | next_write_location, | 430 | next_write_location, |
434 | sg_virt(sg), | 431 | kv_list[i].iov_base, |
435 | sg->length); | 432 | kv_list[i].iov_len); |
436 | } | 433 | } |
437 | 434 | ||
438 | /* Set previous packet start */ | 435 | /* Set previous packet start */ |
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 6b862dadbb7a..9b07e1f070ac 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
@@ -802,7 +802,7 @@ extern int vmbus_open(struct vmbus_channel *channel, | |||
802 | extern void vmbus_close(struct vmbus_channel *channel); | 802 | extern void vmbus_close(struct vmbus_channel *channel); |
803 | 803 | ||
804 | extern int vmbus_sendpacket(struct vmbus_channel *channel, | 804 | extern int vmbus_sendpacket(struct vmbus_channel *channel, |
805 | const void *buffer, | 805 | void *buffer, |
806 | u32 bufferLen, | 806 | u32 bufferLen, |
807 | u64 requestid, | 807 | u64 requestid, |
808 | enum vmbus_packet_type type, | 808 | enum vmbus_packet_type type, |