浏览代码

ALSA: line6: Consolidate URB unlink and sync helpers

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>
Takashi Iwai 10 年之前
父节点
当前提交
d8131e67f0
共有 5 个文件被更改,包括 69 次插入133 次删除
  1. 0 52
      sound/usb/line6/capture.c
  2. 0 4
      sound/usb/line6/capture.h
  3. 69 21
      sound/usb/line6/pcm.c
  4. 0 52
      sound/usb/line6/playback.c
  5. 0 4
      sound/usb/line6/playback.h

+ 0 - 52
sound/usb/line6/capture.c

@@ -84,58 +84,6 @@ int line6_submit_audio_in_all_urbs(struct snd_line6_pcm *line6pcm)
 	return 0;
 	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.
 	Copy data into ALSA capture buffer.
 */
 */

+ 0 - 4
sound/usb/line6/capture.h

@@ -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 int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_free_capture_buffer(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 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);
 extern int snd_line6_capture_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 
 #endif
 #endif

+ 69 - 21
sound/usb/line6/pcm.c

@@ -90,6 +90,47 @@ static int snd_line6_impulse_period_put(struct snd_kcontrol *kcontrol,
 	return 1;
 	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,
 static bool test_flags(unsigned long flags0, unsigned long flags1,
 		       unsigned long mask)
 		       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);
 	} while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old);
 
 
 	if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM))
 	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)) {
 	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);
 		line6_free_capture_buffer(line6pcm);
 	}
 	}
 
 
 	if (test_flags(flags_new, flags_old, LINE6_BITS_PLAYBACK_STREAM))
 	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)) {
 	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);
 		line6_free_playback_buffer(line6pcm);
 	}
 	}
 
 
@@ -325,21 +366,24 @@ static struct snd_kcontrol_new line6_controls[] = {
 /*
 /*
 	Cleanup the PCM device.
 	Cleanup the PCM device.
 */
 */
-static void line6_cleanup_pcm(struct snd_pcm *pcm)
+static void cleanup_urbs(struct line6_pcm_stream *pcms)
 {
 {
 	int i;
 	int i;
-	struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
 
 
 	for (i = 0; i < LINE6_ISO_BUFFERS; i++) {
 	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);
 	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)
 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) {
 	switch (substream->stream) {
 	case SNDRV_PCM_STREAM_PLAYBACK:
 	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;
 		break;
 
 
 	case SNDRV_PCM_STREAM_CAPTURE:
 	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;
 		break;
 	}
 	}
 
 

+ 0 - 52
sound/usb/line6/playback.c

@@ -290,58 +290,6 @@ int line6_submit_audio_out_all_urbs(struct snd_line6_pcm *line6pcm)
 	return 0;
 	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)
 void line6_free_playback_buffer(struct snd_line6_pcm *line6pcm)
 {
 {
 	kfree(line6pcm->out.buffer);
 	kfree(line6pcm->out.buffer);

+ 0 - 4
sound/usb/line6/playback.h

@@ -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 int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
 extern void line6_free_playback_buffer(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 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);
 extern int snd_line6_playback_trigger(struct snd_line6_pcm *line6pcm, int cmd);
 
 
 #endif
 #endif