aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-05-27 16:46:14 +0200
committerTakashi Iwai <tiwai@suse.de>2011-05-27 16:46:14 +0200
commit7ef61883beba68b9c7c1ecb47c0f917273f4d220 (patch)
treeb5ce99a168e0369e2ba6a8851f33062d8f76afc7
parent0ee5f47624ac97fdae56d6c79e19a9324b729fa0 (diff)
downloadsalsa-lib-7ef61883beba68b9c7c1ecb47c0f917273f4d220.tar.gz
Use a common helper for opening subdevice for PCM and rawmidi
-rw-r--r--src/cards.c27
-rw-r--r--src/hwdep.c4
-rw-r--r--src/local.h3
-rw-r--r--src/pcm.c36
-rw-r--r--src/rawmidi.c35
5 files changed, 40 insertions, 65 deletions
diff --git a/src/cards.c b/src/cards.c
index 6861fec..b44a194 100644
--- a/src/cards.c
+++ b/src/cards.c
@@ -77,11 +77,23 @@ int snd_card_next(int *rcard)
return 0;
}
-int _snd_ctl_hw_open(snd_ctl_t **ctlp, int card)
+/* open the substream with the given subdevice number */
+int _snd_open_subdev(const char *filename, int fmode,
+ int card, int subdev, unsigned int prefer_ioctl)
{
- char name[16];
- sprintf(name, "hw:%d", card);
- return snd_ctl_open(ctlp, name, 0);
+ char control[sizeof(SND_FILE_CONTROL) + 10];
+ int ctl, fd;
+
+ fill_control_name(control, card);
+ ctl = open(control, O_RDWR);
+ if (ctl < 0)
+ return -errno;
+ if (ioctl(ctl, prefer_ioctl, &subdev) >= 0)
+ fd = -1;
+ else
+ fd = open(filename, fmode);
+ close(ctl);
+ return fd < 0 ? -errno : fd;
}
static int load_card_info(const char *control, snd_ctl_card_info_t *info)
@@ -126,7 +138,7 @@ int snd_card_get_index(const char *string)
if (*string == '/') /* device name */
return snd_card_load2(string);
if (sscanf(string, "%i", &card) == 1) {
- if (card < 0 || card > 31)
+ if (card < 0 || card >= SALSA_MAX_CARDS)
return -EINVAL;
if (snd_card_load(card))
return card;
@@ -195,8 +207,11 @@ int _snd_dev_get_device(const char *name, int *cardp, int *devp, int *subdevp)
if (devp && subdevp) {
/* parse the secondary and third arguments (if any) */
name = strchr(name, ',');
- if (name)
+ if (name) {
sscanf(name, ",%d,%d", devp, subdevp);
+ if (*devp < 0 || *devp >= SALSA_MAX_DEVICES)
+ return -EINVAL;
+ }
}
return 0;
}
diff --git a/src/hwdep.c b/src/hwdep.c
index 14e76a7..704489c 100644
--- a/src/hwdep.c
+++ b/src/hwdep.c
@@ -41,10 +41,6 @@ int snd_hwdep_open(snd_hwdep_t **handlep, const char *name, int mode)
err = _snd_dev_get_device(name, &card, &device, NULL);
if (err < 0)
return err;
- if (card < 0 || card >= SALSA_MAX_CARDS)
- return -EINVAL;
- if (device < 0 || device >= SALSA_MAX_DEVICES)
- return -EINVAL;
snprintf(filename, sizeof(filename), "%s/hwC%dD%d",
SALSA_DEVPATH, card, device);
fd = open(filename, mode);
diff --git a/src/local.h b/src/local.h
index a038147..64ea15a 100644
--- a/src/local.h
+++ b/src/local.h
@@ -5,7 +5,8 @@
#define SALSA_MAX_DEVICES 32
int _snd_dev_get_device(const char *name, int *cardp, int *devp, int *subdevp);
-int _snd_ctl_hw_open(snd_ctl_t **ctlp, int card);
+int _snd_open_subdev(const char *filename, int fmode,
+ int card, int subdev, unsigned int prefer_ioctl);
int _snd_pcm_mmap(snd_pcm_t *pcm);
int _snd_pcm_munmap(snd_pcm_t *pcm);
diff --git a/src/pcm.c b/src/pcm.c
index f5c2128..8ea91e5 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -45,37 +45,10 @@ static int get_pcm_subdev(int fd)
snd_pcm_info_t info;
memzero_valgrind(&info, sizeof(info));
if (ioctl(fd, SNDRV_PCM_IOCTL_INFO, &info) < 0)
- return -errno;
+ return -1;
return info.subdevice;
}
-/* open the substream with the given subdevice number */
-static int open_with_subdev(const char *filename, int fmode,
- int card, int subdev)
-{
- snd_ctl_t *ctl;
- int err, fd;
-
- err = _snd_ctl_hw_open(&ctl, card);
- if (err < 0)
- return err;
-
- err = snd_ctl_pcm_prefer_subdevice(ctl, subdev);
- if (err < 0)
- return err;
-
- fd = open(filename, fmode);
- if (fd < 0)
- return -errno;
-
- if (get_pcm_subdev(fd) != subdev) {
- close(fd);
- fd = -EBUSY;
- }
- snd_ctl_close(ctl);
- return fd;
-}
-
int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_stream_t stream, int mode)
{
@@ -98,9 +71,14 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
fmode |= O_ASYNC;
if (subdev >= 0) {
- fd = open_with_subdev(filename, fmode, card, subdev);
+ fd = _snd_open_subdev(filename, fmode, card, subdev,
+ SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE);
if (fd < 0)
return fd;
+ if (get_pcm_subdev(fd) != subdev) {
+ close(fd);
+ return -EBUSY;
+ }
} else {
fd = open(filename, fmode);
if (fd < 0)
diff --git a/src/rawmidi.c b/src/rawmidi.c
index 45b3de2..e30ddf5 100644
--- a/src/rawmidi.c
+++ b/src/rawmidi.c
@@ -31,35 +31,15 @@
#include "control.h"
#include "local.h"
-static int open_with_subdev(const char *filename, int fmode,
- int card, int subdev)
+static int get_rawmidi_subdev(int fd, int fmode)
{
snd_rawmidi_info_t info;
- snd_ctl_t *ctl;
- int err, fd;
-
- err = _snd_ctl_hw_open(&ctl, card);
- if (err < 0)
- return err;
-
- err = snd_ctl_rawmidi_prefer_subdevice(ctl, subdev);
- if (err < 0)
- return err;
-
- fd = open(filename, fmode);
- if (fd < 0)
- return -errno;
memzero_valgrind(&info, sizeof(info));
info.stream = ((fmode & O_ACCMODE) != O_RDONLY) ?
SND_RAWMIDI_STREAM_OUTPUT : SND_RAWMIDI_STREAM_INPUT;
- if (ioctl(fd, SNDRV_RAWMIDI_IOCTL_INFO, &info) >= 0 &&
- info.subdevice == subdev) {
- snd_ctl_close(ctl);
- return fd;
- }
- close(fd);
- snd_ctl_close(ctl);
- return -EBUSY;
+ if (ioctl(fd, SNDRV_RAWMIDI_IOCTL_INFO, &info) < 0)
+ return -1;
+ return info.subdevice;
}
static snd_rawmidi_t *new_rmidi(snd_rawmidi_hw_t *hw, int stream, int mode)
@@ -119,9 +99,14 @@ int snd_rawmidi_open(snd_rawmidi_t **in_rmidi, snd_rawmidi_t **out_rmidi,
fmode |= O_SYNC;
if (subdev >= 0) {
- fd = open_with_subdev(filename, fmode, card, subdev);
+ fd = _snd_open_subdev(filename, fmode, card, subdev,
+ SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE);
if (fd < 0)
return fd;
+ if (get_rawmidi_subdev(fd, fmode) != subdev) {
+ close(fd);
+ return -EBUSY;
+ }
} else {
fd = open(filename, fmode);
if (fd < 0)