more stability fixes

This commit is contained in:
Šerif Rami 2025-08-08 18:40:02 +02:00
parent 196cd55787
commit 9ccbea0f11
3 changed files with 31 additions and 4 deletions

View File

@ -332,6 +332,7 @@ static int tascam_suspend(struct usb_interface *intf, pm_message_t message) {
cancel_work_sync(&tascam->capture_work);
cancel_work_sync(&tascam->midi_in_work);
cancel_work_sync(&tascam->midi_out_work);
cancel_work_sync(&tascam->stop_pcm_work);
usb_kill_anchored_urbs(&tascam->playback_anchor);
usb_kill_anchored_urbs(&tascam->capture_anchor);
usb_kill_anchored_urbs(&tascam->feedback_anchor);
@ -494,6 +495,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);
if (kfifo_alloc(&tascam->midi_in_fifo, MIDI_IN_FIFO_SIZE, GFP_KERNEL)) {
snd_card_free(card);
@ -576,6 +578,7 @@ static void tascam_disconnect(struct usb_interface *intf) {
cancel_work_sync(&tascam->capture_work);
cancel_work_sync(&tascam->midi_in_work);
cancel_work_sync(&tascam->midi_out_work);
cancel_work_sync(&tascam->stop_pcm_work);
usb_kill_anchored_urbs(&tascam->playback_anchor);
usb_kill_anchored_urbs(&tascam->capture_anchor);

View File

@ -258,6 +258,7 @@ struct tascam_card {
// Work structs
struct work_struct capture_work;
struct work_struct stop_work;
struct work_struct stop_pcm_work;
struct work_struct midi_in_work;
struct work_struct midi_out_work;
@ -310,6 +311,15 @@ int tascam_alloc_urbs(struct tascam_card *tascam);
*/
void tascam_stop_work_handler(struct work_struct *work);
/**
* tascam_stop_pcm_work_handler() - Work handler to stop PCM streams.
* @work: Pointer to the work_struct.
*
* This function is scheduled to stop PCM streams (playback and capture)
* from a workqueue context, avoiding blocking operations in interrupt context.
*/
void tascam_stop_pcm_work_handler(struct work_struct *work);
/* us144mkii_pcm.h */
#include "us144mkii_pcm.h"

View File

@ -343,10 +343,7 @@ void feedback_urb_complete(struct urb *urb) {
FEEDBACK_SYNC_LOSS_THRESHOLD) {
dev_err(tascam->card->dev,
"Fatal: Feedback sync lost. Stopping stream.\n");
if (playback_ss)
snd_pcm_stop(playback_ss, SNDRV_PCM_STATE_XRUN);
if (capture_ss)
snd_pcm_stop(capture_ss, SNDRV_PCM_STATE_XRUN);
schedule_work(&tascam->stop_pcm_work);
tascam->feedback_synced = false;
goto continue_unlock;
}
@ -427,3 +424,20 @@ continue_unlock:
out:
usb_put_urb(urb);
}
/**
* tascam_stop_pcm_work_handler() - Work handler to stop PCM streams.
* @work: Pointer to the work_struct.
*
* This function is scheduled to stop PCM streams (playback and capture)
* from a workqueue context, avoiding blocking operations in interrupt context.
*/
void tascam_stop_pcm_work_handler(struct work_struct *work) {
struct tascam_card *tascam =
container_of(work, struct tascam_card, stop_pcm_work);
if (tascam->playback_substream)
snd_pcm_stop(tascam->playback_substream, SNDRV_PCM_STATE_XRUN);
if (tascam->capture_substream)
snd_pcm_stop(tascam->capture_substream, SNDRV_PCM_STATE_XRUN);
}