OSDN Git Service

Added support for hw_free in alsa-lib
authorAbramo Bagnara <abramo@alsa-project.org>
Fri, 19 Jan 2001 13:10:50 +0000 (13:10 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Fri, 19 Jan 2001 13:10:50 +0000 (13:10 +0000)
21 files changed:
aserver/aserver.c
include/pcm.h
src/pcm/pcm.c
src/pcm/pcm_adpcm.c
src/pcm/pcm_alaw.c
src/pcm/pcm_copy.c
src/pcm/pcm_file.c
src/pcm/pcm_hw.c
src/pcm/pcm_linear.c
src/pcm/pcm_local.h
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_null.c
src/pcm/pcm_params.c
src/pcm/pcm_plug.c
src/pcm/pcm_plugin.c
src/pcm/pcm_plugin.h
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c

index ac90cef..8dc5555 100644 (file)
@@ -388,6 +388,9 @@ int pcm_shm_cmd(client_t *client)
        case SND_PCM_IOCTL_HW_PARAMS:
                ctrl->result = snd_pcm_hw_params(pcm, (snd_pcm_hw_params_t *) &ctrl->u.hw_params);
                break;
+       case SND_PCM_IOCTL_HW_FREE:
+               ctrl->result = snd_pcm_hw_free(pcm);
+               break;
        case SND_PCM_IOCTL_SW_PARAMS:
                ctrl->result = snd_pcm_sw_params(pcm, (snd_pcm_sw_params_t *) &ctrl->u.sw_params);
                break;
index 96849fe..99809d1 100644 (file)
@@ -60,6 +60,7 @@ int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid);
 int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info);
 int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
 int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+int snd_pcm_hw_free(snd_pcm_t *pcm);
 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
 int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status);
 int snd_pcm_prepare(snd_pcm_t *pcm);
index 9457511..9e8d5be 100644 (file)
@@ -55,9 +55,8 @@ int snd_pcm_close(snd_pcm_t *pcm)
                        snd_pcm_drop(pcm);
                else
                        snd_pcm_drain(pcm);
-       }
-       if (pcm->mmap_channels) {
-               if ((err = snd_pcm_munmap(pcm)) < 0)
+               err = snd_pcm_hw_free(pcm);
+               if (err < 0)
                        ret = err;
        }
        if ((err = pcm->ops->close(pcm->op_arg)) < 0)
index 6928b67..bdbdb66 100644 (file)
@@ -317,18 +317,6 @@ static void adpcm_encode(const snd_pcm_channel_area_t *src_areas,
        }
 }
 
-static int snd_pcm_adpcm_close(snd_pcm_t *pcm)
-{
-       snd_pcm_adpcm_t *adpcm = pcm->private;
-       int err = 0;
-       if (adpcm->plug.close_slave)
-               err = snd_pcm_close(adpcm->plug.slave);
-       if (adpcm->states)
-               free(adpcm->states);
-       free(adpcm);
-       return 0;
-}
-
 static int snd_pcm_adpcm_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private;
@@ -449,12 +437,21 @@ static int snd_pcm_adpcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                        adpcm->func = adpcm_encode;
                }
        }
-       if (adpcm->states)
-               free(adpcm->states);
+       assert(!adpcm->states);
        adpcm->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*adpcm->states));
        return 0;
 }
 
