diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-09 08:26:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-09 08:26:55 -0700 |
commit | e57ccca1ba33e1d92cc3bbf8b6304a46948844b0 (patch) | |
tree | a988a1f7d1d3250f57761dbea365482300a7b3b2 /sound/core/seq/seq_clientmgr.c | |
parent | a2d635decbfa9c1e4ae15cb05b68b2559f7f827c (diff) | |
parent | ed97c988bdc61ab6fb5d1f5f02a709844557b68f (diff) | |
download | linux-stable-e57ccca1ba33e1d92cc3bbf8b6304a46948844b0.tar.gz linux-stable-e57ccca1ba33e1d92cc3bbf8b6304a46948844b0.tar.bz2 linux-stable-e57ccca1ba33e1d92cc3bbf8b6304a46948844b0.zip |
Merge tag 'sound-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"The most significant changes at this cycle are the Sound Open Firmware
support from Intel for the common DSP framework along with its support
for Intel platforms. It's a door opened to a real "free" firmware (in
the sense of FOSS), and other parties show interests in it.
In addition to SOF, we've got a bunch of updates and fixes as usual.
Some highlights are below.
ALSA core:
- Cleanups and fixes in ALSA timer code to cover some races spotted
by syzkaller
- Cleanups and fixes in ALSA sequencer code to cover some races,
again unsurprisingly, spotted by syzkaller
- Optimize the common page allocation helper with alloc_pages_exact()
ASoC:
- Add SOF core support, as well as Intel SOF platform support
- Generic card driver improvements: support for MCLK/sample rate
ratio and pin switches
- A big set of improvements to TLV320AIC32x4 drivers
- New drivers for Freescale audio mixers, several Intel machines,
several Mediatek machines, Meson G12A, Spreadtrum compressed audio
and DMA devices
HD-audio:
- A few Realtek codec fixes for reducing pop noises
- Quirks for Chromebooks
- Workaround for faulty connection report on AMD/Nvidia HDMI
Others:
- A quirk for Focusrite Scarlett Solo USB-audio
- Add support for MOTU 8pre FireWire
- 24bit sample format support in aloop
- GUS patch format support (finally, over a decade) in native emux
synth code"
* tag 'sound-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (375 commits)
ASoC: SOF: Fix unused variable warnings
ALSA: line6: toneport: Fix broken usage of timer for delayed execution
ALSA: aica: Fix a long-time build breakage
ALSA: hda/realtek - Support low power consumption for ALC256
ASoC: stm32: i2s: update pcm hardware constraints
ASoC: codec: hdac_hdmi: no checking monitor in hw_params
ASoC: mediatek: mt6358: save PGA for mixer control
ASoC: mediatek: mt6358: save output volume for mixer controls
ASoC: mediatek: mt6358: initialize setting when ramping volume
ASoC: SOF: core: fix undefined nocodec reference
ASoC: SOF: xtensa: fix undefined references
ASoC: SOF: Propagate sof_get_ctrl_copy_params() error properly
ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14)
ALSA: hda/intel: add CometLake PCI IDs
ALSA: hda/realtek - Support low power consumption for ALC295
ASoC: rockchip: Fix an uninitialized variable compile warning
ASoC: SOF: Fix a compile warning with CONFIG_PCI=n
ASoC: da7219: Fix a compile warning at CONFIG_COMMON_CLK=n
ASoC: sound/soc/sof/: fix kconfig dependency warning
ASoC: stm32: spdifrx: change trace level on iec control
...
Diffstat (limited to 'sound/core/seq/seq_clientmgr.c')
-rw-r--r-- | sound/core/seq/seq_clientmgr.c | 109 |
1 files changed, 58 insertions, 51 deletions
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c index a11bdc0350fc..b3f593ee752e 100644 --- a/sound/core/seq/seq_clientmgr.c +++ b/sound/core/seq/seq_clientmgr.c @@ -179,6 +179,41 @@ struct snd_seq_client *snd_seq_client_use_ptr(int clientid) return client; } +/* Take refcount and perform ioctl_mutex lock on the given client; + * used only for OSS sequencer + * Unlock via snd_seq_client_ioctl_unlock() below + */ +bool snd_seq_client_ioctl_lock(int clientid) +{ + struct snd_seq_client *client; + + client = snd_seq_client_use_ptr(clientid); + if (!client) + return false; + mutex_lock(&client->ioctl_mutex); + /* The client isn't unrefed here; see snd_seq_client_ioctl_unlock() */ + return true; +} +EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_lock); + +/* Unlock and unref the given client; for OSS sequencer use only */ +void snd_seq_client_ioctl_unlock(int clientid) +{ + struct snd_seq_client *client; + + client = snd_seq_client_use_ptr(clientid); + if (WARN_ON(!client)) + return; + mutex_unlock(&client->ioctl_mutex); + /* The doubly unrefs below are intentional; the first one releases the + * leftover from snd_seq_client_ioctl_lock() above, and the second one + * is for releasing snd_seq_client_use_ptr() in this function + */ + snd_seq_client_unlock(client); + snd_seq_client_unlock(client); +} +EXPORT_SYMBOL_GPL(snd_seq_client_ioctl_unlock); + static void usage_alloc(struct snd_seq_usage *res, int num) { res->cur += num; @@ -203,7 +238,6 @@ int __init client_init_data(void) static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) { - unsigned long flags; int c; struct snd_seq_client *client; @@ -224,7 +258,7 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) mutex_init(&client->ioctl_mutex); /* find free slot in the client table */ - spin_lock_irqsave(&clients_lock, flags); + spin_lock_irq(&clients_lock); if (client_index < 0) { for (c = SNDRV_SEQ_DYNAMIC_CLIENTS_BEGIN; c < SNDRV_SEQ_MAX_CLIENTS; @@ -232,17 +266,17 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) if (clienttab[c] || clienttablock[c]) continue; clienttab[client->number = c] = client; - spin_unlock_irqrestore(&clients_lock, flags); + spin_unlock_irq(&clients_lock); return client; } } else { if (clienttab[client_index] == NULL && !clienttablock[client_index]) { clienttab[client->number = client_index] = client; - spin_unlock_irqrestore(&clients_lock, flags); + spin_unlock_irq(&clients_lock); return client; } } - spin_unlock_irqrestore(&clients_lock, flags); + spin_unlock_irq(&clients_lock); snd_seq_pool_delete(&client->pool); kfree(client); return NULL; /* no free slot found or busy, return failure code */ @@ -251,23 +285,21 @@ static struct snd_seq_client *seq_create_client1(int client_index, int poolsize) static int seq_free_client1(struct snd_seq_client *client) { - unsigned long flags; - if (!client) return 0; - spin_lock_irqsave(&clients_lock, flags); + spin_lock_irq(&clients_lock); clienttablock[client->number] = 1; clienttab[client->number] = NULL; - spin_unlock_irqrestore(&clients_lock, flags); + spin_unlock_irq(&clients_lock); snd_seq_delete_all_ports(client); snd_seq_queue_client_leave(client->number); snd_use_lock_sync(&client->use_lock); snd_seq_queue_client_termination(client->number); if (client->pool) snd_seq_pool_delete(&client->pool); - spin_lock_irqsave(&clients_lock, flags); + spin_lock_irq(&clients_lock); clienttablock[client->number] = 0; - spin_unlock_irqrestore(&clients_lock, flags); + spin_unlock_irq(&clients_lock); return 0; } @@ -1900,20 +1932,14 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client, int result; struct snd_seq_client *sender = NULL; struct snd_seq_client_port *sport = NULL; - struct snd_seq_subscribers *p; result = -EINVAL; if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL) goto __end; if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL) goto __end; - p = snd_seq_port_get_subscription(&sport->c_src, &subs->dest); - if (p) { - result = 0; - *subs = p->info; - } else - result = -ENOENT; - + result = snd_seq_port_get_subscription(&sport->c_src, &subs->dest, + subs); __end: if (sport) snd_seq_port_unlock(sport); @@ -2227,12 +2253,13 @@ int snd_seq_delete_kernel_client(int client) } EXPORT_SYMBOL(snd_seq_delete_kernel_client); -/* skeleton to enqueue event, called from snd_seq_kernel_client_enqueue - * and snd_seq_kernel_client_enqueue_blocking +/* + * exported, called by kernel clients to enqueue events (w/o blocking) + * + * RETURN VALUE: zero if succeed, negative if error */ -static int kernel_client_enqueue(int client, struct snd_seq_event *ev, - struct file *file, int blocking, - int atomic, int hop) +int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event *ev, + struct file *file, bool blocking) { struct snd_seq_client *cptr; int result; @@ -2255,41 +2282,21 @@ static int kernel_client_enqueue(int client, struct snd_seq_event *ev, if (cptr == NULL) return -EINVAL; - if (! cptr->accept_output) + if (!cptr->accept_output) { result = -EPERM; - else /* send it */ + } else { /* send it */ + mutex_lock(&cptr->ioctl_mutex); result = snd_seq_client_enqueue_event(cptr, ev, file, blocking, - atomic, hop, NULL); + false, 0, + &cptr->ioctl_mutex); + mutex_unlock(&cptr->ioctl_mutex); + } snd_seq_client_unlock(cptr); return result; } - -/* - * exported, called by kernel clients to enqueue events (w/o blocking) - * - * RETURN VALUE: zero if succeed, negative if error - */ -int snd_seq_kernel_client_enqueue(int client, struct snd_seq_event * ev, - int atomic, int hop) -{ - return kernel_client_enqueue(client, ev, NULL, 0, atomic, hop); -} EXPORT_SYMBOL(snd_seq_kernel_client_enqueue); -/* - * exported, called by kernel clients to enqueue events (with blocking) - * - * RETURN VALUE: zero if succeed, negative if error - */ -int snd_seq_kernel_client_enqueue_blocking(int client, struct snd_seq_event * ev, - struct file *file, - int atomic, int hop) -{ - return kernel_client_enqueue(client, ev, file, 1, atomic, hop); -} -EXPORT_SYMBOL(snd_seq_kernel_client_enqueue_blocking); - /* * exported, called by kernel clients to dispatch events directly to other * clients, bypassing the queues. Event time-stamp will be updated. |