~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/media/video/pvrusb2/pvrusb2-io.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

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