You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'sound-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"We have touched quite a lot of files but with fewer changes at this
cycle; as you can see, most of changes are trivial fixes, especially
constification patches.
Among the massive attacks by constification gangs, we had a few core
changes (mostly for ASoC core), as well the fixes and the updates by
major vendors.
Some highlights:
ALSA core:
- Fix possible races in control API user-TLV codes
- Small cleanup of PCM core
ASoC:
- Continued work for componentization; still half-baked, but we're
certainly progressing
- Use of devres for jack detection GPIOs, rather as a cleanup
- Jack detection support for Qualcomm MSM8916
- Support for Allwinner H3, Cirrus Logic CS43130, Intel Kabylake
systems with RT5663, Realtek RT274, TI TLV320AIC32x6 and Wolfson
WM8523"
* tag 'sound-4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (512 commits)
ALSA: hda/ca0132 - Fix memory leak at error path
ALSA: hda: Fix forget to free resource in error handling code path in hda_codec_driver_probe
ASoC: cs43130: Fix unused compiler warnings for PM runtime
ASoC: cs43130: Fix possible Oops with invalid dev_id
ASoC: cs43130: fix spelling mistake: "irq_occurrance" -> "irq_occurrence"
ALSA: atmel: Remove leftovers of AVR32 removal
ALSA: atmel: convert AC97c driver to GPIO descriptor API
ALSA: hda/realtek - Enable jack detection function for Intel ALC700
ALSA: hda: Fix regression of hdmi eld control created based on invalid pcm
ASoC: Intel: Skylake: Add IPC to configure the copier secondary pins
ASoC: add missing compile rule for max98371
ASoC: add missing compile rule for sirf-audio-codec
ASoC: add missing compile rule for max98371
ASoC: cs43130: Add devicetree bindings for CS43130
ASoC: cs43130: Add support for CS43130 codec
ASoC: make clock direction configurable in asoc-simple
ALSA: ctxfi: Remove null check before kfree
ASoC: max98927: Changed device property read function
ASoC: max98927: Modified DAPM widget and map to enable/disable VI sense path
ASoC: max98927: Added PM suspend and resume function
...
This commit is contained in:
@@ -167,7 +167,7 @@ static int onyx_snd_vol_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new volume_control = {
|
||||
static const struct snd_kcontrol_new volume_control = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Volume",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
@@ -229,7 +229,7 @@ static int onyx_snd_inputgain_put(struct snd_kcontrol *kcontrol,
|
||||
return n != v;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new inputgain_control = {
|
||||
static const struct snd_kcontrol_new inputgain_control = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Capture Volume",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
@@ -284,7 +284,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new capture_source_control = {
|
||||
static const struct snd_kcontrol_new capture_source_control = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
/* If we name this 'Input Source', it properly shows up in
|
||||
* alsamixer as a selection, * but it's shown under the
|
||||
@@ -348,7 +348,7 @@ static int onyx_snd_mute_put(struct snd_kcontrol *kcontrol,
|
||||
return !err ? (v != c) : err;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new mute_control = {
|
||||
static const struct snd_kcontrol_new mute_control = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Master Playback Switch",
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
@@ -476,7 +476,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new onyx_spdif_mask = {
|
||||
static const struct snd_kcontrol_new onyx_spdif_mask = {
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READ,
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
|
||||
@@ -533,7 +533,7 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new onyx_spdif_ctrl = {
|
||||
static const struct snd_kcontrol_new onyx_spdif_ctrl = {
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||
.name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
|
||||
|
||||
@@ -905,8 +905,8 @@ static int tas_i2c_probe(struct i2c_client *client,
|
||||
goto fail;
|
||||
}
|
||||
printk(KERN_DEBUG
|
||||
"snd-aoa-codec-tas: tas found, addr 0x%02x on %s\n",
|
||||
(unsigned int)client->addr, node->full_name);
|
||||
"snd-aoa-codec-tas: tas found, addr 0x%02x on %pOF\n",
|
||||
(unsigned int)client->addr, node);
|
||||
return 0;
|
||||
fail:
|
||||
mutex_destroy(&tas->mtx);
|
||||
|
||||
@@ -778,7 +778,7 @@ static snd_pcm_uframes_t i2sbus_playback_pointer(struct snd_pcm_substream
|
||||
return i2sbus_pcm_pointer(i2sdev, 0);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops i2sbus_playback_ops = {
|
||||
static const struct snd_pcm_ops i2sbus_playback_ops = {
|
||||
.open = i2sbus_playback_open,
|
||||
.close = i2sbus_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -848,7 +848,7 @@ static snd_pcm_uframes_t i2sbus_record_pointer(struct snd_pcm_substream
|
||||
return i2sbus_pcm_pointer(i2sdev, 1);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops i2sbus_record_ops = {
|
||||
static const struct snd_pcm_ops i2sbus_record_ops = {
|
||||
.open = i2sbus_record_open,
|
||||
.close = i2sbus_record_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
||||
+4
-4
@@ -348,7 +348,7 @@ static irqreturn_t aaci_irq(int irq, void *devid)
|
||||
/*
|
||||
* ALSA support.
|
||||
*/
|
||||
static struct snd_pcm_hardware aaci_hw_info = {
|
||||
static const struct snd_pcm_hardware aaci_hw_info = {
|
||||
.info = SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
@@ -635,7 +635,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops aaci_playback_ops = {
|
||||
static const struct snd_pcm_ops aaci_playback_ops = {
|
||||
.open = aaci_pcm_open,
|
||||
.close = aaci_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -738,7 +738,7 @@ static int aaci_pcm_capture_prepare(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops aaci_capture_ops = {
|
||||
static const struct snd_pcm_ops aaci_capture_ops = {
|
||||
.open = aaci_pcm_open,
|
||||
.close = aaci_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -786,7 +786,7 @@ static SIMPLE_DEV_PM_OPS(aaci_dev_pm_ops, aaci_suspend, aaci_resume);
|
||||
#endif
|
||||
|
||||
|
||||
static struct ac97_pcm ac97_defs[] = {
|
||||
static const struct ac97_pcm ac97_defs[] = {
|
||||
[0] = { /* Front PCM */
|
||||
.exclusive = 1,
|
||||
.r = {
|
||||
|
||||
@@ -68,7 +68,7 @@ static int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
|
||||
return __pxa2xx_pcm_close(substream);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops pxa2xx_pcm_ops = {
|
||||
static const struct snd_pcm_ops pxa2xx_pcm_ops = {
|
||||
.open = pxa2xx_pcm_open,
|
||||
.close = pxa2xx_pcm_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
||||
+20
-67
@@ -12,16 +12,15 @@
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/atmel_pdc.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_device.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
@@ -29,7 +28,6 @@
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <sound/atmel-ac97c.h>
|
||||
#include <sound/memalloc.h>
|
||||
|
||||
#include "ac97c.h"
|
||||
@@ -56,7 +54,7 @@ struct atmel_ac97c {
|
||||
void __iomem *regs;
|
||||
int irq;
|
||||
int opened;
|
||||
int reset_pin;
|
||||
struct gpio_desc *reset_pin;
|
||||
};
|
||||
|
||||
#define get_chip(card) ((struct atmel_ac97c *)(card)->private_data)
|
||||
@@ -66,7 +64,7 @@ struct atmel_ac97c {
|
||||
#define ac97c_readl(chip, reg) \
|
||||
__raw_readl((chip)->regs + AC97C_##reg)
|
||||
|
||||
static struct snd_pcm_hardware atmel_ac97c_hw = {
|
||||
static const struct snd_pcm_hardware atmel_ac97c_hw = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP
|
||||
| SNDRV_PCM_INFO_MMAP_VALID
|
||||
| SNDRV_PCM_INFO_INTERLEAVED
|
||||
@@ -461,7 +459,7 @@ atmel_ac97c_capture_pointer(struct snd_pcm_substream *substream)
|
||||
return frames;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops atmel_ac97_playback_ops = {
|
||||
static const struct snd_pcm_ops atmel_ac97_playback_ops = {
|
||||
.open = atmel_ac97c_playback_open,
|
||||
.close = atmel_ac97c_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -472,7 +470,7 @@ static struct snd_pcm_ops atmel_ac97_playback_ops = {
|
||||
.pointer = atmel_ac97c_playback_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops atmel_ac97_capture_ops = {
|
||||
static const struct snd_pcm_ops atmel_ac97_capture_ops = {
|
||||
.open = atmel_ac97c_capture_open,
|
||||
.close = atmel_ac97c_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -558,7 +556,7 @@ static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct ac97_pcm at91_ac97_pcm_defs[] = {
|
||||
static const struct ac97_pcm at91_ac97_pcm_defs[] = {
|
||||
/* Playback */
|
||||
{
|
||||
.exclusive = 1,
|
||||
@@ -700,11 +698,11 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip)
|
||||
ac97c_writel(chip, CAMR, 0);
|
||||
ac97c_writel(chip, COMR, 0);
|
||||
|
||||
if (gpio_is_valid(chip->reset_pin)) {
|
||||
gpio_set_value(chip->reset_pin, 0);
|
||||
if (!IS_ERR(chip->reset_pin)) {
|
||||
gpiod_set_value(chip->reset_pin, 0);
|
||||
/* AC97 v2.2 specifications says minimum 1 us. */
|
||||
udelay(2);
|
||||
gpio_set_value(chip->reset_pin, 1);
|
||||
gpiod_set_value(chip->reset_pin, 1);
|
||||
} else {
|
||||
ac97c_writel(chip, MR, AC97C_MR_WRST | AC97C_MR_ENA);
|
||||
udelay(2);
|
||||
@@ -712,45 +710,18 @@ static void atmel_ac97c_reset(struct atmel_ac97c *chip)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id atmel_ac97c_dt_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9263-ac97c", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, atmel_ac97c_dt_ids);
|
||||
|
||||
static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
|
||||
{
|
||||
struct ac97c_platform_data *pdata;
|
||||
struct device_node *node = dev->of_node;
|
||||
|
||||
if (!node) {
|
||||
dev_err(dev, "Device does not have associated DT data\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pdata->reset_pin = of_get_named_gpio(dev->of_node, "ac97-gpios", 2);
|
||||
|
||||
return pdata;
|
||||
}
|
||||
#else
|
||||
static struct ac97c_platform_data *atmel_ac97c_probe_dt(struct device *dev)
|
||||
{
|
||||
dev_err(dev, "no platform data defined\n");
|
||||
return ERR_PTR(-ENXIO);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int atmel_ac97c_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct snd_card *card;
|
||||
struct atmel_ac97c *chip;
|
||||
struct resource *regs;
|
||||
struct ac97c_platform_data *pdata;
|
||||
struct clk *pclk;
|
||||
static struct snd_ac97_bus_ops ops = {
|
||||
.write = atmel_ac97c_write,
|
||||
@@ -765,13 +736,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
pdata = dev_get_platdata(&pdev->dev);
|
||||
if (!pdata) {
|
||||
pdata = atmel_ac97c_probe_dt(&pdev->dev);
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
}
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_dbg(&pdev->dev, "could not get irq: %d\n", irq);
|
||||
@@ -783,7 +747,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
|
||||
dev_dbg(&pdev->dev, "no peripheral clock\n");
|
||||
return PTR_ERR(pclk);
|
||||
}
|
||||
clk_prepare_enable(pclk);
|
||||
retval = clk_prepare_enable(pclk);
|
||||
if (retval)
|
||||
goto err_prepare_enable;
|
||||
|
||||
retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
|
||||
SNDRV_DEFAULT_STR1, THIS_MODULE,
|
||||
@@ -819,17 +785,9 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
if (gpio_is_valid(pdata->reset_pin)) {
|
||||
if (gpio_request(pdata->reset_pin, "reset_pin")) {
|
||||
dev_dbg(&pdev->dev, "reset pin not available\n");
|
||||
chip->reset_pin = -ENODEV;
|
||||
} else {
|
||||
gpio_direction_output(pdata->reset_pin, 1);
|
||||
chip->reset_pin = pdata->reset_pin;
|
||||
}
|
||||
} else {
|
||||
chip->reset_pin = -EINVAL;
|
||||
}
|
||||
chip->reset_pin = devm_gpiod_get_index(dev, "ac97", 2, GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(chip->reset_pin))
|
||||
dev_dbg(dev, "reset pin not available\n");
|
||||
|
||||
atmel_ac97c_reset(chip);
|
||||
|
||||
@@ -869,9 +827,6 @@ static int atmel_ac97c_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
|
||||
err_ac97_bus:
|
||||
if (gpio_is_valid(chip->reset_pin))
|
||||
gpio_free(chip->reset_pin);
|
||||
|
||||
iounmap(chip->regs);
|
||||
err_ioremap:
|
||||
free_irq(irq, chip);
|
||||
@@ -879,6 +834,7 @@ err_request_irq:
|
||||
snd_card_free(card);
|
||||
err_snd_card_new:
|
||||
clk_disable_unprepare(pclk);
|
||||
err_prepare_enable:
|
||||
clk_put(pclk);
|
||||
return retval;
|
||||
}
|
||||
@@ -897,9 +853,9 @@ static int atmel_ac97c_resume(struct device *pdev)
|
||||
{
|
||||
struct snd_card *card = dev_get_drvdata(pdev);
|
||||
struct atmel_ac97c *chip = card->private_data;
|
||||
int ret = clk_prepare_enable(chip->pclk);
|
||||
|
||||
clk_prepare_enable(chip->pclk);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
|
||||
@@ -913,9 +869,6 @@ static int atmel_ac97c_remove(struct platform_device *pdev)
|
||||
struct snd_card *card = platform_get_drvdata(pdev);
|
||||
struct atmel_ac97c *chip = get_chip(card);
|
||||
|
||||
if (gpio_is_valid(chip->reset_pin))
|
||||
gpio_free(chip->reset_pin);
|
||||
|
||||
ac97c_writel(chip, CAMR, 0);
|
||||
ac97c_writel(chip, COMR, 0);
|
||||
ac97c_writel(chip, MR, 0);
|
||||
@@ -936,7 +889,7 @@ static struct platform_driver atmel_ac97c_driver = {
|
||||
.driver = {
|
||||
.name = "atmel_ac97c",
|
||||
.pm = ATMEL_AC97C_PM_OPS,
|
||||
.of_match_table = of_match_ptr(atmel_ac97c_dt_ids),
|
||||
.of_match_table = atmel_ac97c_dt_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(atmel_ac97c_driver);
|
||||
|
||||
+229
-159
@@ -864,14 +864,14 @@ static int snd_ctl_elem_info_user(struct snd_ctl_file *ctl,
|
||||
|
||||
if (copy_from_user(&info, _info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
snd_power_lock(ctl->card);
|
||||
result = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_info(ctl, &info);
|
||||
snd_power_unlock(ctl->card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
if (result < 0)
|
||||
return result;
|
||||
result = snd_ctl_elem_info(ctl, &info);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (copy_to_user(_info, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -881,24 +881,18 @@ static int snd_ctl_elem_read(struct snd_card *card,
|
||||
struct snd_kcontrol *kctl;
|
||||
struct snd_kcontrol_volatile *vd;
|
||||
unsigned int index_offset;
|
||||
int result;
|
||||
|
||||
down_read(&card->controls_rwsem);
|
||||
kctl = snd_ctl_find_id(card, &control->id);
|
||||
if (kctl == NULL) {
|
||||
result = -ENOENT;
|
||||
} else {
|
||||
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
||||
vd = &kctl->vd[index_offset];
|
||||
if ((vd->access & SNDRV_CTL_ELEM_ACCESS_READ) &&
|
||||
kctl->get != NULL) {
|
||||
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
||||
result = kctl->get(kctl, control);
|
||||
} else
|
||||
result = -EPERM;
|
||||
}
|
||||
up_read(&card->controls_rwsem);
|
||||
return result;
|
||||
if (kctl == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
||||
vd = &kctl->vd[index_offset];
|
||||
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) && kctl->get == NULL)
|
||||
return -EPERM;
|
||||
|
||||
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
||||
return kctl->get(kctl, control);
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_read_user(struct snd_card *card,
|
||||
@@ -911,14 +905,19 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
|
||||
if (IS_ERR(control))
|
||||
return PTR_ERR(control);
|
||||
|
||||
snd_power_lock(card);
|
||||
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_read(card, control);
|
||||
snd_power_unlock(card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
if (result < 0)
|
||||
goto error;
|
||||
|
||||
down_read(&card->controls_rwsem);
|
||||
result = snd_ctl_elem_read(card, control);
|
||||
up_read(&card->controls_rwsem);
|
||||
if (result < 0)
|
||||
goto error;
|
||||
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
error:
|
||||
kfree(control);
|
||||
return result;
|
||||
}
|
||||
@@ -931,30 +930,28 @@ static int snd_ctl_elem_write(struct snd_card *card, struct snd_ctl_file *file,
|
||||
unsigned int index_offset;
|
||||
int result;
|
||||
|
||||
down_read(&card->controls_rwsem);
|
||||
kctl = snd_ctl_find_id(card, &control->id);
|
||||
if (kctl == NULL) {
|
||||
result = -ENOENT;
|
||||
} else {
|
||||
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
||||
vd = &kctl->vd[index_offset];
|
||||
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) ||
|
||||
kctl->put == NULL ||
|
||||
(file && vd->owner && vd->owner != file)) {
|
||||
result = -EPERM;
|
||||
} else {
|
||||
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
||||
result = kctl->put(kctl, control);
|
||||
}
|
||||
if (result > 0) {
|
||||
struct snd_ctl_elem_id id = control->id;
|
||||
up_read(&card->controls_rwsem);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
|
||||
return 0;
|
||||
}
|
||||
if (kctl == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
index_offset = snd_ctl_get_ioff(kctl, &control->id);
|
||||
vd = &kctl->vd[index_offset];
|
||||
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_WRITE) || kctl->put == NULL ||
|
||||
(file && vd->owner && vd->owner != file)) {
|
||||
return -EPERM;
|
||||
}
|
||||
up_read(&card->controls_rwsem);
|
||||
return result;
|
||||
|
||||
snd_ctl_build_ioff(&control->id, kctl, index_offset);
|
||||
result = kctl->put(kctl, control);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
if (result > 0) {
|
||||
struct snd_ctl_elem_id id = control->id;
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE, &id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
@@ -969,14 +966,19 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
return PTR_ERR(control);
|
||||
|
||||
card = file->card;
|
||||
snd_power_lock(card);
|
||||
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
|
||||
if (result >= 0)
|
||||
result = snd_ctl_elem_write(card, file, control);
|
||||
snd_power_unlock(card);
|
||||
if (result >= 0)
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
if (result < 0)
|
||||
goto error;
|
||||
|
||||
down_write(&card->controls_rwsem);
|
||||
result = snd_ctl_elem_write(card, file, control);
|
||||
up_write(&card->controls_rwsem);
|
||||
if (result < 0)
|
||||
goto error;
|
||||
|
||||
if (copy_to_user(_control, control, sizeof(*control)))
|
||||
result = -EFAULT;
|
||||
error:
|
||||
kfree(control);
|
||||
return result;
|
||||
}
|
||||
@@ -1095,9 +1097,7 @@ static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol,
|
||||
char *src = ue->elem_data +
|
||||
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
memcpy(&ucontrol->value, src, size);
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1110,60 +1110,83 @@ static int snd_ctl_elem_user_put(struct snd_kcontrol *kcontrol,
|
||||
char *dst = ue->elem_data +
|
||||
snd_ctl_get_ioff(kcontrol, &ucontrol->id) * size;
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
change = memcmp(&ucontrol->value, dst, size) != 0;
|
||||
if (change)
|
||||
memcpy(dst, &ucontrol->value, size);
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
return change;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
|
||||
int op_flag,
|
||||
unsigned int size,
|
||||
unsigned int __user *tlv)
|
||||
static int replace_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
||||
unsigned int size)
|
||||
{
|
||||
struct user_element *ue = kcontrol->private_data;
|
||||
int change = 0;
|
||||
void *new_data;
|
||||
struct user_element *ue = kctl->private_data;
|
||||
unsigned int *container;
|
||||
struct snd_ctl_elem_id id;
|
||||
unsigned int mask = 0;
|
||||
int i;
|
||||
int change;
|
||||
|
||||
if (op_flag == SNDRV_CTL_TLV_OP_WRITE) {
|
||||
if (size > 1024 * 128) /* sane value */
|
||||
return -EINVAL;
|
||||
if (size > 1024 * 128) /* sane value */
|
||||
return -EINVAL;
|
||||
|
||||
new_data = memdup_user(tlv, size);
|
||||
if (IS_ERR(new_data))
|
||||
return PTR_ERR(new_data);
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
change = ue->tlv_data_size != size;
|
||||
if (!change)
|
||||
change = memcmp(ue->tlv_data, new_data, size) != 0;
|
||||
kfree(ue->tlv_data);
|
||||
ue->tlv_data = new_data;
|
||||
ue->tlv_data_size = size;
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
} else {
|
||||
int ret = 0;
|
||||
container = memdup_user(buf, size);
|
||||
if (IS_ERR(container))
|
||||
return PTR_ERR(container);
|
||||
|
||||
mutex_lock(&ue->card->user_ctl_lock);
|
||||
if (!ue->tlv_data_size || !ue->tlv_data) {
|
||||
ret = -ENXIO;
|
||||
goto err_unlock;
|
||||
}
|
||||
if (size < ue->tlv_data_size) {
|
||||
ret = -ENOSPC;
|
||||
goto err_unlock;
|
||||
}
|
||||
if (copy_to_user(tlv, ue->tlv_data, ue->tlv_data_size))
|
||||
ret = -EFAULT;
|
||||
err_unlock:
|
||||
mutex_unlock(&ue->card->user_ctl_lock);
|
||||
if (ret)
|
||||
return ret;
|
||||
change = ue->tlv_data_size != size;
|
||||
if (!change)
|
||||
change = memcmp(ue->tlv_data, container, size) != 0;
|
||||
if (!change) {
|
||||
kfree(container);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ue->tlv_data == NULL) {
|
||||
/* Now TLV data is available. */
|
||||
for (i = 0; i < kctl->count; ++i)
|
||||
kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
||||
mask = SNDRV_CTL_EVENT_MASK_INFO;
|
||||
}
|
||||
|
||||
kfree(ue->tlv_data);
|
||||
ue->tlv_data = container;
|
||||
ue->tlv_data_size = size;
|
||||
|
||||
mask |= SNDRV_CTL_EVENT_MASK_TLV;
|
||||
for (i = 0; i < kctl->count; ++i) {
|
||||
snd_ctl_build_ioff(&id, kctl, i);
|
||||
snd_ctl_notify(ue->card, mask, &id);
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
static int read_user_tlv(struct snd_kcontrol *kctl, unsigned int __user *buf,
|
||||
unsigned int size)
|
||||
{
|
||||
struct user_element *ue = kctl->private_data;
|
||||
|
||||
if (ue->tlv_data_size == 0 || ue->tlv_data == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
if (size < ue->tlv_data_size)
|
||||
return -ENOSPC;
|
||||
|
||||
if (copy_to_user(buf, ue->tlv_data, ue->tlv_data_size))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kctl, int op_flag,
|
||||
unsigned int size, unsigned int __user *buf)
|
||||
{
|
||||
if (op_flag == SNDRV_CTL_TLV_OP_WRITE)
|
||||
return replace_user_tlv(kctl, buf, size);
|
||||
else
|
||||
return read_user_tlv(kctl, buf, size);
|
||||
}
|
||||
|
||||
static int snd_ctl_elem_init_enum_names(struct user_element *ue)
|
||||
{
|
||||
char *names, *p;
|
||||
@@ -1267,8 +1290,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
|
||||
access &= (SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_INACTIVE |
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE);
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_WRITE);
|
||||
|
||||
/* In initial state, nothing is available as TLV container. */
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
|
||||
@@ -1331,7 +1356,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
kctl->get = snd_ctl_elem_user_get;
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_WRITE)
|
||||
kctl->put = snd_ctl_elem_user_put;
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE)
|
||||
if (access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE)
|
||||
kctl->tlv.c = snd_ctl_elem_user_tlv;
|
||||
|
||||
/* This function manage to free the instance on failure. */
|
||||
@@ -1405,71 +1430,107 @@ static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int call_tlv_handler(struct snd_ctl_file *file, int op_flag,
|
||||
struct snd_kcontrol *kctl,
|
||||
struct snd_ctl_elem_id *id,
|
||||
unsigned int __user *buf, unsigned int size)
|
||||
{
|
||||
static const struct {
|
||||
int op;
|
||||
int perm;
|
||||
} pairs[] = {
|
||||
{SNDRV_CTL_TLV_OP_READ, SNDRV_CTL_ELEM_ACCESS_TLV_READ},
|
||||
{SNDRV_CTL_TLV_OP_WRITE, SNDRV_CTL_ELEM_ACCESS_TLV_WRITE},
|
||||
{SNDRV_CTL_TLV_OP_CMD, SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND},
|
||||
};
|
||||
struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
|
||||
int i;
|
||||
|
||||
/* Check support of the request for this element. */
|
||||
for (i = 0; i < ARRAY_SIZE(pairs); ++i) {
|
||||
if (op_flag == pairs[i].op && (vd->access & pairs[i].perm))
|
||||
break;
|
||||
}
|
||||
if (i == ARRAY_SIZE(pairs))
|
||||
return -ENXIO;
|
||||
|
||||
if (kctl->tlv.c == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
/* When locked, this is unavailable. */
|
||||
if (vd->owner != NULL && vd->owner != file)
|
||||
return -EPERM;
|
||||
|
||||
return kctl->tlv.c(kctl, op_flag, size, buf);
|
||||
}
|
||||
|
||||
static int read_tlv_buf(struct snd_kcontrol *kctl, struct snd_ctl_elem_id *id,
|
||||
unsigned int __user *buf, unsigned int size)
|
||||
{
|
||||
struct snd_kcontrol_volatile *vd = &kctl->vd[snd_ctl_get_ioff(kctl, id)];
|
||||
unsigned int len;
|
||||
|
||||
if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ))
|
||||
return -ENXIO;
|
||||
|
||||
if (kctl->tlv.p == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
len = sizeof(unsigned int) * 2 + kctl->tlv.p[1];
|
||||
if (size < len)
|
||||
return -ENOMEM;
|
||||
|
||||
if (copy_to_user(buf, kctl->tlv.p, len))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
|
||||
struct snd_ctl_tlv __user *_tlv,
|
||||
struct snd_ctl_tlv __user *buf,
|
||||
int op_flag)
|
||||
{
|
||||
struct snd_card *card = file->card;
|
||||
struct snd_ctl_tlv tlv;
|
||||
struct snd_ctl_tlv header;
|
||||
unsigned int *container;
|
||||
unsigned int container_size;
|
||||
struct snd_kcontrol *kctl;
|
||||
struct snd_ctl_elem_id id;
|
||||
struct snd_kcontrol_volatile *vd;
|
||||
unsigned int len;
|
||||
int err = 0;
|
||||
|
||||
if (copy_from_user(&tlv, _tlv, sizeof(tlv)))
|
||||
if (copy_from_user(&header, buf, sizeof(header)))
|
||||
return -EFAULT;
|
||||
if (tlv.length < sizeof(unsigned int) * 2)
|
||||
|
||||
/* In design of control core, numerical ID starts at 1. */
|
||||
if (header.numid == 0)
|
||||
return -EINVAL;
|
||||
if (!tlv.numid)
|
||||
|
||||
/* At least, container should include type and length fields. */
|
||||
if (header.length < sizeof(unsigned int) * 2)
|
||||
return -EINVAL;
|
||||
down_read(&card->controls_rwsem);
|
||||
kctl = snd_ctl_find_numid(card, tlv.numid);
|
||||
if (kctl == NULL) {
|
||||
err = -ENOENT;
|
||||
goto __kctl_end;
|
||||
}
|
||||
if (kctl->tlv.p == NULL) {
|
||||
err = -ENXIO;
|
||||
goto __kctl_end;
|
||||
}
|
||||
vd = &kctl->vd[tlv.numid - kctl->id.numid];
|
||||
if ((op_flag == SNDRV_CTL_TLV_OP_READ &&
|
||||
(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) == 0) ||
|
||||
(op_flag == SNDRV_CTL_TLV_OP_WRITE &&
|
||||
(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) == 0) ||
|
||||
(op_flag == SNDRV_CTL_TLV_OP_CMD &&
|
||||
(vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND) == 0)) {
|
||||
err = -ENXIO;
|
||||
goto __kctl_end;
|
||||
}
|
||||
container_size = header.length;
|
||||
container = buf->tlv;
|
||||
|
||||
kctl = snd_ctl_find_numid(file->card, header.numid);
|
||||
if (kctl == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
/* Calculate index of the element in this set. */
|
||||
id = kctl->id;
|
||||
snd_ctl_build_ioff(&id, kctl, header.numid - id.numid);
|
||||
vd = &kctl->vd[snd_ctl_get_ioff(kctl, &id)];
|
||||
|
||||
if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
|
||||
if (vd->owner != NULL && vd->owner != file) {
|
||||
err = -EPERM;
|
||||
goto __kctl_end;
|
||||
}
|
||||
err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv);
|
||||
if (err > 0) {
|
||||
struct snd_ctl_elem_id id = kctl->id;
|
||||
up_read(&card->controls_rwsem);
|
||||
snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &id);
|
||||
return 0;
|
||||
}
|
||||
return call_tlv_handler(file, op_flag, kctl, &id, container,
|
||||
container_size);
|
||||
} else {
|
||||
if (op_flag != SNDRV_CTL_TLV_OP_READ) {
|
||||
err = -ENXIO;
|
||||
goto __kctl_end;
|
||||
if (op_flag == SNDRV_CTL_TLV_OP_READ) {
|
||||
return read_tlv_buf(kctl, &id, container,
|
||||
container_size);
|
||||
}
|
||||
len = kctl->tlv.p[1] + 2 * sizeof(unsigned int);
|
||||
if (tlv.length < len) {
|
||||
err = -ENOMEM;
|
||||
goto __kctl_end;
|
||||
}
|
||||
if (copy_to_user(_tlv->tlv, kctl->tlv.p, len))
|
||||
err = -EFAULT;
|
||||
}
|
||||
__kctl_end:
|
||||
up_read(&card->controls_rwsem);
|
||||
return err;
|
||||
|
||||
/* Not supported. */
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
@@ -1511,11 +1572,20 @@ static long snd_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg
|
||||
case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
|
||||
return snd_ctl_subscribe_events(ctl, ip);
|
||||
case SNDRV_CTL_IOCTL_TLV_READ:
|
||||
return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
|
||||
down_read(&ctl->card->controls_rwsem);
|
||||
err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_READ);
|
||||
up_read(&ctl->card->controls_rwsem);
|
||||
return err;
|
||||
case SNDRV_CTL_IOCTL_TLV_WRITE:
|
||||
return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
|
||||
down_write(&ctl->card->controls_rwsem);
|
||||
err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_WRITE);
|
||||
up_write(&ctl->card->controls_rwsem);
|
||||
return err;
|
||||
case SNDRV_CTL_IOCTL_TLV_COMMAND:
|
||||
return snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
|
||||
down_write(&ctl->card->controls_rwsem);
|
||||
err = snd_ctl_tlv_ioctl(ctl, argp, SNDRV_CTL_TLV_OP_CMD);
|
||||
up_write(&ctl->card->controls_rwsem);
|
||||
return err;
|
||||
case SNDRV_CTL_IOCTL_POWER:
|
||||
return -ENOPROTOOPT;
|
||||
case SNDRV_CTL_IOCTL_POWER_STATE:
|
||||
|
||||
+15
-19
@@ -111,12 +111,10 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl,
|
||||
if (get_user(data->value.enumerated.item, &data32->value.enumerated.item))
|
||||
goto error;
|
||||
|
||||
snd_power_lock(ctl->card);
|
||||
err = snd_power_wait(ctl->card, SNDRV_CTL_POWER_D0);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_info(ctl, data);
|
||||
snd_power_unlock(ctl->card);
|
||||
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = snd_ctl_elem_info(ctl, data);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
/* restore info to 32bit */
|
||||
@@ -315,14 +313,13 @@ static int ctl_elem_read_user(struct snd_card *card,
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
snd_power_lock(card);
|
||||
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_read(card, data);
|
||||
snd_power_unlock(card);
|
||||
if (err >= 0)
|
||||
err = copy_ctl_value_to_user(userdata, valuep, data,
|
||||
type, count);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = snd_ctl_elem_read(card, data);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
|
||||
error:
|
||||
kfree(data);
|
||||
return err;
|
||||
@@ -344,14 +341,13 @@ static int ctl_elem_write_user(struct snd_ctl_file *file,
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
snd_power_lock(card);
|
||||
err = snd_power_wait(card, SNDRV_CTL_POWER_D0);
|
||||
if (err >= 0)
|
||||
err = snd_ctl_elem_write(card, file, data);
|
||||
snd_power_unlock(card);
|
||||
if (err >= 0)
|
||||
err = copy_ctl_value_to_user(userdata, valuep, data,
|
||||
type, count);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = snd_ctl_elem_write(card, file, data);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
err = copy_ctl_value_to_user(userdata, valuep, data, type, count);
|
||||
error:
|
||||
kfree(data);
|
||||
return err;
|
||||
|
||||
@@ -248,13 +248,11 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
|
||||
INIT_LIST_HEAD(&card->devices);
|
||||
init_rwsem(&card->controls_rwsem);
|
||||
rwlock_init(&card->ctl_files_rwlock);
|
||||
mutex_init(&card->user_ctl_lock);
|
||||
INIT_LIST_HEAD(&card->controls);
|
||||
INIT_LIST_HEAD(&card->ctl_files);
|
||||
spin_lock_init(&card->files_lock);
|
||||
INIT_LIST_HEAD(&card->files_list);
|
||||
#ifdef CONFIG_PM
|
||||
mutex_init(&card->power_lock);
|
||||
init_waitqueue_head(&card->power_sleep);
|
||||
#endif
|
||||
|
||||
@@ -979,8 +977,6 @@ EXPORT_SYMBOL(snd_card_file_remove);
|
||||
* Waits until the power-state is changed.
|
||||
*
|
||||
* Return: Zero if successful, or a negative error code.
|
||||
*
|
||||
* Note: the power lock must be active before call.
|
||||
*/
|
||||
int snd_power_wait(struct snd_card *card, unsigned int power_state)
|
||||
{
|
||||
@@ -1000,9 +996,7 @@ int snd_power_wait(struct snd_card *card, unsigned int power_state)
|
||||
if (snd_power_get_state(card) == power_state)
|
||||
break;
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
snd_power_unlock(card);
|
||||
schedule_timeout(30 * HZ);
|
||||
snd_power_lock(card);
|
||||
}
|
||||
remove_wait_queue(&card->power_sleep, &wait);
|
||||
return result;
|
||||
|
||||
+42
-27
@@ -523,7 +523,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
|
||||
|
||||
sprintf(name, "pcm%i%c", pcm->device,
|
||||
pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
|
||||
if ((entry = snd_info_create_card_entry(pcm->card, name, pcm->card->proc_root)) == NULL)
|
||||
entry = snd_info_create_card_entry(pcm->card, name,
|
||||
pcm->card->proc_root);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -531,8 +533,8 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
pstr->proc_root = entry;
|
||||
|
||||
if ((entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
@@ -542,8 +544,9 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
|
||||
pstr->proc_info_entry = entry;
|
||||
|
||||
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
|
||||
if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
|
||||
pstr->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
|
||||
pstr->proc_root);
|
||||
if (entry) {
|
||||
entry->c.text.read = snd_pcm_xrun_debug_read;
|
||||
entry->c.text.write = snd_pcm_xrun_debug_write;
|
||||
entry->mode |= S_IWUSR;
|
||||
@@ -580,7 +583,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
||||
card = substream->pcm->card;
|
||||
|
||||
sprintf(name, "sub%i", substream->number);
|
||||
if ((entry = snd_info_create_card_entry(card, name, substream->pstr->proc_root)) == NULL)
|
||||
entry = snd_info_create_card_entry(card, name,
|
||||
substream->pstr->proc_root);
|
||||
if (!entry)
|
||||
return -ENOMEM;
|
||||
entry->mode = S_IFDIR | S_IRUGO | S_IXUGO;
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -588,8 +593,8 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
||||
return -ENOMEM;
|
||||
}
|
||||
substream->proc_root = entry;
|
||||
|
||||
if ((entry = snd_info_create_card_entry(card, "info", substream->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(card, "info", substream->proc_root);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, substream,
|
||||
snd_pcm_substream_proc_info_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -598,8 +603,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
||||
}
|
||||
}
|
||||
substream->proc_info_entry = entry;
|
||||
|
||||
if ((entry = snd_info_create_card_entry(card, "hw_params", substream->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(card, "hw_params",
|
||||
substream->proc_root);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, substream,
|
||||
snd_pcm_substream_proc_hw_params_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -608,8 +614,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
||||
}
|
||||
}
|
||||
substream->proc_hw_params_entry = entry;
|
||||
|
||||
if ((entry = snd_info_create_card_entry(card, "sw_params", substream->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(card, "sw_params",
|
||||
substream->proc_root);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, substream,
|
||||
snd_pcm_substream_proc_sw_params_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -618,8 +625,9 @@ static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
|
||||
}
|
||||
}
|
||||
substream->proc_sw_params_entry = entry;
|
||||
|
||||
if ((entry = snd_info_create_card_entry(card, "status", substream->proc_root)) != NULL) {
|
||||
entry = snd_info_create_card_entry(card, "status",
|
||||
substream->proc_root);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, substream,
|
||||
snd_pcm_substream_proc_status_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
@@ -783,21 +791,27 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
|
||||
INIT_LIST_HEAD(&pcm->list);
|
||||
if (id)
|
||||
strlcpy(pcm->id, id, sizeof(pcm->id));
|
||||
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) {
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count)) < 0) {
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
if ((err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)) < 0) {
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
|
||||
playback_count);
|
||||
if (err < 0)
|
||||
goto free_pcm;
|
||||
|
||||
err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);
|
||||
if (err < 0)
|
||||
goto free_pcm;
|
||||
|
||||
err = snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops);
|
||||
if (err < 0)
|
||||
goto free_pcm;
|
||||
|
||||
if (rpcm)
|
||||
*rpcm = pcm;
|
||||
return 0;
|
||||
|
||||
free_pcm:
|
||||
snd_pcm_free(pcm);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1224,7 +1238,8 @@ static void snd_pcm_proc_init(void)
|
||||
{
|
||||
struct snd_info_entry *entry;
|
||||
|
||||
if ((entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL)) != NULL) {
|
||||
entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);
|
||||
if (entry) {
|
||||
snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
|
||||
if (snd_info_register(entry) < 0) {
|
||||
snd_info_free_entry(entry);
|
||||
|
||||
@@ -689,10 +689,7 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
|
||||
case SNDRV_PCM_IOCTL_XRUN:
|
||||
case SNDRV_PCM_IOCTL_LINK:
|
||||
case SNDRV_PCM_IOCTL_UNLINK:
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
return snd_pcm_playback_ioctl1(file, substream, cmd, argp);
|
||||
else
|
||||
return snd_pcm_capture_ioctl1(file, substream, cmd, argp);
|
||||
return snd_pcm_common_ioctl(file, substream, cmd, argp);
|
||||
case SNDRV_PCM_IOCTL_HW_REFINE32:
|
||||
return snd_pcm_ioctl_hw_params_compat(substream, 1, argp);
|
||||
case SNDRV_PCM_IOCTL_HW_PARAMS32:
|
||||
|
||||
+112
-203
@@ -1830,7 +1830,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
|
||||
add_wait_queue(&to_check->sleep, &wait);
|
||||
snd_pcm_stream_unlock_irq(substream);
|
||||
up_read(&snd_pcm_link_rwsem);
|
||||
snd_power_unlock(card);
|
||||
if (runtime->no_period_wakeup)
|
||||
tout = MAX_SCHEDULE_TIMEOUT;
|
||||
else {
|
||||
@@ -1842,7 +1841,6 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
|
||||
tout = msecs_to_jiffies(tout * 1000);
|
||||
}
|
||||
tout = schedule_timeout_interruptible(tout);
|
||||
snd_power_lock(card);
|
||||
down_read(&snd_pcm_link_rwsem);
|
||||
snd_pcm_stream_lock_irq(substream);
|
||||
remove_wait_queue(&to_check->sleep, &wait);
|
||||
@@ -2763,12 +2761,106 @@ static int snd_pcm_tstamp(struct snd_pcm_substream *substream, int __user *_arg)
|
||||
runtime->tstamp_type = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int snd_pcm_xferi_frames_ioctl(struct snd_pcm_substream *substream,
|
||||
struct snd_xferi __user *_xferi)
|
||||
{
|
||||
struct snd_xferi xferi;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (put_user(0, &_xferi->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
|
||||
else
|
||||
result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
|
||||
__put_user(result, &_xferi->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_xfern_frames_ioctl(struct snd_pcm_substream *substream,
|
||||
struct snd_xfern __user *_xfern)
|
||||
{
|
||||
struct snd_xfern xfern;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
void *bufs;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (runtime->channels > 128)
|
||||
return -EINVAL;
|
||||
if (put_user(0, &_xfern->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
|
||||
return -EFAULT;
|
||||
|
||||
bufs = memdup_user(xfern.bufs, sizeof(void *) * runtime->channels);
|
||||
if (IS_ERR(bufs))
|
||||
return PTR_ERR(bufs);
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
|
||||
else
|
||||
result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
|
||||
kfree(bufs);
|
||||
__put_user(result, &_xfern->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_rewind_ioctl(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t __user *_frames)
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_playback_rewind(substream, frames);
|
||||
else
|
||||
result = snd_pcm_capture_rewind(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_forward_ioctl(struct snd_pcm_substream *substream,
|
||||
snd_pcm_uframes_t __user *_frames)
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_sframes_t result;
|
||||
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
result = snd_pcm_playback_forward(substream, frames);
|
||||
else
|
||||
result = snd_pcm_capture_forward(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
|
||||
static int snd_pcm_common_ioctl(struct file *file,
|
||||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file = file->private_data;
|
||||
int res;
|
||||
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
|
||||
res = snd_power_wait(substream->pcm->card, SNDRV_CTL_POWER_D0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_PVERSION:
|
||||
@@ -2841,188 +2933,23 @@ static int snd_pcm_common_ioctl(struct file *file,
|
||||
return snd_pcm_action_lock_irq(&snd_pcm_action_pause,
|
||||
substream,
|
||||
(int)(unsigned long)arg);
|
||||
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
|
||||
case SNDRV_PCM_IOCTL_READI_FRAMES:
|
||||
return snd_pcm_xferi_frames_ioctl(substream, arg);
|
||||
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
|
||||
case SNDRV_PCM_IOCTL_READN_FRAMES:
|
||||
return snd_pcm_xfern_frames_ioctl(substream, arg);
|
||||
case SNDRV_PCM_IOCTL_REWIND:
|
||||
return snd_pcm_rewind_ioctl(substream, arg);
|
||||
case SNDRV_PCM_IOCTL_FORWARD:
|
||||
return snd_pcm_forward_ioctl(substream, arg);
|
||||
}
|
||||
pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
|
||||
return -ENOTTY;
|
||||
}
|
||||
|
||||
static int snd_pcm_common_ioctl1(struct file *file,
|
||||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
struct snd_card *card = substream->pcm->card;
|
||||
int res;
|
||||
|
||||
snd_power_lock(card);
|
||||
res = snd_power_wait(card, SNDRV_CTL_POWER_D0);
|
||||
if (res >= 0)
|
||||
res = snd_pcm_common_ioctl(file, substream, cmd, arg);
|
||||
snd_power_unlock(card);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int snd_pcm_playback_ioctl1(struct file *file,
|
||||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_PLAYBACK))
|
||||
return -EINVAL;
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
|
||||
{
|
||||
struct snd_xferi xferi;
|
||||
struct snd_xferi __user *_xferi = arg;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t result;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (put_user(0, &_xferi->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
|
||||
__put_user(result, &_xferi->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
|
||||
{
|
||||
struct snd_xfern xfern;
|
||||
struct snd_xfern __user *_xfern = arg;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
void __user **bufs;
|
||||
snd_pcm_sframes_t result;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (runtime->channels > 128)
|
||||
return -EINVAL;
|
||||
if (put_user(0, &_xfern->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
|
||||
return -EFAULT;
|
||||
|
||||
bufs = memdup_user(xfern.bufs,
|
||||
sizeof(void *) * runtime->channels);
|
||||
if (IS_ERR(bufs))
|
||||
return PTR_ERR(bufs);
|
||||
result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
|
||||
kfree(bufs);
|
||||
__put_user(result, &_xfern->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_REWIND:
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_uframes_t __user *_frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_playback_rewind(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_FORWARD:
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_uframes_t __user *_frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_playback_forward(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
}
|
||||
return snd_pcm_common_ioctl1(file, substream, cmd, arg);
|
||||
}
|
||||
|
||||
static int snd_pcm_capture_ioctl1(struct file *file,
|
||||
struct snd_pcm_substream *substream,
|
||||
unsigned int cmd, void __user *arg)
|
||||
{
|
||||
if (PCM_RUNTIME_CHECK(substream))
|
||||
return -ENXIO;
|
||||
if (snd_BUG_ON(substream->stream != SNDRV_PCM_STREAM_CAPTURE))
|
||||
return -EINVAL;
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_READI_FRAMES:
|
||||
{
|
||||
struct snd_xferi xferi;
|
||||
struct snd_xferi __user *_xferi = arg;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
snd_pcm_sframes_t result;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (put_user(0, &_xferi->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xferi, _xferi, sizeof(xferi)))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_lib_read(substream, xferi.buf, xferi.frames);
|
||||
__put_user(result, &_xferi->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_READN_FRAMES:
|
||||
{
|
||||
struct snd_xfern xfern;
|
||||
struct snd_xfern __user *_xfern = arg;
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
void *bufs;
|
||||
snd_pcm_sframes_t result;
|
||||
if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
|
||||
return -EBADFD;
|
||||
if (runtime->channels > 128)
|
||||
return -EINVAL;
|
||||
if (put_user(0, &_xfern->result))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
|
||||
return -EFAULT;
|
||||
|
||||
bufs = memdup_user(xfern.bufs,
|
||||
sizeof(void *) * runtime->channels);
|
||||
if (IS_ERR(bufs))
|
||||
return PTR_ERR(bufs);
|
||||
result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
|
||||
kfree(bufs);
|
||||
__put_user(result, &_xfern->result);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_REWIND:
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_uframes_t __user *_frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_capture_rewind(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_FORWARD:
|
||||
{
|
||||
snd_pcm_uframes_t frames;
|
||||
snd_pcm_uframes_t __user *_frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
if (get_user(frames, _frames))
|
||||
return -EFAULT;
|
||||
if (put_user(0, _frames))
|
||||
return -EFAULT;
|
||||
result = snd_pcm_capture_forward(substream, frames);
|
||||
__put_user(result, _frames);
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
}
|
||||
return snd_pcm_common_ioctl1(file, substream, cmd, arg);
|
||||
}
|
||||
|
||||
static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
static long snd_pcm_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file;
|
||||
|
||||
@@ -3031,22 +2958,8 @@ static long snd_pcm_playback_ioctl(struct file *file, unsigned int cmd,
|
||||
if (((cmd >> 8) & 0xff) != 'A')
|
||||
return -ENOTTY;
|
||||
|
||||
return snd_pcm_playback_ioctl1(file, pcm_file->substream, cmd,
|
||||
(void __user *)arg);
|
||||
}
|
||||
|
||||
static long snd_pcm_capture_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct snd_pcm_file *pcm_file;
|
||||
|
||||
pcm_file = file->private_data;
|
||||
|
||||
if (((cmd >> 8) & 0xff) != 'A')
|
||||
return -ENOTTY;
|
||||
|
||||
return snd_pcm_capture_ioctl1(file, pcm_file->substream, cmd,
|
||||
(void __user *)arg);
|
||||
return snd_pcm_common_ioctl(file, pcm_file->substream, cmd,
|
||||
(void __user *)arg);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3064,7 +2977,6 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
|
||||
{
|
||||
snd_pcm_uframes_t *frames = arg;
|
||||
snd_pcm_sframes_t result;
|
||||
int err;
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_IOCTL_FORWARD:
|
||||
@@ -3084,10 +2996,7 @@ int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
|
||||
case SNDRV_PCM_IOCTL_START:
|
||||
return snd_pcm_start_lock_irq(substream);
|
||||
case SNDRV_PCM_IOCTL_DRAIN:
|
||||
snd_power_lock(substream->pcm->card);
|
||||
err = snd_pcm_drain(substream, NULL);
|
||||
snd_power_unlock(substream->pcm->card);
|
||||
return err;
|
||||
return snd_pcm_drain(substream, NULL);
|
||||
case SNDRV_PCM_IOCTL_DROP:
|
||||
return snd_pcm_drop(substream);
|
||||
case SNDRV_PCM_IOCTL_DELAY:
|
||||
@@ -3791,7 +3700,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
||||
.release = snd_pcm_release,
|
||||
.llseek = no_llseek,
|
||||
.poll = snd_pcm_playback_poll,
|
||||
.unlocked_ioctl = snd_pcm_playback_ioctl,
|
||||
.unlocked_ioctl = snd_pcm_ioctl,
|
||||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
.fasync = snd_pcm_fasync,
|
||||
@@ -3805,7 +3714,7 @@ const struct file_operations snd_pcm_f_ops[2] = {
|
||||
.release = snd_pcm_release,
|
||||
.llseek = no_llseek,
|
||||
.poll = snd_pcm_capture_poll,
|
||||
.unlocked_ioctl = snd_pcm_capture_ioctl,
|
||||
.unlocked_ioctl = snd_pcm_ioctl,
|
||||
.compat_ioctl = snd_pcm_ioctl_compat,
|
||||
.mmap = snd_pcm_mmap,
|
||||
.fasync = snd_pcm_fasync,
|
||||
|
||||
+8
-5
@@ -393,7 +393,8 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
|
||||
|
||||
if (timeri == NULL)
|
||||
return 0;
|
||||
if ((timer = timeri->timer) != NULL) {
|
||||
timer = timeri->timer;
|
||||
if (timer) {
|
||||
if (timer->hw.c_resolution)
|
||||
return timer->hw.c_resolution(timer);
|
||||
return timer->hw.resolution;
|
||||
@@ -2096,8 +2097,7 @@ static int __init alsa_timer_init(void)
|
||||
err = snd_timer_register_system();
|
||||
if (err < 0) {
|
||||
pr_err("ALSA: unable to register system timer (%i)\n", err);
|
||||
put_device(&timer_dev);
|
||||
return err;
|
||||
goto put_timer;
|
||||
}
|
||||
|
||||
err = snd_register_device(SNDRV_DEVICE_TYPE_TIMER, NULL, 0,
|
||||
@@ -2105,12 +2105,15 @@ static int __init alsa_timer_init(void)
|
||||
if (err < 0) {
|
||||
pr_err("ALSA: unable to register timer device (%i)\n", err);
|
||||
snd_timer_free_all();
|
||||
put_device(&timer_dev);
|
||||
return err;
|
||||
goto put_timer;
|
||||
}
|
||||
|
||||
snd_timer_proc_init();
|
||||
return 0;
|
||||
|
||||
put_timer:
|
||||
put_device(&timer_dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit alsa_timer_exit(void)
|
||||
|
||||
@@ -561,7 +561,7 @@ static snd_pcm_uframes_t loopback_pointer(struct snd_pcm_substream *substream)
|
||||
return bytes_to_frames(runtime, pos);
|
||||
}
|
||||
|
||||
static struct snd_pcm_hardware loopback_pcm_hardware =
|
||||
static const struct snd_pcm_hardware loopback_pcm_hardware =
|
||||
{
|
||||
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_PAUSE |
|
||||
@@ -750,7 +750,7 @@ static int loopback_close(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops loopback_playback_ops = {
|
||||
static const struct snd_pcm_ops loopback_playback_ops = {
|
||||
.open = loopback_open,
|
||||
.close = loopback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -763,7 +763,7 @@ static struct snd_pcm_ops loopback_playback_ops = {
|
||||
.mmap = snd_pcm_lib_mmap_vmalloc,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops loopback_capture_ops = {
|
||||
static const struct snd_pcm_ops loopback_capture_ops = {
|
||||
.open = loopback_open,
|
||||
.close = loopback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
||||
@@ -520,7 +520,7 @@ static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
|
||||
return get_dummy_ops(substream)->pointer(substream);
|
||||
}
|
||||
|
||||
static struct snd_pcm_hardware dummy_pcm_hardware = {
|
||||
static const struct snd_pcm_hardware dummy_pcm_hardware = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_RESUME |
|
||||
|
||||
@@ -373,7 +373,7 @@ struct snd_ml403_ac97cr {
|
||||
struct snd_pcm_indirect2 capture_ind2_rec;
|
||||
};
|
||||
|
||||
static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
|
||||
static const struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_MMAP_VALID),
|
||||
@@ -392,7 +392,7 @@ static struct snd_pcm_hardware snd_ml403_ac97cr_playback = {
|
||||
.fifo_size = 0,
|
||||
};
|
||||
|
||||
static struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
|
||||
static const struct snd_pcm_hardware snd_ml403_ac97cr_capture = {
|
||||
.info = (SNDRV_PCM_INFO_MMAP |
|
||||
SNDRV_PCM_INFO_INTERLEAVED |
|
||||
SNDRV_PCM_INFO_MMAP_VALID),
|
||||
@@ -759,7 +759,7 @@ static int snd_ml403_ac97cr_capture_close(struct snd_pcm_substream *substream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
|
||||
static const struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
|
||||
.open = snd_ml403_ac97cr_playback_open,
|
||||
.close = snd_ml403_ac97cr_playback_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
@@ -770,7 +770,7 @@ static struct snd_pcm_ops snd_ml403_ac97cr_playback_ops = {
|
||||
.pointer = snd_ml403_ac97cr_pcm_pointer,
|
||||
};
|
||||
|
||||
static struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
|
||||
static const struct snd_pcm_ops snd_ml403_ac97cr_capture_ops = {
|
||||
.open = snd_ml403_ac97cr_capture_open,
|
||||
.close = snd_ml403_ac97cr_capture_close,
|
||||
.ioctl = snd_pcm_lib_ioctl,
|
||||
|
||||
@@ -148,7 +148,7 @@ static struct platform_driver snd_mpu401_driver = {
|
||||
|
||||
#define IO_EXTENT 2
|
||||
|
||||
static struct pnp_device_id snd_mpu401_pnpids[] = {
|
||||
static const struct pnp_device_id snd_mpu401_pnpids[] = {
|
||||
{ .id = "PNPb006" },
|
||||
{ .id = "" }
|
||||
};
|
||||
|
||||
@@ -136,7 +136,7 @@ irqreturn_t snd_mpu401_uart_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct snd_mpu401 *mpu = dev_id;
|
||||
|
||||
if (mpu == NULL)
|
||||
if (!mpu)
|
||||
return IRQ_NONE;
|
||||
_snd_mpu401_uart_interrupt(mpu);
|
||||
return IRQ_HANDLED;
|
||||
@@ -157,7 +157,7 @@ irqreturn_t snd_mpu401_uart_interrupt_tx(int irq, void *dev_id)
|
||||
{
|
||||
struct snd_mpu401 *mpu = dev_id;
|
||||
|
||||
if (mpu == NULL)
|
||||
if (!mpu)
|
||||
return IRQ_NONE;
|
||||
uart_interrupt_tx(mpu);
|
||||
return IRQ_HANDLED;
|
||||
@@ -544,10 +544,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
||||
out_enable, in_enable, &rmidi)) < 0)
|
||||
return err;
|
||||
mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
|
||||
if (mpu == NULL) {
|
||||
snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
|
||||
snd_device_free(card, rmidi);
|
||||
return -ENOMEM;
|
||||
if (!mpu) {
|
||||
err = -ENOMEM;
|
||||
goto free_device;
|
||||
}
|
||||
rmidi->private_data = mpu;
|
||||
rmidi->private_free = snd_mpu401_uart_free;
|
||||
@@ -559,12 +558,12 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
||||
if (! (info_flags & MPU401_INFO_INTEGRATED)) {
|
||||
int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
|
||||
mpu->res = request_region(port, res_size, "MPU401 UART");
|
||||
if (mpu->res == NULL) {
|
||||
if (!mpu->res) {
|
||||
snd_printk(KERN_ERR "mpu401_uart: "
|
||||
"unable to grab port 0x%lx size %d\n",
|
||||
port, res_size);
|
||||
snd_device_free(card, rmidi);
|
||||
return -EBUSY;
|
||||
err = -EBUSY;
|
||||
goto free_device;
|
||||
}
|
||||
}
|
||||
if (info_flags & MPU401_INFO_MMIO) {
|
||||
@@ -584,8 +583,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
||||
"MPU401 UART", (void *) mpu)) {
|
||||
snd_printk(KERN_ERR "mpu401_uart: "
|
||||
"unable to grab IRQ %d\n", irq);
|
||||
snd_device_free(card, rmidi);
|
||||
return -EBUSY;
|
||||
err = -EBUSY;
|
||||
goto free_device;
|
||||
}
|
||||
}
|
||||
if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
|
||||
@@ -613,6 +612,9 @@ int snd_mpu401_uart_new(struct snd_card *card, int device,
|
||||
if (rrawmidi)
|
||||
*rrawmidi = rmidi;
|
||||
return 0;
|
||||
free_device:
|
||||
snd_device_free(card, rmidi);
|
||||
return err;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_mpu401_uart_new);
|
||||
|
||||
@@ -355,10 +355,8 @@ int snd_opl3_new(struct snd_card *card,
|
||||
|
||||
*ropl3 = NULL;
|
||||
opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
|
||||
if (opl3 == NULL) {
|
||||
snd_printk(KERN_ERR "opl3: cannot allocate\n");
|
||||
if (!opl3)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
opl3->card = card;
|
||||
opl3->hardware = hardware;
|
||||
|
||||
@@ -131,8 +131,8 @@ static void debug_alloc(struct snd_opl3 *opl3, char *s, int voice) {
|
||||
|
||||
printk(KERN_DEBUG "time %.5i: %s [%.2i]: ", opl3->use_time, s, voice);
|
||||
for (i = 0; i < opl3->max_voices; i++)
|
||||
printk("%c", *(str + opl3->voices[i].state + 1));
|
||||
printk("\n");
|
||||
printk(KERN_CONT "%c", *(str + opl3->voices[i].state + 1));
|
||||
printk(KERN_CONT "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user