diff options
| -rw-r--r-- | sound/usb/card.c | 13 | ||||
| -rw-r--r-- | sound/usb/endpoint.c | 17 | ||||
| -rw-r--r-- | sound/usb/endpoint.h | 1 |
3 files changed, 25 insertions, 6 deletions
diff --git a/sound/usb/card.c b/sound/usb/card.c index c3b5b7dca1c3..a09e5f3519e3 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -307,6 +307,11 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
| 307 | 307 | ||
| 308 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 308 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
| 309 | { | 309 | { |
| 310 | struct list_head *p, *n; | ||
| 311 | |||
| 312 | list_for_each_safe(p, n, &chip->ep_list) | ||
| 313 | snd_usb_endpoint_free(p); | ||
| 314 | |||
| 310 | mutex_destroy(&chip->mutex); | 315 | mutex_destroy(&chip->mutex); |
| 311 | kfree(chip); | 316 | kfree(chip); |
| 312 | return 0; | 317 | return 0; |
| @@ -585,7 +590,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
| 585 | struct snd_usb_audio *chip) | 590 | struct snd_usb_audio *chip) |
| 586 | { | 591 | { |
| 587 | struct snd_card *card; | 592 | struct snd_card *card; |
| 588 | struct list_head *p, *n; | 593 | struct list_head *p; |
| 589 | 594 | ||
| 590 | if (chip == (void *)-1L) | 595 | if (chip == (void *)-1L) |
| 591 | return; | 596 | return; |
| @@ -598,14 +603,16 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
| 598 | mutex_lock(®ister_mutex); | 603 | mutex_lock(®ister_mutex); |
| 599 | chip->num_interfaces--; | 604 | chip->num_interfaces--; |
| 600 | if (chip->num_interfaces <= 0) { | 605 | if (chip->num_interfaces <= 0) { |
| 606 | struct snd_usb_endpoint *ep; | ||
| 607 | |||
| 601 | snd_card_disconnect(card); | 608 | snd_card_disconnect(card); |
| 602 | /* release the pcm resources */ | 609 | /* release the pcm resources */ |
| 603 | list_for_each(p, &chip->pcm_list) { | 610 | list_for_each(p, &chip->pcm_list) { |
| 604 | snd_usb_stream_disconnect(p); | 611 | snd_usb_stream_disconnect(p); |
| 605 | } | 612 | } |
| 606 | /* release the endpoint resources */ | 613 | /* release the endpoint resources */ |
| 607 | list_for_each_safe(p, n, &chip->ep_list) { | 614 | list_for_each_entry(ep, &chip->ep_list, list) { |
| 608 | snd_usb_endpoint_free(p); | 615 | snd_usb_endpoint_release(ep); |
| 609 | } | 616 | } |
| 610 | /* release the midi resources */ | 617 | /* release the midi resources */ |
| 611 | list_for_each(p, &chip->midi_list) { | 618 | list_for_each(p, &chip->midi_list) { |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 289f582c9130..114e3e7ff511 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
| @@ -987,19 +987,30 @@ void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | |||
| 987 | } | 987 | } |
| 988 | 988 | ||
| 989 | /** | 989 | /** |
| 990 | * snd_usb_endpoint_release: Tear down an snd_usb_endpoint | ||
| 991 | * | ||
| 992 | * @ep: the endpoint to release | ||
| 993 | * | ||
| 994 | * This function does not care for the endpoint's use count but will tear | ||
| 995 | * down all the streaming URBs immediately. | ||
| 996 | */ | ||
| 997 | void snd_usb_endpoint_release(struct snd_usb_endpoint *ep) | ||
| 998 | { | ||
| 999 | release_urbs(ep, 1); | ||
| 1000 | } | ||
| 1001 | |||
| 1002 | /** | ||
| 990 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint | 1003 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint |
| 991 | * | 1004 | * |
| 992 | * @ep: the list header of the endpoint to free | 1005 | * @ep: the list header of the endpoint to free |
| 993 | * | 1006 | * |
| 994 | * This function does not care for the endpoint's use count but will tear | 1007 | * This free all resources of the given ep. |
| 995 | * down all the streaming URBs immediately and free all resources. | ||
| 996 | */ | 1008 | */ |
| 997 | void snd_usb_endpoint_free(struct list_head *head) | 1009 | void snd_usb_endpoint_free(struct list_head *head) |
| 998 | { | 1010 | { |
| 999 | struct snd_usb_endpoint *ep; | 1011 | struct snd_usb_endpoint *ep; |
| 1000 | 1012 | ||
| 1001 | ep = list_entry(head, struct snd_usb_endpoint, list); | 1013 | ep = list_entry(head, struct snd_usb_endpoint, list); |
| 1002 | release_urbs(ep, 1); | ||
| 1003 | kfree(ep); | 1014 | kfree(ep); |
| 1004 | } | 1015 | } |
| 1005 | 1016 | ||
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 1c7e8ee48abc..e61ee5c356a3 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
| @@ -23,6 +23,7 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep); | |||
| 23 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); | 23 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); |
| 24 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); | 24 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); |
| 25 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); | 25 | void snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); |
| 26 | void snd_usb_endpoint_release(struct snd_usb_endpoint *ep); | ||
| 26 | void snd_usb_endpoint_free(struct list_head *head); | 27 | void snd_usb_endpoint_free(struct list_head *head); |
| 27 | 28 | ||
| 28 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); | 29 | int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep); |
