All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2 v2] Open Alsa dshare without channel binding
@ 2019-07-24 10:12 Adam Miartus
  2019-07-24 10:12 ` [PATCH 1/2] alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL Adam Miartus
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Adam Miartus @ 2019-07-24 10:12 UTC (permalink / raw)
  To: patch; +Cc: alsa-devel

The general idea of this patch is to be able to open the device without
defined bindings. As a result, it allows starting the audio clock of
underlying device without blocking a channel.

This might be useful for creating a dummy dsnoop pcm for hardware that
requires running clock early at system start. This clock is then present
even without application streaming audio data.

Patch n.1 is intended to check for null pointer of pcm callbacks,
it is not intended to alter any current functionality, properly defined
plugins should not suffer from this change

Patch n.2 is not intended to alter any current functionality, only
extend it

V2 of the patch, changes from V1:
  - instead of creating new "pcm_unsupported.c" with ops and fast_ops
    callbacks returning -ENOSYS, callback == NULL is checked directly
    in core implementation and error is returned when pcm has no
    callback defined

Adam Miartus (2):
  alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL
  alsa: dshare: allow missing bindings

 src/pcm/pcm.c        | 134 +++++++++++++++++++++++++++++++++++++++++----------
 src/pcm/pcm_dshare.c |  29 ++++++-----
 src/pcm/pcm_local.h  |  20 ++++++++
 src/pcm/pcm_mmap.c   |  15 ++++--
 src/pcm/pcm_params.c |  10 +++-
 5 files changed, 166 insertions(+), 42 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL
  2019-07-24 10:12 [PATCH 0/2 v2] Open Alsa dshare without channel binding Adam Miartus
@ 2019-07-24 10:12 ` Adam Miartus
  2019-07-24 10:13 ` [PATCH 2/2] alsa: dshare: allow missing bindings Adam Miartus
  2019-07-24 13:20 ` [ALSA patch] [PATCH 0/2 v2] Open Alsa dshare without channel binding Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Adam Miartus @ 2019-07-24 10:12 UTC (permalink / raw)
  To: patch; +Cc: alsa-devel

function is allowed to continue until it checks for error variable, as to
not conflict with original implementation flow

for simple functions involving only one line, return error immediately in
case callback is NULL

Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
---
 src/pcm/pcm.c        | 134 +++++++++++++++++++++++++++++++++++++++++----------
 src/pcm/pcm_local.h  |  20 ++++++++
 src/pcm/pcm_mmap.c   |  15 ++++--
 src/pcm/pcm_params.c |  10 +++-
 4 files changed, 148 insertions(+), 31 deletions(-)

diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
index e0ceccc..178d438 100644
--- a/src/pcm/pcm.c
+++ b/src/pcm/pcm.c
@@ -761,7 +761,10 @@ int snd_pcm_close(snd_pcm_t *pcm)
 		snd_async_handler_t *h = list_entry(pcm->async_handlers.next, snd_async_handler_t, hlist);
 		snd_async_del_handler(h);
 	}
-	err = pcm->ops->close(pcm->op_arg);
+	if (pcm->ops->close)
+		err = pcm->ops->close(pcm->op_arg);
+	else
+		err = -ENOSYS;
 	if (err < 0)
 		res = err;
 	err = snd_pcm_free(pcm);
@@ -787,7 +790,11 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
 	 * the possible deadlock in signal handler calling snd_pcm_abort()
 	 */
 	/* __snd_pcm_lock(pcm); */ /* forced lock due to pcm field change */
