diff --git a/0064-ucm-parser-cosmetic-fixes-in-the-comments.patch b/0064-ucm-parser-cosmetic-fixes-in-the-comments.patch new file mode 100644 index 0000000..aa52c10 --- /dev/null +++ b/0064-ucm-parser-cosmetic-fixes-in-the-comments.patch @@ -0,0 +1,103 @@ +From 7d3fec6ac68de0244621ae0aca7474d159336639 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 17 Jan 2020 18:21:08 +0100 +Subject: [PATCH 64/74] ucm: parser - cosmetic fixes in the comments + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 63 ++++++++++++++++++++++++++++---------------------------- + 1 file changed, 31 insertions(+), 32 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index 6c13fafdabbf..6c5d29026e5e 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -676,42 +676,41 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, + /* + * Parse Modifier Use cases + * +- * # Each modifier is described in new section. N modifiers are allowed +- * SectionModifier."Capture Voice" { ++ * # Each modifier is described in new section. N modifiers are allowed ++ * SectionModifier."Capture Voice" { + * +- * Comment "Record voice call" ++ * Comment "Record voice call" + * +- * SupportedDevice [ +- * "x" +- * "y" +- * ] +- * +- * ConflictingDevice [ +- * "x" +- * "y" +- * ] ++ * SupportedDevice [ ++ * "x" ++ * "y" ++ * ] + * +- * EnableSequence [ +- * .... +- * ] ++ * ConflictingDevice [ ++ * "x" ++ * "y" ++ * ] + * +- * DisableSequence [ +- * ... +- * ] ++ * EnableSequence [ ++ * .... ++ * ] + * +- * TransitionSequence."ToModifierName" [ +- * ... +- * ] ++ * DisableSequence [ ++ * ... ++ * ] + * +- * # Optional TQ and ALSA PCMs +- * Value { +- * TQ Voice +- * CapturePCM "hw:1" +- * PlaybackVolume "name='Master Playback Volume',index=2" +- * PlaybackSwitch "name='Master Playback Switch',index=2" +- * } ++ * TransitionSequence."ToModifierName" [ ++ * ... ++ * ] + * +- * } ++ * # Optional TQ and ALSA PCMs ++ * Value { ++ * TQ Voice ++ * CapturePCM "hw:1" ++ * PlaybackVolume "name='Master Playback Volume',index=2" ++ * PlaybackSwitch "name='Master Playback Switch',index=2" ++ * } ++ * } + * + * SupportedDevice and ConflictingDevice cannot be specified together. + * Both are optional. +@@ -836,11 +835,11 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr, + /* + * Parse Device Use Cases + * +- *# Each device is described in new section. N devices are allowed +- *SectionDevice."Headphones" { ++ * # Each device is described in new section. N devices are allowed ++ * SectionDevice."Headphones" { + * Comment "Headphones connected to 3.5mm jack" + * +- * upportedDevice [ ++ * SupportedDevice [ + * "x" + * "y" + * ] +-- +2.16.4 + diff --git a/0065-configure.ac-remove-an-unnecessary-libtool-fix.patch b/0065-configure.ac-remove-an-unnecessary-libtool-fix.patch new file mode 100644 index 0000000..053c6f0 --- /dev/null +++ b/0065-configure.ac-remove-an-unnecessary-libtool-fix.patch @@ -0,0 +1,53 @@ +From b2fe99277a73ec80eac0bd221672dd4aa02defa7 Mon Sep 17 00:00:00 2001 +From: Tanu Kaskinen +Date: Fri, 20 Dec 2019 09:26:12 +0200 +Subject: [PATCH 65/74] configure.ac: remove an unnecessary libtool fix + +This code was added in commit 75d393a563efb578c79364a277087c6326267f52 +without explaining why. I assume it was a mistake, since it looks like +the libtool problem should have gone away a long time ago. The referenced +wiki page https://wiki.debian.org/RpathIssue says: + + Since libtool 1.5.2 (released 2004-01-25), on Linux libtool no + longer sets RPATH for any directories in the dynamic linker search + path, so this should no longer be an issue unless upstream used a + really old version of libtool when creating their distribution + tarball. + +This code caused problems in OpenEmbedded, where the libtool script is +named "x86_64-oe-linux-libtool" or similar rather than just "libtool", +so the sed command failed with a file not found error. Rather than +adapting the code to OpenEmbedded's peculiarities, it seems best to just +remove the unnecessary code altogether. + +Note: The rpath is set (hardcoded) for 'make' but it is corrected +for 'make install' by libtool. + +Signed-off-by: Tanu Kaskinen +Signed-off-by: Jaroslav Kysela +--- + configure.ac | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 886f87bc4458..fb60c03086da 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -765,14 +765,3 @@ test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h + test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h + test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h + cat "$srcdir"/include/asoundlib-tail.h >> include/asoundlib.h +- +-dnl Taken from https://wiki.debian.org/RpathIssue +-case $host in +- *-*-linux-gnu) +- AC_MSG_RESULT([Fixing libtool for -rpath problems.]) +- sed < libtool > libtool-2 \ +- 's/^hardcode_libdir_flag_spec.*$'/'hardcode_libdir_flag_spec=" -D__LIBTOOL_IS_A_FOOL__ "/' +- mv libtool-2 libtool +- chmod 755 libtool +- ;; +-esac +-- +2.16.4 + diff --git a/0066-ucm-parser-use-correct-filename-in-parser_master_fil.patch b/0066-ucm-parser-use-correct-filename-in-parser_master_fil.patch new file mode 100644 index 0000000..7ccdf29 --- /dev/null +++ b/0066-ucm-parser-use-correct-filename-in-parser_master_fil.patch @@ -0,0 +1,38 @@ +From c5a09b0feaf759957dfac2c797b652781a0d41fe Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 3 Feb 2020 14:44:13 +0100 +Subject: [PATCH 66/74] ucm: parser - use correct filename in + parser_master_file() + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index 6c5d29026e5e..dbbd381755b1 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1413,16 +1413,16 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg) + if (uc_mgr->conf_format >= 2) { + err = snd_config_search(cfg, "Syntax", &n); + if (err < 0) { +- uc_error("Syntax field not found in %s", uc_mgr->conf_dir_name); ++ uc_error("Syntax field not found in %s", uc_mgr->conf_file_name); + return -EINVAL; + } + err = snd_config_get_integer(n, &l); + if (err < 0) { +- uc_error("Syntax field is invalid in %s", uc_mgr->conf_dir_name); ++ uc_error("Syntax field is invalid in %s", uc_mgr->conf_file_name); + return err; + } + if (l < 2 || l > SYNTAX_VERSION_MAX) { +- uc_error("Incompatible syntax %d in %s", l, uc_mgr->conf_dir_name); ++ uc_error("Incompatible syntax %d in %s", l, uc_mgr->conf_file_name); + return -EINVAL; + } + /* delete this field to avoid strcmp() call in the loop */ +-- +2.16.4 + diff --git a/0067-ucm-the-ucm2-subdirectory-is-driver-name-based.patch b/0067-ucm-the-ucm2-subdirectory-is-driver-name-based.patch new file mode 100644 index 0000000..27e8560 --- /dev/null +++ b/0067-ucm-the-ucm2-subdirectory-is-driver-name-based.patch @@ -0,0 +1,59 @@ +From 71a1367bcabc50f99302d8c76395f1cb84975775 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 3 Feb 2020 15:24:19 +0100 +Subject: [PATCH 67/74] ucm: the ucm2/ subdirectory is driver name based + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index dbbd381755b1..f576fde429cf 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1515,7 +1515,7 @@ static int get_card_long_name(snd_use_case_mgr_t *mgr, char *longname) + int card, err; + snd_ctl_t *ctl; + snd_ctl_card_info_t *info; +- const char *_name, *_long_name; ++ const char *_driver, *_name, *_long_name; + + snd_ctl_card_info_alloca(&info); + +@@ -1535,9 +1535,11 @@ static int get_card_long_name(snd_use_case_mgr_t *mgr, char *longname) + err = get_card_info(mgr, name, &ctl, info); + + if (err == 0) { ++ _driver = snd_ctl_card_info_get_driver(info); + _name = snd_ctl_card_info_get_name(info); + _long_name = snd_ctl_card_info_get_longname(info); +- if (!strcmp(card_name, _name) || ++ if (!strcmp(card_name, _driver) || ++ !strcmp(card_name, _name) || + !strcmp(card_name, _long_name)) { + snd_strlcpy(longname, _long_name, MAX_CARD_LONG_NAME); + return 0; +@@ -1560,7 +1562,7 @@ static int get_by_card(snd_use_case_mgr_t *mgr, const char *ctl_name, char *long + { + snd_ctl_t *ctl; + snd_ctl_card_info_t *info; +- const char *_name, *_long_name; ++ const char *_driver, *_long_name; + int err; + + snd_ctl_card_info_alloca(&info); +@@ -1569,8 +1571,8 @@ static int get_by_card(snd_use_case_mgr_t *mgr, const char *ctl_name, char *long + if (err) + return err; + +- _name = snd_ctl_card_info_get_name(info); +- if (replace_string(&mgr->conf_dir_name, _name) == NULL) ++ _driver = snd_ctl_card_info_get_driver(info); ++ if (replace_string(&mgr->conf_dir_name, _driver) == NULL) + return -ENOMEM; + _long_name = snd_ctl_card_info_get_longname(info); + snd_strlcpy(longname, _long_name, MAX_CARD_LONG_NAME); +-- +2.16.4 + diff --git a/0068-ucm-implement-RenameDevice-and-RemoveDevice-verb-man.patch b/0068-ucm-implement-RenameDevice-and-RemoveDevice-verb-man.patch new file mode 100644 index 0000000..a35d860 --- /dev/null +++ b/0068-ucm-implement-RenameDevice-and-RemoveDevice-verb-man.patch @@ -0,0 +1,393 @@ +From 251bc204a1e7f1bf1d12b452f2b62e15543bba94 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 7 Feb 2020 10:09:07 +0100 +Subject: [PATCH 68/74] ucm: implement RenameDevice and RemoveDevice verb + management + +With the conditionals, it may be useful to define the devices +in the included configuration files. To satisfy the specification +requirements (device naming) those device names might require +to be renamed or deleted wrong references from the conflicting +or supported lists. + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++- + src/ucm/ucm_local.h | 15 ++++++ + src/ucm/utils.c | 123 ++++++++++++++++++++++++++++++++++++++++++++----- + 3 files changed, 254 insertions(+), 13 deletions(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index f576fde429cf..f9a8f6283c3a 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -985,6 +985,71 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr, + return 0; + } + ++/* ++ * Parse Device Rename/Delete Command ++ * ++ * # The devices might be renamed to allow the better conditional runtime ++ * # evaluation. Bellow example renames Speaker1 device to Speaker and ++ * # removes Speaker2 device. ++ * RenameDevice."Speaker1" "Speaker" ++ * RemoveDevice."Speaker2" "Speaker2" ++ */ ++static int parse_dev_name_list(snd_config_t *cfg, ++ struct list_head *list) ++{ ++ snd_config_t *n; ++ snd_config_iterator_t i, next; ++ const char *id, *name1; ++ char *name2; ++ struct ucm_dev_name *dev; ++ snd_config_iterator_t pos; ++ int err; ++ ++ if (snd_config_get_id(cfg, &id) < 0) ++ return -EINVAL; ++ ++ if (snd_config_get_type(cfg) != SND_CONFIG_TYPE_COMPOUND) { ++ uc_error("compound type expected for %s", id); ++ return -EINVAL; ++ } ++ ++ snd_config_for_each(i, next, cfg) { ++ n = snd_config_iterator_entry(i); ++ ++ if (snd_config_get_id(n, &name1) < 0) ++ return -EINVAL; ++ ++ err = parse_string(n, &name2); ++ if (err < 0) { ++ uc_error("error: failed to get target device name for '%s'", name1); ++ return err; ++ } ++ ++ /* skip duplicates */ ++ list_for_each(pos, list) { ++ dev = list_entry(pos, struct ucm_dev_name, list); ++ if (strcmp(dev->name1, name1) == 0) { ++ free(name2); ++ return 0; ++ } ++ } ++ ++ dev = calloc(1, sizeof(*dev)); ++ if (dev == NULL) ++ return -ENOMEM; ++ dev->name1 = strdup(name1); ++ if (dev->name1 == NULL) { ++ free(dev); ++ free(name2); ++ return -ENOMEM; ++ } ++ dev->name2 = name2; ++ list_add_tail(&dev->list, list); ++ } ++ ++ return 0; ++} ++ + static int parse_compound_check_legacy(snd_use_case_mgr_t *uc_mgr, + snd_config_t *cfg, + int (*fcn)(snd_use_case_mgr_t *, snd_config_t *, void *, void *), +@@ -1044,7 +1109,39 @@ static int parse_modifier_name(snd_use_case_mgr_t *uc_mgr, + void *data1, + void *data2 ATTRIBUTE_UNUSED) + { +- return parse_compound_check_legacy(uc_mgr, cfg, parse_modifier, data1); ++ return parse_compound(uc_mgr, cfg, parse_modifier, data1, data2); ++} ++ ++static int verb_device_management(struct use_case_verb *verb) ++{ ++ struct list_head *pos; ++ struct ucm_dev_name *dev; ++ int err; ++ ++ /* rename devices */ ++ list_for_each(pos, &verb->rename_list) { ++ dev = list_entry(pos, struct ucm_dev_name, list); ++ err = uc_mgr_rename_device(verb, dev->name1, dev->name2); ++ if (err < 0) { ++ uc_error("error: cannot rename device '%s' to '%s'", dev->name1, dev->name2); ++ return err; ++ } ++ } ++ ++ /* remove devices */ ++ list_for_each(pos, &verb->rename_list) { ++ dev = list_entry(pos, struct ucm_dev_name, list); ++ err = uc_mgr_remove_device(verb, dev->name2); ++ if (err < 0) { ++ uc_error("error: cannot remove device '%s'", dev->name2); ++ return err; ++ } ++ } ++ ++ /* those lists are no longer used */ ++ uc_mgr_free_dev_name_list(&verb->rename_list); ++ uc_mgr_free_dev_name_list(&verb->remove_list); ++ return 0; + } + + /* +@@ -1180,6 +1277,8 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + INIT_LIST_HEAD(&verb->cmpt_device_list); + INIT_LIST_HEAD(&verb->modifier_list); + INIT_LIST_HEAD(&verb->value_list); ++ INIT_LIST_HEAD(&verb->rename_list); ++ INIT_LIST_HEAD(&verb->remove_list); + list_add_tail(&verb->list, &uc_mgr->verb_list); + if (use_case_name == NULL) + return -EINVAL; +@@ -1249,6 +1348,26 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + } + continue; + } ++ ++ /* device renames */ ++ if (strcmp(id, "RenameDevice") == 0) { ++ err = parse_dev_name_list(n, &verb->rename_list); ++ if (err < 0) { ++ uc_error("error: %s failed to parse device rename", ++ file); ++ goto _err; ++ } ++ } ++ ++ /* device remove */ ++ if (strcmp(id, "RemoveDevice") == 0) { ++ err = parse_dev_name_list(n, &verb->remove_list); ++ if (err < 0) { ++ uc_error("error: %s failed to parse device remove", ++ file); ++ goto _err; ++ } ++ } + } + + snd_config_delete(cfg); +@@ -1258,6 +1377,14 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr, + uc_error("error: no use case device defined", file); + return -EINVAL; + } ++ ++ /* do device rename and delete */ ++ err = verb_device_management(verb); ++ if (err < 0) { ++ uc_error("error: device management error in verb '%s'", verb->name); ++ return err; ++ } ++ + return 0; + + _err: +diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h +index fa9fc16661bb..ba8d2acb3355 100644 +--- a/src/ucm/ucm_local.h ++++ b/src/ucm/ucm_local.h +@@ -117,6 +117,12 @@ struct ctl_list { + snd_ctl_card_info_t *ctl_info; + }; + ++struct ucm_dev_name { ++ struct list_head list; ++ char *name1; ++ char *name2; ++}; ++ + /* + * Describes a Use Case Modifier and it's enable and disable sequences. + * A use case verb can have N modifiers. +@@ -196,6 +202,10 @@ struct use_case_verb { + + /* value list */ + struct list_head value_list; ++ ++ /* temporary modifications lists */ ++ struct list_head rename_list; ++ struct list_head remove_list; + }; + + /* +@@ -252,6 +262,11 @@ int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg); + int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr); + int uc_mgr_scan_master_configs(const char **_list[]); + ++int uc_mgr_remove_device(struct use_case_verb *verb, const char *name); ++int uc_mgr_rename_device(struct use_case_verb *verb, const char *src, ++ const char *dst); ++ ++void uc_mgr_free_dev_name_list(struct list_head *base); + void uc_mgr_free_sequence_element(struct sequence_element *seq); + void uc_mgr_free_transition_element(struct transition_sequence *seq); + void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr); +diff --git a/src/ucm/utils.c b/src/ucm/utils.c +index daa568c16a30..60a591725835 100644 +--- a/src/ucm/utils.c ++++ b/src/ucm/utils.c +@@ -328,6 +328,44 @@ void uc_mgr_free_dev_list(struct dev_list *dev_list) + } + } + ++int uc_mgr_rename_in_dev_list(struct dev_list *dev_list, const char *src, ++ const char *dst) ++{ ++ struct list_head *pos; ++ struct dev_list_node *dlist; ++ char *dst1; ++ ++ list_for_each(pos, &dev_list->list) { ++ dlist = list_entry(pos, struct dev_list_node, list); ++ if (strcmp(dlist->name, src) == 0) { ++ dst1 = strdup(dst); ++ if (dst1 == NULL) ++ return -ENOMEM; ++ free(dlist->name); ++ dlist->name = dst1; ++ return 0; ++ } ++ } ++ return -ENOENT; ++} ++ ++int uc_mgr_remove_from_dev_list(struct dev_list *dev_list, const char *name) ++{ ++ struct list_head *pos; ++ struct dev_list_node *dlist; ++ ++ list_for_each(pos, &dev_list->list) { ++ dlist = list_entry(pos, struct dev_list_node, list); ++ if (strcmp(dlist->name, name) == 0) { ++ free(dlist->name); ++ list_del(&dlist->list); ++ free(dlist); ++ return 0; ++ } ++ } ++ return -ENODEV; ++} ++ + void uc_mgr_free_sequence_element(struct sequence_element *seq) + { + if (seq == NULL) +@@ -381,6 +419,20 @@ void uc_mgr_free_transition(struct list_head *base) + } + } + ++void uc_mgr_free_dev_name_list(struct list_head *base) ++{ ++ struct list_head *pos, *npos; ++ struct ucm_dev_name *dev; ++ ++ list_for_each_safe(pos, npos, base) { ++ dev = list_entry(pos, struct ucm_dev_name, list); ++ list_del(&dev->list); ++ free(dev->name1); ++ free(dev->name2); ++ free(dev); ++ } ++} ++ + void uc_mgr_free_modifier(struct list_head *base) + { + struct list_head *pos, *npos; +@@ -400,23 +452,68 @@ void uc_mgr_free_modifier(struct list_head *base) + } + } + +-void uc_mgr_free_device(struct list_head *base) ++void uc_mgr_free_device(struct use_case_device *dev) ++{ ++ free(dev->name); ++ free(dev->comment); ++ uc_mgr_free_sequence(&dev->enable_list); ++ uc_mgr_free_sequence(&dev->disable_list); ++ uc_mgr_free_transition(&dev->transition_list); ++ uc_mgr_free_dev_list(&dev->dev_list); ++ uc_mgr_free_value(&dev->value_list); ++ list_del(&dev->list); ++ free(dev); ++} ++ ++void uc_mgr_free_device_list(struct list_head *base) + { + struct list_head *pos, *npos; + struct use_case_device *dev; + + list_for_each_safe(pos, npos, base) { + dev = list_entry(pos, struct use_case_device, list); +- free(dev->name); +- free(dev->comment); +- uc_mgr_free_sequence(&dev->enable_list); +- uc_mgr_free_sequence(&dev->disable_list); +- uc_mgr_free_transition(&dev->transition_list); +- uc_mgr_free_dev_list(&dev->dev_list); +- uc_mgr_free_value(&dev->value_list); +- list_del(&dev->list); +- free(dev); ++ uc_mgr_free_device(dev); ++ } ++} ++ ++int uc_mgr_rename_device(struct use_case_verb *verb, const char *src, ++ const char *dst) ++{ ++ struct use_case_device *device; ++ struct list_head *pos, *npos; ++ char *dst1; ++ ++ /* no errors when device is not found */ ++ list_for_each_safe(pos, npos, &verb->device_list) { ++ device = list_entry(pos, struct use_case_device, list); ++ if (strcmp(device->name, src) == 0) { ++ dst1 = strdup(dst); ++ if (dst1 == NULL) ++ return -ENOMEM; ++ free(device->name); ++ device->name = dst1; ++ continue; ++ } ++ uc_mgr_rename_in_dev_list(&device->dev_list, src, dst); ++ } ++ return 0; ++} ++ ++int uc_mgr_remove_device(struct use_case_verb *verb, const char *name) ++{ ++ struct use_case_device *device; ++ struct list_head *pos, *npos; ++ ++ list_for_each_safe(pos, npos, &verb->device_list) { ++ device = list_entry(pos, struct use_case_device, list); ++ if (strcmp(device->name, name) == 0) { ++ uc_mgr_free_device(device); ++ continue; ++ } ++ uc_mgr_remove_from_dev_list(&device->dev_list, name); ++ return 0; + } ++ return -ENOENT; + } + + void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr) +@@ -432,9 +529,11 @@ void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr) + uc_mgr_free_sequence(&verb->disable_list); + uc_mgr_free_transition(&verb->transition_list); + uc_mgr_free_value(&verb->value_list); +- uc_mgr_free_device(&verb->device_list); +- uc_mgr_free_device(&verb->cmpt_device_list); ++ uc_mgr_free_device_list(&verb->device_list); ++ uc_mgr_free_device_list(&verb->cmpt_device_list); + uc_mgr_free_modifier(&verb->modifier_list); ++ uc_mgr_free_dev_name_list(&verb->rename_list); ++ uc_mgr_free_dev_name_list(&verb->remove_list); + list_del(&verb->list); + free(verb); + } +-- +2.16.4 + diff --git a/0069-ucm-fill-missing-device-entries-conflicting-supporte.patch b/0069-ucm-fill-missing-device-entries-conflicting-supporte.patch new file mode 100644 index 0000000..246d068 --- /dev/null +++ b/0069-ucm-fill-missing-device-entries-conflicting-supporte.patch @@ -0,0 +1,135 @@ +From fdf96312fa3c9261db2954afcde8c6a15d2ebe44 Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Fri, 7 Feb 2020 16:18:11 +0100 +Subject: [PATCH 69/74] ucm: fill missing device entries (conflicting / + supported) + +It is not necessary to maintain this information in sync in the configuration +files. Fill the missing entries to the complementary devices. + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- + src/ucm/ucm_local.h | 1 + + src/ucm/utils.c | 25 +++++++++++++++++++++++++ + 3 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index f9a8f6283c3a..23bf6a63f31e 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1112,6 +1112,52 @@ static int parse_modifier_name(snd_use_case_mgr_t *uc_mgr, + return parse_compound(uc_mgr, cfg, parse_modifier, data1, data2); + } + ++static int verb_dev_list_add(struct use_case_verb *verb, ++ enum dev_list_type dst_type, ++ const char *dst, ++ const char *src) ++{ ++ struct use_case_device *device; ++ struct list_head *pos; ++ ++ list_for_each(pos, &verb->device_list) { ++ device = list_entry(pos, struct use_case_device, list); ++ if (strcmp(device->name, dst) != 0) ++ continue; ++ if (device->dev_list.type != dst_type) { ++ if (list_empty(&device->dev_list.list)) { ++ device->dev_list.type = dst_type; ++ } else { ++ uc_error("error: incompatible device list type ('%s', '%s')", ++ device->name, src); ++ return -EINVAL; ++ } ++ } ++ return uc_mgr_put_to_dev_list(&device->dev_list, src); ++ } ++ return -ENOENT; ++} ++ ++static int verb_dev_list_check(struct use_case_verb *verb) ++{ ++ struct list_head *pos, *pos2; ++ struct use_case_device *device; ++ struct dev_list_node *dlist; ++ int err; ++ ++ list_for_each(pos, &verb->device_list) { ++ device = list_entry(pos, struct use_case_device, list); ++ list_for_each(pos2, &device->dev_list.list) { ++ dlist = list_entry(pos2, struct dev_list_node, list); ++ err = verb_dev_list_add(verb, device->dev_list.type, ++ dlist->name, device->name); ++ if (err < 0) ++ return err; ++ } ++ } ++ return 0; ++} ++ + static int verb_device_management(struct use_case_verb *verb) + { + struct list_head *pos; +@@ -1141,7 +1187,9 @@ static int verb_device_management(struct use_case_verb *verb) + /* those lists are no longer used */ + uc_mgr_free_dev_name_list(&verb->rename_list); + uc_mgr_free_dev_name_list(&verb->remove_list); +- return 0; ++ ++ /* handle conflicting/supported lists */ ++ return verb_dev_list_check(verb); + } + + /* +diff --git a/src/ucm/ucm_local.h b/src/ucm/ucm_local.h +index ba8d2acb3355..acec4bf67e30 100644 +--- a/src/ucm/ucm_local.h ++++ b/src/ucm/ucm_local.h +@@ -262,6 +262,7 @@ int uc_mgr_config_load(int format, const char *file, snd_config_t **cfg); + int uc_mgr_import_master_config(snd_use_case_mgr_t *uc_mgr); + int uc_mgr_scan_master_configs(const char **_list[]); + ++int uc_mgr_put_to_dev_list(struct dev_list *dev_list, const char *name); + int uc_mgr_remove_device(struct use_case_verb *verb, const char *name); + int uc_mgr_rename_device(struct use_case_verb *verb, const char *src, + const char *dst); +diff --git a/src/ucm/utils.c b/src/ucm/utils.c +index 60a591725835..50b2a1df4a6a 100644 +--- a/src/ucm/utils.c ++++ b/src/ucm/utils.c +@@ -328,6 +328,31 @@ void uc_mgr_free_dev_list(struct dev_list *dev_list) + } + } + ++int uc_mgr_put_to_dev_list(struct dev_list *dev_list, const char *name) ++{ ++ struct list_head *pos; ++ struct dev_list_node *dlist; ++ char *n; ++ ++ list_for_each(pos, &dev_list->list) { ++ dlist = list_entry(pos, struct dev_list_node, list); ++ if (strcmp(dlist->name, name) == 0) ++ return 0; ++ } ++ ++ dlist = calloc(1, sizeof(*dlist)); ++ if (dlist == NULL) ++ return -ENOMEM; ++ n = strdup(name); ++ if (n == NULL) { ++ free(dlist); ++ return -ENOMEM; ++ } ++ dlist->name = n; ++ list_add(&dlist->list, &dev_list->list); ++ return 0; ++} ++ + int uc_mgr_rename_in_dev_list(struct dev_list *dev_list, const char *src, + const char *dst) + { +-- +2.16.4 + diff --git a/0070-control-Remove-access-to-the-deprecated-dimen-fields.patch b/0070-control-Remove-access-to-the-deprecated-dimen-fields.patch new file mode 100644 index 0000000..e7dec46 --- /dev/null +++ b/0070-control-Remove-access-to-the-deprecated-dimen-fields.patch @@ -0,0 +1,110 @@ +From 43e137c06451bbdd7998ec5bef20ef82d9f4e5a7 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 10 Feb 2020 12:47:19 +0100 +Subject: [PATCH 70/74] control: Remove access to the deprecated dimen fields + +The dimen fields of control element has been deprecated, and it's +finally dropped in kernel 5.6 ABI definition. Remove the +corresponding accesses in alsa-lib code. + +As of this patch, it's disabled via ifdef, just to be sure. The +disabled code should be removed in a later stage as a cleanup. + +Signed-off-by: Takashi Iwai +--- + src/control/control.c | 24 ++++++++++++++++++++---- + 1 file changed, 20 insertions(+), 4 deletions(-) + +diff --git a/src/control/control.c b/src/control/control.c +index 33650155cac7..27f421350fb7 100644 +--- a/src/control/control.c ++++ b/src/control/control.c +@@ -303,6 +303,7 @@ int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info) + return ctl->ops->element_info(ctl, info); + } + ++#if 0 /* deprecated */ + static bool validate_element_member_dimension(snd_ctl_elem_info_t *info) + { + unsigned int members; +@@ -328,6 +329,9 @@ static bool validate_element_member_dimension(snd_ctl_elem_info_t *info) + + return members == info->count; + } ++#else /* deprecated */ ++#define validate_element_member_dimension(info) true ++#endif /* deprecated */ + + /** + * \brief Create and add some user-defined control elements of integer type. +@@ -2510,11 +2514,12 @@ const char *snd_ctl_elem_info_get_item_name(const snd_ctl_elem_info_t *obj) + * #snd_ctl_elem_info_get_dimensions is deprecated without any replacement. + */ + #ifndef DOXYGEN +-EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj) ++EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimensions)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED) + #else + int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj) + #endif + { ++#if 0 /* deprecated */ + int i; + + assert(obj); +@@ -2522,6 +2527,9 @@ int snd_ctl_elem_info_get_dimensions(const snd_ctl_elem_info_t *obj) + if (obj->dimen.d[i]) + break; + return i + 1; ++#else ++ return -EINVAL; ++#endif + } + use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info_get_dimensions, ALSA_0.9.3); + +@@ -2535,15 +2543,19 @@ use_default_symbol_version(__snd_ctl_elem_info_get_dimensions, snd_ctl_elem_info + * #snd_ctl_elem_info_get_dimension is deprecated without any replacement. + */ + #ifndef DOXYGEN +-EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj, unsigned int idx) ++EXPORT_SYMBOL int INTERNAL(snd_ctl_elem_info_get_dimension)(const snd_ctl_elem_info_t *obj ATTRIBUTE_UNUSED, unsigned int idx ATTRIBUTE_UNUSED) + #else + int snd_ctl_elem_info_get_dimension(const snd_ctl_elem_info_t *obj, unsigned int idx) + #endif + { ++#if 0 /* deprecated */ + assert(obj); + if (idx > 3) + return 0; + return obj->dimen.d[idx]; ++#else /* deprecated */ ++ return -EINVAL; ++#endif /* deprecated */ + } + use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_get_dimension, ALSA_0.9.3); + +@@ -2565,9 +2577,10 @@ use_default_symbol_version(__snd_ctl_elem_info_get_dimension, snd_ctl_elem_info_ + * \deprecated Since 1.1.5 + * #snd_ctl_elem_info_set_dimension is deprecated without any replacement. + */ +-int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info, +- const int dimension[4]) ++int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info ATTRIBUTE_UNUSED, ++ const int dimension[4] ATTRIBUTE_UNUSED) + { ++#if 0 /* deprecated */ + unsigned int i; + + if (info == NULL) +@@ -2581,6 +2594,9 @@ int snd_ctl_elem_info_set_dimension(snd_ctl_elem_info_t *info, + } + + return 0; ++#else /* deprecated */ ++ return -EINVAL; ++#endif /* deprecated */ + } + + /** +-- +2.16.4 + diff --git a/0071-topology-Drop-SNDRV_CTL_ELEM_ACCESS_TIMESTAMP-access.patch b/0071-topology-Drop-SNDRV_CTL_ELEM_ACCESS_TIMESTAMP-access.patch new file mode 100644 index 0000000..53430eb --- /dev/null +++ b/0071-topology-Drop-SNDRV_CTL_ELEM_ACCESS_TIMESTAMP-access.patch @@ -0,0 +1,29 @@ +From beb6b178e6d0ca4a9b6c528bac9bfa899b733462 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 10 Feb 2020 12:49:25 +0100 +Subject: [PATCH 71/74] topology: Drop SNDRV_CTL_ELEM_ACCESS_TIMESTAMP access + +SNDRV_CTL_ELEM_ACCESS_TIMESTAMP is removed from 5.6 kernel ABI as the +ctl timestamp field has been never used and deprecated. +Drop the corresponding access from the topology code, too. + +Signed-off-by: Takashi Iwai +--- + src/topology/ctl.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/topology/ctl.c b/src/topology/ctl.c +index b78f1c54be05..90241b6318c5 100644 +--- a/src/topology/ctl.c ++++ b/src/topology/ctl.c +@@ -35,7 +35,6 @@ static const struct ctl_access_elem ctl_access[] = { + {"read", SNDRV_CTL_ELEM_ACCESS_READ}, + {"write", SNDRV_CTL_ELEM_ACCESS_WRITE}, + {"volatile", SNDRV_CTL_ELEM_ACCESS_VOLATILE}, +- {"timestamp", SNDRV_CTL_ELEM_ACCESS_TIMESTAMP}, + {"tlv_read", SNDRV_CTL_ELEM_ACCESS_TLV_READ}, + {"tlv_write", SNDRV_CTL_ELEM_ACCESS_TLV_WRITE}, + {"tlv_command", SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND}, +-- +2.16.4 + diff --git a/0072-uapi-Sync-with-5.6-kernel-ABI.patch b/0072-uapi-Sync-with-5.6-kernel-ABI.patch new file mode 100644 index 0000000..f52e24d --- /dev/null +++ b/0072-uapi-Sync-with-5.6-kernel-ABI.patch @@ -0,0 +1,721 @@ +From 5bbe8b2fb90e78d6ff35eeddbc2b579b8e05cd8f Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 10 Feb 2020 12:50:50 +0100 +Subject: [PATCH 72/74] uapi: Sync with 5.6 kernel ABI + +This is a sync with 5.6-rc1 kernel headers. The copy is performed +from the sanitized headers installed via make headers_install. + +Signed-off-by: Takashi Iwai +--- + include/sound/uapi/asequencer.h | 12 +- + include/sound/uapi/asoc.h | 9 +- + include/sound/uapi/asound.h | 319 ++++++++++++++++++++++++++-------------- + include/sound/uapi/emu10k1.h | 12 +- + include/sound/uapi/hdsp.h | 4 + + include/sound/uapi/hdspm.h | 4 + + include/sound/uapi/sb16_csp.h | 6 +- + 7 files changed, 235 insertions(+), 131 deletions(-) + +diff --git a/include/sound/uapi/asequencer.h b/include/sound/uapi/asequencer.h +index a75e14edc957..2d600320e2ae 100644 +--- a/include/sound/uapi/asequencer.h ++++ b/include/sound/uapi/asequencer.h +@@ -20,8 +20,8 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +-#ifndef _UAPI__SOUND_ASEQUENCER_H +-#define _UAPI__SOUND_ASEQUENCER_H ++#ifndef __SOUND_ASEQUENCER_H ++#define __SOUND_ASEQUENCER_H + + #include + +@@ -339,9 +339,9 @@ struct snd_seq_running_info { + + /* client types */ + typedef int __bitwise snd_seq_client_type_t; +-#define NO_CLIENT ((__force snd_seq_client_type_t) 0) +-#define USER_CLIENT ((__force snd_seq_client_type_t) 1) +-#define KERNEL_CLIENT ((__force snd_seq_client_type_t) 2) ++#define NO_CLIENT ((snd_seq_client_type_t) 0) ++#define USER_CLIENT ((snd_seq_client_type_t) 1) ++#define KERNEL_CLIENT ((snd_seq_client_type_t) 2) + + /* event filter flags */ + #define SNDRV_SEQ_FILTER_BROADCAST (1<<0) /* accept broadcast messages */ +@@ -609,4 +609,4 @@ struct snd_seq_query_subs { + #define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct snd_seq_client_info) + #define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct snd_seq_port_info) + +-#endif /* _UAPI__SOUND_ASEQUENCER_H */ ++#endif /* __SOUND_ASEQUENCER_H */ +diff --git a/include/sound/uapi/asoc.h b/include/sound/uapi/asoc.h +index a74ca232f1fc..4efb4ec42500 100644 +--- a/include/sound/uapi/asoc.h ++++ b/include/sound/uapi/asoc.h +@@ -17,7 +17,6 @@ + #define __LINUX_UAPI_SND_ASOC_H + + #include +-#include + + /* + * Maximum number of channels topology kcontrol can represent. +@@ -587,7 +586,7 @@ struct snd_soc_tplg_manifest_v4 { + __le32 pcm_elems; /* number of PCM elements */ + __le32 dai_link_elems; /* number of DAI link elements */ + struct snd_soc_tplg_private priv; +-} __packed; ++} __attribute__((packed)); + + /* Stream Capabilities v4 */ + struct snd_soc_tplg_stream_caps_v4 { +@@ -605,7 +604,7 @@ struct snd_soc_tplg_stream_caps_v4 { + __le32 period_size_max; /* max period size bytes */ + __le32 buffer_size_min; /* min buffer size bytes */ + __le32 buffer_size_max; /* max buffer size bytes */ +-} __packed; ++} __attribute__((packed)); + + /* PCM v4 */ + struct snd_soc_tplg_pcm_v4 { +@@ -620,7 +619,7 @@ struct snd_soc_tplg_pcm_v4 { + struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */ + __le32 num_streams; /* number of streams */ + struct snd_soc_tplg_stream_caps_v4 caps[2]; /* playback and capture for DAI */ +-} __packed; ++} __attribute__((packed)); + + /* Physical link config v4 */ + struct snd_soc_tplg_link_config_v4 { +@@ -628,6 +627,6 @@ struct snd_soc_tplg_link_config_v4 { + __le32 id; /* unique ID - used to match */ + struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */ + __le32 num_streams; /* number of streams */ +-} __packed; ++} __attribute__((packed)); + + #endif +diff --git a/include/sound/uapi/asound.h b/include/sound/uapi/asound.h +index df1153cea0b7..ec610c270411 100644 +--- a/include/sound/uapi/asound.h ++++ b/include/sound/uapi/asound.h +@@ -21,19 +21,19 @@ + * + */ + +-#ifndef _UAPI__SOUND_ASOUND_H +-#define _UAPI__SOUND_ASOUND_H ++#ifndef __SOUND_ASOUND_H ++#define __SOUND_ASOUND_H + + #if defined(__KERNEL__) || defined(__linux__) + #include ++#include + #else ++#include + #include + #endif + +-#ifndef __KERNEL__ + #include + #include +-#endif + + /* + * protocol version +@@ -138,7 +138,7 @@ struct snd_hwdep_dsp_status { + struct snd_hwdep_dsp_image { + unsigned int index; /* W: DSP index */ + unsigned char name[64]; /* W: ID (e.g. file name) */ +- unsigned char __user *image; /* W: binary image */ ++ unsigned char *image; /* W: binary image */ + size_t length; /* W: size of image in bytes */ + unsigned long driver_data; /* W: driver-specific data */ + }; +@@ -154,7 +154,7 @@ struct snd_hwdep_dsp_image { + * * + *****************************************************************************/ + +-#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14) ++#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 15) + + typedef unsigned long snd_pcm_uframes_t; + typedef signed long snd_pcm_sframes_t; +@@ -182,66 +182,66 @@ enum { + }; + + typedef int __bitwise snd_pcm_access_t; +-#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((__force snd_pcm_access_t) 0) /* interleaved mmap */ +-#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((__force snd_pcm_access_t) 1) /* noninterleaved mmap */ +-#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((__force snd_pcm_access_t) 2) /* complex mmap */ +-#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((__force snd_pcm_access_t) 3) /* readi/writei */ +-#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((__force snd_pcm_access_t) 4) /* readn/writen */ ++#define SNDRV_PCM_ACCESS_MMAP_INTERLEAVED ((snd_pcm_access_t) 0) /* interleaved mmap */ ++#define SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED ((snd_pcm_access_t) 1) /* noninterleaved mmap */ ++#define SNDRV_PCM_ACCESS_MMAP_COMPLEX ((snd_pcm_access_t) 2) /* complex mmap */ ++#define SNDRV_PCM_ACCESS_RW_INTERLEAVED ((snd_pcm_access_t) 3) /* readi/writei */ ++#define SNDRV_PCM_ACCESS_RW_NONINTERLEAVED ((snd_pcm_access_t) 4) /* readn/writen */ + #define SNDRV_PCM_ACCESS_LAST SNDRV_PCM_ACCESS_RW_NONINTERLEAVED + + typedef int __bitwise snd_pcm_format_t; +-#define SNDRV_PCM_FORMAT_S8 ((__force snd_pcm_format_t) 0) +-#define SNDRV_PCM_FORMAT_U8 ((__force snd_pcm_format_t) 1) +-#define SNDRV_PCM_FORMAT_S16_LE ((__force snd_pcm_format_t) 2) +-#define SNDRV_PCM_FORMAT_S16_BE ((__force snd_pcm_format_t) 3) +-#define SNDRV_PCM_FORMAT_U16_LE ((__force snd_pcm_format_t) 4) +-#define SNDRV_PCM_FORMAT_U16_BE ((__force snd_pcm_format_t) 5) +-#define SNDRV_PCM_FORMAT_S24_LE ((__force snd_pcm_format_t) 6) /* low three bytes */ +-#define SNDRV_PCM_FORMAT_S24_BE ((__force snd_pcm_format_t) 7) /* low three bytes */ +-#define SNDRV_PCM_FORMAT_U24_LE ((__force snd_pcm_format_t) 8) /* low three bytes */ +-#define SNDRV_PCM_FORMAT_U24_BE ((__force snd_pcm_format_t) 9) /* low three bytes */ +-#define SNDRV_PCM_FORMAT_S32_LE ((__force snd_pcm_format_t) 10) +-#define SNDRV_PCM_FORMAT_S32_BE ((__force snd_pcm_format_t) 11) +-#define SNDRV_PCM_FORMAT_U32_LE ((__force snd_pcm_format_t) 12) +-#define SNDRV_PCM_FORMAT_U32_BE ((__force snd_pcm_format_t) 13) +-#define SNDRV_PCM_FORMAT_FLOAT_LE ((__force snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +-#define SNDRV_PCM_FORMAT_FLOAT_BE ((__force snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ +-#define SNDRV_PCM_FORMAT_FLOAT64_LE ((__force snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +-#define SNDRV_PCM_FORMAT_FLOAT64_BE ((__force snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ +-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((__force snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */ +-#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((__force snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */ +-#define SNDRV_PCM_FORMAT_MU_LAW ((__force snd_pcm_format_t) 20) +-#define SNDRV_PCM_FORMAT_A_LAW ((__force snd_pcm_format_t) 21) +-#define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) +-#define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) +-#define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) +-#define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25) /* in four bytes, LSB justified */ +-#define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26) /* in four bytes, LSB justified */ +-#define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27) /* in four bytes, LSB justified */ +-#define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28) /* in four bytes, LSB justified */ ++#define SNDRV_PCM_FORMAT_S8 ((snd_pcm_format_t) 0) ++#define SNDRV_PCM_FORMAT_U8 ((snd_pcm_format_t) 1) ++#define SNDRV_PCM_FORMAT_S16_LE ((snd_pcm_format_t) 2) ++#define SNDRV_PCM_FORMAT_S16_BE ((snd_pcm_format_t) 3) ++#define SNDRV_PCM_FORMAT_U16_LE ((snd_pcm_format_t) 4) ++#define SNDRV_PCM_FORMAT_U16_BE ((snd_pcm_format_t) 5) ++#define SNDRV_PCM_FORMAT_S24_LE ((snd_pcm_format_t) 6) /* low three bytes */ ++#define SNDRV_PCM_FORMAT_S24_BE ((snd_pcm_format_t) 7) /* low three bytes */ ++#define SNDRV_PCM_FORMAT_U24_LE ((snd_pcm_format_t) 8) /* low three bytes */ ++#define SNDRV_PCM_FORMAT_U24_BE ((snd_pcm_format_t) 9) /* low three bytes */ ++#define SNDRV_PCM_FORMAT_S32_LE ((snd_pcm_format_t) 10) ++#define SNDRV_PCM_FORMAT_S32_BE ((snd_pcm_format_t) 11) ++#define SNDRV_PCM_FORMAT_U32_LE ((snd_pcm_format_t) 12) ++#define SNDRV_PCM_FORMAT_U32_BE ((snd_pcm_format_t) 13) ++#define SNDRV_PCM_FORMAT_FLOAT_LE ((snd_pcm_format_t) 14) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++#define SNDRV_PCM_FORMAT_FLOAT_BE ((snd_pcm_format_t) 15) /* 4-byte float, IEEE-754 32-bit, range -1.0 to 1.0 */ ++#define SNDRV_PCM_FORMAT_FLOAT64_LE ((snd_pcm_format_t) 16) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++#define SNDRV_PCM_FORMAT_FLOAT64_BE ((snd_pcm_format_t) 17) /* 8-byte float, IEEE-754 64-bit, range -1.0 to 1.0 */ ++#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE ((snd_pcm_format_t) 18) /* IEC-958 subframe, Little Endian */ ++#define SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE ((snd_pcm_format_t) 19) /* IEC-958 subframe, Big Endian */ ++#define SNDRV_PCM_FORMAT_MU_LAW ((snd_pcm_format_t) 20) ++#define SNDRV_PCM_FORMAT_A_LAW ((snd_pcm_format_t) 21) ++#define SNDRV_PCM_FORMAT_IMA_ADPCM ((snd_pcm_format_t) 22) ++#define SNDRV_PCM_FORMAT_MPEG ((snd_pcm_format_t) 23) ++#define SNDRV_PCM_FORMAT_GSM ((snd_pcm_format_t) 24) ++#define SNDRV_PCM_FORMAT_S20_LE ((snd_pcm_format_t) 25) /* in four bytes, LSB justified */ ++#define SNDRV_PCM_FORMAT_S20_BE ((snd_pcm_format_t) 26) /* in four bytes, LSB justified */ ++#define SNDRV_PCM_FORMAT_U20_LE ((snd_pcm_format_t) 27) /* in four bytes, LSB justified */ ++#define SNDRV_PCM_FORMAT_U20_BE ((snd_pcm_format_t) 28) /* in four bytes, LSB justified */ + /* gap in the numbering for a future standard linear format */ +-#define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) +-#define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U24_3LE ((__force snd_pcm_format_t) 34) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U24_3BE ((__force snd_pcm_format_t) 35) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_S20_3LE ((__force snd_pcm_format_t) 36) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_S20_3BE ((__force snd_pcm_format_t) 37) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U20_3LE ((__force snd_pcm_format_t) 38) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U20_3BE ((__force snd_pcm_format_t) 39) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_S18_3LE ((__force snd_pcm_format_t) 40) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_S18_3BE ((__force snd_pcm_format_t) 41) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U18_3LE ((__force snd_pcm_format_t) 42) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_U18_3BE ((__force snd_pcm_format_t) 43) /* in three bytes */ +-#define SNDRV_PCM_FORMAT_G723_24 ((__force snd_pcm_format_t) 44) /* 8 samples in 3 bytes */ +-#define SNDRV_PCM_FORMAT_G723_24_1B ((__force snd_pcm_format_t) 45) /* 1 sample in 1 byte */ +-#define SNDRV_PCM_FORMAT_G723_40 ((__force snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */ +-#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */ +-#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */ +-#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */ +-#define SNDRV_PCM_FORMAT_DSD_U32_LE ((__force snd_pcm_format_t) 50) /* DSD, 4-byte samples DSD (x32), little endian */ +-#define SNDRV_PCM_FORMAT_DSD_U16_BE ((__force snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */ +-#define SNDRV_PCM_FORMAT_DSD_U32_BE ((__force snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */ ++#define SNDRV_PCM_FORMAT_SPECIAL ((snd_pcm_format_t) 31) ++#define SNDRV_PCM_FORMAT_S24_3LE ((snd_pcm_format_t) 32) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_S24_3BE ((snd_pcm_format_t) 33) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U24_3LE ((snd_pcm_format_t) 34) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U24_3BE ((snd_pcm_format_t) 35) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_S20_3LE ((snd_pcm_format_t) 36) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_S20_3BE ((snd_pcm_format_t) 37) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U20_3LE ((snd_pcm_format_t) 38) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U20_3BE ((snd_pcm_format_t) 39) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_S18_3LE ((snd_pcm_format_t) 40) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_S18_3BE ((snd_pcm_format_t) 41) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U18_3LE ((snd_pcm_format_t) 42) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_U18_3BE ((snd_pcm_format_t) 43) /* in three bytes */ ++#define SNDRV_PCM_FORMAT_G723_24 ((snd_pcm_format_t) 44) /* 8 samples in 3 bytes */ ++#define SNDRV_PCM_FORMAT_G723_24_1B ((snd_pcm_format_t) 45) /* 1 sample in 1 byte */ ++#define SNDRV_PCM_FORMAT_G723_40 ((snd_pcm_format_t) 46) /* 8 Samples in 5 bytes */ ++#define SNDRV_PCM_FORMAT_G723_40_1B ((snd_pcm_format_t) 47) /* 1 sample in 1 byte */ ++#define SNDRV_PCM_FORMAT_DSD_U8 ((snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */ ++#define SNDRV_PCM_FORMAT_DSD_U16_LE ((snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */ ++#define SNDRV_PCM_FORMAT_DSD_U32_LE ((snd_pcm_format_t) 50) /* DSD, 4-byte samples DSD (x32), little endian */ ++#define SNDRV_PCM_FORMAT_DSD_U16_BE ((snd_pcm_format_t) 51) /* DSD, 2-byte samples DSD (x16), big endian */ ++#define SNDRV_PCM_FORMAT_DSD_U32_BE ((snd_pcm_format_t) 52) /* DSD, 4-byte samples DSD (x32), big endian */ + #define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U32_BE + #define SNDRV_PCM_FORMAT_FIRST SNDRV_PCM_FORMAT_S8 + +@@ -273,7 +273,7 @@ typedef int __bitwise snd_pcm_format_t; + #endif + + typedef int __bitwise snd_pcm_subformat_t; +-#define SNDRV_PCM_SUBFORMAT_STD ((__force snd_pcm_subformat_t) 0) ++#define SNDRV_PCM_SUBFORMAT_STD ((snd_pcm_subformat_t) 0) + #define SNDRV_PCM_SUBFORMAT_LAST SNDRV_PCM_SUBFORMAT_STD + + #define SNDRV_PCM_INFO_MMAP 0x00000001 /* hardware supports mmap */ +@@ -301,24 +301,35 @@ typedef int __bitwise snd_pcm_subformat_t; + #define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */ + #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ + +- ++#if (__BITS_PER_LONG == 32 && defined(__USE_TIME_BITS64)) || defined __KERNEL__ ++#define __SND_STRUCT_TIME64 ++#endif + + typedef int __bitwise snd_pcm_state_t; +-#define SNDRV_PCM_STATE_OPEN ((__force snd_pcm_state_t) 0) /* stream is open */ +-#define SNDRV_PCM_STATE_SETUP ((__force snd_pcm_state_t) 1) /* stream has a setup */ +-#define SNDRV_PCM_STATE_PREPARED ((__force snd_pcm_state_t) 2) /* stream is ready to start */ +-#define SNDRV_PCM_STATE_RUNNING ((__force snd_pcm_state_t) 3) /* stream is running */ +-#define SNDRV_PCM_STATE_XRUN ((__force snd_pcm_state_t) 4) /* stream reached an xrun */ +-#define SNDRV_PCM_STATE_DRAINING ((__force snd_pcm_state_t) 5) /* stream is draining */ +-#define SNDRV_PCM_STATE_PAUSED ((__force snd_pcm_state_t) 6) /* stream is paused */ +-#define SNDRV_PCM_STATE_SUSPENDED ((__force snd_pcm_state_t) 7) /* hardware is suspended */ +-#define SNDRV_PCM_STATE_DISCONNECTED ((__force snd_pcm_state_t) 8) /* hardware is disconnected */ ++#define SNDRV_PCM_STATE_OPEN ((snd_pcm_state_t) 0) /* stream is open */ ++#define SNDRV_PCM_STATE_SETUP ((snd_pcm_state_t) 1) /* stream has a setup */ ++#define SNDRV_PCM_STATE_PREPARED ((snd_pcm_state_t) 2) /* stream is ready to start */ ++#define SNDRV_PCM_STATE_RUNNING ((snd_pcm_state_t) 3) /* stream is running */ ++#define SNDRV_PCM_STATE_XRUN ((snd_pcm_state_t) 4) /* stream reached an xrun */ ++#define SNDRV_PCM_STATE_DRAINING ((snd_pcm_state_t) 5) /* stream is draining */ ++#define SNDRV_PCM_STATE_PAUSED ((snd_pcm_state_t) 6) /* stream is paused */ ++#define SNDRV_PCM_STATE_SUSPENDED ((snd_pcm_state_t) 7) /* hardware is suspended */ ++#define SNDRV_PCM_STATE_DISCONNECTED ((snd_pcm_state_t) 8) /* hardware is disconnected */ + #define SNDRV_PCM_STATE_LAST SNDRV_PCM_STATE_DISCONNECTED + + 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, ++#ifdef __SND_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 + }; + + union snd_pcm_sync_id { +@@ -456,8 +467,12 @@ enum { + SNDRV_PCM_AUDIO_TSTAMP_TYPE_LAST = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK_SYNCHRONIZED + }; + ++/* explicit padding avoids incompatibility between i386 and x86-64 */ ++typedef struct { unsigned char pad[sizeof(time_t) - sizeof(int)]; } __time_pad; ++ + struct snd_pcm_status { + snd_pcm_state_t state; /* stream state */ ++ __time_pad pad1; /* align to timespec */ + struct timespec trigger_tstamp; /* time when stream was started/stopped/paused */ + struct timespec tstamp; /* reference timestamp */ + snd_pcm_uframes_t appl_ptr; /* appl ptr */ +@@ -474,16 +489,42 @@ struct snd_pcm_status { + unsigned char reserved[52-2*sizeof(struct timespec)]; /* must be filled with zero */ + }; + +-struct snd_pcm_mmap_status { ++/* ++ * For mmap operations, we need the 64-bit layout, both for compat mode, ++ * and for y2038 compatibility. For 64-bit applications, the two definitions ++ * are identical, so we keep the traditional version. ++ */ ++#ifdef __SND_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 ++#define __snd_timespec64 timespec ++struct __snd_timespec { ++ __s32 tv_sec; ++ __s32 tv_nsec; ++}; ++#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 ++#define __snd_timespec timespec ++struct __snd_timespec64 { ++ __s64 tv_sec; ++ __s64 tv_nsec; ++}; ++ ++#endif ++ ++struct __snd_pcm_mmap_status { + snd_pcm_state_t state; /* RO: state - SNDRV_PCM_STATE_XXXX */ + int pad1; /* Needed for 64 bit alignment */ + snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ +- struct timespec tstamp; /* Timestamp */ ++ struct __snd_timespec tstamp; /* Timestamp */ + snd_pcm_state_t suspended_state; /* RO: suspended stream state */ +- struct timespec audio_tstamp; /* from sample counter or wall clock */ ++ struct __snd_timespec audio_tstamp; /* from sample counter or wall clock */ + }; + +-struct snd_pcm_mmap_control { ++struct __snd_pcm_mmap_control { + snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ + snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ + }; +@@ -492,27 +533,72 @@ struct snd_pcm_mmap_control { + #define SNDRV_PCM_SYNC_PTR_APPL (1<<1) /* get appl_ptr from driver (r/w op) */ + #define SNDRV_PCM_SYNC_PTR_AVAIL_MIN (1<<2) /* get avail_min from driver */ + +-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(__u64) - sizeof(snd_pcm_uframes_t)]; ++typedef char __pad_after_uframe[0]; ++#endif ++ ++#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN) ++typedef char __pad_before_uframe[0]; ++typedef char __pad_after_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)]; ++#endif ++ ++struct __snd_pcm_mmap_status64 { ++ snd_pcm_state_t state; /* RO: state - SNDRV_PCM_STATE_XXXX */ ++ __u32 pad1; /* Needed for 64 bit alignment */ ++ __pad_before_uframe __pad1; ++ snd_pcm_uframes_t hw_ptr; /* RO: hw ptr (0...boundary-1) */ ++ __pad_after_uframe __pad2; ++ struct __snd_timespec64 tstamp; /* Timestamp */ ++ snd_pcm_state_t suspended_state;/* RO: suspended stream state */ ++ __u32 pad3; /* Needed for 64 bit alignment */ ++ struct __snd_timespec64 audio_tstamp; /* sample counter or wall clock */ ++}; ++ ++struct __snd_pcm_mmap_control64 { ++ __pad_before_uframe __pad1; ++ snd_pcm_uframes_t appl_ptr; /* RW: appl ptr (0...boundary-1) */ ++ __pad_before_uframe __pad2; ++ ++ __pad_before_uframe __pad3; ++ snd_pcm_uframes_t avail_min; /* RW: min available frames for wakeup */ ++ __pad_after_uframe __pad4; ++}; ++ ++struct __snd_pcm_sync_ptr64 { ++ __u32 flags; ++ __u32 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; + }; + + struct snd_xferi { + snd_pcm_sframes_t result; +- void __user *buf; ++ void *buf; + snd_pcm_uframes_t frames; + }; + + struct snd_xfern { + snd_pcm_sframes_t result; +- void __user * __user *bufs; ++ void * *bufs; + snd_pcm_uframes_t frames; + }; + +@@ -584,6 +670,8 @@ enum { + #define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct snd_pcm_status) + #define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, snd_pcm_sframes_t) + #define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22) ++#define __SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct __snd_pcm_sync_ptr) ++#define __SNDRV_PCM_IOCTL_SYNC_PTR64 _IOWR('A', 0x23, struct __snd_pcm_sync_ptr64) + #define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct snd_pcm_sync_ptr) + #define SNDRV_PCM_IOCTL_STATUS_EXT _IOWR('A', 0x24, struct snd_pcm_status) + #define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct snd_pcm_channel_info) +@@ -614,7 +702,7 @@ enum { + * Raw MIDI section - /dev/snd/midi?? + */ + +-#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 0) ++#define SNDRV_RAWMIDI_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 1) + + enum { + SNDRV_RAWMIDI_STREAM_OUTPUT = 0, +@@ -650,6 +738,7 @@ struct snd_rawmidi_params { + + struct snd_rawmidi_status { + int stream; ++ __time_pad pad1; + struct timespec tstamp; /* Timestamp */ + size_t avail; /* available bytes */ + size_t xruns; /* count of overruns since last status (in bytes) */ +@@ -667,7 +756,7 @@ struct snd_rawmidi_status { + * Timer section - /dev/snd/timer + */ + +-#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) ++#define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) + + enum { + SNDRV_TIMER_CLASS_NONE = -1, +@@ -772,7 +861,7 @@ struct snd_timer_status { + + #define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) + #define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) +-#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int) ++#define SNDRV_TIMER_IOCTL_TREAD_OLD _IOW('T', 0x02, int) + #define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct snd_timer_ginfo) + #define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct snd_timer_gparams) + #define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct snd_timer_gstatus) +@@ -785,6 +874,15 @@ struct snd_timer_status { + #define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1) + #define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) + #define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) ++#define SNDRV_TIMER_IOCTL_TREAD64 _IOW('T', 0xa4, int) ++ ++#if __BITS_PER_LONG == 64 ++#define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD ++#else ++#define SNDRV_TIMER_IOCTL_TREAD ((sizeof(__kernel_long_t) >= sizeof(time_t)) ? \ ++ SNDRV_TIMER_IOCTL_TREAD_OLD : \ ++ SNDRV_TIMER_IOCTL_TREAD64) ++#endif + + struct snd_timer_read { + unsigned int resolution; +@@ -812,8 +910,10 @@ enum { + + struct snd_timer_tread { + int event; ++ __time_pad pad1; + struct timespec tstamp; + unsigned int val; ++ __time_pad pad2; + }; + + /**************************************************************************** +@@ -822,7 +922,7 @@ struct snd_timer_tread { + * * + ****************************************************************************/ + +-#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) ++#define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8) + + struct snd_ctl_card_info { + int card; /* card number */ +@@ -837,30 +937,30 @@ struct snd_ctl_card_info { + }; + + typedef int __bitwise snd_ctl_elem_type_t; +-#define SNDRV_CTL_ELEM_TYPE_NONE ((__force snd_ctl_elem_type_t) 0) /* invalid */ +-#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((__force snd_ctl_elem_type_t) 1) /* boolean type */ +-#define SNDRV_CTL_ELEM_TYPE_INTEGER ((__force snd_ctl_elem_type_t) 2) /* integer type */ +-#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((__force snd_ctl_elem_type_t) 3) /* enumerated type */ +-#define SNDRV_CTL_ELEM_TYPE_BYTES ((__force snd_ctl_elem_type_t) 4) /* byte array */ +-#define SNDRV_CTL_ELEM_TYPE_IEC958 ((__force snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */ +-#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((__force snd_ctl_elem_type_t) 6) /* 64-bit integer type */ ++#define SNDRV_CTL_ELEM_TYPE_NONE ((snd_ctl_elem_type_t) 0) /* invalid */ ++#define SNDRV_CTL_ELEM_TYPE_BOOLEAN ((snd_ctl_elem_type_t) 1) /* boolean type */ ++#define SNDRV_CTL_ELEM_TYPE_INTEGER ((snd_ctl_elem_type_t) 2) /* integer type */ ++#define SNDRV_CTL_ELEM_TYPE_ENUMERATED ((snd_ctl_elem_type_t) 3) /* enumerated type */ ++#define SNDRV_CTL_ELEM_TYPE_BYTES ((snd_ctl_elem_type_t) 4) /* byte array */ ++#define SNDRV_CTL_ELEM_TYPE_IEC958 ((snd_ctl_elem_type_t) 5) /* IEC958 (S/PDIF) setup */ ++#define SNDRV_CTL_ELEM_TYPE_INTEGER64 ((snd_ctl_elem_type_t) 6) /* 64-bit integer type */ + #define SNDRV_CTL_ELEM_TYPE_LAST SNDRV_CTL_ELEM_TYPE_INTEGER64 + + typedef int __bitwise snd_ctl_elem_iface_t; +-#define SNDRV_CTL_ELEM_IFACE_CARD ((__force snd_ctl_elem_iface_t) 0) /* global control */ +-#define SNDRV_CTL_ELEM_IFACE_HWDEP ((__force snd_ctl_elem_iface_t) 1) /* hardware dependent device */ +-#define SNDRV_CTL_ELEM_IFACE_MIXER ((__force snd_ctl_elem_iface_t) 2) /* virtual mixer device */ +-#define SNDRV_CTL_ELEM_IFACE_PCM ((__force snd_ctl_elem_iface_t) 3) /* PCM device */ +-#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((__force snd_ctl_elem_iface_t) 4) /* RawMidi device */ +-#define SNDRV_CTL_ELEM_IFACE_TIMER ((__force snd_ctl_elem_iface_t) 5) /* timer device */ +-#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((__force snd_ctl_elem_iface_t) 6) /* sequencer client */ ++#define SNDRV_CTL_ELEM_IFACE_CARD ((snd_ctl_elem_iface_t) 0) /* global control */ ++#define SNDRV_CTL_ELEM_IFACE_HWDEP ((snd_ctl_elem_iface_t) 1) /* hardware dependent device */ ++#define SNDRV_CTL_ELEM_IFACE_MIXER ((snd_ctl_elem_iface_t) 2) /* virtual mixer device */ ++#define SNDRV_CTL_ELEM_IFACE_PCM ((snd_ctl_elem_iface_t) 3) /* PCM device */ ++#define SNDRV_CTL_ELEM_IFACE_RAWMIDI ((snd_ctl_elem_iface_t) 4) /* RawMidi device */ ++#define SNDRV_CTL_ELEM_IFACE_TIMER ((snd_ctl_elem_iface_t) 5) /* timer device */ ++#define SNDRV_CTL_ELEM_IFACE_SEQUENCER ((snd_ctl_elem_iface_t) 6) /* sequencer client */ + #define SNDRV_CTL_ELEM_IFACE_LAST SNDRV_CTL_ELEM_IFACE_SEQUENCER + + #define SNDRV_CTL_ELEM_ACCESS_READ (1<<0) + #define SNDRV_CTL_ELEM_ACCESS_WRITE (1<<1) + #define SNDRV_CTL_ELEM_ACCESS_READWRITE (SNDRV_CTL_ELEM_ACCESS_READ|SNDRV_CTL_ELEM_ACCESS_WRITE) + #define SNDRV_CTL_ELEM_ACCESS_VOLATILE (1<<2) /* control value may be changed without a notification */ +-#define SNDRV_CTL_ELEM_ACCESS_TIMESTAMP (1<<3) /* when was control changed */ ++// (1 << 3) is unused. + #define SNDRV_CTL_ELEM_ACCESS_TLV_READ (1<<4) /* TLV read is possible */ + #define SNDRV_CTL_ELEM_ACCESS_TLV_WRITE (1<<5) /* TLV write is possible */ + #define SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE (SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_TLV_WRITE) +@@ -896,7 +996,7 @@ struct snd_ctl_elem_list { + unsigned int space; /* W: count of element IDs to get */ + unsigned int used; /* R: count of element IDs set */ + unsigned int count; /* R: count of all elements */ +- struct snd_ctl_elem_id __user *pids; /* R: IDs */ ++ struct snd_ctl_elem_id *pids; /* R: IDs */ + unsigned char reserved[50]; + }; + +@@ -926,11 +1026,7 @@ struct snd_ctl_elem_info { + } enumerated; + unsigned char reserved[128]; + } value; +- union { +- unsigned short d[4]; /* dimensions */ +- unsigned short *d_ptr; /* indirect - obsoleted */ +- } dimen; +- unsigned char reserved[64-4*sizeof(unsigned short)]; ++ unsigned char reserved[64]; + }; + + struct snd_ctl_elem_value { +@@ -955,8 +1051,7 @@ struct snd_ctl_elem_value { + } bytes; + struct snd_aes_iec958 iec958; + } value; /* RO */ +- struct timespec tstamp; +- unsigned char reserved[128-sizeof(struct timespec)]; ++ unsigned char reserved[128]; + }; + + struct snd_ctl_tlv { +@@ -1035,4 +1130,4 @@ struct snd_ctl_event { + #define SNDRV_CTL_NAME_IEC958_PCM_STREAM "PCM Stream" + #define SNDRV_CTL_NAME_IEC958(expl,direction,what) "IEC958 " expl SNDRV_CTL_NAME_##direction SNDRV_CTL_NAME_IEC958_##what + +-#endif /* _UAPI__SOUND_ASOUND_H */ ++#endif /* __SOUND_ASOUND_H */ +diff --git a/include/sound/uapi/emu10k1.h b/include/sound/uapi/emu10k1.h +index 6bcd76f64c1c..78d794c03cd4 100644 +--- a/include/sound/uapi/emu10k1.h ++++ b/include/sound/uapi/emu10k1.h +@@ -20,8 +20,12 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +-#ifndef _UAPI__SOUND_EMU10K1_H +-#define _UAPI__SOUND_EMU10K1_H ++#ifndef __SOUND_EMU10K1_H ++#define __SOUND_EMU10K1_H ++ ++#ifdef __linux__ ++#include ++#endif + + /* + * ---- FX8010 ---- +@@ -256,13 +260,11 @@ + #define EMU10K1_DBG_SINGLE_STEP_ADDR 0x000001ff /* single step address */ + + /* tank memory address line */ +-#ifndef __KERNEL__ + #define TANKMEMADDRREG_ADDR_MASK 0x000fffff /* 20 bit tank address field */ + #define TANKMEMADDRREG_CLEAR 0x00800000 /* Clear tank memory */ + #define TANKMEMADDRREG_ALIGN 0x00400000 /* Align read or write relative to tank access */ + #define TANKMEMADDRREG_WRITE 0x00200000 /* Write to tank memory */ + #define TANKMEMADDRREG_READ 0x00100000 /* Read from tank memory */ +-#endif + + struct snd_emu10k1_fx8010_info { + unsigned int internal_tram_size; /* in samples */ +@@ -382,4 +384,4 @@ struct snd_emu10k1_fx8010_pcm_rec { + #define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int) + #define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int) + +-#endif /* _UAPI__SOUND_EMU10K1_H */ ++#endif /* __SOUND_EMU10K1_H */ +diff --git a/include/sound/uapi/hdsp.h b/include/sound/uapi/hdsp.h +index 7ac2d3f2a9b3..b8df62b60f4d 100644 +--- a/include/sound/uapi/hdsp.h ++++ b/include/sound/uapi/hdsp.h +@@ -20,6 +20,10 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#ifdef __linux__ ++#include ++#endif ++ + #define HDSP_MATRIX_MIXER_SIZE 2048 + + enum HDSP_IO_Type { +diff --git a/include/sound/uapi/hdspm.h b/include/sound/uapi/hdspm.h +index 3fbfd9dc5f51..14af3d00ea3f 100644 +--- a/include/sound/uapi/hdspm.h ++++ b/include/sound/uapi/hdspm.h +@@ -21,6 +21,10 @@ + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + ++#ifdef __linux__ ++#include ++#endif ++ + /* Maximum channels is 64 even on 56Mode you have 64playbacks to matrix */ + #define HDSPM_MAX_CHANNELS 64 + +diff --git a/include/sound/uapi/sb16_csp.h b/include/sound/uapi/sb16_csp.h +index e64851481d88..55db0b44a8b7 100644 +--- a/include/sound/uapi/sb16_csp.h ++++ b/include/sound/uapi/sb16_csp.h +@@ -20,8 +20,8 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +-#ifndef _UAPI__SOUND_SB16_CSP_H +-#define _UAPI__SOUND_SB16_CSP_H ++#ifndef __SOUND_SB16_CSP_H ++#define __SOUND_SB16_CSP_H + + + /* CSP modes */ +@@ -120,4 +120,4 @@ struct snd_sb_csp_info { + #define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16) + + +-#endif /* _UAPI__SOUND_SB16_CSP_H */ ++#endif /* __SOUND_SB16_CSP_H */ +-- +2.16.4 + diff --git a/0073-ucm-parser-add-error-message-to-verb_dev_list_add.patch b/0073-ucm-parser-add-error-message-to-verb_dev_list_add.patch new file mode 100644 index 0000000..e389b63 --- /dev/null +++ b/0073-ucm-parser-add-error-message-to-verb_dev_list_add.patch @@ -0,0 +1,25 @@ +From 5bc3d4c4c14c6a54f61465987fe7e1a097288e4b Mon Sep 17 00:00:00 2001 +From: Jaroslav Kysela +Date: Mon, 10 Feb 2020 13:18:23 +0100 +Subject: [PATCH 73/74] ucm: parser - add error message to verb_dev_list_add() + +Signed-off-by: Jaroslav Kysela +--- + src/ucm/parser.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/ucm/parser.c b/src/ucm/parser.c +index 23bf6a63f31e..8d6eea31f8e7 100644 +--- a/src/ucm/parser.c ++++ b/src/ucm/parser.c +@@ -1135,6 +1135,7 @@ static int verb_dev_list_add(struct use_case_verb *verb, + } + return uc_mgr_put_to_dev_list(&device->dev_list, src); + } ++ uc_error("error: unable to find device '%s'", dst); + return -ENOENT; + } + +-- +2.16.4 + diff --git a/0074-do-not-set-close-on-exec-flag-on-descriptor-if-it-wa.patch b/0074-do-not-set-close-on-exec-flag-on-descriptor-if-it-wa.patch new file mode 100644 index 0000000..e11e83a --- /dev/null +++ b/0074-do-not-set-close-on-exec-flag-on-descriptor-if-it-wa.patch @@ -0,0 +1,32 @@ +From b367274b4dcdd1e83e6e7211dd2c08df05c8a998 Mon Sep 17 00:00:00 2001 +From: Rolf Eike Beer +Date: Tue, 11 Feb 2020 11:22:18 +0100 +Subject: [PATCH 74/74] do not set close-on-exec flag on descriptor if it was + already set + +There is no need to set this again if O_CLOEXEC is supported. + +Signed-off-by: Rolf Eike Beer +Signed-off-by: Jaroslav Kysela +--- + include/local.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/local.h b/include/local.h +index ea0ec32d96b3..ed6ba93664dd 100644 +--- a/include/local.h ++++ b/include/local.h +@@ -320,8 +320,10 @@ static inline int snd_open_device(const char *filename, int fmode) + fd = rsm_open_device(filename, fmode); + } + #endif ++#ifndef O_CLOEXEC + if (fd >= 0) + fcntl(fd, F_SETFD, FD_CLOEXEC); ++#endif + return fd; + } + +-- +2.16.4 + diff --git a/alsa.changes b/alsa.changes index 6342892..62ebaab 100644 --- a/alsa.changes +++ b/alsa.changes @@ -1,3 +1,21 @@ +------------------------------------------------------------------- +Wed Feb 12 20:36:56 CET 2020 - tiwai@suse.de + +- Backport upstream fixes: + ucm-parser fixes and enhancements, configure script cleanup, + fixes of 5.6 kernel ABI, O_CLOEXEC flag fix: + 0064-ucm-parser-cosmetic-fixes-in-the-comments.patch + 0065-configure.ac-remove-an-unnecessary-libtool-fix.patch + 0066-ucm-parser-use-correct-filename-in-parser_master_fil.patch + 0067-ucm-the-ucm2-subdirectory-is-driver-name-based.patch + 0068-ucm-implement-RenameDevice-and-RemoveDevice-verb-man.patch + 0069-ucm-fill-missing-device-entries-conflicting-supporte.patch + 0070-control-Remove-access-to-the-deprecated-dimen-fields.patch + 0071-topology-Drop-SNDRV_CTL_ELEM_ACCESS_TIMESTAMP-access.patch + 0072-uapi-Sync-with-5.6-kernel-ABI.patch + 0073-ucm-parser-add-error-message-to-verb_dev_list_add.patch + 0074-do-not-set-close-on-exec-flag-on-descriptor-if-it-wa.patch + ------------------------------------------------------------------- Tue Jan 21 15:49:49 CET 2020 - tiwai@suse.de diff --git a/alsa.spec b/alsa.spec index d571c74..7d46b03 100644 --- a/alsa.spec +++ b/alsa.spec @@ -111,6 +111,17 @@ Patch60: 0060-ucm-fix-the-configuration-directory-longname-for-ucm.patch Patch61: 0061-ucm-split-conf_file_name-and-conf_dir_name.patch Patch62: 0062-ucm-remove-MAX_FILE-definition-and-use-correct-PATH_.patch Patch63: 0063-topology-remove-MAX_FILE-definition-and-use-correct-.patch +Patch64: 0064-ucm-parser-cosmetic-fixes-in-the-comments.patch +Patch65: 0065-configure.ac-remove-an-unnecessary-libtool-fix.patch +Patch66: 0066-ucm-parser-use-correct-filename-in-parser_master_fil.patch +Patch67: 0067-ucm-the-ucm2-subdirectory-is-driver-name-based.patch +Patch68: 0068-ucm-implement-RenameDevice-and-RemoveDevice-verb-man.patch +Patch69: 0069-ucm-fill-missing-device-entries-conflicting-supporte.patch +Patch70: 0070-control-Remove-access-to-the-deprecated-dimen-fields.patch +Patch71: 0071-topology-Drop-SNDRV_CTL_ELEM_ACCESS_TIMESTAMP-access.patch +Patch72: 0072-uapi-Sync-with-5.6-kernel-ABI.patch +Patch73: 0073-ucm-parser-add-error-message-to-verb_dev_list_add.patch +Patch74: 0074-do-not-set-close-on-exec-flag-on-descriptor-if-it-wa.patch # rest suse fixes Patch101: alsa-lib-ignore-non-accessible-ALSA_CONFIG_PATH.patch BuildRequires: doxygen @@ -258,6 +269,17 @@ This package contains the library for ALSA topology support. %patch61 -p1 %patch62 -p1 %patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 %patch101 -p1 %build