summaryrefslogtreecommitdiff
path: root/sound/core
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/hwdep.c9
-rw-r--r--sound/core/init.c47
-rw-r--r--sound/core/jack.c45
-rw-r--r--sound/core/misc.c10
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/oss/pcm_oss.c4
-rw-r--r--sound/core/sgbuf.c7
7 files changed, 72 insertions, 53 deletions
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 195cafc5a553..a70ee7f1ed98 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -99,9 +99,6 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
if (hw == NULL)
return -ENODEV;
- if (!hw->ops.open)
- return -ENXIO;
-
if (!try_module_get(hw->card->module))
return -EFAULT;
@@ -113,6 +110,10 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
err = -EBUSY;
break;
}
+ if (!hw->ops.open) {
+ err = 0;
+ break;
+ }
err = hw->ops.open(hw, file);
if (err >= 0)
break;
@@ -151,7 +152,7 @@ static int snd_hwdep_open(struct inode *inode, struct file * file)
static int snd_hwdep_release(struct inode *inode, struct file * file)
{
- int err = -ENXIO;
+ int err = 0;
struct snd_hwdep *hw = file->private_data;
struct module *mod = hw->card->module;
diff --git a/sound/core/init.c b/sound/core/init.c
index 05c6da554cbf..fd56afe846ed 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -121,31 +121,44 @@ static inline int init_info_for_card(struct snd_card *card)
#endif
/**
- * snd_card_new - create and initialize a soundcard structure
+ * snd_card_create - create and initialize a soundcard structure
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
* @xid: card identification (ASCII string)
* @module: top level module for locking
* @extra_size: allocate this extra size after the main soundcard structure
+ * @card_ret: the pointer to store the created card instance
*
* Creates and initializes a soundcard structure.
*
- * Returns kmallocated snd_card structure. Creates the ALSA control interface
- * (which is blocked until snd_card_register function is called).
+ * The function allocates snd_card instance via kzalloc with the given
+ * space for the driver to use freely. The allocated struct is stored
+ * in the given card_ret pointer.
+ *
+ * Returns zero if successful or a negative error code.
*/
-struct snd_card *snd_card_new(int idx, const char *xid,
- struct module *module, int extra_size)
+int snd_card_create(int idx, const char *xid,
+ struct module *module, int extra_size,
+ struct snd_card **card_ret)
{
struct snd_card *card;
int err, idx2;
+ if (snd_BUG_ON(!card_ret))
+ return -EINVAL;
+ *card_ret = NULL;
+
if (extra_size < 0)
extra_size = 0;
card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
- if (card == NULL)
- return NULL;
+ if (!card)
+ return -ENOMEM;
if (xid) {
- if (!snd_info_check_reserved_words(xid))
+ if (!snd_info_check_reserved_words(xid)) {
+ snd_printk(KERN_ERR
+ "given id string '%s' is reserved.\n", xid);
+ err = -EBUSY;
goto __error;
+ }
strlcpy(card->id, xid, sizeof(card->id));
}
err = 0;
@@ -203,26 +216,28 @@ struct snd_card *snd_card_new(int idx, const char *xid,
#endif
/* the control interface cannot be accessed from the user space until */
/* snd_cards_bitmask and snd_cards are set with snd_card_register */
- if ((err = snd_ctl_create(card)) < 0) {
- snd_printd("unable to register control minors\n");
+ err = snd_ctl_create(card);
+ if (err < 0) {
+ snd_printk(KERN_ERR "unable to register control minors\n");
goto __error;
}
- if ((err = snd_info_card_create(card)) < 0) {
- snd_printd("unable to create card info\n");
+ err = snd_info_card_create(card);
+ if (err < 0) {
+ snd_printk(KERN_ERR "unable to create card info\n");
goto __error_ctl;
}
if (extra_size > 0)
card->private_data = (char *)card + sizeof(struct snd_card);
- return card;
+ *card_ret = card;
+ return 0;
__error_ctl:
snd_device_free_all(card, SNDRV_DEV_CMD_PRE);
__error:
kfree(card);
- return NULL;
+ return err;
}
-
-EXPORT_SYMBOL(snd_card_new);
+EXPORT_SYMBOL(snd_card_create);
/* return non-zero if a card is already locked */
int snd_card_locked(int card)
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 077a85262c1c..c8254c667c62 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -23,6 +23,14 @@
#include <sound/jack.h>
#include <sound/core.h>
+static int jack_types[] = {
+ SW_HEADPHONE_INSERT,
+ SW_MICROPHONE_INSERT,
+ SW_LINEOUT_INSERT,
+ SW_JACK_PHYSICAL_INSERT,
+ SW_VIDEOOUT_INSERT,
+};
+
static int snd_jack_dev_free(struct snd_device *device)
{
struct snd_jack *jack = device->device_data;
@@ -79,6 +87,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
{
struct snd_jack *jack;
int err;
+ int i;
static struct snd_device_ops ops = {
.dev_free = snd_jack_dev_free,
.dev_register = snd_jack_dev_register,
@@ -100,18 +109,10 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
jack->type = type;
- if (type & SND_JACK_HEADPHONE)
- input_set_capability(jack->input_dev, EV_SW,
- SW_HEADPHONE_INSERT);
- if (type & SND_JACK_LINEOUT)
- input_set_capability(jack->input_dev, EV_SW,
- SW_LINEOUT_INSERT);
- if (type & SND_JACK_MICROPHONE)
- input_set_capability(jack->input_dev, EV_SW,
- SW_MICROPHONE_INSERT);
- if (type & SND_JACK_MECHANICAL)
- input_set_capability(jack->input_dev, EV_SW,
- SW_JACK_PHYSICAL_INSERT);
+ for (i = 0; i < ARRAY_SIZE(jack_types); i++)
+ if (type & (1 << i))
+ input_set_capability(jack->input_dev, EV_SW,
+ jack_types[i]);
err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
if (err < 0)
@@ -154,21 +155,17 @@ EXPORT_SYMBOL(snd_jack_set_parent);
*/
void snd_jack_report(struct snd_jack *jack, int status)
{
+ int i;
+
if (!jack)
return;
- if (jack->type & SND_JACK_HEADPHONE)
- input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
- status & SND_JACK_HEADPHONE);
- if (jack->type & SND_JACK_LINEOUT)
- input_report_switch(jack->input_dev, SW_LINEOUT_INSERT,
- status & SND_JACK_LINEOUT);
- if (jack->type & SND_JACK_MICROPHONE)
- input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
- status & SND_JACK_MICROPHONE);
- if (jack->type & SND_JACK_MECHANICAL)
- input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT,
- status & SND_JACK_MECHANICAL);
+ for (i = 0; i < ARRAY_SIZE(jack_types); i++) {
+ int testbit = 1 << i;
+ if (jack->type & testbit)
+ input_report_switch(jack->input_dev, jack_types[i],
+ status & testbit);
+ }
input_sync(jack->input_dev);
}
diff --git a/sound/core/misc.c b/sound/core/misc.c
index 38524f615d94..a9710e0c97af 100644
--- a/sound/core/misc.c
+++ b/sound/core/misc.c
@@ -95,12 +95,14 @@ snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
{
const struct snd_pci_quirk *q;
- for (q = list; q->subvendor; q++)
- if (q->subvendor == pci->subsystem_vendor &&
- (!q->subdevice || q->subdevice == pci->subsystem_device))
+ for (q = list; q->subvendor; q++) {
+ if (q->subvendor != pci->subsystem_vendor)
+ continue;
+ if (!q->subdevice ||
+ (pci->subsystem_device & q->subdevice_mask) == q->subdevice)
return q;
+ }
return NULL;
}
-
EXPORT_SYMBOL(snd_pci_quirk_lookup);
#endif
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 4690b8b5681f..e570649184e2 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -692,6 +692,9 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME)
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
+ } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) {
+ snd_mixer_oss_put_volume1_vol(fmixer, pslot,
+ slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) {
snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) {
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 0a1798eafb0b..699d2890535c 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2872,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
setup = kmalloc(sizeof(*setup), GFP_KERNEL);
if (! setup) {
buffer->error = -ENOMEM;
- mutex_lock(&pstr->oss.setup_mutex);
+ mutex_unlock(&pstr->oss.setup_mutex);
return;
}
if (pstr->oss.setup_list == NULL)
@@ -2886,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
if (! template.task_name) {
kfree(setup);
buffer->error = -ENOMEM;
- mutex_lock(&pstr->oss.setup_mutex);
+ mutex_unlock(&pstr->oss.setup_mutex);
return;
}
}
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index d4564edd61d7..4e7ec2b49873 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -38,6 +38,10 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
if (! sgbuf)
return -EINVAL;
+ if (dmab->area)
+ vunmap(dmab->area);
+ dmab->area = NULL;
+
tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
tmpb.dev.dev = sgbuf->dev;
for (i = 0; i < sgbuf->pages; i++) {
@@ -48,9 +52,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab)
tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT;
snd_dma_free_pages(&tmpb);
}
- if (dmab->area)
- vunmap(dmab->area);
- dmab->area = NULL;
kfree(sgbuf->table);
kfree(sgbuf->page_table);