-	if ((err = pcm->ops->nonblock(pcm->op_arg, nonblock)) < 0)
+	if (pcm->ops->nonblock)
+		err = pcm->ops->nonblock(pcm->op_arg, nonblock);
+	else
+		err = -ENOSYS;
+	if (err < 0)
 		goto unlock;
 	if (nonblock == 2) {
 		pcm->mode |= SND_PCM_ABORT;
@@ -818,6 +825,8 @@ int snd_pcm_nonblock(snd_pcm_t *pcm, int nonblock)
  */
 int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
 {
+	int err = 0;
+
 	assert(pcm);
 	if (sig == 0)
 		sig = SIGIO;
@@ -828,7 +837,11 @@ int snd_pcm_async(snd_pcm_t *pcm, int sig, pid_t pid)
 	/* async handler may lead to a deadlock; suppose no multi thread */
 	pcm->lock_enabled = 0;
 #endif
-	return pcm->ops->async(pcm->op_arg, sig, pid);
+	if (pcm->ops->async)
+		err = pcm->ops->async(pcm->op_arg, sig, pid);
+	else
+		err = -ENOSYS;
+	return err;
 }
 #endif
 
@@ -840,8 +853,14 @@ 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 err = 0;
+
 	assert(pcm && info);
-	return pcm->ops->info(pcm->op_arg, info);
+	if (pcm->ops->info)
+		err = pcm->ops->info(pcm->op_arg, info);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /** \brief Retreive current PCM hardware configuration chosen with #snd_pcm_hw_params
@@ -927,7 +946,10 @@ int snd_pcm_hw_free(snd_pcm_t *pcm)
 	}
 	// assert(snd_pcm_state(pcm) == SND_PCM_STATE_SETUP ||
 	//        snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED);
-	err = pcm->ops->hw_free(pcm->op_arg);
+	if (pcm->ops->hw_free)
+		err = pcm->ops->hw_free(pcm->op_arg);
+	else
+		err = -ENOSYS;
 	pcm->setup = 0;
 	if (err < 0)
 		return err;
@@ -968,7 +990,10 @@ int snd_pcm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t *params)
 	}
 #endif
 	__snd_pcm_lock(pcm); /* forced lock due to pcm field change */
-	err = pcm->ops->sw_params(pcm->op_arg, params);
+	if (pcm->ops->sw_params)
+		err = pcm->ops->sw_params(pcm->op_arg, params);
+	else
+		err = -ENOSYS;
 	if (err < 0) {
 		__snd_pcm_unlock(pcm);
 		return err;
@@ -1001,7 +1026,10 @@ int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
 
 	assert(pcm && status);
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->status(pcm->fast_op_arg, status);
+	if (pcm->fast_ops->status)
+		err = pcm->fast_ops->status(pcm->fast_op_arg, status);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 
 	return err;
@@ -1117,13 +1145,19 @@ int snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
  */
 int snd_pcm_resume(snd_pcm_t *pcm)
 {
+	int err = 0;
+
 	assert(pcm);
 	if (CHECK_SANITY(! pcm->setup)) {
 		SNDMSG("PCM not set up");
 		return -EIO;
 	}
 	/* lock handled in the callback */
-	return pcm->fast_ops->resume(pcm->fast_op_arg);
+	if (pcm->fast_ops->resume)
+		err = pcm->fast_ops->resume(pcm->fast_op_arg);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /**
@@ -1148,7 +1182,10 @@ int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_
 		return -EIO;
 	}
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->htimestamp(pcm->fast_op_arg, avail, tstamp);
+	if (pcm->fast_ops->htimestamp)
+		err = pcm->fast_ops->htimestamp(pcm->fast_op_arg, avail, tstamp);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return err;
 }
@@ -1173,7 +1210,10 @@ int snd_pcm_prepare(snd_pcm_t *pcm)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->prepare(pcm->fast_op_arg);
+	if (pcm->fast_ops->prepare)
+		err = pcm->fast_ops->prepare(pcm->fast_op_arg);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return err;
 }
@@ -1197,7 +1237,10 @@ int snd_pcm_reset(snd_pcm_t *pcm)
 		return -EIO;
 	}
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->reset(pcm->fast_op_arg);
+	if (pcm->fast_ops->reset)
+		err = pcm->fast_ops->reset(pcm->fast_op_arg);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return err;
 }
@@ -1254,7 +1297,10 @@ int snd_pcm_drop(snd_pcm_t *pcm)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->drop(pcm->fast_op_arg);
+	if (pcm->fast_ops->drop)
+		err = pcm->fast_ops->drop(pcm->fast_op_arg);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return err;
 }
@@ -1287,7 +1333,11 @@ int snd_pcm_drain(snd_pcm_t *pcm)
 	if (err < 0)
 		return err;
 	/* lock handled in the callback */
-	return pcm->fast_ops->drain(pcm->fast_op_arg);
+	if (pcm->fast_ops->drain)
+		err = pcm->fast_ops->drain(pcm->fast_op_arg);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /**
@@ -1315,7 +1365,10 @@ int snd_pcm_pause(snd_pcm_t *pcm, int enable)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	err = pcm->fast_ops->pause(pcm->fast_op_arg, enable);
+	if (pcm->fast_ops->pause)
+		err = pcm->fast_ops->pause(pcm->fast_op_arg, enable);
+	else
+		err = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return err;
 }
@@ -1345,7 +1398,10 @@ snd_pcm_sframes_t snd_pcm_rewindable(snd_pcm_t *pcm)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	result = pcm->fast_ops->rewindable(pcm->fast_op_arg);
+	if (pcm->fast_ops->rewindable)
+		result = pcm->fast_ops->rewindable(pcm->fast_op_arg);
+	else
+		result = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return result;
 }
@@ -1375,7 +1431,10 @@ snd_pcm_sframes_t snd_pcm_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	result = pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
+	if (pcm->fast_ops->rewind)
+		result = pcm->fast_ops->rewind(pcm->fast_op_arg, frames);
+	else
+		result = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return result;
 }
@@ -1405,7 +1464,10 @@ snd_pcm_sframes_t snd_pcm_forwardable(snd_pcm_t *pcm)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	result = pcm->fast_ops->forwardable(pcm->fast_op_arg);
+	if (pcm->fast_ops->forwardable)
+		result = pcm->fast_ops->forwardable(pcm->fast_op_arg);
+	else
+		result = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return result;
 }
@@ -1439,7 +1501,10 @@ snd_pcm_sframes_t snd_pcm_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 	if (err < 0)
 		return err;
 	snd_pcm_lock(pcm);
-	result = pcm->fast_ops->forward(pcm->fast_op_arg, frames);
+	if (pcm->fast_ops->forward)
+		result = pcm->fast_ops->forward(pcm->fast_op_arg, frames);
+	else
+		result = -ENOSYS;
 	snd_pcm_unlock(pcm);
 	return result;
 }
@@ -1611,11 +1676,15 @@ snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t s
  */ 
 int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
 {
+	int err = 0;
+
 	assert(pcm1);
 	assert(pcm2);
 	if (pcm1->fast_ops->link)
-		return pcm1->fast_ops->link(pcm1, pcm2);
-	return -ENOSYS;
+		err = pcm1->fast_ops->link(pcm1, pcm2);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /**
@@ -1625,10 +1694,14 @@ int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2)
  */
 int snd_pcm_unlink(snd_pcm_t *pcm)
 {
+	int err = 0;
+
 	assert(pcm);
 	if (pcm->fast_ops->unlink)
-		return pcm->fast_ops->unlink(pcm);
-	return -ENOSYS;
+		err = pcm->fast_ops->unlink(pcm);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /* locked version */
@@ -2275,10 +2348,15 @@ int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out)
  */
 int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out)
 {
+	int err = 0;
+
 	assert(pcm);
 	assert(out);
-	pcm->ops->dump(pcm->op_arg, out);
-	return 0;
+	if (pcm->ops->dump)
+		pcm->ops->dump(pcm->op_arg, out);
+	else
+		err = -ENOSYS;
+	return err;
 }
 
 /**
@@ -7242,7 +7320,10 @@ snd_pcm_sframes_t __snd_pcm_mmap_commit(snd_pcm_t *pcm,
 		       snd_pcm_mmap_avail(pcm));
 		return -EPIPE;
 	}
-	return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
+	if (pcm->fast_ops->mmap_commit)
+		return pcm->fast_ops->mmap_commit(pcm->fast_op_arg, offset, frames);
+	else
+		return -ENOSYS;
 }
 
 int _snd_pcm_poll_descriptor(snd_pcm_t *pcm)
@@ -7969,7 +8050,8 @@ static int chmap_equal(const snd_pcm_chmap_t *a, const snd_pcm_chmap_t *b)
  * \return the NULL-terminated array of integer pointers, each of
  * which contains the channel map. A channel map is represented by an
  * integer array, beginning with the channel map type, followed by the
- * number of channels, and the position of each channel.
+ * number of channels, and the position of each channel. Return NULL
+ * in case of an error.
  *
  * Note: the caller is requested to release the returned value via
  * snd_pcm_free_chmaps().
diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h
index d5726eb..05ed935 100644
--- a/src/pcm/pcm_local.h
+++ b/src/pcm/pcm_local.h
@@ -410,6 +410,8 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset,
 				     snd_pcm_uframes_t size);
 static inline int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
 {
+	if (!pcm->ops->channel_info)
+		return -ENOSYS;
 	return pcm->ops->channel_info(pcm, info);
 }
 int snd_pcm_channel_info_shm(snd_pcm_t *pcm, snd_pcm_channel_info_t *info, int shmid);
@@ -427,26 +429,36 @@ int __snd_pcm_wait_in_lock(snd_pcm_t *pcm, int timeout);
 
 static inline snd_pcm_sframes_t __snd_pcm_avail_update(snd_pcm_t *pcm)
 {
+	if (!pcm->fast_ops->avail_update)
+		return -ENOSYS;
 	return pcm->fast_ops->avail_update(pcm->fast_op_arg);
 }
 
 static inline int __snd_pcm_start(snd_pcm_t *pcm)
 {
+	if (!pcm->fast_ops->start)
+		return -ENOSYS;
 	return pcm->fast_ops->start(pcm->fast_op_arg);
 }
 
 static inline snd_pcm_state_t __snd_pcm_state(snd_pcm_t *pcm)
 {
+	if (!pcm->fast_ops->state)
+		return -ENOSYS;
 	return pcm->fast_ops->state(pcm->fast_op_arg);
 }
 
 static inline int __snd_pcm_hwsync(snd_pcm_t *pcm)
 {
+	if (!pcm->fast_ops->hwsync)
+		return -ENOSYS;
 	return pcm->fast_ops->hwsync(pcm->fast_op_arg);
 }
 
 static inline int __snd_pcm_delay(snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)
 {
+	if (!pcm->fast_ops->delay)
+		return -ENOSYS;
 	return pcm->fast_ops->delay(pcm->fast_op_arg, delayp);
 }
 
@@ -604,24 +616,32 @@ static inline unsigned int snd_pcm_channel_area_step(const snd_pcm_channel_area_
 static inline snd_pcm_sframes_t _snd_pcm_writei(snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)
 {
 	/* lock handled in the callback */
+	if (!pcm->fast_ops->writei)
+		return -ENOSYS;
 	return pcm->fast_ops->writei(pcm->fast_op_arg, buffer, size);
 }
 
 static inline snd_pcm_sframes_t _snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
 	/* lock handled in the callback */
+	if (!pcm->fast_ops->writen)
+		return -ENOSYS;
 	return pcm->fast_ops->writen(pcm->fast_op_arg, bufs, size);
 }
 
 static inline snd_pcm_sframes_t _snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t size)
 {
 	/* lock handled in the callback */
+	if (!pcm->fast_ops->readi)
+		return -ENOSYS;
 	return pcm->fast_ops->readi(pcm->fast_op_arg, buffer, size);
 }
 
 static inline snd_pcm_sframes_t _snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size)
 {
 	/* lock handled in the callback */
+	if (!pcm->fast_ops->readn)
+		return -ENOSYS;
 	return pcm->fast_ops->readn(pcm->fast_op_arg, bufs, size);
 }
 
