From 9105bb7fcd73de1bba6a64097ea772d12ed24344 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 19 Jan 2004 19:48:27 +0000 Subject: [PATCH] Added SNDRV_PCM_STATE_DISCONNECTED state. Changed direct plugins to handle DISCONNECT/SUSPEND states from slave. --- include/pcm.h | 4 +++- src/pcm/pcm.c | 10 ++++++++++ src/pcm/pcm_dmix.c | 28 ++++++++++++++++++++++++++-- src/pcm/pcm_dshare.c | 26 +++++++++++++++++++++++++- src/pcm/pcm_dsnoop.c | 26 +++++++++++++++++++++++++- 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/include/pcm.h b/include/pcm.h index 4699b939..b4d1fc3f 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -254,7 +254,9 @@ typedef enum _snd_pcm_state { SND_PCM_STATE_PAUSED, /** Hardware is suspended */ SND_PCM_STATE_SUSPENDED, - SND_PCM_STATE_LAST = SND_PCM_STATE_SUSPENDED + /** Hardware is disconnected */ + SND_PCM_STATE_DISCONNECTED, + SND_PCM_STATE_LAST = SND_PCM_STATE_DISCONNECTED } snd_pcm_state_t; /** PCM start mode */ diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 0a433f5a..da539347 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -199,6 +199,9 @@ In other case, the calls #snd_pcm_prepare(), #snd_pcm_drop(), #snd_pcm_drain() can be used to leave this state. +\par SND_PCM_STATE_DISCONNECTED +The device is physicaly disconnected. It does not accept any I/O calls in this state. + \section pcm_formats PCM formats The full list of formats present the #snd_pcm_format_t type. @@ -1276,6 +1279,7 @@ static const char *snd_pcm_state_names[] = { STATE(DRAINING), STATE(PAUSED), STATE(SUSPENDED), + STATE(DISCONNECTED), }; static const char *snd_pcm_access_names[] = { @@ -2050,6 +2054,8 @@ int snd_pcm_wait(snd_pcm_t *pcm, int timeout) return -EPIPE; case SND_PCM_STATE_SUSPENDED: return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + return -ENOTTY; /* linux VFS does this? */ default: return -EIO; } @@ -5932,6 +5938,8 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_ return -EPIPE; case SND_PCM_STATE_SUSPENDED: return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } @@ -6003,6 +6011,8 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area return -EPIPE; case SND_PCM_STATE_SUSPENDED: return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c index e27e7b19..c8e0414c 100644 --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -385,6 +385,15 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm) snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail; snd_pcm_sframes_t diff; + switch (snd_pcm_state(dmix->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dmix->state = -ENOTTY; + return -ENOTTY; + default: + break; + } old_slave_hw_ptr = dmix->slave_hw_ptr; slave_hw_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; diff = slave_hw_ptr - old_slave_hw_ptr; @@ -420,6 +429,7 @@ static int snd_pcm_dmix_sync_ptr(snd_pcm_t *pcm) static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_direct_t *dmix = pcm->private_data; + snd_pcm_state_t state; switch (dmix->state) { case SNDRV_PCM_STATE_DRAINING: @@ -430,7 +440,8 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status) break; } memset(status, 0, sizeof(*status)); - status->state = dmix->state; + state = snd_pcm_state(dmix->spcm); + status->state = state == SNDRV_PCM_STATE_RUNNING ? dmix->state : state; status->trigger_tstamp = dmix->trigger_tstamp; status->tstamp = snd_pcm_hw_fast_tstamp(dmix->spcm); status->avail = snd_pcm_mmap_playback_avail(pcm); @@ -442,6 +453,15 @@ static int snd_pcm_dmix_status(snd_pcm_t *pcm, snd_pcm_status_t * status) static snd_pcm_state_t snd_pcm_dmix_state(snd_pcm_t *pcm) { snd_pcm_direct_t *dmix = pcm->private_data; + switch (snd_pcm_state(dmix->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dmix->state = -ENOTTY; + return -ENOTTY; + default: + break; + } return dmix->state; } @@ -462,6 +482,8 @@ static int snd_pcm_dmix_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } @@ -480,6 +502,8 @@ static int snd_pcm_dmix_hwsync(snd_pcm_t *pcm) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } @@ -891,7 +915,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, const char *name, if (dmix->channels == UINT_MAX) dmix->channels = dmix->shmptr->s.channels; - + snd_pcm_direct_semaphore_up(dmix, DIRECT_IPC_SEM_CLIENT); *pcmp = pcm; diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c index c4ac1205..8d344852 100644 --- a/src/pcm/pcm_dshare.c +++ b/src/pcm/pcm_dshare.c @@ -132,6 +132,15 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm) snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail; snd_pcm_sframes_t diff; + switch (snd_pcm_state(dshare->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dshare->state = SNDRV_PCM_STATE_DISCONNECTED; + return -ENOTTY; + default: + break; + } old_slave_hw_ptr = dshare->slave_hw_ptr; slave_hw_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr; diff = slave_hw_ptr - old_slave_hw_ptr; @@ -167,6 +176,7 @@ static int snd_pcm_dshare_sync_ptr(snd_pcm_t *pcm) static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_direct_t *dshare = pcm->private_data; + snd_pcm_state_t state; switch (dshare->state) { case SNDRV_PCM_STATE_DRAINING: @@ -177,7 +187,8 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) break; } memset(status, 0, sizeof(*status)); - status->state = dshare->state; + state = snd_pcm_state(dshare->spcm); + status->state = state == SND_PCM_STATE_RUNNING ? dshare->state : state; status->trigger_tstamp = dshare->trigger_tstamp; status->tstamp = snd_pcm_hw_fast_tstamp(dshare->spcm); status->avail = snd_pcm_mmap_playback_avail(pcm); @@ -189,6 +200,15 @@ static int snd_pcm_dshare_status(snd_pcm_t *pcm, snd_pcm_status_t * status) static snd_pcm_state_t snd_pcm_dshare_state(snd_pcm_t *pcm) { snd_pcm_direct_t *dshare = pcm->private_data; + switch (snd_pcm_state(dshare->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dshare->state = SNDRV_PCM_STATE_DISCONNECTED; + return -ENOTTY; + default: + break; + } return dshare->state; } @@ -209,6 +229,8 @@ static int snd_pcm_dshare_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } @@ -227,6 +249,8 @@ static int snd_pcm_dshare_hwsync(snd_pcm_t *pcm) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c index df428154..967ee747 100644 --- a/src/pcm/pcm_dsnoop.c +++ b/src/pcm/pcm_dsnoop.c @@ -114,6 +114,15 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm) snd_pcm_uframes_t slave_hw_ptr, old_slave_hw_ptr, avail; snd_pcm_sframes_t diff; + switch (snd_pcm_state(dsnoop->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dsnoop->state = SNDRV_PCM_STATE_DISCONNECTED; + return -ENOTTY; + default: + break; + } old_slave_hw_ptr = dsnoop->slave_hw_ptr; slave_hw_ptr = dsnoop->slave_hw_ptr = *dsnoop->spcm->hw.ptr; diff = slave_hw_ptr - old_slave_hw_ptr; @@ -150,6 +159,7 @@ static snd_pcm_sframes_t snd_pcm_dsnoop_sync_ptr(snd_pcm_t *pcm) static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) { snd_pcm_direct_t *dsnoop = pcm->private_data; + snd_pcm_state_t state; switch(dsnoop->state) { case SNDRV_PCM_STATE_DRAINING: @@ -160,7 +170,8 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) break; } memset(status, 0, sizeof(*status)); - status->state = dsnoop->state; + state = snd_pcm_state(dsnoop->spcm); + status->state = state == SND_PCM_STATE_RUNNING ? dsnoop->state : state; status->trigger_tstamp = dsnoop->trigger_tstamp; status->tstamp = snd_pcm_hw_fast_tstamp(dsnoop->spcm); status->avail = snd_pcm_mmap_capture_avail(pcm); @@ -172,6 +183,15 @@ static int snd_pcm_dsnoop_status(snd_pcm_t *pcm, snd_pcm_status_t * status) static snd_pcm_state_t snd_pcm_dsnoop_state(snd_pcm_t *pcm) { snd_pcm_direct_t *dsnoop = pcm->private_data; + switch (snd_pcm_state(dsnoop->spcm)) { + case SND_PCM_STATE_SUSPENDED: + return -ESTRPIPE; + case SND_PCM_STATE_DISCONNECTED: + dsnoop->state = SNDRV_PCM_STATE_DISCONNECTED; + return -ENOTTY; + default: + break; + } return dsnoop->state; } @@ -192,6 +212,8 @@ static int snd_pcm_dsnoop_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } @@ -210,6 +232,8 @@ static int snd_pcm_dsnoop_hwsync(snd_pcm_t *pcm) return 0; case SNDRV_PCM_STATE_XRUN: return -EPIPE; + case SNDRV_PCM_STATE_DISCONNECTED: + return -ENOTTY; default: return -EBADFD; } -- 2.47.1