int version;
int fd;
int card, device, subdevice;
- int sync_ptr_ioctl;
+
volatile struct snd_pcm_mmap_status * mmap_status;
struct snd_pcm_mmap_control *mmap_control;
+ bool mmap_status_fallbacked;
struct snd_pcm_sync_ptr *sync_ptr;
+
int period_event;
snd_timer_t *period_timer;
struct pollfd period_timer_pfd;
return xfern.result;
}
-static int map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr)
+static bool map_status_data(snd_pcm_hw_t *hw, struct snd_pcm_sync_ptr *sync_ptr,
+ bool force_fallback)
{
- void *ptr;
+ struct snd_pcm_mmap_status *mmap_status;
+ bool fallbacked;
+
+ mmap_status = MAP_FAILED;
+ if (!force_fallback) {
+ mmap_status = mmap(NULL, page_align(sizeof(*mmap_status)),
+ PROT_READ, MAP_FILE|MAP_SHARED,
+ hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
+ }
- ptr = MAP_FAILED;
- if (hw->sync_ptr_ioctl == 0)
- ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_status)),
- PROT_READ, MAP_FILE|MAP_SHARED,
- hw->fd, SNDRV_PCM_MMAP_OFFSET_STATUS);
- if (ptr == MAP_FAILED || ptr == NULL) {
- hw->mmap_status = &sync_ptr->s.status;
- hw->mmap_control = &sync_ptr->c.control;
- hw->sync_ptr_ioctl = 1;
+ if (mmap_status == MAP_FAILED || mmap_status == NULL) {
+ mmap_status = &sync_ptr->s.status;
+ fallbacked = true;
} else {
- hw->mmap_status = ptr;
+ fallbacked = false;
}
- return 0;
+ hw->mmap_status = mmap_status;
+
+ return fallbacked;
}
-static int map_control_data(snd_pcm_hw_t *hw)
+static bool map_control_data(snd_pcm_hw_t *hw,
+ struct snd_pcm_sync_ptr *sync_ptr,
+ bool force_fallback)
{
- void *ptr;
+ struct snd_pcm_mmap_control *mmap_control;
int err;
- if (hw->sync_ptr_ioctl == 0) {
- ptr = mmap(NULL, page_align(sizeof(struct snd_pcm_mmap_control)),
- PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
- hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL);
- if (ptr == MAP_FAILED || ptr == NULL) {
+
+ 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;
}
- hw->mmap_control = ptr;
+ } else {
+ mmap_control = &sync_ptr->c.control;
}
+ hw->mmap_control = mmap_control;
+
return 0;
}
return -ENOMEM;
memset(sync_ptr, 0, sizeof(*sync_ptr));
- hw->sync_ptr_ioctl = (int)force_fallback;
-
- err = map_status_data(hw, sync_ptr);
- if (err < 0)
- return err;
-
- err = map_control_data(hw);
+ 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;
/* Any fallback mode needs to keep the buffer. */
- if (hw->sync_ptr_ioctl == 0) {
+ if (hw->mmap_status_fallbacked == 0) {
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->sync_ptr_ioctl) {
+ if (hw->mmap_status_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_status_data(snd_pcm_hw_t *hw)
{
- if (!hw->sync_ptr) {
+ if (!hw->mmap_status_fallbacked) {
if (munmap((void *)hw->mmap_status,
page_align(sizeof(*hw->mmap_status))) < 0)
SYSMSG("status munmap failed (%u)", errno);
static void unmap_control_data(snd_pcm_hw_t *hw)
{
- if (!hw->sync_ptr) {
+ if (!hw->mmap_status_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->sync_ptr)
+ if (hw->mmap_status_fallbacked)
free(hw->sync_ptr);
hw->mmap_status = NULL;
hw->mmap_control = NULL;
+ hw->mmap_status_fallbacked = false;
hw->sync_ptr = NULL;
}