misc.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Misc and compatibility things
  4. * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  5. */
  6. #include <linux/init.h>
  7. #include <linux/export.h>
  8. #include <linux/moduleparam.h>
  9. #include <linux/time.h>
  10. #include <linux/slab.h>
  11. #include <linux/ioport.h>
  12. #include <sound/core.h>
  13. #ifdef CONFIG_SND_DEBUG
  14. #ifdef CONFIG_SND_DEBUG_VERBOSE
  15. #define DEFAULT_DEBUG_LEVEL 2
  16. #else
  17. #define DEFAULT_DEBUG_LEVEL 1
  18. #endif
  19. static int debug = DEFAULT_DEBUG_LEVEL;
  20. module_param(debug, int, 0644);
  21. MODULE_PARM_DESC(debug, "Debug level (0 = disable)");
  22. #endif /* CONFIG_SND_DEBUG */
  23. void release_and_free_resource(struct resource *res)
  24. {
  25. if (res) {
  26. release_resource(res);
  27. kfree(res);
  28. }
  29. }
  30. EXPORT_SYMBOL(release_and_free_resource);
  31. #ifdef CONFIG_SND_VERBOSE_PRINTK
  32. /* strip the leading path if the given path is absolute */
  33. static const char *sanity_file_name(const char *path)
  34. {
  35. if (*path == '/')
  36. return strrchr(path, '/') + 1;
  37. else
  38. return path;
  39. }
  40. #endif
  41. #if defined(CONFIG_SND_DEBUG) || defined(CONFIG_SND_VERBOSE_PRINTK)
  42. void __snd_printk(unsigned int level, const char *path, int line,
  43. const char *format, ...)
  44. {
  45. va_list args;
  46. #ifdef CONFIG_SND_VERBOSE_PRINTK
  47. int kern_level;
  48. struct va_format vaf;
  49. char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV";
  50. bool level_found = false;
  51. #endif
  52. #ifdef CONFIG_SND_DEBUG
  53. if (debug < level)
  54. return;
  55. #endif
  56. va_start(args, format);
  57. #ifdef CONFIG_SND_VERBOSE_PRINTK
  58. vaf.fmt = format;
  59. vaf.va = &args;
  60. while ((kern_level = printk_get_level(vaf.fmt)) != 0) {
  61. const char *end_of_header = printk_skip_level(vaf.fmt);
  62. /* Ignore KERN_CONT. We print filename:line for each piece. */
  63. if (kern_level >= '0' && kern_level <= '7') {
  64. memcpy(verbose_fmt, vaf.fmt, end_of_header - vaf.fmt);
  65. level_found = true;
  66. }
  67. vaf.fmt = end_of_header;
  68. }
  69. if (!level_found && level)
  70. memcpy(verbose_fmt, KERN_DEBUG, sizeof(KERN_DEBUG) - 1);
  71. printk(verbose_fmt, sanity_file_name(path), line, &vaf);
  72. #else
  73. vprintk(format, args);
  74. #endif
  75. va_end(args);
  76. }
  77. EXPORT_SYMBOL_GPL(__snd_printk);
  78. #endif
  79. #ifdef CONFIG_PCI
  80. #include <linux/pci.h>
  81. /**
  82. * snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
  83. * @vendor: PCI SSV id
  84. * @device: PCI SSD id
  85. * @list: quirk list, terminated by a null entry
  86. *
  87. * Look through the given quirk list and finds a matching entry
  88. * with the same PCI SSID. When subdevice is 0, all subdevice
  89. * values may match.
  90. *
  91. * Returns the matched entry pointer, or NULL if nothing matched.
  92. */
  93. const struct snd_pci_quirk *
  94. snd_pci_quirk_lookup_id(u16 vendor, u16 device,
  95. const struct snd_pci_quirk *list)
  96. {
  97. const struct snd_pci_quirk *q;
  98. for (q = list; q->subvendor; q++) {
  99. if (q->subvendor != vendor)
  100. continue;
  101. if (!q->subdevice ||
  102. (device & q->subdevice_mask) == q->subdevice)
  103. return q;
  104. }
  105. return NULL;
  106. }
  107. EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
  108. /**
  109. * snd_pci_quirk_lookup - look up a PCI SSID quirk list
  110. * @pci: pci_dev handle
  111. * @list: quirk list, terminated by a null entry
  112. *
  113. * Look through the given quirk list and finds a matching entry
  114. * with the same PCI SSID. When subdevice is 0, all subdevice
  115. * values may match.
  116. *
  117. * Returns the matched entry pointer, or NULL if nothing matched.
  118. */
  119. const struct snd_pci_quirk *
  120. snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
  121. {
  122. if (!pci)
  123. return NULL;
  124. return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
  125. pci->subsystem_device,
  126. list);
  127. }
  128. EXPORT_SYMBOL(snd_pci_quirk_lookup);
  129. #endif