+static int snd_pcm_adpcm_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_adpcm_t *adpcm = pcm->private;
+       if (adpcm->states) {
+               free(adpcm->states);
+               adpcm->states = 0;
+       }
+       return snd_pcm_hw_free(adpcm->plug.slave);
+}
+
 static int snd_pcm_adpcm_init(snd_pcm_t *pcm)
 {
        snd_pcm_adpcm_t *adpcm = pcm->private;
@@ -550,11 +547,12 @@ static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)
 }
 
 snd_pcm_ops_t snd_pcm_adpcm_ops = {
-       close: snd_pcm_adpcm_close,
+       close: snd_pcm_plugin_close,
        card: snd_pcm_plugin_card,
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_adpcm_hw_refine,
        hw_params: snd_pcm_adpcm_hw_params,
+       hw_free: snd_pcm_adpcm_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_adpcm_dump,
index c9756d8..6644483 100644 (file)
@@ -422,6 +422,7 @@ snd_pcm_ops_t snd_pcm_alaw_ops = {
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_alaw_hw_refine,
        hw_params: snd_pcm_alaw_hw_params,
+       hw_free: snd_pcm_plugin_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_alaw_dump,
index 9072b53..d5c5e9a 100644 (file)
@@ -179,6 +179,7 @@ snd_pcm_ops_t snd_pcm_copy_ops = {
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_copy_hw_refine,
        hw_params: snd_pcm_copy_hw_params,
+       hw_free: snd_pcm_plugin_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_copy_dump,
index d5cb588..a080f7f 100644 (file)
@@ -105,12 +105,6 @@ static int snd_pcm_file_close(snd_pcm_t *pcm)
                free(file->fname);
                close(file->fd);
        }
-       if (file->wbuf) {
-               free(file->wbuf);
-               free(file->wbuf_areas);
-               file->wbuf = 0;
-               file->wbuf_areas = 0;
-       }
        free(file);
        return 0;
 }
@@ -322,13 +316,10 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        int err = snd_pcm_hw_params(slave, params);
        if (err < 0)
                return err;
-       if (file->wbuf) {
-               free(file->wbuf);
-               free(file->wbuf_areas);
-       }
        file->buffer_bytes = snd_pcm_frames_to_bytes(slave, slave->buffer_size);
        file->wbuf_size = slave->buffer_size * 2;
        file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
+       assert(!file->wbuf);
        file->wbuf = malloc(file->wbuf_size_bytes);
        file->wbuf_areas = malloc(sizeof(*file->wbuf_areas) * slave->channels);
        file->appl_ptr = file->file_ptr_bytes = 0;
@@ -341,6 +332,18 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
+static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_file_t *file = pcm->private;
+       if (file->wbuf) {
+               free(file->wbuf);
+               free(file->wbuf_areas);
+               file->wbuf = 0;
+               file->wbuf_areas = 0;
+       }
+       return snd_pcm_hw_free(file->slave);
+}
+
 static int snd_pcm_file_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_file_t *file = pcm->private;
@@ -378,6 +381,7 @@ snd_pcm_ops_t snd_pcm_file_ops = {
        info: snd_pcm_file_info,
        hw_refine: snd_pcm_file_hw_refine,
        hw_params: snd_pcm_file_hw_params,
+       hw_free: snd_pcm_file_hw_free,
        sw_params: snd_pcm_file_sw_params,
        channel_info: snd_pcm_file_channel_info,
        dump: snd_pcm_file_dump,
index 5170112..55b5c85 100644 (file)
@@ -148,6 +148,17 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        return 0;
 }
 
+static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_hw_t *hw = pcm->private;
+       int fd = hw->fd;
+       if (ioctl(fd, SND_PCM_IOCTL_HW_FREE) < 0) {
+               SYSERR("SND_PCM_IOCTL_HW_FREE failed");
+               return -errno;
+       }
+       return 0;
+}
+
 static int snd_pcm_hw_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_hw_t *hw = pcm->private;
