pcm.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Digital Audio (PCM) abstract layer
  4. * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
  5. */
  6. #include <linux/init.h>
  7. #include <linux/slab.h>
  8. #include <linux/module.h>
  9. #include <linux/time.h>
  10. #include <linux/mutex.h>
  11. #include <linux/device.h>
  12. #include <linux/nospec.h>
  13. #include <sound/core.h>
  14. #include <sound/minors.h>
  15. #include <sound/pcm.h>
  16. #include <sound/timer.h>
  17. #include <sound/control.h>
  18. #include <sound/info.h>
  19. #include "pcm_local.h"
  20. MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
  21. MODULE_DESCRIPTION("Midlevel PCM code for ALSA.");
  22. MODULE_LICENSE("GPL");
  23. static LIST_HEAD(snd_pcm_devices);
  24. static DEFINE_MUTEX(register_mutex);
  25. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  26. static LIST_HEAD(snd_pcm_notify_list);
  27. #endif
  28. static int snd_pcm_free(struct snd_pcm *pcm);
  29. static int snd_pcm_dev_free(struct snd_device *device);
  30. static int snd_pcm_dev_register(struct snd_device *device);
  31. static int snd_pcm_dev_disconnect(struct snd_device *device);
  32. static struct snd_pcm *snd_pcm_get(struct snd_card *card, int device)
  33. {
  34. struct snd_pcm *pcm;
  35. list_for_each_entry(pcm, &snd_pcm_devices, list) {
  36. if (pcm->card == card && pcm->device == device)
  37. return pcm;
  38. }
  39. return NULL;
  40. }
  41. static int snd_pcm_next(struct snd_card *card, int device)
  42. {
  43. struct snd_pcm *pcm;
  44. list_for_each_entry(pcm, &snd_pcm_devices, list) {
  45. if (pcm->card == card && pcm->device > device)
  46. return pcm->device;
  47. else if (pcm->card->number > card->number)
  48. return -1;
  49. }
  50. return -1;
  51. }
  52. static int snd_pcm_add(struct snd_pcm *newpcm)
  53. {
  54. struct snd_pcm *pcm;
  55. if (newpcm->internal)
  56. return 0;
  57. list_for_each_entry(pcm, &snd_pcm_devices, list) {
  58. if (pcm->card == newpcm->card && pcm->device == newpcm->device)
  59. return -EBUSY;
  60. if (pcm->card->number > newpcm->card->number ||
  61. (pcm->card == newpcm->card &&
  62. pcm->device > newpcm->device)) {
  63. list_add(&newpcm->list, pcm->list.prev);
  64. return 0;
  65. }
  66. }
  67. list_add_tail(&newpcm->list, &snd_pcm_devices);
  68. return 0;
  69. }
  70. static int snd_pcm_control_ioctl(struct snd_card *card,
  71. struct snd_ctl_file *control,
  72. unsigned int cmd, unsigned long arg)
  73. {
  74. switch (cmd) {
  75. case SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE:
  76. {
  77. int device;
  78. if (get_user(device, (int __user *)arg))
  79. return -EFAULT;
  80. scoped_guard(mutex, &register_mutex)
  81. device = snd_pcm_next(card, device);
  82. if (put_user(device, (int __user *)arg))
  83. return -EFAULT;
  84. return 0;
  85. }
  86. case SNDRV_CTL_IOCTL_PCM_INFO:
  87. {
  88. struct snd_pcm_info __user *info;
  89. unsigned int device, subdevice;
  90. int stream;
  91. struct snd_pcm *pcm;
  92. struct snd_pcm_str *pstr;
  93. struct snd_pcm_substream *substream;
  94. info = (struct snd_pcm_info __user *)arg;
  95. if (get_user(device, &info->device))
  96. return -EFAULT;
  97. if (get_user(stream, &info->stream))
  98. return -EFAULT;
  99. if (stream < 0 || stream > 1)
  100. return -EINVAL;
  101. stream = array_index_nospec(stream, 2);
  102. if (get_user(subdevice, &info->subdevice))
  103. return -EFAULT;
  104. guard(mutex)(&register_mutex);
  105. pcm = snd_pcm_get(card, device);
  106. if (pcm == NULL)
  107. return -ENXIO;
  108. pstr = &pcm->streams[stream];
  109. if (pstr->substream_count == 0)
  110. return -ENOENT;
  111. if (subdevice >= pstr->substream_count)
  112. return -ENXIO;
  113. for (substream = pstr->substream; substream;
  114. substream = substream->next)
  115. if (substream->number == (int)subdevice)
  116. break;
  117. if (substream == NULL)
  118. return -ENXIO;
  119. guard(mutex)(&pcm->open_mutex);
  120. return snd_pcm_info_user(substream, info);
  121. }
  122. case SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE:
  123. {
  124. int val;
  125. if (get_user(val, (int __user *)arg))
  126. return -EFAULT;
  127. control->preferred_subdevice[SND_CTL_SUBDEV_PCM] = val;
  128. return 0;
  129. }
  130. }
  131. return -ENOIOCTLCMD;
  132. }
  133. #define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
  134. static const char * const snd_pcm_format_names[] = {
  135. FORMAT(S8),
  136. FORMAT(U8),
  137. FORMAT(S16_LE),
  138. FORMAT(S16_BE),
  139. FORMAT(U16_LE),
  140. FORMAT(U16_BE),
  141. FORMAT(S24_LE),
  142. FORMAT(S24_BE),
  143. FORMAT(U24_LE),
  144. FORMAT(U24_BE),
  145. FORMAT(S32_LE),
  146. FORMAT(S32_BE),
  147. FORMAT(U32_LE),
  148. FORMAT(U32_BE),
  149. FORMAT(FLOAT_LE),
  150. FORMAT(FLOAT_BE),
  151. FORMAT(FLOAT64_LE),
  152. FORMAT(FLOAT64_BE),
  153. FORMAT(IEC958_SUBFRAME_LE),
  154. FORMAT(IEC958_SUBFRAME_BE),
  155. FORMAT(MU_LAW),
  156. FORMAT(A_LAW),
  157. FORMAT(IMA_ADPCM),
  158. FORMAT(MPEG),
  159. FORMAT(GSM),
  160. FORMAT(SPECIAL),
  161. FORMAT(S24_3LE),
  162. FORMAT(S24_3BE),
  163. FORMAT(U24_3LE),
  164. FORMAT(U24_3BE),
  165. FORMAT(S20_3LE),
  166. FORMAT(S20_3BE),
  167. FORMAT(U20_3LE),
  168. FORMAT(U20_3BE),
  169. FORMAT(S18_3LE),
  170. FORMAT(S18_3BE),
  171. FORMAT(U18_3LE),
  172. FORMAT(U18_3BE),
  173. FORMAT(G723_24),
  174. FORMAT(G723_24_1B),
  175. FORMAT(G723_40),
  176. FORMAT(G723_40_1B),
  177. FORMAT(DSD_U8),
  178. FORMAT(DSD_U16_LE),
  179. FORMAT(DSD_U32_LE),
  180. FORMAT(DSD_U16_BE),
  181. FORMAT(DSD_U32_BE),
  182. FORMAT(S20_LE),
  183. FORMAT(S20_BE),
  184. FORMAT(U20_LE),
  185. FORMAT(U20_BE),
  186. };
  187. /**
  188. * snd_pcm_format_name - Return a name string for the given PCM format
  189. * @format: PCM format
  190. *
  191. * Return: the format name string
  192. */
  193. const char *snd_pcm_format_name(snd_pcm_format_t format)
  194. {
  195. unsigned int format_num = (__force unsigned int)format;
  196. if (format_num >= ARRAY_SIZE(snd_pcm_format_names) || !snd_pcm_format_names[format_num])
  197. return "Unknown";
  198. return snd_pcm_format_names[format_num];
  199. }
  200. EXPORT_SYMBOL_GPL(snd_pcm_format_name);
  201. #ifdef CONFIG_SND_VERBOSE_PROCFS
  202. #define STATE(v) [SNDRV_PCM_STATE_##v] = #v
  203. #define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
  204. #define READY(v) [SNDRV_PCM_READY_##v] = #v
  205. #define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
  206. #define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
  207. #define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
  208. #define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
  209. #define START(v) [SNDRV_PCM_START_##v] = #v
  210. #define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
  211. static const char * const snd_pcm_stream_names[] = {
  212. STREAM(PLAYBACK),
  213. STREAM(CAPTURE),
  214. };
  215. static const char * const snd_pcm_state_names[] = {
  216. STATE(OPEN),
  217. STATE(SETUP),
  218. STATE(PREPARED),
  219. STATE(RUNNING),
  220. STATE(XRUN),
  221. STATE(DRAINING),
  222. STATE(PAUSED),
  223. STATE(SUSPENDED),
  224. STATE(DISCONNECTED),
  225. };
  226. static const char * const snd_pcm_access_names[] = {
  227. ACCESS(MMAP_INTERLEAVED),
  228. ACCESS(MMAP_NONINTERLEAVED),
  229. ACCESS(MMAP_COMPLEX),
  230. ACCESS(RW_INTERLEAVED),
  231. ACCESS(RW_NONINTERLEAVED),
  232. };
  233. static const char * const snd_pcm_subformat_names[] = {
  234. SUBFORMAT(STD),
  235. SUBFORMAT(MSBITS_MAX),
  236. SUBFORMAT(MSBITS_20),
  237. SUBFORMAT(MSBITS_24),
  238. };
  239. static const char * const snd_pcm_tstamp_mode_names[] = {
  240. TSTAMP(NONE),
  241. TSTAMP(ENABLE),
  242. };
  243. static const char *snd_pcm_stream_name(int stream)
  244. {
  245. return snd_pcm_stream_names[stream];
  246. }
  247. static const char *snd_pcm_access_name(snd_pcm_access_t access)
  248. {
  249. return snd_pcm_access_names[(__force int)access];
  250. }
  251. static const char *snd_pcm_subformat_name(snd_pcm_subformat_t subformat)
  252. {
  253. return snd_pcm_subformat_names[(__force int)subformat];
  254. }
  255. static const char *snd_pcm_tstamp_mode_name(int mode)
  256. {
  257. return snd_pcm_tstamp_mode_names[mode];
  258. }
  259. static const char *snd_pcm_state_name(snd_pcm_state_t state)
  260. {
  261. return snd_pcm_state_names[(__force int)state];
  262. }
  263. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  264. #include <linux/soundcard.h>
  265. static const char *snd_pcm_oss_format_name(int format)
  266. {
  267. switch (format) {
  268. case AFMT_MU_LAW:
  269. return "MU_LAW";
  270. case AFMT_A_LAW:
  271. return "A_LAW";
  272. case AFMT_IMA_ADPCM:
  273. return "IMA_ADPCM";
  274. case AFMT_U8:
  275. return "U8";
  276. case AFMT_S16_LE:
  277. return "S16_LE";
  278. case AFMT_S16_BE:
  279. return "S16_BE";
  280. case AFMT_S8:
  281. return "S8";
  282. case AFMT_U16_LE:
  283. return "U16_LE";
  284. case AFMT_U16_BE:
  285. return "U16_BE";
  286. case AFMT_MPEG:
  287. return "MPEG";
  288. default:
  289. return "unknown";
  290. }
  291. }
  292. #endif
  293. static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream,
  294. struct snd_info_buffer *buffer)
  295. {
  296. int err;
  297. if (! substream)
  298. return;
  299. struct snd_pcm_info *info __free(kfree) =
  300. kmalloc_obj(*info);
  301. if (!info)
  302. return;
  303. err = snd_pcm_info(substream, info);
  304. if (err < 0) {
  305. snd_iprintf(buffer, "error %d\n", err);
  306. return;
  307. }
  308. snd_iprintf(buffer, "card: %d\n", info->card);
  309. snd_iprintf(buffer, "device: %d\n", info->device);
  310. snd_iprintf(buffer, "subdevice: %d\n", info->subdevice);
  311. snd_iprintf(buffer, "stream: %s\n", snd_pcm_stream_name(info->stream));
  312. snd_iprintf(buffer, "id: %s\n", info->id);
  313. snd_iprintf(buffer, "name: %s\n", info->name);
  314. snd_iprintf(buffer, "subname: %s\n", info->subname);
  315. snd_iprintf(buffer, "class: %d\n", info->dev_class);
  316. snd_iprintf(buffer, "subclass: %d\n", info->dev_subclass);
  317. snd_iprintf(buffer, "subdevices_count: %d\n", info->subdevices_count);
  318. snd_iprintf(buffer, "subdevices_avail: %d\n", info->subdevices_avail);
  319. }
  320. static void snd_pcm_stream_proc_info_read(struct snd_info_entry *entry,
  321. struct snd_info_buffer *buffer)
  322. {
  323. snd_pcm_proc_info_read(((struct snd_pcm_str *)entry->private_data)->substream,
  324. buffer);
  325. }
  326. static void snd_pcm_substream_proc_info_read(struct snd_info_entry *entry,
  327. struct snd_info_buffer *buffer)
  328. {
  329. snd_pcm_proc_info_read(entry->private_data, buffer);
  330. }
  331. static void snd_pcm_substream_proc_hw_params_read(struct snd_info_entry *entry,
  332. struct snd_info_buffer *buffer)
  333. {
  334. struct snd_pcm_substream *substream = entry->private_data;
  335. struct snd_pcm_runtime *runtime;
  336. guard(mutex)(&substream->pcm->open_mutex);
  337. runtime = substream->runtime;
  338. if (!runtime) {
  339. snd_iprintf(buffer, "closed\n");
  340. return;
  341. }
  342. if (runtime->state == SNDRV_PCM_STATE_OPEN) {
  343. snd_iprintf(buffer, "no setup\n");
  344. return;
  345. }
  346. snd_iprintf(buffer, "access: %s\n", snd_pcm_access_name(runtime->access));
  347. snd_iprintf(buffer, "format: %s\n", snd_pcm_format_name(runtime->format));
  348. snd_iprintf(buffer, "subformat: %s\n", snd_pcm_subformat_name(runtime->subformat));
  349. snd_iprintf(buffer, "channels: %u\n", runtime->channels);
  350. snd_iprintf(buffer, "rate: %u (%u/%u)\n", runtime->rate, runtime->rate_num, runtime->rate_den);
  351. snd_iprintf(buffer, "period_size: %lu\n", runtime->period_size);
  352. snd_iprintf(buffer, "buffer_size: %lu\n", runtime->buffer_size);
  353. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  354. if (substream->oss.oss) {
  355. snd_iprintf(buffer, "OSS format: %s\n", snd_pcm_oss_format_name(runtime->oss.format));
  356. snd_iprintf(buffer, "OSS channels: %u\n", runtime->oss.channels);
  357. snd_iprintf(buffer, "OSS rate: %u\n", runtime->oss.rate);
  358. snd_iprintf(buffer, "OSS period bytes: %lu\n", (unsigned long)runtime->oss.period_bytes);
  359. snd_iprintf(buffer, "OSS periods: %u\n", runtime->oss.periods);
  360. snd_iprintf(buffer, "OSS period frames: %lu\n", (unsigned long)runtime->oss.period_frames);
  361. }
  362. #endif
  363. }
  364. static void snd_pcm_substream_proc_sw_params_read(struct snd_info_entry *entry,
  365. struct snd_info_buffer *buffer)
  366. {
  367. struct snd_pcm_substream *substream = entry->private_data;
  368. struct snd_pcm_runtime *runtime;
  369. guard(mutex)(&substream->pcm->open_mutex);
  370. runtime = substream->runtime;
  371. if (!runtime) {
  372. snd_iprintf(buffer, "closed\n");
  373. return;
  374. }
  375. if (runtime->state == SNDRV_PCM_STATE_OPEN) {
  376. snd_iprintf(buffer, "no setup\n");
  377. return;
  378. }
  379. snd_iprintf(buffer, "tstamp_mode: %s\n", snd_pcm_tstamp_mode_name(runtime->tstamp_mode));
  380. snd_iprintf(buffer, "period_step: %u\n", runtime->period_step);
  381. snd_iprintf(buffer, "avail_min: %lu\n", runtime->control->avail_min);
  382. snd_iprintf(buffer, "start_threshold: %lu\n", runtime->start_threshold);
  383. snd_iprintf(buffer, "stop_threshold: %lu\n", runtime->stop_threshold);
  384. snd_iprintf(buffer, "silence_threshold: %lu\n", runtime->silence_threshold);
  385. snd_iprintf(buffer, "silence_size: %lu\n", runtime->silence_size);
  386. snd_iprintf(buffer, "boundary: %lu\n", runtime->boundary);
  387. }
  388. static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
  389. struct snd_info_buffer *buffer)
  390. {
  391. struct snd_pcm_substream *substream = entry->private_data;
  392. struct snd_pcm_runtime *runtime;
  393. struct snd_pcm_status64 status;
  394. int err;
  395. guard(mutex)(&substream->pcm->open_mutex);
  396. runtime = substream->runtime;
  397. if (!runtime) {
  398. snd_iprintf(buffer, "closed\n");
  399. return;
  400. }
  401. memset(&status, 0, sizeof(status));
  402. err = snd_pcm_status64(substream, &status);
  403. if (err < 0) {
  404. snd_iprintf(buffer, "error %d\n", err);
  405. return;
  406. }
  407. snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
  408. snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
  409. snd_iprintf(buffer, "trigger_time: %lld.%09lld\n",
  410. status.trigger_tstamp_sec, status.trigger_tstamp_nsec);
  411. snd_iprintf(buffer, "tstamp : %lld.%09lld\n",
  412. status.tstamp_sec, status.tstamp_nsec);
  413. snd_iprintf(buffer, "delay : %ld\n", status.delay);
  414. snd_iprintf(buffer, "avail : %ld\n", status.avail);
  415. snd_iprintf(buffer, "avail_max : %ld\n", status.avail_max);
  416. snd_iprintf(buffer, "-----\n");
  417. snd_iprintf(buffer, "hw_ptr : %ld\n", runtime->status->hw_ptr);
  418. snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
  419. #ifdef CONFIG_SND_PCM_XRUN_DEBUG
  420. snd_iprintf(buffer, "xrun_counter: %d\n", substream->xrun_counter);
  421. #endif
  422. }
  423. #ifdef CONFIG_SND_PCM_XRUN_DEBUG
  424. static void snd_pcm_xrun_injection_write(struct snd_info_entry *entry,
  425. struct snd_info_buffer *buffer)
  426. {
  427. struct snd_pcm_substream *substream = entry->private_data;
  428. snd_pcm_stop_xrun(substream);
  429. }
  430. static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
  431. struct snd_info_buffer *buffer)
  432. {
  433. struct snd_pcm_str *pstr = entry->private_data;
  434. snd_iprintf(buffer, "%d\n", pstr->xrun_debug);
  435. }
  436. static void snd_pcm_xrun_debug_write(struct snd_info_entry *entry,
  437. struct snd_info_buffer *buffer)
  438. {
  439. struct snd_pcm_str *pstr = entry->private_data;
  440. char line[64];
  441. if (!snd_info_get_line(buffer, line, sizeof(line)))
  442. pstr->xrun_debug = simple_strtoul(line, NULL, 10);
  443. }
  444. #endif
  445. static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
  446. {
  447. struct snd_pcm *pcm = pstr->pcm;
  448. struct snd_info_entry *entry;
  449. char name[16];
  450. sprintf(name, "pcm%i%c", pcm->device,
  451. pstr->stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
  452. entry = snd_info_create_card_entry(pcm->card, name,
  453. pcm->card->proc_root);
  454. if (!entry)
  455. return -ENOMEM;
  456. entry->mode = S_IFDIR | 0555;
  457. pstr->proc_root = entry;
  458. entry = snd_info_create_card_entry(pcm->card, "info", pstr->proc_root);
  459. if (entry)
  460. snd_info_set_text_ops(entry, pstr, snd_pcm_stream_proc_info_read);
  461. #ifdef CONFIG_SND_PCM_XRUN_DEBUG
  462. entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
  463. pstr->proc_root);
  464. if (entry) {
  465. snd_info_set_text_ops(entry, pstr, snd_pcm_xrun_debug_read);
  466. entry->c.text.write = snd_pcm_xrun_debug_write;
  467. entry->mode |= 0200;
  468. }
  469. #endif
  470. return 0;
  471. }
  472. static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
  473. {
  474. snd_info_free_entry(pstr->proc_root);
  475. pstr->proc_root = NULL;
  476. return 0;
  477. }
  478. static struct snd_info_entry *
  479. create_substream_info_entry(struct snd_pcm_substream *substream,
  480. const char *name,
  481. void (*read)(struct snd_info_entry *,
  482. struct snd_info_buffer *))
  483. {
  484. struct snd_info_entry *entry;
  485. entry = snd_info_create_card_entry(substream->pcm->card, name,
  486. substream->proc_root);
  487. if (entry)
  488. snd_info_set_text_ops(entry, substream, read);
  489. return entry;
  490. }
  491. static int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream)
  492. {
  493. struct snd_info_entry *entry;
  494. struct snd_card *card;
  495. char name[16];
  496. card = substream->pcm->card;
  497. sprintf(name, "sub%i", substream->number);
  498. entry = snd_info_create_card_entry(card, name,
  499. substream->pstr->proc_root);
  500. if (!entry)
  501. return -ENOMEM;
  502. entry->mode = S_IFDIR | 0555;
  503. substream->proc_root = entry;
  504. create_substream_info_entry(substream, "info",
  505. snd_pcm_substream_proc_info_read);
  506. create_substream_info_entry(substream, "hw_params",
  507. snd_pcm_substream_proc_hw_params_read);
  508. create_substream_info_entry(substream, "sw_params",
  509. snd_pcm_substream_proc_sw_params_read);
  510. create_substream_info_entry(substream, "status",
  511. snd_pcm_substream_proc_status_read);
  512. #ifdef CONFIG_SND_PCM_XRUN_DEBUG
  513. entry = create_substream_info_entry(substream, "xrun_injection", NULL);
  514. if (entry) {
  515. entry->c.text.write = snd_pcm_xrun_injection_write;
  516. entry->mode = S_IFREG | 0200;
  517. }
  518. #endif /* CONFIG_SND_PCM_XRUN_DEBUG */
  519. return 0;
  520. }
  521. #else /* !CONFIG_SND_VERBOSE_PROCFS */
  522. static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
  523. static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
  524. static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
  525. #endif /* CONFIG_SND_VERBOSE_PROCFS */
  526. static const struct attribute_group *pcm_dev_attr_groups[];
  527. /*
  528. * PM callbacks: we need to deal only with suspend here, as the resume is
  529. * triggered either from user-space or the driver's resume callback
  530. */
  531. static int do_pcm_suspend(struct device *dev)
  532. {
  533. struct snd_pcm_str *pstr = dev_get_drvdata(dev);
  534. if (!pstr->pcm->no_device_suspend)
  535. snd_pcm_suspend_all(pstr->pcm);
  536. return 0;
  537. }
  538. static const struct dev_pm_ops pcm_dev_pm_ops = {
  539. SYSTEM_SLEEP_PM_OPS(do_pcm_suspend, NULL)
  540. };
  541. /* device type for PCM -- basically only for passing PM callbacks */
  542. static const struct device_type pcm_dev_type = {
  543. .name = "pcm",
  544. .pm = &pcm_dev_pm_ops,
  545. };
  546. /**
  547. * snd_pcm_new_stream - create a new PCM stream
  548. * @pcm: the pcm instance
  549. * @stream: the stream direction, SNDRV_PCM_STREAM_XXX
  550. * @substream_count: the number of substreams
  551. *
  552. * Creates a new stream for the pcm.
  553. * The corresponding stream on the pcm must have been empty before
  554. * calling this, i.e. zero must be given to the argument of
  555. * snd_pcm_new().
  556. *
  557. * Return: Zero if successful, or a negative error code on failure.
  558. */
  559. int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
  560. {
  561. int idx, err;
  562. struct snd_pcm_str *pstr = &pcm->streams[stream];
  563. struct snd_pcm_substream *substream, *prev;
  564. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  565. mutex_init(&pstr->oss.setup_mutex);
  566. #endif
  567. pstr->stream = stream;
  568. pstr->pcm = pcm;
  569. pstr->substream_count = substream_count;
  570. if (!substream_count)
  571. return 0;
  572. err = snd_device_alloc(&pstr->dev, pcm->card);
  573. if (err < 0)
  574. return err;
  575. dev_set_name(pstr->dev, "pcmC%iD%i%c", pcm->card->number, pcm->device,
  576. stream == SNDRV_PCM_STREAM_PLAYBACK ? 'p' : 'c');
  577. pstr->dev->groups = pcm_dev_attr_groups;
  578. pstr->dev->type = &pcm_dev_type;
  579. dev_set_drvdata(pstr->dev, pstr);
  580. if (!pcm->internal) {
  581. err = snd_pcm_stream_proc_init(pstr);
  582. if (err < 0) {
  583. pcm_err(pcm, "Error in snd_pcm_stream_proc_init\n");
  584. return err;
  585. }
  586. }
  587. prev = NULL;
  588. for (idx = 0, prev = NULL; idx < substream_count; idx++) {
  589. substream = kzalloc_obj(*substream);
  590. if (!substream)
  591. return -ENOMEM;
  592. substream->pcm = pcm;
  593. substream->pstr = pstr;
  594. substream->number = idx;
  595. substream->stream = stream;
  596. sprintf(substream->name, "subdevice #%i", idx);
  597. substream->buffer_bytes_max = UINT_MAX;
  598. if (prev == NULL)
  599. pstr->substream = substream;
  600. else
  601. prev->next = substream;
  602. if (!pcm->internal) {
  603. err = snd_pcm_substream_proc_init(substream);
  604. if (err < 0) {
  605. pcm_err(pcm,
  606. "Error in snd_pcm_stream_proc_init\n");
  607. if (prev == NULL)
  608. pstr->substream = NULL;
  609. else
  610. prev->next = NULL;
  611. kfree(substream);
  612. return err;
  613. }
  614. }
  615. substream->group = &substream->self_group;
  616. snd_pcm_group_init(&substream->self_group);
  617. list_add_tail(&substream->link_list, &substream->self_group.substreams);
  618. atomic_set(&substream->mmap_count, 0);
  619. prev = substream;
  620. }
  621. return 0;
  622. }
  623. EXPORT_SYMBOL(snd_pcm_new_stream);
  624. static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
  625. int playback_count, int capture_count, bool internal,
  626. struct snd_pcm **rpcm)
  627. {
  628. struct snd_pcm *pcm;
  629. int err;
  630. static const struct snd_device_ops ops = {
  631. .dev_free = snd_pcm_dev_free,
  632. .dev_register = snd_pcm_dev_register,
  633. .dev_disconnect = snd_pcm_dev_disconnect,
  634. };
  635. static const struct snd_device_ops internal_ops = {
  636. .dev_free = snd_pcm_dev_free,
  637. };
  638. if (snd_BUG_ON(!card))
  639. return -ENXIO;
  640. if (rpcm)
  641. *rpcm = NULL;
  642. pcm = kzalloc_obj(*pcm);
  643. if (!pcm)
  644. return -ENOMEM;
  645. pcm->card = card;
  646. pcm->device = device;
  647. pcm->internal = internal;
  648. mutex_init(&pcm->open_mutex);
  649. init_waitqueue_head(&pcm->open_wait);
  650. INIT_LIST_HEAD(&pcm->list);
  651. if (id)
  652. strscpy(pcm->id, id, sizeof(pcm->id));
  653. err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK,
  654. playback_count);
  655. if (err < 0)
  656. goto free_pcm;
  657. err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_CAPTURE, capture_count);
  658. if (err < 0)
  659. goto free_pcm;
  660. err = snd_device_new(card, SNDRV_DEV_PCM, pcm,
  661. internal ? &internal_ops : &ops);
  662. if (err < 0)
  663. goto free_pcm;
  664. if (rpcm)
  665. *rpcm = pcm;
  666. return 0;
  667. free_pcm:
  668. snd_pcm_free(pcm);
  669. return err;
  670. }
  671. /**
  672. * snd_pcm_new - create a new PCM instance
  673. * @card: the card instance
  674. * @id: the id string
  675. * @device: the device index (zero based)
  676. * @playback_count: the number of substreams for playback
  677. * @capture_count: the number of substreams for capture
  678. * @rpcm: the pointer to store the new pcm instance
  679. *
  680. * Creates a new PCM instance.
  681. *
  682. * The pcm operators have to be set afterwards to the new instance
  683. * via snd_pcm_set_ops().
  684. *
  685. * Return: Zero if successful, or a negative error code on failure.
  686. */
  687. int snd_pcm_new(struct snd_card *card, const char *id, int device,
  688. int playback_count, int capture_count, struct snd_pcm **rpcm)
  689. {
  690. return _snd_pcm_new(card, id, device, playback_count, capture_count,
  691. false, rpcm);
  692. }
  693. EXPORT_SYMBOL(snd_pcm_new);
  694. /**
  695. * snd_pcm_new_internal - create a new internal PCM instance
  696. * @card: the card instance
  697. * @id: the id string
  698. * @device: the device index (zero based - shared with normal PCMs)
  699. * @playback_count: the number of substreams for playback
  700. * @capture_count: the number of substreams for capture
  701. * @rpcm: the pointer to store the new pcm instance
  702. *
  703. * Creates a new internal PCM instance with no userspace device or procfs
  704. * entries. This is used by ASoC Back End PCMs in order to create a PCM that
  705. * will only be used internally by kernel drivers. i.e. it cannot be opened
  706. * by userspace. It provides existing ASoC components drivers with a substream
  707. * and access to any private data.
  708. *
  709. * The pcm operators have to be set afterwards to the new instance
  710. * via snd_pcm_set_ops().
  711. *
  712. * Return: Zero if successful, or a negative error code on failure.
  713. */
  714. int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
  715. int playback_count, int capture_count,
  716. struct snd_pcm **rpcm)
  717. {
  718. return _snd_pcm_new(card, id, device, playback_count, capture_count,
  719. true, rpcm);
  720. }
  721. EXPORT_SYMBOL(snd_pcm_new_internal);
  722. static void free_chmap(struct snd_pcm_str *pstr)
  723. {
  724. if (pstr->chmap_kctl) {
  725. struct snd_card *card = pstr->pcm->card;
  726. snd_ctl_remove(card, pstr->chmap_kctl);
  727. pstr->chmap_kctl = NULL;
  728. }
  729. }
  730. static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
  731. {
  732. struct snd_pcm_substream *substream, *substream_next;
  733. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  734. struct snd_pcm_oss_setup *setup, *setupn;
  735. #endif
  736. /* free all proc files under the stream */
  737. snd_pcm_stream_proc_done(pstr);
  738. substream = pstr->substream;
  739. while (substream) {
  740. substream_next = substream->next;
  741. snd_pcm_timer_done(substream);
  742. kfree(substream);
  743. substream = substream_next;
  744. }
  745. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  746. for (setup = pstr->oss.setup_list; setup; setup = setupn) {
  747. setupn = setup->next;
  748. kfree(setup->task_name);
  749. kfree(setup);
  750. }
  751. #endif
  752. free_chmap(pstr);
  753. if (pstr->substream_count)
  754. put_device(pstr->dev);
  755. }
  756. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  757. #define pcm_call_notify(pcm, call) \
  758. do { \
  759. struct snd_pcm_notify *_notify; \
  760. list_for_each_entry(_notify, &snd_pcm_notify_list, list) \
  761. _notify->call(pcm); \
  762. } while (0)
  763. #else
  764. #define pcm_call_notify(pcm, call) do {} while (0)
  765. #endif
  766. static int snd_pcm_free(struct snd_pcm *pcm)
  767. {
  768. if (!pcm)
  769. return 0;
  770. if (!pcm->internal)
  771. pcm_call_notify(pcm, n_unregister);
  772. if (pcm->private_free)
  773. pcm->private_free(pcm);
  774. snd_pcm_lib_preallocate_free_for_all(pcm);
  775. snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK]);
  776. snd_pcm_free_stream(&pcm->streams[SNDRV_PCM_STREAM_CAPTURE]);
  777. kfree(pcm);
  778. return 0;
  779. }
  780. static int snd_pcm_dev_free(struct snd_device *device)
  781. {
  782. struct snd_pcm *pcm = device->device_data;
  783. return snd_pcm_free(pcm);
  784. }
  785. int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
  786. struct file *file,
  787. struct snd_pcm_substream **rsubstream)
  788. {
  789. struct snd_pcm_str * pstr;
  790. struct snd_pcm_substream *substream;
  791. struct snd_pcm_runtime *runtime;
  792. struct snd_card *card;
  793. int prefer_subdevice;
  794. size_t size;
  795. if (snd_BUG_ON(!pcm || !rsubstream))
  796. return -ENXIO;
  797. if (snd_BUG_ON(stream != SNDRV_PCM_STREAM_PLAYBACK &&
  798. stream != SNDRV_PCM_STREAM_CAPTURE))
  799. return -EINVAL;
  800. *rsubstream = NULL;
  801. pstr = &pcm->streams[stream];
  802. if (pstr->substream == NULL || pstr->substream_count == 0)
  803. return -ENODEV;
  804. card = pcm->card;
  805. prefer_subdevice = snd_ctl_get_preferred_subdevice(card, SND_CTL_SUBDEV_PCM);
  806. if (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX) {
  807. int opposite = !stream;
  808. for (substream = pcm->streams[opposite].substream; substream;
  809. substream = substream->next) {
  810. if (SUBSTREAM_BUSY(substream))
  811. return -EAGAIN;
  812. }
  813. }
  814. if (file->f_flags & O_APPEND) {
  815. if (prefer_subdevice < 0) {
  816. if (pstr->substream_count > 1)
  817. return -EINVAL; /* must be unique */
  818. substream = pstr->substream;
  819. } else {
  820. for (substream = pstr->substream; substream;
  821. substream = substream->next)
  822. if (substream->number == prefer_subdevice)
  823. break;
  824. }
  825. if (! substream)
  826. return -ENODEV;
  827. if (! SUBSTREAM_BUSY(substream))
  828. return -EBADFD;
  829. substream->ref_count++;
  830. *rsubstream = substream;
  831. return 0;
  832. }
  833. for (substream = pstr->substream; substream; substream = substream->next) {
  834. if (!SUBSTREAM_BUSY(substream) &&
  835. (prefer_subdevice == -1 ||
  836. substream->number == prefer_subdevice))
  837. break;
  838. }
  839. if (substream == NULL)
  840. return -EAGAIN;
  841. runtime = kzalloc_obj(*runtime);
  842. if (runtime == NULL)
  843. return -ENOMEM;
  844. size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status));
  845. runtime->status = alloc_pages_exact(size, GFP_KERNEL);
  846. if (runtime->status == NULL) {
  847. kfree(runtime);
  848. return -ENOMEM;
  849. }
  850. memset(runtime->status, 0, size);
  851. size = PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control));
  852. runtime->control = alloc_pages_exact(size, GFP_KERNEL);
  853. if (runtime->control == NULL) {
  854. free_pages_exact(runtime->status,
  855. PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
  856. kfree(runtime);
  857. return -ENOMEM;
  858. }
  859. memset(runtime->control, 0, size);
  860. init_waitqueue_head(&runtime->sleep);
  861. init_waitqueue_head(&runtime->tsleep);
  862. __snd_pcm_set_state(runtime, SNDRV_PCM_STATE_OPEN);
  863. mutex_init(&runtime->buffer_mutex);
  864. atomic_set(&runtime->buffer_accessing, 0);
  865. substream->runtime = runtime;
  866. substream->private_data = pcm->private_data;
  867. substream->ref_count = 1;
  868. substream->f_flags = file->f_flags;
  869. substream->pid = get_pid(task_pid(current));
  870. pstr->substream_opened++;
  871. *rsubstream = substream;
  872. #ifdef CONFIG_SND_PCM_XRUN_DEBUG
  873. substream->xrun_counter = 0;
  874. #endif /* CONFIG_SND_PCM_XRUN_DEBUG */
  875. return 0;
  876. }
  877. void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
  878. {
  879. struct snd_pcm_runtime *runtime;
  880. if (PCM_RUNTIME_CHECK(substream))
  881. return;
  882. runtime = substream->runtime;
  883. if (runtime->private_free != NULL)
  884. runtime->private_free(runtime);
  885. free_pages_exact(runtime->status,
  886. PAGE_ALIGN(sizeof(struct snd_pcm_mmap_status)));
  887. free_pages_exact(runtime->control,
  888. PAGE_ALIGN(sizeof(struct snd_pcm_mmap_control)));
  889. kfree(runtime->hw_constraints.rules);
  890. /* Avoid concurrent access to runtime via PCM timer interface */
  891. if (substream->timer) {
  892. scoped_guard(spinlock_irq, &substream->timer->lock)
  893. substream->runtime = NULL;
  894. } else {
  895. substream->runtime = NULL;
  896. }
  897. mutex_destroy(&runtime->buffer_mutex);
  898. snd_fasync_free(runtime->fasync);
  899. kfree(runtime);
  900. put_pid(substream->pid);
  901. substream->pid = NULL;
  902. substream->pstr->substream_opened--;
  903. }
  904. static ssize_t pcm_class_show(struct device *dev,
  905. struct device_attribute *attr, char *buf)
  906. {
  907. struct snd_pcm_str *pstr = dev_get_drvdata(dev);
  908. struct snd_pcm *pcm = pstr->pcm;
  909. const char *str;
  910. static const char *strs[SNDRV_PCM_CLASS_LAST + 1] = {
  911. [SNDRV_PCM_CLASS_GENERIC] = "generic",
  912. [SNDRV_PCM_CLASS_MULTI] = "multi",
  913. [SNDRV_PCM_CLASS_MODEM] = "modem",
  914. [SNDRV_PCM_CLASS_DIGITIZER] = "digitizer",
  915. };
  916. if (pcm->dev_class > SNDRV_PCM_CLASS_LAST)
  917. str = "none";
  918. else
  919. str = strs[pcm->dev_class];
  920. return sysfs_emit(buf, "%s\n", str);
  921. }
  922. static DEVICE_ATTR_RO(pcm_class);
  923. static struct attribute *pcm_dev_attrs[] = {
  924. &dev_attr_pcm_class.attr,
  925. NULL
  926. };
  927. static const struct attribute_group pcm_dev_attr_group = {
  928. .attrs = pcm_dev_attrs,
  929. };
  930. static const struct attribute_group *pcm_dev_attr_groups[] = {
  931. &pcm_dev_attr_group,
  932. NULL
  933. };
  934. static int snd_pcm_dev_register(struct snd_device *device)
  935. {
  936. int cidx, err;
  937. struct snd_pcm_substream *substream;
  938. struct snd_pcm *pcm;
  939. if (snd_BUG_ON(!device || !device->device_data))
  940. return -ENXIO;
  941. pcm = device->device_data;
  942. guard(mutex)(&register_mutex);
  943. err = snd_pcm_add(pcm);
  944. if (err)
  945. return err;
  946. for (cidx = 0; cidx < 2; cidx++) {
  947. int devtype = -1;
  948. if (pcm->streams[cidx].substream == NULL)
  949. continue;
  950. switch (cidx) {
  951. case SNDRV_PCM_STREAM_PLAYBACK:
  952. devtype = SNDRV_DEVICE_TYPE_PCM_PLAYBACK;
  953. break;
  954. case SNDRV_PCM_STREAM_CAPTURE:
  955. devtype = SNDRV_DEVICE_TYPE_PCM_CAPTURE;
  956. break;
  957. }
  958. /* register pcm */
  959. err = snd_register_device(devtype, pcm->card, pcm->device,
  960. &snd_pcm_f_ops[cidx], pcm,
  961. pcm->streams[cidx].dev);
  962. if (err < 0) {
  963. list_del_init(&pcm->list);
  964. return err;
  965. }
  966. for (substream = pcm->streams[cidx].substream; substream; substream = substream->next)
  967. snd_pcm_timer_init(substream);
  968. }
  969. pcm_call_notify(pcm, n_register);
  970. return err;
  971. }
  972. static int snd_pcm_dev_disconnect(struct snd_device *device)
  973. {
  974. struct snd_pcm *pcm = device->device_data;
  975. struct snd_pcm_substream *substream;
  976. int cidx;
  977. guard(mutex)(&register_mutex);
  978. guard(mutex)(&pcm->open_mutex);
  979. wake_up(&pcm->open_wait);
  980. list_del_init(&pcm->list);
  981. for_each_pcm_substream(pcm, cidx, substream) {
  982. snd_pcm_stream_lock_irq(substream);
  983. if (substream->runtime) {
  984. if (snd_pcm_running(substream))
  985. snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
  986. /* to be sure, set the state unconditionally */
  987. __snd_pcm_set_state(substream->runtime,
  988. SNDRV_PCM_STATE_DISCONNECTED);
  989. wake_up(&substream->runtime->sleep);
  990. wake_up(&substream->runtime->tsleep);
  991. }
  992. snd_pcm_stream_unlock_irq(substream);
  993. }
  994. for_each_pcm_substream(pcm, cidx, substream)
  995. snd_pcm_sync_stop(substream, false);
  996. pcm_call_notify(pcm, n_disconnect);
  997. for (cidx = 0; cidx < 2; cidx++) {
  998. if (pcm->streams[cidx].dev)
  999. snd_unregister_device(pcm->streams[cidx].dev);
  1000. free_chmap(&pcm->streams[cidx]);
  1001. }
  1002. return 0;
  1003. }
  1004. #if IS_ENABLED(CONFIG_SND_PCM_OSS)
  1005. /**
  1006. * snd_pcm_notify - Add/remove the notify list
  1007. * @notify: PCM notify list
  1008. * @nfree: 0 = register, 1 = unregister
  1009. *
  1010. * This adds the given notifier to the global list so that the callback is
  1011. * called for each registered PCM devices. This exists only for PCM OSS
  1012. * emulation, so far.
  1013. *
  1014. * Return: zero if successful, or a negative error code
  1015. */
  1016. int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
  1017. {
  1018. struct snd_pcm *pcm;
  1019. if (snd_BUG_ON(!notify ||
  1020. !notify->n_register ||
  1021. !notify->n_unregister ||
  1022. !notify->n_disconnect))
  1023. return -EINVAL;
  1024. guard(mutex)(&register_mutex);
  1025. if (nfree) {
  1026. list_del(&notify->list);
  1027. list_for_each_entry(pcm, &snd_pcm_devices, list)
  1028. notify->n_unregister(pcm);
  1029. } else {
  1030. list_add_tail(&notify->list, &snd_pcm_notify_list);
  1031. list_for_each_entry(pcm, &snd_pcm_devices, list)
  1032. notify->n_register(pcm);
  1033. }
  1034. return 0;
  1035. }
  1036. EXPORT_SYMBOL(snd_pcm_notify);
  1037. #endif /* CONFIG_SND_PCM_OSS */
  1038. #ifdef CONFIG_SND_PROC_FS
  1039. /*
  1040. * Info interface
  1041. */
  1042. static void snd_pcm_proc_read(struct snd_info_entry *entry,
  1043. struct snd_info_buffer *buffer)
  1044. {
  1045. struct snd_pcm *pcm;
  1046. guard(mutex)(&register_mutex);
  1047. list_for_each_entry(pcm, &snd_pcm_devices, list) {
  1048. snd_iprintf(buffer, "%02i-%02i: %s : %s",
  1049. pcm->card->number, pcm->device, pcm->id, pcm->name);
  1050. if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream)
  1051. snd_iprintf(buffer, " : playback %i",
  1052. pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count);
  1053. if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream)
  1054. snd_iprintf(buffer, " : capture %i",
  1055. pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count);
  1056. snd_iprintf(buffer, "\n");
  1057. }
  1058. }
  1059. static struct snd_info_entry *snd_pcm_proc_entry;
  1060. static void snd_pcm_proc_init(void)
  1061. {
  1062. struct snd_info_entry *entry;
  1063. entry = snd_info_create_module_entry(THIS_MODULE, "pcm", NULL);
  1064. if (entry) {
  1065. snd_info_set_text_ops(entry, NULL, snd_pcm_proc_read);
  1066. if (snd_info_register(entry) < 0) {
  1067. snd_info_free_entry(entry);
  1068. entry = NULL;
  1069. }
  1070. }
  1071. snd_pcm_proc_entry = entry;
  1072. }
  1073. static void snd_pcm_proc_done(void)
  1074. {
  1075. snd_info_free_entry(snd_pcm_proc_entry);
  1076. }
  1077. #else /* !CONFIG_SND_PROC_FS */
  1078. #define snd_pcm_proc_init()
  1079. #define snd_pcm_proc_done()
  1080. #endif /* CONFIG_SND_PROC_FS */
  1081. /*
  1082. * ENTRY functions
  1083. */
  1084. static int __init alsa_pcm_init(void)
  1085. {
  1086. snd_ctl_register_ioctl(snd_pcm_control_ioctl);
  1087. snd_ctl_register_ioctl_compat(snd_pcm_control_ioctl);
  1088. snd_pcm_proc_init();
  1089. return 0;
  1090. }
  1091. static void __exit alsa_pcm_exit(void)
  1092. {
  1093. snd_ctl_unregister_ioctl(snd_pcm_control_ioctl);
  1094. snd_ctl_unregister_ioctl_compat(snd_pcm_control_ioctl);
  1095. snd_pcm_proc_done();
  1096. }
  1097. module_init(alsa_pcm_init)
  1098. module_exit(alsa_pcm_exit)