revert back to stable
This commit is contained in:
parent
89af7a67e3
commit
b013e2e0f8
14
us144mkii.c
14
us144mkii.c
|
|
@ -258,7 +258,16 @@ error:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void tascam_stop_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct tascam_card *tascam =
|
||||
container_of(work, struct tascam_card, stop_work);
|
||||
|
||||
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||
usb_kill_anchored_urbs(&tascam->capture_anchor);
|
||||
atomic_set(&tascam->active_urbs, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* tascam_card_private_free() - Frees private data associated with the sound
|
||||
|
|
@ -302,6 +311,7 @@ static int tascam_suspend(struct usb_interface *intf, pm_message_t message)
|
|||
|
||||
snd_pcm_suspend_all(tascam->pcm);
|
||||
|
||||
cancel_work_sync(&tascam->stop_work);
|
||||
cancel_work_sync(&tascam->capture_work);
|
||||
cancel_work_sync(&tascam->midi_in_work);
|
||||
cancel_work_sync(&tascam->midi_out_work);
|
||||
|
|
@ -483,10 +493,8 @@ static int tascam_probe(struct usb_interface *intf,
|
|||
tascam->capture_34_source = 1;
|
||||
|
||||
spin_lock_init(&tascam->lock);
|
||||
spin_lock_init(&tascam->trigger_lock);
|
||||
spin_lock_init(&tascam->midi_in_lock);
|
||||
spin_lock_init(&tascam->midi_out_lock);
|
||||
atomic_set(&tascam->stream_active, 0);
|
||||
init_usb_anchor(&tascam->playback_anchor);
|
||||
init_usb_anchor(&tascam->capture_anchor);
|
||||
init_usb_anchor(&tascam->feedback_anchor);
|
||||
|
|
@ -495,6 +503,7 @@ static int tascam_probe(struct usb_interface *intf,
|
|||
|
||||
timer_setup(&tascam->error_timer, tascam_error_timer, 0);
|
||||
|
||||
INIT_WORK(&tascam->stop_work, tascam_stop_work_handler);
|
||||
INIT_WORK(&tascam->stop_pcm_work, tascam_stop_pcm_work_handler);
|
||||
INIT_WORK(&tascam->capture_work, tascam_capture_work_handler);
|
||||
init_completion(&tascam->midi_out_drain_completion);
|
||||
|
|
@ -574,6 +583,7 @@ static void tascam_disconnect(struct usb_interface *intf)
|
|||
if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
|
||||
/* Ensure all deferred work is complete before freeing resources */
|
||||
snd_card_disconnect(tascam->card);
|
||||
cancel_work_sync(&tascam->stop_work);
|
||||
cancel_work_sync(&tascam->capture_work);
|
||||
cancel_work_sync(&tascam->midi_in_work);
|
||||
cancel_work_sync(&tascam->midi_out_work);
|
||||
|
|
|
|||
12
us144mkii.h
12
us144mkii.h
|
|
@ -229,10 +229,8 @@ struct tascam_card {
|
|||
|
||||
/* --- Stream State --- */
|
||||
spinlock_t lock;
|
||||
spinlock_t trigger_lock;
|
||||
atomic_t playback_active;
|
||||
atomic_t capture_active;
|
||||
atomic_t stream_active;
|
||||
atomic_t active_urbs;
|
||||
int current_rate;
|
||||
|
||||
|
|
@ -275,6 +273,7 @@ struct tascam_card {
|
|||
struct us144mkii_frame_pattern_observer fpo;
|
||||
|
||||
/* --- Workqueues --- */
|
||||
struct work_struct stop_work;
|
||||
struct work_struct stop_pcm_work;
|
||||
struct work_struct capture_work;
|
||||
struct work_struct midi_in_work;
|
||||
|
|
@ -309,7 +308,14 @@ void tascam_free_urbs(struct tascam_card *tascam);
|
|||
*/
|
||||
int tascam_alloc_urbs(struct tascam_card *tascam);
|
||||
|
||||
|
||||
/**
|
||||
* tascam_stop_work_handler() - Work handler to stop all active streams.
|
||||
* @work: Pointer to the work_struct.
|
||||
*
|
||||
* This function is scheduled to stop all active URBs (playback, feedback,
|
||||
* capture) and reset the active_urbs counter.
|
||||
*/
|
||||
void tascam_stop_work_handler(struct work_struct *work);
|
||||
|
||||
/* us144mkii_pcm.h */
|
||||
#include "us144mkii_pcm.h"
|
||||
|
|
|
|||
170
us144mkii_pcm.c
170
us144mkii_pcm.c
|
|
@ -282,103 +282,97 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
|||
struct tascam_card *tascam = snd_pcm_substream_chip(substream);
|
||||
int err = 0;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
bool do_start = false;
|
||||
bool do_stop = false;
|
||||
|
||||
spin_lock_irqsave(&tascam->trigger_lock, flags);
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (atomic_xchg(&tascam->playback_active, 1) == 0) {
|
||||
if (atomic_fetch_inc(&tascam->stream_active) == 0) {
|
||||
for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
|
||||
usb_get_urb(tascam->feedback_urbs[i]);
|
||||
usb_anchor_urb(tascam->feedback_urbs[i], &tascam->feedback_anchor);
|
||||
err = usb_submit_urb(tascam->feedback_urbs[i], GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->feedback_urbs[i]);
|
||||
usb_put_urb(tascam->feedback_urbs[i]);
|
||||
atomic_dec(&tascam->active_urbs);
|
||||
break;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
|
||||
usb_get_urb(tascam->playback_urbs[i]);
|
||||
usb_anchor_urb(tascam->playback_urbs[i], &tascam->playback_anchor);
|
||||
err = usb_submit_urb(tascam->playback_urbs[i], GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->playback_urbs[i]);
|
||||
usb_put_urb(tascam->playback_urbs[i]);
|
||||
break;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
scoped_guard(spinlock_irqsave, &tascam->lock) {
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (!atomic_read(&tascam->playback_active)) {
|
||||
atomic_set(&tascam->playback_active, 1);
|
||||
atomic_set(&tascam->capture_active, 1);
|
||||
do_start = true;
|
||||
}
|
||||
} else {
|
||||
if (atomic_xchg(&tascam->capture_active, 1) == 0) {
|
||||
if (atomic_fetch_inc(&tascam->stream_active) == 0) {
|
||||
for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
|
||||
usb_get_urb(tascam->feedback_urbs[i]);
|
||||
usb_anchor_urb(tascam->feedback_urbs[i], &tascam->feedback_anchor);
|
||||
err = usb_submit_urb(tascam->feedback_urbs[i], GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->feedback_urbs[i]);
|
||||
usb_put_urb(tascam->feedback_urbs[i]);
|
||||
atomic_dec(&tascam->active_urbs);
|
||||
break;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_CAPTURE_URBS; i++) {
|
||||
usb_get_urb(tascam->capture_urbs[i]);
|
||||
usb_anchor_urb(tascam->capture_urbs[i], &tascam->capture_anchor);
|
||||
err = usb_submit_urb(tascam->capture_urbs[i], GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->capture_urbs[i]);
|
||||
usb_put_urb(tascam->capture_urbs[i]);
|
||||
break;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (atomic_read(&tascam->playback_active)) {
|
||||
atomic_set(&tascam->playback_active, 0);
|
||||
atomic_set(&tascam->capture_active, 0);
|
||||
do_stop = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SNDRV_PCM_TRIGGER_STOP:
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||
if (atomic_xchg(&tascam->playback_active, 0) == 1) {
|
||||
if (atomic_dec_and_test(&tascam->stream_active))
|
||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||
|
||||
usb_kill_anchored_urbs(&tascam->playback_anchor);
|
||||
|
||||
}
|
||||
} else {
|
||||
if (atomic_xchg(&tascam->capture_active, 0) == 1) {
|
||||
if (atomic_dec_and_test(&tascam->stream_active))
|
||||
usb_kill_anchored_urbs(&tascam->feedback_anchor);
|
||||
|
||||
usb_kill_anchored_urbs(&tascam->capture_anchor);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&tascam->trigger_lock, flags);
|
||||
if (do_start) {
|
||||
if (atomic_read(&tascam->active_urbs) > 0) {
|
||||
dev_warn(tascam->card->dev,
|
||||
"Cannot start, URBs still active.\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_FEEDBACK_URBS; i++) {
|
||||
usb_get_urb(tascam->feedback_urbs[i]);
|
||||
usb_anchor_urb(tascam->feedback_urbs[i],
|
||||
&tascam->feedback_anchor);
|
||||
err = usb_submit_urb(tascam->feedback_urbs[i],
|
||||
GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->feedback_urbs[i]);
|
||||
usb_put_urb(tascam->feedback_urbs[i]);
|
||||
atomic_dec(&tascam->active_urbs);
|
||||
goto start_rollback;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
for (i = 0; i < NUM_PLAYBACK_URBS; i++) {
|
||||
usb_get_urb(tascam->playback_urbs[i]);
|
||||
usb_anchor_urb(tascam->playback_urbs[i],
|
||||
&tascam->playback_anchor);
|
||||
err = usb_submit_urb(tascam->playback_urbs[i],
|
||||
GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->playback_urbs[i]);
|
||||
usb_put_urb(tascam->playback_urbs[i]);
|
||||
atomic_dec(&tascam->active_urbs);
|
||||
goto start_rollback;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
for (i = 0; i < NUM_CAPTURE_URBS; i++) {
|
||||
usb_get_urb(tascam->capture_urbs[i]);
|
||||
usb_anchor_urb(tascam->capture_urbs[i],
|
||||
&tascam->capture_anchor);
|
||||
err = usb_submit_urb(tascam->capture_urbs[i],
|
||||
GFP_ATOMIC);
|
||||
if (err < 0) {
|
||||
usb_unanchor_urb(tascam->capture_urbs[i]);
|
||||
usb_put_urb(tascam->capture_urbs[i]);
|
||||
atomic_dec(&tascam->active_urbs);
|
||||
goto start_rollback;
|
||||
}
|
||||
atomic_inc(&tascam->active_urbs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
start_rollback:
|
||||
dev_err(tascam->card->dev,
|
||||
"Failed to submit URBs to start stream: %d\n", err);
|
||||
do_stop = true;
|
||||
}
|
||||
|
||||
if (do_stop)
|
||||
schedule_work(&tascam->stop_work);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int tascam_init_pcm(struct snd_pcm *pcm)
|
||||
{
|
||||
struct tascam_card *tascam = pcm->private_data;
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ void feedback_urb_complete(struct urb *urb)
|
|||
}
|
||||
goto out;
|
||||
}
|
||||
if (!tascam || !atomic_read(&tascam->stream_active))
|
||||
if (!tascam || !atomic_read(&tascam->playback_active))
|
||||
goto out;
|
||||
|
||||
playback_ss = tascam->playback_substream;
|
||||
|
|
|
|||
Loading…
Reference in New Issue