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