Fix significant bugs: probe abort, license mismatch, pause flags, work handler race

- BUG-05: Abort probe with -EIO if device rate initialization fails
  instead of registering a non-functional card.
- BUG-06: Remove SNDRV_PCM_INFO_PAUSE and SNDRV_PCM_INFO_RESUME from
  both capture and playback hw info since true pause is not implemented.
- BUG-07: Change MODULE_LICENSE to 'GPL v2' to match SPDX identifier.
- BUG-08: Hold tascam->lock when reading substream pointers in
  stop_pcm_work_handler to prevent use-after-free on concurrent close.
This commit is contained in:
Marvin 2026-04-22 19:31:11 -03:00
parent 57cbd3d53f
commit f6c59c4f9f
4 changed files with 23 additions and 13 deletions

View File

@ -5,7 +5,7 @@
MODULE_AUTHOR("Šerif Rami <ramiserifpersia@gmail.com>");
MODULE_DESCRIPTION("ALSA Driver for TASCAM US-144MKII");
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL v2");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@ -294,10 +294,12 @@ static int tascam_probe(struct usb_interface *intf, const struct usb_device_id *
u16 stream_mode = (tascam->dev_id == USB_PID_TASCAM_US200) ? MODE_VAL_STREAM_START_US200 : MODE_VAL_STREAM_START;
if (us144mkii_configure_device_for_rate(tascam, 48000, stream_mode) < 0)
dev_warn(&dev->dev, "Failed to initialize device at 48khz\n");
else
tascam->current_rate = 48000;
if (us144mkii_configure_device_for_rate(tascam, 48000, stream_mode) < 0) {
dev_err(&dev->dev, "Failed to initialize device at 48khz\n");
err = -EIO;
goto free_card;
}
tascam->current_rate = 48000;
err = snd_card_register(card);
if (err < 0)

View File

@ -6,8 +6,7 @@
const struct snd_pcm_hardware tascam_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),

View File

@ -154,9 +154,19 @@ int tascam_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_
void tascam_stop_pcm_work_handler(struct work_struct *work)
{
struct tascam_card *tascam = container_of(work, struct tascam_card, stop_pcm_work);
struct snd_pcm_substream *pb, *cap;
unsigned long flags;
if (tascam->dev && tascam->playback_substream)
snd_pcm_stop(tascam->playback_substream, SNDRV_PCM_STATE_XRUN);
if (tascam->dev && tascam->capture_substream)
snd_pcm_stop(tascam->capture_substream, SNDRV_PCM_STATE_XRUN);
if (!tascam || !tascam->dev)
return;
spin_lock_irqsave(&tascam->lock, flags);
pb = tascam->playback_substream;
cap = tascam->capture_substream;
spin_unlock_irqrestore(&tascam->lock, flags);
if (pb)
snd_pcm_stop(pb, SNDRV_PCM_STATE_XRUN);
if (cap)
snd_pcm_stop(cap, SNDRV_PCM_STATE_XRUN);
}

View File

@ -5,8 +5,7 @@
const struct snd_pcm_hardware tascam_playback_hw = {
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_S24_3LE,
.rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000),