Commit 14b9e4ab authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'for-next' into for-linus

Prep for 6.9 merge.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 21e59fe2 6fa9ba2d
...@@ -3864,14 +3864,16 @@ corresponding destructor. ...@@ -3864,14 +3864,16 @@ corresponding destructor.
And next, set suspend/resume callbacks to the pci_driver:: And next, set suspend/resume callbacks to the pci_driver::
static SIMPLE_DEV_PM_OPS(snd_my_pm_ops, mychip_suspend, mychip_resume); static DEFINE_SIMPLE_DEV_PM_OPS(snd_my_pm_ops, mychip_suspend, mychip_resume);
static struct pci_driver driver = { static struct pci_driver driver = {
.name = KBUILD_MODNAME, .name = KBUILD_MODNAME,
.id_table = snd_my_ids, .id_table = snd_my_ids,
.probe = snd_my_probe, .probe = snd_my_probe,
.remove = snd_my_remove, .remove = snd_my_remove,
.driver.pm = &snd_my_pm_ops, .driver = {
.pm = &snd_my_pm_ops,
},
}; };
Module Parameters Module Parameters
......
...@@ -5014,6 +5014,7 @@ F: include/linux/mfd/cs42l43* ...@@ -5014,6 +5014,7 @@ F: include/linux/mfd/cs42l43*
F: include/sound/cs* F: include/sound/cs*
F: sound/pci/hda/cirrus* F: sound/pci/hda/cirrus*
F: sound/pci/hda/cs* F: sound/pci/hda/cs*
F: sound/pci/hda/hda_component*
F: sound/pci/hda/hda_cs_dsp_ctl.* F: sound/pci/hda/hda_cs_dsp_ctl.*
F: sound/soc/codecs/cs* F: sound/soc/codecs/cs*
...@@ -20485,6 +20486,12 @@ F: include/uapi/sound/compress_* ...@@ -20485,6 +20486,12 @@ F: include/uapi/sound/compress_*
F: sound/core/compress_offload.c F: sound/core/compress_offload.c
F: sound/soc/soc-compress.c F: sound/soc/soc-compress.c
SOUND - CORE KUNIT TEST
M: Ivan Orlov <ivan.orlov0322@gmail.com>
L: linux-sound@vger.kernel.org
S: Supported
F: sound/core/sound_kunit.c
SOUND - DMAENGINE HELPERS SOUND - DMAENGINE HELPERS
M: Lars-Peter Clausen <lars@metafoo.de> M: Lars-Peter Clausen <lars@metafoo.de>
S: Supported S: Supported
......
...@@ -1725,7 +1725,9 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) ...@@ -1725,7 +1725,9 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device)
{"BSG1160", }, {"BSG1160", },
{"BSG2150", }, {"BSG2150", },
{"CSC3551", }, {"CSC3551", },
{"CSC3554", },
{"CSC3556", }, {"CSC3556", },
{"CSC3557", },
{"INT33FE", }, {"INT33FE", },
{"INT3515", }, {"INT3515", },
/* Non-conforming _HID for Cirrus Logic already released */ /* Non-conforming _HID for Cirrus Logic already released */
......
...@@ -329,6 +329,19 @@ static const struct smi_node cs35l41_hda = { ...@@ -329,6 +329,19 @@ static const struct smi_node cs35l41_hda = {
.bus_type = SMI_AUTO_DETECT, .bus_type = SMI_AUTO_DETECT,
}; };
static const struct smi_node cs35l54_hda = {
.instances = {
{ "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l54-hda", IRQ_RESOURCE_AUTO, 0 },
/* a 5th entry is an alias address, not a real device */
{ "cs35l54-hda_dummy_dev" },
{}
},
.bus_type = SMI_AUTO_DETECT,
};
static const struct smi_node cs35l56_hda = { static const struct smi_node cs35l56_hda = {
.instances = { .instances = {
{ "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 }, { "cs35l56-hda", IRQ_RESOURCE_AUTO, 0 },
...@@ -342,6 +355,19 @@ static const struct smi_node cs35l56_hda = { ...@@ -342,6 +355,19 @@ static const struct smi_node cs35l56_hda = {
.bus_type = SMI_AUTO_DETECT, .bus_type = SMI_AUTO_DETECT,
}; };
static const struct smi_node cs35l57_hda = {
.instances = {
{ "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 },
{ "cs35l57-hda", IRQ_RESOURCE_AUTO, 0 },
/* a 5th entry is an alias address, not a real device */
{ "cs35l57-hda_dummy_dev" },
{}
},
.bus_type = SMI_AUTO_DETECT,
};
/* /*
* Note new device-ids must also be added to ignore_serial_bus_ids in * Note new device-ids must also be added to ignore_serial_bus_ids in
* drivers/acpi/scan.c: acpi_device_enumeration_by_parent(). * drivers/acpi/scan.c: acpi_device_enumeration_by_parent().
...@@ -350,7 +376,9 @@ static const struct acpi_device_id smi_acpi_ids[] = { ...@@ -350,7 +376,9 @@ static const struct acpi_device_id smi_acpi_ids[] = {
{ "BSG1160", (unsigned long)&bsg1160_data }, { "BSG1160", (unsigned long)&bsg1160_data },
{ "BSG2150", (unsigned long)&bsg2150_data }, { "BSG2150", (unsigned long)&bsg2150_data },
{ "CSC3551", (unsigned long)&cs35l41_hda }, { "CSC3551", (unsigned long)&cs35l41_hda },
{ "CSC3554", (unsigned long)&cs35l54_hda },
{ "CSC3556", (unsigned long)&cs35l56_hda }, { "CSC3556", (unsigned long)&cs35l56_hda },
{ "CSC3557", (unsigned long)&cs35l57_hda },
{ "INT3515", (unsigned long)&int3515_data }, { "INT3515", (unsigned long)&int3515_data },
/* Non-conforming _HID for Cirrus Logic already released */ /* Non-conforming _HID for Cirrus Logic already released */
{ "CLSA0100", (unsigned long)&cs35l41_hda }, { "CLSA0100", (unsigned long)&cs35l41_hda },
......
...@@ -65,6 +65,9 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531, ...@@ -65,6 +65,9 @@ int snd_ak4531_mixer(struct snd_card *card, struct snd_ak4531 *_ak4531,
#ifdef CONFIG_PM #ifdef CONFIG_PM
void snd_ak4531_suspend(struct snd_ak4531 *ak4531); void snd_ak4531_suspend(struct snd_ak4531 *ak4531);
void snd_ak4531_resume(struct snd_ak4531 *ak4531); void snd_ak4531_resume(struct snd_ak4531 *ak4531);
#else
static inline void snd_ak4531_suspend(struct snd_ak4531 *ak4531) {}
static inline void snd_ak4531_resume(struct snd_ak4531 *ak4531) {}
#endif #endif
#endif /* __SOUND_AK4531_CODEC_H */ #endif /* __SOUND_AK4531_CODEC_H */
...@@ -257,6 +257,7 @@ struct cs35l56_base { ...@@ -257,6 +257,7 @@ struct cs35l56_base {
struct regmap *regmap; struct regmap *regmap;
int irq; int irq;
struct mutex irq_lock; struct mutex irq_lock;
u8 type;
u8 rev; u8 rev;
bool init_done; bool init_done;
bool fw_patched; bool fw_patched;
......
...@@ -103,7 +103,7 @@ struct snd_emux { ...@@ -103,7 +103,7 @@ struct snd_emux {
int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */ int ports[SNDRV_EMUX_MAX_PORTS]; /* The ports for this device */
struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS]; struct snd_emux_port *portptrs[SNDRV_EMUX_MAX_PORTS];
int used; /* use counter */ int used; /* use counter */
char *name; /* name of the device (internal) */ const char *name; /* name of the device (internal) */
struct snd_rawmidi **vmidi; struct snd_rawmidi **vmidi;
struct timer_list tlist; /* for pending note-offs */ struct timer_list tlist; /* for pending note-offs */
int timer_active; int timer_active;
......
...@@ -659,6 +659,18 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, ...@@ -659,6 +659,18 @@ void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
flags = _snd_pcm_stream_lock_irqsave_nested(substream); \ flags = _snd_pcm_stream_lock_irqsave_nested(substream); \
} while (0) } while (0)
/* definitions for guard(); use like guard(pcm_stream_lock) */
DEFINE_LOCK_GUARD_1(pcm_stream_lock, struct snd_pcm_substream,
snd_pcm_stream_lock(_T->lock),
snd_pcm_stream_unlock(_T->lock))
DEFINE_LOCK_GUARD_1(pcm_stream_lock_irq, struct snd_pcm_substream,
snd_pcm_stream_lock_irq(_T->lock),
snd_pcm_stream_unlock_irq(_T->lock))
DEFINE_LOCK_GUARD_1(pcm_stream_lock_irqsave, struct snd_pcm_substream,
snd_pcm_stream_lock_irqsave(_T->lock, _T->flags),
snd_pcm_stream_unlock_irqrestore(_T->lock, _T->flags),
unsigned long flags)
/** /**
* snd_pcm_group_for_each_entry - iterate over the linked substreams * snd_pcm_group_for_each_entry - iterate over the linked substreams
* @s: the iterator * @s: the iterator
......
...@@ -290,6 +290,9 @@ int snd_sbmixer_new(struct snd_sb *chip); ...@@ -290,6 +290,9 @@ int snd_sbmixer_new(struct snd_sb *chip);
#ifdef CONFIG_PM #ifdef CONFIG_PM
void snd_sbmixer_suspend(struct snd_sb *chip); void snd_sbmixer_suspend(struct snd_sb *chip);
void snd_sbmixer_resume(struct snd_sb *chip); void snd_sbmixer_resume(struct snd_sb *chip);
#else
static inline void snd_sbmixer_suspend(struct snd_sb *chip) {}
static inline void snd_sbmixer_resume(struct snd_sb *chip) {}
#endif #endif
/* sb8_init.c */ /* sb8_init.c */
......
...@@ -7,6 +7,14 @@ ...@@ -7,6 +7,14 @@
#include <linux/virtio_types.h> #include <linux/virtio_types.h>
/*******************************************************************************
* FEATURE BITS
*/
enum {
/* device supports control elements */
VIRTIO_SND_F_CTLS = 0
};
/******************************************************************************* /*******************************************************************************
* CONFIGURATION SPACE * CONFIGURATION SPACE
*/ */
...@@ -17,6 +25,8 @@ struct virtio_snd_config { ...@@ -17,6 +25,8 @@ struct virtio_snd_config {
__le32 streams; __le32 streams;
/* # of available channel maps */ /* # of available channel maps */
__le32 chmaps; __le32 chmaps;
/* # of available control elements */
__le32 controls;
}; };
enum { enum {
...@@ -55,6 +65,15 @@ enum { ...@@ -55,6 +65,15 @@ enum {
/* channel map control request types */ /* channel map control request types */
VIRTIO_SND_R_CHMAP_INFO = 0x0200, VIRTIO_SND_R_CHMAP_INFO = 0x0200,
/* control element request types */
VIRTIO_SND_R_CTL_INFO = 0x0300,
VIRTIO_SND_R_CTL_ENUM_ITEMS,
VIRTIO_SND_R_CTL_READ,
VIRTIO_SND_R_CTL_WRITE,
VIRTIO_SND_R_CTL_TLV_READ,
VIRTIO_SND_R_CTL_TLV_WRITE,
VIRTIO_SND_R_CTL_TLV_COMMAND,
/* jack event types */ /* jack event types */
VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000, VIRTIO_SND_EVT_JACK_CONNECTED = 0x1000,
VIRTIO_SND_EVT_JACK_DISCONNECTED, VIRTIO_SND_EVT_JACK_DISCONNECTED,
...@@ -63,6 +82,9 @@ enum { ...@@ -63,6 +82,9 @@ enum {
VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100, VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED = 0x1100,
VIRTIO_SND_EVT_PCM_XRUN, VIRTIO_SND_EVT_PCM_XRUN,
/* control element event types */
VIRTIO_SND_EVT_CTL_NOTIFY = 0x1200,
/* common status codes */ /* common status codes */
VIRTIO_SND_S_OK = 0x8000, VIRTIO_SND_S_OK = 0x8000,
VIRTIO_SND_S_BAD_MSG, VIRTIO_SND_S_BAD_MSG,
...@@ -331,4 +353,136 @@ struct virtio_snd_chmap_info { ...@@ -331,4 +353,136 @@ struct virtio_snd_chmap_info {
__u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE]; __u8 positions[VIRTIO_SND_CHMAP_MAX_SIZE];
}; };
/*******************************************************************************
* CONTROL ELEMENTS MESSAGES
*/
struct virtio_snd_ctl_hdr {
/* VIRTIO_SND_R_CTL_XXX */
struct virtio_snd_hdr hdr;
/* 0 ... virtio_snd_config::controls - 1 */
__le32 control_id;
};
/* supported roles for control elements */
enum {
VIRTIO_SND_CTL_ROLE_UNDEFINED = 0,
VIRTIO_SND_CTL_ROLE_VOLUME,
VIRTIO_SND_CTL_ROLE_MUTE,
VIRTIO_SND_CTL_ROLE_GAIN
};
/* supported value types for control elements */
enum {
VIRTIO_SND_CTL_TYPE_BOOLEAN = 0,
VIRTIO_SND_CTL_TYPE_INTEGER,
VIRTIO_SND_CTL_TYPE_INTEGER64,
VIRTIO_SND_CTL_TYPE_ENUMERATED,
VIRTIO_SND_CTL_TYPE_BYTES,
VIRTIO_SND_CTL_TYPE_IEC958
};
/* supported access rights for control elements */
enum {
VIRTIO_SND_CTL_ACCESS_READ = 0,
VIRTIO_SND_CTL_ACCESS_WRITE,
VIRTIO_SND_CTL_ACCESS_VOLATILE,
VIRTIO_SND_CTL_ACCESS_INACTIVE,
VIRTIO_SND_CTL_ACCESS_TLV_READ,
VIRTIO_SND_CTL_ACCESS_TLV_WRITE,
VIRTIO_SND_CTL_ACCESS_TLV_COMMAND
};
struct virtio_snd_ctl_info {
/* common header */
struct virtio_snd_info hdr;
/* element role (VIRTIO_SND_CTL_ROLE_XXX) */
__le32 role;
/* element value type (VIRTIO_SND_CTL_TYPE_XXX) */
__le32 type;
/* element access right bit map (1 << VIRTIO_SND_CTL_ACCESS_XXX) */
__le32 access;
/* # of members in the element value */
__le32 count;
/* index for an element with a non-unique name */
__le32 index;
/* name identifier string for the element */
__u8 name[44];
/* additional information about the element's value */
union {
/* VIRTIO_SND_CTL_TYPE_INTEGER */
struct {
/* minimum supported value */
__le32 min;
/* maximum supported value */
__le32 max;
/* fixed step size for value (0 = variable size) */
__le32 step;
} integer;
/* VIRTIO_SND_CTL_TYPE_INTEGER64 */
struct {
/* minimum supported value */
__le64 min;
/* maximum supported value */
__le64 max;
/* fixed step size for value (0 = variable size) */
__le64 step;
} integer64;
/* VIRTIO_SND_CTL_TYPE_ENUMERATED */
struct {
/* # of options supported for value */
__le32 items;
} enumerated;
} value;
};
struct virtio_snd_ctl_enum_item {
/* option name */
__u8 item[64];
};
struct virtio_snd_ctl_iec958 {
/* AES/IEC958 channel status bits */
__u8 status[24];
/* AES/IEC958 subcode bits */
__u8 subcode[147];
/* nothing */
__u8 pad;
/* AES/IEC958 subframe bits */
__u8 dig_subframe[4];
};
struct virtio_snd_ctl_value {
union {
/* VIRTIO_SND_CTL_TYPE_BOOLEAN|INTEGER value */
__le32 integer[128];
/* VIRTIO_SND_CTL_TYPE_INTEGER64 value */
__le64 integer64[64];
/* VIRTIO_SND_CTL_TYPE_ENUMERATED value (option indexes) */
__le32 enumerated[128];
/* VIRTIO_SND_CTL_TYPE_BYTES value */
__u8 bytes[512];
/* VIRTIO_SND_CTL_TYPE_IEC958 value */
struct virtio_snd_ctl_iec958 iec958;
} value;
};
/* supported event reason types */
enum {
/* element's value has changed */
VIRTIO_SND_CTL_EVT_MASK_VALUE = 0,
/* element's information has changed */
VIRTIO_SND_CTL_EVT_MASK_INFO,
/* element's metadata has changed */
VIRTIO_SND_CTL_EVT_MASK_TLV
};
struct virtio_snd_ctl_event {
/* VIRTIO_SND_EVT_CTL_NOTIFY */
struct virtio_snd_hdr hdr;
/* 0 ... virtio_snd_config::controls - 1 */
__le16 control_id;
/* event reason bit map (1 << VIRTIO_SND_CTL_EVT_MASK_XXX) */
__le16 mask;
};
#endif /* VIRTIO_SND_IF_H */ #endif /* VIRTIO_SND_IF_H */
...@@ -1126,7 +1126,6 @@ static void aoa_fabric_layout_remove(struct soundbus_dev *sdev) ...@@ -1126,7 +1126,6 @@ static void aoa_fabric_layout_remove(struct soundbus_dev *sdev)
sdev->pcmname = NULL; sdev->pcmname = NULL;
} }
#ifdef CONFIG_PM_SLEEP
static int aoa_fabric_layout_suspend(struct device *dev) static int aoa_fabric_layout_suspend(struct device *dev)
{ {
struct layout_dev *ldev = dev_get_drvdata(dev); struct layout_dev *ldev = dev_get_drvdata(dev);
...@@ -1147,11 +1146,9 @@ static int aoa_fabric_layout_resume(struct device *dev) ...@@ -1147,11 +1146,9 @@ static int aoa_fabric_layout_resume(struct device *dev)
return 0; return 0;
} }
static SIMPLE_DEV_PM_OPS(aoa_fabric_layout_pm_ops, static DEFINE_SIMPLE_DEV_PM_OPS(aoa_fabric_layout_pm_ops,
aoa_fabric_layout_suspend, aoa_fabric_layout_resume); aoa_fabric_layout_suspend, aoa_fabric_layout_resume);
#endif
static struct soundbus_driver aoa_soundbus_driver = { static struct soundbus_driver aoa_soundbus_driver = {
.name = "snd_aoa_soundbus_drv", .name = "snd_aoa_soundbus_drv",
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1159,9 +1156,7 @@ static struct soundbus_driver aoa_soundbus_driver = { ...@@ -1159,9 +1156,7 @@ static struct soundbus_driver aoa_soundbus_driver = {
.remove = aoa_fabric_layout_remove, .remove = aoa_fabric_layout_remove,
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_PM_SLEEP
.pm = &aoa_fabric_layout_pm_ops, .pm = &aoa_fabric_layout_pm_ops,
#endif
} }
}; };
......
...@@ -127,7 +127,7 @@ static void soundbus_device_shutdown(struct device *dev) ...@@ -127,7 +127,7 @@ static void soundbus_device_shutdown(struct device *dev)
/* soundbus_dev_attrs is declared in sysfs.c */ /* soundbus_dev_attrs is declared in sysfs.c */
ATTRIBUTE_GROUPS(soundbus_dev); ATTRIBUTE_GROUPS(soundbus_dev);
static struct bus_type soundbus_bus_type = { static const struct bus_type soundbus_bus_type = {
.name = "aoa-soundbus", .name = "aoa-soundbus",
.probe = soundbus_probe, .probe = soundbus_probe,
.uevent = soundbus_uevent, .uevent = soundbus_uevent,
......
...@@ -737,7 +737,6 @@ static const struct snd_pcm_ops aaci_capture_ops = { ...@@ -737,7 +737,6 @@ static const struct snd_pcm_ops aaci_capture_ops = {
/* /*
* Power Management. * Power Management.
*/ */
#ifdef CONFIG_PM
static int aaci_do_suspend(struct snd_card *card) static int aaci_do_suspend(struct snd_card *card)
{ {
struct aaci *aaci = card->private_data; struct aaci *aaci = card->private_data;
...@@ -763,12 +762,7 @@ static int aaci_resume(struct device *dev) ...@@ -763,12 +762,7 @@ static int aaci_resume(struct device *dev)
return card ? aaci_do_resume(card) : 0; return card ? aaci_do_resume(card) : 0;
} }
static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume); static DEFINE_SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume);
#define AACI_DEV_PM_OPS (&aaci_dev_pm_ops)
#else
#define AACI_DEV_PM_OPS NULL
#endif
static const struct ac97_pcm ac97_defs[] = { static const struct ac97_pcm ac97_defs[] = {
[0] = { /* Front PCM */ [0] = { /* Front PCM */
...@@ -1081,7 +1075,7 @@ MODULE_DEVICE_TABLE(amba, aaci_ids); ...@@ -1081,7 +1075,7 @@ MODULE_DEVICE_TABLE(amba, aaci_ids);
static struct amba_driver aaci_driver = { static struct amba_driver aaci_driver = {
.drv = { .drv = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pm = AACI_DEV_PM_OPS, .pm = &aaci_dev_pm_ops,
}, },
.probe = aaci_probe, .probe = aaci_probe,
.remove = aaci_remove, .remove = aaci_remove,
......
...@@ -111,8 +111,6 @@ static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -111,8 +111,6 @@ static int pxa2xx_ac97_pcm_prepare(struct snd_pcm_substream *substream)
return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate); return snd_ac97_set_rate(pxa2xx_ac97_ac97, reg, runtime->rate);
} }
#ifdef CONFIG_PM_SLEEP
static int pxa2xx_ac97_do_suspend(struct snd_card *card) static int pxa2xx_ac97_do_suspend(struct snd_card *card)
{ {
pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
...@@ -164,8 +162,7 @@ static int pxa2xx_ac97_resume(struct device *dev) ...@@ -164,8 +162,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
return ret; return ret;
} }
static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume); static DEFINE_SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
#endif
static const struct snd_pcm_ops pxa2xx_ac97_pcm_ops = { static const struct snd_pcm_ops pxa2xx_ac97_pcm_ops = {
.open = pxa2xx_ac97_pcm_open, .open = pxa2xx_ac97_pcm_open,
...@@ -277,9 +274,7 @@ static struct platform_driver pxa2xx_ac97_driver = { ...@@ -277,9 +274,7 @@ static struct platform_driver pxa2xx_ac97_driver = {
.remove_new = pxa2xx_ac97_remove, .remove_new = pxa2xx_ac97_remove,
.driver = { .driver = {
.name = "pxa2xx-ac97", .name = "pxa2xx-ac97",
#ifdef CONFIG_PM_SLEEP
.pm = &pxa2xx_ac97_pm_ops, .pm = &pxa2xx_ac97_pm_ops,
#endif
}, },
}; };
......
...@@ -39,6 +39,23 @@ config SND_UMP_LEGACY_RAWMIDI ...@@ -39,6 +39,23 @@ config SND_UMP_LEGACY_RAWMIDI
legacy MIDI 1.0 byte streams is created for each UMP Endpoint. legacy MIDI 1.0 byte streams is created for each UMP Endpoint.
The device contains 16 substreams corresponding to UMP groups. The device contains 16 substreams corresponding to UMP groups.
config SND_CORE_TEST
tristate "Sound core KUnit test"
depends on KUNIT
select SND_PCM
default KUNIT_ALL_TESTS
help
This options enables the sound core functions KUnit test.
KUnit tests run during boot and output the results to the debug
log in TAP format (https://testanything.org/). Only useful for
kernel devs running KUnit test harness and are not for inclusion
into a production build.
For more information on KUnit and unit tests in general, refer
to the KUnit documentation in Documentation/dev-tools/kunit/.
config SND_COMPRESS_OFFLOAD config SND_COMPRESS_OFFLOAD
tristate tristate
......
...@@ -48,6 +48,8 @@ obj-$(CONFIG_SND_SEQ_DEVICE) += snd-seq-device.o ...@@ -48,6 +48,8 @@ obj-$(CONFIG_SND_SEQ_DEVICE) += snd-seq-device.o
obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
obj-$(CONFIG_SND_UMP) += snd-ump.o obj-$(CONFIG_SND_UMP) += snd-ump.o
obj-$(CONFIG_SND_CORE_TEST) += sound_kunit.o
obj-$(CONFIG_SND_OSSEMUL) += oss/ obj-$(CONFIG_SND_OSSEMUL) += oss/
obj-$(CONFIG_SND_SEQUENCER) += seq/ obj-$(CONFIG_SND_SEQUENCER) += seq/
......
...@@ -127,9 +127,8 @@ static int snd_compr_open(struct inode *inode, struct file *f) ...@@ -127,9 +127,8 @@ static int snd_compr_open(struct inode *inode, struct file *f)
init_waitqueue_head(&runtime->sleep); init_waitqueue_head(&runtime->sleep);
data->stream.runtime = runtime; data->stream.runtime = runtime;
f->private_data = (void *)data; f->private_data = (void *)data;
mutex_lock(&compr->lock); scoped_guard(mutex, &compr->lock)
ret = compr->ops->open(&data->stream); ret = compr->ops->open(&data->stream);
mutex_unlock(&compr->lock);
if (ret) { if (ret) {
kfree(runtime); kfree(runtime);
kfree(data); kfree(data);
...@@ -288,7 +287,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, ...@@ -288,7 +287,7 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
return -EFAULT; return -EFAULT;
stream = &data->stream; stream = &data->stream;
mutex_lock(&stream->device->lock); guard(mutex)(&stream->device->lock);
/* write is allowed when stream is running or has been steup */ /* write is allowed when stream is running or has been steup */
switch (stream->runtime->state) { switch (stream->runtime->state) {
case SNDRV_PCM_STATE_SETUP: case SNDRV_PCM_STATE_SETUP:
...@@ -296,7 +295,6 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, ...@@ -296,7 +295,6 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
case SNDRV_PCM_STATE_RUNNING: case SNDRV_PCM_STATE_RUNNING:
break; break;
default: default:
mutex_unlock(&stream->device->lock);
return -EBADFD; return -EBADFD;
} }
...@@ -322,7 +320,6 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf, ...@@ -322,7 +320,6 @@ static ssize_t snd_compr_write(struct file *f, const char __user *buf,
pr_debug("stream prepared, Houston we are good to go\n"); pr_debug("stream prepared, Houston we are good to go\n");
} }
mutex_unlock(&stream->device->lock);
return retval; return retval;
} }
...@@ -339,7 +336,7 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf, ...@@ -339,7 +336,7 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
return -EFAULT; return -EFAULT;
stream = &data->stream; stream = &data->stream;
mutex_lock(&stream->device->lock); guard(mutex)(&stream->device->lock);
/* read is allowed when stream is running, paused, draining and setup /* read is allowed when stream is running, paused, draining and setup
* (yes setup is state which we transition to after stop, so if user * (yes setup is state which we transition to after stop, so if user
...@@ -350,11 +347,9 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf, ...@@ -350,11 +347,9 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
case SNDRV_PCM_STATE_PREPARED: case SNDRV_PCM_STATE_PREPARED:
case SNDRV_PCM_STATE_SUSPENDED: case SNDRV_PCM_STATE_SUSPENDED:
case SNDRV_PCM_STATE_DISCONNECTED: case SNDRV_PCM_STATE_DISCONNECTED:
retval = -EBADFD; return -EBADFD;
goto out;
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
retval = -EPIPE; return -EPIPE;
goto out;
} }
avail = snd_compr_get_avail(stream); avail = snd_compr_get_avail(stream);
...@@ -363,17 +358,13 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf, ...@@ -363,17 +358,13 @@ static ssize_t snd_compr_read(struct file *f, char __user *buf,
if (avail > count) if (avail > count)
avail = count; avail = count;
if (stream->ops->copy) { if (stream->ops->copy)
retval = stream->ops->copy(stream, buf, avail); retval = stream->ops->copy(stream, buf, avail);
} else { else
retval = -ENXIO; return -ENXIO;
goto out;
}
if (retval > 0) if (retval > 0)
stream->runtime->total_bytes_transferred += retval; stream->runtime->total_bytes_transferred += retval;
out:
mutex_unlock(&stream->device->lock);
return retval; return retval;
} }
...@@ -402,13 +393,12 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait) ...@@ -402,13 +393,12 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
stream = &data->stream; stream = &data->stream;
mutex_lock(&stream->device->lock); guard(mutex)(&stream->device->lock);
switch (stream->runtime->state) { switch (stream->runtime->state) {
case SNDRV_PCM_STATE_OPEN: case SNDRV_PCM_STATE_OPEN:
case SNDRV_PCM_STATE_XRUN: case SNDRV_PCM_STATE_XRUN:
retval = snd_compr_get_poll(stream) | EPOLLERR; return snd_compr_get_poll(stream) | EPOLLERR;
goto out;
default: default:
break; break;
} }
...@@ -433,11 +423,9 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait) ...@@ -433,11 +423,9 @@ static __poll_t snd_compr_poll(struct file *f, poll_table *wait)
retval = snd_compr_get_poll(stream); retval = snd_compr_get_poll(stream);
break; break;
default: default:
retval = snd_compr_get_poll(stream) | EPOLLERR; return snd_compr_get_poll(stream) | EPOLLERR;
break;
} }
out:
mutex_unlock(&stream->device->lock);
return retval; return retval;
} }
...@@ -465,7 +453,7 @@ static int ...@@ -465,7 +453,7 @@ static int
snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
{ {
int retval; int retval;
struct snd_compr_codec_caps *caps; struct snd_compr_codec_caps *caps __free(kfree) = NULL;
if (!stream->ops->get_codec_caps) if (!stream->ops->get_codec_caps)
return -ENXIO; return -ENXIO;
...@@ -476,12 +464,9 @@ snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) ...@@ -476,12 +464,9 @@ snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg)
retval = stream->ops->get_codec_caps(stream, caps); retval = stream->ops->get_codec_caps(stream, caps);
if (retval) if (retval)
goto out; return retval;
if (copy_to_user((void __user *)arg, caps, sizeof(*caps))) if (copy_to_user((void __user *)arg, caps, sizeof(*caps)))
retval = -EFAULT; return -EFAULT;
out:
kfree(caps);
return retval; return retval;
} }
#endif /* !COMPR_CODEC_CAPS_OVERFLOW */ #endif /* !COMPR_CODEC_CAPS_OVERFLOW */
...@@ -586,7 +571,7 @@ static int snd_compress_check_input(struct snd_compr_params *params) ...@@ -586,7 +571,7 @@ static int snd_compress_check_input(struct snd_compr_params *params)
static int static int
snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
{ {
struct snd_compr_params *params; struct snd_compr_params *params __free(kfree) = NULL;
int retval; int retval;
if (stream->runtime->state == SNDRV_PCM_STATE_OPEN || stream->next_track) { if (stream->runtime->state == SNDRV_PCM_STATE_OPEN || stream->next_track) {
...@@ -596,24 +581,22 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) ...@@ -596,24 +581,22 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
*/ */
params = memdup_user((void __user *)arg, sizeof(*params)); params = memdup_user((void __user *)arg, sizeof(*params));
if (IS_ERR(params)) if (IS_ERR(params))
return PTR_ERR(params); return PTR_ERR(no_free_ptr(params));
retval = snd_compress_check_input(params); retval = snd_compress_check_input(params);
if (retval) if (retval)
goto out; return retval;
retval = snd_compr_allocate_buffer(stream, params); retval = snd_compr_allocate_buffer(stream, params);
if (retval) { if (retval)
retval = -ENOMEM; return -ENOMEM;
goto out;
}
retval = stream->ops->set_params(stream, params); retval = stream->ops->set_params(stream, params);
if (retval) if (retval)
goto out; return retval;
if (stream->next_track) if (stream->next_track)
goto out; return retval;
stream->metadata_set = false; stream->metadata_set = false;
stream->next_track = false; stream->next_track = false;
...@@ -622,15 +605,13 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) ...@@ -622,15 +605,13 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
} else { } else {
return -EPERM; return -EPERM;
} }
out:
kfree(params);
return retval; return retval;
} }
static int static int
snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
{ {
struct snd_codec *params; struct snd_codec *params __free(kfree) = NULL;
int retval; int retval;
if (!stream->ops->get_params) if (!stream->ops->get_params)
...@@ -641,12 +622,9 @@ snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) ...@@ -641,12 +622,9 @@ snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg)
return -ENOMEM; return -ENOMEM;
retval = stream->ops->get_params(stream, params); retval = stream->ops->get_params(stream, params);
if (retval) if (retval)
goto out; return retval;
if (copy_to_user((char __user *)arg, params, sizeof(*params))) if (copy_to_user((char __user *)arg, params, sizeof(*params)))
retval = -EFAULT; return -EFAULT;
out:
kfree(params);
return retval; return retval;
} }
...@@ -805,12 +783,10 @@ static void error_delayed_work(struct work_struct *work) ...@@ -805,12 +783,10 @@ static void error_delayed_work(struct work_struct *work)
stream = container_of(work, struct snd_compr_stream, error_work.work); stream = container_of(work, struct snd_compr_stream, error_work.work);
mutex_lock(&stream->device->lock); guard(mutex)(&stream->device->lock);
stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
wake_up(&stream->runtime->sleep); wake_up(&stream->runtime->sleep);
mutex_unlock(&stream->device->lock);
} }
/** /**
...@@ -967,70 +943,52 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg) ...@@ -967,70 +943,52 @@ static long snd_compr_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{ {
struct snd_compr_file *data = f->private_data; struct snd_compr_file *data = f->private_data;
struct snd_compr_stream *stream; struct snd_compr_stream *stream;
int retval = -ENOTTY;
if (snd_BUG_ON(!data)) if (snd_BUG_ON(!data))
return -EFAULT; return -EFAULT;
stream = &data->stream; stream = &data->stream;
mutex_lock(&stream->device->lock); guard(mutex)(&stream->device->lock);
switch (_IOC_NR(cmd)) { switch (_IOC_NR(cmd)) {
case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION): case _IOC_NR(SNDRV_COMPRESS_IOCTL_VERSION):
retval = put_user(SNDRV_COMPRESS_VERSION, return put_user(SNDRV_COMPRESS_VERSION,
(int __user *)arg) ? -EFAULT : 0; (int __user *)arg) ? -EFAULT : 0;
break;
case _IOC_NR(SNDRV_COMPRESS_GET_CAPS): case _IOC_NR(SNDRV_COMPRESS_GET_CAPS):
retval = snd_compr_get_caps(stream, arg); return snd_compr_get_caps(stream, arg);
break;
#ifndef COMPR_CODEC_CAPS_OVERFLOW #ifndef COMPR_CODEC_CAPS_OVERFLOW
case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS): case _IOC_NR(SNDRV_COMPRESS_GET_CODEC_CAPS):
retval = snd_compr_get_codec_caps(stream, arg); return snd_compr_get_codec_caps(stream, arg);
break;
#endif #endif
case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS): case _IOC_NR(SNDRV_COMPRESS_SET_PARAMS):
retval = snd_compr_set_params(stream, arg); return snd_compr_set_params(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS): case _IOC_NR(SNDRV_COMPRESS_GET_PARAMS):
retval = snd_compr_get_params(stream, arg); return snd_compr_get_params(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_SET_METADATA): case _IOC_NR(SNDRV_COMPRESS_SET_METADATA):
retval = snd_compr_set_metadata(stream, arg); return snd_compr_set_metadata(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_GET_METADATA): case _IOC_NR(SNDRV_COMPRESS_GET_METADATA):
retval = snd_compr_get_metadata(stream, arg); return snd_compr_get_metadata(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_TSTAMP): case _IOC_NR(SNDRV_COMPRESS_TSTAMP):
retval = snd_compr_tstamp(stream, arg); return snd_compr_tstamp(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_AVAIL): case _IOC_NR(SNDRV_COMPRESS_AVAIL):
retval = snd_compr_ioctl_avail(stream, arg); return snd_compr_ioctl_avail(stream, arg);
break;
case _IOC_NR(SNDRV_COMPRESS_PAUSE): case _IOC_NR(SNDRV_COMPRESS_PAUSE):
retval = snd_compr_pause(stream); return snd_compr_pause(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_RESUME): case _IOC_NR(SNDRV_COMPRESS_RESUME):
retval = snd_compr_resume(stream); return snd_compr_resume(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_START): case _IOC_NR(SNDRV_COMPRESS_START):
retval = snd_compr_start(stream); return snd_compr_start(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_STOP): case _IOC_NR(SNDRV_COMPRESS_STOP):
retval = snd_compr_stop(stream); return snd_compr_stop(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_DRAIN): case _IOC_NR(SNDRV_COMPRESS_DRAIN):
retval = snd_compr_drain(stream); return snd_compr_drain(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN): case _IOC_NR(SNDRV_COMPRESS_PARTIAL_DRAIN):
retval = snd_compr_partial_drain(stream); return snd_compr_partial_drain(stream);
break;
case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK): case _IOC_NR(SNDRV_COMPRESS_NEXT_TRACK):
retval = snd_compr_next_track(stream); return snd_compr_next_track(stream);
break;
} }
mutex_unlock(&stream->device->lock);
return retval; return -ENOTTY;
} }
/* support of 32bit userspace on 64bit platforms */ /* support of 32bit userspace on 64bit platforms */
......
This diff is collapsed.
...@@ -79,61 +79,56 @@ struct snd_ctl_elem_info32 { ...@@ -79,61 +79,56 @@ struct snd_ctl_elem_info32 {
static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
struct snd_ctl_elem_info32 __user *data32) struct snd_ctl_elem_info32 __user *data32)
{ {
struct snd_ctl_elem_info *data; struct snd_ctl_elem_info *data __free(kfree) = NULL;
int err; int err;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data) if (! data)
return -ENOMEM; return -ENOMEM;
err = -EFAULT;
/* copy id */ /* copy id */
if (copy_from_user(&data->id, &data32->id, sizeof(data->id))) if (copy_from_user(&data->id, &data32->id, sizeof(data->id)))
goto error; return -EFAULT;
/* we need to copy the item index. /* we need to copy the item index.
* hope this doesn't break anything.. * hope this doesn't break anything..
*/ */
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item)) if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
goto error; return -EFAULT;
err = snd_ctl_elem_info(ctl, data); err = snd_ctl_elem_info(ctl, data);
if (err < 0) if (err < 0)
goto error; return err;
/* restore info to 32bit */ /* restore info to 32bit */
err = -EFAULT;
/* id, type, access, count */ /* id, type, access, count */
if (copy_to_user(&data32->id, &data->id, sizeof(data->id)) || if (copy_to_user(&data32->id, &data->id, sizeof(data->id)) ||
copy_to_user(&data32->type, &data->type, 3 * sizeof(u32))) copy_to_user(&data32->type, &data->type, 3 * sizeof(u32)))
goto error; return -EFAULT;
if (put_user(data->owner, &data32->owner)) if (put_user(data->owner, &data32->owner))
goto error; return -EFAULT;
switch (data->type) { switch (data->type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
if (put_user(data->value.integer.min, &data32->value.integer.min) || if (put_user(data->value.integer.min, &data32->value.integer.min) ||
put_user(data->value.integer.max, &data32->value.integer.max) || put_user(data->value.integer.max, &data32->value.integer.max) ||
put_user(data->value.integer.step, &data32->value.integer.step)) put_user(data->value.integer.step, &data32->value.integer.step))
goto error; return -EFAULT;
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
if (copy_to_user(&data32->value.integer64, if (copy_to_user(&data32->value.integer64,
&data->value.integer64, &data->value.integer64,
sizeof(data->value.integer64))) sizeof(data->value.integer64)))
goto error; return -EFAULT;
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
if (copy_to_user(&data32->value.enumerated, if (copy_to_user(&data32->value.enumerated,
&data->value.enumerated, &data->value.enumerated,
sizeof(data->value.enumerated))) sizeof(data->value.enumerated)))
goto error; return -EFAULT;
break; break;
default: default:
break; break;
} }
err = 0; return 0;
error:
kfree(data);
return err;
} }
/* read / write */ /* read / write */
...@@ -169,31 +164,25 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, ...@@ -169,31 +164,25 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
int *countp) int *countp)
{ {
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct snd_ctl_elem_info *info; struct snd_ctl_elem_info *info __free(kfree) = NULL;
int err; int err;
down_read(&card->controls_rwsem); guard(rwsem_read)(&card->controls_rwsem);
kctl = snd_ctl_find_id_locked(card, id); kctl = snd_ctl_find_id_locked(card, id);
if (! kctl) { if (!kctl)
up_read(&card->controls_rwsem);
return -ENOENT; return -ENOENT;
}
info = kzalloc(sizeof(*info), GFP_KERNEL); info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) { if (info == NULL)
up_read(&card->controls_rwsem);
return -ENOMEM; return -ENOMEM;
}
info->id = *id; info->id = *id;
err = snd_power_ref_and_wait(card); err = snd_power_ref_and_wait(card);
if (!err) if (!err)
err = kctl->info(kctl, info); err = kctl->info(kctl, info);
snd_power_unref(card); snd_power_unref(card);
up_read(&card->controls_rwsem);
if (err >= 0) { if (err >= 0) {
err = info->type; err = info->type;
*countp = info->count; *countp = info->count;
} }
kfree(info);
return err; return err;
} }
...@@ -289,7 +278,7 @@ static int copy_ctl_value_to_user(void __user *userdata, ...@@ -289,7 +278,7 @@ static int copy_ctl_value_to_user(void __user *userdata,
static int ctl_elem_read_user(struct snd_card *card, static int ctl_elem_read_user(struct snd_card *card,
void __user *userdata, void __user *valuep) void __user *userdata, void __user *valuep)
{ {
struct snd_ctl_elem_value *data; struct snd_ctl_elem_value *data __free(kfree) = NULL;
int err, type, count; int err, type, count;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
...@@ -299,21 +288,18 @@ static int ctl_elem_read_user(struct snd_card *card, ...@@ -299,21 +288,18 @@ static int ctl_elem_read_user(struct snd_card *card,
err = copy_ctl_value_from_user(card, data, userdata, valuep, err = copy_ctl_value_from_user(card, data, userdata, valuep,
&type, &count); &type, &count);
if (err < 0) if (err < 0)
goto error; return err;
err = snd_ctl_elem_read(card, data); err = snd_ctl_elem_read(card, data);
if (err < 0) if (err < 0)
goto error; return err;
err = copy_ctl_value_to_user(userdata, valuep, data, type, count); return copy_ctl_value_to_user(userdata, valuep, data, type, count);
error:
kfree(data);
return err;
} }
static int ctl_elem_write_user(struct snd_ctl_file *file, static int ctl_elem_write_user(struct snd_ctl_file *file,
void __user *userdata, void __user *valuep) void __user *userdata, void __user *valuep)
{ {
struct snd_ctl_elem_value *data; struct snd_ctl_elem_value *data __free(kfree) = NULL;
struct snd_card *card = file->card; struct snd_card *card = file->card;
int err, type, count; int err, type, count;
...@@ -324,15 +310,12 @@ static int ctl_elem_write_user(struct snd_ctl_file *file, ...@@ -324,15 +310,12 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
err = copy_ctl_value_from_user(card, data, userdata, valuep, err = copy_ctl_value_from_user(card, data, userdata, valuep,
&type, &count); &type, &count);
if (err < 0) if (err < 0)
goto error; return err;
err = snd_ctl_elem_write(card, file, data); err = snd_ctl_elem_write(card, file, data);
if (err < 0) if (err < 0)
goto error; return err;
err = copy_ctl_value_to_user(userdata, valuep, data, type, count); return copy_ctl_value_to_user(userdata, valuep, data, type, count);
error:
kfree(data);
return err;
} }
static int snd_ctl_elem_read_user_compat(struct snd_card *card, static int snd_ctl_elem_read_user_compat(struct snd_card *card,
...@@ -366,49 +349,44 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, ...@@ -366,49 +349,44 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
struct snd_ctl_elem_info32 __user *data32, struct snd_ctl_elem_info32 __user *data32,
int replace) int replace)
{ {
struct snd_ctl_elem_info *data; struct snd_ctl_elem_info *data __free(kfree) = NULL;
int err;
data = kzalloc(sizeof(*data), GFP_KERNEL); data = kzalloc(sizeof(*data), GFP_KERNEL);
if (! data) if (! data)
return -ENOMEM; return -ENOMEM;
err = -EFAULT;
/* id, type, access, count */ \ /* id, type, access, count */ \
if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) || if (copy_from_user(&data->id, &data32->id, sizeof(data->id)) ||
copy_from_user(&data->type, &data32->type, 3 * sizeof(u32))) copy_from_user(&data->type, &data32->type, 3 * sizeof(u32)))
goto error; return -EFAULT;
if (get_user(data->owner, &data32->owner)) if (get_user(data->owner, &data32->owner))
goto error; return -EFAULT;
switch (data->type) { switch (data->type) {
case SNDRV_CTL_ELEM_TYPE_BOOLEAN: case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
case SNDRV_CTL_ELEM_TYPE_INTEGER: case SNDRV_CTL_ELEM_TYPE_INTEGER:
if (get_user(data->value.integer.min, &data32->value.integer.min) || if (get_user(data->value.integer.min, &data32->value.integer.min) ||
get_user(data->value.integer.max, &data32->value.integer.max) || get_user(data->value.integer.max, &data32->value.integer.max) ||
get_user(data->value.integer.step, &data32->value.integer.step)) get_user(data->value.integer.step, &data32->value.integer.step))
goto error; return -EFAULT;
break; break;
case SNDRV_CTL_ELEM_TYPE_INTEGER64: case SNDRV_CTL_ELEM_TYPE_INTEGER64:
if (copy_from_user(&data->value.integer64, if (copy_from_user(&data->value.integer64,
&data32->value.integer64, &data32->value.integer64,
sizeof(data->value.integer64))) sizeof(data->value.integer64)))
goto error; return -EFAULT;
break; break;
case SNDRV_CTL_ELEM_TYPE_ENUMERATED: case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
if (copy_from_user(&data->value.enumerated, if (copy_from_user(&data->value.enumerated,
&data32->value.enumerated, &data32->value.enumerated,
sizeof(data->value.enumerated))) sizeof(data->value.enumerated)))
goto error; return -EFAULT;
data->value.enumerated.names_ptr = data->value.enumerated.names_ptr =
(uintptr_t)compat_ptr(data->value.enumerated.names_ptr); (uintptr_t)compat_ptr(data->value.enumerated.names_ptr);
break; break;
default: default:
break; break;
} }
err = snd_ctl_elem_add(file, data, replace); return snd_ctl_elem_add(file, data, replace);
error:
kfree(data);
return err;
} }
enum { enum {
...@@ -468,16 +446,13 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns ...@@ -468,16 +446,13 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
#endif /* CONFIG_X86_X32_ABI */ #endif /* CONFIG_X86_X32_ABI */
} }
down_read(&snd_ioctl_rwsem); guard(rwsem_read)(&snd_ioctl_rwsem);
list_for_each_entry(p, &snd_control_compat_ioctls, list) { list_for_each_entry(p, &snd_control_compat_ioctls, list) {
if (p->fioctl) { if (p->fioctl) {
err = p->fioctl(ctl->card, ctl, cmd, arg); err = p->fioctl(ctl->card, ctl, cmd, arg);
if (err != -ENOIOCTLCMD) { if (err != -ENOIOCTLCMD)
up_read(&snd_ioctl_rwsem);
return err; return err;
}
} }
} }
up_read(&snd_ioctl_rwsem);
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
...@@ -147,29 +147,27 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access, ...@@ -147,29 +147,27 @@ static void snd_ctl_led_set_state(struct snd_card *card, unsigned int access,
return; return;
route = -1; route = -1;
found = false; found = false;
mutex_lock(&snd_ctl_led_mutex); scoped_guard(mutex, &snd_ctl_led_mutex) {
/* the card may not be registered (active) at this point */ /* the card may not be registered (active) at this point */
if (card && !snd_ctl_led_card_valid[card->number]) { if (card && !snd_ctl_led_card_valid[card->number])
mutex_unlock(&snd_ctl_led_mutex); return;
return; list_for_each_entry(lctl, &led->controls, list) {
} if (lctl->kctl == kctl && lctl->index_offset == ioff)
list_for_each_entry(lctl, &led->controls, list) { found = true;
if (lctl->kctl == kctl && lctl->index_offset == ioff)
found = true;
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
}
if (!found && kctl && card) {
lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
if (lctl) {
lctl->card = card;
lctl->access = access;
lctl->kctl = kctl;
lctl->index_offset = ioff;
list_add(&lctl->list, &led->controls);
UPDATE_ROUTE(route, snd_ctl_led_get(lctl)); UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
} }
if (!found && kctl && card) {
lctl = kzalloc(sizeof(*lctl), GFP_KERNEL);
if (lctl) {
lctl->card = card;
lctl->access = access;
lctl->kctl = kctl;
lctl->index_offset = ioff;
list_add(&lctl->list, &led->controls);
UPDATE_ROUTE(route, snd_ctl_led_get(lctl));
}
}
} }
mutex_unlock(&snd_ctl_led_mutex);
switch (led->mode) { switch (led->mode) {
case MODE_OFF: route = 1; break; case MODE_OFF: route = 1; break;
case MODE_ON: route = 0; break; case MODE_ON: route = 0; break;
...@@ -201,14 +199,13 @@ static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int i ...@@ -201,14 +199,13 @@ static unsigned int snd_ctl_led_remove(struct snd_kcontrol *kctl, unsigned int i
struct snd_ctl_led_ctl *lctl; struct snd_ctl_led_ctl *lctl;
unsigned int ret = 0; unsigned int ret = 0;
mutex_lock(&snd_ctl_led_mutex); guard(mutex)(&snd_ctl_led_mutex);
lctl = snd_ctl_led_find(kctl, ioff); lctl = snd_ctl_led_find(kctl, ioff);
if (lctl && (access == 0 || access != lctl->access)) { if (lctl && (access == 0 || access != lctl->access)) {
ret = lctl->access; ret = lctl->access;
list_del(&lctl->list); list_del(&lctl->list);
kfree(lctl); kfree(lctl);
} }
mutex_unlock(&snd_ctl_led_mutex);
return ret; return ret;
} }
...@@ -239,44 +236,36 @@ static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask, ...@@ -239,44 +236,36 @@ static void snd_ctl_led_notify(struct snd_card *card, unsigned int mask,
} }
} }
DEFINE_FREE(snd_card_unref, struct snd_card *, if (_T) snd_card_unref(_T))
static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id, static int snd_ctl_led_set_id(int card_number, struct snd_ctl_elem_id *id,
unsigned int group, bool set) unsigned int group, bool set)
{ {
struct snd_card *card; struct snd_card *card __free(snd_card_unref) = NULL;
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct snd_kcontrol_volatile *vd; struct snd_kcontrol_volatile *vd;
unsigned int ioff, access, new_access; unsigned int ioff, access, new_access;
int err = 0;
card = snd_card_ref(card_number); card = snd_card_ref(card_number);
if (card) { if (!card)
down_write(&card->controls_rwsem); return -ENXIO;
kctl = snd_ctl_find_id_locked(card, id); guard(rwsem_write)(&card->controls_rwsem);
if (kctl) { kctl = snd_ctl_find_id_locked(card, id);
ioff = snd_ctl_get_ioff(kctl, id); if (!kctl)
vd = &kctl->vd[ioff]; return -ENOENT;
access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK; ioff = snd_ctl_get_ioff(kctl, id);
if (access != 0 && access != group_to_access(group)) { vd = &kctl->vd[ioff];
err = -EXDEV; access = vd->access & SNDRV_CTL_ELEM_ACCESS_LED_MASK;
goto unlock; if (access != 0 && access != group_to_access(group))
} return -EXDEV;
new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK; new_access = vd->access & ~SNDRV_CTL_ELEM_ACCESS_LED_MASK;
if (set) if (set)
new_access |= group_to_access(group); new_access |= group_to_access(group);
if (new_access != vd->access) { if (new_access != vd->access) {
vd->access = new_access; vd->access = new_access;
snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff); snd_ctl_led_notify(card, SNDRV_CTL_EVENT_MASK_INFO, kctl, ioff);
}
} else {
err = -ENOENT;
}
unlock:
up_write(&card->controls_rwsem);
snd_card_unref(card);
} else {
err = -ENXIO;
} }
return err; return 0;
} }
static void snd_ctl_led_refresh(void) static void snd_ctl_led_refresh(void)
...@@ -312,7 +301,7 @@ static void snd_ctl_led_clean(struct snd_card *card) ...@@ -312,7 +301,7 @@ static void snd_ctl_led_clean(struct snd_card *card)
static int snd_ctl_led_reset(int card_number, unsigned int group) static int snd_ctl_led_reset(int card_number, unsigned int group)
{ {
struct snd_card *card; struct snd_card *card __free(snd_card_unref) = NULL;
struct snd_ctl_led *led; struct snd_ctl_led *led;
struct snd_ctl_led_ctl *lctl; struct snd_ctl_led_ctl *lctl;
struct snd_kcontrol_volatile *vd; struct snd_kcontrol_volatile *vd;
...@@ -322,26 +311,22 @@ static int snd_ctl_led_reset(int card_number, unsigned int group) ...@@ -322,26 +311,22 @@ static int snd_ctl_led_reset(int card_number, unsigned int group)
if (!card) if (!card)
return -ENXIO; return -ENXIO;
mutex_lock(&snd_ctl_led_mutex); scoped_guard(mutex, &snd_ctl_led_mutex) {
if (!snd_ctl_led_card_valid[card_number]) { if (!snd_ctl_led_card_valid[card_number])
mutex_unlock(&snd_ctl_led_mutex); return -ENXIO;
snd_card_unref(card); led = &snd_ctl_leds[group];
return -ENXIO;
}
led = &snd_ctl_leds[group];
repeat: repeat:
list_for_each_entry(lctl, &led->controls, list) list_for_each_entry(lctl, &led->controls, list)
if (lctl->card == card) { if (lctl->card == card) {
vd = &lctl->kctl->vd[lctl->index_offset]; vd = &lctl->kctl->vd[lctl->index_offset];
vd->access &= ~group_to_access(group); vd->access &= ~group_to_access(group);
snd_ctl_led_ctl_destroy(lctl); snd_ctl_led_ctl_destroy(lctl);
change = true; change = true;
goto repeat; goto repeat;
} }
mutex_unlock(&snd_ctl_led_mutex); }
if (change) if (change)
snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0); snd_ctl_led_set_state(NULL, group_to_access(group), NULL, 0);
snd_card_unref(card);
return 0; return 0;
} }
...@@ -353,9 +338,8 @@ static void snd_ctl_led_register(struct snd_card *card) ...@@ -353,9 +338,8 @@ static void snd_ctl_led_register(struct snd_card *card)
if (snd_BUG_ON(card->number < 0 || if (snd_BUG_ON(card->number < 0 ||
card->number >= ARRAY_SIZE(snd_ctl_led_card_valid))) card->number >= ARRAY_SIZE(snd_ctl_led_card_valid)))
return; return;
mutex_lock(&snd_ctl_led_mutex); scoped_guard(mutex, &snd_ctl_led_mutex)
snd_ctl_led_card_valid[card->number] = true; snd_ctl_led_card_valid[card->number] = true;
mutex_unlock(&snd_ctl_led_mutex);
/* the register callback is already called with held card->controls_rwsem */ /* the register callback is already called with held card->controls_rwsem */
list_for_each_entry(kctl, &card->controls, list) list_for_each_entry(kctl, &card->controls, list)
for (ioff = 0; ioff < kctl->count; ioff++) for (ioff = 0; ioff < kctl->count; ioff++)
...@@ -367,10 +351,10 @@ static void snd_ctl_led_register(struct snd_card *card) ...@@ -367,10 +351,10 @@ static void snd_ctl_led_register(struct snd_card *card)
static void snd_ctl_led_disconnect(struct snd_card *card) static void snd_ctl_led_disconnect(struct snd_card *card)
{ {
snd_ctl_led_sysfs_remove(card); snd_ctl_led_sysfs_remove(card);
mutex_lock(&snd_ctl_led_mutex); scoped_guard(mutex, &snd_ctl_led_mutex) {
snd_ctl_led_card_valid[card->number] = false; snd_ctl_led_card_valid[card->number] = false;
snd_ctl_led_clean(card); snd_ctl_led_clean(card);
mutex_unlock(&snd_ctl_led_mutex); }
snd_ctl_led_refresh(); snd_ctl_led_refresh();
} }
...@@ -430,9 +414,8 @@ static ssize_t mode_store(struct device *dev, ...@@ -430,9 +414,8 @@ static ssize_t mode_store(struct device *dev,
else else
return count; return count;
mutex_lock(&snd_ctl_led_mutex); scoped_guard(mutex, &snd_ctl_led_mutex)
led->mode = mode; led->mode = mode;
mutex_unlock(&snd_ctl_led_mutex);
snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0); snd_ctl_led_set_state(NULL, group_to_access(led->group), NULL, 0);
return count; return count;
...@@ -615,15 +598,15 @@ static ssize_t list_show(struct device *dev, ...@@ -615,15 +598,15 @@ static ssize_t list_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev); struct snd_ctl_led_card *led_card = container_of(dev, struct snd_ctl_led_card, dev);
struct snd_card *card; struct snd_card *card __free(snd_card_unref) = NULL;
struct snd_ctl_led_ctl *lctl; struct snd_ctl_led_ctl *lctl;
size_t l = 0; size_t l = 0;
card = snd_card_ref(led_card->number); card = snd_card_ref(led_card->number);
if (!card) if (!card)
return -ENXIO; return -ENXIO;
down_read(&card->controls_rwsem); guard(rwsem_read)(&card->controls_rwsem);
mutex_lock(&snd_ctl_led_mutex); guard(mutex)(&snd_ctl_led_mutex);
if (snd_ctl_led_card_valid[led_card->number]) { if (snd_ctl_led_card_valid[led_card->number]) {
list_for_each_entry(lctl, &led_card->led->controls, list) { list_for_each_entry(lctl, &led_card->led->controls, list) {
if (lctl->card != card) if (lctl->card != card)
...@@ -634,9 +617,6 @@ static ssize_t list_show(struct device *dev, ...@@ -634,9 +617,6 @@ static ssize_t list_show(struct device *dev,
lctl->kctl->id.numid + lctl->index_offset); lctl->kctl->id.numid + lctl->index_offset);
} }
} }
mutex_unlock(&snd_ctl_led_mutex);
up_read(&card->controls_rwsem);
snd_card_unref(card);
return l; return l;
} }
......
...@@ -35,12 +35,12 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) ...@@ -35,12 +35,12 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
unsigned long ticks; unsigned long ticks;
enum hrtimer_restart ret = HRTIMER_NORESTART; enum hrtimer_restart ret = HRTIMER_NORESTART;
spin_lock(&t->lock); scoped_guard(spinlock, &t->lock) {
if (!t->running) if (!t->running)
goto out; /* fast path */ return HRTIMER_NORESTART; /* fast path */
stime->in_callback = true; stime->in_callback = true;
ticks = t->sticks; ticks = t->sticks;
spin_unlock(&t->lock); }
/* calculate the drift */ /* calculate the drift */
delta = ktime_sub(hrt->base->get_time(), hrtimer_get_expires(hrt)); delta = ktime_sub(hrt->base->get_time(), hrtimer_get_expires(hrt));
...@@ -49,15 +49,13 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) ...@@ -49,15 +49,13 @@ static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
snd_timer_interrupt(stime->timer, ticks); snd_timer_interrupt(stime->timer, ticks);
spin_lock(&t->lock); guard(spinlock)(&t->lock);
if (t->running) { if (t->running) {
hrtimer_add_expires_ns(hrt, t->sticks * resolution); hrtimer_add_expires_ns(hrt, t->sticks * resolution);
ret = HRTIMER_RESTART; ret = HRTIMER_RESTART;
} }
stime->in_callback = false; stime->in_callback = false;
out:
spin_unlock(&t->lock);
return ret; return ret;
} }
...@@ -80,10 +78,10 @@ static int snd_hrtimer_close(struct snd_timer *t) ...@@ -80,10 +78,10 @@ static int snd_hrtimer_close(struct snd_timer *t)
struct snd_hrtimer *stime = t->private_data; struct snd_hrtimer *stime = t->private_data;
if (stime) { if (stime) {
spin_lock_irq(&t->lock); scoped_guard(spinlock_irq, &t->lock) {
t->running = 0; /* just to be sure */ t->running = 0; /* just to be sure */
stime->in_callback = 1; /* skip start/stop */ stime->in_callback = 1; /* skip start/stop */
spin_unlock_irq(&t->lock); }
hrtimer_cancel(&stime->hrt); hrtimer_cancel(&stime->hrt);
kfree(stime); kfree(stime);
......
...@@ -149,12 +149,12 @@ static int snd_hwdep_release(struct inode *inode, struct file * file) ...@@ -149,12 +149,12 @@ static int snd_hwdep_release(struct inode *inode, struct file * file)
struct snd_hwdep *hw = file->private_data; struct snd_hwdep *hw = file->private_data;
struct module *mod = hw->card->module; struct module *mod = hw->card->module;
mutex_lock(&hw->open_mutex); scoped_guard(mutex, &hw->open_mutex) {
if (hw->ops.release) if (hw->ops.release)
err = hw->ops.release(hw, file); err = hw->ops.release(hw, file);
if (hw->used > 0) if (hw->used > 0)
hw->used--; hw->used--;
mutex_unlock(&hw->open_mutex); }
wake_up(&hw->open_wait); wake_up(&hw->open_wait);
snd_card_file_remove(hw->card, file); snd_card_file_remove(hw->card, file);
...@@ -272,23 +272,23 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, ...@@ -272,23 +272,23 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
if (get_user(device, (int __user *)arg)) if (get_user(device, (int __user *)arg))
return -EFAULT; return -EFAULT;
mutex_lock(&register_mutex);
scoped_guard(mutex, &register_mutex) {
if (device < 0) if (device < 0)
device = 0; device = 0;
else if (device < SNDRV_MINOR_HWDEPS) else if (device < SNDRV_MINOR_HWDEPS)
device++; device++;
else else
device = SNDRV_MINOR_HWDEPS; device = SNDRV_MINOR_HWDEPS;
while (device < SNDRV_MINOR_HWDEPS) { while (device < SNDRV_MINOR_HWDEPS) {
if (snd_hwdep_search(card, device)) if (snd_hwdep_search(card, device))
break; break;
device++; device++;
}
if (device >= SNDRV_MINOR_HWDEPS)
device = -1;
} }
if (device >= SNDRV_MINOR_HWDEPS)
device = -1;
mutex_unlock(&register_mutex);
if (put_user(device, (int __user *)arg)) if (put_user(device, (int __user *)arg))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -296,19 +296,18 @@ static int snd_hwdep_control_ioctl(struct snd_card *card, ...@@ -296,19 +296,18 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
case SNDRV_CTL_IOCTL_HWDEP_INFO: case SNDRV_CTL_IOCTL_HWDEP_INFO:
{ {
struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg; struct snd_hwdep_info __user *info = (struct snd_hwdep_info __user *)arg;
int device, err; int device;
struct snd_hwdep *hwdep; struct snd_hwdep *hwdep;
if (get_user(device, &info->device)) if (get_user(device, &info->device))
return -EFAULT; return -EFAULT;
mutex_lock(&register_mutex); scoped_guard(mutex, &register_mutex) {
hwdep = snd_hwdep_search(card, device); hwdep = snd_hwdep_search(card, device);
if (hwdep) if (!hwdep)
err = snd_hwdep_info(hwdep, info); return -ENXIO;
else return snd_hwdep_info(hwdep, info);
err = -ENXIO; }
mutex_unlock(&register_mutex); break;
return err;
} }
} }
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
...@@ -422,11 +421,9 @@ static int snd_hwdep_dev_register(struct snd_device *device) ...@@ -422,11 +421,9 @@ static int snd_hwdep_dev_register(struct snd_device *device)
struct snd_card *card = hwdep->card; struct snd_card *card = hwdep->card;
int err; int err;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
if (snd_hwdep_search(card, hwdep->device)) { if (snd_hwdep_search(card, hwdep->device))
mutex_unlock(&register_mutex);
return -EBUSY; return -EBUSY;
}
list_add_tail(&hwdep->list, &snd_hwdep_devices); list_add_tail(&hwdep->list, &snd_hwdep_devices);
err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP, err = snd_register_device(SNDRV_DEVICE_TYPE_HWDEP,
hwdep->card, hwdep->device, hwdep->card, hwdep->device,
...@@ -434,7 +431,6 @@ static int snd_hwdep_dev_register(struct snd_device *device) ...@@ -434,7 +431,6 @@ static int snd_hwdep_dev_register(struct snd_device *device)
if (err < 0) { if (err < 0) {
dev_err(hwdep->dev, "unable to register\n"); dev_err(hwdep->dev, "unable to register\n");
list_del(&hwdep->list); list_del(&hwdep->list);
mutex_unlock(&register_mutex);
return err; return err;
} }
...@@ -454,7 +450,6 @@ static int snd_hwdep_dev_register(struct snd_device *device) ...@@ -454,7 +450,6 @@ static int snd_hwdep_dev_register(struct snd_device *device)
hwdep->ossreg = 1; hwdep->ossreg = 1;
} }
#endif #endif
mutex_unlock(&register_mutex);
return 0; return 0;
} }
...@@ -464,12 +459,10 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) ...@@ -464,12 +459,10 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
if (snd_BUG_ON(!hwdep)) if (snd_BUG_ON(!hwdep))
return -ENXIO; return -ENXIO;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep) { if (snd_hwdep_search(hwdep->card, hwdep->device) != hwdep)
mutex_unlock(&register_mutex);
return -EINVAL; return -EINVAL;
} guard(mutex)(&hwdep->open_mutex);
mutex_lock(&hwdep->open_mutex);
wake_up(&hwdep->open_wait); wake_up(&hwdep->open_wait);
#ifdef CONFIG_SND_OSSEMUL #ifdef CONFIG_SND_OSSEMUL
if (hwdep->ossreg) if (hwdep->ossreg)
...@@ -477,8 +470,6 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device) ...@@ -477,8 +470,6 @@ static int snd_hwdep_dev_disconnect(struct snd_device *device)
#endif #endif
snd_unregister_device(hwdep->dev); snd_unregister_device(hwdep->dev);
list_del_init(&hwdep->list); list_del_init(&hwdep->list);
mutex_unlock(&hwdep->open_mutex);
mutex_unlock(&register_mutex);
return 0; return 0;
} }
...@@ -492,11 +483,10 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry, ...@@ -492,11 +483,10 @@ static void snd_hwdep_proc_read(struct snd_info_entry *entry,
{ {
struct snd_hwdep *hwdep; struct snd_hwdep *hwdep;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
list_for_each_entry(hwdep, &snd_hwdep_devices, list) list_for_each_entry(hwdep, &snd_hwdep_devices, list)
snd_iprintf(buffer, "%02i-%02i: %s\n", snd_iprintf(buffer, "%02i-%02i: %s\n",
hwdep->card->number, hwdep->device, hwdep->name); hwdep->card->number, hwdep->device, hwdep->name);
mutex_unlock(&register_mutex);
} }
static struct snd_info_entry *snd_hwdep_proc_entry; static struct snd_info_entry *snd_hwdep_proc_entry;
......
...@@ -105,17 +105,15 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) ...@@ -105,17 +105,15 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
{ {
struct snd_info_private_data *data; struct snd_info_private_data *data;
struct snd_info_entry *entry; struct snd_info_entry *entry;
loff_t ret = -EINVAL, size; loff_t size;
data = file->private_data; data = file->private_data;
entry = data->entry; entry = data->entry;
mutex_lock(&entry->access); guard(mutex)(&entry->access);
if (entry->c.ops->llseek) { if (entry->c.ops->llseek)
ret = entry->c.ops->llseek(entry, return entry->c.ops->llseek(entry,
data->file_private_data, data->file_private_data,
file, offset, orig); file, offset, orig);
goto out;
}
size = entry->size; size = entry->size;
switch (orig) { switch (orig) {
...@@ -126,21 +124,18 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig) ...@@ -126,21 +124,18 @@ static loff_t snd_info_entry_llseek(struct file *file, loff_t offset, int orig)
break; break;
case SEEK_END: case SEEK_END:
if (!size) if (!size)
goto out; return -EINVAL;
offset += size; offset += size;
break; break;
default: default:
goto out; return -EINVAL;
} }
if (offset < 0) if (offset < 0)
goto out; return -EINVAL;
if (size && offset > size) if (size && offset > size)
offset = size; offset = size;
file->f_pos = offset; file->f_pos = offset;
ret = offset; return offset;
out:
mutex_unlock(&entry->access);
return ret;
} }
static ssize_t snd_info_entry_read(struct file *file, char __user *buffer, static ssize_t snd_info_entry_read(struct file *file, char __user *buffer,
...@@ -238,10 +233,10 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) ...@@ -238,10 +233,10 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
struct snd_info_private_data *data; struct snd_info_private_data *data;
int mode, err; int mode, err;
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
err = alloc_info_private(entry, &data); err = alloc_info_private(entry, &data);
if (err < 0) if (err < 0)
goto unlock; return err;
mode = file->f_flags & O_ACCMODE; mode = file->f_flags & O_ACCMODE;
if (((mode == O_RDONLY || mode == O_RDWR) && !entry->c.ops->read) || if (((mode == O_RDONLY || mode == O_RDWR) && !entry->c.ops->read) ||
...@@ -257,14 +252,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file) ...@@ -257,14 +252,11 @@ static int snd_info_entry_open(struct inode *inode, struct file *file)
} }
file->private_data = data; file->private_data = data;
mutex_unlock(&info_mutex);
return 0; return 0;
error: error:
kfree(data); kfree(data);
module_put(entry->module); module_put(entry->module);
unlock:
mutex_unlock(&info_mutex);
return err; return err;
} }
...@@ -306,7 +298,6 @@ static ssize_t snd_info_text_entry_write(struct file *file, ...@@ -306,7 +298,6 @@ static ssize_t snd_info_text_entry_write(struct file *file,
struct snd_info_buffer *buf; struct snd_info_buffer *buf;
loff_t pos; loff_t pos;
size_t next; size_t next;
int err = 0;
if (!entry->c.text.write) if (!entry->c.text.write)
return -EIO; return -EIO;
...@@ -317,34 +308,24 @@ static ssize_t snd_info_text_entry_write(struct file *file, ...@@ -317,34 +308,24 @@ static ssize_t snd_info_text_entry_write(struct file *file,
/* don't handle too large text inputs */ /* don't handle too large text inputs */
if (next > 16 * 1024) if (next > 16 * 1024)
return -EIO; return -EIO;
mutex_lock(&entry->access); guard(mutex)(&entry->access);
buf = data->wbuffer; buf = data->wbuffer;
if (!buf) { if (!buf) {
data->wbuffer = buf = kzalloc(sizeof(*buf), GFP_KERNEL); data->wbuffer = buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (!buf) { if (!buf)
err = -ENOMEM; return -ENOMEM;
goto error;
}
} }
if (next > buf->len) { if (next > buf->len) {
char *nbuf = kvzalloc(PAGE_ALIGN(next), GFP_KERNEL); char *nbuf = kvzalloc(PAGE_ALIGN(next), GFP_KERNEL);
if (!nbuf) { if (!nbuf)
err = -ENOMEM; return -ENOMEM;
goto error;
}
kvfree(buf->buffer); kvfree(buf->buffer);
buf->buffer = nbuf; buf->buffer = nbuf;
buf->len = PAGE_ALIGN(next); buf->len = PAGE_ALIGN(next);
} }
if (copy_from_user(buf->buffer + pos, buffer, count)) { if (copy_from_user(buf->buffer + pos, buffer, count))
err = -EFAULT; return -EFAULT;
goto error;
}
buf->size = next; buf->size = next;
error:
mutex_unlock(&entry->access);
if (err < 0)
return err;
*offset = next; *offset = next;
return count; return count;
} }
...@@ -369,10 +350,10 @@ static int snd_info_text_entry_open(struct inode *inode, struct file *file) ...@@ -369,10 +350,10 @@ static int snd_info_text_entry_open(struct inode *inode, struct file *file)
struct snd_info_private_data *data; struct snd_info_private_data *data;
int err; int err;
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
err = alloc_info_private(entry, &data); err = alloc_info_private(entry, &data);
if (err < 0) if (err < 0)
goto unlock; return err;
data->rbuffer = kzalloc(sizeof(*data->rbuffer), GFP_KERNEL); data->rbuffer = kzalloc(sizeof(*data->rbuffer), GFP_KERNEL);
if (!data->rbuffer) { if (!data->rbuffer) {
...@@ -386,15 +367,12 @@ static int snd_info_text_entry_open(struct inode *inode, struct file *file) ...@@ -386,15 +367,12 @@ static int snd_info_text_entry_open(struct inode *inode, struct file *file)
err = single_open(file, snd_info_seq_show, data); err = single_open(file, snd_info_seq_show, data);
if (err < 0) if (err < 0)
goto error; goto error;
mutex_unlock(&info_mutex);
return 0; return 0;
error: error:
kfree(data->rbuffer); kfree(data->rbuffer);
kfree(data); kfree(data);
module_put(entry->module); module_put(entry->module);
unlock:
mutex_unlock(&info_mutex);
return err; return err;
} }
...@@ -549,7 +527,7 @@ int snd_info_card_register(struct snd_card *card) ...@@ -549,7 +527,7 @@ int snd_info_card_register(struct snd_card *card)
*/ */
void snd_info_card_id_change(struct snd_card *card) void snd_info_card_id_change(struct snd_card *card)
{ {
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
if (card->proc_root_link) { if (card->proc_root_link) {
proc_remove(card->proc_root_link); proc_remove(card->proc_root_link);
card->proc_root_link = NULL; card->proc_root_link = NULL;
...@@ -558,7 +536,6 @@ void snd_info_card_id_change(struct snd_card *card) ...@@ -558,7 +536,6 @@ void snd_info_card_id_change(struct snd_card *card)
card->proc_root_link = proc_symlink(card->id, card->proc_root_link = proc_symlink(card->id,
snd_proc_root->p, snd_proc_root->p,
card->proc_root->name); card->proc_root->name);
mutex_unlock(&info_mutex);
} }
/* /*
...@@ -574,12 +551,11 @@ void snd_info_card_disconnect(struct snd_card *card) ...@@ -574,12 +551,11 @@ void snd_info_card_disconnect(struct snd_card *card)
if (card->proc_root) if (card->proc_root)
proc_remove(card->proc_root->p); proc_remove(card->proc_root->p);
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
if (card->proc_root) if (card->proc_root)
snd_info_clear_entries(card->proc_root); snd_info_clear_entries(card->proc_root);
card->proc_root_link = NULL; card->proc_root_link = NULL;
card->proc_root = NULL; card->proc_root = NULL;
mutex_unlock(&info_mutex);
} }
/* /*
...@@ -703,9 +679,8 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent, ...@@ -703,9 +679,8 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent,
entry->parent = parent; entry->parent = parent;
entry->module = module; entry->module = module;
if (parent) { if (parent) {
mutex_lock(&parent->access); guard(mutex)(&parent->access);
list_add_tail(&entry->list, &parent->children); list_add_tail(&entry->list, &parent->children);
mutex_unlock(&parent->access);
} }
return entry; return entry;
} }
...@@ -775,9 +750,8 @@ void snd_info_free_entry(struct snd_info_entry * entry) ...@@ -775,9 +750,8 @@ void snd_info_free_entry(struct snd_info_entry * entry)
return; return;
if (entry->p) { if (entry->p) {
proc_remove(entry->p); proc_remove(entry->p);
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
snd_info_clear_entries(entry); snd_info_clear_entries(entry);
mutex_unlock(&info_mutex);
} }
/* free all children at first */ /* free all children at first */
...@@ -786,9 +760,8 @@ void snd_info_free_entry(struct snd_info_entry * entry) ...@@ -786,9 +760,8 @@ void snd_info_free_entry(struct snd_info_entry * entry)
p = entry->parent; p = entry->parent;
if (p) { if (p) {
mutex_lock(&p->access); guard(mutex)(&p->access);
list_del(&entry->list); list_del(&entry->list);
mutex_unlock(&p->access);
} }
kfree(entry->name); kfree(entry->name);
if (entry->private_free) if (entry->private_free)
...@@ -804,15 +777,13 @@ static int __snd_info_register(struct snd_info_entry *entry) ...@@ -804,15 +777,13 @@ static int __snd_info_register(struct snd_info_entry *entry)
if (snd_BUG_ON(!entry)) if (snd_BUG_ON(!entry))
return -ENXIO; return -ENXIO;
root = entry->parent == NULL ? snd_proc_root->p : entry->parent->p; root = entry->parent == NULL ? snd_proc_root->p : entry->parent->p;
mutex_lock(&info_mutex); guard(mutex)(&info_mutex);
if (entry->p || !root) if (entry->p || !root)
goto unlock; return 0;
if (S_ISDIR(entry->mode)) { if (S_ISDIR(entry->mode)) {
p = proc_mkdir_mode(entry->name, entry->mode, root); p = proc_mkdir_mode(entry->name, entry->mode, root);
if (!p) { if (!p)
mutex_unlock(&info_mutex);
return -ENOMEM; return -ENOMEM;
}
} else { } else {
const struct proc_ops *ops; const struct proc_ops *ops;
if (entry->content == SNDRV_INFO_CONTENT_DATA) if (entry->content == SNDRV_INFO_CONTENT_DATA)
...@@ -821,15 +792,11 @@ static int __snd_info_register(struct snd_info_entry *entry) ...@@ -821,15 +792,11 @@ static int __snd_info_register(struct snd_info_entry *entry)
ops = &snd_info_text_entry_ops; ops = &snd_info_text_entry_ops;
p = proc_create_data(entry->name, entry->mode, root, p = proc_create_data(entry->name, entry->mode, root,
ops, entry); ops, entry);
if (!p) { if (!p)
mutex_unlock(&info_mutex);
return -ENOMEM; return -ENOMEM;
}
proc_set_size(p, entry->size); proc_set_size(p, entry->size);
} }
entry->p = p; entry->p = p;
unlock:
mutex_unlock(&info_mutex);
return 0; return 0;
} }
......
...@@ -29,20 +29,17 @@ int snd_oss_info_register(int dev, int num, char *string) ...@@ -29,20 +29,17 @@ int snd_oss_info_register(int dev, int num, char *string)
return -ENXIO; return -ENXIO;
if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS)) if (snd_BUG_ON(num < 0 || num >= SNDRV_CARDS))
return -ENXIO; return -ENXIO;
mutex_lock(&strings); guard(mutex)(&strings);
if (string == NULL) { if (string == NULL) {
x = snd_sndstat_strings[num][dev]; x = snd_sndstat_strings[num][dev];
kfree(x); kfree(x);
x = NULL; x = NULL;
} else { } else {
x = kstrdup(string, GFP_KERNEL); x = kstrdup(string, GFP_KERNEL);
if (x == NULL) { if (x == NULL)
mutex_unlock(&strings);
return -ENOMEM; return -ENOMEM;
}
} }
snd_sndstat_strings[num][dev] = x; snd_sndstat_strings[num][dev] = x;
mutex_unlock(&strings);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_oss_info_register); EXPORT_SYMBOL(snd_oss_info_register);
...@@ -53,7 +50,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d ...@@ -53,7 +50,7 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
char *str; char *str;
snd_iprintf(buf, "\n%s:", id); snd_iprintf(buf, "\n%s:", id);
mutex_lock(&strings); guard(mutex)(&strings);
for (idx = 0; idx < SNDRV_CARDS; idx++) { for (idx = 0; idx < SNDRV_CARDS; idx++) {
str = snd_sndstat_strings[idx][dev]; str = snd_sndstat_strings[idx][dev];
if (str) { if (str) {
...@@ -64,7 +61,6 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d ...@@ -64,7 +61,6 @@ static int snd_sndstat_show_strings(struct snd_info_buffer *buf, char *id, int d
snd_iprintf(buf, "%i: %s\n", idx, str); snd_iprintf(buf, "%i: %s\n", idx, str);
} }
} }
mutex_unlock(&strings);
if (ok < 0) if (ok < 0)
snd_iprintf(buf, " NOT ENABLED IN CONFIG\n"); snd_iprintf(buf, " NOT ENABLED IN CONFIG\n");
return ok; return ok;
......
This diff is collapsed.
...@@ -42,11 +42,9 @@ static int snd_jack_dev_disconnect(struct snd_device *device) ...@@ -42,11 +42,9 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
#ifdef CONFIG_SND_JACK_INPUT_DEV #ifdef CONFIG_SND_JACK_INPUT_DEV
struct snd_jack *jack = device->device_data; struct snd_jack *jack = device->device_data;
mutex_lock(&jack->input_dev_lock); guard(mutex)(&jack->input_dev_lock);
if (!jack->input_dev) { if (!jack->input_dev)
mutex_unlock(&jack->input_dev_lock);
return 0; return 0;
}
/* If the input device is registered with the input subsystem /* If the input device is registered with the input subsystem
* then we need to use a different deallocator. */ * then we need to use a different deallocator. */
...@@ -55,7 +53,6 @@ static int snd_jack_dev_disconnect(struct snd_device *device) ...@@ -55,7 +53,6 @@ static int snd_jack_dev_disconnect(struct snd_device *device)
else else
input_free_device(jack->input_dev); input_free_device(jack->input_dev);
jack->input_dev = NULL; jack->input_dev = NULL;
mutex_unlock(&jack->input_dev_lock);
#endif /* CONFIG_SND_JACK_INPUT_DEV */ #endif /* CONFIG_SND_JACK_INPUT_DEV */
return 0; return 0;
} }
...@@ -92,11 +89,9 @@ static int snd_jack_dev_register(struct snd_device *device) ...@@ -92,11 +89,9 @@ static int snd_jack_dev_register(struct snd_device *device)
snprintf(jack->name, sizeof(jack->name), "%s %s", snprintf(jack->name, sizeof(jack->name), "%s %s",
card->shortname, jack->id); card->shortname, jack->id);
mutex_lock(&jack->input_dev_lock); guard(mutex)(&jack->input_dev_lock);
if (!jack->input_dev) { if (!jack->input_dev)
mutex_unlock(&jack->input_dev_lock);
return 0; return 0;
}
jack->input_dev->name = jack->name; jack->input_dev->name = jack->name;
...@@ -121,7 +116,6 @@ static int snd_jack_dev_register(struct snd_device *device) ...@@ -121,7 +116,6 @@ static int snd_jack_dev_register(struct snd_device *device)
if (err == 0) if (err == 0)
jack->registered = 1; jack->registered = 1;
mutex_unlock(&jack->input_dev_lock);
return err; return err;
} }
#endif /* CONFIG_SND_JACK_INPUT_DEV */ #endif /* CONFIG_SND_JACK_INPUT_DEV */
...@@ -586,14 +580,9 @@ EXPORT_SYMBOL(snd_jack_new); ...@@ -586,14 +580,9 @@ EXPORT_SYMBOL(snd_jack_new);
void snd_jack_set_parent(struct snd_jack *jack, struct device *parent) void snd_jack_set_parent(struct snd_jack *jack, struct device *parent)
{ {
WARN_ON(jack->registered); WARN_ON(jack->registered);
mutex_lock(&jack->input_dev_lock); guard(mutex)(&jack->input_dev_lock);
if (!jack->input_dev) { if (jack->input_dev)
mutex_unlock(&jack->input_dev_lock); jack->input_dev->dev.parent = parent;
return;
}
jack->input_dev->dev.parent = parent;
mutex_unlock(&jack->input_dev_lock);
} }
EXPORT_SYMBOL(snd_jack_set_parent); EXPORT_SYMBOL(snd_jack_set_parent);
......
This diff is collapsed.
...@@ -377,7 +377,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, ...@@ -377,7 +377,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
snd_pcm_hw_param_t var, unsigned int best, snd_pcm_hw_param_t var, unsigned int best,
int *dir) int *dir)
{ {
struct snd_pcm_hw_params *save = NULL; struct snd_pcm_hw_params *save __free(kfree) = NULL;
int v; int v;
unsigned int saved_min; unsigned int saved_min;
int last = 0; int last = 0;
...@@ -404,38 +404,30 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, ...@@ -404,38 +404,30 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
saved_min = min; saved_min = min;
min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir); min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
if (min >= 0) { if (min >= 0) {
struct snd_pcm_hw_params *params1; struct snd_pcm_hw_params *params1 __free(kfree) = NULL;
if (max < 0) if (max < 0)
goto _end; goto _end;
if ((unsigned int)min == saved_min && mindir == valdir) if ((unsigned int)min == saved_min && mindir == valdir)
goto _end; goto _end;
params1 = kmalloc(sizeof(*params1), GFP_KERNEL); params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
if (params1 == NULL) { if (params1 == NULL)
kfree(save);
return -ENOMEM; return -ENOMEM;
}
*params1 = *save; *params1 = *save;
max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir); max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
if (max < 0) { if (max < 0)
kfree(params1);
goto _end; goto _end;
}
if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) { if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
*params = *params1; *params = *params1;
last = 1; last = 1;
} }
kfree(params1);
} else { } else {
*params = *save; *params = *save;
max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
if (max < 0) { if (max < 0)
kfree(save);
return max; return max;
}
last = 1; last = 1;
} }
_end: _end:
kfree(save);
if (last) if (last)
v = snd_pcm_hw_param_last(pcm, params, var, dir); v = snd_pcm_hw_param_last(pcm, params, var, dir);
else else
...@@ -789,7 +781,7 @@ static int choose_rate(struct snd_pcm_substream *substream, ...@@ -789,7 +781,7 @@ static int choose_rate(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, unsigned int best_rate) struct snd_pcm_hw_params *params, unsigned int best_rate)
{ {
const struct snd_interval *it; const struct snd_interval *it;
struct snd_pcm_hw_params *save; struct snd_pcm_hw_params *save __free(kfree) = NULL;
unsigned int rate, prev; unsigned int rate, prev;
save = kmalloc(sizeof(*save), GFP_KERNEL); save = kmalloc(sizeof(*save), GFP_KERNEL);
...@@ -808,10 +800,8 @@ static int choose_rate(struct snd_pcm_substream *substream, ...@@ -808,10 +800,8 @@ static int choose_rate(struct snd_pcm_substream *substream,
ret = snd_pcm_hw_param_set(substream, params, ret = snd_pcm_hw_param_set(substream, params,
SNDRV_PCM_HW_PARAM_RATE, SNDRV_PCM_HW_PARAM_RATE,
rate, 0); rate, 0);
if (ret == (int)rate) { if (ret == (int)rate)
kfree(save);
return rate; return rate;
}
*params = *save; *params = *save;
} }
prev = rate; prev = rate;
...@@ -821,7 +811,6 @@ static int choose_rate(struct snd_pcm_substream *substream, ...@@ -821,7 +811,6 @@ static int choose_rate(struct snd_pcm_substream *substream,
} }
/* not found, use the nearest rate */ /* not found, use the nearest rate */
kfree(save);
return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
} }
...@@ -1634,9 +1623,8 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size) ...@@ -1634,9 +1623,8 @@ static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
break; break;
result = 0; result = 0;
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
snd_pcm_stream_lock_irq(substream); scoped_guard(pcm_stream_lock_irq, substream)
state = runtime->state; state = runtime->state;
snd_pcm_stream_unlock_irq(substream);
if (state != SNDRV_PCM_STATE_RUNNING) { if (state != SNDRV_PCM_STATE_RUNNING) {
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
break; break;
...@@ -1847,7 +1835,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) ...@@ -1847,7 +1835,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
int err; int err;
int direct; int direct;
struct snd_pcm_hw_params *params; struct snd_pcm_hw_params *params __free(kfree) = NULL;
unsigned int formats = 0; unsigned int formats = 0;
const struct snd_mask *format_mask; const struct snd_mask *format_mask;
int fmt; int fmt;
...@@ -1873,7 +1861,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) ...@@ -1873,7 +1861,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
_snd_pcm_hw_params_any(params); _snd_pcm_hw_params_any(params);
err = snd_pcm_hw_refine(substream, params); err = snd_pcm_hw_refine(substream, params);
if (err < 0) if (err < 0)
goto error; return err;
format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT); format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
for (fmt = 0; fmt < 32; ++fmt) { for (fmt = 0; fmt < 32; ++fmt) {
if (snd_mask_test(format_mask, fmt)) { if (snd_mask_test(format_mask, fmt)) {
...@@ -1883,9 +1871,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) ...@@ -1883,9 +1871,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
} }
} }
error: return formats;
kfree(params);
return err < 0 ? err : formats;
} }
static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
...@@ -2347,7 +2333,7 @@ static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, ...@@ -2347,7 +2333,7 @@ static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
{ {
struct snd_pcm_oss_setup *setup; struct snd_pcm_oss_setup *setup;
mutex_lock(&pcm->streams[stream].oss.setup_mutex); guard(mutex)(&pcm->streams[stream].oss.setup_mutex);
do { do {
for (setup = pcm->streams[stream].oss.setup_list; setup; for (setup = pcm->streams[stream].oss.setup_list; setup;
setup = setup->next) { setup = setup->next) {
...@@ -2358,7 +2344,6 @@ static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, ...@@ -2358,7 +2344,6 @@ static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
out: out:
if (setup) if (setup)
*rsetup = *setup; *rsetup = *setup;
mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
} }
static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
...@@ -2853,23 +2838,23 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait) ...@@ -2853,23 +2838,23 @@ static __poll_t snd_pcm_oss_poll(struct file *file, poll_table * wait)
if (psubstream != NULL) { if (psubstream != NULL) {
struct snd_pcm_runtime *runtime = psubstream->runtime; struct snd_pcm_runtime *runtime = psubstream->runtime;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(psubstream); scoped_guard(pcm_stream_lock_irq, psubstream) {
if (runtime->state != SNDRV_PCM_STATE_DRAINING && if (runtime->state != SNDRV_PCM_STATE_DRAINING &&
(runtime->state != SNDRV_PCM_STATE_RUNNING || (runtime->state != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_playback_ready(psubstream))) snd_pcm_oss_playback_ready(psubstream)))
mask |= EPOLLOUT | EPOLLWRNORM; mask |= EPOLLOUT | EPOLLWRNORM;
snd_pcm_stream_unlock_irq(psubstream); }
} }
if (csubstream != NULL) { if (csubstream != NULL) {
struct snd_pcm_runtime *runtime = csubstream->runtime; struct snd_pcm_runtime *runtime = csubstream->runtime;
snd_pcm_state_t ostate; snd_pcm_state_t ostate;
poll_wait(file, &runtime->sleep, wait); poll_wait(file, &runtime->sleep, wait);
snd_pcm_stream_lock_irq(csubstream); scoped_guard(pcm_stream_lock_irq, csubstream) {
ostate = runtime->state; ostate = runtime->state;
if (ostate != SNDRV_PCM_STATE_RUNNING || if (ostate != SNDRV_PCM_STATE_RUNNING ||
snd_pcm_oss_capture_ready(csubstream)) snd_pcm_oss_capture_ready(csubstream))
mask |= EPOLLIN | EPOLLRDNORM; mask |= EPOLLIN | EPOLLRDNORM;
snd_pcm_stream_unlock_irq(csubstream); }
if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) { if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
struct snd_pcm_oss_file ofile; struct snd_pcm_oss_file ofile;
memset(&ofile, 0, sizeof(ofile)); memset(&ofile, 0, sizeof(ofile));
...@@ -2964,7 +2949,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, ...@@ -2964,7 +2949,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
{ {
struct snd_pcm_str *pstr = entry->private_data; struct snd_pcm_str *pstr = entry->private_data;
struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
mutex_lock(&pstr->oss.setup_mutex); guard(mutex)(&pstr->oss.setup_mutex);
while (setup) { while (setup) {
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
setup->task_name, setup->task_name,
...@@ -2978,7 +2963,6 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, ...@@ -2978,7 +2963,6 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
setup->nosilence ? " no-silence" : ""); setup->nosilence ? " no-silence" : "");
setup = setup->next; setup = setup->next;
} }
mutex_unlock(&pstr->oss.setup_mutex);
} }
static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
...@@ -3004,12 +2988,11 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -3004,12 +2988,11 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
struct snd_pcm_oss_setup *setup, *setup1, template; struct snd_pcm_oss_setup *setup, *setup1, template;
while (!snd_info_get_line(buffer, line, sizeof(line))) { while (!snd_info_get_line(buffer, line, sizeof(line))) {
mutex_lock(&pstr->oss.setup_mutex); guard(mutex)(&pstr->oss.setup_mutex);
memset(&template, 0, sizeof(template)); memset(&template, 0, sizeof(template));
ptr = snd_info_get_str(task_name, line, sizeof(task_name)); ptr = snd_info_get_str(task_name, line, sizeof(task_name));
if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
snd_pcm_oss_proc_free_setup_list(pstr); snd_pcm_oss_proc_free_setup_list(pstr);
mutex_unlock(&pstr->oss.setup_mutex);
continue; continue;
} }
for (setup = pstr->oss.setup_list; setup; setup = setup->next) { for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
...@@ -3049,7 +3032,6 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -3049,7 +3032,6 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
setup = kmalloc(sizeof(*setup), GFP_KERNEL); setup = kmalloc(sizeof(*setup), GFP_KERNEL);
if (! setup) { if (! setup) {
buffer->error = -ENOMEM; buffer->error = -ENOMEM;
mutex_unlock(&pstr->oss.setup_mutex);
return; return;
} }
if (pstr->oss.setup_list == NULL) if (pstr->oss.setup_list == NULL)
...@@ -3063,12 +3045,10 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, ...@@ -3063,12 +3045,10 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
if (! template.task_name) { if (! template.task_name) {
kfree(setup); kfree(setup);
buffer->error = -ENOMEM; buffer->error = -ENOMEM;
mutex_unlock(&pstr->oss.setup_mutex);
return; return;
} }
} }
*setup = template; *setup = template;
mutex_unlock(&pstr->oss.setup_mutex);
} }
} }
......
...@@ -91,9 +91,8 @@ static int snd_pcm_control_ioctl(struct snd_card *card, ...@@ -91,9 +91,8 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
if (get_user(device, (int __user *)arg)) if (get_user(device, (int __user *)arg))
return -EFAULT; return -EFAULT;
mutex_lock(&register_mutex); scoped_guard(mutex, &register_mutex)
device = snd_pcm_next(card, device); device = snd_pcm_next(card, device);
mutex_unlock(&register_mutex);
if (put_user(device, (int __user *)arg)) if (put_user(device, (int __user *)arg))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -106,7 +105,6 @@ static int snd_pcm_control_ioctl(struct snd_card *card, ...@@ -106,7 +105,6 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
struct snd_pcm *pcm; struct snd_pcm *pcm;
struct snd_pcm_str *pstr; struct snd_pcm_str *pstr;
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
int err;
info = (struct snd_pcm_info __user *)arg; info = (struct snd_pcm_info __user *)arg;
if (get_user(device, &info->device)) if (get_user(device, &info->device))
...@@ -118,35 +116,23 @@ static int snd_pcm_control_ioctl(struct snd_card *card, ...@@ -118,35 +116,23 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
stream = array_index_nospec(stream, 2); stream = array_index_nospec(stream, 2);
if (get_user(subdevice, &info->subdevice)) if (get_user(subdevice, &info->subdevice))
return -EFAULT; return -EFAULT;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
pcm = snd_pcm_get(card, device); pcm = snd_pcm_get(card, device);
if (pcm == NULL) { if (pcm == NULL)
err = -ENXIO; return -ENXIO;
goto _error;
}
pstr = &pcm->streams[stream]; pstr = &pcm->streams[stream];
if (pstr->substream_count == 0) { if (pstr->substream_count == 0)
err = -ENOENT; return -ENOENT;
goto _error; if (subdevice >= pstr->substream_count)
} return -ENXIO;
if (subdevice >= pstr->substream_count) {
err = -ENXIO;
goto _error;
}
for (substream = pstr->substream; substream; for (substream = pstr->substream; substream;
substream = substream->next) substream = substream->next)
if (substream->number == (int)subdevice) if (substream->number == (int)subdevice)
break; break;
if (substream == NULL) { if (substream == NULL)
err = -ENXIO; return -ENXIO;
goto _error; guard(mutex)(&pcm->open_mutex);
} return snd_pcm_info_user(substream, info);
mutex_lock(&pcm->open_mutex);
err = snd_pcm_info_user(substream, info);
mutex_unlock(&pcm->open_mutex);
_error:
mutex_unlock(&register_mutex);
return err;
} }
case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE: case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
{ {
...@@ -225,9 +211,11 @@ static const char * const snd_pcm_format_names[] = { ...@@ -225,9 +211,11 @@ static const char * const snd_pcm_format_names[] = {
*/ */
const char *snd_pcm_format_name(snd_pcm_format_t format) const char *snd_pcm_format_name(snd_pcm_format_t format)
{ {
if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) unsigned int format_num = (__force unsigned int)format;
if (format_num >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format_num])
return "Unknown"; return "Unknown";
return snd_pcm_format_names[(__force unsigned int)format]; return snd_pcm_format_names[format_num];
} }
EXPORT_SYMBOL_GPL(snd_pcm_format_name); EXPORT_SYMBOL_GPL(snd_pcm_format_name);
...@@ -340,7 +328,7 @@ static const char *snd_pcm_oss_format_name(int format) ...@@ -340,7 +328,7 @@ static const char *snd_pcm_oss_format_name(int format)
static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream, static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
struct snd_info_buffer *buffer) struct snd_info_buffer *buffer)
{ {
struct snd_pcm_info *info; struct snd_pcm_info *info __free(kfree) = NULL;
int err; int err;
if (! substream) if (! substream)
...@@ -353,7 +341,6 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream, ...@@ -353,7 +341,6 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
err = snd_pcm_info(substream, info); err = snd_pcm_info(substream, info);
if (err < 0) { if (err < 0) {
snd_iprintf(buffer, "error %d\n", err); snd_iprintf(buffer, "error %d\n", err);
kfree(info);
return; return;
} }
snd_iprintf(buffer, "card: %d\n", info->card); snd_iprintf(buffer, "card: %d\n", info->card);
...@@ -367,7 +354,6 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream, ...@@ -367,7 +354,6 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass); snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);
snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count); snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);
snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail); snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);
kfree(info);
} }
static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry, static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
...@@ -389,15 +375,15 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, ...@@ -389,15 +375,15 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
struct snd_pcm_substream *substream = entry->private_data; struct snd_pcm_substream *substream = entry->private_data;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
mutex_lock(&substream->pcm->open_mutex); guard(mutex)(&substream->pcm->open_mutex);
runtime = substream->runtime; runtime = substream->runtime;
if (!runtime) { if (!runtime) {
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
goto unlock; return;
} }
if (runtime->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
goto unlock; return;
} }
snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access)); snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format)); snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
...@@ -416,8 +402,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry, ...@@ -416,8 +402,6 @@ static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames); snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
} }
#endif #endif
unlock:
mutex_unlock(&substream->pcm->open_mutex);
} }
static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
...@@ -426,15 +410,15 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, ...@@ -426,15 +410,15 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
struct snd_pcm_substream *substream = entry->private_data; struct snd_pcm_substream *substream = entry->private_data;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
mutex_lock(&substream->pcm->open_mutex); guard(mutex)(&substream->pcm->open_mutex);
runtime = substream->runtime; runtime = substream->runtime;
if (!runtime) { if (!runtime) {
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
goto unlock; return;
} }
if (runtime->state == SNDRV_PCM_STATE_OPEN) { if (runtime->state == SNDRV_PCM_STATE_OPEN) {
snd_iprintf(buffer, "no setup\n"); snd_iprintf(buffer, "no setup\n");
goto unlock; return;
} }
snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode)); snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
snd_iprintf(buffer, "period_step: %u\n", runtime->period_step); snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
...@@ -444,8 +428,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry, ...@@ -444,8 +428,6 @@ static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold); snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size); snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary); snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
unlock:
mutex_unlock(&substream->pcm->open_mutex);
} }
static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
...@@ -456,17 +438,17 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, ...@@ -456,17 +438,17 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
struct snd_pcm_status64 status; struct snd_pcm_status64 status;
int err; int err;
mutex_lock(&substream->pcm->open_mutex); guard(mutex)(&substream->pcm->open_mutex);
runtime = substream->runtime; runtime = substream->runtime;
if (!runtime) { if (!runtime) {
snd_iprintf(buffer, "closed\n"); snd_iprintf(buffer, "closed\n");
goto unlock; return;
} }
memset(&status, 0, sizeof(status)); memset(&status, 0, sizeof(status));
err = snd_pcm_status64(substream, &status); err = snd_pcm_status64(substream, &status);
if (err < 0) { if (err < 0) {
snd_iprintf(buffer, "error %d\n", err); snd_iprintf(buffer, "error %d\n", err);
goto unlock; return;
} }
snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid)); snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
...@@ -480,8 +462,6 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry, ...@@ -480,8 +462,6 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "-----\n"); snd_iprintf(buffer, "-----\n");
snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr); snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr); snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
unlock:
mutex_unlock(&substream->pcm->open_mutex);
} }
#ifdef CONFIG_SND_PCM_XRUN_DEBUG #ifdef CONFIG_SND_PCM_XRUN_DEBUG
...@@ -1009,9 +989,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream) ...@@ -1009,9 +989,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
kfree(runtime->hw_constraints.rules); kfree(runtime->hw_constraints.rules);
/* Avoid concurrent access to runtime via PCM timer interface */ /* Avoid concurrent access to runtime via PCM timer interface */
if (substream->timer) { if (substream->timer) {
spin_lock_irq(&substream->timer->lock); scoped_guard(spinlock_irq, &substream->timer->lock)
substream->runtime = NULL; substream->runtime = NULL;
spin_unlock_irq(&substream->timer->lock);
} else { } else {
substream->runtime = NULL; substream->runtime = NULL;
} }
...@@ -1068,10 +1047,10 @@ static int snd_pcm_dev_register(struct snd_device *device) ...@@ -1068,10 +1047,10 @@ static int snd_pcm_dev_register(struct snd_device *device)
return -ENXIO; return -ENXIO;
pcm = device->device_data; pcm = device->device_data;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
err = snd_pcm_add(pcm); err = snd_pcm_add(pcm);
if (err) if (err)
goto unlock; return err;
for (cidx = 0; cidx < 2; cidx++) { for (cidx = 0; cidx < 2; cidx++) {
int devtype = -1; int devtype = -1;
if (pcm->streams[cidx].substream == NULL) if (pcm->streams[cidx].substream == NULL)
...@@ -1090,7 +1069,7 @@ static int snd_pcm_dev_register(struct snd_device *device) ...@@ -1090,7 +1069,7 @@ static int snd_pcm_dev_register(struct snd_device *device)
pcm->streams[cidx].dev); pcm->streams[cidx].dev);
if (err < 0) { if (err < 0) {
list_del_init(&pcm->list); list_del_init(&pcm->list);
goto unlock; return err;
} }
for (substream = pcm->streams[cidx].substream; substream; substream = substream->next) for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
...@@ -1098,9 +1077,6 @@ static int snd_pcm_dev_register(struct snd_device *device) ...@@ -1098,9 +1077,6 @@ static int snd_pcm_dev_register(struct snd_device *device)
} }
pcm_call_notify(pcm, n_register); pcm_call_notify(pcm, n_register);
unlock:
mutex_unlock(&register_mutex);
return err; return err;
} }
...@@ -1110,8 +1086,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) ...@@ -1110,8 +1086,8 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
struct snd_pcm_substream *substream; struct snd_pcm_substream *substream;
int cidx; int cidx;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
mutex_lock(&pcm->open_mutex); guard(mutex)(&pcm->open_mutex);
wake_up(&pcm->open_wait); wake_up(&pcm->open_wait);
list_del_init(&pcm->list); list_del_init(&pcm->list);
...@@ -1138,8 +1114,6 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) ...@@ -1138,8 +1114,6 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
snd_unregister_device(pcm->streams[cidx].dev); snd_unregister_device(pcm->streams[cidx].dev);
free_chmap(&pcm->streams[cidx]); free_chmap(&pcm->streams[cidx]);
} }
mutex_unlock(&pcm->open_mutex);
mutex_unlock(&register_mutex);
return 0; return 0;
} }
...@@ -1164,7 +1138,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) ...@@ -1164,7 +1138,7 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
!notify->n_unregister || !notify->n_unregister ||
!notify->n_disconnect)) !notify->n_disconnect))
return -EINVAL; return -EINVAL;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
if (nfree) { if (nfree) {
list_del(&notify->list); list_del(&notify->list);
list_for_each_entry(pcm, &snd_pcm_devices, list) list_for_each_entry(pcm, &snd_pcm_devices, list)
...@@ -1174,7 +1148,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) ...@@ -1174,7 +1148,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
list_for_each_entry(pcm, &snd_pcm_devices, list) list_for_each_entry(pcm, &snd_pcm_devices, list)
notify->n_register(pcm); notify->n_register(pcm);
} }
mutex_unlock(&register_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_pcm_notify); EXPORT_SYMBOL(snd_pcm_notify);
...@@ -1190,7 +1163,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, ...@@ -1190,7 +1163,7 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
{ {
struct snd_pcm *pcm; struct snd_pcm *pcm;
mutex_lock(&register_mutex); guard(mutex)(&register_mutex);
list_for_each_entry(pcm, &snd_pcm_devices, list) { list_for_each_entry(pcm, &snd_pcm_devices, list) {
snd_iprintf(buffer, "%02i-%02i: %s : %s", snd_iprintf(buffer, "%02i-%02i: %s : %s",
pcm->card->number, pcm->device, pcm->id, pcm->name); pcm->card->number, pcm->device, pcm->id, pcm->name);
...@@ -1202,7 +1175,6 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry, ...@@ -1202,7 +1175,6 @@ static void snd_pcm_proc_read(struct snd_info_entry *entry,
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count); pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
snd_iprintf(buffer, "\n"); snd_iprintf(buffer, "\n");
} }
mutex_unlock(&register_mutex);
} }
static struct snd_info_entry *snd_pcm_proc_entry; static struct snd_info_entry *snd_pcm_proc_entry;
......
...@@ -235,7 +235,7 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, ...@@ -235,7 +235,7 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
int refine, int refine,
struct snd_pcm_hw_params32 __user *data32) struct snd_pcm_hw_params32 __user *data32)
{ {
struct snd_pcm_hw_params *data; struct snd_pcm_hw_params *data __free(kfree) = NULL;
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
int err; int err;
...@@ -248,34 +248,28 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, ...@@ -248,34 +248,28 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
return -ENOMEM; return -ENOMEM;
/* only fifo_size (RO from userspace) is different, so just copy all */ /* only fifo_size (RO from userspace) is different, so just copy all */
if (copy_from_user(data, data32, sizeof(*data32))) { if (copy_from_user(data, data32, sizeof(*data32)))
err = -EFAULT; return -EFAULT;
goto error;
}
if (refine) { if (refine) {
err = snd_pcm_hw_refine(substream, data); err = snd_pcm_hw_refine(substream, data);
if (err < 0) if (err < 0)
goto error; return err;
err = fixup_unreferenced_params(substream, data); err = fixup_unreferenced_params(substream, data);
} else { } else {
err = snd_pcm_hw_params(substream, data); err = snd_pcm_hw_params(substream, data);
} }
if (err < 0) if (err < 0)
goto error; return err;
if (copy_to_user(data32, data, sizeof(*data32)) || if (copy_to_user(data32, data, sizeof(*data32)) ||
put_user(data->fifo_size, &data32->fifo_size)) { put_user(data->fifo_size, &data32->fifo_size))
err = -EFAULT; return -EFAULT;
goto error;
}
if (! refine) { if (! refine) {
unsigned int new_boundary = recalculate_boundary(runtime); unsigned int new_boundary = recalculate_boundary(runtime);
if (new_boundary) if (new_boundary)
runtime->boundary = new_boundary; runtime->boundary = new_boundary;
} }
error:
kfree(data);
return err; return err;
} }
...@@ -338,7 +332,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, ...@@ -338,7 +332,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
compat_caddr_t buf; compat_caddr_t buf;
compat_caddr_t __user *bufptr; compat_caddr_t __user *bufptr;
u32 frames; u32 frames;
void __user **bufs; void __user **bufs __free(kfree) = NULL;
int err, ch, i; int err, ch, i;
if (! substream->runtime) if (! substream->runtime)
...@@ -360,10 +354,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, ...@@ -360,10 +354,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
return -ENOMEM; return -ENOMEM;
for (i = 0; i < ch; i++) { for (i = 0; i < ch; i++) {
u32 ptr; u32 ptr;
if (get_user(ptr, bufptr)) { if (get_user(ptr, bufptr))
kfree(bufs);
return -EFAULT; return -EFAULT;
}
bufs[i] = compat_ptr(ptr); bufs[i] = compat_ptr(ptr);
bufptr++; bufptr++;
} }
...@@ -373,9 +365,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, ...@@ -373,9 +365,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
err = snd_pcm_lib_readv(substream, bufs, frames); err = snd_pcm_lib_readv(substream, bufs, frames);
if (err >= 0) { if (err >= 0) {
if (put_user(err, &data32->result)) if (put_user(err, &data32->result))
err = -EFAULT; return -EFAULT;
} }
kfree(bufs);
return err; return err;
} }
...@@ -441,22 +432,22 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream, ...@@ -441,22 +432,22 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
boundary = recalculate_boundary(runtime); boundary = recalculate_boundary(runtime);
if (!boundary) if (!boundary)
boundary = 0x7fffffff; boundary = 0x7fffffff;
snd_pcm_stream_lock_irq(substream); scoped_guard(pcm_stream_lock_irq, substream) {
/* FIXME: we should consider the boundary for the sync from app */ /* FIXME: we should consider the boundary for the sync from app */
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
control->appl_ptr = scontrol.appl_ptr; control->appl_ptr = scontrol.appl_ptr;
else else
scontrol.appl_ptr = control->appl_ptr % boundary; scontrol.appl_ptr = control->appl_ptr % boundary;
if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN)) if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
control->avail_min = scontrol.avail_min; control->avail_min = scontrol.avail_min;
else else
scontrol.avail_min = control->avail_min; scontrol.avail_min = control->avail_min;
sstatus.state = status->state; sstatus.state = status->state;
sstatus.hw_ptr = status->hw_ptr % boundary; sstatus.hw_ptr = status->hw_ptr % boundary;
sstatus.tstamp = status->tstamp; sstatus.tstamp = status->tstamp;
sstatus.suspended_state = status->suspended_state; sstatus.suspended_state = status->suspended_state;
sstatus.audio_tstamp = status->audio_tstamp; sstatus.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream); }
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL)) if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE); snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
if (put_user(sstatus.state, &src->s.status.state) || if (put_user(sstatus.state, &src->s.status.state) ||
...@@ -519,26 +510,24 @@ static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream, ...@@ -519,26 +510,24 @@ static int snd_pcm_ioctl_sync_ptr_buggy(struct snd_pcm_substream *substream,
if (err < 0) if (err < 0)
return err; return err;
} }
snd_pcm_stream_lock_irq(substream); scoped_guard(pcm_stream_lock_irq, substream) {
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) { if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) {
err = pcm_lib_apply_appl_ptr(substream, sync_cp->appl_ptr); err = pcm_lib_apply_appl_ptr(substream, sync_cp->appl_ptr);
if (err < 0) { if (err < 0)
snd_pcm_stream_unlock_irq(substream); return err;
return err; } else {
sync_cp->appl_ptr = control->appl_ptr;
} }
} else { if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
sync_cp->appl_ptr = control->appl_ptr; control->avail_min = sync_cp->avail_min;
else
sync_cp->avail_min = control->avail_min;
sync_ptr.s.status.state = status->state;
sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp;
sync_ptr.s.status.suspended_state = status->suspended_state;
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
} }
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
control->avail_min = sync_cp->avail_min;
else
sync_cp->avail_min = control->avail_min;
sync_ptr.s.status.state = status->state;
sync_ptr.s.status.hw_ptr = status->hw_ptr;
sync_ptr.s.status.tstamp = status->tstamp;
sync_ptr.s.status.suspended_state = status->suspended_state;
sync_ptr.s.status.audio_tstamp = status->audio_tstamp;
snd_pcm_stream_unlock_irq(substream);
if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL)) if (!(sync_ptr.flags & SNDRV_PCM_SYNC_PTR_APPL))
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE); snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr))) if (copy_to_user(_sync_ptr, &sync_ptr, sizeof(sync_ptr)))
......
...@@ -1744,8 +1744,8 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, ...@@ -1744,8 +1744,8 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
void *arg) void *arg)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
unsigned long flags;
snd_pcm_stream_lock_irqsave(substream, flags); guard(pcm_stream_lock_irqsave)(substream);
if (snd_pcm_running(substream) && if (snd_pcm_running(substream) &&
snd_pcm_update_hw_ptr(substream) >= 0) snd_pcm_update_hw_ptr(substream) >= 0)
runtime->status->hw_ptr %= runtime->buffer_size; runtime->status->hw_ptr %= runtime->buffer_size;
...@@ -1753,7 +1753,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, ...@@ -1753,7 +1753,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
runtime->status->hw_ptr = 0; runtime->status->hw_ptr = 0;
runtime->hw_ptr_wrap = 0; runtime->hw_ptr_wrap = 0;
} }
snd_pcm_stream_unlock_irqrestore(substream, flags);
return 0; return 0;
} }
...@@ -1899,14 +1898,11 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock); ...@@ -1899,14 +1898,11 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed_under_stream_lock);
*/ */
void snd_pcm_period_elapsed(struct snd_pcm_substream *substream) void snd_pcm_period_elapsed(struct snd_pcm_substream *substream)
{ {
unsigned long flags;
if (snd_BUG_ON(!substream)) if (snd_BUG_ON(!substream))
return; return;
snd_pcm_stream_lock_irqsave(substream, flags); guard(pcm_stream_lock_irqsave)(substream);
snd_pcm_period_elapsed_under_stream_lock(substream); snd_pcm_period_elapsed_under_stream_lock(substream);
snd_pcm_stream_unlock_irqrestore(substream, flags);
} }
EXPORT_SYMBOL(snd_pcm_period_elapsed); EXPORT_SYMBOL(snd_pcm_period_elapsed);
......
...@@ -38,17 +38,15 @@ static void __update_allocated_size(struct snd_card *card, ssize_t bytes) ...@@ -38,17 +38,15 @@ static void __update_allocated_size(struct snd_card *card, ssize_t bytes)
static void update_allocated_size(struct snd_card *card, ssize_t bytes) static void update_allocated_size(struct snd_card *card, ssize_t bytes)
{ {
mutex_lock(&card->memory_mutex); guard(mutex)(&card->memory_mutex);
__update_allocated_size(card, bytes); __update_allocated_size(card, bytes);
mutex_unlock(&card->memory_mutex);
} }
static void decrease_allocated_size(struct snd_card *card, size_t bytes) static void decrease_allocated_size(struct snd_card *card, size_t bytes)
{ {
mutex_lock(&card->memory_mutex); guard(mutex)(&card->memory_mutex);
WARN_ON(card->total_pcm_alloc_bytes < bytes); WARN_ON(card->total_pcm_alloc_bytes < bytes);
__update_allocated_size(card, -(ssize_t)bytes); __update_allocated_size(card, -(ssize_t)bytes);
mutex_unlock(&card->memory_mutex);
} }
static int do_alloc_pages(struct snd_card *card, int type, struct device *dev, static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
...@@ -58,14 +56,12 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev, ...@@ -58,14 +56,12 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
int err; int err;
/* check and reserve the requested size */ /* check and reserve the requested size */
mutex_lock(&card->memory_mutex); scoped_guard(mutex, &card->memory_mutex) {
if (max_alloc_per_card && if (max_alloc_per_card &&
card->total_pcm_alloc_bytes + size > max_alloc_per_card) { card->total_pcm_alloc_bytes + size > max_alloc_per_card)
mutex_unlock(&card->memory_mutex); return -ENOMEM;
return -ENOMEM; __update_allocated_size(card, size);
} }
__update_allocated_size(card, size);
mutex_unlock(&card->memory_mutex);
if (str == SNDRV_PCM_STREAM_PLAYBACK) if (str == SNDRV_PCM_STREAM_PLAYBACK)
dir = DMA_TO_DEVICE; dir = DMA_TO_DEVICE;
...@@ -191,20 +187,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, ...@@ -191,20 +187,20 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
size_t size; size_t size;
struct snd_dma_buffer new_dmab; struct snd_dma_buffer new_dmab;
mutex_lock(&substream->pcm->open_mutex); guard(mutex)(&substream->pcm->open_mutex);
if (substream->runtime) { if (substream->runtime) {
buffer->error = -EBUSY; buffer->error = -EBUSY;
goto unlock; return;
} }
if (!snd_info_get_line(buffer, line, sizeof(line))) { if (!snd_info_get_line(buffer, line, sizeof(line))) {
snd_info_get_str(str, line, sizeof(str)); snd_info_get_str(str, line, sizeof(str));
size = simple_strtoul(str, NULL, 10) * 1024; size = simple_strtoul(str, NULL, 10) * 1024;
if ((size != 0 && size < 8192) || size > substream->dma_max) { if ((size != 0 && size < 8192) || size > substream->dma_max) {
buffer->error = -EINVAL; buffer->error = -EINVAL;
goto unlock; return;
} }
if (substream->dma_buffer.bytes == size) if (substream->dma_buffer.bytes == size)
goto unlock; return;
memset(&new_dmab, 0, sizeof(new_dmab)); memset(&new_dmab, 0, sizeof(new_dmab));
new_dmab.dev = substream->dma_buffer.dev; new_dmab.dev = substream->dma_buffer.dev;
if (size > 0) { if (size > 0) {
...@@ -218,7 +214,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, ...@@ -218,7 +214,7 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
substream->pcm->card->number, substream->pcm->device, substream->pcm->card->number, substream->pcm->device,
substream->stream ? 'c' : 'p', substream->number, substream->stream ? 'c' : 'p', substream->number,
substream->pcm->name, size); substream->pcm->name, size);
goto unlock; return;
} }
substream->buffer_bytes_max = size; substream->buffer_bytes_max = size;
} else { } else {
...@@ -230,8 +226,6 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry, ...@@ -230,8 +226,6 @@ static void snd_pcm_lib_preallocate_proc_write(struct snd_info_entry *entry,
} else { } else {
buffer->error = -EINVAL; buffer->error = -EINVAL;
} }
unlock:
mutex_unlock(&substream->pcm->open_mutex);
} }
static inline void preallocate_info_init(struct snd_pcm_substream *substream) static inline void preallocate_info_init(struct snd_pcm_substream *substream)
......
This diff is collapsed.
This diff is collapsed.
...@@ -71,7 +71,6 @@ config SND_SEQ_UMP ...@@ -71,7 +71,6 @@ config SND_SEQ_UMP
among legacy and UMP clients. among legacy and UMP clients.
config SND_SEQ_UMP_CLIENT config SND_SEQ_UMP_CLIENT
tristate
def_tristate SND_UMP def_tristate SND_UMP
endif # SND_SEQUENCER endif # SND_SEQUENCER
...@@ -163,6 +163,6 @@ snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, ...@@ -163,6 +163,6 @@ snd_seq_oss_fill_addr(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
/* misc. functions for proc interface */ /* misc. functions for proc interface */
char *enabled_str(int bool); char *enabled_str(bool b);
#endif /* __SEQ_OSS_DEVICE_H */ #endif /* __SEQ_OSS_DEVICE_H */
...@@ -63,20 +63,18 @@ int __init ...@@ -63,20 +63,18 @@ int __init
snd_seq_oss_create_client(void) snd_seq_oss_create_client(void)
{ {
int rc; int rc;
struct snd_seq_port_info *port; struct snd_seq_port_info *port __free(kfree) = NULL;
struct snd_seq_port_callback port_callback; struct snd_seq_port_callback port_callback;
port = kzalloc(sizeof(*port), GFP_KERNEL); port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port) { if (!port)
rc = -ENOMEM; return -ENOMEM;
goto __error;
}
/* create ALSA client */ /* create ALSA client */
rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS, rc = snd_seq_create_kernel_client(NULL, SNDRV_SEQ_CLIENT_OSS,
"OSS sequencer"); "OSS sequencer");
if (rc < 0) if (rc < 0)
goto __error; return rc;
system_client = rc; system_client = rc;
...@@ -104,14 +102,11 @@ snd_seq_oss_create_client(void) ...@@ -104,14 +102,11 @@ snd_seq_oss_create_client(void)
subs.dest.port = system_port; subs.dest.port = system_port;
call_ctl(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs); call_ctl(SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &subs);
} }
rc = 0;
/* look up midi devices */ /* look up midi devices */
schedule_work(&async_lookup_work); schedule_work(&async_lookup_work);
__error: return 0;
kfree(port);
return rc;
} }
...@@ -455,9 +450,9 @@ snd_seq_oss_reset(struct seq_oss_devinfo *dp) ...@@ -455,9 +450,9 @@ snd_seq_oss_reset(struct seq_oss_devinfo *dp)
* misc. functions for proc interface * misc. functions for proc interface
*/ */
char * char *
enabled_str(int bool) enabled_str(bool b)
{ {
return bool ? "enabled" : "disabled"; return b ? "enabled" : "disabled";
} }
static const char * static const char *
......
...@@ -64,16 +64,13 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, ...@@ -64,16 +64,13 @@ static int send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev,
int int
snd_seq_oss_midi_lookup_ports(int client) snd_seq_oss_midi_lookup_ports(int client)
{ {
struct snd_seq_client_info *clinfo; struct snd_seq_client_info *clinfo __free(kfree) = NULL;
struct snd_seq_port_info *pinfo; struct snd_seq_port_info *pinfo __free(kfree) = NULL;
clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL); clinfo = kzalloc(sizeof(*clinfo), GFP_KERNEL);
pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL); pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
if (! clinfo || ! pinfo) { if (!clinfo || !pinfo)
kfree(clinfo);
kfree(pinfo);
return -ENOMEM; return -ENOMEM;
}
clinfo->client = -1; clinfo->client = -1;
while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) { while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT, clinfo) == 0) {
if (clinfo->client == client) if (clinfo->client == client)
...@@ -83,8 +80,6 @@ snd_seq_oss_midi_lookup_ports(int client) ...@@ -83,8 +80,6 @@ snd_seq_oss_midi_lookup_ports(int client)
while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0) while (snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT, pinfo) == 0)
snd_seq_oss_midi_check_new_port(pinfo); snd_seq_oss_midi_check_new_port(pinfo);
} }
kfree(clinfo);
kfree(pinfo);
return 0; return 0;
} }
......
...@@ -31,8 +31,8 @@ struct snd_seq_port_info32 { ...@@ -31,8 +31,8 @@ struct snd_seq_port_info32 {
static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd, static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned int cmd,
struct snd_seq_port_info32 __user *data32) struct snd_seq_port_info32 __user *data32)
{ {
int err = -EFAULT; struct snd_seq_port_info *data __free(kfree) = NULL;
struct snd_seq_port_info *data; int err;
data = kmalloc(sizeof(*data), GFP_KERNEL); data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data) if (!data)
...@@ -41,20 +41,18 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned ...@@ -41,20 +41,18 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned
if (copy_from_user(data, data32, sizeof(*data32)) || if (copy_from_user(data, data32, sizeof(*data32)) ||
get_user(data->flags, &data32->flags) || get_user(data->flags, &data32->flags) ||
get_user(data->time_queue, &data32->time_queue)) get_user(data->time_queue, &data32->time_queue))
goto error; return -EFAULT;
data->kernel = NULL; data->kernel = NULL;
err = snd_seq_kernel_client_ctl(client->number, cmd, data); err = snd_seq_kernel_client_ctl(client->number, cmd, data);
if (err < 0) if (err < 0)
goto error; return err;
if (copy_to_user(data32, data, sizeof(*data32)) || if (copy_to_user(data32, data, sizeof(*data32)) ||
put_user(data->flags, &data32->flags) || put_user(data->flags, &data32->flags) ||
put_user(data->time_queue, &data32->time_queue)) put_user(data->time_queue, &data32->time_queue))
err = -EFAULT; return -EFAULT;
error:
kfree(data);
return err; return err;
} }
......
This diff is collapsed.
...@@ -232,7 +232,6 @@ static inline void free_cell(struct snd_seq_pool *pool, ...@@ -232,7 +232,6 @@ static inline void free_cell(struct snd_seq_pool *pool,
void snd_seq_cell_free(struct snd_seq_event_cell * cell) void snd_seq_cell_free(struct snd_seq_event_cell * cell)
{ {
unsigned long flags;
struct snd_seq_pool *pool; struct snd_seq_pool *pool;
if (snd_BUG_ON(!cell)) if (snd_BUG_ON(!cell))
...@@ -241,7 +240,7 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) ...@@ -241,7 +240,7 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
if (snd_BUG_ON(!pool)) if (snd_BUG_ON(!pool))
return; return;
spin_lock_irqsave(&pool->lock, flags); guard(spinlock_irqsave)(&pool->lock);
free_cell(pool, cell); free_cell(pool, cell);
if (snd_seq_ev_is_variable(&cell->event)) { if (snd_seq_ev_is_variable(&cell->event)) {
if (cell->event.data.ext.len & SNDRV_SEQ_EXT_CHAINED) { if (cell->event.data.ext.len & SNDRV_SEQ_EXT_CHAINED) {
...@@ -259,7 +258,6 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell) ...@@ -259,7 +258,6 @@ void snd_seq_cell_free(struct snd_seq_event_cell * cell)
if (snd_seq_output_ok(pool)) if (snd_seq_output_ok(pool))
wake_up(&pool->output_sleep); wake_up(&pool->output_sleep);
} }
spin_unlock_irqrestore(&pool->lock, flags);
} }
...@@ -449,9 +447,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) ...@@ -449,9 +447,8 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
return -ENOMEM; return -ENOMEM;
/* add new cells to the free cell list */ /* add new cells to the free cell list */
spin_lock_irq(&pool->lock); guard(spinlock_irq)(&pool->lock);
if (pool->ptr) { if (pool->ptr) {
spin_unlock_irq(&pool->lock);
kvfree(cellptr); kvfree(cellptr);
return 0; return 0;
} }
...@@ -470,20 +467,16 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) ...@@ -470,20 +467,16 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
/* init statistics */ /* init statistics */
pool->max_used = 0; pool->max_used = 0;
pool->total_elements = pool->size; pool->total_elements = pool->size;
spin_unlock_irq(&pool->lock);
return 0; return 0;
} }
/* refuse the further insertion to the pool */ /* refuse the further insertion to the pool */
void snd_seq_pool_mark_closing(struct snd_seq_pool *pool) void snd_seq_pool_mark_closing(struct snd_seq_pool *pool)
{ {
unsigned long flags;
if (snd_BUG_ON(!pool)) if (snd_BUG_ON(!pool))
return; return;
spin_lock_irqsave(&pool->lock, flags); guard(spinlock_irqsave)(&pool->lock);
pool->closing = 1; pool->closing = 1;
spin_unlock_irqrestore(&pool->lock, flags);
} }
/* remove events */ /* remove events */
...@@ -502,18 +495,17 @@ int snd_seq_pool_done(struct snd_seq_pool *pool) ...@@ -502,18 +495,17 @@ int snd_seq_pool_done(struct snd_seq_pool *pool)
schedule_timeout_uninterruptible(1); schedule_timeout_uninterruptible(1);
/* release all resources */ /* release all resources */
spin_lock_irq(&pool->lock); scoped_guard(spinlock_irq, &pool->lock) {
ptr = pool->ptr; ptr = pool->ptr;
pool->ptr = NULL; pool->ptr = NULL;
pool->free = NULL; pool->free = NULL;
pool->total_elements = 0; pool->total_elements = 0;
spin_unlock_irq(&pool->lock); }
kvfree(ptr); kvfree(ptr);
spin_lock_irq(&pool->lock); guard(spinlock_irq)(&pool->lock);
pool->closing = 0; pool->closing = 0;
spin_unlock_irq(&pool->lock);
return 0; return 0;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -49,7 +49,7 @@ static int snd_seq_bus_match(struct device *dev, struct device_driver *drv) ...@@ -49,7 +49,7 @@ static int snd_seq_bus_match(struct device *dev, struct device_driver *drv)
sdrv->argsize == sdev->argsize; sdrv->argsize == sdev->argsize;
} }
static struct bus_type snd_seq_bus_type = { static const struct bus_type snd_seq_bus_type = {
.name = "snd_seq", .name = "snd_seq",
.match = snd_seq_bus_match, .match = snd_seq_bus_match,
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -115,10 +115,7 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, ...@@ -115,10 +115,7 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct snd_timer_user *tu = file->private_data; struct snd_timer_user *tu = file->private_data;
long ret;
mutex_lock(&tu->ioctl_lock); guard(mutex)(&tu->ioctl_lock);
ret = __snd_timer_user_ioctl_compat(file, cmd, arg); return __snd_timer_user_ioctl_compat(file, cmd, arg);
mutex_unlock(&tu->ioctl_lock);
return ret;
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment