Commit | Line | Data |
---|---|---|
aa337ef1 SS |
1 | /* |
2 | ||
3 | Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan, | |
484d3be1 | 4 | Jason Lapenta, Scott Smedley, Greg Sharp |
aa337ef1 SS |
5 | |
6 | This file is part of the DT3155 Device Driver. | |
7 | ||
8 | The DT3155 Device Driver is free software; you can redistribute it | |
9 | and/or modify it under the terms of the GNU General Public License as | |
10 | published by the Free Software Foundation; either version 2 of the | |
11 | License, or (at your option) any later version. | |
12 | ||
13 | The DT3155 Device Driver is distributed in the hope that it will be | |
14 | useful, but WITHOUT ANY WARRANTY; without even the implied warranty | |
15 | of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with the DT3155 Device Driver; if not, write to the Free | |
20 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | MA 02111-1307 USA | |
22 | ||
23 | File: dt3155_isr.c | |
24 | Purpose: Buffer management routines, and other routines for the ISR | |
484d3be1 | 25 | (the actual isr is in dt3155_drv.c) |
aa337ef1 SS |
26 | |
27 | -- Changes -- | |
28 | ||
29 | Date Programmer Description of changes made | |
30 | ------------------------------------------------------------------- | |
31 | 03-Jul-2000 JML n/a | |
32 | 02-Apr-2002 SS Mods to make work with separate allocator | |
484d3be1 GI |
33 | module; Merged John Roll's mods to make work with |
34 | multiple boards. | |
aa337ef1 | 35 | 10-Jul-2002 GCS Complete rewrite of setup_buffers to disallow |
484d3be1 | 36 | buffers which span a 4MB boundary. |
aa337ef1 SS |
37 | 24-Jul-2002 SS GPL licence. |
38 | 30-Jul-2002 NJC Added support for buffer loop. | |
39 | 31-Jul-2002 NJC Complete rewrite of buffer management | |
40 | 02-Aug-2002 NJC Including slab.h instead of malloc.h (no warning). | |
484d3be1 GI |
41 | Also, allocator_init() now returns allocator_max |
42 | so cleaned up allocate_buffers() accordingly. | |
aa337ef1 SS |
43 | 08-Aug-2005 SS port to 2.6 kernel. |
44 | ||
45 | */ | |
46 | ||
47 | #include <asm/system.h> | |
5a0e3ad6 | 48 | #include <linux/gfp.h> |
aa337ef1 SS |
49 | #include <linux/sched.h> |
50 | #include <linux/types.h> | |
51 | ||
52 | #include "dt3155.h" | |
53 | #include "dt3155_drv.h" | |
54 | #include "dt3155_io.h" | |
55 | #include "dt3155_isr.h" | |
56 | #include "allocator.h" | |
57 | ||
58 | #define FOUR_MB (0x0400000) /* Can't DMA accross a 4MB boundary!*/ | |
59 | #define UPPER_10_BITS (0x3FF<<22) /* Can't DMA accross a 4MB boundary!*/ | |
60 | ||
61 | ||
62 | /* Pointer into global structure for handling buffers */ | |
e802b4b7 | 63 | struct dt3155_fbuffer *dt3155_fbuffer[MAXBOARDS] = {NULL |
aa337ef1 SS |
64 | #if MAXBOARDS == 2 |
65 | , NULL | |
66 | #endif | |
67 | }; | |
68 | ||
69 | /****************************************************************************** | |
70 | * Simple array based que struct | |
71 | * | |
72 | * Some handy functions using the buffering structure. | |
73 | *****************************************************************************/ | |
74 | ||
75 | ||
76 | /*************************** | |
77 | * are_empty_buffers | |
78 | * m is minor # of device | |
79 | ***************************/ | |
e8afd402 | 80 | bool are_empty_buffers(int m) |
aa337ef1 | 81 | { |
484d3be1 | 82 | return dt3155_fbuffer[m]->empty_len; |
aa337ef1 SS |
83 | } |
84 | ||
85 | /************************** | |
86 | * push_empty | |
87 | * m is minor # of device | |
88 | * | |
89 | * This is slightly confusing. The number empty_len is the literal # | |
90 | * of empty buffers. After calling, empty_len-1 is the index into the | |
91 | * empty buffer stack. So, if empty_len == 1, there is one empty buffer, | |
92 | * given by dt3155_fbuffer[m]->empty_buffers[0]. | |
93 | * empty_buffers should never fill up, though this is not checked. | |
94 | **************************/ | |
e8afd402 | 95 | void push_empty(int index, int m) |
aa337ef1 | 96 | { |
484d3be1 | 97 | dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len] = index; |
aa337ef1 SS |
98 | dt3155_fbuffer[m]->empty_len++; |
99 | } | |
100 | ||
101 | /************************** | |
484d3be1 | 102 | * pop_empty(m) |
aa337ef1 SS |
103 | * m is minor # of device |
104 | **************************/ | |
e8afd402 | 105 | int pop_empty(int m) |
aa337ef1 SS |
106 | { |
107 | dt3155_fbuffer[m]->empty_len--; | |
484d3be1 | 108 | return dt3155_fbuffer[m]->empty_buffers[dt3155_fbuffer[m]->empty_len]; |
aa337ef1 SS |
109 | } |
110 | ||
111 | /************************* | |
484d3be1 | 112 | * is_ready_buf_empty(m) |
aa337ef1 SS |
113 | * m is minor # of device |
114 | *************************/ | |
e8afd402 | 115 | bool is_ready_buf_empty(int m) |
aa337ef1 | 116 | { |
484d3be1 | 117 | return ((dt3155_fbuffer[m]->ready_len) == 0); |
aa337ef1 SS |
118 | } |
119 | ||
120 | /************************* | |
484d3be1 | 121 | * is_ready_buf_full(m) |
aa337ef1 SS |
122 | * m is minor # of device |
123 | * this should *never* be true if there are any active, locked or empty | |
124 | * buffers, since it corresponds to nbuffers ready buffers!! | |
125 | * 7/31/02: total rewrite. --NJC | |
126 | *************************/ | |
e8afd402 | 127 | bool is_ready_buf_full(int m) |
aa337ef1 | 128 | { |
484d3be1 | 129 | return dt3155_fbuffer[m]->ready_len == dt3155_fbuffer[m]->nbuffers; |
aa337ef1 SS |
130 | } |
131 | ||
132 | /***************************************************** | |
484d3be1 | 133 | * push_ready(m, buffer) |
aa337ef1 SS |
134 | * m is minor # of device |
135 | * | |
136 | *****************************************************/ | |
e8afd402 | 137 | void push_ready(int m, int index) |
aa337ef1 SS |
138 | { |
139 | int head = dt3155_fbuffer[m]->ready_head; | |
140 | ||
484d3be1 GI |
141 | dt3155_fbuffer[m]->ready_que[head] = index; |
142 | dt3155_fbuffer[m]->ready_head = ((head + 1) % | |
143 | (dt3155_fbuffer[m]->nbuffers)); | |
144 | dt3155_fbuffer[m]->ready_len++; | |
aa337ef1 SS |
145 | |
146 | } | |
147 | ||
148 | /***************************************************** | |
149 | * get_tail() | |
150 | * m is minor # of device | |
151 | * | |
152 | * Simply comptutes the tail given the head and the length. | |
153 | *****************************************************/ | |
e8afd402 | 154 | static int get_tail(int m) |
aa337ef1 | 155 | { |
484d3be1 GI |
156 | return (dt3155_fbuffer[m]->ready_head - |
157 | dt3155_fbuffer[m]->ready_len + | |
158 | dt3155_fbuffer[m]->nbuffers)% | |
159 | (dt3155_fbuffer[m]->nbuffers); | |
aa337ef1 SS |
160 | } |
161 | ||
162 | ||
163 | ||
164 | /***************************************************** | |
165 | * pop_ready() | |
166 | * m is minor # of device | |
167 | * | |
168 | * This assumes that there is a ready buffer ready... should | |
169 | * be checked (e.g. with is_ready_buf_empty() prior to call. | |
170 | *****************************************************/ | |
e8afd402 | 171 | int pop_ready(int m) |
aa337ef1 SS |
172 | { |
173 | int tail; | |
174 | tail = get_tail(m); | |
484d3be1 GI |
175 | dt3155_fbuffer[m]->ready_len--; |
176 | return dt3155_fbuffer[m]->ready_que[tail]; | |
aa337ef1 SS |
177 | } |
178 | ||
179 | ||
180 | /***************************************************** | |
181 | * printques | |
182 | * m is minor # of device | |
183 | *****************************************************/ | |
e8afd402 | 184 | void printques(int m) |
aa337ef1 | 185 | { |
484d3be1 | 186 | int head = dt3155_fbuffer[m]->ready_head; |
aa337ef1 | 187 | int tail; |
484d3be1 | 188 | int num = dt3155_fbuffer[m]->nbuffers; |
aa337ef1 SS |
189 | int frame_index; |
190 | int index; | |
191 | ||
192 | tail = get_tail(m); | |
193 | ||
194 | printk("\n R:"); | |
484d3be1 GI |
195 | for (index = tail; index != head; index++, index = index % (num)) { |
196 | frame_index = dt3155_fbuffer[m]->ready_que[index]; | |
197 | printk(" %d ", frame_index); | |
aa337ef1 SS |
198 | } |
199 | ||
200 | printk("\n E:"); | |
484d3be1 GI |
201 | for (index = 0; index < dt3155_fbuffer[m]->empty_len; index++) { |
202 | frame_index = dt3155_fbuffer[m]->empty_buffers[index]; | |
203 | printk(" %d ", frame_index); | |
aa337ef1 SS |
204 | } |
205 | ||
484d3be1 | 206 | frame_index = dt3155_fbuffer[m]->active_buf; |
aa337ef1 SS |
207 | printk("\n A: %d", frame_index); |
208 | ||
484d3be1 GI |
209 | frame_index = dt3155_fbuffer[m]->locked_buf; |
210 | printk("\n L: %d\n", frame_index); | |
aa337ef1 SS |
211 | |
212 | } | |
213 | ||
214 | /***************************************************** | |
215 | * adjust_4MB | |
216 | * | |
217 | * If a buffer intersects the 4MB boundary, push | |
218 | * the start address up to the beginning of the | |
219 | * next 4MB chunk (assuming bufsize < 4MB). | |
220 | *****************************************************/ | |
484d3be1 GI |
221 | u32 adjust_4MB(u32 buf_addr, u32 bufsize) |
222 | { | |
223 | if (((buf_addr+bufsize) & UPPER_10_BITS) != (buf_addr & UPPER_10_BITS)) | |
224 | return (buf_addr+bufsize) & UPPER_10_BITS; | |
225 | else | |
226 | return buf_addr; | |
aa337ef1 SS |
227 | } |
228 | ||
229 | ||
230 | /***************************************************** | |
231 | * allocate_buffers | |
232 | * | |
233 | * Try to allocate enough memory for all requested | |
234 | * buffers. If there is not enough free space | |
235 | * try for less memory. | |
236 | *****************************************************/ | |
484d3be1 | 237 | void allocate_buffers(u32 *buf_addr, u32* total_size_kbs, |
3a8954e8 | 238 | u32 bufsize) |
aa337ef1 SS |
239 | { |
240 | /* Compute the minimum amount of memory guaranteed to hold all | |
241 | MAXBUFFERS such that no buffer crosses the 4MB boundary. | |
242 | Store this value in the variable "full_size" */ | |
243 | ||
3a8954e8 HS |
244 | u32 allocator_max; |
245 | u32 bufs_per_chunk = (FOUR_MB / bufsize); | |
246 | u32 filled_chunks = (MAXBUFFERS-1) / bufs_per_chunk; | |
247 | u32 leftover_bufs = MAXBUFFERS - filled_chunks * bufs_per_chunk; | |
aa337ef1 | 248 | |
3a8954e8 | 249 | u32 full_size = bufsize /* possibly unusable part of 1st chunk */ |
aa337ef1 SS |
250 | + filled_chunks * FOUR_MB /* max # of completely filled 4mb chunks */ |
251 | + leftover_bufs * bufsize; /* these buffs will be in a partly filled | |
252 | chunk at beginning or end */ | |
253 | ||
3a8954e8 HS |
254 | u32 full_size_kbs = 1 + (full_size-1) / 1024; |
255 | u32 min_size_kbs = 2*ndevices*bufsize / 1024; | |
256 | u32 size_kbs; | |
aa337ef1 SS |
257 | |
258 | /* Now, try to allocate full_size. If this fails, keep trying for | |
259 | less & less memory until it succeeds. */ | |
260 | #ifndef STANDALONE_ALLOCATOR | |
261 | /* initialize the allocator */ | |
262 | allocator_init(&allocator_max); | |
263 | #endif | |
264 | size_kbs = full_size_kbs; | |
265 | *buf_addr = 0; | |
3a8954e8 HS |
266 | printk("DT3155: We would like to get: %d KB\n", full_size_kbs); |
267 | printk("DT3155: ...but need at least: %d KB\n", min_size_kbs); | |
268 | printk("DT3155: ...the allocator has: %d KB\n", allocator_max); | |
aa337ef1 | 269 | size_kbs = (full_size_kbs <= allocator_max ? full_size_kbs : allocator_max); |
484d3be1 GI |
270 | if (size_kbs > min_size_kbs) { |
271 | if ((*buf_addr = allocator_allocate_dma(size_kbs, GFP_KERNEL)) != 0) { | |
272 | printk("DT3155: Managed to allocate: %d KB\n", size_kbs); | |
273 | *total_size_kbs = size_kbs; | |
274 | return; | |
275 | } | |
aa337ef1 | 276 | } |
aa337ef1 | 277 | /* If we got here, the allocation failed */ |
484d3be1 | 278 | printk("DT3155: Allocator failed!\n"); |
aa337ef1 SS |
279 | *buf_addr = 0; |
280 | *total_size_kbs = 0; | |
281 | return; | |
282 | ||
283 | } | |
284 | ||
285 | ||
286 | /***************************************************** | |
287 | * dt3155_setup_buffers | |
288 | * | |
289 | * setup_buffers just puts the buffering system into | |
290 | * a consistent state before the start of interrupts | |
291 | * | |
292 | * JML : it looks like all the buffers need to be | |
293 | * continuous. So I'm going to try and allocate one | |
294 | * continuous buffer. | |
295 | * | |
296 | * GCS : Fix DMA problems when buffer spans | |
297 | * 4MB boundary. Also, add error checking. This | |
298 | * function will return -ENOMEM when not enough memory. | |
299 | *****************************************************/ | |
3a8954e8 | 300 | u32 dt3155_setup_buffers(u32 *allocatorAddr) |
aa337ef1 SS |
301 | |
302 | { | |
3a8954e8 HS |
303 | u32 index; |
304 | u32 rambuff_addr; /* start of allocation */ | |
305 | u32 rambuff_size; /* total size allocated to driver */ | |
306 | u32 rambuff_acm; /* accumlator, keep track of how much | |
aa337ef1 | 307 | is left after being split up*/ |
3a8954e8 HS |
308 | u32 rambuff_end; /* end of rambuff */ |
309 | u32 numbufs; /* number of useful buffers allocated (per device) */ | |
310 | u32 bufsize = DT3155_MAX_ROWS * DT3155_MAX_COLS; | |
aa337ef1 SS |
311 | int m; /* minor # of device, looped for all devs */ |
312 | ||
313 | /* zero the fbuffer status and address structure */ | |
484d3be1 GI |
314 | for (m = 0; m < ndevices; m++) { |
315 | dt3155_fbuffer[m] = &(dt3155_status[m].fbuffer); | |
aa337ef1 SS |
316 | |
317 | /* Make sure the buffering variables are consistent */ | |
318 | { | |
484d3be1 | 319 | u8 *ptr = (u8 *) dt3155_fbuffer[m]; |
e802b4b7 | 320 | for (index = 0; index < sizeof(struct dt3155_fbuffer); index++) |
484d3be1 | 321 | *(ptr++) = 0; |
aa337ef1 SS |
322 | } |
323 | } | |
324 | ||
325 | /* allocate a large contiguous chunk of RAM */ | |
484d3be1 | 326 | allocate_buffers(&rambuff_addr, &rambuff_size, bufsize); |
3a8954e8 | 327 | printk("DT3155: mem info\n"); |
484d3be1 GI |
328 | printk(" - rambuf_addr = 0x%x\n", rambuff_addr); |
329 | printk(" - length (kb) = %u\n", rambuff_size); | |
330 | if (rambuff_addr == 0) { | |
331 | printk(KERN_INFO | |
332 | "DT3155: Error setup_buffers() allocator dma failed\n"); | |
333 | return -ENOMEM; | |
aa337ef1 SS |
334 | } |
335 | *allocatorAddr = rambuff_addr; | |
336 | rambuff_end = rambuff_addr + 1024 * rambuff_size; | |
337 | ||
338 | /* after allocation, we need to count how many useful buffers there | |
339 | are so we can give an equal number to each device */ | |
340 | rambuff_acm = rambuff_addr; | |
484d3be1 GI |
341 | for (index = 0; index < MAXBUFFERS; index++) { |
342 | rambuff_acm = adjust_4MB(rambuff_acm, bufsize);/*avoid spanning 4MB bdry*/ | |
343 | if (rambuff_acm + bufsize > rambuff_end) | |
344 | break; | |
345 | rambuff_acm += bufsize; | |
346 | } | |
aa337ef1 SS |
347 | /* Following line is OK, will waste buffers if index |
348 | * not evenly divisible by ndevices -NJC*/ | |
349 | numbufs = index / ndevices; | |
3a8954e8 | 350 | printk(" - numbufs = %u\n", numbufs); |
484d3be1 GI |
351 | if (numbufs < 2) { |
352 | printk(KERN_INFO | |
353 | "DT3155: Error setup_buffers() couldn't allocate 2 bufs/board\n"); | |
354 | return -ENOMEM; | |
355 | } | |
aa337ef1 SS |
356 | |
357 | /* now that we have board memory we spit it up */ | |
358 | /* between the boards and the buffers */ | |
484d3be1 GI |
359 | rambuff_acm = rambuff_addr; |
360 | for (m = 0; m < ndevices; m++) { | |
361 | rambuff_acm = adjust_4MB(rambuff_acm, bufsize); | |
362 | ||
363 | /* Save the start of this boards buffer space (for mmap). */ | |
364 | dt3155_status[m].mem_addr = rambuff_acm; | |
365 | ||
366 | for (index = 0; index < numbufs; index++) { | |
367 | rambuff_acm = adjust_4MB(rambuff_acm, bufsize); | |
368 | if (rambuff_acm + bufsize > rambuff_end) { | |
369 | /* Should never happen */ | |
370 | printk("DT3155 PROGRAM ERROR (GCS)\n" | |
371 | "Error distributing allocated buffers\n"); | |
372 | return -ENOMEM; | |
373 | } | |
374 | ||
375 | dt3155_fbuffer[m]->frame_info[index].addr = rambuff_acm; | |
376 | push_empty(index, m); | |
377 | /* printk(" - Buffer : %lx\n", | |
378 | * dt3155_fbuffer[m]->frame_info[index].addr); | |
379 | */ | |
380 | dt3155_fbuffer[m]->nbuffers += 1; | |
381 | rambuff_acm += bufsize; | |
aa337ef1 SS |
382 | } |
383 | ||
484d3be1 GI |
384 | /* Make sure there is an active buffer there. */ |
385 | dt3155_fbuffer[m]->active_buf = pop_empty(m); | |
386 | dt3155_fbuffer[m]->even_happened = 0; | |
387 | dt3155_fbuffer[m]->even_stopped = 0; | |
aa337ef1 | 388 | |
484d3be1 GI |
389 | /* make sure there is no locked_buf JML 2/28/00 */ |
390 | dt3155_fbuffer[m]->locked_buf = -1; | |
aa337ef1 | 391 | |
484d3be1 GI |
392 | dt3155_status[m].mem_size = |
393 | rambuff_acm - dt3155_status[m].mem_addr; | |
aa337ef1 | 394 | |
484d3be1 GI |
395 | /* setup the ready queue */ |
396 | dt3155_fbuffer[m]->ready_head = 0; | |
397 | dt3155_fbuffer[m]->ready_len = 0; | |
398 | printk("Available buffers for device %d: %d\n", | |
399 | m, dt3155_fbuffer[m]->nbuffers); | |
aa337ef1 SS |
400 | } |
401 | ||
484d3be1 | 402 | return 1; |
aa337ef1 SS |
403 | } |
404 | ||
405 | /***************************************************** | |
406 | * internal_release_locked_buffer | |
407 | * | |
408 | * The internal function for releasing a locked buffer. | |
409 | * It assumes interrupts are turned off. | |
410 | * | |
411 | * m is minor number of device | |
412 | *****************************************************/ | |
e8afd402 | 413 | static void internal_release_locked_buffer(int m) |
aa337ef1 SS |
414 | { |
415 | /* Pointer into global structure for handling buffers */ | |
484d3be1 GI |
416 | if (dt3155_fbuffer[m]->locked_buf >= 0) { |
417 | push_empty(dt3155_fbuffer[m]->locked_buf, m); | |
418 | dt3155_fbuffer[m]->locked_buf = -1; | |
aa337ef1 SS |
419 | } |
420 | } | |
421 | ||
422 | ||
423 | /***************************************************** | |
424 | * dt3155_release_locked_buffer() | |
425 | * m is minor # of device | |
426 | * | |
427 | * The user function of the above. | |
428 | * | |
429 | *****************************************************/ | |
e8afd402 | 430 | void dt3155_release_locked_buffer(int m) |
aa337ef1 | 431 | { |
aa337ef1 SS |
432 | unsigned long int flags; |
433 | local_save_flags(flags); | |
434 | local_irq_disable(); | |
435 | internal_release_locked_buffer(m); | |
436 | local_irq_restore(flags); | |
aa337ef1 SS |
437 | } |
438 | ||
439 | ||
440 | /***************************************************** | |
441 | * dt3155_flush() | |
442 | * m is minor # of device | |
443 | * | |
444 | *****************************************************/ | |
e8afd402 | 445 | int dt3155_flush(int m) |
aa337ef1 SS |
446 | { |
447 | int index; | |
2141ec62 SH |
448 | unsigned long int flags; |
449 | local_save_flags(flags); | |
450 | local_irq_disable(); | |
aa337ef1 | 451 | |
484d3be1 GI |
452 | internal_release_locked_buffer(m); |
453 | dt3155_fbuffer[m]->empty_len = 0; | |
aa337ef1 | 454 | |
484d3be1 GI |
455 | for (index = 0; index < dt3155_fbuffer[m]->nbuffers; index++) |
456 | push_empty(index, m); | |
aa337ef1 SS |
457 | |
458 | /* Make sure there is an active buffer there. */ | |
484d3be1 | 459 | dt3155_fbuffer[m]->active_buf = pop_empty(m); |
aa337ef1 | 460 | |
484d3be1 GI |
461 | dt3155_fbuffer[m]->even_happened = 0; |
462 | dt3155_fbuffer[m]->even_stopped = 0; | |
aa337ef1 SS |
463 | |
464 | /* setup the ready queue */ | |
484d3be1 GI |
465 | dt3155_fbuffer[m]->ready_head = 0; |
466 | dt3155_fbuffer[m]->ready_len = 0; | |
aa337ef1 | 467 | |
aa337ef1 | 468 | local_irq_restore(flags); |
aa337ef1 SS |
469 | |
470 | return 0; | |
471 | } | |
472 | ||
473 | /***************************************************** | |
474 | * dt3155_get_ready_buffer() | |
475 | * m is minor # of device | |
476 | * | |
477 | * get_ready_buffer will grab the next chunk of data | |
478 | * if it is already there, otherwise it returns 0. | |
479 | * If the user has a buffer locked it will unlock | |
480 | * that buffer before returning the new one. | |
481 | *****************************************************/ | |
e8afd402 | 482 | int dt3155_get_ready_buffer(int m) |
aa337ef1 SS |
483 | { |
484 | int frame_index; | |
2141ec62 SH |
485 | unsigned long int flags; |
486 | local_save_flags(flags); | |
487 | local_irq_disable(); | |
aa337ef1 SS |
488 | |
489 | #ifdef DEBUG_QUES_A | |
484d3be1 | 490 | printques(m); |
aa337ef1 SS |
491 | #endif |
492 | ||
484d3be1 | 493 | internal_release_locked_buffer(m); |
aa337ef1 | 494 | |
484d3be1 GI |
495 | if (is_ready_buf_empty(m)) |
496 | frame_index = -1; | |
497 | else { | |
498 | frame_index = pop_ready(m); | |
499 | dt3155_fbuffer[m]->locked_buf = frame_index; | |
aa337ef1 SS |
500 | } |
501 | ||
502 | #ifdef DEBUG_QUES_B | |
484d3be1 | 503 | printques(m); |
aa337ef1 SS |
504 | #endif |
505 | ||
aa337ef1 | 506 | local_irq_restore(flags); |
aa337ef1 SS |
507 | |
508 | return frame_index; | |
509 | } |