diff --git a/src/pcm/pcm_mmap.c b/src/pcm/pcm_mmap.c
index 0d00f26..024ae65 100644
--- a/src/pcm/pcm_mmap.c
+++ b/src/pcm/pcm_mmap.c
@@ -269,7 +269,10 @@ int snd_pcm_mmap(snd_pcm_t *pcm)
 		SNDMSG("Already mmapped");
 		return -EBUSY;
 	}
-	err = pcm->ops->mmap(pcm);
+	if (pcm->ops->mmap)
+		err = pcm->ops->mmap(pcm);
+	else
+		err = -ENOSYS;
 	if (err < 0)
 		return err;
 	if (pcm->mmap_shadow)
@@ -445,7 +448,10 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
 		return -ENXIO;
 	}
 	if (pcm->mmap_shadow)
-		return pcm->ops->munmap(pcm);
+		if (pcm->ops->munmap)
+			return pcm->ops->munmap(pcm);
+		else
+			return -ENOSYS;
 	for (c = 0; c < pcm->channels; ++c) {
 		snd_pcm_channel_info_t *i = &pcm->mmap_channels[c];
 		unsigned int c1;
@@ -503,7 +509,10 @@ int snd_pcm_munmap(snd_pcm_t *pcm)
 		}
 		i->addr = NULL;
 	}
