]> git.alsa-project.org Git - alsa-lib.git/commitdiff
MMAP changes (/dev/snd/pcmcontrol).
authorJaroslav Kysela <perex@perex.cz>
Sun, 26 Dec 1999 17:27:43 +0000 (17:27 +0000)
committerJaroslav Kysela <perex@perex.cz>
Sun, 26 Dec 1999 17:27:43 +0000 (17:27 +0000)
Removed unregister callback from snd_minor_t.

include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_local.h

index 32566e0b5a526beee321be7540bdb2ff1f4bf823..e6ffb772df826eed7f83a63d3ce8e51da4f39863 100644 (file)
@@ -8,10 +8,7 @@
 #define SND_PCM_OPEN_PLAYBACK          0x0001
 #define SND_PCM_OPEN_CAPTURE           0x0002
 #define SND_PCM_OPEN_DUPLEX            0x0003
-#define SND_PCM_OPEN_STREAM            0x1000
-#define SND_PCM_OPEN_STREAM_PLAYBACK   0x1001
-#define SND_PCM_OPEN_STREAM_CAPTURE    0x1002
-#define SND_PCM_OPEN_STREAM_DUPLEX     0x1003
+#define SND_PCM_OPEN_NONBLOCK          0x1000
 
 #ifdef __cplusplus
 extern "C" {
index 87e6a3d2130f9438835494e2dd45a1a20a6325ad..dd91f5b6cf9be82b473e0f5e2973ee3788b11e1c 100644 (file)
@@ -30,6 +30,7 @@
 #include "pcm_local.h"
 
 #define SND_FILE_PCM           "/dev/snd/pcmC%iD%i"
+#define SND_FILE_PCM_CONTROL   "/dev/snd/pcmcontrol"
 #define SND_PCM_VERSION_MAX    SND_PROTOCOL_VERSION(1, 0, 0)
 
 int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode)
@@ -37,13 +38,6 @@ int snd_pcm_open(snd_pcm_t **handle, int card, int device, int mode)
        return snd_pcm_open_subdevice(handle, card, device, -1, mode);
 }
 
