aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2021-10-11 16:57:45 +0200
committerTakashi Iwai <tiwai@suse.de>2021-10-11 16:57:45 +0200
commit63e7c13d86141f3c9de51dcf2cf3510dc753b45e (patch)
tree8b3875227ba91a03a36b513542e849bb128913f1
parent54b6914338e0369cf20eb6fa8b2d99cd9c472777 (diff)
downloadsalsa-lib-63e7c13d86141f3c9de51dcf2cf3510dc753b45e.tar.gz
Allow enforcing 64bit timespec build
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--configure.ac14
-rw-r--r--src/asound.h164
-rw-r--r--src/pcm.c8
-rw-r--r--src/pcm_macros.h12
-rw-r--r--src/rawmidi_macros.h2
-rw-r--r--src/recipe.h.in3
-rw-r--r--src/timer_macros.h2
7 files changed, 173 insertions, 32 deletions
diff --git a/configure.ac b/configure.ac
index 69a0ddf..8058556 100644
--- a/configure.ac
+++ b/configure.ac
@@ -142,6 +142,11 @@ AC_ARG_ENABLE(ctlasciiparser,
[enable ctl ASCII parser (for amixer)]),
ctlasciiparser="$enableval", ctlasciiparser="no")
+AC_ARG_ENABLE(time64,
+ AS_HELP_STRING([--enable-time64],
+ [enforce 64bit timespec for ioctls]),
+ struct_time64="$enableval", struct_time64="no")
+
AC_ARG_ENABLE(everything,
AS_HELP_STRING([--enable-everything],
[enable everything :)]),
@@ -166,6 +171,7 @@ if test "$everything" = "yes"; then
support_4bit="yes"
abicheck="yes"
ctlasciiparser="yes"
+ struct_time64="yes"
fi
SALSA_DEPLIBS=""
@@ -259,6 +265,13 @@ else
fi
AC_SUBST(SALSA_CTL_ASCII_PARSER)
+if test "$struct_time64" = "yes"; then
+ SALSA_STRUCT_TIME64=1
+else
+ SALSA_STRUCT_TIME64=0
+fi
+AC_SUBST(SALSA_STRUCT_TIME64)
+
if test "$delight_valgrind" = "yes"; then
AC_DEFINE(DELIGHT_VALGRIND)
fi
@@ -319,3 +332,4 @@ echo " - Support string-output via snd_output: $output_buffer"
echo " - Support floating-point: $support_float"
echo " - Enable library ABI check: $abicheck"
echo " - Support ctl ASCII parser: $ctlasciiparser"
+echo " - Enforce 64bit timespec: $struct_time64"
diff --git a/src/asound.h b/src/asound.h
index d919f65..e405c3d 100644
--- a/src/asound.h
+++ b/src/asound.h
@@ -20,6 +20,7 @@
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <stdint.h>
#include <endian.h>
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define SND_LITTLE_ENDIAN
@@ -33,6 +34,38 @@
#define SNDRV_PROTOCOL_VERSION(major, minor, subminor) \
(((major) << 16) | ((minor) << 8) | (subminor))
+typedef struct timeval snd_timestamp_t;
+typedef struct timespec snd_htimestamp_t;
+
+struct __snd_timespec64 {
+ int64_t tv_sec;
+ int64_t tv_nsec;
+};
+
+#if __TIMESIZE == 32 && SALSA_STRUCT_TIME64
+#define __snd_timespec __snd_timespec64
+typedef struct { unsigned char pad[sizeof(int64_t) - sizeof(int)]; } __time_pad;
+
+static inline void __copy_to_snd_htimestamp(const struct __snd_timespec *src, snd_htimestamp_t *dst)
+{
+ dst->tv_sec = src->tv_sec;
+ dst->tv_nsec = src->tv_nsec;
+}
+
+static inline snd_htimestamp_t __to_snd_htimestamp(const struct __snd_timespec *src)
+{
+ snd_htimestamp_t val;
+ __copy_to_snd_htimestamp(src, &val);
+ return val;
+}
+#else
+#define __snd_timespec timespec
+typedef struct { unsigned char pad[sizeof(time_t) - sizeof(int)]; } __time_pad;
+
+#define __copy_to_snd_htimestamp(src, dst) do { *(dst) = *(src); } while (0)
+#define __to_snd_htimestamp(src) *(src)
+#endif
+
/* IEC958 status bits definition */
typedef struct snd_aes_iec958 {
unsigned char status[24];
@@ -99,10 +132,10 @@ enum {
/* PCM interface */
-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 12)
+#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15)
typedef unsigned long snd_pcm_uframes_t;
-typedef long snd_pcm_sframes_t;
+typedef signed long snd_pcm_sframes_t;
typedef enum _snd_pcm_class {
SND_PCM_CLASS_GENERIC = 0,
@@ -229,6 +262,12 @@ typedef enum _snd_pcm_subformat {
#define SNDRV_PCM_INFO_SYNC_START 0x00400000
#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000
#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000
+#define SNDRV_PCM_INFO_HAS_WALL_CLOCK 0x01000000
+#define SNDRV_PCM_INFO_HAS_LINK_ATIME 0x01000000
+#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000
+#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000
+#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000
+#define SNDRV_PCM_INFO_EXPLICIT_SYNC 0x10000000
typedef enum _snd_pcm_state {
SND_PCM_STATE_OPEN = 0,
@@ -245,8 +284,17 @@ typedef enum _snd_pcm_state {
enum {
SNDRV_PCM_MMAP_OFFSET_DATA = 0x00000000,
- SNDRV_PCM_MMAP_OFFSET_STATUS = 0x80000000,
- SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x81000000,
+ SNDRV_PCM_MMAP_OFFSET_STATUS_OLD = 0x80000000,
+ SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD = 0x81000000,
+ SNDRV_PCM_MMAP_OFFSET_STATUS_NEW = 0x82000000,
+ SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW = 0x83000000,
+#if __TIMESIZE == 64 || SALSA_STRUCT_TIME64
+ SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_NEW,
+ SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_NEW,
+#else
+ SNDRV_PCM_MMAP_OFFSET_STATUS = SNDRV_PCM_MMAP_OFFSET_STATUS_OLD,
+ SNDRV_PCM_MMAP_OFFSET_CONTROL = SNDRV_PCM_MMAP_OFFSET_CONTROL_OLD,
+#endif
};
typedef union _snd_pcm_sync_id {
@@ -369,10 +417,31 @@ struct sndrv_pcm_channel_info {
unsigned int step;
};
+typedef enum _snd_pcm_audio_tstamp_type {
+ SND_PCM_AUDIO_TSTAMP_TYPE_COMPAT = 0,
+ SND_PCM_AUDIO_TSTAMP_TYPE_DEFAULT = 1,
+ SND_PCM_AUDIO_TSTAMP_TYPE_LINK = 2,
+ SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ABSOLUTE = 3,
+ SND_PCM_AUDIO_TSTAMP_TYPE_LINK_ESTIMATED = 4,
+ SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED = 5,
+ SND_PCM_AUDIO_TSTAMP_TYPE_LAST = SND_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED
+} snd_pcm_audio_tstamp_type_t;
+
+#if __TIMESIZE == 32 && SALSA_STRUCT_TIME64
+#define __snd_pcm_mmap_status64 snd_pcm_mmap_status
+#define __snd_pcm_mmap_control64 snd_pcm_mmap_control
+#define __snd_pcm_sync_ptr64 snd_pcm_sync_ptr
+#else
+#define __snd_pcm_mmap_status snd_pcm_mmap_status
+#define __snd_pcm_mmap_control snd_pcm_mmap_control
+#define __snd_pcm_sync_ptr snd_pcm_sync_ptr
+#endif
+
typedef struct snd_pcm_status {
int state;
- struct timespec trigger_tstamp;
- struct timespec tstamp;
+ __time_pad pad1;
+ struct __snd_timespec trigger_tstamp;
+ struct __snd_timespec tstamp;
snd_pcm_uframes_t appl_ptr;
snd_pcm_uframes_t hw_ptr;
snd_pcm_sframes_t delay;
@@ -380,20 +449,23 @@ typedef struct snd_pcm_status {
snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t overrange;
int suspended_state;
- struct timespec audio_tstamp;
- unsigned char reserved[60 - sizeof(struct timespec)];
+ struct __snd_timespec audio_tstamp;
+ struct __snd_timespec driver_tstamp;
+ unsigned int audio_tstamp_accuracy;
+
+ unsigned char reserved[52 - 2*sizeof(struct __snd_timespec)];
} snd_pcm_status_t;
-struct snd_pcm_mmap_status {
- int state;
+struct __snd_pcm_mmap_status {
+ snd_pcm_state_t state;
int pad1;
snd_pcm_uframes_t hw_ptr;
- struct timespec tstamp;
- int suspended_state;
- struct timespec audio_tstamp;
+ struct __snd_timespec tstamp;
+ snd_pcm_state_t suspended_state;
+ struct __snd_timespec audio_tstamp;
};
-struct snd_pcm_mmap_control {
+struct __snd_pcm_mmap_control {
snd_pcm_uframes_t appl_ptr;
snd_pcm_uframes_t avail_min;
};
@@ -402,14 +474,56 @@ struct snd_pcm_mmap_control {
#define SNDRV_PCM_SYNC_PTR_APPL (1<<1)
#define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2)
-struct snd_pcm_sync_ptr {
+struct __snd_pcm_sync_ptr {
unsigned int flags;
union {
- struct snd_pcm_mmap_status status;
+ struct __snd_pcm_mmap_status status;
unsigned char reserved[64];
} s;
union {
- struct snd_pcm_mmap_control control;
+ struct __snd_pcm_mmap_control control;
+ unsigned char reserved[64];
+ } c;
+};
+
+#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __BIG_ENDIAN : defined(__BIG_ENDIAN)
+typedef char __pad_before_uframe[sizeof(int64_t) - sizeof(snd_pcm_uframes_t)];
+typedef char __pad_after_uframe[0];
+#else
+typedef char __pad_before_uframe[0];
+typedef char __pad_after_uframe[sizeof(int64_t) - sizeof(snd_pcm_uframes_t)];
+#endif
+
+struct __snd_pcm_mmap_status64 {
+ snd_pcm_state_t state;
+ unsigned int pad1;
+ __pad_before_uframe __pad1;
+ snd_pcm_uframes_t hw_ptr;
+ __pad_after_uframe __pad2;
+ struct __snd_timespec64 tstamp;
+ snd_pcm_state_t suspended_state;
+ unsigned int pad3;
+ struct __snd_timespec64 audio_tstamp;
+};
+
+struct __snd_pcm_mmap_control64 {
+ __pad_before_uframe __pad1;
+ snd_pcm_uframes_t appl_ptr;
+ __pad_before_uframe __pad2;
+ __pad_before_uframe __pad3;
+ snd_pcm_uframes_t avail_min;
+ __pad_after_uframe __pad4;
+};
+
+struct __snd_pcm_sync_ptr64 {
+ unsigned int flags;
+ unsigned int pad1;
+ union {
+ struct __snd_pcm_mmap_status64 status;
+ unsigned char reserved[64];
+ } s;
+ union {
+ struct __snd_pcm_mmap_control64 control;
unsigned char reserved[64];
} c;
};
@@ -431,6 +545,7 @@ enum {
SNDRV_PCM_IOCTL_INFO = _IOR('A', 0x01, snd_pcm_info_t),
SNDRV_PCM_IOCTL_TSTAMP = _IOW('A', 0x02, int),
SNDRV_PCM_IOCTL_TTSTAMP = _IOW('A', 0x03, int),
+ SNDRV_PCM_IOCTL_USER_PVERSION = _IOW('A', 0x04, int),
SNDRV_PCM_IOCTL_HW_REFINE = _IOWR('A', 0x10, snd_pcm_hw_params_t),
SNDRV_PCM_IOCTL_HW_PARAMS = _IOWR('A', 0x11, snd_pcm_hw_params_t),
SNDRV_PCM_IOCTL_HW_FREE = _IO('A', 0x12),
@@ -438,7 +553,10 @@ enum {
SNDRV_PCM_IOCTL_STATUS = _IOR('A', 0x20, snd_pcm_status_t),
SNDRV_PCM_IOCTL_DELAY = _IOR('A', 0x21, snd_pcm_sframes_t),
SNDRV_PCM_IOCTL_HWSYNC = _IO('A', 0x22),
+ __SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct __snd_pcm_sync_ptr),
+ __SNDRV_PCM_IOCTL_SYNC_PTR64 = _IOWR('A', 0x23, struct __snd_pcm_sync_ptr64),
SNDRV_PCM_IOCTL_SYNC_PTR = _IOWR('A', 0x23, struct snd_pcm_sync_ptr),
+ SNDRV_PCM_IOCTL_STATUS_EXT = _IOWR('A', 0x24, snd_pcm_status_t),
SNDRV_PCM_IOCTL_CHANNEL_INFO = _IOR('A', 0x32, struct sndrv_pcm_channel_info),
SNDRV_PCM_IOCTL_PREPARE = _IO('A', 0x40),
SNDRV_PCM_IOCTL_RESET = _IO('A', 0x41),
@@ -567,7 +685,7 @@ typedef struct snd_rawmidi_params {
typedef struct snd_rawmidi_status {
int stream;
- struct timespec tstamp;
+ struct __snd_timespec tstamp;
size_t avail;
size_t xruns;
unsigned char reserved[16];
@@ -678,7 +796,7 @@ typedef struct snd_timer_params {
} snd_timer_params_t;
typedef struct snd_timer_status {
- struct timespec tstamp;
+ struct __snd_timespec tstamp;
unsigned int resolution;
unsigned int lost;
unsigned int overrun;
@@ -727,12 +845,9 @@ typedef enum _snd_timer_event {
SND_TIMER_EVENT_MRESUME = SND_TIMER_EVENT_RESUME + 10
} snd_timer_event_t;
-typedef struct timeval snd_timestamp_t;
-typedef struct timespec snd_htimestamp_t;
-
typedef struct _snd_timer_tread {
snd_timer_event_t event;
- snd_htimestamp_t tstamp;
+ struct __snd_timespec tstamp;
unsigned int val;
} snd_timer_tread_t;
@@ -865,8 +980,7 @@ typedef struct snd_ctl_elem_value {
} bytes;
struct snd_aes_iec958 iec958;
} value;
- struct timespec tstamp;
- unsigned char reserved[128-sizeof(struct timespec)];
+ unsigned char reserved[128];
} snd_ctl_elem_value_t;
typedef struct snd_ctl_tlv {
diff --git a/src/pcm.c b/src/pcm.c
index b50c69f..da958e3 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -107,6 +107,14 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
goto error;
}
+ if (SNDRV_PROTOCOL_VERSION(2, 0, 14) <= ver) {
+ unsigned int user_ver = SNDRV_PCM_VERSION;
+ if (ioctl(fd, SNDRV_PCM_IOCTL_USER_PVERSION, &user_ver) < 0) {
+ err = -errno;
+ goto error;
+ }
+ }
+
pcm = calloc(1, sizeof(*pcm));
if (!pcm) {
err = -ENOMEM;
diff --git a/src/pcm_macros.h b/src/pcm_macros.h
index f252014..07cd538 100644
--- a/src/pcm_macros.h
+++ b/src/pcm_macros.h
@@ -151,7 +151,9 @@ int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
__SALSA_EXPORT_FUNC
int snd_pcm_status(snd_pcm_t *pcm, snd_pcm_status_t *status)
{
- if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_STATUS, status) < 0)
+ int cmd = pcm->protocol < SNDRV_PROTOCOL_VERSION(2, 0, 13) ?
+ SNDRV_PCM_IOCTL_STATUS : SNDRV_PCM_IOCTL_STATUS_EXT;
+ if (ioctl(pcm->fd, cmd, status) < 0)
return -errno;
return 0;
}
@@ -1991,7 +1993,7 @@ __SALSA_EXPORT_FUNC
void snd_pcm_status_get_trigger_htstamp(const snd_pcm_status_t *obj,
snd_htimestamp_t *ptr)
{
- *ptr = obj->trigger_tstamp;
+ __copy_to_snd_htimestamp(&obj->trigger_tstamp, ptr);
}
__SALSA_EXPORT_FUNC
@@ -2004,13 +2006,13 @@ void snd_pcm_status_get_tstamp(const snd_pcm_status_t *obj, snd_timestamp_t *ptr
__SALSA_EXPORT_FUNC
void snd_pcm_status_get_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
{
- *ptr = obj->tstamp;
+ __copy_to_snd_htimestamp(&obj->tstamp, ptr);
}
__SALSA_EXPORT_FUNC
void snd_pcm_status_get_audio_htstamp(const snd_pcm_status_t *obj, snd_htimestamp_t *ptr)
{
- *ptr = obj->audio_tstamp;
+ __copy_to_snd_htimestamp(&obj->audio_tstamp, ptr);
}
__SALSA_EXPORT_FUNC
@@ -2136,7 +2138,7 @@ int snd_pcm_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail,
snd_htimestamp_t *tstamp)
{
*avail = snd_pcm_avail_update(pcm);
- *tstamp = pcm->mmap_status->tstamp;
+ __copy_to_snd_htimestamp(&pcm->mmap_status->tstamp, tstamp);
return 0;
}
diff --git a/src/rawmidi_macros.h b/src/rawmidi_macros.h
index c3146cc..f312016 100644
--- a/src/rawmidi_macros.h
+++ b/src/rawmidi_macros.h
@@ -243,7 +243,7 @@ __SALSA_EXPORT_FUNC
void snd_rawmidi_status_get_tstamp(const snd_rawmidi_status_t *obj,
snd_htimestamp_t *ptr)
{
- *ptr = obj->tstamp;
+ __copy_to_snd_htimestamp(&obj->tstamp, ptr);
}
__SALSA_EXPORT_FUNC
diff --git a/src/recipe.h.in b/src/recipe.h.in
index 620745f..e1e0815 100644
--- a/src/recipe.h.in
+++ b/src/recipe.h.in
@@ -34,6 +34,9 @@
/* Support ASCII value parser for ctl */
#define SALSA_CTL_ASCII_PARSER @SALSA_CTL_ASCII_PARSER@
+/* Use 64bit time */
+#define SALSA_STRUCT_TIME64 @SALSA_STRUCT_TIME64@
+
/* Default device path prefix */
#define SALSA_DEVPATH "@DEVPATH@"
diff --git a/src/timer_macros.h b/src/timer_macros.h
index 1cd37be..5b6a286 100644
--- a/src/timer_macros.h
+++ b/src/timer_macros.h
@@ -368,7 +368,7 @@ __snd_define_type(snd_timer_status);
__SALSA_EXPORT_FUNC
snd_htimestamp_t snd_timer_status_get_timestamp(snd_timer_status_t * status)
{
- return status->tstamp;
+ return __to_snd_htimestamp(&status->tstamp);
}
__SALSA_EXPORT_FUNC