@@ -508,6 +519,7 @@ snd_pcm_ops_t snd_pcm_hw_ops = {
        info: snd_pcm_hw_info,
        hw_refine: snd_pcm_hw_hw_refine,
        hw_params: snd_pcm_hw_hw_params,
+       hw_free: snd_pcm_hw_hw_free,
        sw_params: snd_pcm_hw_sw_params,
        channel_info: snd_pcm_hw_channel_info,
        dump: snd_pcm_hw_dump,
index 95c0971..3731ac1 100644 (file)
@@ -262,6 +262,7 @@ snd_pcm_ops_t snd_pcm_linear_ops = {
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_linear_hw_refine,
        hw_params: snd_pcm_linear_hw_params,
+       hw_free: snd_pcm_plugin_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_linear_dump,
index 36badaa..c869a1d 100644 (file)
@@ -55,6 +55,7 @@ typedef struct {
        int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
        int (*hw_refine)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
        int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params);
+       int (*hw_free)(snd_pcm_t *pcm);
        int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
        int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
        void (*dump)(snd_pcm_t *pcm, snd_output_t *out);
index b501e66..3cab2b5 100644 (file)
@@ -437,6 +437,7 @@ snd_pcm_ops_t snd_pcm_mulaw_ops = {
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_mulaw_hw_refine,
        hw_params: snd_pcm_mulaw_hw_params,
+       hw_free: snd_pcm_plugin_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_mulaw_dump,
index 53fbbc8..121014e 100644 (file)
@@ -286,6 +286,20 @@ static int snd_pcm_multi_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        return 0;
 }
 
+static int snd_pcm_multi_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_multi_t *multi = pcm->private;
+       unsigned int i;
+       int err = 0;
+       for (i = 0; i < multi->slaves_count; ++i) {
+               snd_pcm_t *slave = multi->slaves[i].pcm;
+               int e = snd_pcm_hw_free(slave);
+               if (e < 0)
+                       err = e;
+       }
+       return err;
+}
+
 static int snd_pcm_multi_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
 {
        snd_pcm_multi_t *multi = pcm->private;
@@ -468,6 +482,7 @@ snd_pcm_ops_t snd_pcm_multi_ops = {
        info: snd_pcm_multi_info,
        hw_refine: snd_pcm_multi_hw_refine,
        hw_params: snd_pcm_multi_hw_params,
+       hw_free: snd_pcm_multi_hw_free,
        sw_params: snd_pcm_multi_sw_params,
        channel_info: snd_pcm_multi_channel_info,
        dump: snd_pcm_multi_dump,
index 1f46659..eb16dea 100644 (file)
@@ -241,6 +241,11 @@ static int snd_pcm_null_hw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_pa
        return 0;
 }
 
+static int snd_pcm_null_hw_free(snd_pcm_t *pcm ATTRIBUTE_UNUSED)
+{
+       return 0;
+}
+
 static int snd_pcm_null_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t * params ATTRIBUTE_UNUSED)
 {
        return 0;
@@ -286,6 +291,7 @@ snd_pcm_ops_t snd_pcm_null_ops = {
        info: snd_pcm_null_info,
        hw_refine: snd_pcm_null_hw_refine,
        hw_params: snd_pcm_null_hw_params,
+       hw_free: snd_pcm_null_hw_free,
        sw_params: snd_pcm_null_sw_params,
        channel_info: snd_pcm_null_channel_info,
        dump: snd_pcm_null_dump,
index b2fe8a0..6f1151e 100644 (file)
@@ -2274,14 +2274,14 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        if (err < 0)
                return err;
        snd_pcm_hw_params_choose(pcm, params);
-       if (pcm->mmap_channels) {
-               err = snd_pcm_munmap(pcm);
+       if (pcm->setup) {
+               err = snd_pcm_hw_free(pcm);
                if (err < 0)
-                       return err;
+                       return 0;
        }
        err = pcm->ops->hw_params(pcm->op_arg, params);
        if (err < 0)
-               goto _mmap;
+               return err;
 
        pcm->setup = 1;
        pcm->access = snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_ACCESS, 0);
@@ -2314,22 +2314,32 @@ int snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        err = snd_pcm_sw_params(pcm, &sw);
        assert(err >= 0);
 
- _mmap:
-       if (pcm->setup &&
-           (pcm->mmap_rw || 
-            (pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED ||
-             pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED ||
-             pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX))) {
-               int err;
+       if (pcm->mmap_rw || 
+           pcm->access == SND_PCM_ACCESS_MMAP_INTERLEAVED ||
+           pcm->access == SND_PCM_ACCESS_MMAP_NONINTERLEAVED ||
+           pcm->access == SND_PCM_ACCESS_MMAP_COMPLEX) {
                err = snd_pcm_mmap(pcm);
-               if (err < 0)
-                       return err;
        }
        if (err >= 0)
                err = snd_pcm_prepare(pcm);
        return err;
 }
 
+int snd_pcm_hw_free(snd_pcm_t *pcm)
+{
+       int err;
+       assert(pcm->setup);
+       assert(snd_pcm_state(pcm) <= SND_PCM_STATE_PREPARED);
+       if (pcm->mmap_channels) {
+               err = snd_pcm_munmap(pcm);
+               if (err < 0)
+                       return err;
+       }
+       err = pcm->ops->hw_free(pcm->op_arg);
+       pcm->setup = 0;
+       return err;
+}
+
 int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
 {
        int err;
index acd1f76..34bb36e 100644 (file)
@@ -37,11 +37,7 @@ static int snd_pcm_plug_close(snd_pcm_t *pcm)
        int err, result = 0;
        if (plug->ttable)
                free(plug->ttable);
-       if (plug->slave != plug->req_slave) {
-               err = snd_pcm_close(plug->slave);
-               if (err < 0)
-                       result = err;
-       }
+       assert(plug->slave == plug->req_slave);
        if (plug->close_slave) {
                err = snd_pcm_close(plug->req_slave);
                if (err < 0)
@@ -587,6 +583,15 @@ static int snd_pcm_plug_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        return 0;
 }
 
+static int snd_pcm_plug_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_plug_t *plug = pcm->private;
+       snd_pcm_t *slave = plug->slave;
+       int err = snd_pcm_hw_free(slave);
+       snd_pcm_plug_clear(pcm);
+       return err;
+}
+
 static int snd_pcm_plug_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_plug_t *plug = pcm->private;
@@ -639,6 +644,7 @@ snd_pcm_ops_t snd_pcm_plug_ops = {
        info: snd_pcm_plug_info,
        hw_refine: snd_pcm_plug_hw_refine,
        hw_params: snd_pcm_plug_hw_params,
+       hw_free: snd_pcm_plug_hw_free,
        sw_params: snd_pcm_plug_sw_params,
        channel_info: snd_pcm_plug_channel_info,
        dump: snd_pcm_plug_dump,
index 78eb558..87415bb 100644 (file)
@@ -58,6 +58,12 @@ int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
        return snd_pcm_info(plugin->slave, info);
 }
 
+int snd_pcm_plugin_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_plugin_t *plugin = pcm->private;
+       return snd_pcm_hw_free(plugin->slave);
+}
+
 int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
 {
        snd_pcm_plugin_t *plugin = pcm->private;
index 62f75dd..eca3b2f 100644 (file)
@@ -36,6 +36,7 @@ int snd_pcm_plugin_card(snd_pcm_t *pcm);
 int snd_pcm_plugin_nonblock(snd_pcm_t *pcm, int nonblock);
 int snd_pcm_plugin_async(snd_pcm_t *pcm, int sig, pid_t pid);
 int snd_pcm_plugin_info(snd_pcm_t *pcm, snd_pcm_info_t * info);
+int snd_pcm_plugin_hw_free(snd_pcm_t *pcm);
 int snd_pcm_plugin_sw_refine(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
 int snd_pcm_plugin_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params);
 int snd_pcm_plugin_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info);
index 780f2b4..c018678 100644 (file)
@@ -222,18 +222,6 @@ static snd_pcm_uframes_t resample_shrink(const snd_pcm_channel_area_t *src_areas
        return src_frames1;
 }
 
-static int snd_pcm_rate_close(snd_pcm_t *pcm)
-{
-       snd_pcm_rate_t *rate = pcm->private;
-       int err = 0;
-       if (rate->plug.close_slave)
-               err = snd_pcm_close(rate->plug.slave);
-       if (rate->states)
-               free(rate->states);
-       free(rate);
-       return 0;
-}
-
 static int snd_pcm_rate_hw_refine_cprepare(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_hw_params_t *params)
 {
        int err;
@@ -390,12 +378,21 @@ static int snd_pcm_rate_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                /* pitch is get_increment */
        }
        rate->pitch = (((u_int64_t)dst_rate * DIV) + src_rate / 2) / src_rate;
-       if (rate->states)
-               free(rate->states);
+       assert(!rate->states);
        rate->states = malloc(snd_pcm_hw_param_value(params, SND_PCM_HW_PARAM_CHANNELS, 0) * sizeof(*rate->states));
        return 0;
 }
 
+static int snd_pcm_rate_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_rate_t *rate = pcm->private;
+       if (rate->states) {
+               free(rate->states);
+               rate->states = 0;
+       }
+       return snd_pcm_hw_free(rate->plug.slave);
+}
+
 static int snd_pcm_rate_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_rate_t *rate = pcm->private;
