diff options
Diffstat (limited to 'sound/usb/endpoint.c')
-rw-r--r-- | sound/usb/endpoint.c | 53 |
1 files changed, 20 insertions, 33 deletions
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 34de6f2faf61..21049b882ee6 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -485,15 +485,10 @@ __exit_unlock: | |||
485 | static int wait_clear_urbs(struct snd_usb_endpoint *ep) | 485 | static int wait_clear_urbs(struct snd_usb_endpoint *ep) |
486 | { | 486 | { |
487 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); | 487 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); |
488 | unsigned int i; | ||
489 | int alive; | 488 | int alive; |
490 | 489 | ||
491 | do { | 490 | do { |
492 | alive = 0; | 491 | alive = bitmap_weight(&ep->active_mask, ep->nurbs); |
493 | for (i = 0; i < ep->nurbs; i++) | ||
494 | if (test_bit(i, &ep->active_mask)) | ||
495 | alive++; | ||
496 | |||
497 | if (!alive) | 492 | if (!alive) |
498 | break; | 493 | break; |
499 | 494 | ||
@@ -520,33 +515,24 @@ void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) | |||
520 | /* | 515 | /* |
521 | * unlink active urbs. | 516 | * unlink active urbs. |
522 | */ | 517 | */ |
523 | static int deactivate_urbs(struct snd_usb_endpoint *ep, int force, int can_sleep) | 518 | static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force) |
524 | { | 519 | { |
525 | unsigned int i; | 520 | unsigned int i; |
526 | int async; | ||
527 | 521 | ||
528 | if (!force && ep->chip->shutdown) /* to be sure... */ | 522 | if (!force && ep->chip->shutdown) /* to be sure... */ |
529 | return -EBADFD; | 523 | return -EBADFD; |
530 | 524 | ||
531 | async = !can_sleep && ep->chip->async_unlink; | ||
532 | |||
533 | clear_bit(EP_FLAG_RUNNING, &ep->flags); | 525 | clear_bit(EP_FLAG_RUNNING, &ep->flags); |
534 | 526 | ||
535 | INIT_LIST_HEAD(&ep->ready_playback_urbs); | 527 | INIT_LIST_HEAD(&ep->ready_playback_urbs); |
536 | ep->next_packet_read_pos = 0; | 528 | ep->next_packet_read_pos = 0; |
537 | ep->next_packet_write_pos = 0; | 529 | ep->next_packet_write_pos = 0; |
538 | 530 | ||
539 | if (!async && in_interrupt()) | ||
540 | return 0; | ||
541 | |||
542 | for (i = 0; i < ep->nurbs; i++) { | 531 | for (i = 0; i < ep->nurbs; i++) { |
543 | if (test_bit(i, &ep->active_mask)) { | 532 | if (test_bit(i, &ep->active_mask)) { |
544 | if (!test_and_set_bit(i, &ep->unlink_mask)) { | 533 | if (!test_and_set_bit(i, &ep->unlink_mask)) { |
545 | struct urb *u = ep->urb[i].urb; | 534 | struct urb *u = ep->urb[i].urb; |
546 | if (async) | 535 | usb_unlink_urb(u); |
547 | usb_unlink_urb(u); | ||
548 | else | ||
549 | usb_kill_urb(u); | ||
550 | } | 536 | } |
551 | } | 537 | } |
552 | } | 538 | } |
@@ -566,7 +552,7 @@ static void release_urbs(struct snd_usb_endpoint *ep, int force) | |||
566 | ep->prepare_data_urb = NULL; | 552 | ep->prepare_data_urb = NULL; |
567 | 553 | ||
568 | /* stop urbs */ | 554 | /* stop urbs */ |
569 | deactivate_urbs(ep, force, 1); | 555 | deactivate_urbs(ep, force); |
570 | wait_clear_urbs(ep); | 556 | wait_clear_urbs(ep); |
571 | 557 | ||
572 | for (i = 0; i < ep->nurbs; i++) | 558 | for (i = 0; i < ep->nurbs; i++) |
@@ -829,7 +815,7 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | |||
829 | * | 815 | * |
830 | * Returns an error if the URB submission failed, 0 in all other cases. | 816 | * Returns an error if the URB submission failed, 0 in all other cases. |
831 | */ | 817 | */ |
832 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep) | 818 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) |
833 | { | 819 | { |
834 | int err; | 820 | int err; |
835 | unsigned int i; | 821 | unsigned int i; |
@@ -842,7 +828,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep) | |||
842 | return 0; | 828 | return 0; |
843 | 829 | ||
844 | /* just to be sure */ | 830 | /* just to be sure */ |
845 | deactivate_urbs(ep, 0, can_sleep); | 831 | deactivate_urbs(ep, false); |
846 | if (can_sleep) | 832 | if (can_sleep) |
847 | wait_clear_urbs(ep); | 833 | wait_clear_urbs(ep); |
848 | 834 | ||
@@ -896,7 +882,7 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, int can_sleep) | |||
896 | __error: | 882 | __error: |
897 | clear_bit(EP_FLAG_RUNNING, &ep->flags); | 883 | clear_bit(EP_FLAG_RUNNING, &ep->flags); |
898 | ep->use_count--; | 884 | ep->use_count--; |
899 | deactivate_urbs(ep, 0, 0); | 885 | deactivate_urbs(ep, false); |
900 | return -EPIPE; | 886 | return -EPIPE; |
901 | } | 887 | } |
902 | 888 | ||
@@ -910,9 +896,11 @@ __error: | |||
910 | * actually be deactivated. | 896 | * actually be deactivated. |
911 | * | 897 | * |
912 | * Must be balanced to calls of snd_usb_endpoint_start(). | 898 | * Must be balanced to calls of snd_usb_endpoint_start(). |
899 | * | ||
900 | * The caller needs to synchronize the pending stop operation via | ||
901 | * snd_usb_endpoint_sync_pending_stop(). | ||
913 | */ | 902 | */ |
914 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | 903 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep) |
915 | int force, int can_sleep, int wait) | ||
916 | { | 904 | { |
917 | if (!ep) | 905 | if (!ep) |
918 | return; | 906 | return; |
@@ -921,16 +909,12 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | |||
921 | return; | 909 | return; |
922 | 910 | ||
923 | if (--ep->use_count == 0) { | 911 | if (--ep->use_count == 0) { |
924 | deactivate_urbs(ep, force, can_sleep); | 912 | deactivate_urbs(ep, false); |
925 | ep->data_subs = NULL; | 913 | ep->data_subs = NULL; |
926 | ep->sync_slave = NULL; | 914 | ep->sync_slave = NULL; |
927 | ep->retire_data_urb = NULL; | 915 | ep->retire_data_urb = NULL; |
928 | ep->prepare_data_urb = NULL; | 916 | ep->prepare_data_urb = NULL; |
929 | 917 | set_bit(EP_FLAG_STOPPING, &ep->flags); | |
930 | if (wait) | ||
931 | wait_clear_urbs(ep); | ||
932 | else | ||
933 | set_bit(EP_FLAG_STOPPING, &ep->flags); | ||
934 | } | 918 | } |
935 | } | 919 | } |
936 | 920 | ||
@@ -952,7 +936,7 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | |||
952 | if (!ep) | 936 | if (!ep) |
953 | return -EINVAL; | 937 | return -EINVAL; |
954 | 938 | ||
955 | deactivate_urbs(ep, 1, 1); | 939 | deactivate_urbs(ep, true); |
956 | wait_clear_urbs(ep); | 940 | wait_clear_urbs(ep); |
957 | 941 | ||
958 | if (ep->use_count != 0) | 942 | if (ep->use_count != 0) |
@@ -1034,15 +1018,18 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
1034 | /* | 1018 | /* |
1035 | * Iterate through the inbound packet and prepare the lengths | 1019 | * Iterate through the inbound packet and prepare the lengths |
1036 | * for the output packet. The OUT packet we are about to send | 1020 | * for the output packet. The OUT packet we are about to send |
1037 | * will have the same amount of payload bytes than the IN | 1021 | * will have the same amount of payload bytes per stride as the |
1038 | * packet we just received. | 1022 | * IN packet we just received. Since the actual size is scaled |
1023 | * by the stride, use the sender stride to calculate the length | ||
1024 | * in case the number of channels differ between the implicitly | ||
1025 | * fed-back endpoint and the synchronizing endpoint. | ||
1039 | */ | 1026 | */ |
1040 | 1027 | ||
1041 | out_packet->packets = in_ctx->packets; | 1028 | out_packet->packets = in_ctx->packets; |
1042 | for (i = 0; i < in_ctx->packets; i++) { | 1029 | for (i = 0; i < in_ctx->packets; i++) { |
1043 | if (urb->iso_frame_desc[i].status == 0) | 1030 | if (urb->iso_frame_desc[i].status == 0) |
1044 | out_packet->packet_size[i] = | 1031 | out_packet->packet_size[i] = |
1045 | urb->iso_frame_desc[i].actual_length / ep->stride; | 1032 | urb->iso_frame_desc[i].actual_length / sender->stride; |
1046 | else | 1033 | else |
1047 | out_packet->packet_size[i] = 0; | 1034 | out_packet->packet_size[i] = 0; |
1048 | } | 1035 | } |