-	err = pcm->ops->munmap(pcm);
+	if (pcm->ops->munmap)
+		err = pcm->ops->munmap(pcm);
+	else
+		err = -ENOSYS;
 	if (err < 0)
 		return err;
 	free(pcm->mmap_channels);
diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c
index 8826bc3..ceb3b1a 100644
--- a/src/pcm/pcm_params.c
+++ b/src/pcm/pcm_params.c
@@ -2356,7 +2356,10 @@ int snd_pcm_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 	snd_output_printf(log, "REFINE called:\n");
 	snd_pcm_hw_params_dump(params, log);
 #endif
-	res = pcm->ops->hw_refine(pcm->op_arg, params);
+	if (pcm->ops->hw_refine)
+		res = pcm->ops->hw_refine(pcm->op_arg, params);
+	else
+		res = -ENOSYS;
 #ifdef REFINE_DEBUG
 	snd_output_printf(log, "refine done - result = %i\n", res);
 	snd_pcm_hw_params_dump(params, log);
@@ -2391,7 +2394,10 @@ int _snd_pcm_hw_params_internal(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
 		if (err < 0)
 			return err;
 	}
-	err = pcm->ops->hw_params(pcm->op_arg, params);
+	if (pcm->ops->hw_params)
+		err = pcm->ops->hw_params(pcm->op_arg, params);
+	else
+		err = -ENOSYS;
 	if (err < 0)
 		return err;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] alsa: dshare: allow missing bindings
  2019-07-24 10:12 [PATCH 0/2 v2] Open Alsa dshare without channel binding Adam Miartus
  2019-07-24 10:12 ` [PATCH 1/2] alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL Adam Miartus
@ 2019-07-24 10:13 ` Adam Miartus
  2019-07-24 13:20 ` [ALSA patch] [PATCH 0/2 v2] Open Alsa dshare without channel binding Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Adam Miartus @ 2019-07-24 10:13 UTC (permalink / raw)
  To: patch; +Cc: alsa-devel, Andreas Pape

allow opening the device and start the audio clock without blocking
any channel

this is required if the audio clock has to be available all the time,
even when application is not streaming audio data

Signed-off-by: Andreas Pape <apape@de.adit-jv.com>
Signed-off-by: Adam Miartus <amiartus@de.adit-jv.com>
---
 src/pcm/pcm_dshare.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c
index b75809c..1d29ffe 100644
--- a/src/pcm/pcm_dshare.c
+++ b/src/pcm/pcm_dshare.c
@@ -508,7 +508,8 @@ static int snd_pcm_dshare_close(snd_pcm_t *pcm)
 
 	if (dshare->timer)
 		snd_timer_close(dshare->timer);
-	do_silence(pcm);
+	if (dshare->bindings)
+		do_silence(pcm);
 	snd_pcm_direct_semaphore_down(dshare, DIRECT_IPC_SEM_CLIENT);
 	dshare->shmptr->u.dshare.chn_mask &= ~dshare->u.dshare.chn_mask;
 	snd_pcm_close(dshare->spcm);
@@ -621,6 +622,12 @@ static void snd_pcm_dshare_dump(snd_pcm_t *pcm, snd_output_t *out)
 		snd_pcm_dump(dshare->spcm, out);
 }
 
+static const snd_pcm_ops_t snd_pcm_dshare_dummy_ops = {
+	.close = snd_pcm_dshare_close,
+};
+
+static const snd_pcm_fast_ops_t snd_pcm_dshare_fast_dummy_ops;
+
 static const snd_pcm_ops_t snd_pcm_dshare_ops = {
 	.close = snd_pcm_dshare_close,
 	.info = snd_pcm_direct_info,
@@ -713,12 +720,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 	if (ret < 0)
 		goto _err_nosem;
 		
-	if (!dshare->bindings) {
-		SNDERR("dshare: specify bindings!!!");
-		ret = -EINVAL;
-		goto _err_nosem;
-	}
-	
+
 	dshare->ipc_key = opts->ipc_key;
 	dshare->ipc_perm = opts->ipc_perm;
 	dshare->ipc_gid = opts->ipc_gid;
@@ -751,9 +753,14 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 		SNDERR("unable to create IPC shm instance");
 		goto _err;
 	}
-		
-	pcm->ops = &snd_pcm_dshare_ops;
-	pcm->fast_ops = &snd_pcm_dshare_fast_ops;
+
+	if (!dshare->bindings) {
+		pcm->ops = &snd_pcm_dshare_dummy_ops;
+		pcm->fast_ops = &snd_pcm_dshare_fast_dummy_ops;
+	} else {
+		pcm->ops = &snd_pcm_dshare_ops;
+		pcm->fast_ops = &snd_pcm_dshare_fast_ops;
+	}
 	pcm->private_data = dshare;
 	dshare->state = SND_PCM_STATE_OPEN;
 	dshare->slowptr = opts->slowptr;
@@ -843,7 +850,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name,
 		dshare->spcm = spcm;
 	}
 
-	for (chn = 0; chn < dshare->channels; chn++) {
+	for (chn = 0; dshare->bindings && (chn < dshare->channels); chn++) {
 		unsigned int dchn = dshare->bindings ? dshare->bindings[chn] : chn;
 		if (dchn != UINT_MAX)
 			dshare->u.dshare.chn_mask |= (1ULL << dchn);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [ALSA patch] [PATCH 0/2 v2] Open Alsa dshare without channel binding
  2019-07-24 10:12 [PATCH 0/2 v2] Open Alsa dshare without channel binding Adam Miartus
  2019-07-24 10:12 ` [PATCH 1/2] alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL Adam Miartus
  2019-07-24 10:13 ` [PATCH 2/2] alsa: dshare: allow missing bindings Adam Miartus
@ 2019-07-24 13:20 ` Takashi Iwai
  2 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2019-07-24 13:20 UTC (permalink / raw)
  To: Adam Miartus; +Cc: alsa-devel

