Remove obsolete #include <linux/config.h>
[pandora-kernel.git] / drivers / media / video / pvrusb2 / pvrusb2-io.c
1 /*
2  *
3  *  $Id$
4  *
5  *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "pvrusb2-io.h"
23 #include "pvrusb2-debug.h"
24 #include <linux/errno.h>
25 #include <linux/string.h>
26 #include <linux/slab.h>
27 #include <linux/mutex.h>
28
29 #define BUFFER_SIG 0x47653271
30
31 // #define SANITY_CHECK_BUFFERS
32
33
34 #ifdef SANITY_CHECK_BUFFERS
35 #define BUFFER_CHECK(bp) do { \
36         if ((bp)->signature != BUFFER_SIG) { \
37                 pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
38                 "Buffer %p is bad at %s:%d", \
39                 (bp),__FILE__,__LINE__); \
40                 pvr2_buffer_describe(bp,"BadSig"); \
41                 BUG(); \
42         } \
43 } while (0)
44 #else
45 #define BUFFER_CHECK(bp) do {} while(0)
46 #endif
47
48 struct pvr2_stream {
49         /* Buffers queued for reading */
50         struct list_head queued_list;
51         unsigned int q_count;
52         unsigned int q_bcount;
53         /* Buffers with retrieved data */
54         struct list_head ready_list;
55         unsigned int r_count;
56         unsigned int r_bcount;
57         /* Buffers available for use */
58         struct list_head idle_list;
59         unsigned int i_count;
60         unsigned int i_bcount;
61         /* Pointers to all buffers */
62         struct pvr2_buffer **buffers;
63         /* Array size of buffers */
64         unsigned int buffer_slot_count;
65         /* Total buffers actually in circulation */
66         unsigned int buffer_total_count;
67         /* Designed number of buffers to be in circulation */
68         unsigned int buffer_target_count;
69         /* Executed when ready list become non-empty */
70         pvr2_stream_callback callback_func;
71         void *callback_data;
72         /* Context for transfer endpoint */
73         struct usb_device *dev;
74         int endpoint;
75         /* Overhead for mutex enforcement */
76         spinlock_t list_lock;
77         struct mutex mutex;
78         /* Tracking state for tolerating errors */
79         unsigned int fail_count;
80         unsigned int fail_tolerance;
81 };
82
83 struct pvr2_buffer {
84         int id;
85         int signature;
86         enum pvr2_buffer_state state;
87         void *ptr;               /* Pointer to storage area */
88         unsigned int max_count;  /* Size of storage area */
89         unsigned int used_count; /* Amount of valid data in storage area */
90         int status;              /* Transfer result status */
91         struct pvr2_stream *stream;
92         struct list_head list_overhead;
93         struct urb *purb;
94 };
95
96 const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
97 {
98         switch (st) {
99         case pvr2_buffer_state_none: return "none";
100         case pvr2_buffer_state_idle: return "idle";
101         case pvr2_buffer_state_queued: return "queued";
102         case pvr2_buffer_state_ready: return "ready";
103         }
104         return "unknown";
105 }
106
107 void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
108 {
109         pvr2_trace(PVR2_TRACE_INFO,
110                    "buffer%s%s %p state=%s id=%d status=%d"
111                    " stream=%p purb=%p sig=0x%x",
112                    (msg ? " " : ""),
113                    (msg ? msg : ""),
114                    bp,
115                    (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"),
116                    (bp ? bp->id : 0),
117                    (bp ? bp->status : 0),
118                    (bp ? bp->stream : 0),
119                    (bp ? bp->purb : 0),
120                    (bp ? bp->signature : 0));
121 }
122
123 static void pvr2_buffer_remove(struct pvr2_buffer *bp)
124 {
125         unsigned int *cnt;
126         unsigned int *bcnt;
127         unsigned int ccnt;
128         struct pvr2_stream *sp = bp->stream;
129         switch (bp->state) {
130         case pvr2_buffer_state_idle:
131                 cnt = &sp->i_count;
132                 bcnt = &sp->i_bcount;
133                 ccnt = bp->max_count;
134                 break;
135         case pvr2_buffer_state_queued:
136                 cnt = &sp->q_count;
137                 bcnt = &sp->q_bcount;
138                 ccnt = bp->max_count;
139                 break;
140         case pvr2_buffer_state_ready:
141                 cnt = &sp->r_count;
142                 bcnt = &sp->r_bcount;
143                 ccnt = bp->used_count;
144                 break;
145         default:
146                 return;
147         }
148         list_del_init(&bp->list_overhead);
149         (*cnt)--;
150         (*bcnt) -= ccnt;
151         pvr2_trace(PVR2_TRACE_BUF_FLOW,
152                    "/*---TRACE_FLOW---*/"
153                    " bufferPool     %8s dec cap=%07d cnt=%02d",
154                    pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
155         bp->state = pvr2_buffer_state_none;
156 }
157
158 static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
159 {
160         unsigned long irq_flags;
161         struct pvr2_stream *sp;
162         BUFFER_CHECK(bp);
163         sp = bp->stream;
164         pvr2_trace(PVR2_TRACE_BUF_FLOW,
165                    "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
166                    bp,
167                    pvr2_buffer_state_decode(bp->state),
168                    pvr2_buffer_state_decode(pvr2_buffer_state_none));
169         spin_lock_irqsave(&sp->list_lock,irq_flags);
170         pvr2_buffer_remove(bp);
171         spin_unlock_irqrestore(&sp->list_lock,irq_flags);
172 }
173
174 static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
175 {
176         int fl;
177         unsigned long irq_flags;
178         struct pvr2_stream *sp;
179         BUFFER_CHECK(bp);
180         sp = bp->stream;
181         pvr2_trace(PVR2_TRACE_BUF_FLOW,
182                    "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
183                    bp,
184                    pvr2_buffer_state_decode(bp->state),
185                    pvr2_buffer_state_decode(pvr2_buffer_state_ready));
186         spin_lock_irqsave(&sp->list_lock,irq_flags);
187         fl = (sp->r_count == 0);
188         pvr2_buffer_remove(bp);
189         list_add_tail(&bp->list_overhead,&sp->ready_list);
190         bp->state = pvr2_buffer_state_ready;
191         (sp->r_count)++;
192         sp->r_bcount += bp->used_count;
193         pvr2_trace(PVR2_TRACE_BUF_FLOW,
194                    "/*---TRACE_FLOW---*/"
195                    " bufferPool     %8s inc cap=%07d cnt=%02d",
196                    pvr2_buffer_state_decode(bp->state),
197                    sp->r_bcount,sp->r_count);
198         spin_unlock_irqrestore(&sp->list_lock,irq_flags);
199         return fl;
200 }
201
202 static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
203 {
204         unsigned long irq_flags;
205         struct pvr2_stream *sp;
206         BUFFER_CHECK(bp);
207         sp = bp->stream;
208         pvr2_trace(PVR2_TRACE_BUF_FLOW,
209                    "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
210                    bp,
211                    pvr2_buffer_state_decode(bp->state),
212                    pvr2_buffer_state_decode(pvr2_buffer_state_idle));
213         spin_lock_irqsave(&sp->list_lock,irq_flags);
214         pvr2_buffer_remove(bp);
215         list_add_tail(&bp->list_overhead,&sp->idle_list);
216         bp->state = pvr2_buffer_state_idle;
217         (sp->i_count)++;
218         sp->i_bcount += bp->max_count;
219         pvr2_trace(PVR2_TRACE_BUF_FLOW,
220                    "/*---TRACE_FLOW---*/"
221                    " bufferPool     %8s inc cap=%07d cnt=%02d",
222                    pvr2_buffer_state_decode(bp->state),
223                    sp->i_bcount,sp->i_count);
224         spin_unlock_irqrestore(&sp->list_lock,irq_flags);
225 }
226
227 static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
228 {
229         unsigned long irq_flags;
230         struct pvr2_stream *sp;
231         BUFFER_CHECK(bp);
232         sp = bp->stream;
233         pvr2_trace(PVR2_TRACE_BUF_FLOW,
234                    "/*---TRACE_FLOW---*/ bufferState    %p %6s --> %6s",
235                    bp,
236                    pvr2_buffer_state_decode(bp->state),
237                    pvr2_buffer_state_decode(pvr2_buffer_state_queued));
238         spin_lock_irqsave(&sp->list_lock,irq_flags);
239         pvr2_buffer_remove(bp);
240         list_add_tail(&bp->list_overhead,&sp->queued_list);
241         bp->state = pvr2_buffer_state_queued;
242         (sp->q_count)++;
243         sp->q_bcount += bp->max_count;
244         pvr2_trace(PVR2_TRACE_BUF_FLOW,
245                    "/*---TRACE_FLOW---*/"
246                    " bufferPool     %8s inc cap=%07d cnt=%02d",
247                    pvr2_buffer_state_decode(bp->state),
248                    sp->q_bcount,sp->q_count);
249         spin_unlock_irqrestore(&sp->list_lock,irq_flags);
250 }
251
252 static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
253 {
254         if (bp->state == pvr2_buffer_state_queued) {
255                 usb_kill_urb(bp->purb);
256         }
257 }
258
259 static int pvr2_buffer_init(struct pvr2_buffer *bp,
260                             struct pvr2_stream *sp,
261                             unsigned int id)
262 {
263         memset(bp,0,sizeof(*bp));
264         bp->signature = BUFFER_SIG;
265         bp->id = id;
266         pvr2_trace(PVR2_TRACE_BUF_POOL,
267                    "/*---TRACE_FLOW---*/ bufferInit     %p stream=%p",bp,sp);
268         bp->stream = sp;
269         bp->state = pvr2_buffer_state_none;
270         INIT_LIST_HEAD(&bp->list_overhead);
271         bp->purb = usb_alloc_urb(0,GFP_KERNEL);
272         if (! bp->purb) return -ENOMEM;
273 #ifdef SANITY_CHECK_BUFFERS
274         pvr2_buffer_describe(bp,"create");
275 #endif
276         return 0;
277 }
278
279 static void pvr2_buffer_done(struct pvr2_buffer *bp)
280 {
281 #ifdef SANITY_CHECK_BUFFERS
282         pvr2_buffer_describe(bp,"delete");
283 #endif
284         pvr2_buffer_wipe(bp);
285         pvr2_buffer_set_none(bp);
286         bp->signature = 0;
287         bp->stream = 0;
288         if (bp->purb) usb_free_urb(bp->purb);
289         pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
290                    " bufferDone     %p",bp);
291 }
292
293 static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
294 {
295         int ret;
296         unsigned int scnt;
297
298         /* Allocate buffers pointer array in multiples of 32 entries */
299         if (cnt == sp->buffer_total_count) return 0;
300
301         pvr2_trace(PVR2_TRACE_BUF_POOL,
302                    "/*---TRACE_FLOW---*/ poolResize    "
303                    " stream=%p cur=%d adj=%+d",
304                    sp,
305                    sp->buffer_total_count,
306                    cnt-sp->buffer_total_count);
307
308         scnt = cnt & ~0x1f;
309         if (cnt > scnt) scnt += 0x20;
310
311         if (cnt > sp->buffer_total_count) {
312                 if (scnt > sp->buffer_slot_count) {
313                         struct pvr2_buffer **nb;
314                         nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
315                         if (!nb) return -ENOMEM;
316                         if (sp->buffer_slot_count) {
317                                 memcpy(nb,sp->buffers,
318                                        sp->buffer_slot_count * sizeof(*nb));
319                                 kfree(sp->buffers);
320                         }
321                         sp->buffers = nb;
322                         sp->buffer_slot_count = scnt;
323                 }
324                 while (sp->buffer_total_count < cnt) {
325                         struct pvr2_buffer *bp;
326                         bp = kmalloc(sizeof(*bp),GFP_KERNEL);
327                         if (!bp) return -ENOMEM;
328                         ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
329                         if (ret) {
330                                 kfree(bp);
331                                 return -ENOMEM;
332                         }
333                         sp->buffers[sp->buffer_total_count] = bp;
334                         (sp->buffer_total_count)++;
335                         pvr2_buffer_set_idle(bp);
336                 }
337         } else {
338                 while (sp->buffer_total_count > cnt) {
339                         struct pvr2_buffer *bp;
340                         bp = sp->buffers[sp->buffer_total_count - 1];
341                         /* Paranoia */
342                         sp->buffers[sp->buffer_total_count - 1] = 0;
343                         (sp->buffer_total_count)--;
344                         pvr2_buffer_done(bp);
345                         kfree(bp);
346                 }
347                 if (scnt < sp->buffer_slot_count) {
348                         struct pvr2_buffer **nb = 0;
349                         if (scnt) {
350                                 nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
351                                 if (!nb) return -ENOMEM;
352                                 memcpy(nb,sp->buffers,scnt * sizeof(*nb));
353                         }
354                         kfree(sp->buffers);
355                         sp->buffers = nb;
356                         sp->buffer_slot_count = scnt;
357                 }
358         }
359         return 0;
360 }
361
362 static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
363 {
364         struct pvr2_buffer *bp;
365         unsigned int cnt;
366
367         if (sp->buffer_total_count == sp->buffer_target_count) return 0;
368
369         pvr2_trace(PVR2_TRACE_BUF_POOL,
370                    "/*---TRACE_FLOW---*/"
371                    " poolCheck      stream=%p cur=%d tgt=%d",
372                    sp,sp->buffer_total_count,sp->buffer_target_count);
373
374         if (sp->buffer_total_count < sp->buffer_target_count) {
375                 return pvr2_stream_buffer_count(sp,sp->buffer_target_count);
376         }
377
378         cnt = 0;
379         while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) {
380                 bp = sp->buffers[sp->buffer_total_count - (cnt + 1)];
381                 if (bp->state != pvr2_buffer_state_idle) break;
382                 cnt++;
383         }
384         if (cnt) {
385                 pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt);
386         }
387
388         return 0;
389 }
390
391 static void pvr2_stream_internal_flush(struct pvr2_stream *sp)
392 {
393         struct list_head *lp;
394         struct pvr2_buffer *bp1;
395         while ((lp = sp->queued_list.next) != &sp->queued_list) {
396                 bp1 = list_entry(lp,struct pvr2_buffer,list_overhead);
397                 pvr2_buffer_wipe(bp1);
398                 /* At this point, we should be guaranteed that no
399                    completion callback may happen on this buffer.  But it's
400                    possible that it might have completed after we noticed
401                    it but before we wiped it.  So double check its status
402                    here first. */
403                 if (bp1->state != pvr2_buffer_state_queued) continue;
404                 pvr2_buffer_set_idle(bp1);
405         }
406         if (sp->buffer_total_count != sp->buffer_target_count) {
407                 pvr2_stream_achieve_buffer_count(sp);
408         }
409 }
410
411 static void pvr2_stream_init(struct pvr2_stream *sp)
412 {
413         spin_lock_init(&sp->list_lock);
414         mutex_init(&sp->mutex);
415         INIT_LIST_HEAD(&sp->queued_list);
416         INIT_LIST_HEAD(&sp->ready_list);
417         INIT_LIST_HEAD(&sp->idle_list);
418 }
419
420 static void pvr2_stream_done(struct pvr2_stream *sp)
421 {
422         mutex_lock(&sp->mutex); do {
423                 pvr2_stream_internal_flush(sp);
424                 pvr2_stream_buffer_count(sp,0);
425         } while (0); mutex_unlock(&sp->mutex);
426 }
427
428 static void buffer_complete(struct urb *urb, struct pt_regs *regs)
429 {
430         struct pvr2_buffer *bp = urb->context;
431         struct pvr2_stream *sp;
432         unsigned long irq_flags;
433         BUFFER_CHECK(bp);
434         sp = bp->stream;
435         bp->used_count = 0;
436         bp->status = 0;
437         pvr2_trace(PVR2_TRACE_BUF_FLOW,
438                    "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d",
439                    bp,urb->status,urb->actual_length);
440         spin_lock_irqsave(&sp->list_lock,irq_flags);
441         if ((!(urb->status)) ||
442             (urb->status == -ENOENT) ||
443             (urb->status == -ECONNRESET) ||
444             (urb->status == -ESHUTDOWN)) {
445                 bp->used_count = urb->actual_length;
446                 if (sp->fail_count) {
447                         pvr2_trace(PVR2_TRACE_TOLERANCE,
448                                    "stream %p transfer ok"
449                                    " - fail count reset",sp);
450                         sp->fail_count = 0;
451                 }
452         } else if (sp->fail_count < sp->fail_tolerance) {
453                 // We can tolerate this error, because we're below the
454                 // threshold...
455                 (sp->fail_count)++;
456                 pvr2_trace(PVR2_TRACE_TOLERANCE,
457                            "stream %p ignoring error %d"
458                            " - fail count increased to %u",
459                            sp,urb->status,sp->fail_count);
460         } else {
461                 bp->status = urb->status;
462         }
463         spin_unlock_irqrestore(&sp->list_lock,irq_flags);
464         pvr2_buffer_set_ready(bp);
465         if (sp && sp->callback_func) {
466                 sp->callback_func(sp->callback_data);
467         }
468 }
469
470 struct pvr2_stream *pvr2_stream_create(void)
471 {
472         struct pvr2_stream *sp;
473         sp = kmalloc(sizeof(*sp),GFP_KERNEL);
474         if (!sp) return sp;
475         memset(sp,0,sizeof(*sp));
476         pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
477         pvr2_stream_init(sp);
478         return sp;
479 }
480
481 void pvr2_stream_destroy(struct pvr2_stream *sp)
482 {
483         if (!sp) return;
484         pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
485         pvr2_stream_done(sp);
486         kfree(sp);
487 }
488
489 void pvr2_stream_setup(struct pvr2_stream *sp,
490                        struct usb_device *dev,
491                        int endpoint,
492                        unsigned int tolerance)
493 {
494         mutex_lock(&sp->mutex); do {
495                 pvr2_stream_internal_flush(sp);
496                 sp->dev = dev;
497                 sp->endpoint = endpoint;
498                 sp->fail_tolerance = tolerance;
499         } while(0); mutex_unlock(&sp->mutex);
500 }
501
502 void pvr2_stream_set_callback(struct pvr2_stream *sp,
503                               pvr2_stream_callback func,
504                               void *data)
505 {
506         unsigned long irq_flags;
507         mutex_lock(&sp->mutex); do {
508                 spin_lock_irqsave(&sp->list_lock,irq_flags);
509                 sp->callback_data = data;
510                 sp->callback_func = func;
511                 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
512         } while(0); mutex_unlock(&sp->mutex);
513 }
514
515 /* Query / set the nominal buffer count */
516 int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
517 {
518         return sp->buffer_target_count;
519 }
520
521 int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
522 {
523         int ret;
524         if (sp->buffer_target_count == cnt) return 0;
525         mutex_lock(&sp->mutex); do {
526                 sp->buffer_target_count = cnt;
527                 ret = pvr2_stream_achieve_buffer_count(sp);
528         } while(0); mutex_unlock(&sp->mutex);
529         return ret;
530 }
531
532 struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
533 {
534         struct list_head *lp = sp->idle_list.next;
535         if (lp == &sp->idle_list) return 0;
536         return list_entry(lp,struct pvr2_buffer,list_overhead);
537 }
538
539 struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
540 {
541         struct list_head *lp = sp->ready_list.next;
542         if (lp == &sp->ready_list) return 0;
543         return list_entry(lp,struct pvr2_buffer,list_overhead);
544 }
545
546 struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
547 {
548         if (id < 0) return 0;
549         if (id >= sp->buffer_total_count) return 0;
550         return sp->buffers[id];
551 }
552
553 int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
554 {
555         return sp->r_count;
556 }
557
558 int pvr2_stream_get_idle_count(struct pvr2_stream *sp)
559 {
560         return sp->i_count;
561 }
562
563 void pvr2_stream_flush(struct pvr2_stream *sp)
564 {
565         mutex_lock(&sp->mutex); do {
566                 pvr2_stream_internal_flush(sp);
567         } while(0); mutex_unlock(&sp->mutex);
568 }
569
570 void pvr2_stream_kill(struct pvr2_stream *sp)
571 {
572         struct pvr2_buffer *bp;
573         mutex_lock(&sp->mutex); do {
574                 pvr2_stream_internal_flush(sp);
575                 while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) {
576                         pvr2_buffer_set_idle(bp);
577                 }
578                 if (sp->buffer_total_count != sp->buffer_target_count) {
579                         pvr2_stream_achieve_buffer_count(sp);
580                 }
581         } while(0); mutex_unlock(&sp->mutex);
582 }
583
584 int pvr2_buffer_queue(struct pvr2_buffer *bp)
585 {
586 #undef SEED_BUFFER
587 #ifdef SEED_BUFFER
588         unsigned int idx;
589         unsigned int val;
590 #endif
591         int ret = 0;
592         struct pvr2_stream *sp;
593         if (!bp) return -EINVAL;
594         sp = bp->stream;
595         mutex_lock(&sp->mutex); do {
596                 pvr2_buffer_wipe(bp);
597                 if (!sp->dev) {
598                         ret = -EIO;
599                         break;
600                 }
601                 pvr2_buffer_set_queued(bp);
602 #ifdef SEED_BUFFER
603                 for (idx = 0; idx < (bp->max_count) / 4; idx++) {
604                         val = bp->id << 24;
605                         val |= idx;
606                         ((unsigned int *)(bp->ptr))[idx] = val;
607                 }
608 #endif
609                 bp->status = -EINPROGRESS;
610                 usb_fill_bulk_urb(bp->purb,      // struct urb *urb
611                                   sp->dev,       // struct usb_device *dev
612                                   // endpoint (below)
613                                   usb_rcvbulkpipe(sp->dev,sp->endpoint),
614                                   bp->ptr,       // void *transfer_buffer
615                                   bp->max_count, // int buffer_length
616                                   buffer_complete,
617                                   bp);
618                 usb_submit_urb(bp->purb,GFP_KERNEL);
619         } while(0); mutex_unlock(&sp->mutex);
620         return ret;
621 }
622
623 int pvr2_buffer_idle(struct pvr2_buffer *bp)
624 {
625         struct pvr2_stream *sp;
626         if (!bp) return -EINVAL;
627         sp = bp->stream;
628         mutex_lock(&sp->mutex); do {
629                 pvr2_buffer_wipe(bp);
630                 pvr2_buffer_set_idle(bp);
631                 if (sp->buffer_total_count != sp->buffer_target_count) {
632                         pvr2_stream_achieve_buffer_count(sp);
633                 }
634         } while(0); mutex_unlock(&sp->mutex);
635         return 0;
636 }
637
638 int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
639 {
640         int ret = 0;
641         unsigned long irq_flags;
642         struct pvr2_stream *sp;
643         if (!bp) return -EINVAL;
644         sp = bp->stream;
645         mutex_lock(&sp->mutex); do {
646                 spin_lock_irqsave(&sp->list_lock,irq_flags);
647                 if (bp->state != pvr2_buffer_state_idle) {
648                         ret = -EPERM;
649                 } else {
650                         bp->ptr = ptr;
651                         bp->stream->i_bcount -= bp->max_count;
652                         bp->max_count = cnt;
653                         bp->stream->i_bcount += bp->max_count;
654                         pvr2_trace(PVR2_TRACE_BUF_FLOW,
655                                    "/*---TRACE_FLOW---*/ bufferPool    "
656                                    " %8s cap cap=%07d cnt=%02d",
657                                    pvr2_buffer_state_decode(
658                                            pvr2_buffer_state_idle),
659                                    bp->stream->i_bcount,bp->stream->i_count);
660                 }
661                 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
662         } while(0); mutex_unlock(&sp->mutex);
663         return ret;
664 }
665
666 unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
667 {
668         return bp->used_count;
669 }
670
671 int pvr2_buffer_get_status(struct pvr2_buffer *bp)
672 {
673         return bp->status;
674 }
675
676 enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *bp)
677 {
678         return bp->state;
679 }
680
681 int pvr2_buffer_get_id(struct pvr2_buffer *bp)
682 {
683         return bp->id;
684 }
685
686
687 /*
688   Stuff for Emacs to see, in order to encourage consistent editing style:
689   *** Local Variables: ***
690   *** mode: c ***
691   *** fill-column: 75 ***
692   *** tab-width: 8 ***
693   *** c-basic-offset: 8 ***
694   *** End: ***
695   */