diff --git a/0001-pcm-direct-Add-generic-hw_ptr_alignment-function-for.patch b/0001-pcm-direct-Add-generic-hw_ptr_alignment-function-for.patch new file mode 100644 index 0000000..564898f --- /dev/null +++ b/0001-pcm-direct-Add-generic-hw_ptr_alignment-function-for.patch @@ -0,0 +1,137 @@ +From 63ba5243ab7a33b77be5b65c0a8a2a0d5e26983f Mon Sep 17 00:00:00 2001 +From: Vanitha Channaiah +Date: Wed, 15 May 2019 11:56:32 +0530 +Subject: [PATCH 01/25] pcm: direct: Add generic hw_ptr_alignment function for + dmix, dshare and dsnoop + +Move the code snd_pcm_direct_reset_slave_ptr() from pcm_dmix.c +to pcm_direct.c and its header so that the helper function can be +re-used by other direct-pcm plugins. +There is no change in the behavior or the functionality. + +Signed-off-by: Vanitha Channaiah +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_direct.c | 19 +++++++++++++++++++ + src/pcm/pcm_direct.h | 8 ++++++++ + src/pcm/pcm_dmix.c | 25 ++----------------------- + 3 files changed, 29 insertions(+), 23 deletions(-) + +diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c +index 666a8ce5b130..411a035b32ed 100644 +--- a/src/pcm/pcm_direct.c ++++ b/src/pcm/pcm_direct.c +@@ -2040,3 +2040,22 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, + + return 0; + } ++ ++void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix) ++{ ++ dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; ++ ++ if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP || ++ (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO && ++ pcm->buffer_size <= pcm->period_size * 2)) ++ dmix->slave_appl_ptr = ++ ((dmix->slave_appl_ptr + dmix->slave_period_size - 1) / ++ dmix->slave_period_size) * dmix->slave_period_size; ++ else if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDDOWN || ++ (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO && ++ (dmix->slave_period_size * SEC_TO_MS) / ++ pcm->rate < LOW_LATENCY_PERIOD_TIME)) ++ dmix->slave_appl_ptr = dmix->slave_hw_ptr = ++ ((dmix->slave_hw_ptr / dmix->slave_period_size) * ++ dmix->slave_period_size); ++} +diff --git a/src/pcm/pcm_direct.h b/src/pcm/pcm_direct.h +index da5e280e711d..a71aab13afa9 100644 +--- a/src/pcm/pcm_direct.h ++++ b/src/pcm/pcm_direct.h +@@ -24,6 +24,11 @@ + + #define DIRECT_IPC_SEMS 1 + #define DIRECT_IPC_SEM_CLIENT 0 ++/* Seconds representing in Milli seconds */ ++#define SEC_TO_MS 1000 ++/* slave_period time for low latency requirements in ms */ ++#define LOW_LATENCY_PERIOD_TIME 10 ++ + + typedef void (mix_areas_t)(unsigned int size, + volatile void *dst, void *src, +@@ -257,6 +262,8 @@ struct snd_pcm_direct { + snd1_pcm_direct_get_chmap + #define snd_pcm_direct_set_chmap \ + snd1_pcm_direct_set_chmap ++#define snd_pcm_direct_reset_slave_ptr \ ++ snd1_pcm_direct_reset_slave_ptr + + int snd_pcm_direct_semaphore_create_or_connect(snd_pcm_direct_t *dmix); + +@@ -341,6 +348,7 @@ int snd_pcm_direct_slave_recover(snd_pcm_direct_t *direct); + int snd_pcm_direct_client_chk_xrun(snd_pcm_direct_t *direct, snd_pcm_t *pcm); + int snd_timer_async(snd_timer_t *timer, int sig, pid_t pid); + struct timespec snd_pcm_hw_fast_tstamp(snd_pcm_t *pcm); ++void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix); + + struct snd_pcm_direct_open_conf { + key_t ipc_key; +diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c +index c5592cdba3c4..dcde40d9976e 100644 +--- a/src/pcm/pcm_dmix.c ++++ b/src/pcm/pcm_dmix.c +@@ -55,9 +55,6 @@ const char *_snd_module_pcm_dmix = ""; + #define STATE_RUN_PENDING 1024 + #endif + +-#define SEC_TO_MS 1000 /* Seconds representing in Milli seconds */ +-#define LOW_LATENCY_PERIOD_TIME 10 /* slave_period time for low latency requirements in ms */ +- + /* + * + */ +@@ -560,30 +557,12 @@ static int snd_pcm_dmix_hwsync(snd_pcm_t *pcm) + } + } + +-static void reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix) +-{ +- dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; +- +- if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP || +- (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO && +- pcm->buffer_size <= pcm->period_size * 2)) +- dmix->slave_appl_ptr = +- ((dmix->slave_appl_ptr + dmix->slave_period_size - 1) +- / dmix->slave_period_size) * dmix->slave_period_size; +- else if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDDOWN || +- (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO && +- (dmix->slave_period_size * SEC_TO_MS) / pcm->rate < LOW_LATENCY_PERIOD_TIME)) +- dmix->slave_appl_ptr = dmix->slave_hw_ptr = +- ((dmix->slave_hw_ptr / dmix->slave_period_size) * +- dmix->slave_period_size); +-} +- + static int snd_pcm_dmix_reset(snd_pcm_t *pcm) + { + snd_pcm_direct_t *dmix = pcm->private_data; + dmix->hw_ptr %= pcm->period_size; + dmix->appl_ptr = dmix->last_appl_ptr = dmix->hw_ptr; +- reset_slave_ptr(pcm, dmix); ++ snd_pcm_direct_reset_slave_ptr(pcm, dmix); + return 0; + } + +@@ -592,7 +571,7 @@ static int snd_pcm_dmix_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dmix) + int err; + + snd_pcm_hwsync(dmix->spcm); +- reset_slave_ptr(pcm, dmix); ++ snd_pcm_direct_reset_slave_ptr(pcm, dmix); + err = snd_timer_start(dmix->timer); + if (err < 0) + return err; +-- +2.16.4 + diff --git a/0002-pcm-dshare-Added-hw_ptr_alignment-option-in-configur.patch b/0002-pcm-dshare-Added-hw_ptr_alignment-option-in-configur.patch new file mode 100644 index 0000000..eafc98e --- /dev/null +++ b/0002-pcm-dshare-Added-hw_ptr_alignment-option-in-configur.patch @@ -0,0 +1,126 @@ +From 7265e603bf880a9ec2cd01c3cf2afbd7709e5af4 Mon Sep 17 00:00:00 2001 +From: Vanitha Channaiah +Date: Wed, 15 May 2019 11:56:33 +0530 +Subject: [PATCH 02/25] pcm: dshare: Added "hw_ptr_alignment" option in + configuration for alignment of slave pointers + +This change adapt the fix commit 6b058fda9dce +("pcm: dmix: Add option to allow alignment of slave pointers") +for dshare plugin + +Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr +is not period aligned. Therefore snd_pcm_wait() will block for a longer +time as required. + +With these rcar driver changes the exact position of the dma is returned. +During snd_pcm_start they read hw_ptr as reference, and this hw_ptr +is now not period aligned, and is a little ahead over the period while it +is read. Therefore when the avail is calculated during snd_pcm_wait(), +it is missing the avail_min by a few frames. + +An additional option hw_ptr_alignment is provided to dshare configuration, +to allow the user to configure the slave application and hw pointer +alignment at startup + +Signed-off-by: Vanitha Channaiah +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_dshare.c | 40 +++++++++++++++++++++++++++++++++++----- + 1 file changed, 35 insertions(+), 5 deletions(-) + +diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c +index f135b5dfce8b..cf8a8631dd5e 100644 +--- a/src/pcm/pcm_dshare.c ++++ b/src/pcm/pcm_dshare.c +@@ -333,16 +333,16 @@ static int snd_pcm_dshare_reset(snd_pcm_t *pcm) + snd_pcm_direct_t *dshare = pcm->private_data; + dshare->hw_ptr %= pcm->period_size; + dshare->appl_ptr = dshare->last_appl_ptr = dshare->hw_ptr; +- dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr; ++ snd_pcm_direct_reset_slave_ptr(pcm, dshare); + return 0; + } + +-static int snd_pcm_dshare_start_timer(snd_pcm_direct_t *dshare) ++static int snd_pcm_dshare_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dshare) + { + int err; + + snd_pcm_hwsync(dshare->spcm); +- dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr; ++ snd_pcm_direct_reset_slave_ptr(pcm, dshare); + err = snd_timer_start(dshare->timer); + if (err < 0) + return err; +@@ -364,7 +364,8 @@ static int snd_pcm_dshare_start(snd_pcm_t *pcm) + else if (avail < 0) + return 0; + else { +- if ((err = snd_pcm_dshare_start_timer(dshare)) < 0) ++ err = snd_pcm_dshare_start_timer(pcm, dshare); ++ if (err < 0) + return err; + snd_pcm_dshare_sync_area(pcm); + } +@@ -547,7 +548,8 @@ static snd_pcm_sframes_t snd_pcm_dshare_mmap_commit(snd_pcm_t *pcm, + return 0; + snd_pcm_mmap_appl_forward(pcm, size); + if (dshare->state == STATE_RUN_PENDING) { +- if ((err = snd_pcm_dshare_start_timer(dshare)) < 0) ++ err = snd_pcm_dshare_start_timer(pcm, dshare); ++ if (err < 0) + return err; + } else if (dshare->state == SND_PCM_STATE_RUNNING || + dshare->state == SND_PCM_STATE_DRAINING) { +@@ -755,6 +757,7 @@ int snd_pcm_dshare_open(snd_pcm_t **pcmp, const char *name, + dshare->slowptr = opts->slowptr; + dshare->max_periods = opts->max_periods; + dshare->var_periodsize = opts->var_periodsize; ++ dshare->hw_ptr_alignment = opts->hw_ptr_alignment; + dshare->sync_ptr = snd_pcm_dshare_sync_ptr; + + retry: +@@ -912,6 +915,12 @@ pcm.name { + ipc_key INT # unique IPC key + ipc_key_add_uid BOOL # add current uid to unique IPC key + ipc_perm INT # IPC permissions (octal, default 0600) ++ hw_ptr_alignment STR # Slave application and hw pointer alignment type ++ # STR can be one of the below strings : ++ # no ++ # roundup ++ # rounddown ++ # auto (default) + slave STR + # or + slave { # Slave definition +@@ -936,6 +945,27 @@ pcm.name { + } + \endcode + ++hw_ptr_alignment specifies slave application and hw ++pointer alignment type. By default hw_ptr_alignment is auto. Below are ++the possible configurations: ++- no: minimal latency with minimal frames dropped at startup. But ++ wakeup of application (return from snd_pcm_wait() or poll()) can ++ take up to 2 * period. ++- roundup: It is guaranteed that all frames will be played at ++ startup. But the latency will increase upto period-1 frames. ++- rounddown: It is guaranteed that a wakeup will happen for each ++ period and frames can be written from application. But on startup ++ upto period-1 frames will be dropped. ++- auto: Selects the best approach depending on the used period and ++ buffer size. ++ If the application buffer size is < 2 * application period, ++ "roundup" will be selected to avoid under runs. If the slave_period ++ is < 10ms we could expect that there are low latency ++ requirements. Therefore "rounddown" will be chosen to avoid long ++ wakeup times. Such wakeup delay could otherwise end up with Xruns in ++ case of a dependency to another sound device (e.g. forwarding of ++ microphone to speaker). Else "no" will be chosen. ++ + \subsection pcm_plugins_dshare_funcref Function reference + +
    +-- +2.16.4 + diff --git a/0003-pcm-dsnoop-Added-hw_ptr_alignment-option-in-configur.patch b/0003-pcm-dsnoop-Added-hw_ptr_alignment-option-in-configur.patch new file mode 100644 index 0000000..85a5b1a --- /dev/null +++ b/0003-pcm-dsnoop-Added-hw_ptr_alignment-option-in-configur.patch @@ -0,0 +1,162 @@ +From 3ab798004733ce65bd5c7a48d650de3465825210 Mon Sep 17 00:00:00 2001 +From: Vanitha Channaiah +Date: Wed, 15 May 2019 11:56:34 +0530 +Subject: [PATCH 03/25] pcm: dsnoop: Added "hw_ptr_alignment" option in + configuration for slave pointer alignment + +This change adapt the fix commit 6b058fda9dce +("pcm: dmix: Add option to allow alignment of slave pointers") +for dsnoop plugin + +Issue is that snd_pcm_wait() goes back to waiting because the hw_ptr +is not period aligned. Therefore snd_pcm_wait() will block for a longer +time as required. + +With these rcar driver changes the exact position of the dma is returned. +During snd_pcm_start they read hw_ptr as reference, and this hw_ptr +is now not period aligned, and is a little ahead over the period while it +is read. Therefore when the avail is calculated during snd_pcm_wait(), +it is missing the avail_min by a few frames. + +An additional option hw_ptr_alignment is provided to dsnoop configuration, +to allow the user to configure the slave application and hw pointer +alignment at startup + +Signed-off-by: Vanitha Channaiah +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_direct.c | 1 - + src/pcm/pcm_dmix.c | 2 ++ + src/pcm/pcm_dshare.c | 2 ++ + src/pcm/pcm_dsnoop.c | 30 +++++++++++++++++++++++++++++- + 4 files changed, 33 insertions(+), 2 deletions(-) + +diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c +index 411a035b32ed..54d99005461b 100644 +--- a/src/pcm/pcm_direct.c ++++ b/src/pcm/pcm_direct.c +@@ -2043,7 +2043,6 @@ int snd_pcm_direct_parse_open_conf(snd_config_t *root, snd_config_t *conf, + + void snd_pcm_direct_reset_slave_ptr(snd_pcm_t *pcm, snd_pcm_direct_t *dmix) + { +- dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; + + if (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_ROUNDUP || + (dmix->hw_ptr_alignment == SND_PCM_HW_PTR_ALIGNMENT_AUTO && +diff --git a/src/pcm/pcm_dmix.c b/src/pcm/pcm_dmix.c +index dcde40d9976e..274726e47a7d 100644 +--- a/src/pcm/pcm_dmix.c ++++ b/src/pcm/pcm_dmix.c +@@ -562,6 +562,7 @@ static int snd_pcm_dmix_reset(snd_pcm_t *pcm) + snd_pcm_direct_t *dmix = pcm->private_data; + dmix->hw_ptr %= pcm->period_size; + dmix->appl_ptr = dmix->last_appl_ptr = dmix->hw_ptr; ++ dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; + snd_pcm_direct_reset_slave_ptr(pcm, dmix); + return 0; + } +@@ -571,6 +572,7 @@ static int snd_pcm_dmix_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dmix) + int err; + + snd_pcm_hwsync(dmix->spcm); ++ dmix->slave_appl_ptr = dmix->slave_hw_ptr = *dmix->spcm->hw.ptr; + snd_pcm_direct_reset_slave_ptr(pcm, dmix); + err = snd_timer_start(dmix->timer); + if (err < 0) +diff --git a/src/pcm/pcm_dshare.c b/src/pcm/pcm_dshare.c +index cf8a8631dd5e..b75809c8aa06 100644 +--- a/src/pcm/pcm_dshare.c ++++ b/src/pcm/pcm_dshare.c +@@ -333,6 +333,7 @@ static int snd_pcm_dshare_reset(snd_pcm_t *pcm) + snd_pcm_direct_t *dshare = pcm->private_data; + dshare->hw_ptr %= pcm->period_size; + dshare->appl_ptr = dshare->last_appl_ptr = dshare->hw_ptr; ++ dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr; + snd_pcm_direct_reset_slave_ptr(pcm, dshare); + return 0; + } +@@ -342,6 +343,7 @@ static int snd_pcm_dshare_start_timer(snd_pcm_t *pcm, snd_pcm_direct_t *dshare) + int err; + + snd_pcm_hwsync(dshare->spcm); ++ dshare->slave_appl_ptr = dshare->slave_hw_ptr = *dshare->spcm->hw.ptr; + snd_pcm_direct_reset_slave_ptr(pcm, dshare); + err = snd_timer_start(dshare->timer); + if (err < 0) +diff --git a/src/pcm/pcm_dsnoop.c b/src/pcm/pcm_dsnoop.c +index d08b6241ac19..58b1e5347836 100644 +--- a/src/pcm/pcm_dsnoop.c ++++ b/src/pcm/pcm_dsnoop.c +@@ -278,6 +278,7 @@ static int snd_pcm_dsnoop_reset(snd_pcm_t *pcm) + dsnoop->hw_ptr %= pcm->period_size; + dsnoop->appl_ptr = dsnoop->hw_ptr; + dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr; ++ snd_pcm_direct_reset_slave_ptr(pcm, dsnoop); + return 0; + } + +@@ -285,12 +286,13 @@ static int snd_pcm_dsnoop_start(snd_pcm_t *pcm) + { + snd_pcm_direct_t *dsnoop = pcm->private_data; + int err; +- ++ + if (dsnoop->state != SND_PCM_STATE_PREPARED) + return -EBADFD; + snd_pcm_hwsync(dsnoop->spcm); + snoop_timestamp(pcm); + dsnoop->slave_appl_ptr = dsnoop->slave_hw_ptr; ++ snd_pcm_direct_reset_slave_ptr(pcm, dsnoop); + err = snd_timer_start(dsnoop->timer); + if (err < 0) + return err; +@@ -627,6 +629,7 @@ int snd_pcm_dsnoop_open(snd_pcm_t **pcmp, const char *name, + dsnoop->max_periods = opts->max_periods; + dsnoop->var_periodsize = opts->var_periodsize; + dsnoop->sync_ptr = snd_pcm_dsnoop_sync_ptr; ++ dsnoop->hw_ptr_alignment = opts->hw_ptr_alignment; + + retry: + if (first_instance) { +@@ -771,6 +774,12 @@ pcm.name { + ipc_key INT # unique IPC key + ipc_key_add_uid BOOL # add current uid to unique IPC key + ipc_perm INT # IPC permissions (octal, default 0600) ++ hw_ptr_alignment STR # Slave application and hw pointer alignment type ++ # STR can be one of the below strings : ++ # no ++ # roundup ++ # rounddown ++ # auto (default) + slave STR + # or + slave { # Slave definition +@@ -795,6 +804,25 @@ pcm.name { + } + \endcode + ++hw_ptr_alignment specifies slave application and hw ++pointer alignment type. By default hw_ptr_alignment is auto. Below are ++the possible configurations: ++- no: minimal latency with minimal frames dropped at startup. But ++ wakeup of application (return from snd_pcm_wait() or poll()) can ++ take up to 2 * period. ++- roundup: It is guaranteed that all frames will be played at ++ startup. But the latency will increase upto period-1 frames. ++- rounddown: It is guaranteed that a wakeup will happen for each ++ period and frames can be written from application. But on startup ++ upto period-1 frames will be dropped. ++- auto: Selects the best approach depending on the used period and ++ buffer size. ++ If the application buffer size is < 2 * application period, ++ "roundup" will be selected to avoid over runs. If the slave_period ++ is < 10ms we could expect that there are low latency ++ requirements. Therefore "rounddown" will be chosen to avoid long ++ wakeup times. Else "no" will be chosen. ++ + \subsection pcm_plugins_dsnoop_funcref Function reference + +
      +-- +2.16.4 + diff --git a/0004-pcm-file-add-support-for-infile-reading-in-non-inter.patch b/0004-pcm-file-add-support-for-infile-reading-in-non-inter.patch new file mode 100644 index 0000000..2e39575 --- /dev/null +++ b/0004-pcm-file-add-support-for-infile-reading-in-non-inter.patch @@ -0,0 +1,133 @@ +From 5f2e5af61b0b8cfbf310e8b1e08a034d993e432f Mon Sep 17 00:00:00 2001 +From: Adam Miartus +Date: Tue, 21 May 2019 15:32:47 +0200 +Subject: [PATCH 04/25] pcm: file: add support for infile reading in non + interleaved mode + +add helper function to copy input file data to buffer mapped by areas, +in case of an error, do not fill the areas, allowing device read buffer +to be provided to api caller + +previously unused rbuf variable is reused for this purpose + +Signed-off-by: Adam Miartus +Reviewed-by: Timo Wischer +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_file.c | 67 +++++++++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 56 insertions(+), 11 deletions(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 3a19cef9597c..3c682659d5ec 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -77,6 +77,7 @@ typedef struct { + snd_pcm_uframes_t appl_ptr; + snd_pcm_uframes_t file_ptr_bytes; + snd_pcm_uframes_t wbuf_size; ++ snd_pcm_uframes_t rbuf_size; + size_t wbuf_size_bytes; + size_t wbuf_used_bytes; + char *wbuf; +@@ -266,6 +267,39 @@ static int snd_pcm_file_open_output_file(snd_pcm_file_t *file) + return 0; + } + ++/* fill areas with data from input file, return bytes red */ ++static int snd_pcm_file_areas_read_infile(snd_pcm_t *pcm, ++ const snd_pcm_channel_area_t *areas, ++ snd_pcm_uframes_t offset, ++ snd_pcm_uframes_t frames) ++{ ++ snd_pcm_file_t *file = pcm->private_data; ++ snd_pcm_channel_area_t areas_if[pcm->channels]; ++ ssize_t bytes; ++ ++ if (file->ifd < 0) ++ return -EBADF; ++ ++ if (file->rbuf == NULL) ++ return -ENOMEM; ++ ++ if (file->rbuf_size < frames) { ++ SYSERR("requested more frames than pcm buffer"); ++ return -ENOMEM; ++ } ++ ++ bytes = read(file->ifd, file->rbuf, snd_pcm_frames_to_bytes(pcm, frames)); ++ if (bytes < 0) { ++ SYSERR("read from file failed, error: %d", bytes); ++ return bytes; ++ } ++ ++ snd_pcm_areas_from_buf(pcm, areas_if, file->rbuf); ++ snd_pcm_areas_copy(areas, offset, areas_if, 0, pcm->channels, snd_pcm_bytes_to_frames(pcm, bytes), pcm->format); ++ ++ return bytes; ++} ++ + static void setup_wav_header(snd_pcm_t *pcm, struct wav_fmt *fmt) + { + fmt->fmt = TO_LE16(0x01); +@@ -568,19 +602,19 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm + { + snd_pcm_file_t *file = pcm->private_data; + snd_pcm_channel_area_t areas[pcm->channels]; +- snd_pcm_sframes_t n; ++ snd_pcm_sframes_t frames; + +- if (file->ifd >= 0) { +- SNDERR("DEBUG: Noninterleaved read not yet implemented.\n"); +- return 0; /* TODO: Noninterleaved read */ +- } ++ __snd_pcm_lock(pcm); ++ frames = _snd_pcm_readn(file->gen.slave, bufs, size); ++ if (frames <= 0) ++ return frames; + +- n = _snd_pcm_readn(file->gen.slave, bufs, size); +- if (n > 0) { +- snd_pcm_areas_from_bufs(pcm, areas, bufs); +- snd_pcm_file_add_frames(pcm, areas, 0, n); +- } +- return n; ++ snd_pcm_areas_from_bufs(pcm, areas, bufs); ++ snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); ++ snd_pcm_file_add_frames(pcm, areas, 0, frames); ++ ++ __snd_pcm_unlock(pcm); ++ return frames; + } + + static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm, +@@ -609,9 +643,11 @@ static int snd_pcm_file_hw_free(snd_pcm_t *pcm) + free(file->wbuf); + free(file->wbuf_areas); + free(file->final_fname); ++ free(file->rbuf); + file->wbuf = NULL; + file->wbuf_areas = NULL; + file->final_fname = NULL; ++ file->rbuf = NULL; + return snd_pcm_hw_free(file->gen.slave); + } + +@@ -638,6 +674,15 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) + snd_pcm_file_hw_free(pcm); + return -ENOMEM; + } ++ assert(!file->rbuf); ++ file->rbuf_size = slave->buffer_size; ++ file->rbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->rbuf_size); ++ file->rbuf_used_bytes = 0; ++ file->rbuf = malloc(file->rbuf_size_bytes); ++ if (file->rbuf == NULL) { ++ snd_pcm_file_hw_free(pcm); ++ return -ENOMEM; ++ } + file->appl_ptr = file->file_ptr_bytes = 0; + for (channel = 0; channel < slave->channels; ++channel) { + snd_pcm_channel_area_t *a = &file->wbuf_areas[channel]; +-- +2.16.4 + diff --git a/0005-pcm-file-use-snd_pcm_file_areas_read_infile-for-read.patch b/0005-pcm-file-use-snd_pcm_file_areas_read_infile-for-read.patch new file mode 100644 index 0000000..9975cf3 --- /dev/null +++ b/0005-pcm-file-use-snd_pcm_file_areas_read_infile-for-read.patch @@ -0,0 +1,64 @@ +From 349b42f5477c904fa3e10bac2fa2429fad2cbc65 Mon Sep 17 00:00:00 2001 +From: Adam Miartus +Date: Tue, 21 May 2019 15:33:08 +0200 +Subject: [PATCH 05/25] pcm: file: use snd_pcm_file_areas_read_infile for readi + +use previously introduced helper function, this commit unifies behavior +of readi and readn + +corner case behavior of readi is changed by this commit, previously, +in case 0 bytes were red from file (EOF), frames = 0 was returned, +signaling api user as if no data was red from slave, after the patch, +amount of frames red from slave with data red from slave stored in buffer +is returned when EOF is reached + +Signed-off-by: Adam Miartus +Reviewed-by: Timo Wischer +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_file.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 3c682659d5ec..dcaa41d10e35 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -579,22 +579,21 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc + { + snd_pcm_file_t *file = pcm->private_data; + snd_pcm_channel_area_t areas[pcm->channels]; +- snd_pcm_sframes_t n; ++ snd_pcm_sframes_t frames; ++ ++ __snd_pcm_lock(pcm); ++ ++ frames = _snd_pcm_readi(file->gen.slave, buffer, size); ++ if (frames <= 0) ++ return frames; + +- n = _snd_pcm_readi(file->gen.slave, buffer, size); +- if (n <= 0) +- return n; +- if (file->ifd >= 0) { +- __snd_pcm_lock(pcm); +- n = read(file->ifd, buffer, n * pcm->frame_bits / 8); +- __snd_pcm_unlock(pcm); +- if (n < 0) +- return n; +- n = n * 8 / pcm->frame_bits; +- } + snd_pcm_areas_from_buf(pcm, areas, buffer); +- snd_pcm_file_add_frames(pcm, areas, 0, n); +- return n; ++ snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); ++ snd_pcm_file_add_frames(pcm, areas, 0, frames); ++ ++ __snd_pcm_unlock(pcm); ++ ++ return frames; + } + + /* locking */ +-- +2.16.4 + diff --git a/0006-pcm-file-add-missing-unlock-on-early-return.patch b/0006-pcm-file-add-missing-unlock-on-early-return.patch new file mode 100644 index 0000000..85c9d55 --- /dev/null +++ b/0006-pcm-file-add-missing-unlock-on-early-return.patch @@ -0,0 +1,42 @@ +From 33c7ea0865b7f87cef1c3d3e767734c0edd02e84 Mon Sep 17 00:00:00 2001 +From: Adam Miartus +Date: Thu, 23 May 2019 11:44:30 +0200 +Subject: [PATCH 06/25] pcm: file: add missing unlock on early return + +Signed-off-by: Adam Miartus +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index dcaa41d10e35..8e2c70b12ab1 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -584,8 +584,10 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc + __snd_pcm_lock(pcm); + + frames = _snd_pcm_readi(file->gen.slave, buffer, size); +- if (frames <= 0) ++ if (frames <= 0) { ++ __snd_pcm_unlock(pcm); + return frames; ++ } + + snd_pcm_areas_from_buf(pcm, areas, buffer); + snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); +@@ -605,8 +607,10 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm + + __snd_pcm_lock(pcm); + frames = _snd_pcm_readn(file->gen.slave, bufs, size); +- if (frames <= 0) ++ if (frames <= 0) { ++ __snd_pcm_unlock(pcm); + return frames; ++ } + + snd_pcm_areas_from_bufs(pcm, areas, bufs); + snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); +-- +2.16.4 + diff --git a/0007-ucm-Add-UCM-profile-for-CX2072X-codec-on-Baytrail-Ch.patch b/0007-ucm-Add-UCM-profile-for-CX2072X-codec-on-Baytrail-Ch.patch new file mode 100644 index 0000000..d59c69b --- /dev/null +++ b/0007-ucm-Add-UCM-profile-for-CX2072X-codec-on-Baytrail-Ch.patch @@ -0,0 +1,301 @@ +From 108a2f43791fe769fd58726881b12ad908ebd2e0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 18 Apr 2019 20:40:18 +0200 +Subject: [PATCH 07/25] ucm: Add UCM profile for CX2072X codec on + Baytrail/Cherrytrail profiles + +Adding a new Conexant CX2072X codec profile and reusing the existing +BYT/CHT platform snippets. + +Currently tested only on ASUS E200HA laptop. + +Signed-off-by: Takashi Iwai +--- + configure.ac | 2 ++ + src/conf/ucm/Makefile.am | 1 + + src/conf/ucm/bytcht-cx2072x/HiFi.conf | 24 ++++++++++++++++++++++++ + src/conf/ucm/bytcht-cx2072x/Makefile.am | 4 ++++ + src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf | 8 ++++++++ + src/conf/ucm/codecs/Makefile.am | 1 + + src/conf/ucm/codecs/cx2072x/DisableSeq.conf | 7 +++++++ + src/conf/ucm/codecs/cx2072x/EnableSeq.conf | 13 +++++++++++++ + src/conf/ucm/codecs/cx2072x/HeadPhones.conf | 24 ++++++++++++++++++++++++ + src/conf/ucm/codecs/cx2072x/HeadsetMic.conf | 25 +++++++++++++++++++++++++ + src/conf/ucm/codecs/cx2072x/InternalMic.conf | 24 ++++++++++++++++++++++++ + src/conf/ucm/codecs/cx2072x/Makefile.am | 6 ++++++ + src/conf/ucm/codecs/cx2072x/Speaker.conf | 23 +++++++++++++++++++++++ + 13 files changed, 162 insertions(+) + create mode 100644 src/conf/ucm/bytcht-cx2072x/HiFi.conf + create mode 100644 src/conf/ucm/bytcht-cx2072x/Makefile.am + create mode 100644 src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/DisableSeq.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/EnableSeq.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/HeadPhones.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/HeadsetMic.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/InternalMic.conf + create mode 100644 src/conf/ucm/codecs/cx2072x/Makefile.am + create mode 100644 src/conf/ucm/codecs/cx2072x/Speaker.conf + +diff --git a/configure.ac b/configure.ac +index 0fb34de4fb65..2e955760a6c6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -720,6 +720,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/conf/ucm/ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN/Makefile \ + src/conf/ucm/broadwell-rt286/Makefile \ + src/conf/ucm/broxton-rt298/Makefile \ ++ src/conf/ucm/bytcht-cx2072x/Makefile \ + src/conf/ucm/bytcht-es8316/Makefile \ + src/conf/ucm/bytcht-es8316-mono-spk-in1-mic/Makefile \ + src/conf/ucm/bytcht-es8316-mono-spk-in2-mic/Makefile \ +@@ -765,6 +766,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile doc/doxygen.cfg \ + src/conf/ucm/tegraalc5632/Makefile \ + src/conf/ucm/VEYRON-I2S/Makefile \ + src/conf/ucm/codecs/Makefile \ ++ src/conf/ucm/codecs/cx2072x/Makefile \ + src/conf/ucm/codecs/es8316/Makefile \ + src/conf/ucm/codecs/nau8824/Makefile \ + src/conf/ucm/codecs/rt5640/Makefile \ +diff --git a/src/conf/ucm/Makefile.am b/src/conf/ucm/Makefile.am +index e9f88ed683a2..02257048860f 100644 +--- a/src/conf/ucm/Makefile.am ++++ b/src/conf/ucm/Makefile.am +@@ -4,6 +4,7 @@ platforms \ + ASUSTeKCOMPUTERINC.-T100HAN-1.0-T100HAN \ + broadwell-rt286 \ + broxton-rt298 \ ++bytcht-cx2072x \ + bytcht-es8316 \ + bytcht-es8316-mono-spk-in1-mic \ + bytcht-es8316-mono-spk-in2-mic \ +diff --git a/src/conf/ucm/bytcht-cx2072x/HiFi.conf b/src/conf/ucm/bytcht-cx2072x/HiFi.conf +new file mode 100644 +index 000000000000..e9c1f7573d50 +--- /dev/null ++++ b/src/conf/ucm/bytcht-cx2072x/HiFi.conf +@@ -0,0 +1,24 @@ ++SectionVerb { ++ EnableSequence [ ++ cdev "hw:bytchtcx2072x" ++ ++ ++ ] ++ ++ DisableSequence [ ++ cdev "hw:bytchtcx2072x" ++ ++ ++ ] ++ ++ Value { ++ PlaybackPCM "hw:bytchtcx2072x" ++ CapturePCM "hw:bytchtcx2072x" ++ } ++} ++ ++ ++ ++ ++ ++ +diff --git a/src/conf/ucm/bytcht-cx2072x/Makefile.am b/src/conf/ucm/bytcht-cx2072x/Makefile.am +new file mode 100644 +index 000000000000..373b2a77079a +--- /dev/null ++++ b/src/conf/ucm/bytcht-cx2072x/Makefile.am +@@ -0,0 +1,4 @@ ++alsaconfigdir = @ALSA_CONFIG_DIR@ ++ucmdir = $(alsaconfigdir)/ucm/bytcht-cx2072x ++ucm_DATA = bytcht-cx2072x.conf HiFi.conf ++EXTRA_DIST = $(ucm_DATA) +diff --git a/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf b/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf +new file mode 100644 +index 000000000000..fce04456c678 +--- /dev/null ++++ b/src/conf/ucm/bytcht-cx2072x/bytcht-cx2072x.conf +@@ -0,0 +1,8 @@ ++SectionUseCase."HiFi" { ++ File "HiFi.conf" ++ Comment "Play HiFi quality Music" ++} ++ ++SectionDefaults [ ++ cdev "hw:bytchtcx2072x" ++] +diff --git a/src/conf/ucm/codecs/Makefile.am b/src/conf/ucm/codecs/Makefile.am +index f78fd0817f75..5987b9cf89a4 100644 +--- a/src/conf/ucm/codecs/Makefile.am ++++ b/src/conf/ucm/codecs/Makefile.am +@@ -1,4 +1,5 @@ + SUBDIRS=\ ++cx2072x \ + es8316 \ + rt5640 \ + rt5645 \ +diff --git a/src/conf/ucm/codecs/cx2072x/DisableSeq.conf b/src/conf/ucm/codecs/cx2072x/DisableSeq.conf +new file mode 100644 +index 000000000000..1e3d5489da3f +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/DisableSeq.conf +@@ -0,0 +1,7 @@ ++# Output Configuration ++cset "name='I2S DAC1L Switch' off" ++cset "name='I2S DAC1R Switch' off" ++ ++# Input Configuration ++cset "name='I2S ADC1L Switch' off" ++cset "name='I2S ADC1R Switch' off" +diff --git a/src/conf/ucm/codecs/cx2072x/EnableSeq.conf b/src/conf/ucm/codecs/cx2072x/EnableSeq.conf +new file mode 100644 +index 000000000000..fb8e3fe23c4d +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/EnableSeq.conf +@@ -0,0 +1,13 @@ ++# Disable all inputs / outputs ++cset "name='Ext Spk Switch' off" ++cset "name='Headphone Switch' off" ++cset "name='Headset Mic Switch' off" ++cset "name='Int Mic Switch' off" ++ ++# Output Configuration ++cset "name='I2S DAC1L Switch' on" ++cset "name='I2S DAC1R Switch' on" ++ ++# Input Configuration ++cset "name='I2S ADC1L Switch' on" ++cset "name='I2S ADC1R Switch' on" +diff --git a/src/conf/ucm/codecs/cx2072x/HeadPhones.conf b/src/conf/ucm/codecs/cx2072x/HeadPhones.conf +new file mode 100644 +index 000000000000..4e3ff950c130 +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/HeadPhones.conf +@@ -0,0 +1,24 @@ ++SectionDevice."Headphones" { ++ Comment "Headphones" ++ ++ ConflictingDevice [ ++ "Speaker" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Headphone Switch' on" ++ cset "name='PortA Out En Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Headphone Switch' off" ++ cset "name='PortA Out En Switch' off" ++ ] ++ ++ Value { ++ PlaybackChannels "2" ++ JackControl "Headphone Jack" ++ } ++} +diff --git a/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf b/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf +new file mode 100644 +index 000000000000..26b8df160385 +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/HeadsetMic.conf +@@ -0,0 +1,25 @@ ++SectionDevice."HeadsetMic" { ++ Comment "Headset Microphone" ++ ++ ConflictingDevice [ ++ "InternalMic" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Headset Mic Switch' on" ++ cset "name='ADC1 Mux' 'PortD Switch'" ++ cset "name='PortD In En Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Headset Mic Switch' off" ++ cset "name='PortD In En Switch' off" ++ ] ++ ++ Value { ++ CaptureChannels "2" ++ JackControl "Headset Mic Jack" ++ } ++} +diff --git a/src/conf/ucm/codecs/cx2072x/InternalMic.conf b/src/conf/ucm/codecs/cx2072x/InternalMic.conf +new file mode 100644 +index 000000000000..a3e14538fe58 +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/InternalMic.conf +@@ -0,0 +1,24 @@ ++SectionDevice."InternalMic" { ++ Comment "Internal Microphone" ++ ++ ConflictingDevice [ ++ "HeadsetMic" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Int Mic Switch' on" ++ cset "name='ADC1 Mux' 'PortC Switch'" ++ cset "name='PortC In En Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Int Mic Switch' off" ++ cset "name='PortC In En Switch' off" ++ ] ++ ++ Value { ++ CaptureChannels "2" ++ } ++} +diff --git a/src/conf/ucm/codecs/cx2072x/Makefile.am b/src/conf/ucm/codecs/cx2072x/Makefile.am +new file mode 100644 +index 000000000000..2990fd096178 +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/Makefile.am +@@ -0,0 +1,6 @@ ++alsaconfigdir = @ALSA_CONFIG_DIR@ ++ucmdir = $(alsaconfigdir)/ucm/codecs/cx2072x ++ucm_DATA = EnableSeq.conf DisableSeq.conf \ ++ HeadPhones.conf Speaker.conf \ ++ InternalMic.conf HeadsetMic.conf ++EXTRA_DIST = $(ucm_DATA) +diff --git a/src/conf/ucm/codecs/cx2072x/Speaker.conf b/src/conf/ucm/codecs/cx2072x/Speaker.conf +new file mode 100644 +index 000000000000..55e2b2ba33e4 +--- /dev/null ++++ b/src/conf/ucm/codecs/cx2072x/Speaker.conf +@@ -0,0 +1,23 @@ ++SectionDevice."Speaker" { ++ Comment "Speakers" ++ ++ ConflictingDevice [ ++ "Headphones" ++ ] ++ ++ EnableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Ext Spk Switch' on" ++ cset "name='PortG Out En Switch' on" ++ ] ++ ++ DisableSequence [ ++ cdev "hw:bytchtcx2072x" ++ cset "name='Ext Spk Switch' off" ++ cset "name='PortG Out En Switch' off" ++ ] ++ ++ Value { ++ PlaybackChannels "2" ++ } ++} +-- +2.16.4 + diff --git a/0008-pcm-add-mmap_begin-callback-to-snd_pcm_fast_ops_t-ap.patch b/0008-pcm-add-mmap_begin-callback-to-snd_pcm_fast_ops_t-ap.patch new file mode 100644 index 0000000..fae51b3 --- /dev/null +++ b/0008-pcm-add-mmap_begin-callback-to-snd_pcm_fast_ops_t-ap.patch @@ -0,0 +1,60 @@ +From e520f454803acfdb9af5cd7224129b37904eef4a Mon Sep 17 00:00:00 2001 +From: Adam Miartus +Date: Thu, 23 May 2019 15:00:39 +0200 +Subject: [PATCH 08/25] pcm: add mmap_begin callback to snd_pcm_fast_ops_t api + +main motivation for adding the callback is to use it to enable operation +on mmaped buffer before user access for pcm_file plugin + +support for MMAP read access with masking by data from input file is not +implemented for pcm_file plugin, by adding this callback implementing +such feature can be done by rewriting next continuous portion of buffer +on each mmap_begin call + +plugins like softvol use pcm_plugin interface and overwrite the buffer by +looping around it in avail_update callback, this patch hopes to simplify +the task by adding new api callback, removing the need for rewriting +pcm_file (to use pcm_plugin callbacks) and careful checking when looping +around whole mmaped buffer + +Signed-off-by: Adam Miartus +Reviewed-by: Timo Wischer +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm.c | 6 ++++++ + src/pcm/pcm_local.h | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c +index 3a71d79b278e..323926e1fc25 100644 +--- a/src/pcm/pcm.c ++++ b/src/pcm/pcm.c +@@ -7129,7 +7129,13 @@ int __snd_pcm_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, + snd_pcm_uframes_t f; + snd_pcm_uframes_t avail; + const snd_pcm_channel_area_t *xareas; ++ + assert(pcm && areas && offset && frames); ++ ++ if (pcm->fast_ops->mmap_begin) ++ return pcm->fast_ops->mmap_begin(pcm->fast_op_arg, areas, offset, frames); ++ ++ /* fallback for plugins that do not specify new callback */ + xareas = snd_pcm_mmap_areas(pcm); + if (xareas == NULL) + return -EBADFD; +diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h +index d52229d8ddea..d5726eb29242 100644 +--- a/src/pcm/pcm_local.h ++++ b/src/pcm/pcm_local.h +@@ -184,6 +184,7 @@ typedef struct { + int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space); /* locked */ + int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents); /* locked */ + int (*may_wait_for_avail_min)(snd_pcm_t *pcm, snd_pcm_uframes_t avail); ++ int (*mmap_begin)(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames); /* locked */ + } snd_pcm_fast_ops_t; + + struct _snd_pcm { +-- +2.16.4 + diff --git a/0009-pcm-file-add-infile-read-support-for-mmap-mode.patch b/0009-pcm-file-add-infile-read-support-for-mmap-mode.patch new file mode 100644 index 0000000..09edd1f --- /dev/null +++ b/0009-pcm-file-add-infile-read-support-for-mmap-mode.patch @@ -0,0 +1,93 @@ +From fe7ff721a954c3f8c2183febc7c3fa5736357b67 Mon Sep 17 00:00:00 2001 +From: Adam Miartus +Date: Thu, 23 May 2019 15:00:40 +0200 +Subject: [PATCH 09/25] pcm: file: add infile read support for mmap mode + +mmap_begin callback is used to copy data from input file to mmaped +buffer + +guard for corner use of api (multiple mmap_begin calls by user) is +introduced to check if next continuous buffer was already overwritten + +buffer is overwritten with input file data only in case of stream capture + +Signed-off-by: Adam Miartus +Reviewed-by: Timo Wischer +Signed-off-by: Takashi Iwai +--- + src/pcm/pcm_file.c | 31 +++++++++++++++++++++++++++++++ + 1 file changed, 31 insertions(+) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 8e2c70b12ab1..52cc10a9436a 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -88,6 +88,7 @@ typedef struct { + size_t buffer_bytes; + struct wav_fmt wav_header; + size_t filelen; ++ char ifmmap_overwritten; + } snd_pcm_file_t; + + #if __BYTE_ORDER == __LITTLE_ENDIAN +@@ -630,6 +631,8 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm, + const snd_pcm_channel_area_t *areas; + snd_pcm_sframes_t result; + ++ file->ifmmap_overwritten = 0; ++ + result = snd_pcm_mmap_begin(file->gen.slave, &areas, &ofs, &siz); + if (result >= 0) { + assert(ofs == offset && siz == size); +@@ -640,6 +643,32 @@ static snd_pcm_sframes_t snd_pcm_file_mmap_commit(snd_pcm_t *pcm, + return result; + } + ++static int snd_pcm_file_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, ++ snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) ++{ ++ snd_pcm_file_t *file = pcm->private_data; ++ snd_pcm_channel_area_t areas_if[pcm->channels]; ++ snd_pcm_uframes_t frames_if; ++ void *buffer = NULL; ++ int result; ++ ++ result = snd_pcm_mmap_begin(file->gen.slave, areas, offset, frames); ++ if (result < 0) ++ return result; ++ ++ if (pcm->stream != SND_PCM_STREAM_CAPTURE) ++ return result; ++ ++ /* user may run mmap_begin without mmap_commit multiple times in row */ ++ if (file->ifmmap_overwritten) ++ return result; ++ file->ifmmap_overwritten = 1; ++ ++ snd_pcm_file_areas_read_infile(pcm, *areas, *offset, *frames); ++ ++ return result; ++} ++ + static int snd_pcm_file_hw_free(snd_pcm_t *pcm) + { + snd_pcm_file_t *file = pcm->private_data; +@@ -666,6 +695,7 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params) + file->wbuf_size = slave->buffer_size * 2; + file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size); + file->wbuf_used_bytes = 0; ++ file->ifmmap_overwritten = 0; + assert(!file->wbuf); + file->wbuf = malloc(file->wbuf_size_bytes); + if (file->wbuf == NULL) { +@@ -777,6 +807,7 @@ static const snd_pcm_fast_ops_t snd_pcm_file_fast_ops = { + .poll_descriptors = snd_pcm_generic_poll_descriptors, + .poll_revents = snd_pcm_generic_poll_revents, + .htimestamp = snd_pcm_generic_htimestamp, ++ .mmap_begin = snd_pcm_file_mmap_begin, + }; + + /** +-- +2.16.4 + diff --git a/0010-aserver-fix-resource-leak-coverity.patch b/0010-aserver-fix-resource-leak-coverity.patch new file mode 100644 index 0000000..e182782 --- /dev/null +++ b/0010-aserver-fix-resource-leak-coverity.patch @@ -0,0 +1,105 @@ +From 47bc6d534102aca9cc2aed1b6bdd5633ef645a3f Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:27:25 +0200 +Subject: [PATCH 10/25] aserver: fix resource leak coverity + +Signed-off-by: Jaroslav Kysela +--- + aserver/aserver.c | 33 +++++++++++++++++++-------------- + 1 file changed, 19 insertions(+), 14 deletions(-) + +diff --git a/aserver/aserver.c b/aserver/aserver.c +index 066414d8624c..6d20f3301ae0 100644 +--- a/aserver/aserver.c ++++ b/aserver/aserver.c +@@ -75,6 +75,7 @@ static int make_local_socket(const char *filename) + if (bind(sock, (struct sockaddr *) addr, size) < 0) { + int result = -errno; + SYSERROR("bind failed"); ++ close(sock); + return result; + } + +@@ -101,6 +102,7 @@ static int make_inet_socket(int port) + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + int result = -errno; + SYSERROR("bind failed"); ++ close(sock); + return result; + } + +@@ -916,10 +918,9 @@ static int inet_handler(waiter_t *waiter, unsigned short events ATTRIBUTE_UNUSED + + static int server(const char *sockname, int port) + { +- int err; ++ int err, result, sockn = -1, socki = -1; + unsigned int k; + long open_max; +- int result; + + if (!sockname && port < 0) + return -EINVAL; +@@ -933,36 +934,36 @@ static int server(const char *sockname, int port) + waiters = calloc((size_t) open_max, sizeof(*waiters)); + + if (sockname) { +- int sock = make_local_socket(sockname); +- if (sock < 0) +- return sock; +- if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { ++ sockn = make_local_socket(sockname); ++ if (sockn < 0) ++ return sockn; ++ if (fcntl(sockn, F_SETFL, O_NONBLOCK) < 0) { + result = -errno; + SYSERROR("fcntl O_NONBLOCK failed"); + goto _end; + } +- if (listen(sock, 4) < 0) { ++ if (listen(sockn, 4) < 0) { + result = -errno; + SYSERROR("listen failed"); + goto _end; + } +- add_waiter(sock, POLLIN, local_handler, NULL); ++ add_waiter(sockn, POLLIN, local_handler, NULL); + } + if (port >= 0) { +- int sock = make_inet_socket(port); +- if (sock < 0) +- return sock; +- if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) { ++ socki = make_inet_socket(port); ++ if (socki < 0) ++ return socki; ++ if (fcntl(socki, F_SETFL, O_NONBLOCK) < 0) { + result = -errno; + SYSERROR("fcntl failed"); + goto _end; + } +- if (listen(sock, 4) < 0) { ++ if (listen(socki, 4) < 0) { + result = -errno; + SYSERROR("listen failed"); + goto _end; + } +- add_waiter(sock, POLLIN, inet_handler, NULL); ++ add_waiter(socki, POLLIN, inet_handler, NULL); + } + + while (1) { +@@ -991,6 +992,10 @@ static int server(const char *sockname, int port) + } + } + _end: ++ if (sockn >= 0) ++ close(sockn); ++ if (socki >= 0) ++ close(socki); + free(pollfds); + free(waiters); + return result; +-- +2.16.4 + diff --git a/0011-src-conf.c-add-missing-va_end-call-coverity.patch b/0011-src-conf.c-add-missing-va_end-call-coverity.patch new file mode 100644 index 0000000..67e6f80 --- /dev/null +++ b/0011-src-conf.c-add-missing-va_end-call-coverity.patch @@ -0,0 +1,41 @@ +From 4aa960c48b4d292425597d283f3ef15d02590082 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:39:05 +0200 +Subject: [PATCH 11/25] src/conf.c: add missing va_end() call (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/conf.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/conf.c b/src/conf.c +index cda5518e673b..3a3c91bf4284 100644 +--- a/src/conf.c ++++ b/src/conf.c +@@ -3034,8 +3034,10 @@ int snd_config_save(snd_config_t *config, snd_output_t *out) + if (!k) \ + break; \ + err = fcn(config, k, &n); \ +- if (err < 0) \ ++ if (err < 0) { \ ++ va_end(arg); \ + return err; \ ++ } \ + config = n; \ + } \ + va_end(arg); \ +@@ -3056,8 +3058,10 @@ int snd_config_save(snd_config_t *config, snd_output_t *out) + if (!k) \ + break; \ + err = fcn(root, config, k, &n); \ +- if (err < 0) \ ++ if (err < 0) { \ ++ va_end(arg); \ + return err; \ ++ } \ + config = n; \ + } \ + va_end(arg); \ +-- +2.16.4 + diff --git a/0012-config-parse_string-fix-the-dynamic-buffer-allocatio.patch b/0012-config-parse_string-fix-the-dynamic-buffer-allocatio.patch new file mode 100644 index 0000000..93f2c10 --- /dev/null +++ b/0012-config-parse_string-fix-the-dynamic-buffer-allocatio.patch @@ -0,0 +1,52 @@ +From 990b1a53ed800caac0bab1c2b7987205569861fe Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:44:49 +0200 +Subject: [PATCH 12/25] config: parse_string() fix the dynamic buffer + allocation failure code (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/conf.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/src/conf.c b/src/conf.c +index 3a3c91bf4284..3e4b76a34ecf 100644 +--- a/src/conf.c ++++ b/src/conf.c +@@ -4747,8 +4747,11 @@ static int parse_string(const char **ptr, char **val) + return -EINVAL; + case '\\': + c = parse_char(ptr); +- if (c < 0) ++ if (c < 0) { ++ if (alloc > bufsize) ++ free(buf); + return c; ++ } + break; + default: + (*ptr)++; +@@ -4768,12 +4771,17 @@ static int parse_string(const char **ptr, char **val) + alloc *= 2; + if (old_alloc == bufsize) { + buf = malloc(alloc); ++ if (!buf) ++ return -ENOMEM; + memcpy(buf, _buf, old_alloc); + } else { +- buf = realloc(buf, alloc); ++ char *buf2 = realloc(buf, alloc); ++ if (!buf2) { ++ free(buf); ++ return -ENOMEM; ++ } ++ buf = buf2; + } +- if (!buf) +- return -ENOMEM; + } + buf[idx++] = c; + } +-- +2.16.4 + diff --git a/0013-control_shm-remove-duplicate-code-coverity.patch b/0013-control_shm-remove-duplicate-code-coverity.patch new file mode 100644 index 0000000..28f35cf --- /dev/null +++ b/0013-control_shm-remove-duplicate-code-coverity.patch @@ -0,0 +1,61 @@ +From 51881cacc05e7d5e3cc8fc1ec9a4ac93a6327703 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:51:47 +0200 +Subject: [PATCH 13/25] control_shm: remove duplicate code (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/control/control_shm.c | 18 +++--------------- + 1 file changed, 3 insertions(+), 15 deletions(-) + +diff --git a/src/control/control_shm.c b/src/control/control_shm.c +index d7b4139831d0..1d9de8b75860 100644 +--- a/src/control/control_shm.c ++++ b/src/control/control_shm.c +@@ -302,13 +302,9 @@ static int snd_ctl_shm_pcm_prefer_subdevice(snd_ctl_t *ctl, int subdev) + { + snd_ctl_shm_t *shm = ctl->private_data; + volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl; +- int err; + ctrl->u.pcm_prefer_subdevice = subdev; + ctrl->cmd = SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE; +- err = snd_ctl_shm_action(ctl); +- if (err < 0) +- return err; +- return err; ++ return snd_ctl_shm_action(ctl); + } + + static int snd_ctl_shm_rawmidi_next_device(snd_ctl_t *ctl, int * device) +@@ -343,26 +339,18 @@ static int snd_ctl_shm_rawmidi_prefer_subdevice(snd_ctl_t *ctl, int subdev) + { + snd_ctl_shm_t *shm = ctl->private_data; + volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl; +- int err; + ctrl->u.rawmidi_prefer_subdevice = subdev; + ctrl->cmd = SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE; +- err = snd_ctl_shm_action(ctl); +- if (err < 0) +- return err; +- return err; ++ return snd_ctl_shm_action(ctl); + } + + static int snd_ctl_shm_set_power_state(snd_ctl_t *ctl, unsigned int state) + { + snd_ctl_shm_t *shm = ctl->private_data; + volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl; +- int err; + ctrl->u.power_state = state; + ctrl->cmd = SNDRV_CTL_IOCTL_POWER; +- err = snd_ctl_shm_action(ctl); +- if (err < 0) +- return err; +- return err; ++ return snd_ctl_shm_action(ctl); + } + + static int snd_ctl_shm_get_power_state(snd_ctl_t *ctl, unsigned int *state) +-- +2.16.4 + diff --git a/0014-control_shm-add-missing-socket-close-to-the-error-pa.patch b/0014-control_shm-add-missing-socket-close-to-the-error-pa.patch new file mode 100644 index 0000000..cbc31a0 --- /dev/null +++ b/0014-control_shm-add-missing-socket-close-to-the-error-pa.patch @@ -0,0 +1,30 @@ +From d6ba264038fde08baf5e62bdde2a5614792db5c8 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:53:09 +0200 +Subject: [PATCH 14/25] control_shm: add missing socket close to the error path + (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/control/control_shm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/control/control_shm.c b/src/control/control_shm.c +index 1d9de8b75860..40d4264342fc 100644 +--- a/src/control/control_shm.c ++++ b/src/control/control_shm.c +@@ -424,8 +424,10 @@ static int make_local_socket(const char *filename) + addr->sun_family = AF_LOCAL; + memcpy(addr->sun_path, filename, l); + +- if (connect(sock, (struct sockaddr *) addr, size) < 0) ++ if (connect(sock, (struct sockaddr *) addr, size) < 0) { ++ close(sock); + return -errno; ++ } + return sock; + } + +-- +2.16.4 + diff --git a/0015-pcm-fix-memory-leak-in-_snd_pcm_parse_config_chmaps-.patch b/0015-pcm-fix-memory-leak-in-_snd_pcm_parse_config_chmaps-.patch new file mode 100644 index 0000000..f2367ed --- /dev/null +++ b/0015-pcm-fix-memory-leak-in-_snd_pcm_parse_config_chmaps-.patch @@ -0,0 +1,26 @@ +From d5a1cf35b710d255508e56ed19633e1fbf41a2d4 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 10:57:20 +0200 +Subject: [PATCH 15/25] pcm: fix memory leak in _snd_pcm_parse_config_chmaps() + (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c +index 323926e1fc25..fa51ca9987a8 100644 +--- a/src/pcm/pcm.c ++++ b/src/pcm/pcm.c +@@ -8391,6 +8391,7 @@ _snd_pcm_parse_config_chmaps(snd_config_t *conf) + free(chmap); + goto error; + } ++ free(chmap); + nums++; + } + return maps; +-- +2.16.4 + diff --git a/0016-pcm_file-call-pclose-correctly-for-popen-coverity.patch b/0016-pcm_file-call-pclose-correctly-for-popen-coverity.patch new file mode 100644 index 0000000..6d1d638 --- /dev/null +++ b/0016-pcm_file-call-pclose-correctly-for-popen-coverity.patch @@ -0,0 +1,34 @@ +From 22ade9b8c150240a960ca683ee6d8f53ce8bc6ea Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 11:09:43 +0200 +Subject: [PATCH 16/25] pcm_file: call pclose() correctly for popen() + (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_file.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 52cc10a9436a..99db3754fa32 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -227,7 +227,14 @@ static int snd_pcm_file_open_output_file(snd_pcm_file_t *file) + file->final_fname); + return -errno; + } +- fd = fileno(pipe); ++ fd = dup(fileno(pipe)); ++ err = -errno; ++ pclose(pipe); ++ if (fd < 0) { ++ SYSERR("unable to dup pipe file handle for command %s", ++ file->final_fname); ++ return err; ++ } + } else { + if (file->trunc) + fd = open(file->final_fname, O_WRONLY|O_CREAT|O_TRUNC, +-- +2.16.4 + diff --git a/0017-pcm_hw-close-file-descriptor-in-the-error-path-in-sn.patch b/0017-pcm_hw-close-file-descriptor-in-the-error-path-in-sn.patch new file mode 100644 index 0000000..4c04eb4 --- /dev/null +++ b/0017-pcm_hw-close-file-descriptor-in-the-error-path-in-sn.patch @@ -0,0 +1,34 @@ +From 3ae743efea704c16c9464f38d502c23759b71245 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 11:11:46 +0200 +Subject: [PATCH 17/25] pcm_hw: close file descriptor in the error path in + snd_pcm_hw_open() (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_hw.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c +index 91370a88c0fd..77d4dae1b20b 100644 +--- a/src/pcm/pcm_hw.c ++++ b/src/pcm/pcm_hw.c +@@ -1724,12 +1724,15 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, + } + if (info.subdevice != (unsigned int) subdevice) { + close(fd); ++ fd = -1; + goto __again; + } + } + snd_ctl_close(ctl); + return snd_pcm_hw_open_fd(pcmp, name, fd, sync_ptr_ioctl); + _err: ++ if (fd >= 0) ++ close(fd); + snd_ctl_close(ctl); + return ret; + } +-- +2.16.4 + diff --git a/0018-rawmidi-use-snd_dlobj_cache_get2-in-rawmidi-open-cov.patch b/0018-rawmidi-use-snd_dlobj_cache_get2-in-rawmidi-open-cov.patch new file mode 100644 index 0000000..ed044c2 --- /dev/null +++ b/0018-rawmidi-use-snd_dlobj_cache_get2-in-rawmidi-open-cov.patch @@ -0,0 +1,222 @@ +From 8ab0393b42e08655a5fee0a8e84b3ba84932465b Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 20:31:24 +0200 +Subject: [PATCH 18/25] rawmidi: use snd_dlobj_cache_get2() in rawmidi open + (coverity) + +Use proper reference counting for the dynamic symbol. + +Signed-off-by: Jaroslav Kysela +--- + include/local.h | 3 +++ + src/dlmisc.c | 41 ++++++++++++++++++++++++++++++++++------- + src/rawmidi/rawmidi.c | 43 +++++++++++++++++++------------------------ + src/rawmidi/rawmidi_local.h | 2 +- + 4 files changed, 57 insertions(+), 32 deletions(-) + +diff --git a/include/local.h b/include/local.h +index 5edad317e955..e8390df59994 100644 +--- a/include/local.h ++++ b/include/local.h +@@ -328,6 +328,8 @@ static inline int snd_open_device(const char *filename, int fmode) + /* make local functions really local */ + #define snd_dlobj_cache_get \ + snd1_dlobj_cache_get ++#define snd_dlobj_cache_get2 \ ++ snd1_dlobj_cache_get2 + #define snd_dlobj_cache_put \ + snd1_dlobj_cache_put + #define snd_dlobj_cache_cleanup \ +@@ -341,6 +343,7 @@ static inline int snd_open_device(const char *filename, int fmode) + + /* dlobj cache */ + void *snd_dlobj_cache_get(const char *lib, const char *name, const char *version, int verbose); ++void *snd_dlobj_cache_get2(const char *lib, const char *name, const char *version, int verbose); + int snd_dlobj_cache_put(void *open_func); + void snd_dlobj_cache_cleanup(void); + +diff --git a/src/dlmisc.c b/src/dlmisc.c +index 012e61bc00c0..8c8f3ff72fd3 100644 +--- a/src/dlmisc.c ++++ b/src/dlmisc.c +@@ -251,15 +251,15 @@ static inline void snd_dlobj_unlock(void) {} + + static LIST_HEAD(pcm_dlobj_list); + +-void *snd_dlobj_cache_get(const char *lib, const char *name, +- const char *version, int verbose) ++static struct dlobj_cache * ++snd_dlobj_cache_get0(const char *lib, const char *name, ++ const char *version, int verbose) + { + struct list_head *p; + struct dlobj_cache *c; + void *func, *dlobj; + char errbuf[256]; + +- snd_dlobj_lock(); + list_for_each(p, &pcm_dlobj_list) { + c = list_entry(p, struct dlobj_cache, list); + if (c->lib && lib && strcmp(c->lib, lib) != 0) +@@ -270,9 +270,7 @@ void *snd_dlobj_cache_get(const char *lib, const char *name, + continue; + if (strcmp(c->name, name) == 0) { + c->refcnt++; +- func = c->func; +- snd_dlobj_unlock(); +- return func; ++ return c; + } + } + +@@ -285,7 +283,6 @@ void *snd_dlobj_cache_get(const char *lib, const char *name, + SNDERR("Cannot open shared library %s (%s)", + lib ? lib : "[builtin]", + errbuf); +- snd_dlobj_unlock(); + return NULL; + } + +@@ -314,6 +311,36 @@ void *snd_dlobj_cache_get(const char *lib, const char *name, + c->dlobj = dlobj; + c->func = func; + list_add_tail(&c->list, &pcm_dlobj_list); ++ return c; ++} ++ ++void *snd_dlobj_cache_get(const char *lib, const char *name, ++ const char *version, int verbose) ++{ ++ struct dlobj_cache *c; ++ void *func = NULL; ++ ++ snd_dlobj_lock(); ++ c = snd_dlobj_cache_get0(lib, name, version, verbose); ++ if (c) ++ func = c->func; ++ snd_dlobj_unlock(); ++ return func; ++} ++ ++void *snd_dlobj_cache_get2(const char *lib, const char *name, ++ const char *version, int verbose) ++{ ++ struct dlobj_cache *c; ++ void *func = NULL; ++ ++ snd_dlobj_lock(); ++ c = snd_dlobj_cache_get0(lib, name, version, verbose); ++ if (c) { ++ func = c->func; ++ /* double reference */ ++ c->refcnt++; ++ } + snd_dlobj_unlock(); + return func; + } +diff --git a/src/rawmidi/rawmidi.c b/src/rawmidi/rawmidi.c +index 2f419142b9b5..1b5f8525e59e 100644 +--- a/src/rawmidi/rawmidi.c ++++ b/src/rawmidi/rawmidi.c +@@ -162,7 +162,7 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp + snd_config_t *rawmidi_conf, int mode) + { + const char *str; +- char buf[256], errbuf[256]; ++ char buf[256]; + int err; + snd_config_t *conf, *type_conf = NULL; + snd_config_iterator_t i, next; +@@ -174,7 +174,6 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp + #ifndef PIC + extern void *snd_rawmidi_open_symbols(void); + #endif +- void *h = NULL; + if (snd_config_get_type(rawmidi_conf) != SND_CONFIG_TYPE_COMPOUND) { + if (name) + SNDERR("Invalid type for RAWMIDI %s definition", name); +@@ -239,41 +238,37 @@ static int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp + #ifndef PIC + snd_rawmidi_open_symbols(); + #endif +- h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf)); +- if (h) +- open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION)); +- err = 0; +- if (!h) { +- SNDERR("Cannot open shared library %s (%s)", lib, errbuf); +- err = -ENOENT; +- } else if (!open_func) { +- SNDERR("symbol %s is not defined inside %s", open_name, lib); +- snd_dlclose(h); ++ open_func = snd_dlobj_cache_get2(lib, open_name, ++ SND_DLSYM_VERSION(SND_RAWMIDI_DLSYM_VERSION), 1); ++ if (!open_func) { + err = -ENXIO; ++ goto _err; + } +- _err: + if (type_conf) + snd_config_delete(type_conf); +- if (err >= 0) +- err = open_func(inputp, outputp, name, rawmidi_root, rawmidi_conf, mode); +- if (err < 0) { +- if (h) +- snd_dlclose(h); +- return err; +- } ++ err = open_func(inputp, outputp, name, rawmidi_root, rawmidi_conf, mode); ++ if (err < 0) ++ goto _err; + if (inputp) { +- (*inputp)->dl_handle = h; h = NULL; ++ (*inputp)->open_func = open_func; + snd_rawmidi_params_default(*inputp, ¶ms); + err = snd_rawmidi_params(*inputp, ¶ms); + assert(err >= 0); + } + if (outputp) { +- (*outputp)->dl_handle = h; ++ (*outputp)->open_func = open_func; + snd_rawmidi_params_default(*outputp, ¶ms); + err = snd_rawmidi_params(*outputp, ¶ms); + assert(err >= 0); + } + return 0; ++ ++ _err: ++ if (open_func) ++ snd_dlobj_cache_put(open_func); ++ if (type_conf) ++ snd_config_delete(type_conf); ++ return err; + } + + static int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, +@@ -350,8 +345,8 @@ int snd_rawmidi_close(snd_rawmidi_t *rawmidi) + assert(rawmidi); + err = rawmidi->ops->close(rawmidi); + free(rawmidi->name); +- if (rawmidi->dl_handle) +- snd_dlclose(rawmidi->dl_handle); ++ if (rawmidi->open_func) ++ snd_dlobj_cache_put(rawmidi->open_func); + free(rawmidi); + return err; + } +diff --git a/src/rawmidi/rawmidi_local.h b/src/rawmidi/rawmidi_local.h +index d76b35a33bf4..721e1ec9deec 100644 +--- a/src/rawmidi/rawmidi_local.h ++++ b/src/rawmidi/rawmidi_local.h +@@ -37,7 +37,7 @@ typedef struct { + } snd_rawmidi_ops_t; + + struct _snd_rawmidi { +- void *dl_handle; ++ void *open_func; + char *name; + snd_rawmidi_type_t type; + snd_rawmidi_stream_t stream; +-- +2.16.4 + diff --git a/0019-rawmidi_hw-add-sanity-check-for-the-invalid-stream-a.patch b/0019-rawmidi_hw-add-sanity-check-for-the-invalid-stream-a.patch new file mode 100644 index 0000000..4ef5d28 --- /dev/null +++ b/0019-rawmidi_hw-add-sanity-check-for-the-invalid-stream-a.patch @@ -0,0 +1,27 @@ +From 6efa23f2837a6fa9982b4f34b837401a66941ee3 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 20:45:26 +0200 +Subject: [PATCH 19/25] rawmidi_hw: add sanity check for the invalid stream + arguments (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/rawmidi/rawmidi_hw.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/rawmidi/rawmidi_hw.c b/src/rawmidi/rawmidi_hw.c +index 7cc8c0d1e7ec..eaa8a76de52f 100644 +--- a/src/rawmidi/rawmidi_hw.c ++++ b/src/rawmidi/rawmidi_hw.c +@@ -186,6 +186,8 @@ int snd_rawmidi_hw_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, + *inputp = NULL; + if (outputp) + *outputp = NULL; ++ if (!inputp && !outputp) ++ return -EINVAL; + + if ((ret = snd_ctl_hw_open(&ctl, NULL, card, 0)) < 0) + return ret; +-- +2.16.4 + diff --git a/0020-topology-various-coverity-fixes.patch b/0020-topology-various-coverity-fixes.patch new file mode 100644 index 0000000..18abc8d --- /dev/null +++ b/0020-topology-various-coverity-fixes.patch @@ -0,0 +1,103 @@ +From 0d97f53c25b4dd36d3f6511fae85b597aebc61a1 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 20:52:00 +0200 +Subject: [PATCH 20/25] topology: various coverity fixes + +Signed-off-by: Jaroslav Kysela +--- + src/topology/ctl.c | 4 ++-- + src/topology/data.c | 19 +++++++++++++------ + src/topology/parser.c | 5 +++-- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/src/topology/ctl.c b/src/topology/ctl.c +index 9c13b12c4bf4..a096252263a5 100644 +--- a/src/topology/ctl.c ++++ b/src/topology/ctl.c +@@ -880,8 +880,8 @@ int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl, + if (enum_ctl->texts != NULL) { + for (i = 0; i < num_items; i++) { + if (enum_ctl->texts[i] != NULL) +- strncpy(ec->texts[i], enum_ctl->texts[i], +- SNDRV_CTL_ELEM_ID_NAME_MAXLEN); ++ snd_strlcpy(ec->texts[i], enum_ctl->texts[i], ++ SNDRV_CTL_ELEM_ID_NAME_MAXLEN); + } + } + +diff --git a/src/topology/data.c b/src/topology/data.c +index fd72abbb5e08..aa2b87e73f50 100644 +--- a/src/topology/data.c ++++ b/src/topology/data.c +@@ -124,12 +124,12 @@ static int tplg_parse_data_file(snd_config_t *cfg, struct tplg_elem *elem) + + if (fclose(fp) == EOF) { + SNDERR("Cannot close data file."); +- ret = -errno; +- goto err; ++ return -errno; + } + return 0; + + err: ++ fclose(fp); + if (priv) + free(priv); + return ret; +@@ -422,7 +422,7 @@ static unsigned int get_tuple_size(int type) + static int copy_tuples(struct tplg_elem *elem, + struct tplg_vendor_tuples *tuples, struct tplg_vendor_tokens *tokens) + { +- struct snd_soc_tplg_private *priv = elem->data; ++ struct snd_soc_tplg_private *priv = elem->data, *priv2; + struct tplg_tuple_set *tuple_set; + struct tplg_tuple *tuple; + struct snd_soc_tplg_vendor_array *array; +@@ -447,10 +447,17 @@ static int copy_tuples(struct tplg_elem *elem, + return -EINVAL; + } + +- if (priv != NULL) +- priv = realloc(priv, sizeof(*priv) + size); +- else ++ if (priv != NULL) { ++ priv2 = realloc(priv, sizeof(*priv) + size); ++ if (priv2 == NULL) { ++ free(priv); ++ priv = NULL; ++ } else { ++ priv = priv2; ++ } ++ } else { + priv = calloc(1, sizeof(*priv) + size); ++ } + if (!priv) + return -ENOMEM; + +diff --git a/src/topology/parser.c b/src/topology/parser.c +index cfc20e000e5c..a7cff1c30edc 100644 +--- a/src/topology/parser.c ++++ b/src/topology/parser.c +@@ -237,8 +237,9 @@ static int tplg_load_config(const char *file, snd_config_t **cfg) + + ret = snd_input_stdio_attach(&in, fp, 1); + if (ret < 0) { ++ fclose(fp); + SNDERR("error: could not attach stdio %s", file); +- goto err; ++ return ret; + } + ret = snd_config_top(&top); + if (ret < 0) +@@ -261,7 +262,7 @@ static int tplg_load_config(const char *file, snd_config_t **cfg) + err_load: + snd_config_delete(top); + err: +- fclose(fp); ++ snd_input_close(in); + return ret; + } + +-- +2.16.4 + diff --git a/0021-ucm-coverity-fixes.patch b/0021-ucm-coverity-fixes.patch new file mode 100644 index 0000000..3c4cb7d --- /dev/null +++ b/0021-ucm-coverity-fixes.patch @@ -0,0 +1,118 @@ +From ed156a218644e3334bc452ef2bc948409735c330 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 24 May 2019 21:11:00 +0200 +Subject: [PATCH 21/25] ucm: coverity fixes + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 18 ++++++++++++++---- + src/ucm/utils.c | 12 +++++++++--- + 2 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index ad6bcec78622..61d5d7f9c47c 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1114,7 +1114,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + if (err < 0) { + uc_error("error: %s failed to parse verb", + file); +- return err; ++ goto _err; + } + continue; + } +@@ -1126,7 +1126,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + if (err < 0) { + uc_error("error: %s failed to parse device", + file); +- return err; ++ goto _err; + } + continue; + } +@@ -1138,18 +1138,24 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + if (err < 0) { + uc_error("error: %s failed to parse modifier", + file); +- return err; ++ goto _err; + } + continue; + } + } + ++ snd_config_delete(cfg); ++ + /* use case verb must have at least 1 device */ + if (list_empty(&verb->device_list)) { + uc_error("error: no use case device defined", file); + return -EINVAL; + } + return 0; ++ ++ _err: ++ snd_config_delete(cfg); ++ return err; + } + + /* +@@ -1399,6 +1405,7 @@ next_card: + + return -1; + } ++ + static int load_master_config(const char *card_name, snd_config_t **cfg) + { + char filename[MAX_FILE]; +@@ -1610,8 +1617,11 @@ int uc_mgr_scan_master_configs(const char **_list[]) + } + free(namelist); + +- if (err >= 0) ++ if (err >= 0) { + *_list = list; ++ } else { ++ free(list); ++ } + + return err; + } +diff --git a/src/ucm/utils.c b/src/ucm/utils.c +index 14227e0aed5b..efd5a97999b1 100644 +--- a/src/ucm/utils.c ++++ b/src/ucm/utils.c +@@ -58,14 +58,18 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg) + int err; + + fp = fopen(file, "r"); +- err = fp == NULL ? -errno : snd_input_stdio_attach(&in, fp, 1); +- if (err < 0) { ++ if (!fp) { ++ err = -errno; ++ __err0: + uc_error("could not open configuration file %s", file); + return err; + } ++ err = snd_input_stdio_attach(&in, fp, 1); ++ if (err < 0) ++ goto __err0; + err = snd_config_top(&top); + if (err < 0) +- return err; ++ goto __err1; + + default_path = getenv(ALSA_CONFIG_UCM_VAR); + if (!default_path || !*default_path) +@@ -88,6 +92,8 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg) + + __err2: + snd_config_delete(top); ++ __err1: ++ snd_input_close(in); + return err; + } + +-- +2.16.4 + diff --git a/0022-pcm_file-coverity-fixes-including-double-locking.patch b/0022-pcm_file-coverity-fixes-including-double-locking.patch new file mode 100644 index 0000000..b7d32c5 --- /dev/null +++ b/0022-pcm_file-coverity-fixes-including-double-locking.patch @@ -0,0 +1,60 @@ +From 022c790aabc300eabad4da8947a3f2bdadce41e1 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 27 May 2019 13:57:12 +0200 +Subject: [PATCH 22/25] pcm_file: coverity fixes (including double locking) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_file.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 99db3754fa32..54142a3d16ef 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -296,7 +296,10 @@ static int snd_pcm_file_areas_read_infile(snd_pcm_t *pcm, + return -ENOMEM; + } + +- bytes = read(file->ifd, file->rbuf, snd_pcm_frames_to_bytes(pcm, frames)); ++ bytes = snd_pcm_frames_to_bytes(pcm, frames); ++ if (bytes < 0) ++ return bytes; ++ bytes = read(file->ifd, file->rbuf, bytes); + if (bytes < 0) { + SYSERR("read from file failed, error: %d", bytes); + return bytes; +@@ -589,18 +592,14 @@ static snd_pcm_sframes_t snd_pcm_file_readi(snd_pcm_t *pcm, void *buffer, snd_pc + snd_pcm_channel_area_t areas[pcm->channels]; + snd_pcm_sframes_t frames; + +- __snd_pcm_lock(pcm); +- + frames = _snd_pcm_readi(file->gen.slave, buffer, size); +- if (frames <= 0) { +- __snd_pcm_unlock(pcm); ++ if (frames <= 0) + return frames; +- } + + snd_pcm_areas_from_buf(pcm, areas, buffer); + snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); ++ __snd_pcm_lock(pcm); + snd_pcm_file_add_frames(pcm, areas, 0, frames); +- + __snd_pcm_unlock(pcm); + + return frames; +@@ -654,9 +653,6 @@ static int snd_pcm_file_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t + snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames) + { + snd_pcm_file_t *file = pcm->private_data; +- snd_pcm_channel_area_t areas_if[pcm->channels]; +- snd_pcm_uframes_t frames_if; +- void *buffer = NULL; + int result; + + result = snd_pcm_mmap_begin(file->gen.slave, areas, offset, frames); +-- +2.16.4 + diff --git a/0023-topology-next-round-of-coverity-fixes.patch b/0023-topology-next-round-of-coverity-fixes.patch new file mode 100644 index 0000000..878c4d1 --- /dev/null +++ b/0023-topology-next-round-of-coverity-fixes.patch @@ -0,0 +1,70 @@ +From c6e7fd8b1e0d8729c7220734ca0b529c35d926ed Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 27 May 2019 14:05:12 +0200 +Subject: [PATCH 23/25] topology: next round of coverity fixes + +Signed-off-by: Jaroslav Kysela +--- + src/topology/data.c | 5 ++--- + src/topology/parser.c | 7 +++++-- + 2 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/topology/data.c b/src/topology/data.c +index aa2b87e73f50..b3f4421f5d5c 100644 +--- a/src/topology/data.c ++++ b/src/topology/data.c +@@ -88,8 +88,7 @@ static int tplg_parse_data_file(snd_config_t *cfg, struct tplg_elem *elem) + if (fp == NULL) { + SNDERR("error: invalid data file path '%s'\n", + filename); +- ret = -errno; +- goto err; ++ return -errno; + } + + fseek(fp, 0L, SEEK_END); +@@ -463,6 +462,7 @@ static int copy_tuples(struct tplg_elem *elem, + + off = priv->size; + priv->size = size; /* update private data size */ ++ elem->data = priv; + + array = (struct snd_soc_tplg_vendor_array *)(priv->data + off); + array->size = set_size; +@@ -499,7 +499,6 @@ static int copy_tuples(struct tplg_elem *elem, + } + } + +- elem->data = priv; + return 0; + } + +diff --git a/src/topology/parser.c b/src/topology/parser.c +index a7cff1c30edc..5940692da2e2 100644 +--- a/src/topology/parser.c ++++ b/src/topology/parser.c +@@ -253,8 +253,10 @@ static int tplg_load_config(const char *file, snd_config_t **cfg) + } + + ret = snd_input_close(in); +- if (ret < 0) ++ if (ret < 0) { ++ in = NULL; + goto err_load; ++ } + + *cfg = top; + return 0; +@@ -262,7 +264,8 @@ static int tplg_load_config(const char *file, snd_config_t **cfg) + err_load: + snd_config_delete(top); + err: +- snd_input_close(in); ++ if (in) ++ snd_input_close(in); + return ret; + } + +-- +2.16.4 + diff --git a/0024-pcm_file-another-locking-fix-coverity.patch b/0024-pcm_file-another-locking-fix-coverity.patch new file mode 100644 index 0000000..17987ce --- /dev/null +++ b/0024-pcm_file-another-locking-fix-coverity.patch @@ -0,0 +1,39 @@ +From ac6df1106c314de5d027176d910b9bc43a1fa7f9 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 27 May 2019 20:10:32 +0200 +Subject: [PATCH 24/25] pcm_file: another locking fix (coverity) + +Signed-off-by: Jaroslav Kysela +--- + src/pcm/pcm_file.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c +index 54142a3d16ef..1ef80b599b06 100644 +--- a/src/pcm/pcm_file.c ++++ b/src/pcm/pcm_file.c +@@ -612,18 +612,16 @@ static snd_pcm_sframes_t snd_pcm_file_readn(snd_pcm_t *pcm, void **bufs, snd_pcm + snd_pcm_channel_area_t areas[pcm->channels]; + snd_pcm_sframes_t frames; + +- __snd_pcm_lock(pcm); + frames = _snd_pcm_readn(file->gen.slave, bufs, size); +- if (frames <= 0) { +- __snd_pcm_unlock(pcm); ++ if (frames <= 0) + return frames; +- } + + snd_pcm_areas_from_bufs(pcm, areas, bufs); + snd_pcm_file_areas_read_infile(pcm, areas, 0, frames); ++ __snd_pcm_lock(pcm); + snd_pcm_file_add_frames(pcm, areas, 0, frames); +- + __snd_pcm_unlock(pcm); ++ + return frames; + } + +-- +2.16.4 + diff --git a/0025-ucm-another-coverity-fix-in-uc_mgr_config_load.patch b/0025-ucm-another-coverity-fix-in-uc_mgr_config_load.patch new file mode 100644 index 0000000..3dc4e78 --- /dev/null +++ b/0025-ucm-another-coverity-fix-in-uc_mgr_config_load.patch @@ -0,0 +1,38 @@ +From 5905af199670ca34eaaafbd3319d94d230b7e4d4 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 27 May 2019 20:10:52 +0200 +Subject: [PATCH 25/25] ucm: another coverity fix in uc_mgr_config_load() + +--- + src/ucm/utils.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/src/ucm/utils.c b/src/ucm/utils.c +index efd5a97999b1..5607304e6426 100644 +--- a/src/ucm/utils.c ++++ b/src/ucm/utils.c +@@ -85,15 +85,18 @@ int uc_mgr_config_load(const char *file, snd_config_t **cfg) + goto __err2; + } + err = snd_input_close(in); +- if (err < 0) ++ if (err < 0) { ++ in = NULL; + goto __err2; ++ } + *cfg = top; + return 0; + + __err2: +- snd_config_delete(top); ++ snd_config_delete(top); + __err1: +- snd_input_close(in); ++ if (in) ++ snd_input_close(in); + return err; + } + +-- +2.16.4 + diff --git a/50-alsa.conf b/50-alsa.conf deleted file mode 100644 index cc6347a..0000000 --- a/50-alsa.conf +++ /dev/null @@ -1,3 +0,0 @@ -install snd /sbin/install-snd-module snd $CMDLINE_OPTS -install snd-pcm /sbin/install-snd-module snd-pcm $CMDLINE_OPTS -install snd-seq /sbin/install-snd-module snd-seq $CMDLINE_OPTS diff --git a/alsa.changes b/alsa.changes index eb048b7..b97238b 100644 --- a/alsa.changes +++ b/alsa.changes @@ -1,3 +1,40 @@ +------------------------------------------------------------------- +Tue May 28 12:32:16 CEST 2019 - tiwai@suse.de + +- Remove hackish modprobe install scripts for auto-loading OSS and + sequencer modules (bsc#1136562); + it's invoked from systemd unit file included in alsa-utils now + +- Backport upstream fixes: + 0001-pcm-direct-Add-generic-hw_ptr_alignment-function-for.patch + 0002-pcm-dshare-Added-hw_ptr_alignment-option-in-configur.patch + 0003-pcm-dsnoop-Added-hw_ptr_alignment-option-in-configur.patch + 0004-pcm-file-add-support-for-infile-reading-in-non-inter.patch + 0005-pcm-file-use-snd_pcm_file_areas_read_infile-for-read.patch + 0006-pcm-file-add-missing-unlock-on-early-return.patch + 0007-ucm-Add-UCM-profile-for-CX2072X-codec-on-Baytrail-Ch.patch + 0008-pcm-add-mmap_begin-callback-to-snd_pcm_fast_ops_t-ap.patch + 0009-pcm-file-add-infile-read-support-for-mmap-mode.patch + 0010-aserver-fix-resource-leak-coverity.patch + 0011-src-conf.c-add-missing-va_end-call-coverity.patch + 0012-config-parse_string-fix-the-dynamic-buffer-allocatio.patch + 0013-control_shm-remove-duplicate-code-coverity.patch + 0014-control_shm-add-missing-socket-close-to-the-error-pa.patch + 0015-pcm-fix-memory-leak-in-_snd_pcm_parse_config_chmaps-.patch + 0016-pcm_file-call-pclose-correctly-for-popen-coverity.patch + 0017-pcm_hw-close-file-descriptor-in-the-error-path-in-sn.patch + 0018-rawmidi-use-snd_dlobj_cache_get2-in-rawmidi-open-cov.patch + 0019-rawmidi_hw-add-sanity-check-for-the-invalid-stream-a.patch + 0020-topology-various-coverity-fixes.patch + 0021-ucm-coverity-fixes.patch + 0022-pcm_file-coverity-fixes-including-double-locking.patch + 0023-topology-next-round-of-coverity-fixes.patch + 0024-pcm_file-another-locking-fix-coverity.patch + 0025-ucm-another-coverity-fix-in-uc_mgr_config_load.patch + +- Drop the downstream CX2072X UCM profile, which is replaced with + upstream patches above + ------------------------------------------------------------------- Fri May 10 13:00:38 CEST 2019 - tiwai@suse.de diff --git a/alsa.spec b/alsa.spec index caf8ec7..57c3690 100644 --- a/alsa.spec +++ b/alsa.spec @@ -12,7 +12,7 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # @@ -47,13 +47,34 @@ Source30: all_notes_off Source31: all_notes_off.bin Source32: all_notes_off.mid Source34: alsa-init.sh -Source40: 50-alsa.conf -Source41: install-snd-module # upstream fixes +Patch1: 0001-pcm-direct-Add-generic-hw_ptr_alignment-function-for.patch +Patch2: 0002-pcm-dshare-Added-hw_ptr_alignment-option-in-configur.patch +Patch3: 0003-pcm-dsnoop-Added-hw_ptr_alignment-option-in-configur.patch +Patch4: 0004-pcm-file-add-support-for-infile-reading-in-non-inter.patch +Patch5: 0005-pcm-file-use-snd_pcm_file_areas_read_infile-for-read.patch +Patch6: 0006-pcm-file-add-missing-unlock-on-early-return.patch +Patch7: 0007-ucm-Add-UCM-profile-for-CX2072X-codec-on-Baytrail-Ch.patch +Patch8: 0008-pcm-add-mmap_begin-callback-to-snd_pcm_fast_ops_t-ap.patch +Patch9: 0009-pcm-file-add-infile-read-support-for-mmap-mode.patch +Patch10: 0010-aserver-fix-resource-leak-coverity.patch +Patch11: 0011-src-conf.c-add-missing-va_end-call-coverity.patch +Patch12: 0012-config-parse_string-fix-the-dynamic-buffer-allocatio.patch +Patch13: 0013-control_shm-remove-duplicate-code-coverity.patch +Patch14: 0014-control_shm-add-missing-socket-close-to-the-error-pa.patch +Patch15: 0015-pcm-fix-memory-leak-in-_snd_pcm_parse_config_chmaps-.patch +Patch16: 0016-pcm_file-call-pclose-correctly-for-popen-coverity.patch +Patch17: 0017-pcm_hw-close-file-descriptor-in-the-error-path-in-sn.patch +Patch18: 0018-rawmidi-use-snd_dlobj_cache_get2-in-rawmidi-open-cov.patch +Patch19: 0019-rawmidi_hw-add-sanity-check-for-the-invalid-stream-a.patch +Patch20: 0020-topology-various-coverity-fixes.patch +Patch21: 0021-ucm-coverity-fixes.patch +Patch22: 0022-pcm_file-coverity-fixes-including-double-locking.patch +Patch23: 0023-topology-next-round-of-coverity-fixes.patch +Patch24: 0024-pcm_file-another-locking-fix-coverity.patch +Patch25: 0025-ucm-another-coverity-fix-in-uc_mgr_config_load.patch # rest suse fixes Patch101: alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch -Source101: chtcx2072x.conf -Source102: chtcx2072x-HiFi.conf BuildRequires: doxygen BuildRequires: libtool BuildRequires: pkgconfig @@ -116,6 +137,31 @@ Architecture. %prep %setup -q -n alsa-lib-%{version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 %patch101 -p1 %build @@ -137,10 +183,6 @@ make -C doc doc %{?_smp_mflags} %install # install shared library %make_install -# additional UCM profiles -mkdir -p %{buildroot}%{_datadir}/alsa/ucm/chtcx2072x -install -c -m 0644 %{S:101} %{buildroot}%{_datadir}/alsa/ucm/chtcx2072x/chtcx2072x.conf -install -c -m 0644 %{S:102} %{buildroot}%{_datadir}/alsa/ucm/chtcx2072x/HiFi.conf # clean up unneeded files rm -f %{buildroot}%{_libdir}/*.*a # rm -f %{buildroot}%{_libdir}/alsa-lib/smixer/*.*a @@ -187,15 +229,6 @@ install -c -m 0644 %{SOURCE8} %{buildroot}%{_udevrulesdir} %endif install -c -m 0644 %{SOURCE9} %{buildroot}%{_udevrulesdir} # -# modprobe config and the module install script for loading OSS-emulation -# and sequencer modules automatically -%if 0%{?suse_version} > 1220 -mkdir -p %{buildroot}%{_sysconfdir}/modprobe.d -install -c -m 0644 %{SOURCE40} %{buildroot}%{_sysconfdir}/modprobe.d -mkdir -p %{buildroot}/sbin -install -c -m 0755 %{SOURCE41} %{buildroot}/sbin -%endif -# # install template to update rc.config and sysconfig files: # (updating the actual files is done in the %post-script) # @@ -249,10 +282,6 @@ exit 0 %if 0%{?suse_version} <= 1310 %{_initddir}/* %endif -%if 0%{?suse_version} > 1220 -%{_sysconfdir}/modprobe.d -/sbin/* -%endif %{_sbindir}/* %{_bindir}/* %{_prefix}/lib/all_notes_off.* diff --git a/chtcx2072x-HiFi.conf b/chtcx2072x-HiFi.conf deleted file mode 100644 index a24addb..0000000 --- a/chtcx2072x-HiFi.conf +++ /dev/null @@ -1,185 +0,0 @@ -SectionVerb { - # ALSA PCM - Value { - TQ "HiFi" - - # ALSA PCM device for HiFi - PlaybackPCM "hw:chtcx2072x,0" - CapturePCM "hw:chtcx2072x,0" - } - - EnableSequence [ - cdev "hw:chtcx2072x" - - # Enable audio output path - cset "name='codec_out0 mix 0 pcm0_in Switch' on" - cset "name='media0_out mix 0 media1_in Switch' on" - - cset "name='media1_in Gain 0 Ramp Delay' 50" - cset "name='media1_in Gain 0 Switch' on" - cset "name='media1_in Gain 0 Volume' 0dB" - - cset "name='pcm0_in Gain 0 Ramp Delay' 50" - cset "name='pcm0_in Gain 0 Switch' on" - cset "name='pcm0_in Gain 0 Volume' 0dB" - - cset "name='codec_out0 Gain 0 Ramp Delay' 50" - cset "name='codec_out0 Gain 0 Switch' on" - cset "name='codec_out0 Gain 0 Volume' 0dB" - - # Enable audio input path - cset "name='pcm1_out mix 0 media_loop2_in Switch' on" - cset "name='media_loop2_out mix 0 codec_in0 Switch' on" - - cset "name='codec_in0 Gain 0 Ramp Delay' 50" - cset "name='codec_in0 Gain 0 Switch' on" - cset "name='codec_in0 Gain 0 Volume' 0dB" - - cset "name='media_loop2_out Gain 0 Ramp Delay' 50" - cset "name='media_loop2_out Gain 0 Switch' on" - cset "name='media_loop2_out Gain 0 Volume' 0dB" - - cset "name='pcm1_out Gain 0 Ramp Delay' 50" - cset "name='pcm1_out Gain 0 Switch' on" - cset "name='pcm1_out Gain 0 Volume' 0dB" - - # Output Configuration - cset "name='I2S DAC1L Switch' on" - cset "name='I2S DAC1R Switch' on" - - # Input Configuration - cset "name='I2S ADC1L Switch' on" - cset "name='I2S ADC1R Switch' on" - ] - - DisableSequence [ - cdev "hw:chtcx2072x" - - # Disable audio output path - cset "name='codec_out0 mix 0 pcm0_in Switch' off" - cset "name='media0_out mix 0 media1_in Switch' off" - - cset "name='media1_in Gain 0 Switch' off" - cset "name='pcm0_in Gain 0 Switch' off" - cset "name='codec_out0 Gain 0 Switch' off" - - # Disable audio input path - cset "name='pcm1_out mix 0 media_loop2_in Switch' off" - cset "name='media_loop2_out mix 0 codec_in0 Switch' off" - - cset "name='media_loop2_out Gain 0 Switch' off" - cset "name='pcm1_out Gain 0 Switch' off" - cset "name='codec_in0 Gain 0 Switch' off" - - # Output Configuration - cset "name='I2S DAC1L Switch' off" - cset "name='I2S DAC1R Switch' off" - - # Input Configuration - cset "name='I2S ADC1L Switch' off" - cset "name='I2S ADC1R Switch' off" - ] -} - -SectionDevice."Speaker" { - Comment "Speaker" - - Value { - PlaybackChannels "2" - } - - ConflictingDevice [ - "Headphone" - ] - - EnableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Ext Spk Switch' on" - cset "name='PortG Out En Switch' on" - ] - - DisableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Ext Spk Switch' off" - cset "name='PortG Out En Switch' off" - ] -} - -SectionDevice."Headphone".0 { - Comment "Headphones" - - Value { - PlaybackChannels "2" - JackControl "Headphone Jack" - JackHWMute "Speaker" - } - - ConflictingDevice [ - "Speaker" - ] - - EnableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Headphone Switch' on" - cset "name='PortA Out En Switch' on" - ] - - DisableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Headphone Switch' off" - cset "name='PortA Out En Switch' off" - ] -} - -SectionDevice."Mic".0 { - Comment "Internal Microphone" - - Value { - CaptureChannels "2" - CapturePriority "150" - } - - EnableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Int Mic Switch' on" - cset "name='ADC1 Mux' 'PortC Switch'" - cset "name='PortC In En Switch' on" - ] - - DisableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Int Mic Switch' off" - cset "name='PortC In En Switch' off" - ] -} - -SectionDevice."HSMic".0 { - Comment "Headset Microphone" - - Value { - CaptureChannels "2" - JackControl "Headset Mic Jack" - JackHWMute "Mic" - } - - EnableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Headset Mic Switch' on" - cset "name='ADC1 Mux' 'PortD Switch'" - cset "name='PortD In En Switch' on" - ] - - DisableSequence [ - cdev "hw:chtcx2072x" - - cset "name='Headset Mic Switch' off" - cset "name='PortD In En Switch' off" - ] -} diff --git a/chtcx2072x.conf b/chtcx2072x.conf deleted file mode 100644 index c21ee6d..0000000 --- a/chtcx2072x.conf +++ /dev/null @@ -1,5 +0,0 @@ -Comment "Intel SoC Audio Device" -SectionUseCase."HiFi" { - File "HiFi.conf" - Comment "Default" -} diff --git a/install-snd-module b/install-snd-module deleted file mode 100644 index 9472998..0000000 --- a/install-snd-module +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -/sbin/modprobe --ignore-install "$@" || exit $? - -. /etc/sysconfig/sound - -case "$1" in - snd) - /sbin/modprobe --quiet --use-blacklist snd-ioctl32 - test "$LOAD_OSS_EMUL_MODULES" = "yes" && \ - /sbin/modprobe --quiet --use-blacklist snd-mixer-oss - test "$LOAD_SEQUENCER" = "yes" && \ - /sbin/modprobe --quiet --use-blacklist snd-seq - ;; - snd-pcm|snd_pcm) - test "$LOAD_OSS_EMUL_MODULES" = "yes" && \ - /sbin/modprobe --quiet --use-blacklist snd-pcm-oss - ;; - snd-seq|snd_seq) - if [ -r /proc/asound/seq/drivers ]; then - OLDIFS="$IFS" - IFS="," - while read t x c; do - /sbin/modprobe --quiet --use-blacklist $t - done < /proc/asound/seq/drivers - IFS="$OLDIFS" - fi - test "$LOAD_OSS_SEQ_MODULE" = "yes" && \ - /sbin/modprobe --quiet --use-blacklist snd-seq-oss - ;; -esac - -exit 0