1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Chapter&#160;12.&#160;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&#160;13.&#160;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&#160;12.&#160;Proc Interface</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="buffer-and-memory-vmalloced.html">Prev</a>&#160;</td><th width="60%" align="center">&#160;</th><td width="20%" align="right">&#160;<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&#160;12.&#160;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">&lt;sound/info.h&gt;</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", &amp;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-&gt;private_data;
65
66          snd_iprintf(buffer, "This is my chip!\n");
67          snd_iprintf(buffer, "Port = %ld\n", chip-&gt;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-&gt;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-&gt;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-&gt;content = SNDRV_INFO_CONTENT_DATA;
106  entry-&gt;private_data = chip;
107  entry-&gt;c.ops = &amp;my_file_io_ops;
108  entry-&gt;size = 4096;
109  entry-&gt;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>&#160;</td><td width="20%" align="center">&#160;</td><td width="40%" align="right">&#160;<a accesskey="n" href="power-management.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Vmalloc'ed Buffers&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Chapter&#160;13.&#160;Power Management</td></tr></table></div></body></html>
144