summaryrefslogtreecommitdiff
path: root/sound/usb/midi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-10-02 11:37:19 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-10-02 11:37:19 -0700
commit05a54fa773284d1a7923cdfdd8f0c8dabb98bd26 (patch)
tree9697e9a5fae64e7b34009bebd188d9e46e2fddf5 /sound/usb/midi.c
parente1b1d03ceec343362524318c076b110066ffe305 (diff)
parentf65dc3b1ab145c9b8b36301256d703c1dd153f71 (diff)
Merge tag 'sound-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "It's been relatively calm in this cycle from the feature POV, but there were lots of cleanup works in the wide-range of code for converting with the auto-cleanup macros like guard(). The mostly user-visible changes are the support of a couple of new compress-offload API extensions, and the support of new ASoC codec / platform drivers as well as USB-audio quirks. Here we go with some highlights: Core: - Compress-offload API extension for 64bit timestamp support - Compress-offload API extension for OPUS codec support - Workaround for PCM locking issue with PREEMPT_RT and softirq - KCSAN warning fix for ALSA sequencer core ASoC: - Continued cleanup works for ASoC core APIs - Lots of cleanups and conversions of DT bindings - Substantial maintainance work on the Intel AVS drivers - Support for Qualcomm Glymur and PM4125, Realtek RT1321, Shanghai FourSemi FS2104/5S, Texas Instruments PCM1754 and TAS2783A - Remove support for TI WL1273 for old Nokia systems USB-audio: - Support for Tascam US-144mkII, Presonus S1824c support - More flexible quirk option handling - Fix for USB MIDI timer bug triggered by fuzzer Others: - A large series of cleanups with guard() & co macros over (non-ASoC) sound drivers (PCI, ISA, HD-audio, USB-audio, drivers, etc) - TAS5825 HD-audio side-codec support" * tag 'sound-6.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (454 commits) ALSA: usb-audio: don't hardcode gain for output channel of Presonus Studio ALSA: usb-audio: add the initial mix for Presonus Studio 1824c ALSA: doc: improved docs about quirk_flags in snd-usb-audio ALSA: usb-audio: make param quirk_flags change-able in runtime ALSA: usb-audio: improve module param quirk_flags ALSA: usb-audio: add two-way convert between name and bit for QUIRK_FLAG_* ALSA: usb-audio: fix race condition to UAF in snd_usbmidi_free ALSA: usb-audio: add mono main switch to Presonus S1824c ALSA: compress: document 'chan_map' member in snd_dec_opus ASoC: cs35l56: Add support for CS35L56 B2 silicon ASoC: cs35l56: Set fw_regs table after getting REVID ALSA: hda/realtek: Add quirk for HP Spectre 14t-ea100 ASoc: tas2783A: Fix an error code in probe() ASoC: tlv320aic3x: Fix class-D initialization for tlv320aic3007 ASoC: qcom: sc8280xp: use sa8775p/ subdir for QCS9100 / QCS9075 ASoC: stm32: sai: manage context in set_sysclk callback ASoC: renesas: msiof: ignore 1st FSERR ASoC: renesas: msiof: Add note for The possibility of R/L opposite Capture ASoC: renesas: msiof: setup both (Playback/Capture) in the same time ASoC: renesas: msiof: tidyup DMAC stop timing ...
Diffstat (limited to 'sound/usb/midi.c')
-rw-r--r--sound/usb/midi.c77
1 files changed, 30 insertions, 47 deletions
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index acb3bf92857c..dd8249e75970 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -265,16 +265,15 @@ static void snd_usbmidi_out_urb_complete(struct urb *urb)
struct out_urb_context *context = urb->context;
struct snd_usb_midi_out_endpoint *ep = context->ep;
unsigned int urb_index;
- unsigned long flags;
-
- spin_lock_irqsave(&ep->buffer_lock, flags);
- urb_index = context - ep->urbs;
- ep->active_urbs &= ~(1 << urb_index);
- if (unlikely(ep->drain_urbs)) {
- ep->drain_urbs &= ~(1 << urb_index);
- wake_up(&ep->drain_wait);
+
+ scoped_guard(spinlock_irqsave, &ep->buffer_lock) {
+ urb_index = context - ep->urbs;
+ ep->active_urbs &= ~(1 << urb_index);
+ if (unlikely(ep->drain_urbs)) {
+ ep->drain_urbs &= ~(1 << urb_index);
+ wake_up(&ep->drain_wait);
+ }
}
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
if (urb->status < 0) {
int err = snd_usbmidi_urb_error(urb);
if (err < 0) {
@@ -295,13 +294,10 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
{
unsigned int urb_index;
struct urb *urb;
- unsigned long flags;
- spin_lock_irqsave(&ep->buffer_lock, flags);
- if (ep->umidi->disconnected) {
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
+ guard(spinlock_irqsave)(&ep->buffer_lock);
+ if (ep->umidi->disconnected)
return;
- }
urb_index = ep->next_urb;
for (;;) {
@@ -325,7 +321,6 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint *ep)
break;
}
ep->next_urb = urb_index;
- spin_unlock_irqrestore(&ep->buffer_lock, flags);
}
static void snd_usbmidi_out_work(struct work_struct *work)
@@ -342,9 +337,8 @@ static void snd_usbmidi_error_timer(struct timer_list *t)
struct snd_usb_midi *umidi = timer_container_of(umidi, t, error_timer);
unsigned int i, j;
- spin_lock(&umidi->disc_lock);
+ guard(spinlock)(&umidi->disc_lock);
if (umidi->disconnected) {
- spin_unlock(&umidi->disc_lock);
return;
}
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
@@ -361,7 +355,6 @@ static void snd_usbmidi_error_timer(struct timer_list *t)
if (umidi->endpoints[i].out)
snd_usbmidi_do_output(umidi->endpoints[i].out);
}
- spin_unlock(&umidi->disc_lock);
}
/* helper function to send static data that may not DMA-able */
@@ -1148,13 +1141,11 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
struct snd_usb_midi *umidi = substream->rmidi->private_data;
struct snd_kcontrol *ctl;
- down_read(&umidi->disc_rwsem);
- if (umidi->disconnected) {
- up_read(&umidi->disc_rwsem);
+ guard(rwsem_read)(&umidi->disc_rwsem);
+ if (umidi->disconnected)
return open ? -ENODEV : 0;
- }
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
if (open) {
if (!umidi->opened[0] && !umidi->opened[1]) {
if (umidi->roland_load_ctl) {
@@ -1183,8 +1174,6 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
}
}
}
- mutex_unlock(&umidi->mutex);
- up_read(&umidi->disc_rwsem);
return 0;
}
@@ -1522,15 +1511,14 @@ static void snd_usbmidi_free(struct snd_usb_midi *umidi)
{
int i;
+ if (!umidi->disconnected)
+ snd_usbmidi_disconnect(&umidi->list);
+
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
struct snd_usb_midi_endpoint *ep = &umidi->endpoints[i];
- if (ep->out)
- snd_usbmidi_out_endpoint_delete(ep->out);
- if (ep->in)
- snd_usbmidi_in_endpoint_delete(ep->in);
+ kfree(ep->out);
}
mutex_destroy(&umidi->mutex);
- timer_shutdown_sync(&umidi->error_timer);
kfree(umidi);
}
@@ -1548,11 +1536,10 @@ void snd_usbmidi_disconnect(struct list_head *p)
* a timer may submit an URB. To reliably break the cycle
* a flag under lock must be used
*/
- down_write(&umidi->disc_rwsem);
- spin_lock_irq(&umidi->disc_lock);
- umidi->disconnected = 1;
- spin_unlock_irq(&umidi->disc_lock);
- up_write(&umidi->disc_rwsem);
+ scoped_guard(rwsem_write, &umidi->disc_rwsem) {
+ guard(spinlock_irq)(&umidi->disc_lock);
+ umidi->disconnected = 1;
+ }
timer_shutdown_sync(&umidi->error_timer);
@@ -2094,11 +2081,10 @@ static int roland_load_put(struct snd_kcontrol *kcontrol,
if (value->value.enumerated.item[0] > 1)
return -EINVAL;
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
changed = value->value.enumerated.item[0] != kcontrol->private_value;
if (changed)
kcontrol->private_value = value->value.enumerated.item[0];
- mutex_unlock(&umidi->mutex);
return changed;
}
@@ -2448,18 +2434,17 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi *umidi,
struct snd_usb_midi_in_endpoint *ep)
{
unsigned int i;
- unsigned long flags;
if (!ep)
return;
for (i = 0; i < INPUT_URBS; ++i) {
struct urb *urb = ep->urbs[i];
- spin_lock_irqsave(&umidi->disc_lock, flags);
- if (!atomic_read(&urb->use_count)) {
- urb->dev = ep->umidi->dev;
- snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+ scoped_guard(spinlock_irqsave, &umidi->disc_lock) {
+ if (!atomic_read(&urb->use_count)) {
+ urb->dev = ep->umidi->dev;
+ snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
+ }
}
- spin_unlock_irqrestore(&umidi->disc_lock, flags);
}
}
@@ -2488,9 +2473,8 @@ void snd_usbmidi_suspend(struct list_head *p)
struct snd_usb_midi *umidi;
umidi = list_entry(p, struct snd_usb_midi, list);
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
snd_usbmidi_input_stop(p);
- mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_suspend);
@@ -2502,9 +2486,8 @@ void snd_usbmidi_resume(struct list_head *p)
struct snd_usb_midi *umidi;
umidi = list_entry(p, struct snd_usb_midi, list);
- mutex_lock(&umidi->mutex);
+ guard(mutex)(&umidi->mutex);
snd_usbmidi_input_start(p);
- mutex_unlock(&umidi->mutex);
}
EXPORT_SYMBOL(snd_usbmidi_resume);