@@ -577,11 +574,12 @@ static void snd_pcm_rate_dump(snd_pcm_t *pcm, snd_output_t *out)
 }
 
 snd_pcm_ops_t snd_pcm_rate_ops = {
-       close: snd_pcm_rate_close,
+       close: snd_pcm_plugin_close,
        card: snd_pcm_plugin_card,
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_rate_hw_refine,
        hw_params: snd_pcm_rate_hw_params,
+       hw_free: snd_pcm_rate_hw_free,
        sw_params: snd_pcm_rate_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_rate_dump,
index afe6ce5..dfe2a97 100644 (file)
@@ -678,6 +678,7 @@ snd_pcm_ops_t snd_pcm_route_ops = {
        info: snd_pcm_plugin_info,
        hw_refine: snd_pcm_route_hw_refine,
        hw_params: snd_pcm_route_hw_params,
+       hw_free: snd_pcm_plugin_hw_free,
        sw_params: snd_pcm_plugin_sw_params,
        channel_info: snd_pcm_plugin_channel_info,
        dump: snd_pcm_route_dump,
index 57c3e57..194d000 100644 (file)
@@ -649,6 +649,20 @@ static int snd_pcm_share_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
        return err;
 }
 
+static int snd_pcm_share_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_share_t *share = pcm->private;
+       snd_pcm_share_slave_t *slave = share->slave;
+       int err = 0;
+       Pthread_mutex_lock(&slave->mutex);
+       slave->setup_count--;
+       if (slave->setup_count == 0)
+               err = snd_pcm_hw_free(slave->pcm);
+       share->state = SND_PCM_STATE_OPEN;
+       Pthread_mutex_unlock(&slave->mutex);
+       return err;
+}
+
 static int snd_pcm_share_sw_params(snd_pcm_t *pcm ATTRIBUTE_UNUSED, snd_pcm_sw_params_t *params ATTRIBUTE_UNUSED)
 {
        return 0;
@@ -1078,8 +1092,6 @@ static int snd_pcm_share_close(snd_pcm_t *pcm)
        int err = 0;
        Pthread_mutex_lock(&slaves_mutex);
        Pthread_mutex_lock(&slave->mutex);
-       if (pcm->setup)
-               slave->setup_count--;
        slave->open_count--;
        if (slave->open_count == 0) {
                err = snd_pcm_close(slave->pcm);
@@ -1137,6 +1149,7 @@ snd_pcm_ops_t snd_pcm_share_ops = {
        info: snd_pcm_share_info,
        hw_refine: snd_pcm_share_hw_refine,
        hw_params: snd_pcm_share_hw_params,
+       hw_free: snd_pcm_share_hw_free,
        sw_params: snd_pcm_share_sw_params,
        channel_info: snd_pcm_share_channel_info,
        dump: snd_pcm_share_dump,
index b895bde..b478ec7 100644 (file)
@@ -253,6 +253,14 @@ static int snd_pcm_shm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
                                       snd_pcm_shm_hw_params_slave);
 }
 
+static int snd_pcm_shm_hw_free(snd_pcm_t *pcm)
+{
+       snd_pcm_shm_t *shm = pcm->private;
+       volatile snd_pcm_shm_ctrl_t *ctrl = shm->ctrl;
+       ctrl->cmd = SND_PCM_IOCTL_HW_FREE;
+       return snd_pcm_shm_action(pcm);
+}
+
 static int snd_pcm_shm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
 {
        snd_pcm_shm_t *shm = pcm->private;
@@ -487,6 +495,7 @@ snd_pcm_ops_t snd_pcm_shm_ops = {
        info: snd_pcm_shm_info,
        hw_refine: snd_pcm_shm_hw_refine,
        hw_params: snd_pcm_shm_hw_params,
+       hw_free: snd_pcm_shm_hw_free,
        sw_params: snd_pcm_shm_sw_params,
        channel_info: snd_pcm_shm_channel_info,
        dump: snd_pcm_shm_dump,