revert back to stable

This commit is contained in:
Šerif Rami 2025-11-28 11:59:40 +01:00
parent 89af7a67e3
commit b013e2e0f8
6 changed files with 104 additions and 94 deletions

0
build_and_install.sh Normal file → Executable file
View File

0
tascam_controls/build_appimage.sh Normal file → Executable file
View File

View File

@ -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);

View File

@ -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"

View File

@ -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;

View File

@ -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;