1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>Xenomai API: include/analogy/buffer.h Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.5.6 -->
<div class="navigation" id="top">
<div class="tabs">
<ul>
<li><a href="main.html"><span>Main Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data Structures</span></a></li>
<li class="current"><a href="files.html"><span>Files</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
<li>
<form action="search.php" method="get">
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td><label> <u>S</u>earch for </label></td>
<td><input type="text" name="query" value="" size="20" accesskey="s"/></td>
</tr>
</table>
</form>
</li>
</ul>
</div>
<h1>include/analogy/buffer.h</h1><a href="analogy_2buffer_8h.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001
<a name="l00023"></a>00023 <span class="preprocessor">#ifndef __ANALOGY_BUFFER_H__</span>
<a name="l00024"></a>00024 <span class="preprocessor"></span><span class="preprocessor">#define __ANALOGY_BUFFER_H__</span>
<a name="l00025"></a>00025 <span class="preprocessor"></span>
<a name="l00026"></a>00026 <span class="preprocessor">#ifndef DOXYGEN_CPP</span>
<a name="l00027"></a>00027 <span class="preprocessor"></span>
<a name="l00028"></a>00028 <span class="preprocessor">#ifdef __KERNEL__</span>
<a name="l00029"></a>00029 <span class="preprocessor"></span>
<a name="l00030"></a>00030 <span class="preprocessor">#include <linux/version.h></span>
<a name="l00031"></a>00031 <span class="preprocessor">#include <linux/mm.h></span>
<a name="l00032"></a>00032
<a name="l00033"></a>00033 <span class="preprocessor">#include <<a class="code" href="rtdm__driver_8h.html" title="Real-Time Driver Model for Xenomai, driver API header.">rtdm/rtdm_driver.h</a>></span>
<a name="l00034"></a>00034
<a name="l00035"></a>00035 <span class="preprocessor">#include <<a class="code" href="os__facilities_8h.html" title="Analogy for Linux, Operation system facilities.">analogy/os_facilities.h</a>></span>
<a name="l00036"></a>00036 <span class="preprocessor">#include <<a class="code" href="context_8h.html" title="Analogy for Linux, context structure / macros declarations.">analogy/context.h</a>></span>
<a name="l00037"></a>00037
<a name="l00038"></a>00038 <span class="comment">/* --- Events bits / flags --- */</span>
<a name="l00039"></a>00039
<a name="l00040"></a>00040 <span class="preprocessor">#define A4L_BUF_EOBUF_NR 0</span>
<a name="l00041"></a>00041 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_EOBUF (1 << A4L_BUF_EOBUF_NR)</span>
<a name="l00042"></a>00042 <span class="preprocessor"></span>
<a name="l00043"></a>00043 <span class="preprocessor">#define A4L_BUF_ERROR_NR 1</span>
<a name="l00044"></a>00044 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_ERROR (1 << A4L_BUF_ERROR_NR)</span>
<a name="l00045"></a>00045 <span class="preprocessor"></span>
<a name="l00046"></a>00046 <span class="preprocessor">#define A4L_BUF_EOA_NR 2</span>
<a name="l00047"></a>00047 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_EOA (1 << A4L_BUF_EOA_NR)</span>
<a name="l00048"></a>00048 <span class="preprocessor"></span>
<a name="l00049"></a>00049 <span class="comment">/* --- Status bits / flags --- */</span>
<a name="l00050"></a>00050
<a name="l00051"></a>00051 <span class="preprocessor">#define A4L_BUF_BULK_NR 8</span>
<a name="l00052"></a>00052 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_BULK (1 << A4L_BUF_BULK_NR)</span>
<a name="l00053"></a>00053 <span class="preprocessor"></span>
<a name="l00054"></a>00054 <span class="preprocessor">#define A4L_BUF_MAP_NR 9</span>
<a name="l00055"></a>00055 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_MAP (1 << A4L_BUF_MAP_NR)</span>
<a name="l00056"></a>00056 <span class="preprocessor"></span>
<a name="l00057"></a>00057 <span class="keyword">struct </span><a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a>;
<a name="l00058"></a>00058
<a name="l00059"></a>00059 <span class="comment">/* Buffer descriptor structure */</span>
<a name="l00060"></a>00060 <span class="keyword">struct </span>a4l_buffer {
<a name="l00061"></a>00061
<a name="l00062"></a>00062 <span class="comment">/* Added by the structure update */</span>
<a name="l00063"></a>00063 <span class="keyword">struct </span><a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd;
<a name="l00064"></a>00064
<a name="l00065"></a>00065 <span class="comment">/* Buffer's first virtual page pointer */</span>
<a name="l00066"></a>00066 <span class="keywordtype">void</span> *<a class="code" href="structa4l__subdevice.html#102957cf30f6328e9b9cac05e4f980ec" title="Linked buffer.">buf</a>;
<a name="l00067"></a>00067
<a name="l00068"></a>00068 <span class="comment">/* Buffer's global size */</span>
<a name="l00069"></a>00069 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> size;
<a name="l00070"></a>00070 <span class="comment">/* Tab containing buffer's pages pointers */</span>
<a name="l00071"></a>00071 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> *pg_list;
<a name="l00072"></a>00072
<a name="l00073"></a>00073 <span class="comment">/* RT/NRT synchronization element */</span>
<a name="l00074"></a>00074 a4l_sync_t sync;
<a name="l00075"></a>00075
<a name="l00076"></a>00076 <span class="comment">/* Counters needed for transfer */</span>
<a name="l00077"></a>00077 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> end_count;
<a name="l00078"></a>00078 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> prd_count;
<a name="l00079"></a>00079 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> cns_count;
<a name="l00080"></a>00080 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> tmp_count;
<a name="l00081"></a>00081
<a name="l00082"></a>00082 <span class="comment">/* Status + events occuring during transfer */</span>
<a name="l00083"></a>00083 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="structa4l__subdevice.html#1c2510cef59e5ec58cb3edee397d886f" title="Type flags.">flags</a>;
<a name="l00084"></a>00084
<a name="l00085"></a>00085 <span class="comment">/* Command on progress */</span>
<a name="l00086"></a>00086 <a class="code" href="structa4l__cmd__desc.html" title="Structure describing the asynchronous instruction.">a4l_cmd_t</a> *cur_cmd;
<a name="l00087"></a>00087
<a name="l00088"></a>00088 <span class="comment">/* Munge counter */</span>
<a name="l00089"></a>00089 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> mng_count;
<a name="l00090"></a>00090 };
<a name="l00091"></a>00091 <span class="keyword">typedef</span> <span class="keyword">struct </span>a4l_buffer a4l_buf_t;
<a name="l00092"></a>00092
<a name="l00093"></a>00093 <span class="comment">/* Static inline Buffer related functions */</span>
<a name="l00094"></a>00094
<a name="l00095"></a>00095 <span class="comment">/* Produce memcpy function */</span>
<a name="l00096"></a>00096 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __produce(a4l_cxt_t *cxt,
<a name="l00097"></a>00097 a4l_buf_t *buf, <span class="keywordtype">void</span> *pin, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00098"></a>00098 {
<a name="l00099"></a>00099 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> start_ptr = (buf->prd_count % buf->size);
<a name="l00100"></a>00100 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> tmp_cnt = count;
<a name="l00101"></a>00101 <span class="keywordtype">int</span> ret = 0;
<a name="l00102"></a>00102
<a name="l00103"></a>00103 <span class="keywordflow">while</span> (ret == 0 && tmp_cnt != 0) {
<a name="l00104"></a>00104 <span class="comment">/* Check the data copy can be performed contiguously */</span>
<a name="l00105"></a>00105 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> blk_size = (start_ptr + tmp_cnt > buf->size) ?
<a name="l00106"></a>00106 buf->size - start_ptr : tmp_cnt;
<a name="l00107"></a>00107
<a name="l00108"></a>00108 <span class="comment">/* Perform the copy */</span>
<a name="l00109"></a>00109 if (cxt == NULL)
<a name="l00110"></a>00110 memcpy(buf->buf + start_ptr, pin, blk_size);
<a name="l00111"></a>00111 <span class="keywordflow">else</span>
<a name="l00112"></a>00112 ret = <a class="code" href="group__util.html#g8e2ada3a5665c1366cd2c91f304bfa34" title="Check if read access to user-space memory block and copy it to specified buffer.">rtdm_safe_copy_from_user</a>(cxt->user_info,
<a name="l00113"></a>00113 buf->buf + start_ptr,
<a name="l00114"></a>00114 pin, blk_size);
<a name="l00115"></a>00115
<a name="l00116"></a>00116 <span class="comment">/* Update pointers/counts */</span>
<a name="l00117"></a>00117 pin += blk_size;
<a name="l00118"></a>00118 tmp_cnt -= blk_size;
<a name="l00119"></a>00119 start_ptr = 0;
<a name="l00120"></a>00120 }
<a name="l00121"></a>00121
<a name="l00122"></a>00122 <span class="keywordflow">return</span> ret;
<a name="l00123"></a>00123 }
<a name="l00124"></a>00124
<a name="l00125"></a>00125 <span class="comment">/* Consume memcpy function */</span>
<a name="l00126"></a>00126 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __consume(a4l_cxt_t *cxt,
<a name="l00127"></a>00127 a4l_buf_t *buf, <span class="keywordtype">void</span> *pout, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00128"></a>00128 {
<a name="l00129"></a>00129 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> start_ptr = (buf->cns_count % buf->size);
<a name="l00130"></a>00130 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> tmp_cnt = count;
<a name="l00131"></a>00131 <span class="keywordtype">int</span> ret = 0;
<a name="l00132"></a>00132
<a name="l00133"></a>00133 <span class="keywordflow">while</span> (ret == 0 && tmp_cnt != 0) {
<a name="l00134"></a>00134 <span class="comment">/* Check the data copy can be performed contiguously */</span>
<a name="l00135"></a>00135 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> blk_size = (start_ptr + tmp_cnt > buf->size) ?
<a name="l00136"></a>00136 buf->size - start_ptr : tmp_cnt;
<a name="l00137"></a>00137
<a name="l00138"></a>00138 <span class="comment">/* Perform the copy */</span>
<a name="l00139"></a>00139 if (cxt == NULL)
<a name="l00140"></a>00140 memcpy(pout, buf->buf + start_ptr, blk_size);
<a name="l00141"></a>00141 <span class="keywordflow">else</span>
<a name="l00142"></a>00142 ret = <a class="code" href="group__util.html#g53f7bacd08774bfd26e13798cbfb21b8" title="Check if read/write access to user-space memory block is safe and copy specified...">rtdm_safe_copy_to_user</a>(cxt->user_info,
<a name="l00143"></a>00143 pout,
<a name="l00144"></a>00144 buf->buf + start_ptr,
<a name="l00145"></a>00145 blk_size);
<a name="l00146"></a>00146
<a name="l00147"></a>00147 <span class="comment">/* Update pointers/counts */</span>
<a name="l00148"></a>00148 pout += blk_size;
<a name="l00149"></a>00149 tmp_cnt -= blk_size;
<a name="l00150"></a>00150 start_ptr = 0;
<a name="l00151"></a>00151 }
<a name="l00152"></a>00152
<a name="l00153"></a>00153 <span class="keywordflow">return</span> ret;
<a name="l00154"></a>00154 }
<a name="l00155"></a>00155
<a name="l00156"></a>00156 <span class="comment">/* Munge procedure */</span>
<a name="l00157"></a>00157 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">void</span> __munge(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> * subd,
<a name="l00158"></a>00158 <span class="keywordtype">void</span> (*munge) (<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *,
<a name="l00159"></a>00159 <span class="keywordtype">void</span> *, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>),
<a name="l00160"></a>00160 a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00161"></a>00161 {
<a name="l00162"></a>00162 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> start_ptr = (buf->mng_count % buf->size);
<a name="l00163"></a>00163 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> tmp_cnt = count;
<a name="l00164"></a>00164
<a name="l00165"></a>00165 <span class="keywordflow">while</span> (tmp_cnt != 0) {
<a name="l00166"></a>00166 <span class="comment">/* Check the data copy can be performed contiguously */</span>
<a name="l00167"></a>00167 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> blk_size = (start_ptr + tmp_cnt > buf->size) ?
<a name="l00168"></a>00168 buf->size - start_ptr : tmp_cnt;
<a name="l00169"></a>00169
<a name="l00170"></a>00170 <span class="comment">/* Perform the munge operation */</span>
<a name="l00171"></a>00171 munge(subd, buf-><a class="code" href="structa4l__subdevice.html#102957cf30f6328e9b9cac05e4f980ec" title="Linked buffer.">buf</a> + start_ptr, blk_size);
<a name="l00172"></a>00172
<a name="l00173"></a>00173 <span class="comment">/* Update the start pointer and the count */</span>
<a name="l00174"></a>00174 tmp_cnt -= blk_size;
<a name="l00175"></a>00175 start_ptr = 0;
<a name="l00176"></a>00176 }
<a name="l00177"></a>00177 }
<a name="l00178"></a>00178
<a name="l00179"></a>00179 <span class="comment">/* Event consumption function */</span>
<a name="l00180"></a>00180 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __handle_event(a4l_buf_t * buf)
<a name="l00181"></a>00181 {
<a name="l00182"></a>00182 <span class="keywordtype">int</span> ret = 0;
<a name="l00183"></a>00183
<a name="l00184"></a>00184 <span class="comment">/* The event "End of acquisition" must not be cleaned</span>
<a name="l00185"></a>00185 <span class="comment"> before the complete flush of the buffer */</span>
<a name="l00186"></a>00186 <span class="keywordflow">if</span> (test_bit(A4L_BUF_EOA_NR, &buf->flags)) {
<a name="l00187"></a>00187 ret = -ENOENT;
<a name="l00188"></a>00188 }
<a name="l00189"></a>00189
<a name="l00190"></a>00190 <span class="keywordflow">if</span> (test_bit(A4L_BUF_ERROR_NR, &buf->flags)) {
<a name="l00191"></a>00191 ret = -EPIPE;
<a name="l00192"></a>00192 }
<a name="l00193"></a>00193
<a name="l00194"></a>00194 <span class="keywordflow">return</span> ret;
<a name="l00195"></a>00195 }
<a name="l00196"></a>00196
<a name="l00197"></a>00197 <span class="comment">/* Counters management functions */</span>
<a name="l00198"></a>00198
<a name="l00199"></a>00199 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __pre_abs_put(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00200"></a>00200 {
<a name="l00201"></a>00201 <span class="keywordflow">if</span> (count - buf->tmp_count > buf->size) {
<a name="l00202"></a>00202 set_bit(A4L_BUF_ERROR_NR, &buf->flags);
<a name="l00203"></a>00203 <span class="keywordflow">return</span> -EPIPE;
<a name="l00204"></a>00204 }
<a name="l00205"></a>00205
<a name="l00206"></a>00206 buf->tmp_count = buf->cns_count;
<a name="l00207"></a>00207
<a name="l00208"></a>00208 <span class="keywordflow">return</span> 0;
<a name="l00209"></a>00209 }
<a name="l00210"></a>00210
<a name="l00211"></a>00211 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __pre_put(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00212"></a>00212 {
<a name="l00213"></a>00213 <span class="keywordflow">return</span> __pre_abs_put(buf, buf->tmp_count + count);
<a name="l00214"></a>00214 }
<a name="l00215"></a>00215
<a name="l00216"></a>00216 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __pre_abs_get(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00217"></a>00217 {
<a name="l00218"></a>00218 <span class="comment">/* The first time, we expect the buffer to be properly filled</span>
<a name="l00219"></a>00219 <span class="comment"> before the trigger occurence; by the way, we need tmp_count to</span>
<a name="l00220"></a>00220 <span class="comment"> have been initialized and tmp_count is updated right here */</span>
<a name="l00221"></a>00221 <span class="keywordflow">if</span> (buf->tmp_count == 0 || buf->cns_count == 0)
<a name="l00222"></a>00222 <span class="keywordflow">goto</span> out;
<a name="l00223"></a>00223
<a name="l00224"></a>00224 <span class="comment">/* At the end of the acquisition, the user application has</span>
<a name="l00225"></a>00225 <span class="comment"> written the defined amount of data into the buffer; so the</span>
<a name="l00226"></a>00226 <span class="comment"> last time, the DMA channel can easily overtake the tmp</span>
<a name="l00227"></a>00227 <span class="comment"> frontier because no more data were sent from user space;</span>
<a name="l00228"></a>00228 <span class="comment"> therefore no useless alarm should be sent */</span>
<a name="l00229"></a>00229 <span class="keywordflow">if</span> (buf->end_count != 0 && (<span class="keywordtype">long</span>)(count - buf->end_count) > 0)
<a name="l00230"></a>00230 <span class="keywordflow">goto</span> out;
<a name="l00231"></a>00231
<a name="l00232"></a>00232 <span class="comment">/* Once the exception are passed, we check that the DMA</span>
<a name="l00233"></a>00233 <span class="comment"> transfer has not overtaken the last record of the production</span>
<a name="l00234"></a>00234 <span class="comment"> count (tmp_count was updated with prd_count the last time</span>
<a name="l00235"></a>00235 <span class="comment"> __pre_abs_get was called). We must understand that we cannot</span>
<a name="l00236"></a>00236 <span class="comment"> compare the current DMA count with the current production</span>
<a name="l00237"></a>00237 <span class="comment"> count because even if, right now, the production count is</span>
<a name="l00238"></a>00238 <span class="comment"> higher than the DMA count, it does not mean that the DMA count</span>
<a name="l00239"></a>00239 <span class="comment"> was not greater a few cycles before; in such case, the DMA</span>
<a name="l00240"></a>00240 <span class="comment"> channel would have retrieved the wrong data */</span>
<a name="l00241"></a>00241 <span class="keywordflow">if</span> ((<span class="keywordtype">long</span>)(count - buf->tmp_count) > 0) {
<a name="l00242"></a>00242 set_bit(A4L_BUF_ERROR_NR, &buf->flags);
<a name="l00243"></a>00243 <span class="keywordflow">return</span> -EPIPE;
<a name="l00244"></a>00244 }
<a name="l00245"></a>00245
<a name="l00246"></a>00246 out:
<a name="l00247"></a>00247 buf->tmp_count = buf->prd_count;
<a name="l00248"></a>00248
<a name="l00249"></a>00249 <span class="keywordflow">return</span> 0;
<a name="l00250"></a>00250 }
<a name="l00251"></a>00251
<a name="l00252"></a>00252 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __pre_get(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00253"></a>00253 {
<a name="l00254"></a>00254 <span class="keywordflow">return</span> __pre_abs_get(buf, buf->tmp_count + count);
<a name="l00255"></a>00255 }
<a name="l00256"></a>00256
<a name="l00257"></a>00257 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __abs_put(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00258"></a>00258 {
<a name="l00259"></a>00259 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> old = buf->prd_count;
<a name="l00260"></a>00260
<a name="l00261"></a>00261 <span class="keywordflow">if</span> ((<span class="keywordtype">long</span>)(buf->prd_count - count) >= 0)
<a name="l00262"></a>00262 <span class="keywordflow">return</span> -EINVAL;
<a name="l00263"></a>00263
<a name="l00264"></a>00264 buf->prd_count = count;
<a name="l00265"></a>00265
<a name="l00266"></a>00266 <span class="keywordflow">if</span> ((old / buf->size) != (count / buf->size))
<a name="l00267"></a>00267 set_bit(A4L_BUF_EOBUF_NR, &buf->flags);
<a name="l00268"></a>00268
<a name="l00269"></a>00269 <span class="keywordflow">if</span> (buf->end_count != 0 && (<span class="keywordtype">long</span>)(count - buf->end_count) >= 0)
<a name="l00270"></a>00270 set_bit(A4L_BUF_EOA_NR, &buf->flags);
<a name="l00271"></a>00271
<a name="l00272"></a>00272 <span class="keywordflow">return</span> 0;
<a name="l00273"></a>00273 }
<a name="l00274"></a>00274
<a name="l00275"></a>00275 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __put(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00276"></a>00276 {
<a name="l00277"></a>00277 <span class="keywordflow">return</span> __abs_put(buf, buf->prd_count + count);
<a name="l00278"></a>00278 }
<a name="l00279"></a>00279
<a name="l00280"></a>00280 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __abs_get(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00281"></a>00281 {
<a name="l00282"></a>00282 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> old = buf->cns_count;
<a name="l00283"></a>00283
<a name="l00284"></a>00284 <span class="keywordflow">if</span> ((<span class="keywordtype">long</span>)(buf->cns_count - count) >= 0)
<a name="l00285"></a>00285 <span class="keywordflow">return</span> -EINVAL;
<a name="l00286"></a>00286
<a name="l00287"></a>00287 buf->cns_count = count;
<a name="l00288"></a>00288
<a name="l00289"></a>00289 <span class="keywordflow">if</span> ((old / buf->size) != count / buf->size)
<a name="l00290"></a>00290 set_bit(A4L_BUF_EOBUF_NR, &buf->flags);
<a name="l00291"></a>00291
<a name="l00292"></a>00292 <span class="keywordflow">if</span> (buf->end_count != 0 && (<span class="keywordtype">long</span>)(count - buf->end_count) >= 0)
<a name="l00293"></a>00293 set_bit(A4L_BUF_EOA_NR, &buf->flags);
<a name="l00294"></a>00294
<a name="l00295"></a>00295 <span class="keywordflow">return</span> 0;
<a name="l00296"></a>00296 }
<a name="l00297"></a>00297
<a name="l00298"></a>00298 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> __get(a4l_buf_t * buf, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count)
<a name="l00299"></a>00299 {
<a name="l00300"></a>00300 <span class="keywordflow">return</span> __abs_get(buf, buf->cns_count + count);
<a name="l00301"></a>00301 }
<a name="l00302"></a>00302
<a name="l00303"></a>00303 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> __count_to_put(a4l_buf_t * buf)
<a name="l00304"></a>00304 {
<a name="l00305"></a>00305 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> ret;
<a name="l00306"></a>00306
<a name="l00307"></a>00307 <span class="keywordflow">if</span> ((<span class="keywordtype">long</span>) (buf->size + buf->cns_count - buf->prd_count) > 0)
<a name="l00308"></a>00308 ret = buf->size + buf->cns_count - buf->prd_count;
<a name="l00309"></a>00309 <span class="keywordflow">else</span>
<a name="l00310"></a>00310 ret = 0;
<a name="l00311"></a>00311
<a name="l00312"></a>00312 <span class="keywordflow">return</span> ret;
<a name="l00313"></a>00313 }
<a name="l00314"></a>00314
<a name="l00315"></a>00315 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> __count_to_get(a4l_buf_t * buf)
<a name="l00316"></a>00316 {
<a name="l00317"></a>00317 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> ret;
<a name="l00318"></a>00318
<a name="l00319"></a>00319 <span class="comment">/* If the acquisition is unlimited (end_count == 0), we must</span>
<a name="l00320"></a>00320 <span class="comment"> not take into account end_count */</span>
<a name="l00321"></a>00321 <span class="keywordflow">if</span> (buf->end_count == 0 || (<span class="keywordtype">long</span>)(buf->end_count - buf->prd_count) > 0)
<a name="l00322"></a>00322 ret = buf->prd_count;
<a name="l00323"></a>00323 <span class="keywordflow">else</span>
<a name="l00324"></a>00324 ret = buf->end_count;
<a name="l00325"></a>00325
<a name="l00326"></a>00326 <span class="keywordflow">if</span> ((<span class="keywordtype">long</span>)(ret - buf->cns_count) > 0)
<a name="l00327"></a>00327 ret -= buf->cns_count;
<a name="l00328"></a>00328 <span class="keywordflow">else</span>
<a name="l00329"></a>00329 ret = 0;
<a name="l00330"></a>00330
<a name="l00331"></a>00331 <span class="keywordflow">return</span> ret;
<a name="l00332"></a>00332 }
<a name="l00333"></a>00333
<a name="l00334"></a>00334 <span class="comment">/* --- Buffer internal functions --- */</span>
<a name="l00335"></a>00335
<a name="l00336"></a>00336 <span class="keywordtype">int</span> a4l_alloc_buffer(a4l_buf_t *buf_desc, <span class="keywordtype">int</span> buf_size);
<a name="l00337"></a>00337
<a name="l00338"></a>00338 <span class="keywordtype">void</span> a4l_free_buffer(a4l_buf_t *buf_desc);
<a name="l00339"></a>00339
<a name="l00340"></a>00340 <span class="keywordtype">void</span> a4l_init_buffer(a4l_buf_t * buf_desc);
<a name="l00341"></a>00341
<a name="l00342"></a>00342 <span class="keywordtype">void</span> a4l_cleanup_buffer(a4l_buf_t * buf_desc);
<a name="l00343"></a>00343
<a name="l00344"></a>00344 <span class="keywordtype">int</span> a4l_setup_buffer(a4l_cxt_t *cxt, <a class="code" href="structa4l__cmd__desc.html" title="Structure describing the asynchronous instruction.">a4l_cmd_t</a> *cmd);
<a name="l00345"></a>00345
<a name="l00346"></a>00346 <span class="keywordtype">int</span> a4l_cancel_buffer(a4l_cxt_t *cxt);
<a name="l00347"></a>00347
<a name="l00348"></a>00348 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g8ffbc9832255a701624fe874d319e5f4" title="Update the absolute count of data sent from the device to the buffer since the start...">a4l_buf_prepare_absput</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00349"></a>00349 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00350"></a>00350
<a name="l00351"></a>00351 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g8d053d9fc6e19eb47f9c08abf485cea9" title="Set the absolute count of data which was sent from the device to the buffer since...">a4l_buf_commit_absput</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00352"></a>00352 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00353"></a>00353
<a name="l00354"></a>00354 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g582e96ac8358717a19995e0c8c41dffc" title="Set the count of data which is to be sent to the buffer at the next DMA shot.">a4l_buf_prepare_put</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00355"></a>00355 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00356"></a>00356
<a name="l00357"></a>00357 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gb03dcc685bcb3ad9111c9aa3dbe3baf5" title="Set the count of data sent to the buffer during the last completed DMA shots.">a4l_buf_commit_put</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00358"></a>00358 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00359"></a>00359
<a name="l00360"></a>00360 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gec920d203e34f2020eb51ddad3461d1c" title="Copy some data from the device driver to the buffer.">a4l_buf_put</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00361"></a>00361 <span class="keywordtype">void</span> *bufdata, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00362"></a>00362
<a name="l00363"></a>00363 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g7fecd99d23d53c69381aacee4d9222d8" title="Update the absolute count of data sent from the buffer to the device since the start...">a4l_buf_prepare_absget</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00364"></a>00364 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00365"></a>00365
<a name="l00366"></a>00366 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gdadad4789e1da9236fed49a33b1b2284" title="Set the absolute count of data which was sent from the buffer to the device since...">a4l_buf_commit_absget</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00367"></a>00367 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00368"></a>00368
<a name="l00369"></a>00369 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gf9fe0b2fe2279e4f753ddec776d10c5f" title="Set the count of data which is to be sent from the buffer to the device at the next...">a4l_buf_prepare_get</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00370"></a>00370 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00371"></a>00371
<a name="l00372"></a>00372 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gbd70bc9f8bb4615f60c0107d51ca1f29" title="Set the count of data sent from the buffer to the device during the last completed...">a4l_buf_commit_get</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00373"></a>00373 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00374"></a>00374
<a name="l00375"></a>00375 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g6af2dcaaecfd2cd9f0deb6e9167d3cff" title="Copy some data from the buffer to the device driver.">a4l_buf_get</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd,
<a name="l00376"></a>00376 <span class="keywordtype">void</span> *bufdata, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> count);
<a name="l00377"></a>00377
<a name="l00378"></a>00378 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#gc275c834264a50b9443304d33908f657" title="Signal some event(s) to a user-space program involved in some read / write operation...">a4l_buf_evt</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd, <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> evts);
<a name="l00379"></a>00379
<a name="l00380"></a>00380 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="group__analogy__buffer.html#gd9e80150586b4a869562d3d098f49d36" title="Get the data amount available in the Analogy buffer.">a4l_buf_count</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd);
<a name="l00381"></a>00381
<a name="l00382"></a>00382 <span class="comment">/* --- Current Command management function --- */</span>
<a name="l00383"></a>00383
<a name="l00384"></a>00384 <span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="structa4l__cmd__desc.html" title="Structure describing the asynchronous instruction.">a4l_cmd_t</a> *<a class="code" href="group__analogy__buffer.html#g2386d5a9d84393b5db9beb22ae7674e9" title="Get the current Analogy command descriptor.">a4l_get_cmd</a>(<a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subd_t</a> *subd)
<a name="l00385"></a>00385 {
<a name="l00386"></a>00386 <span class="keywordflow">return</span> (subd-><a class="code" href="structa4l__subdevice.html#102957cf30f6328e9b9cac05e4f980ec" title="Linked buffer.">buf</a>) ? subd-><a class="code" href="structa4l__subdevice.html#102957cf30f6328e9b9cac05e4f980ec" title="Linked buffer.">buf</a>->cur_cmd : NULL;
<a name="l00387"></a>00387 }
<a name="l00388"></a>00388
<a name="l00389"></a>00389 <span class="comment">/* --- Munge related function --- */</span>
<a name="l00390"></a>00390
<a name="l00391"></a>00391 <span class="keywordtype">int</span> <a class="code" href="group__analogy__buffer.html#g6e33ba6f8a06e3dbbfe3896b0258857f" title="Get the channel index according to its type.">a4l_get_chan</a>(<span class="keyword">struct</span> <a class="code" href="structa4l__subdevice.html" title="Structure describing the subdevice.">a4l_subdevice</a> *subd);
<a name="l00392"></a>00392
<a name="l00393"></a>00393 <span class="comment">/* --- IOCTL / FOPS functions --- */</span>
<a name="l00394"></a>00394
<a name="l00395"></a>00395 <span class="keywordtype">int</span> a4l_ioctl_mmap(a4l_cxt_t * cxt, <span class="keywordtype">void</span> *arg);
<a name="l00396"></a>00396 <span class="keywordtype">int</span> a4l_ioctl_bufcfg(a4l_cxt_t * cxt, <span class="keywordtype">void</span> *arg);
<a name="l00397"></a>00397 <span class="keywordtype">int</span> a4l_ioctl_bufinfo(a4l_cxt_t * cxt, <span class="keywordtype">void</span> *arg);
<a name="l00398"></a>00398 <span class="keywordtype">int</span> a4l_ioctl_poll(a4l_cxt_t * cxt, <span class="keywordtype">void</span> *arg);
<a name="l00399"></a>00399 ssize_t a4l_read_buffer(a4l_cxt_t * cxt, <span class="keywordtype">void</span> *bufdata, <span class="keywordtype">size_t</span> nbytes);
<a name="l00400"></a>00400 ssize_t a4l_write_buffer(a4l_cxt_t * cxt, <span class="keyword">const</span> <span class="keywordtype">void</span> *bufdata, <span class="keywordtype">size_t</span> nbytes);
<a name="l00401"></a>00401 <span class="keywordtype">int</span> a4l_select(a4l_cxt_t *cxt,
<a name="l00402"></a>00402 rtdm_selector_t *selector,
<a name="l00403"></a>00403 <span class="keyword">enum</span> <a class="code" href="group__rtdmsync.html#ge18228df8c70c9da1f90f61b01e92501">rtdm_selecttype</a> type, <span class="keywordtype">unsigned</span> fd_index);
<a name="l00404"></a>00404
<a name="l00405"></a>00405 <span class="preprocessor">#endif </span><span class="comment">/* __KERNEL__ */</span>
<a name="l00406"></a>00406
<a name="l00407"></a>00407 <span class="comment">/* MMAP ioctl argument structure */</span>
<a name="l00408"></a>00408 <span class="keyword">struct </span>a4l_mmap_arg {
<a name="l00409"></a>00409 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx_subd;
<a name="l00410"></a>00410 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> size;
<a name="l00411"></a>00411 <span class="keywordtype">void</span> *ptr;
<a name="l00412"></a>00412 };
<a name="l00413"></a>00413 <span class="keyword">typedef</span> <span class="keyword">struct </span>a4l_mmap_arg a4l_mmap_t;
<a name="l00414"></a>00414
<a name="l00415"></a>00415 <span class="comment">/* Constants related with buffer size</span>
<a name="l00416"></a>00416 <span class="comment"> (might be used with BUFCFG ioctl) */</span>
<a name="l00417"></a>00417 <span class="preprocessor">#define A4L_BUF_MAXSIZE 0x1000000</span>
<a name="l00418"></a>00418 <span class="preprocessor"></span><span class="preprocessor">#define A4L_BUF_DEFSIZE 0x10000</span>
<a name="l00419"></a>00419 <span class="preprocessor"></span>
<a name="l00420"></a>00420 <span class="comment">/* BUFCFG ioctl argument structure */</span>
<a name="l00421"></a>00421 <span class="keyword">struct </span>a4l_buffer_config {
<a name="l00422"></a>00422 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx_subd;
<a name="l00423"></a>00423 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> buf_size;
<a name="l00424"></a>00424 };
<a name="l00425"></a>00425 <span class="keyword">typedef</span> <span class="keyword">struct </span>a4l_buffer_config a4l_bufcfg_t;
<a name="l00426"></a>00426
<a name="l00427"></a>00427 <span class="comment">/* BUFINFO ioctl argument structure */</span>
<a name="l00428"></a>00428 <span class="keyword">struct </span>a4l_buffer_info {
<a name="l00429"></a>00429 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx_subd;
<a name="l00430"></a>00430 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> buf_size;
<a name="l00431"></a>00431 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> rw_count;
<a name="l00432"></a>00432 };
<a name="l00433"></a>00433 <span class="keyword">typedef</span> <span class="keyword">struct </span>a4l_buffer_info a4l_bufinfo_t;
<a name="l00434"></a>00434
<a name="l00435"></a>00435 <span class="comment">/* POLL ioctl argument structure */</span>
<a name="l00436"></a>00436 <span class="keyword">struct </span><a class="code" href="group__async1__lib.html#g43ab969b00aae973ef4b67c234b17720" title="Get the available data count.">a4l_poll</a> {
<a name="l00437"></a>00437 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx_subd;
<a name="l00438"></a>00438 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> arg;
<a name="l00439"></a>00439 };
<a name="l00440"></a>00440 <span class="keyword">typedef</span> <span class="keyword">struct </span><a class="code" href="group__async1__lib.html#g43ab969b00aae973ef4b67c234b17720" title="Get the available data count.">a4l_poll</a> a4l_poll_t;
<a name="l00441"></a>00441
<a name="l00442"></a>00442 <span class="preprocessor">#endif </span><span class="comment">/* !DOXYGEN_CPP */</span>
<a name="l00443"></a>00443
<a name="l00444"></a>00444 <span class="preprocessor">#endif </span><span class="comment">/* __ANALOGY_BUFFER_H__ */</span>
</pre></div></div>
<hr size="1"><address style="text-align: right;"><small>Generated on Mon Aug 2 12:48:36 2010 for Xenomai API by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.5.6 </small></address>
</body>
</html>
|