-#ifndef O_WRITEFLG
-#define O_WRITEFLG     0x10000000
-#endif
-#ifndef O_READFLG
-#define O_READFLG      0x20000000
-#endif
-
 int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int mode)
 {
        int fd, fmode, ver, err, attempt = 0;
@@ -58,16 +52,18 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
                return -EINVAL;
        if ((err = snd_ctl_open(&ctl, card)) < 0)
                return err;
-       fmode = O_RDWR;
-       if (mode & SND_PCM_OPEN_PLAYBACK)
-               fmode |= O_WRITEFLG;
-       if (mode & SND_PCM_OPEN_CAPTURE)
-               fmode |= O_READFLG;
-       if (fmode == O_RDWR) {
+       if ((mode & (SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) ==
+                   (SND_PCM_OPEN_PLAYBACK|SND_PCM_OPEN_CAPTURE)) {
+               fmode = O_RDWR;
+       } else if (mode & SND_PCM_OPEN_PLAYBACK) {
+               fmode = O_WRONLY;
+       } else if (mode & SND_PCM_OPEN_CAPTURE) {
+               fmode = O_RDONLY;
+       } else {
                snd_ctl_close(ctl);
                return -EINVAL;
        }
-       if (mode & SND_PCM_OPEN_STREAM)
+       if (mode & SND_PCM_OPEN_NONBLOCK)
                fmode |= O_NONBLOCK;
       __again:
        if (attempt++ > 3) {
@@ -133,6 +129,8 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
        pcm->device = device;
        pcm->fd = fd;
        pcm->mode = mode;
+       pcm->ver = ver;
+       pcm->mmap_ctrl_fd[0] = pcm->mmap_ctrl_fd[1] = -1;
        *handle = pcm;
        return 0;
 }
@@ -394,9 +392,9 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t size)
 int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, void **buffer)
 {
        snd_pcm_channel_info_t info;
-       int err;
+       snd_pcm_mmap_select_t sel;
+       int err, ctrl_fd, ver, prot;
        void *caddr, *daddr;
-       off_t offset;
 
        if (control)
                *control = NULL;
@@ -408,24 +406,44 @@ int snd_pcm_mmap(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control,
        info.channel = channel;
        if ((err = snd_pcm_channel_info(pcm, &info))<0)
                return err;
-       offset = channel == SND_PCM_CHANNEL_PLAYBACK ?
-                       SND_PCM_MMAP_OFFSET_PLAYBACK_CONTROL :
-                       SND_PCM_MMAP_OFFSET_CAPTURE_CONTROL;
-       caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, pcm->fd, offset);
-       if (caddr == (caddr_t)-1 || caddr == NULL)
+       ctrl_fd = open(SND_FILE_PCM_CONTROL, O_RDWR);
+       if (ctrl_fd < 0)
+               return -errno;
+       if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_PVERSION, &ver) < 0) {
+               err = -errno;
+               close(ctrl_fd);
+               return err;
+       }
+       if (pcm->ver != ver) {
+               close(ctrl_fd);
+               return -SND_ERROR_INCOMPATIBLE_VERSION;
+       }
+       sel.card = pcm->card;
+       sel.device = pcm->device;
+       sel.subdevice = info.subdevice;
+       sel.channel = channel;
+       if (ioctl(ctrl_fd, SND_PCM_CTRL_IOCTL_SELECT, &sel) < 0) {
+               err = -errno;
+               close(ctrl_fd);
+               return err;
+       }
+       caddr = mmap(NULL, sizeof(snd_pcm_mmap_control_t), PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_CONTROL);
+       if (caddr == (caddr_t)-1 || caddr == NULL) {
+               close(ctrl_fd);
                return -errno;
-       offset = channel == SND_PCM_CHANNEL_PLAYBACK ?
-                       SND_PCM_MMAP_OFFSET_PLAYBACK :
-                       SND_PCM_MMAP_OFFSET_CAPTURE;
-       daddr = mmap(NULL, info.mmap_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, pcm->fd, offset);
+       }
+       prot = channel == SND_PCM_CHANNEL_PLAYBACK ? PROT_WRITE : PROT_READ;
+       daddr = mmap(NULL, info.mmap_size, prot, MAP_FILE|MAP_SHARED, ctrl_fd, SND_PCM_MMAP_OFFSET_DATA);
        if (daddr == (caddr_t)-1 || daddr == NULL) {
                err = -errno;
                munmap(caddr, sizeof(snd_pcm_mmap_control_t));
+               close(ctrl_fd);
                return err;
        }
        *control = pcm->mmap_caddr[channel] = caddr;
        *buffer = pcm->mmap_daddr[channel] = daddr;
        pcm->mmap_size[channel] = info.mmap_size;
+       pcm->mmap_ctrl_fd[channel] = ctrl_fd;
        return 0;
 }
 
@@ -442,5 +460,9 @@ int snd_pcm_munmap(snd_pcm_t *pcm, int channel)
                pcm->mmap_daddr[channel] = NULL;
                pcm->mmap_size[channel] = 0;
        }
+       if (pcm->mmap_ctrl_fd[channel] >= 0) {
+               close(pcm->mmap_ctrl_fd[channel]);
+               pcm->mmap_ctrl_fd[channel] = -1;
+       }
        return 0;
 }
index 271a1769ab19810716938a00ad4907697fe7d79e..7fd9714adc9e8b1f5fcba14bad258fff62fb8bb4 100644 (file)
@@ -26,8 +26,10 @@ struct snd_pcm {
        int device;
        int fd;
        int mode;
+       int ver;
        int setup_is_valid[2];
        snd_pcm_channel_setup_t setup[2];
+       int mmap_ctrl_fd[2];
        snd_pcm_mmap_control_t *mmap_caddr[2];
        char *mmap_daddr[2];
        long mmap_size[2];