On Wed, 24 Jul 2019 12:12:58 +0200,
Adam Miartus wrote:
> 
> The general idea of this patch is to be able to open the device without
> defined bindings. As a result, it allows starting the audio clock of
> underlying device without blocking a channel.
> 
> This might be useful for creating a dummy dsnoop pcm for hardware that
> requires running clock early at system start. This clock is then present
> even without application streaming audio data.
> 
> Patch n.1 is intended to check for null pointer of pcm callbacks,
> it is not intended to alter any current functionality, properly defined
> plugins should not suffer from this change
> 
> Patch n.2 is not intended to alter any current functionality, only
> extend it
> 
> V2 of the patch, changes from V1:
>   - instead of creating new "pcm_unsupported.c" with ops and fast_ops
>     callbacks returning -ENOSYS, callback == NULL is checked directly
>     in core implementation and error is returned when pcm has no
>     callback defined

Looks much better now to me.  Applied both patches.
Thanks!

Takashi

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-07-24 13:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-24 10:12 [PATCH 0/2 v2] Open Alsa dshare without channel binding Adam Miartus
2019-07-24 10:12 ` [PATCH 1/2] alsa: pcm: return -ENOSYS when ops or fast_ops callback is NULL Adam Miartus
2019-07-24 10:13 ` [PATCH 2/2] alsa: dshare: allow missing bindings Adam Miartus
2019-07-24 13:20 ` [ALSA patch] [PATCH 0/2 v2] Open Alsa dshare without channel binding Takashi Iwai

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.