diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-05-27 16:46:14 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-05-27 16:46:14 +0200 |
commit | 7ef61883beba68b9c7c1ecb47c0f917273f4d220 (patch) | |
tree | b5ce99a168e0369e2ba6a8851f33062d8f76afc7 | |
parent | 0ee5f47624ac97fdae56d6c79e19a9324b729fa0 (diff) | |
download | salsa-lib-7ef61883beba68b9c7c1ecb47c0f917273f4d220.tar.gz |
Use a common helper for opening subdevice for PCM and rawmidi
-rw-r--r-- | src/cards.c | 27 | ||||
-rw-r--r-- | src/hwdep.c | 4 | ||||
-rw-r--r-- | src/local.h | 3 | ||||
-rw-r--r-- | src/pcm.c | 36 | ||||
-rw-r--r-- | src/rawmidi.c | 35 |
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); @@ -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) |