volatile struct snd_pcm_mmap_status * mmap_status;
struct snd_pcm_mmap_control *mmap_control;
bool mmap_status_fallbacked;
+ bool mmap_control_fallbacked;
struct snd_pcm_sync_ptr *sync_ptr;
int period_event;
return 0;
}
-static inline int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
+static int sync_ptr(snd_pcm_hw_t *hw, unsigned int flags)
{
- return hw->sync_ptr ? sync_ptr1(hw, flags) : 0;
+ if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked)
+ return sync_ptr1(hw, flags);
+ return 0;
}
static int snd_pcm_hw_clear_timer_queue(snd_pcm_hw_t *hw)
bool force_fallback)
{
struct snd_pcm_mmap_control *mmap_control;
- int err;
+ bool fallbacked;
if (!force_fallback) {
mmap_control = mmap(NULL, page_align(sizeof(*mmap_control)),
PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
- if (mmap_control == MAP_FAILED || mmap_control == NULL) {
- err = -errno;
- SYSMSG("control mmap failed (%i)", err);
- return err;
- }
- } else {
+ }
+
+ if (mmap_control == MAP_FAILED || mmap_control == NULL) {
mmap_control = &sync_ptr->c.control;
+ fallbacked = true;
+ } else {
+ fallbacked = false;
}
hw->mmap_control = mmap_control;
- return 0;
+ return fallbacked;
}
static int map_status_and_control_data(snd_pcm_t *pcm, bool force_fallback)
hw->mmap_status_fallbacked =
map_status_data(hw, sync_ptr, force_fallback);
- err = map_control_data(hw, sync_ptr, hw->mmap_status_fallbacked);
- if (err < 0)
- return err;
+ hw->mmap_control_fallbacked =
+ map_control_data(hw, sync_ptr, force_fallback);
/* Any fallback mode needs to keep the buffer. */
- if (hw->mmap_status_fallbacked == 0) {
+ if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked) {
hw->sync_ptr = sync_ptr;
} else {
free(sync_ptr);
offsetof(struct snd_pcm_mmap_status, hw_ptr));
snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd,
SNDRV_PCM_MMAP_OFFSET_CONTROL);
- if (hw->mmap_status_fallbacked) {
+ if (hw->mmap_control_fallbacked) {
if (ioctl(hw->fd, SNDRV_PCM_IOCTL_SYNC_PTR, hw->sync_ptr) < 0) {
err = -errno;
SYSMSG("SNDRV_PCM_IOCTL_SYNC_PTR failed (%i)", err);
static void unmap_control_data(snd_pcm_hw_t *hw)
{
- if (!hw->mmap_status_fallbacked) {
+ if (!hw->mmap_control_fallbacked) {
if (munmap((void *)hw->mmap_control,
page_align(sizeof(*hw->mmap_control))) < 0)
SYSMSG("control munmap failed (%u)", errno);
unmap_status_data(hw);
unmap_control_data(hw);
- if (hw->mmap_status_fallbacked)
+ if (hw->mmap_status_fallbacked || hw->mmap_control_fallbacked)
free(hw->sync_ptr);
hw->mmap_status = NULL;
hw->mmap_control = NULL;
hw->mmap_status_fallbacked = false;
+ hw->mmap_control_fallbacked = false;
hw->sync_ptr = NULL;
}