OSDN Git Service

Fixed pointers use
[android-x86/external-alsa-lib.git] / src / pcm / pcm_share.c
index 0b3e50f..98aa2c4 100644 (file)
@@ -42,6 +42,7 @@ typedef struct {
        size_t channels_count;
        size_t open_count;
        size_t setup_count;
+       size_t mmap_count;
        size_t prepared_count;
        size_t running_count;
        size_t safety_threshold;
@@ -61,8 +62,9 @@ typedef struct {
        pid_t async_pid;
        struct timeval trigger_time;
        size_t draining_silence;
-       snd_pcm_mmap_control_t mmap_control;
-       snd_pcm_mmap_status_t mmap_status;
+       int state;
+       size_t hw_ptr;
+       size_t appl_ptr;
        int ready;
        int client_socket;
        int slave_socket;
@@ -79,7 +81,7 @@ static void snd_pcm_share_interrupt(snd_pcm_share_slave_t *slave)
                snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
                snd_pcm_t *pcm = share->pcm;
                int ready;
-               switch (share->mmap_status.state) {
+               switch (share->state) {
                case SND_PCM_STATE_DRAINING:
                        if (pcm->stream == SND_PCM_STREAM_CAPTURE)
                                ready = 1;
@@ -146,22 +148,21 @@ static void snd_pcm_share_stop(snd_pcm_t *pcm, int state)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
-       share->mmap_status.state = state;
+       share->state = state;
        gettimeofday(&share->trigger_time, 0);
        slave->prepared_count--;
        slave->running_count--;
-       if (slave->running_count == 0) {
-               int err = snd_pcm_drop(slave->pcm);
-               assert(err >= 0);
-       }
        if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
+               snd_pcm_avail_update(slave->pcm);
                snd_pcm_areas_copy(pcm->running_areas, 0,
                                   pcm->stopped_areas, 0,
                                   pcm->setup.format.channels, pcm->setup.buffer_size,
                                   pcm->setup.format.sfmt);
        }
-       share->mmap_status.hw_ptr = slave->pcm->mmap_status->hw_ptr;
-       pcm->mmap_status = &share->mmap_status;
+       if (slave->running_count == 0) {
+               int err = snd_pcm_drop(slave->pcm);
+               assert(err >= 0);
+       }
 }
 
 /* Warning: take the mutex before to call this */
@@ -182,11 +183,11 @@ static void snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
        buffer_size = slave->pcm->setup.buffer_size;
        min_frames = buffer_size;
        max_frames = 0;
-       slave_appl_ptr = slave->pcm->mmap_control->appl_ptr;
+       slave_appl_ptr = *slave->pcm->appl_ptr;
        for (i = slave->clients.next; i != &slave->clients; i = i->next) {
                snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
                snd_pcm_t *pcm = share->pcm;
-               switch (share->mmap_status.state) {
+               switch (share->state) {
                case SND_PCM_STATE_RUNNING:
                        break;
                case SND_PCM_STATE_DRAINING:
@@ -220,7 +221,7 @@ static void snd_pcm_share_slave_forward(snd_pcm_share_slave_t *slave)
                default:
                        continue;
                }
-               frames = share->mmap_control.appl_ptr - slave_appl_ptr;
+               frames = share->appl_ptr - slave_appl_ptr;
                if (frames > (ssize_t)buffer_size)
                        frames -= pcm->setup.boundary;
                else if (frames < -(ssize_t)pcm->setup.buffer_size)
@@ -262,7 +263,7 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
-       if (share->mmap_status.state == SND_PCM_STATE_RUNNING) {
+       if (share->state == SND_PCM_STATE_RUNNING) {
                if (pcm->mode & SND_PCM_NONBLOCK)
                        snd_pcm_drop(pcm);
                else
@@ -276,11 +277,14 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
                pthread_kill(slave->thread, SIGTERM);
                err = snd_pcm_close(slave->pcm);
                list_del(&slave->list);
+               pthread_mutex_unlock(&slave->mutex);
                pthread_mutex_destroy(&slave->mutex);
                free(slave);
+               list_del(&share->list);
+       } else {
+               list_del(&share->list);
+               pthread_mutex_unlock(&slave->mutex);
        }
-       list_del(&share->list);
-       pthread_mutex_unlock(&slave->mutex);
        close(share->client_socket);
        close(share->slave_socket);
        free(share->slave_channels);
@@ -358,6 +362,64 @@ static int snd_pcm_share_params_info(snd_pcm_t *pcm, snd_pcm_params_info_t *info
        return err;
 }
 
+static int snd_pcm_share_mmap(snd_pcm_t *pcm)
+{
+       snd_pcm_share_t *share = pcm->private;
+       snd_pcm_share_slave_t *slave = share->slave;
+       snd_pcm_mmap_info_t *i;
+       int err;
+       pthread_mutex_lock(&slave->mutex);
+       if (slave->mmap_count == 0) {
+               err = snd_pcm_mmap(slave->pcm);
+               if (err < 0) {
+                       pthread_mutex_unlock(&slave->mutex);
+                       return err;
+               }
+               if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
+                       snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->setup.format.channels, slave->pcm->setup.buffer_size, slave->pcm->setup.format.sfmt);
+               slave->mmap_count++;
+       }
+       pthread_mutex_unlock(&slave->mutex);
+       pcm->mmap_info_count = slave->pcm->mmap_info_count + 1;
+       pcm->mmap_info = malloc(pcm->mmap_info_count * sizeof(*pcm->mmap_info));
+       if (!pcm->mmap_info)
+               return -ENOMEM;
+       memcpy(pcm->mmap_info, slave->pcm->mmap_info, slave->pcm->mmap_info_count * sizeof(*pcm->mmap_info));
+       i = &pcm->mmap_info[slave->pcm->mmap_info_count];
+       i->type = SND_PCM_MMAP_USER;
+       i->size = snd_pcm_frames_to_bytes(pcm, pcm->setup.buffer_size);
+       share->stopped_data = malloc(i->size);
+       if (share->stopped_data == 0) {
+               free(pcm->mmap_info);
+               pcm->mmap_info = 0;
+               return -ENOMEM;
+       }
+       i->addr = share->stopped_data;
+       return 0;
+}
+
+static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       snd_pcm_share_t *share = pcm->private;
+       snd_pcm_share_slave_t *slave = share->slave;
+       int err;
+       pthread_mutex_lock(&slave->mutex);
+       slave->mmap_count--;
+       if (slave->mmap_count == 0) {
+               err = snd_pcm_munmap(slave->pcm);
+               if (err < 0) {
+                       pthread_mutex_unlock(&slave->mutex);
+                       return err;
+               }
+       }
+       pthread_mutex_unlock(&slave->mutex);
+       free(pcm->mmap_info);
+       pcm->mmap_info_count = 0;
+       pcm->mmap_info = 0;
+       free(share->stopped_data);
+       return 0;
+}
+               
 static int snd_pcm_share_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
 {
        snd_pcm_share_t *share = pcm->private;
@@ -367,7 +429,7 @@ static int snd_pcm_share_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
        if (channels != share->channels_count) {
                params->fail_mask = SND_PCM_PARAMS_CHANNELS;
                params->fail_reason = SND_PCM_PARAMS_FAIL_INVAL;
-               ERR("channels requested (%d) differs from configuration (%d)", channels, share->channels_count);
+               ERR("channels requested (%d) differs from configuration (%ld)", channels, (long)share->channels_count);
                return -EINVAL;
        }
        share->xfer_mode = params->xfer_mode;
@@ -387,22 +449,14 @@ static int snd_pcm_share_params(snd_pcm_t *pcm, snd_pcm_params_t *params)
                }
        } else {
                snd_pcm_params_t sp = *params;
-               if (slave->pcm->mmap_data) {
-                       err = snd_pcm_munmap_data(slave->pcm);
-                       if (err < 0)
-                               goto _end;
-               }
                sp.xfer_mode = SND_PCM_XFER_UNSPECIFIED;
                sp.xrun_mode = SND_PCM_XRUN_NONE;
                sp.format.channels = slave->channels_count;
                err = snd_pcm_params(slave->pcm, &sp);
-               snd_pcm_mmap_data(slave->pcm, NULL);
                if (err < 0)
                        goto _end;
-               if (slave->pcm->stream == SND_PCM_STREAM_PLAYBACK)
-                       snd_pcm_areas_silence(slave->pcm->running_areas, 0, slave->pcm->setup.format.channels, slave->pcm->setup.buffer_size, slave->pcm->setup.format.sfmt);
        }
-       share->mmap_status.state = SND_PCM_STATE_SETUP;
+       share->state = SND_PCM_STATE_SETUP;
        slave->setup_count++;
  _end:
        pthread_mutex_unlock(&slave->mutex);
@@ -437,13 +491,13 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
        pthread_mutex_lock(&slave->mutex);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                status->avail = snd_pcm_mmap_playback_avail(pcm);
-               if (share->mmap_status.state != SND_PCM_STATE_RUNNING &&
-                   share->mmap_status.state != SND_PCM_STATE_DRAINING)
+               if (share->state != SND_PCM_STATE_RUNNING &&
+                   share->state != SND_PCM_STATE_DRAINING)
                        goto _notrunning;
                d = pcm->setup.buffer_size - status->avail;
        } else {
                status->avail = snd_pcm_mmap_capture_avail(pcm);
-               if (share->mmap_status.state != SND_PCM_STATE_RUNNING)
+               if (share->state != SND_PCM_STATE_RUNNING)
                        goto _notrunning;
                d = status->avail;
        }
@@ -452,7 +506,7 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
                goto _end;
  _notrunning:
        status->delay = sd + d;
-       status->state = share->mmap_status.state;
+       status->state = share->state;
        status->trigger_time = share->trigger_time;
  _end:
        pthread_mutex_unlock(&slave->mutex);
@@ -462,7 +516,7 @@ static int snd_pcm_share_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
 static int snd_pcm_share_state(snd_pcm_t *pcm)
 {
        snd_pcm_share_t *share = pcm->private;
-       return share->mmap_status.state;
+       return share->state;
 }
 
 static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
@@ -472,7 +526,7 @@ static int snd_pcm_share_delay(snd_pcm_t *pcm, ssize_t *delayp)
        int err = 0;
        ssize_t sd;
        pthread_mutex_lock(&slave->mutex);
-       switch (share->mmap_status.state) {
+       switch (share->state) {
        case SND_PCM_STATE_XRUN:
                err = -EPIPE;
                goto _end;
@@ -502,12 +556,14 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
        ssize_t ret = 0;
        pthread_mutex_lock(&slave->mutex);
        ret = snd_pcm_avail_update(slave->pcm);
+       if (share->state == SND_PCM_STATE_RUNNING)
+               share->hw_ptr = *slave->pcm->hw_ptr;
        if (ret == -EPIPE) {
                struct list_head *i;
                for (i = slave->clients.next; i != &slave->clients; i = i->next) {
                        snd_pcm_share_t *share = list_entry(i, snd_pcm_share_t, list);
                        snd_pcm_t *pcm = share->pcm;
-                       if (share->mmap_status.state == SND_PCM_STATE_RUNNING &&
+                       if (share->state == SND_PCM_STATE_RUNNING &&
                            pcm->setup.xrun_mode != SND_PCM_XRUN_NONE)
                                snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
                }
@@ -515,22 +571,26 @@ static ssize_t snd_pcm_share_avail_update(snd_pcm_t *pcm)
        pthread_mutex_unlock(&slave->mutex);
        if (ret >= 0) {
                ret = snd_pcm_mmap_avail(pcm);
-               if ((size_t)ret > pcm->setup.buffer_size)
+               if ((size_t)ret > pcm->setup.buffer_size) {
+                       if (share->state == SND_PCM_STATE_RUNNING &&
+                           pcm->setup.xrun_mode != SND_PCM_XRUN_NONE)
+                               snd_pcm_share_stop(pcm, SND_PCM_STATE_XRUN);
                        return -EPIPE;
+               }
        }
        return ret;
 }
 
-static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+/* Call it with mutex held */
+static ssize_t _snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
 {
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        ssize_t ret = 0;
        ssize_t frames;
-       pthread_mutex_lock(&slave->mutex);
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
-           share->mmap_status.state == SND_PCM_STATE_RUNNING) {
-               frames = slave->pcm->mmap_control->appl_ptr - share->mmap_control.appl_ptr;
+           share->state == SND_PCM_STATE_RUNNING) {
+               frames = *slave->pcm->appl_ptr - share->appl_ptr;
                if (frames > (ssize_t)pcm->setup.buffer_size)
                        frames -= pcm->setup.boundary;
                else if (frames < -(ssize_t)pcm->setup.buffer_size)
@@ -538,19 +598,27 @@ static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
                if (frames > 0) {
                        /* Latecomer PCM */
                        ret = snd_pcm_rewind(slave->pcm, frames);
-                       if (ret < 0) {
-                               pthread_mutex_unlock(&slave->mutex);
+                       if (ret < 0)
                                return ret;
-                       }
                        size += ret;
                }
        }
        snd_pcm_mmap_appl_forward(pcm, size);
        snd_pcm_share_slave_forward(share->slave);
-       pthread_mutex_unlock(&slave->mutex);
        return size;
 }
 
+static ssize_t snd_pcm_share_mmap_forward(snd_pcm_t *pcm, size_t size)
+{
+       snd_pcm_share_t *share = pcm->private;
+       snd_pcm_share_slave_t *slave = share->slave;
+       ssize_t ret;
+       pthread_mutex_lock(&slave->mutex);
+       ret = _snd_pcm_share_mmap_forward(pcm, size);
+       pthread_mutex_unlock(&slave->mutex);
+       return ret;
+}
+
 static int snd_pcm_share_prepare(snd_pcm_t *pcm)
 {
        snd_pcm_share_t *share = pcm->private;
@@ -563,9 +631,9 @@ static int snd_pcm_share_prepare(snd_pcm_t *pcm)
                        goto _end;
        }
        slave->prepared_count++;
-       share->mmap_status.hw_ptr = 0;
-       share->mmap_control.appl_ptr = 0;
-       share->mmap_status.state = SND_PCM_STATE_PREPARED;
+       share->hw_ptr = 0;
+       share->appl_ptr = 0;
+       share->state = SND_PCM_STATE_PREPARED;
  _end:
        pthread_mutex_unlock(&slave->mutex);
        return err;
@@ -576,10 +644,10 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
        snd_pcm_share_t *share = pcm->private;
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
-       if (share->mmap_status.state != SND_PCM_STATE_PREPARED)
+       if (share->state != SND_PCM_STATE_PREPARED)
                return -EBADFD;
        pthread_mutex_lock(&slave->mutex);
-       share->mmap_status.state = SND_PCM_STATE_RUNNING;
+       share->state = SND_PCM_STATE_RUNNING;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                size_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
                if (hw_avail == 0) {
@@ -595,15 +663,14 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
                        if (err < 0)
                                goto _end;
                }
-               assert(share->mmap_status.hw_ptr == 0);
-               /* Use the same mmap_status of slave */
-               pcm->mmap_status = slave->pcm->mmap_status;
-               share->mmap_control.appl_ptr = slave->pcm->mmap_control->appl_ptr;
+               assert(share->hw_ptr == 0);
+               share->hw_ptr = *slave->pcm->hw_ptr;
+               share->appl_ptr = *slave->pcm->appl_ptr;
                snd_pcm_areas_copy(pcm->stopped_areas, 0,
                                   pcm->running_areas, snd_pcm_mmap_offset(pcm),
                                   pcm->setup.format.channels, hw_avail,
                                   pcm->setup.format.sfmt);
-               snd_pcm_mmap_forward(pcm, pcm->setup.buffer_size);
+               _snd_pcm_share_mmap_forward(pcm, pcm->setup.buffer_size);
        }
        if (slave->running_count == 0) {
                err = snd_pcm_start(slave->pcm);
@@ -623,7 +690,7 @@ static int snd_pcm_share_drop(snd_pcm_t *pcm)
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
        pthread_mutex_lock(&slave->mutex);
-       switch (share->mmap_status.state) {
+       switch (share->state) {
        case SND_PCM_STATE_OPEN:
                err = -EBADFD;
                goto _end;
@@ -631,7 +698,7 @@ static int snd_pcm_share_drop(snd_pcm_t *pcm)
                goto _end;
        case SND_PCM_STATE_DRAINING:
                if (pcm->stream == SND_PCM_STREAM_CAPTURE) {
-                       share->mmap_status.state = SND_PCM_STATE_SETUP;
+                       share->state = SND_PCM_STATE_SETUP;
                        break;
                }
                /* Fall through */
@@ -640,7 +707,7 @@ static int snd_pcm_share_drop(snd_pcm_t *pcm)
                break;
        case SND_PCM_STATE_PREPARED:
        case SND_PCM_STATE_XRUN:
-               share->mmap_status.state = SND_PCM_STATE_SETUP;
+               share->state = SND_PCM_STATE_SETUP;
                break;
        }
        
@@ -659,7 +726,7 @@ static int snd_pcm_share_drop(snd_pcm_t *pcm)
                                      pcm->setup.buffer_size, pcm->setup.format.sfmt);
                snd_pcm_mmap_forward(pcm, pcm->setup.buffer_size);
        }
-       share->mmap_control.appl_ptr = share->mmap_status.hw_ptr = 0;
+       share->appl_ptr = share->hw_ptr = 0;
  _end:
        pthread_mutex_unlock(&slave->mutex);
        return err;
@@ -671,29 +738,29 @@ static int snd_pcm_share_drain(snd_pcm_t *pcm)
        snd_pcm_share_slave_t *slave = share->slave;
        int err = 0;
        pthread_mutex_lock(&slave->mutex);
-       switch (share->mmap_status.state) {
+       switch (share->state) {
        case SND_PCM_STATE_OPEN:
                err = -EBADFD;
                goto _end;
        case SND_PCM_STATE_PREPARED:
-               share->mmap_status.state = SND_PCM_STATE_SETUP;
+               share->state = SND_PCM_STATE_SETUP;
                break;
        case SND_PCM_STATE_SETUP:
        case SND_PCM_STATE_DRAINING:
                goto _end;
        case SND_PCM_STATE_XRUN:
                if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
-                       share->mmap_status.state = SND_PCM_STATE_SETUP;
+                       share->state = SND_PCM_STATE_SETUP;
                        break;
                }
                /* Fall through */
        case SND_PCM_STATE_RUNNING:
                if (snd_pcm_mmap_avail(pcm) <= 0) {
-                       share->mmap_status.state = SND_PCM_STATE_SETUP;
+                       share->state = SND_PCM_STATE_SETUP;
                        break;
                }
                share->draining_silence = 0;
-               share->mmap_status.state = SND_PCM_STATE_DRAINING;
+               share->state = SND_PCM_STATE_DRAINING;
                break;
        }
  _end:
@@ -742,7 +809,26 @@ static int snd_pcm_share_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *
        setup->channel = c;
        err = snd_pcm_channel_setup(slave->pcm, setup);
        setup->channel = channel;
-       return err;
+       if (err < 0)
+               return err;
+       if (!pcm->mmap_info)
+               return 0;
+       switch (pcm->setup.mmap_shape) {
+       case SND_PCM_MMAP_INTERLEAVED:
+       case SND_PCM_MMAP_COMPLEX:
+               setup->stopped_area.addr = share->stopped_data;
+               setup->stopped_area.first = channel * pcm->bits_per_sample;
+               setup->stopped_area.step = pcm->bits_per_frame;
+               break;
+       case SND_PCM_MMAP_NONINTERLEAVED:
+               setup->stopped_area.addr = share->stopped_data + c * pcm->setup.buffer_size * pcm->bits_per_sample / 8;
+               setup->stopped_area.first = 0;
+               setup->stopped_area.step = pcm->bits_per_sample;
+               break;
+       default:
+               assert(0);
+       }
+       return 0;
 }
 
 static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
@@ -751,7 +837,7 @@ static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
        snd_pcm_share_slave_t *slave = share->slave;
        int ret = -EBADFD;
        ssize_t n;
-       switch (share->mmap_status.state) {
+       switch (share->state) {
        case SND_PCM_STATE_RUNNING:
                break;
        case SND_PCM_STATE_PREPARED:
@@ -774,7 +860,7 @@ static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
                        n = frames;
                frames -= n;
        }
-       if (share->mmap_status.state == SND_PCM_STATE_RUNNING &&
+       if (share->state == SND_PCM_STATE_RUNNING &&
            frames > 0) {
                pthread_mutex_lock(&slave->mutex);
                ret = snd_pcm_rewind(slave->pcm, frames);
@@ -793,43 +879,6 @@ static ssize_t snd_pcm_share_rewind(snd_pcm_t *pcm, size_t frames)
        return ret;
 }
 
-static int snd_pcm_share_mmap_status(snd_pcm_t *pcm)
-{
-       snd_pcm_share_t *share = pcm->private;
-       pcm->mmap_status = &share->mmap_status;
-       return 0;
-}
-
-static int snd_pcm_share_mmap_control(snd_pcm_t *pcm)
-{
-       snd_pcm_share_t *share = pcm->private;
-       pcm->mmap_control = &share->mmap_control;
-       return 0;
-}
-
-static int snd_pcm_share_mmap_data(snd_pcm_t *pcm)
-{
-       snd_pcm_share_t *share = pcm->private;
-       snd_pcm_share_slave_t *slave = share->slave;
-       pcm->mmap_data = slave->pcm->mmap_data;
-       return 0;
-}
-
-static int snd_pcm_share_munmap_status(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-               
-static int snd_pcm_share_munmap_control(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-               
-static int snd_pcm_share_munmap_data(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
-{
-       return 0;
-}
-               
 static int snd_pcm_share_channels_mask(snd_pcm_t *pcm, bitset_t *cmask)
 {
        snd_pcm_share_t *share = pcm->private;
@@ -869,7 +918,7 @@ static void snd_pcm_share_dump(snd_pcm_t *pcm, FILE *fp)
        snd_pcm_dump(slave->pcm, fp);
 }
 
-struct snd_pcm_ops snd_pcm_share_ops = {
+snd_pcm_ops_t snd_pcm_share_ops = {
        close: snd_pcm_share_close,
        info: snd_pcm_share_info,
        params_info: snd_pcm_share_params_info,
@@ -881,15 +930,11 @@ struct snd_pcm_ops snd_pcm_share_ops = {
        dump: snd_pcm_share_dump,
        nonblock: snd_pcm_share_nonblock,
        async: snd_pcm_share_async,
-       mmap_status: snd_pcm_share_mmap_status,
-       mmap_control: snd_pcm_share_mmap_control,
-       mmap_data: snd_pcm_share_mmap_data,
-       munmap_status: snd_pcm_share_munmap_status,
-       munmap_control: snd_pcm_share_munmap_control,
-       munmap_data: snd_pcm_share_munmap_data,
+       mmap: snd_pcm_share_mmap,
+       munmap: snd_pcm_share_munmap,
 };
 
-struct snd_pcm_fast_ops snd_pcm_share_fast_ops = {
+snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
        status: snd_pcm_share_status,
        state: snd_pcm_share_state,
        delay: snd_pcm_share_delay,
@@ -903,18 +948,17 @@ struct snd_pcm_fast_ops snd_pcm_share_fast_ops = {
        readi: snd_pcm_mmap_readi,
        readn: snd_pcm_mmap_readn,
        rewind: snd_pcm_share_rewind,
-       poll_descriptor: snd_pcm_share_poll_descriptor,
        channels_mask: snd_pcm_share_channels_mask,
        avail_update: snd_pcm_share_avail_update,
        mmap_forward: snd_pcm_share_mmap_forward,
 };
 
-int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
+int snd_pcm_share_open(snd_pcm_t **pcmp, char *name, char *sname,
                       size_t schannels_count,
                       size_t channels_count, int *channels_map,
                       int stream, int mode)
 {
-       snd_pcm_t *handle;
+       snd_pcm_t *pcm;
        snd_pcm_share_t *share;
        int err;
        struct list_head *i;
@@ -923,7 +967,7 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
        snd_pcm_share_slave_t *slave = NULL;
        int sd[2];
 
-       assert(handlep);
+       assert(pcmp);
        assert(channels_count > 0 && sname && channels_map);
 
        for (k = 0; k < channels_count; ++k) {
@@ -951,8 +995,8 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
        }
        memcpy(share->slave_channels, channels_map, channels_count * sizeof(*share->slave_channels));
 
-       handle = calloc(1, sizeof(snd_pcm_t));
-       if (!handle) {
+       pcm = calloc(1, sizeof(snd_pcm_t));
+       if (!pcm) {
                free(share->slave_channels);
                free(share);
                return -ENOMEM;
@@ -976,7 +1020,7 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
        }
        if (err < 0) {
                err = -errno;
-               free(handle);
+               free(pcm);
                free(share->slave_channels);
                free(share);
                return err;
@@ -997,7 +1041,7 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
                        pthread_mutex_unlock(&slaves_mutex);
                        close(sd[0]);
                        close(sd[1]);
-                       free(handle);
+                       free(pcm);
                        free(share->slave_channels);
                        free(share);
                        return err;
@@ -1008,7 +1052,7 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
                        snd_pcm_close(spcm);
                        close(sd[0]);
                        close(sd[1]);
-                       free(handle);
+                       free(pcm);
                        free(share->slave_channels);
                        free(share);
                        return err;
@@ -1031,28 +1075,27 @@ int snd_pcm_share_open(snd_pcm_t **handlep, char *name, char *sname,
        pthread_mutex_unlock(&slave->mutex);
 
        share->slave = slave;
-       share->pcm = handle;
+       share->pcm = pcm;
        share->client_socket = sd[0];
        share->slave_socket = sd[1];
        share->async_sig = SIGIO;
        share->async_pid = getpid();
        
        if (name)
-               handle->name = strdup(name);
-       handle->type = SND_PCM_TYPE_SHARE;
-       handle->stream = stream;
-       handle->mode = mode;
-       handle->ops = &snd_pcm_share_ops;
-       handle->op_arg = handle;
-       handle->fast_ops = &snd_pcm_share_fast_ops;
-       handle->fast_op_arg = handle;
-       handle->private = share;
-       err = snd_pcm_init(handle);
-       if (err < 0) {
-               snd_pcm_close(handle);
-               return err;
-       }
-       *handlep = handle;
+               pcm->name = strdup(name);
+       pcm->type = SND_PCM_TYPE_SHARE;
+       pcm->stream = stream;
+       pcm->mode = mode;
+       pcm->mmap_auto = 1;
+       pcm->ops = &snd_pcm_share_ops;
+       pcm->op_arg = pcm;
+       pcm->fast_ops = &snd_pcm_share_fast_ops;
+       pcm->fast_op_arg = pcm;
+       pcm->private = share;
+       pcm->poll_fd = share->client_socket;
+       pcm->hw_ptr = &share->hw_ptr;
+       pcm->appl_ptr = &share->appl_ptr;
+       *pcmp = pcm;
        return 0;
 }
 
@@ -1104,11 +1147,11 @@ int _snd_pcm_share_open(snd_pcm_t **pcmp, char *name, snd_config_t *conf,
                return -EINVAL;
        }
        if (!sname) {
-               ERR("Missing sname");
+               ERR("sname is not defined");
                return -EINVAL;
        }
        if (!binding) {
-               ERR("Missing binding");
+               ERR("binding is not defined");
                return -EINVAL;
        }
        snd_config_foreach(i, binding) {