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