1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter 12. Proc Interface</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Writing an ALSA Driver"><link rel="up" href="index.html" title="Writing an ALSA Driver"><link rel="prev" href="buffer-and-memory-vmalloced.html" title="Vmalloc'ed Buffers"><link rel="next" href="power-management.html" title="Chapter 13. Power Management"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter 12. Proc Interface</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="buffer-and-memory-vmalloced.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="power-management.html">Next</a></td></tr></table><hr></div><div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="proc-interface"></a>Chapter 12. Proc Interface</h1></div></div></div><p> 2 ALSA provides an easy interface for procfs. The proc files are 3 very useful for debugging. I recommend you set up proc files if 4 you write a driver and want to get a running status or register 5 dumps. The API is found in 6 <code class="filename"><sound/info.h></code>. 7 </p><p> 8 To create a proc file, call 9 <code class="function">snd_card_proc_new()</code>. 10 11 </p><div class="informalexample"><pre class="programlisting"> 12 13 struct snd_info_entry *entry; 14 int err = snd_card_proc_new(card, "my-file", &entry); 15 16 </pre></div><p> 17 18 where the second argument specifies the name of the proc file to be 19 created. The above example will create a file 20 <code class="filename">my-file</code> under the card directory, 21 e.g. <code class="filename">/proc/asound/card0/my-file</code>. 22 </p><p> 23 Like other components, the proc entry created via 24 <code class="function">snd_card_proc_new()</code> will be registered and 25 released automatically in the card registration and release 26 functions. 27 </p><p> 28 When the creation is successful, the function stores a new 29 instance in the pointer given in the third argument. 30 It is initialized as a text proc file for read only. To use 31 this proc file as a read-only text file as it is, set the read 32 callback with a private data via 33 <code class="function">snd_info_set_text_ops()</code>. 34 35 </p><div class="informalexample"><pre class="programlisting"> 36 37 snd_info_set_text_ops(entry, chip, my_proc_read); 38 39 </pre></div><p> 40 41 where the second argument (<em class="parameter"><code>chip</code></em>) is the 42 private data to be used in the callbacks. The third parameter 43 specifies the read buffer size and the fourth 44 (<em class="parameter"><code>my_proc_read</code></em>) is the callback function, which 45 is defined like 46 47 </p><div class="informalexample"><pre class="programlisting"> 48 49 static void my_proc_read(struct snd_info_entry *entry, 50 struct snd_info_buffer *buffer); 51 52 </pre></div><p> 53 54 </p><p> 55 In the read callback, use <code class="function">snd_iprintf()</code> for 56 output strings, which works just like normal 57 <code class="function">printf()</code>. For example, 58 59 </p><div class="informalexample"><pre class="programlisting"> 60 61 static void my_proc_read(struct snd_info_entry *entry, 62 struct snd_info_buffer *buffer) 63 { 64 struct my_chip *chip = entry->private_data; 65 66 snd_iprintf(buffer, "This is my chip!\n"); 67 snd_iprintf(buffer, "Port = %ld\n", chip->port); 68 } 69 70 </pre></div><p> 71 </p><p> 72 The file permissions can be changed afterwards. As default, it's 73 set as read only for all users. If you want to add write 74 permission for the user (root as default), do as follows: 75 76 </p><div class="informalexample"><pre class="programlisting"> 77 78 entry->mode = S_IFREG | S_IRUGO | S_IWUSR; 79 80 </pre></div><p> 81 82 and set the write buffer size and the callback 83 84 </p><div class="informalexample"><pre class="programlisting"> 85 86 entry->c.text.write = my_proc_write; 87 88 </pre></div><p> 89 </p><p> 90 For the write callback, you can use 91 <code class="function">snd_info_get_line()</code> to get a text line, and 92 <code class="function">snd_info_get_str()</code> to retrieve a string from 93 the line. Some examples are found in 94 <code class="filename">core/oss/mixer_oss.c</code>, core/oss/and 95 <code class="filename">pcm_oss.c</code>. 96 </p><p> 97 For a raw-data proc-file, set the attributes as follows: 98 99 </p><div class="informalexample"><pre class="programlisting"> 100 101 static struct snd_info_entry_ops my_file_io_ops = { 102 .read = my_file_io_read, 103 }; 104 105 entry->content = SNDRV_INFO_CONTENT_DATA; 106 entry->private_data = chip; 107 entry->c.ops = &my_file_io_ops; 108 entry->size = 4096; 109 entry->mode = S_IFREG | S_IRUGO; 110 111 </pre></div><p> 112 113 For the raw data, <em class="structfield"><code>size</code></em> field must be 114 set properly. This specifies the maximum size of the proc file access. 115 </p><p> 116 The read/write callbacks of raw mode are more direct than the text mode. 117 You need to use a low-level I/O functions such as 118 <code class="function">copy_from/to_user()</code> to transfer the 119 data. 120 121 </p><div class="informalexample"><pre class="programlisting"> 122 123 static ssize_t my_file_io_read(struct snd_info_entry *entry, 124 void *file_private_data, 125 struct file *file, 126 char *buf, 127 size_t count, 128 loff_t pos) 129 { 130 if (copy_to_user(buf, local_data + pos, count)) 131 return -EFAULT; 132 return count; 133 } 134 135 </pre></div><p> 136 137 If the size of the info entry has been set up properly, 138 <em class="structfield"><code>count</code></em> and <em class="structfield"><code>pos</code></em> are 139 guaranteed to fit within 0 and the given size. 140 You don't have to check the range in the callbacks unless any 141 other condition is required. 142 143 </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="buffer-and-memory-vmalloced.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="power-management.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Vmalloc'ed Buffers </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 13. Power Management</td></tr></table></div></body></html> 144