ALSA: line6: Consolidate URB unlink and sync helpers
authorTakashi Iwai <tiwai@suse.de>
Fri, 23 Jan 2015 15:18:42 +0000 (16:18 +0100)
committerTakashi Iwai <tiwai@suse.de>
Wed, 28 Jan 2015 06:21:27 +0000 (07:21 +0100)
The codes to unlink and sync URBs are identical for both playback and
capture streams.  Consolidate to single helper functions.

Tested-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/line6/capture.c
sound/usb/line6/capture.h
sound/usb/line6/pcm.c
sound/usb/line6/playback.c
sound/usb/line6/playback.h

index 439f1941eb56d98783205ef3a309eec9b335d06f..1d477d7a42fbfd74f36cc807b59937c18b8f9dc9 100644 (file)
@@ -84,58 +84,6 @@ int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
        return 0;
 }
 
-/*
-       Unlink all currently active capture URBs.
-*/
-void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       unsigned int i;
-
-       for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (test_bit(i, &line6pcm->in.active_urbs)) {
-                       if (!test_and_set_bit(i, &line6pcm->in.unlink_urbs)) {
-                               struct urb *u = line6pcm->in.urbs[i];
-
-                               usb_unlink_urb(u);
-                       }
-               }
-       }
-}
-
-/*
-       Wait until unlinking of all currently active capture URBs has been
-       finished.
-*/
-void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int timeout = HZ;
-       unsigned int i;
-       int alive;
-
-       do {
-               alive = 0;
-               for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-                       if (test_bit(i, &line6pcm->in.active_urbs))
-                               alive++;
-               }
-               if (!alive)
-                       break;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-       } while (--timeout > 0);
-       if (alive)
-               snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-}
-
-/*
-       Unlink all currently active capture URBs, and wait for finishing.
-*/
-void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
-{
-       line6_unlink_audio_in_urbs(line6pcm);
-       line6_wait_clear_audio_in_urbs(line6pcm);
-}
-
 /*
        Copy data into ALSA capture buffer.
 */
index 0939f400a40561423a04c25f7a7c3a4b4c6c643e..3cc71bc70b21cced03d3e79bd7dab40d1beb73c0 100644 (file)
@@ -26,10 +26,6 @@ extern void line6_capture_check_period(struct snd_line6_pcm *line6pcm,
 extern int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_free_capture_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm
-                                                 *line6pcm);
-extern void line6_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 #endif
index 738bfd82cecd48d14db7060f166479ae87b7d35a..677419dcacf9599a15511e10e64c5e07e241661f 100644 (file)
@@ -90,6 +90,47 @@ static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
        return 1;
 }
 
+/*
+       Unlink all currently active URBs.
+*/
+static void line6_unlink_audio_urbs(struct snd_line6_pcm *line6pcm,
+                                   struct line6_pcm_stream *pcms)
+{
+       int i;
+
+       for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
+               if (test_bit(i, &pcms->active_urbs)) {
+                       if (!test_and_set_bit(i, &pcms->unlink_urbs))
+                               usb_unlink_urb(pcms->urbs[i]);
+               }
+       }
+}
+
+/*
+       Wait until unlinking of all currently active URBs has been finished.
+*/
+static void line6_wait_clear_audio_urbs(struct snd_line6_pcm *line6pcm,
+                                       struct line6_pcm_stream *pcms)
+{
+       int timeout = HZ;
+       int i;
+       int alive;
+
+       do {
+               alive = 0;
+               for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
+                       if (test_bit(i, &pcms->active_urbs))
+                               alive++;
+               }
+               if (!alive)
+                       break;
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(1);
+       } while (--timeout > 0);
+       if (alive)
+               snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+}
+
 static bool test_flags(unsigned long flags0, unsigned long flags1,
                       unsigned long mask)
 {
@@ -202,18 +243,18 @@ int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels)
        } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
 
        if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
-               line6_unlink_audio_in_urbs(line6pcm);
+               line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
 
        if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_BUFFER)) {
-               line6_wait_clear_audio_in_urbs(line6pcm);
+               line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
                line6_free_capture_buffer(line6pcm);
        }
 
        if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
-               line6_unlink_audio_out_urbs(line6pcm);
+               line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
 
        if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_BUFFER)) {
-               line6_wait_clear_audio_out_urbs(line6pcm);
+               line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
                line6_free_playback_buffer(line6pcm);
        }
 
