diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2011-02-11 12:59:43 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-18 16:11:03 -0500 |
commit | 0c3b7b2f75158f9420ceeb87d5924bdbd8d0304a (patch) | |
tree | df9a27e92c5b3c2fea857e9fed706513fb9f99b4 /drivers/staging/hv | |
parent | df3493e0b3ba72f9b6192a91b24197cac41ce557 (diff) |
Staging: hv: Use native wait primitives
In preperation for getting rid of the osd layer; change
the code to use native wait interfaces. As part of this,
fixed the buggy implementation in the osd_wait_primitive
where the condition was cleared potentially after the
condition was signalled.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv')
-rw-r--r-- | drivers/staging/hv/channel.c | 58 | ||||
-rw-r--r-- | drivers/staging/hv/channel_mgmt.c | 46 | ||||
-rw-r--r-- | drivers/staging/hv/channel_mgmt.h | 4 | ||||
-rw-r--r-- | drivers/staging/hv/connection.c | 28 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc.c | 102 | ||||
-rw-r--r-- | drivers/staging/hv/netvsc.h | 3 | ||||
-rw-r--r-- | drivers/staging/hv/rndis_filter.c | 38 | ||||
-rw-r--r-- | drivers/staging/hv/storvsc.c | 98 | ||||
-rw-r--r-- | drivers/staging/hv/vmbus_private.h | 3 |
9 files changed, 208 insertions, 172 deletions
diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 6c292e69e99..5a0923ca565 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Hank Janssen <hjanssen@microsoft.com> | 19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/wait.h> | ||
22 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -243,11 +245,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
243 | goto errorout; | 245 | goto errorout; |
244 | } | 246 | } |
245 | 247 | ||
246 | openInfo->waitevent = osd_waitevent_create(); | 248 | init_waitqueue_head(&openInfo->waitevent); |
247 | if (!openInfo->waitevent) { | ||
248 | err = -ENOMEM; | ||
249 | goto errorout; | ||
250 | } | ||
251 | 249 | ||
252 | openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; | 250 | openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; |
253 | openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; | 251 | openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; |
@@ -280,8 +278,15 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, | |||
280 | goto Cleanup; | 278 | goto Cleanup; |
281 | } | 279 | } |
282 | 280 | ||
283 | /* FIXME: Need to time-out here */ | 281 | openInfo->wait_condition = 0; |
284 | osd_waitevent_wait(openInfo->waitevent); | 282 | wait_event_timeout(openInfo->waitevent, |
283 | openInfo->wait_condition, | ||
284 | msecs_to_jiffies(1000)); | ||
285 | if (openInfo->wait_condition == 0) { | ||
286 | err = -ETIMEDOUT; | ||
287 | goto errorout; | ||
288 | } | ||
289 | |||
285 | 290 | ||
286 | if (openInfo->response.open_result.status == 0) | 291 | if (openInfo->response.open_result.status == 0) |
287 | DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); | 292 | DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); |
@@ -294,7 +299,6 @@ Cleanup: | |||
294 | list_del(&openInfo->msglistentry); | 299 | list_del(&openInfo->msglistentry); |
295 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 300 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
296 | 301 | ||
297 | kfree(openInfo->waitevent); | ||
298 | kfree(openInfo); | 302 | kfree(openInfo); |
299 | return 0; | 303 | return 0; |
300 | 304 | ||
@@ -509,11 +513,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, | |||
509 | if (ret) | 513 | if (ret) |
510 | return ret; | 514 | return ret; |
511 | 515 | ||
512 | msginfo->waitevent = osd_waitevent_create(); | 516 | init_waitqueue_head(&msginfo->waitevent); |
513 | if (!msginfo->waitevent) { | ||
514 | ret = -ENOMEM; | ||
515 | goto Cleanup; | ||
516 | } | ||
517 | 517 | ||
518 | gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg; | 518 | gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg; |
519 | gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER; | 519 | gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER; |
@@ -533,6 +533,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, | |||
533 | DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", | 533 | DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", |
534 | msginfo->msgsize - sizeof(*msginfo)); | 534 | msginfo->msgsize - sizeof(*msginfo)); |
535 | 535 | ||
536 | msginfo->wait_condition = 0; | ||
536 | ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - | 537 | ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize - |
537 | sizeof(*msginfo)); | 538 | sizeof(*msginfo)); |
538 | if (ret != 0) { | 539 | if (ret != 0) { |
@@ -566,7 +567,11 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, | |||
566 | 567 | ||
567 | } | 568 | } |
568 | } | 569 | } |
569 | osd_waitevent_wait(msginfo->waitevent); | 570 | wait_event_timeout(msginfo->waitevent, |
571 | msginfo->wait_condition, | ||
572 | msecs_to_jiffies(1000)); | ||
573 | BUG_ON(msginfo->wait_condition == 0); | ||
574 | |||
570 | 575 | ||
571 | /* At this point, we received the gpadl created msg */ | 576 | /* At this point, we received the gpadl created msg */ |
572 | DPRINT_DBG(VMBUS, "Received GPADL created " | 577 | DPRINT_DBG(VMBUS, "Received GPADL created " |
@@ -582,7 +587,6 @@ Cleanup: | |||
582 | list_del(&msginfo->msglistentry); | 587 | list_del(&msginfo->msglistentry); |
583 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 588 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
584 | 589 | ||
585 | kfree(msginfo->waitevent); | ||
586 | kfree(msginfo); | 590 | kfree(msginfo); |
587 | return ret; | 591 | return ret; |
588 | } | 592 | } |
@@ -605,11 +609,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) | |||
605 | if (!info) | 609 | if (!info) |
606 | return -ENOMEM; | 610 | return -ENOMEM; |
607 | 611 | ||
608 | info->waitevent = osd_waitevent_create(); | 612 | init_waitqueue_head(&info->waitevent); |
609 | if (!info->waitevent) { | ||
610 | kfree(info); | ||
611 | return -ENOMEM; | ||
612 | } | ||
613 | 613 | ||
614 | msg = (struct vmbus_channel_gpadl_teardown *)info->msg; | 614 | msg = (struct vmbus_channel_gpadl_teardown *)info->msg; |
615 | 615 | ||
@@ -621,22 +621,20 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) | |||
621 | list_add_tail(&info->msglistentry, | 621 | list_add_tail(&info->msglistentry, |
622 | &vmbus_connection.chn_msg_list); | 622 | &vmbus_connection.chn_msg_list); |
623 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 623 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
624 | 624 | info->wait_condition = 0; | |
625 | ret = vmbus_post_msg(msg, | 625 | ret = vmbus_post_msg(msg, |
626 | sizeof(struct vmbus_channel_gpadl_teardown)); | 626 | sizeof(struct vmbus_channel_gpadl_teardown)); |
627 | if (ret != 0) { | ||
628 | /* TODO: */ | ||
629 | /* something... */ | ||
630 | } | ||
631 | 627 | ||
632 | osd_waitevent_wait(info->waitevent); | 628 | BUG_ON(ret != 0); |
629 | wait_event_timeout(info->waitevent, | ||
630 | info->wait_condition, msecs_to_jiffies(1000)); | ||
631 | BUG_ON(info->wait_condition == 0); | ||
633 | 632 | ||
634 | /* Received a torndown response */ | 633 | /* Received a torndown response */ |
635 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | 634 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); |
636 | list_del(&info->msglistentry); | 635 | list_del(&info->msglistentry); |
637 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 636 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
638 | 637 | ||
639 | kfree(info->waitevent); | ||
640 | kfree(info); | 638 | kfree(info); |
641 | return ret; | 639 | return ret; |
642 | } | 640 | } |
@@ -664,18 +662,14 @@ void vmbus_close(struct vmbus_channel *channel) | |||
664 | if (!info) | 662 | if (!info) |
665 | return; | 663 | return; |
666 | 664 | ||
667 | /* info->waitEvent = osd_waitevent_create(); */ | ||
668 | 665 | ||
669 | msg = (struct vmbus_channel_close_channel *)info->msg; | 666 | msg = (struct vmbus_channel_close_channel *)info->msg; |
670 | msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; | 667 | msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; |
671 | msg->child_relid = channel->offermsg.child_relid; | 668 | msg->child_relid = channel->offermsg.child_relid; |
672 | 669 | ||
673 | ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel)); | 670 | ret = vmbus_post_msg(msg, sizeof(struct vmbus_channel_close_channel)); |
674 | if (ret != 0) { | ||
675 | /* TODO: */ | ||
676 | /* something... */ | ||
677 | } | ||
678 | 671 | ||
672 | BUG_ON(ret != 0); | ||
679 | /* Tear down the gpadl for the channel's ring buffer */ | 673 | /* Tear down the gpadl for the channel's ring buffer */ |
680 | if (channel->ringbuffer_gpadlhandle) | 674 | if (channel->ringbuffer_gpadlhandle) |
681 | vmbus_teardown_gpadl(channel, | 675 | vmbus_teardown_gpadl(channel, |
diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index a9c9d49a99b..da1e56a9c4d 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Hank Janssen <hjanssen@microsoft.com> | 19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/wait.h> | ||
22 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/list.h> | 26 | #include <linux/list.h> |
@@ -593,7 +595,8 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) | |||
593 | memcpy(&msginfo->response.open_result, | 595 | memcpy(&msginfo->response.open_result, |
594 | result, | 596 | result, |
595 | sizeof(struct vmbus_channel_open_result)); | 597 | sizeof(struct vmbus_channel_open_result)); |
596 | osd_waitevent_set(msginfo->waitevent); | 598 | msginfo->wait_condition = 1; |
599 | wake_up(&msginfo->waitevent); | ||
597 | break; | 600 | break; |
598 | } | 601 | } |
599 | } | 602 | } |
@@ -643,7 +646,8 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) | |||
643 | memcpy(&msginfo->response.gpadl_created, | 646 | memcpy(&msginfo->response.gpadl_created, |
644 | gpadlcreated, | 647 | gpadlcreated, |
645 | sizeof(struct vmbus_channel_gpadl_created)); | 648 | sizeof(struct vmbus_channel_gpadl_created)); |
646 | osd_waitevent_set(msginfo->waitevent); | 649 | msginfo->wait_condition = 1; |
650 | wake_up(&msginfo->waitevent); | ||
647 | break; | 651 | break; |
648 | } | 652 | } |
649 | } | 653 | } |
@@ -689,7 +693,8 @@ static void vmbus_ongpadl_torndown( | |||
689 | memcpy(&msginfo->response.gpadl_torndown, | 693 | memcpy(&msginfo->response.gpadl_torndown, |
690 | gpadl_torndown, | 694 | gpadl_torndown, |
691 | sizeof(struct vmbus_channel_gpadl_torndown)); | 695 | sizeof(struct vmbus_channel_gpadl_torndown)); |
692 | osd_waitevent_set(msginfo->waitevent); | 696 | msginfo->wait_condition = 1; |
697 | wake_up(&msginfo->waitevent); | ||
693 | break; | 698 | break; |
694 | } | 699 | } |
695 | } | 700 | } |
@@ -730,7 +735,8 @@ static void vmbus_onversion_response( | |||
730 | memcpy(&msginfo->response.version_response, | 735 | memcpy(&msginfo->response.version_response, |
731 | version_response, | 736 | version_response, |
732 | sizeof(struct vmbus_channel_version_response)); | 737 | sizeof(struct vmbus_channel_version_response)); |
733 | osd_waitevent_set(msginfo->waitevent); | 738 | msginfo->wait_condition = 1; |
739 | wake_up(&msginfo->waitevent); | ||
734 | } | 740 | } |
735 | } | 741 | } |
736 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | 742 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); |
@@ -805,44 +811,34 @@ int vmbus_request_offers(void) | |||
805 | if (!msginfo) | 811 | if (!msginfo) |
806 | return -ENOMEM; | 812 | return -ENOMEM; |
807 | 813 | ||
808 | msginfo->waitevent = osd_waitevent_create(); | 814 | init_waitqueue_head(&msginfo->waitevent); |
809 | if (!msginfo->waitevent) { | ||
810 | kfree(msginfo); | ||
811 | return -ENOMEM; | ||
812 | } | ||
813 | 815 | ||
814 | msg = (struct vmbus_channel_message_header *)msginfo->msg; | 816 | msg = (struct vmbus_channel_message_header *)msginfo->msg; |
815 | 817 | ||
816 | msg->msgtype = CHANNELMSG_REQUESTOFFERS; | 818 | msg->msgtype = CHANNELMSG_REQUESTOFFERS; |
817 | 819 | ||
818 | /*SpinlockAcquire(gVmbusConnection.channelMsgLock); | ||
819 | INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, | ||
820 | &msgInfo->msgListEntry); | ||
821 | SpinlockRelease(gVmbusConnection.channelMsgLock);*/ | ||
822 | 820 | ||
823 | ret = vmbus_post_msg(msg, | 821 | ret = vmbus_post_msg(msg, |
824 | sizeof(struct vmbus_channel_message_header)); | 822 | sizeof(struct vmbus_channel_message_header)); |
825 | if (ret != 0) { | 823 | if (ret != 0) { |
826 | DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); | 824 | DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret); |
827 | 825 | ||
828 | /*SpinlockAcquire(gVmbusConnection.channelMsgLock); | 826 | goto cleanup; |
829 | REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); | 827 | } |
830 | SpinlockRelease(gVmbusConnection.channelMsgLock);*/ | ||
831 | 828 | ||
832 | goto Cleanup; | 829 | msginfo->wait_condition = 0; |
830 | wait_event_timeout(msginfo->waitevent, msginfo->wait_condition, | ||
831 | msecs_to_jiffies(1000)); | ||
832 | if (msginfo->wait_condition == 0) { | ||
833 | ret = -ETIMEDOUT; | ||
834 | goto cleanup; | ||
833 | } | 835 | } |
834 | /* osd_waitevent_wait(msgInfo->waitEvent); */ | ||
835 | 836 | ||
836 | /*SpinlockAcquire(gVmbusConnection.channelMsgLock); | ||
837 | REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); | ||
838 | SpinlockRelease(gVmbusConnection.channelMsgLock);*/ | ||
839 | 837 | ||
840 | 838 | ||
841 | Cleanup: | 839 | cleanup: |
842 | if (msginfo) { | 840 | if (msginfo) |
843 | kfree(msginfo->waitevent); | ||
844 | kfree(msginfo); | 841 | kfree(msginfo); |
845 | } | ||
846 | 842 | ||
847 | return ret; | 843 | return ret; |
848 | } | 844 | } |
diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index fe40bf2706d..3368bf14e3c 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h | |||
@@ -289,8 +289,8 @@ struct vmbus_channel_msginfo { | |||
289 | struct list_head submsglist; | 289 | struct list_head submsglist; |
290 | 290 | ||
291 | /* Synchronize the request/response if needed */ | 291 | /* Synchronize the request/response if needed */ |
292 | struct osd_waitevent *waitevent; | 292 | int wait_condition; |
293 | 293 | wait_queue_head_t waitevent; | |
294 | union { | 294 | union { |
295 | struct vmbus_channel_version_supported version_supported; | 295 | struct vmbus_channel_version_supported version_supported; |
296 | struct vmbus_channel_open_result open_result; | 296 | struct vmbus_channel_open_result open_result; |
diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index ed0976aad6f..51dd362188b 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c | |||
@@ -21,6 +21,8 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/sched.h> | ||
25 | #include <linux/wait.h> | ||
24 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
25 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
26 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
@@ -97,11 +99,7 @@ int vmbus_connect(void) | |||
97 | goto Cleanup; | 99 | goto Cleanup; |
98 | } | 100 | } |
99 | 101 | ||
100 | msginfo->waitevent = osd_waitevent_create(); | 102 | init_waitqueue_head(&msginfo->waitevent); |
101 | if (!msginfo->waitevent) { | ||
102 | ret = -ENOMEM; | ||
103 | goto Cleanup; | ||
104 | } | ||
105 | 103 | ||
106 | msg = (struct vmbus_channel_initiate_contact *)msginfo->msg; | 104 | msg = (struct vmbus_channel_initiate_contact *)msginfo->msg; |
107 | 105 | ||
@@ -131,14 +129,30 @@ int vmbus_connect(void) | |||
131 | ret = vmbus_post_msg(msg, | 129 | ret = vmbus_post_msg(msg, |
132 | sizeof(struct vmbus_channel_initiate_contact)); | 130 | sizeof(struct vmbus_channel_initiate_contact)); |
133 | if (ret != 0) { | 131 | if (ret != 0) { |
132 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | ||
134 | list_del(&msginfo->msglistentry); | 133 | list_del(&msginfo->msglistentry); |
134 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, | ||
135 | flags); | ||
135 | goto Cleanup; | 136 | goto Cleanup; |
136 | } | 137 | } |
137 | 138 | ||
138 | /* Wait for the connection response */ | 139 | /* Wait for the connection response */ |
139 | osd_waitevent_wait(msginfo->waitevent); | 140 | msginfo->wait_condition = 0; |
141 | wait_event_timeout(msginfo->waitevent, msginfo->wait_condition, | ||
142 | msecs_to_jiffies(1000)); | ||
143 | if (msginfo->wait_condition == 0) { | ||
144 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, | ||
145 | flags); | ||
146 | list_del(&msginfo->msglistentry); | ||
147 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, | ||
148 | flags); | ||
149 | ret = -ETIMEDOUT; | ||
150 | goto Cleanup; | ||
151 | } | ||
140 | 152 | ||
153 | spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); | ||
141 | list_del(&msginfo->msglistentry); | 154 | list_del(&msginfo->msglistentry); |
155 | spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); | ||
142 | 156 | ||
143 | /* Check if successful */ | 157 | /* Check if successful */ |
144 | if (msginfo->response.version_response.version_supported) { | 158 | if (msginfo->response.version_response.version_supported) { |
@@ -153,7 +167,6 @@ int vmbus_connect(void) | |||
153 | goto Cleanup; | 167 | goto Cleanup; |
154 | } | 168 | } |
155 | 169 | ||
156 | kfree(msginfo->waitevent); | ||
157 | kfree(msginfo); | 170 | kfree(msginfo); |
158 | return 0; | 171 | return 0; |
159 | 172 | ||
@@ -174,7 +187,6 @@ Cleanup: | |||
174 | } | 187 | } |
175 | 188 | ||
176 | if (msginfo) { | 189 | if (msginfo) { |
177 | kfree(msginfo->waitevent); | ||
178 | kfree(msginfo); | 190 | kfree(msginfo); |
179 | } | 191 | } |
180 | 192 | ||
diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index a271aa790c9..7233564668e 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Hank Janssen <hjanssen@microsoft.com> | 19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/wait.h> | ||
22 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
23 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
24 | #include <linux/io.h> | 26 | #include <linux/io.h> |
@@ -230,7 +232,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
230 | "unable to allocate receive buffer of size %d", | 232 | "unable to allocate receive buffer of size %d", |
231 | net_device->recv_buf_size); | 233 | net_device->recv_buf_size); |
232 | ret = -1; | 234 | ret = -1; |
233 | goto Cleanup; | 235 | goto cleanup; |
234 | } | 236 | } |
235 | /* page-aligned buffer */ | 237 | /* page-aligned buffer */ |
236 | /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ | 238 | /* ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE - 1)) == */ |
@@ -249,10 +251,9 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
249 | if (ret != 0) { | 251 | if (ret != 0) { |
250 | DPRINT_ERR(NETVSC, | 252 | DPRINT_ERR(NETVSC, |
251 | "unable to establish receive buffer's gpadl"); | 253 | "unable to establish receive buffer's gpadl"); |
252 | goto Cleanup; | 254 | goto cleanup; |
253 | } | 255 | } |
254 | 256 | ||
255 | /* osd_waitevent_wait(ext->ChannelInitEvent); */ | ||
256 | 257 | ||
257 | /* Notify the NetVsp of the gpadl handle */ | 258 | /* Notify the NetVsp of the gpadl handle */ |
258 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); | 259 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); |
@@ -268,6 +269,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
268 | send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; | 269 | send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; |
269 | 270 | ||
270 | /* Send the gpadl notification request */ | 271 | /* Send the gpadl notification request */ |
272 | net_device->wait_condition = 0; | ||
271 | ret = vmbus_sendpacket(device->channel, init_packet, | 273 | ret = vmbus_sendpacket(device->channel, init_packet, |
272 | sizeof(struct nvsp_message), | 274 | sizeof(struct nvsp_message), |
273 | (unsigned long)init_packet, | 275 | (unsigned long)init_packet, |
@@ -276,10 +278,14 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
276 | if (ret != 0) { | 278 | if (ret != 0) { |
277 | DPRINT_ERR(NETVSC, | 279 | DPRINT_ERR(NETVSC, |
278 | "unable to send receive buffer's gpadl to netvsp"); | 280 | "unable to send receive buffer's gpadl to netvsp"); |
279 | goto Cleanup; | 281 | goto cleanup; |
280 | } | 282 | } |
281 | 283 | ||
282 | osd_waitevent_wait(net_device->channel_init_event); | 284 | wait_event_timeout(net_device->channel_init_wait, |
285 | net_device->wait_condition, | ||
286 | msecs_to_jiffies(1000)); | ||
287 | BUG_ON(net_device->wait_condition == 0); | ||
288 | |||
283 | 289 | ||
284 | /* Check the response */ | 290 | /* Check the response */ |
285 | if (init_packet->msg.v1_msg. | 291 | if (init_packet->msg.v1_msg. |
@@ -289,7 +295,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
289 | init_packet->msg.v1_msg. | 295 | init_packet->msg.v1_msg. |
290 | send_recv_buf_complete.status); | 296 | send_recv_buf_complete.status); |
291 | ret = -1; | 297 | ret = -1; |
292 | goto Cleanup; | 298 | goto cleanup; |
293 | } | 299 | } |
294 | 300 | ||
295 | /* Parse the response */ | 301 | /* Parse the response */ |
@@ -303,7 +309,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
303 | * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); | 309 | * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); |
304 | if (net_device->recv_section == NULL) { | 310 | if (net_device->recv_section == NULL) { |
305 | ret = -1; | 311 | ret = -1; |
306 | goto Cleanup; | 312 | goto cleanup; |
307 | } | 313 | } |
308 | 314 | ||
309 | memcpy(net_device->recv_section, | 315 | memcpy(net_device->recv_section, |
@@ -327,15 +333,15 @@ static int netvsc_init_recv_buf(struct hv_device *device) | |||
327 | if (net_device->recv_section_cnt != 1 || | 333 | if (net_device->recv_section_cnt != 1 || |
328 | net_device->recv_section->offset != 0) { | 334 | net_device->recv_section->offset != 0) { |
329 | ret = -1; | 335 | ret = -1; |
330 | goto Cleanup; | 336 | goto cleanup; |
331 | } | 337 | } |
332 | 338 | ||
333 | goto Exit; | 339 | goto exit; |
334 | 340 | ||
335 | Cleanup: | 341 | cleanup: |
336 | netvsc_destroy_recv_buf(net_device); | 342 | netvsc_destroy_recv_buf(net_device); |
337 | 343 | ||
338 | Exit: | 344 | exit: |
339 | put_net_device(device); | 345 | put_net_device(device); |
340 | return ret; | 346 | return ret; |
341 | } | 347 | } |
@@ -354,7 +360,7 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
354 | } | 360 | } |
355 | if (net_device->send_buf_size <= 0) { | 361 | if (net_device->send_buf_size <= 0) { |
356 | ret = -EINVAL; | 362 | ret = -EINVAL; |
357 | goto Cleanup; | 363 | goto cleanup; |
358 | } | 364 | } |
359 | 365 | ||
360 | /* page-size grandularity */ | 366 | /* page-size grandularity */ |
@@ -367,7 +373,7 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
367 | DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", | 373 | DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", |
368 | net_device->send_buf_size); | 374 | net_device->send_buf_size); |
369 | ret = -1; | 375 | ret = -1; |
370 | goto Cleanup; | 376 | goto cleanup; |
371 | } | 377 | } |
372 | /* page-aligned buffer */ | 378 | /* page-aligned buffer */ |
373 | /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ | 379 | /* ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE - 1)) == 0); */ |
@@ -384,11 +390,9 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
384 | &net_device->send_buf_gpadl_handle); | 390 | &net_device->send_buf_gpadl_handle); |
385 | if (ret != 0) { | 391 | if (ret != 0) { |
386 | DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); | 392 | DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); |
387 | goto Cleanup; | 393 | goto cleanup; |
388 | } | 394 | } |
389 | 395 | ||
390 | /* osd_waitevent_wait(ext->ChannelInitEvent); */ | ||
391 | |||
392 | /* Notify the NetVsp of the gpadl handle */ | 396 | /* Notify the NetVsp of the gpadl handle */ |
393 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); | 397 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); |
394 | 398 | ||
@@ -403,6 +407,7 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
403 | NETVSC_SEND_BUFFER_ID; | 407 | NETVSC_SEND_BUFFER_ID; |
404 | 408 | ||
405 | /* Send the gpadl notification request */ | 409 | /* Send the gpadl notification request */ |
410 | net_device->wait_condition = 0; | ||
406 | ret = vmbus_sendpacket(device->channel, init_packet, | 411 | ret = vmbus_sendpacket(device->channel, init_packet, |
407 | sizeof(struct nvsp_message), | 412 | sizeof(struct nvsp_message), |
408 | (unsigned long)init_packet, | 413 | (unsigned long)init_packet, |
@@ -411,10 +416,13 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
411 | if (ret != 0) { | 416 | if (ret != 0) { |
412 | DPRINT_ERR(NETVSC, | 417 | DPRINT_ERR(NETVSC, |
413 | "unable to send receive buffer's gpadl to netvsp"); | 418 | "unable to send receive buffer's gpadl to netvsp"); |
414 | goto Cleanup; | 419 | goto cleanup; |
415 | } | 420 | } |
416 | 421 | ||
417 | osd_waitevent_wait(net_device->channel_init_event); | 422 | wait_event_timeout(net_device->channel_init_wait, |
423 | net_device->wait_condition, | ||
424 | msecs_to_jiffies(1000)); | ||
425 | BUG_ON(net_device->wait_condition == 0); | ||
418 | 426 | ||
419 | /* Check the response */ | 427 | /* Check the response */ |
420 | if (init_packet->msg.v1_msg. | 428 | if (init_packet->msg.v1_msg. |
@@ -424,18 +432,18 @@ static int netvsc_init_send_buf(struct hv_device *device) | |||
424 | init_packet->msg.v1_msg. | 432 | init_packet->msg.v1_msg. |
425 | send_send_buf_complete.status); | 433 | send_send_buf_complete.status); |
426 | ret = -1; | 434 | ret = -1; |
427 | goto Cleanup; | 435 | goto cleanup; |
428 | } | 436 | } |
429 | 437 | ||
430 | net_device->send_section_size = init_packet-> | 438 | net_device->send_section_size = init_packet-> |
431 | msg.v1_msg.send_send_buf_complete.section_size; | 439 | msg.v1_msg.send_send_buf_complete.section_size; |
432 | 440 | ||
433 | goto Exit; | 441 | goto exit; |
434 | 442 | ||
435 | Cleanup: | 443 | cleanup: |
436 | netvsc_destroy_send_buf(net_device); | 444 | netvsc_destroy_send_buf(net_device); |
437 | 445 | ||
438 | Exit: | 446 | exit: |
439 | put_net_device(device); | 447 | put_net_device(device); |
440 | return ret; | 448 | return ret; |
441 | } | 449 | } |
@@ -611,6 +619,7 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
611 | DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); | 619 | DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); |
612 | 620 | ||
613 | /* Send the init request */ | 621 | /* Send the init request */ |
622 | net_device->wait_condition = 0; | ||
614 | ret = vmbus_sendpacket(device->channel, init_packet, | 623 | ret = vmbus_sendpacket(device->channel, init_packet, |
615 | sizeof(struct nvsp_message), | 624 | sizeof(struct nvsp_message), |
616 | (unsigned long)init_packet, | 625 | (unsigned long)init_packet, |
@@ -619,10 +628,16 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
619 | 628 | ||
620 | if (ret != 0) { | 629 | if (ret != 0) { |
621 | DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); | 630 | DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit"); |
622 | goto Cleanup; | 631 | goto cleanup; |
623 | } | 632 | } |
624 | 633 | ||
625 | osd_waitevent_wait(net_device->channel_init_event); | 634 | wait_event_timeout(net_device->channel_init_wait, |
635 | net_device->wait_condition, | ||
636 | msecs_to_jiffies(1000)); | ||
637 | if (net_device->wait_condition == 0) { | ||
638 | ret = -ETIMEDOUT; | ||
639 | goto cleanup; | ||
640 | } | ||
626 | 641 | ||
627 | /* Now, check the response */ | 642 | /* Now, check the response */ |
628 | /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ | 643 | /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ |
@@ -637,7 +652,7 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
637 | "unable to initialize with netvsp (status 0x%x)", | 652 | "unable to initialize with netvsp (status 0x%x)", |
638 | init_packet->msg.init_msg.init_complete.status); | 653 | init_packet->msg.init_msg.init_complete.status); |
639 | ret = -1; | 654 | ret = -1; |
640 | goto Cleanup; | 655 | goto cleanup; |
641 | } | 656 | } |
642 | 657 | ||
643 | if (init_packet->msg.init_msg.init_complete. | 658 | if (init_packet->msg.init_msg.init_complete. |
@@ -647,7 +662,7 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
647 | init_packet->msg.init_msg. | 662 | init_packet->msg.init_msg. |
648 | init_complete.negotiated_protocol_ver); | 663 | init_complete.negotiated_protocol_ver); |
649 | ret = -1; | 664 | ret = -1; |
650 | goto Cleanup; | 665 | goto cleanup; |
651 | } | 666 | } |
652 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); | 667 | DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); |
653 | 668 | ||
@@ -666,29 +681,22 @@ static int netvsc_connect_vsp(struct hv_device *device) | |||
666 | 681 | ||
667 | /* Send the init request */ | 682 | /* Send the init request */ |
668 | ret = vmbus_sendpacket(device->channel, init_packet, | 683 | ret = vmbus_sendpacket(device->channel, init_packet, |
669 | sizeof(struct nvsp_message), | 684 | sizeof(struct nvsp_message), |
670 | (unsigned long)init_packet, | 685 | (unsigned long)init_packet, |
671 | VM_PKT_DATA_INBAND, 0); | 686 | VM_PKT_DATA_INBAND, 0); |
672 | if (ret != 0) { | 687 | if (ret != 0) { |
673 | DPRINT_ERR(NETVSC, | 688 | DPRINT_ERR(NETVSC, |
674 | "unable to send NvspMessage1TypeSendNdisVersion"); | 689 | "unable to send NvspMessage1TypeSendNdisVersion"); |
675 | ret = -1; | 690 | ret = -1; |
676 | goto Cleanup; | 691 | goto cleanup; |
677 | } | 692 | } |
678 | /* | ||
679 | * BUGBUG - We have to wait for the above msg since the | ||
680 | * netvsp uses KMCL which acknowledges packet (completion | ||
681 | * packet) since our Vmbus always set the | ||
682 | * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag | ||
683 | */ | ||
684 | /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */ | ||
685 | 693 | ||
686 | /* Post the big receive buffer to NetVSP */ | 694 | /* Post the big receive buffer to NetVSP */ |
687 | ret = netvsc_init_recv_buf(device); | 695 | ret = netvsc_init_recv_buf(device); |
688 | if (ret == 0) | 696 | if (ret == 0) |
689 | ret = netvsc_init_send_buf(device); | 697 | ret = netvsc_init_send_buf(device); |
690 | 698 | ||
691 | Cleanup: | 699 | cleanup: |
692 | put_net_device(device); | 700 | put_net_device(device); |
693 | return ret; | 701 | return ret; |
694 | } | 702 | } |
@@ -715,7 +723,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) | |||
715 | net_device = alloc_net_device(device); | 723 | net_device = alloc_net_device(device); |
716 | if (!net_device) { | 724 | if (!net_device) { |
717 | ret = -1; | 725 | ret = -1; |
718 | goto Cleanup; | 726 | goto cleanup; |
719 | } | 727 | } |
720 | 728 | ||
721 | DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); | 729 | DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); |
@@ -741,11 +749,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) | |||
741 | list_add_tail(&packet->list_ent, | 749 | list_add_tail(&packet->list_ent, |
742 | &net_device->recv_pkt_list); | 750 | &net_device->recv_pkt_list); |
743 | } | 751 | } |
744 | net_device->channel_init_event = osd_waitevent_create(); | 752 | init_waitqueue_head(&net_device->channel_init_wait); |
745 | if (!net_device->channel_init_event) { | ||
746 | ret = -ENOMEM; | ||
747 | goto Cleanup; | ||
748 | } | ||
749 | 753 | ||
750 | /* Open the channel */ | 754 | /* Open the channel */ |
751 | ret = vmbus_open(device->channel, net_driver->ring_buf_size, | 755 | ret = vmbus_open(device->channel, net_driver->ring_buf_size, |
@@ -755,7 +759,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) | |||
755 | if (ret != 0) { | 759 | if (ret != 0) { |
756 | DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); | 760 | DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); |
757 | ret = -1; | 761 | ret = -1; |
758 | goto Cleanup; | 762 | goto cleanup; |
759 | } | 763 | } |
760 | 764 | ||
761 | /* Channel is opened */ | 765 | /* Channel is opened */ |
@@ -778,11 +782,9 @@ close: | |||
778 | /* Now, we can close the channel safely */ | 782 | /* Now, we can close the channel safely */ |
779 | vmbus_close(device->channel); | 783 | vmbus_close(device->channel); |
780 | 784 | ||
781 | Cleanup: | 785 | cleanup: |
782 | 786 | ||
783 | if (net_device) { | 787 | if (net_device) { |
784 | kfree(net_device->channel_init_event); | ||
785 | |||
786 | list_for_each_entry_safe(packet, pos, | 788 | list_for_each_entry_safe(packet, pos, |
787 | &net_device->recv_pkt_list, | 789 | &net_device->recv_pkt_list, |
788 | list_ent) { | 790 | list_ent) { |
@@ -847,7 +849,6 @@ static int netvsc_device_remove(struct hv_device *device) | |||
847 | kfree(netvsc_packet); | 849 | kfree(netvsc_packet); |
848 | } | 850 | } |
849 | 851 | ||
850 | kfree(net_device->channel_init_event); | ||
851 | free_net_device(net_device); | 852 | free_net_device(net_device); |
852 | return 0; | 853 | return 0; |
853 | } | 854 | } |
@@ -887,7 +888,8 @@ static void netvsc_send_completion(struct hv_device *device, | |||
887 | /* Copy the response back */ | 888 | /* Copy the response back */ |
888 | memcpy(&net_device->channel_init_pkt, nvsp_packet, | 889 | memcpy(&net_device->channel_init_pkt, nvsp_packet, |
889 | sizeof(struct nvsp_message)); | 890 | sizeof(struct nvsp_message)); |
890 | osd_waitevent_set(net_device->channel_init_event); | 891 | net_device->wait_condition = 1; |
892 | wake_up(&net_device->channel_init_wait); | ||
891 | } else if (nvsp_packet->hdr.msg_type == | 893 | } else if (nvsp_packet->hdr.msg_type == |
892 | NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) { | 894 | NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) { |
893 | /* Get the send context */ | 895 | /* Get the send context */ |
diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index 5f6dcf15fa2..45d24b9d91a 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h | |||
@@ -318,7 +318,8 @@ struct netvsc_device { | |||
318 | struct nvsp_1_receive_buffer_section *recv_section; | 318 | struct nvsp_1_receive_buffer_section *recv_section; |
319 | 319 | ||
320 | /* Used for NetVSP initialization protocol */ | 320 | /* Used for NetVSP initialization protocol */ |
321 | struct osd_waitevent *channel_init_event; | 321 | int wait_condition; |
322 | wait_queue_head_t channel_init_wait; | ||
322 | struct nvsp_message channel_init_pkt; | 323 | struct nvsp_message channel_init_pkt; |
323 | 324 | ||
324 | struct nvsp_message revoke_packet; | 325 | struct nvsp_message revoke_packet; |
diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 287e12eddd8..e3bf00491d7 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Hank Janssen <hjanssen@microsoft.com> | 19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/wait.h> | ||
22 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/io.h> | 26 | #include <linux/io.h> |
@@ -57,7 +59,8 @@ struct rndis_device { | |||
57 | 59 | ||
58 | struct rndis_request { | 60 | struct rndis_request { |
59 | struct list_head list_ent; | 61 | struct list_head list_ent; |
60 | struct osd_waitevent *waitevent; | 62 | int wait_condition; |
63 | wait_queue_head_t wait_event; | ||
61 | 64 | ||
62 | /* | 65 | /* |
63 | * FIXME: We assumed a fixed size response here. If we do ever need to | 66 | * FIXME: We assumed a fixed size response here. If we do ever need to |
@@ -129,11 +132,7 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev, | |||
129 | if (!request) | 132 | if (!request) |
130 | return NULL; | 133 | return NULL; |
131 | 134 | ||
132 | request->waitevent = osd_waitevent_create(); | 135 | init_waitqueue_head(&request->wait_event); |
133 | if (!request->waitevent) { | ||
134 | kfree(request); | ||
135 | return NULL; | ||
136 | } | ||
137 | 136 | ||
138 | rndis_msg = &request->request_msg; | 137 | rndis_msg = &request->request_msg; |
139 | rndis_msg->ndis_msg_type = msg_type; | 138 | rndis_msg->ndis_msg_type = msg_type; |
@@ -164,7 +163,6 @@ static void put_rndis_request(struct rndis_device *dev, | |||
164 | list_del(&req->list_ent); | 163 | list_del(&req->list_ent); |
165 | spin_unlock_irqrestore(&dev->request_lock, flags); | 164 | spin_unlock_irqrestore(&dev->request_lock, flags); |
166 | 165 | ||
167 | kfree(req->waitevent); | ||
168 | kfree(req); | 166 | kfree(req); |
169 | } | 167 | } |
170 | 168 | ||
@@ -321,7 +319,8 @@ static void rndis_filter_receive_response(struct rndis_device *dev, | |||
321 | } | 319 | } |
322 | } | 320 | } |
323 | 321 | ||
324 | osd_waitevent_set(request->waitevent); | 322 | request->wait_condition = 1; |
323 | wake_up(&request->wait_event); | ||
325 | } else { | 324 | } else { |
326 | DPRINT_ERR(NETVSC, "no rndis request found for this response " | 325 | DPRINT_ERR(NETVSC, "no rndis request found for this response " |
327 | "(id 0x%x res type 0x%x)", | 326 | "(id 0x%x res type 0x%x)", |
@@ -503,11 +502,17 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, | |||
503 | query->info_buflen = 0; | 502 | query->info_buflen = 0; |
504 | query->dev_vc_handle = 0; | 503 | query->dev_vc_handle = 0; |
505 | 504 | ||
505 | request->wait_condition = 0; | ||
506 | ret = rndis_filter_send_request(dev, request); | 506 | ret = rndis_filter_send_request(dev, request); |
507 | if (ret != 0) | 507 | if (ret != 0) |
508 | goto Cleanup; | 508 | goto Cleanup; |
509 | 509 | ||
510 | osd_waitevent_wait(request->waitevent); | 510 | wait_event_timeout(request->wait_event, request->wait_condition, |
511 | msecs_to_jiffies(1000)); | ||
512 | if (request->wait_condition == 0) { | ||
513 | ret = -ETIMEDOUT; | ||
514 | goto Cleanup; | ||
515 | } | ||
511 | 516 | ||
512 | /* Copy the response back */ | 517 | /* Copy the response back */ |
513 | query_complete = &request->response_msg.msg.query_complete; | 518 | query_complete = &request->response_msg.msg.query_complete; |
@@ -578,12 +583,14 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, | |||
578 | memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), | 583 | memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), |
579 | &new_filter, sizeof(u32)); | 584 | &new_filter, sizeof(u32)); |
580 | 585 | ||
586 | request->wait_condition = 0; | ||
581 | ret = rndis_filter_send_request(dev, request); | 587 | ret = rndis_filter_send_request(dev, request); |
582 | if (ret != 0) | 588 | if (ret != 0) |
583 | goto Cleanup; | 589 | goto Cleanup; |
584 | 590 | ||
585 | ret = osd_waitevent_waitex(request->waitevent, 2000/*2sec*/); | 591 | wait_event_timeout(request->wait_event, request->wait_condition, |
586 | if (!ret) { | 592 | msecs_to_jiffies(2000)); |
593 | if (request->wait_condition == 0) { | ||
587 | ret = -1; | 594 | ret = -1; |
588 | DPRINT_ERR(NETVSC, "timeout before we got a set response..."); | 595 | DPRINT_ERR(NETVSC, "timeout before we got a set response..."); |
589 | /* | 596 | /* |
@@ -669,13 +676,20 @@ static int rndis_filter_init_device(struct rndis_device *dev) | |||
669 | 676 | ||
670 | dev->state = RNDIS_DEV_INITIALIZING; | 677 | dev->state = RNDIS_DEV_INITIALIZING; |
671 | 678 | ||
679 | request->wait_condition = 0; | ||
672 | ret = rndis_filter_send_request(dev, request); | 680 | ret = rndis_filter_send_request(dev, request); |
673 | if (ret != 0) { | 681 | if (ret != 0) { |
674 | dev->state = RNDIS_DEV_UNINITIALIZED; | 682 | dev->state = RNDIS_DEV_UNINITIALIZED; |
675 | goto Cleanup; | 683 | goto Cleanup; |
676 | } | 684 | } |
677 | 685 | ||
678 | osd_waitevent_wait(request->waitevent); | 686 | |
687 | wait_event_timeout(request->wait_event, request->wait_condition, | ||
688 | msecs_to_jiffies(1000)); | ||
689 | if (request->wait_condition == 0) { | ||
690 | ret = -ETIMEDOUT; | ||
691 | goto Cleanup; | ||
692 | } | ||
679 | 693 | ||
680 | init_complete = &request->response_msg.msg.init_complete; | 694 | init_complete = &request->response_msg.msg.init_complete; |
681 | status = init_complete->status; | 695 | status = init_complete->status; |
diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index a6121092d47..2560342a0b9 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c | |||
@@ -19,6 +19,8 @@ | |||
19 | * Hank Janssen <hjanssen@microsoft.com> | 19 | * Hank Janssen <hjanssen@microsoft.com> |
20 | */ | 20 | */ |
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/wait.h> | ||
22 | #include <linux/string.h> | 24 | #include <linux/string.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
@@ -38,7 +40,8 @@ struct storvsc_request_extension { | |||
38 | struct hv_device *device; | 40 | struct hv_device *device; |
39 | 41 | ||
40 | /* Synchronize the request/response if needed */ | 42 | /* Synchronize the request/response if needed */ |
41 | struct osd_waitevent *wait_event; | 43 | int wait_condition; |
44 | wait_queue_head_t wait_event; | ||
42 | 45 | ||
43 | struct vstor_packet vstor_packet; | 46 | struct vstor_packet vstor_packet; |
44 | }; | 47 | }; |
@@ -200,21 +203,13 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
200 | * channel | 203 | * channel |
201 | */ | 204 | */ |
202 | memset(request, 0, sizeof(struct storvsc_request_extension)); | 205 | memset(request, 0, sizeof(struct storvsc_request_extension)); |
203 | request->wait_event = osd_waitevent_create(); | 206 | init_waitqueue_head(&request->wait_event); |
204 | if (!request->wait_event) { | ||
205 | ret = -ENOMEM; | ||
206 | goto nomem; | ||
207 | } | ||
208 | |||
209 | vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; | 207 | vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; |
210 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; | 208 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
211 | 209 | ||
212 | /*SpinlockAcquire(gDriverExt.packetListLock); | ||
213 | INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); | ||
214 | SpinlockRelease(gDriverExt.packetListLock);*/ | ||
215 | |||
216 | DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); | 210 | DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); |
217 | 211 | ||
212 | request->wait_condition = 0; | ||
218 | ret = vmbus_sendpacket(device->channel, vstor_packet, | 213 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
219 | sizeof(struct vstor_packet), | 214 | sizeof(struct vstor_packet), |
220 | (unsigned long)request, | 215 | (unsigned long)request, |
@@ -223,17 +218,23 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
223 | if (ret != 0) { | 218 | if (ret != 0) { |
224 | DPRINT_ERR(STORVSC, | 219 | DPRINT_ERR(STORVSC, |
225 | "unable to send BEGIN_INITIALIZATION_OPERATION"); | 220 | "unable to send BEGIN_INITIALIZATION_OPERATION"); |
226 | goto Cleanup; | 221 | goto cleanup; |
222 | } | ||
223 | |||
224 | wait_event_timeout(request->wait_event, request->wait_condition, | ||
225 | msecs_to_jiffies(1000)); | ||
226 | if (request->wait_condition == 0) { | ||
227 | ret = -ETIMEDOUT; | ||
228 | goto cleanup; | ||
227 | } | 229 | } |
228 | 230 | ||
229 | osd_waitevent_wait(request->wait_event); | ||
230 | 231 | ||
231 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || | 232 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
232 | vstor_packet->status != 0) { | 233 | vstor_packet->status != 0) { |
233 | DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " | 234 | DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " |
234 | "(op %d status 0x%x)", | 235 | "(op %d status 0x%x)", |
235 | vstor_packet->operation, vstor_packet->status); | 236 | vstor_packet->operation, vstor_packet->status); |
236 | goto Cleanup; | 237 | goto cleanup; |
237 | } | 238 | } |
238 | 239 | ||
239 | DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); | 240 | DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); |
@@ -246,6 +247,7 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
246 | vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; | 247 | vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; |
247 | FILL_VMSTOR_REVISION(vstor_packet->version.revision); | 248 | FILL_VMSTOR_REVISION(vstor_packet->version.revision); |
248 | 249 | ||
250 | request->wait_condition = 0; | ||
249 | ret = vmbus_sendpacket(device->channel, vstor_packet, | 251 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
250 | sizeof(struct vstor_packet), | 252 | sizeof(struct vstor_packet), |
251 | (unsigned long)request, | 253 | (unsigned long)request, |
@@ -254,10 +256,15 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
254 | if (ret != 0) { | 256 | if (ret != 0) { |
255 | DPRINT_ERR(STORVSC, | 257 | DPRINT_ERR(STORVSC, |
256 | "unable to send BEGIN_INITIALIZATION_OPERATION"); | 258 | "unable to send BEGIN_INITIALIZATION_OPERATION"); |
257 | goto Cleanup; | 259 | goto cleanup; |
258 | } | 260 | } |
259 | 261 | ||
260 | osd_waitevent_wait(request->wait_event); | 262 | wait_event_timeout(request->wait_event, request->wait_condition, |
263 | msecs_to_jiffies(1000)); | ||
264 | if (request->wait_condition == 0) { | ||
265 | ret = -ETIMEDOUT; | ||
266 | goto cleanup; | ||
267 | } | ||
261 | 268 | ||
262 | /* TODO: Check returned version */ | 269 | /* TODO: Check returned version */ |
263 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || | 270 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
@@ -265,7 +272,7 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
265 | DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " | 272 | DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " |
266 | "(op %d status 0x%x)", | 273 | "(op %d status 0x%x)", |
267 | vstor_packet->operation, vstor_packet->status); | 274 | vstor_packet->operation, vstor_packet->status); |
268 | goto Cleanup; | 275 | goto cleanup; |
269 | } | 276 | } |
270 | 277 | ||
271 | /* Query channel properties */ | 278 | /* Query channel properties */ |
@@ -277,6 +284,7 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
277 | vstor_packet->storage_channel_properties.port_number = | 284 | vstor_packet->storage_channel_properties.port_number = |
278 | stor_device->port_number; | 285 | stor_device->port_number; |
279 | 286 | ||
287 | request->wait_condition = 0; | ||
280 | ret = vmbus_sendpacket(device->channel, vstor_packet, | 288 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
281 | sizeof(struct vstor_packet), | 289 | sizeof(struct vstor_packet), |
282 | (unsigned long)request, | 290 | (unsigned long)request, |
@@ -286,10 +294,15 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
286 | if (ret != 0) { | 294 | if (ret != 0) { |
287 | DPRINT_ERR(STORVSC, | 295 | DPRINT_ERR(STORVSC, |
288 | "unable to send QUERY_PROPERTIES_OPERATION"); | 296 | "unable to send QUERY_PROPERTIES_OPERATION"); |
289 | goto Cleanup; | 297 | goto cleanup; |
290 | } | 298 | } |
291 | 299 | ||
292 | osd_waitevent_wait(request->wait_event); | 300 | wait_event_timeout(request->wait_event, request->wait_condition, |
301 | msecs_to_jiffies(1000)); | ||
302 | if (request->wait_condition == 0) { | ||
303 | ret = -ETIMEDOUT; | ||
304 | goto cleanup; | ||
305 | } | ||
293 | 306 | ||
294 | /* TODO: Check returned version */ | 307 | /* TODO: Check returned version */ |
295 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || | 308 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
@@ -297,7 +310,7 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
297 | DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " | 310 | DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " |
298 | "(op %d status 0x%x)", | 311 | "(op %d status 0x%x)", |
299 | vstor_packet->operation, vstor_packet->status); | 312 | vstor_packet->operation, vstor_packet->status); |
300 | goto Cleanup; | 313 | goto cleanup; |
301 | } | 314 | } |
302 | 315 | ||
303 | stor_device->path_id = vstor_packet->storage_channel_properties.path_id; | 316 | stor_device->path_id = vstor_packet->storage_channel_properties.path_id; |
@@ -314,6 +327,7 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
314 | vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; | 327 | vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; |
315 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; | 328 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
316 | 329 | ||
330 | request->wait_condition = 0; | ||
317 | ret = vmbus_sendpacket(device->channel, vstor_packet, | 331 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
318 | sizeof(struct vstor_packet), | 332 | sizeof(struct vstor_packet), |
319 | (unsigned long)request, | 333 | (unsigned long)request, |
@@ -323,25 +337,27 @@ static int stor_vsc_channel_init(struct hv_device *device) | |||
323 | if (ret != 0) { | 337 | if (ret != 0) { |
324 | DPRINT_ERR(STORVSC, | 338 | DPRINT_ERR(STORVSC, |
325 | "unable to send END_INITIALIZATION_OPERATION"); | 339 | "unable to send END_INITIALIZATION_OPERATION"); |
326 | goto Cleanup; | 340 | goto cleanup; |
327 | } | 341 | } |
328 | 342 | ||
329 | osd_waitevent_wait(request->wait_event); | 343 | wait_event_timeout(request->wait_event, request->wait_condition, |
344 | msecs_to_jiffies(1000)); | ||
345 | if (request->wait_condition == 0) { | ||
346 | ret = -ETIMEDOUT; | ||
347 | goto cleanup; | ||
348 | } | ||
330 | 349 | ||
331 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || | 350 | if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || |
332 | vstor_packet->status != 0) { | 351 | vstor_packet->status != 0) { |
333 | DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " | 352 | DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " |
334 | "(op %d status 0x%x)", | 353 | "(op %d status 0x%x)", |
335 | vstor_packet->operation, vstor_packet->status); | 354 | vstor_packet->operation, vstor_packet->status); |
336 | goto Cleanup; | 355 | goto cleanup; |
337 | } | 356 | } |
338 | 357 | ||
339 | DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); | 358 | DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); |
340 | 359 | ||
341 | Cleanup: | 360 | cleanup: |
342 | kfree(request->wait_event); | ||
343 | request->wait_event = NULL; | ||
344 | nomem: | ||
345 | put_stor_device(device); | 361 | put_stor_device(device); |
346 | return ret; | 362 | return ret; |
347 | } | 363 | } |
@@ -476,8 +492,8 @@ static void stor_vsc_on_channel_callback(void *context) | |||
476 | 492 | ||
477 | memcpy(&request->vstor_packet, packet, | 493 | memcpy(&request->vstor_packet, packet, |
478 | sizeof(struct vstor_packet)); | 494 | sizeof(struct vstor_packet)); |
479 | 495 | request->wait_condition = 1; | |
480 | osd_waitevent_set(request->wait_event); | 496 | wake_up(&request->wait_event); |
481 | } else { | 497 | } else { |
482 | stor_vsc_on_receive(device, | 498 | stor_vsc_on_receive(device, |
483 | (struct vstor_packet *)packet, | 499 | (struct vstor_packet *)packet, |
@@ -539,7 +555,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, | |||
539 | stor_device = alloc_stor_device(device); | 555 | stor_device = alloc_stor_device(device); |
540 | if (!stor_device) { | 556 | if (!stor_device) { |
541 | ret = -1; | 557 | ret = -1; |
542 | goto Cleanup; | 558 | goto cleanup; |
543 | } | 559 | } |
544 | 560 | ||
545 | /* Save the channel properties to our storvsc channel */ | 561 | /* Save the channel properties to our storvsc channel */ |
@@ -569,7 +585,7 @@ static int stor_vsc_on_device_add(struct hv_device *device, | |||
569 | stor_device->port_number, stor_device->path_id, | 585 | stor_device->port_number, stor_device->path_id, |
570 | stor_device->target_id); | 586 | stor_device->target_id); |
571 | 587 | ||
572 | Cleanup: | 588 | cleanup: |
573 | return ret; | 589 | return ret; |
574 | } | 590 | } |
575 | 591 | ||
@@ -629,16 +645,13 @@ int stor_vsc_on_host_reset(struct hv_device *device) | |||
629 | request = &stor_device->reset_request; | 645 | request = &stor_device->reset_request; |
630 | vstor_packet = &request->vstor_packet; | 646 | vstor_packet = &request->vstor_packet; |
631 | 647 | ||
632 | request->wait_event = osd_waitevent_create(); | 648 | init_waitqueue_head(&request->wait_event); |
633 | if (!request->wait_event) { | ||
634 | ret = -ENOMEM; | ||
635 | goto Cleanup; | ||
636 | } | ||
637 | 649 | ||
638 | vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; | 650 | vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; |
639 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; | 651 | vstor_packet->flags = REQUEST_COMPLETION_FLAG; |
640 | vstor_packet->vm_srb.path_id = stor_device->path_id; | 652 | vstor_packet->vm_srb.path_id = stor_device->path_id; |
641 | 653 | ||
654 | request->wait_condition = 0; | ||
642 | ret = vmbus_sendpacket(device->channel, vstor_packet, | 655 | ret = vmbus_sendpacket(device->channel, vstor_packet, |
643 | sizeof(struct vstor_packet), | 656 | sizeof(struct vstor_packet), |
644 | (unsigned long)&stor_device->reset_request, | 657 | (unsigned long)&stor_device->reset_request, |
@@ -647,13 +660,16 @@ int stor_vsc_on_host_reset(struct hv_device *device) | |||
647 | if (ret != 0) { | 660 | if (ret != 0) { |
648 | DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", | 661 | DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", |
649 | vstor_packet, ret); | 662 | vstor_packet, ret); |
650 | goto Cleanup; | 663 | goto cleanup; |
651 | } | 664 | } |
652 | 665 | ||
653 | /* FIXME: Add a timeout */ | 666 | wait_event_timeout(request->wait_event, request->wait_condition, |
654 | osd_waitevent_wait(request->wait_event); | 667 | msecs_to_jiffies(1000)); |
668 | if (request->wait_condition == 0) { | ||
669 | ret = -ETIMEDOUT; | ||
670 | goto cleanup; | ||
671 | } | ||
655 | 672 | ||
656 | kfree(request->wait_event); | ||
657 | DPRINT_INFO(STORVSC, "host adapter reset completed"); | 673 | DPRINT_INFO(STORVSC, "host adapter reset completed"); |
658 | 674 | ||
659 | /* | 675 | /* |
@@ -661,7 +677,7 @@ int stor_vsc_on_host_reset(struct hv_device *device) | |||
661 | * should have been flushed out and return to us | 677 | * should have been flushed out and return to us |
662 | */ | 678 | */ |
663 | 679 | ||
664 | Cleanup: | 680 | cleanup: |
665 | put_stor_device(device); | 681 | put_stor_device(device); |
666 | return ret; | 682 | return ret; |
667 | } | 683 | } |
diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 004d8de1c7d..9f505c44c60 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h | |||
@@ -91,7 +91,8 @@ struct vmbus_msginfo { | |||
91 | struct list_head msglist_entry; | 91 | struct list_head msglist_entry; |
92 | 92 | ||
93 | /* Synchronize the request/response if needed */ | 93 | /* Synchronize the request/response if needed */ |
94 | struct osd_waitevent *wait_event; | 94 | int wait_condition; |
95 | wait_queue_head_t wait_event; | ||
95 | 96 | ||
96 | /* The message itself */ | 97 | /* The message itself */ |
97 | unsigned char msg[0]; | 98 | unsigned char msg[0]; |