@@ -325,21 +366,24 @@ static struct snd_kcontrol_new line6_controls[] = {
 /*
        Cleanup the PCM device.
 */
-static void line6_cleanup_pcm(struct snd_pcm *pcm)
+static void cleanup_urbs(struct line6_pcm_stream *pcms)
 {
        int i;
-       struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
 
        for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (line6pcm->out.urbs[i]) {
-                       usb_kill_urb(line6pcm->out.urbs[i]);
-                       usb_free_urb(line6pcm->out.urbs[i]);
-               }
-               if (line6pcm->in.urbs[i]) {
-                       usb_kill_urb(line6pcm->in.urbs[i]);
-                       usb_free_urb(line6pcm->in.urbs[i]);
+               if (pcms->urbs[i]) {
+                       usb_kill_urb(pcms->urbs[i]);
+                       usb_free_urb(pcms->urbs[i]);
                }
        }
+}
+
+static void line6_cleanup_pcm(struct snd_pcm *pcm)
+{
+       struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+
+       cleanup_urbs(&line6pcm->out);
+       cleanup_urbs(&line6pcm->in);
        kfree(line6pcm);
 }
 
@@ -374,8 +418,10 @@ static int snd_line6_new_pcm(struct usb_line6 *line6, struct snd_pcm **pcm_ret)
 */
 void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm)
 {
-       line6_unlink_wait_clear_audio_out_urbs(line6pcm);
-       line6_unlink_wait_clear_audio_in_urbs(line6pcm);
+       line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
+       line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
+       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
+       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
 }
 
 /*
@@ -451,15 +497,17 @@ int snd_line6_prepare(struct snd_pcm_substream *substream)
 
        switch (substream->stream) {
        case SNDRV_PCM_STREAM_PLAYBACK:
-               if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0)
-                       line6_unlink_wait_clear_audio_out_urbs(line6pcm);
-
+               if ((line6pcm->flags & LINE6_BITS_PLAYBACK_STREAM) == 0) {
+                       line6_unlink_audio_urbs(line6pcm, &line6pcm->out);
+                       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->out);
+               }
                break;
 
        case SNDRV_PCM_STREAM_CAPTURE:
-               if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0)
-                       line6_unlink_wait_clear_audio_in_urbs(line6pcm);
-
+               if ((line6pcm->flags & LINE6_BITS_CAPTURE_STREAM) == 0) {
+                       line6_unlink_audio_urbs(line6pcm, &line6pcm->in);
+                       line6_wait_clear_audio_urbs(line6pcm, &line6pcm->in);
+               }
                break;
        }
 
index d619c17183065be70c25c7f84ae2d6e5cbfea022..3820ed08b3420a4253fd9e800eee2401bc5836ac 100644 (file)
@@ -290,58 +290,6 @@ int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
        return 0;
 }
 
-/*
-       Unlink all currently active playback URBs.
-*/
-void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       unsigned int i;
-
-       for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-               if (test_bit(i, &line6pcm->out.active_urbs)) {
-                       if (!test_and_set_bit(i, &line6pcm->out.unlink_urbs)) {
-                               struct urb *u = line6pcm->out.urbs[i];
-
-                               usb_unlink_urb(u);
-                       }
-               }
-       }
-}
-
-/*
-       Wait until unlinking of all currently active playback URBs has been
-       finished.
-*/
-void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       int timeout = HZ;
-       unsigned int i;
-       int alive;
-
-       do {
-               alive = 0;
-               for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
-                       if (test_bit(i, &line6pcm->out.active_urbs))
-                               alive++;
-               }
-               if (!alive)
-                       break;
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(1);
-       } while (--timeout > 0);
-       if (alive)
-               snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
-}
-
-/*
-       Unlink all currently active playback URBs, and wait for finishing.
-*/
-void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
-{
-       line6_unlink_audio_out_urbs(line6pcm);
-       line6_wait_clear_audio_out_urbs(line6pcm);
-}
-
 void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
 {
        kfree(line6pcm->out.buffer);
index 78a8851132213d4c820c92928384eb7e658997c5..52a278353d3bc86b2ab3d77fc288664277dffdc1 100644 (file)
@@ -32,10 +32,6 @@ extern struct snd_pcm_ops snd_line6_playback_ops;
 extern int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm);
 extern int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm);
-extern void line6_unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm
-                                                  *line6pcm);
-extern void line6_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 #endif