4 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
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
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.
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
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>
28 static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state
);
30 #define BUFFER_SIG 0x47653271
32 // #define SANITY_CHECK_BUFFERS
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"); \
46 #define BUFFER_CHECK(bp) do {} while(0)
50 /* Buffers queued for reading */
51 struct list_head queued_list
;
53 unsigned int q_bcount
;
54 /* Buffers with retrieved data */
55 struct list_head ready_list
;
57 unsigned int r_bcount
;
58 /* Buffers available for use */
59 struct list_head idle_list
;
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
;
73 /* Context for transfer endpoint */
74 struct usb_device
*dev
;
76 /* Overhead for mutex enforcement */
79 /* Tracking state for tolerating errors */
80 unsigned int fail_count
;
81 unsigned int fail_tolerance
;
83 unsigned int buffers_processed
;
84 unsigned int buffers_failed
;
85 unsigned int bytes_processed
;
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
;
101 static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state 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";
112 #ifdef SANITY_CHECK_BUFFERS
113 static void pvr2_buffer_describe(struct pvr2_buffer
*bp
,const char *msg
)
115 pvr2_trace(PVR2_TRACE_INFO
,
116 "buffer%s%s %p state=%s id=%d status=%d stream=%p purb=%p sig=0x%x",
120 (bp
? pvr2_buffer_state_decode(bp
->state
) : "(invalid)"),
122 (bp
? bp
->status
: 0),
123 (bp
? bp
->stream
: NULL
),
124 (bp
? bp
->purb
: NULL
),
125 (bp
? bp
->signature
: 0));
127 #endif /* SANITY_CHECK_BUFFERS */
129 static void pvr2_buffer_remove(struct pvr2_buffer
*bp
)
134 struct pvr2_stream
*sp
= bp
->stream
;
136 case pvr2_buffer_state_idle
:
138 bcnt
= &sp
->i_bcount
;
139 ccnt
= bp
->max_count
;
141 case pvr2_buffer_state_queued
:
143 bcnt
= &sp
->q_bcount
;
144 ccnt
= bp
->max_count
;
146 case pvr2_buffer_state_ready
:
148 bcnt
= &sp
->r_bcount
;
149 ccnt
= bp
->used_count
;
154 list_del_init(&bp
->list_overhead
);
157 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
158 "/*---TRACE_FLOW---*/ bufferPool %8s dec cap=%07d cnt=%02d",
159 pvr2_buffer_state_decode(bp
->state
),*bcnt
,*cnt
);
160 bp
->state
= pvr2_buffer_state_none
;
163 static void pvr2_buffer_set_none(struct pvr2_buffer
*bp
)
165 unsigned long irq_flags
;
166 struct pvr2_stream
*sp
;
169 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
170 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
172 pvr2_buffer_state_decode(bp
->state
),
173 pvr2_buffer_state_decode(pvr2_buffer_state_none
));
174 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
175 pvr2_buffer_remove(bp
);
176 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
179 static int pvr2_buffer_set_ready(struct pvr2_buffer
*bp
)
182 unsigned long irq_flags
;
183 struct pvr2_stream
*sp
;
186 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
187 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
189 pvr2_buffer_state_decode(bp
->state
),
190 pvr2_buffer_state_decode(pvr2_buffer_state_ready
));
191 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
192 fl
= (sp
->r_count
== 0);
193 pvr2_buffer_remove(bp
);
194 list_add_tail(&bp
->list_overhead
,&sp
->ready_list
);
195 bp
->state
= pvr2_buffer_state_ready
;
197 sp
->r_bcount
+= bp
->used_count
;
198 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
199 "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d",
200 pvr2_buffer_state_decode(bp
->state
),
201 sp
->r_bcount
,sp
->r_count
);
202 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
206 static void pvr2_buffer_set_idle(struct pvr2_buffer
*bp
)
208 unsigned long irq_flags
;
209 struct pvr2_stream
*sp
;
212 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
213 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
215 pvr2_buffer_state_decode(bp
->state
),
216 pvr2_buffer_state_decode(pvr2_buffer_state_idle
));
217 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
218 pvr2_buffer_remove(bp
);
219 list_add_tail(&bp
->list_overhead
,&sp
->idle_list
);
220 bp
->state
= pvr2_buffer_state_idle
;
222 sp
->i_bcount
+= bp
->max_count
;
223 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
224 "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d",
225 pvr2_buffer_state_decode(bp
->state
),
226 sp
->i_bcount
,sp
->i_count
);
227 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
230 static void pvr2_buffer_set_queued(struct pvr2_buffer
*bp
)
232 unsigned long irq_flags
;
233 struct pvr2_stream
*sp
;
236 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
237 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
239 pvr2_buffer_state_decode(bp
->state
),
240 pvr2_buffer_state_decode(pvr2_buffer_state_queued
));
241 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
242 pvr2_buffer_remove(bp
);
243 list_add_tail(&bp
->list_overhead
,&sp
->queued_list
);
244 bp
->state
= pvr2_buffer_state_queued
;
246 sp
->q_bcount
+= bp
->max_count
;
247 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
248 "/*---TRACE_FLOW---*/ bufferPool %8s inc cap=%07d cnt=%02d",
249 pvr2_buffer_state_decode(bp
->state
),
250 sp
->q_bcount
,sp
->q_count
);
251 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
254 static void pvr2_buffer_wipe(struct pvr2_buffer
*bp
)
256 if (bp
->state
== pvr2_buffer_state_queued
) {
257 usb_kill_urb(bp
->purb
);
261 static int pvr2_buffer_init(struct pvr2_buffer
*bp
,
262 struct pvr2_stream
*sp
,
265 memset(bp
,0,sizeof(*bp
));
266 bp
->signature
= BUFFER_SIG
;
268 pvr2_trace(PVR2_TRACE_BUF_POOL
,
269 "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp
,sp
);
271 bp
->state
= pvr2_buffer_state_none
;
272 INIT_LIST_HEAD(&bp
->list_overhead
);
273 bp
->purb
= usb_alloc_urb(0,GFP_KERNEL
);
274 if (! bp
->purb
) return -ENOMEM
;
275 #ifdef SANITY_CHECK_BUFFERS
276 pvr2_buffer_describe(bp
,"create");
281 static void pvr2_buffer_done(struct pvr2_buffer
*bp
)
283 #ifdef SANITY_CHECK_BUFFERS
284 pvr2_buffer_describe(bp
,"delete");
286 pvr2_buffer_wipe(bp
);
287 pvr2_buffer_set_none(bp
);
290 usb_free_urb(bp
->purb
);
291 pvr2_trace(PVR2_TRACE_BUF_POOL
, "/*---TRACE_FLOW---*/ bufferDone %p",
295 static int pvr2_stream_buffer_count(struct pvr2_stream
*sp
,unsigned int cnt
)
300 /* Allocate buffers pointer array in multiples of 32 entries */
301 if (cnt
== sp
->buffer_total_count
) return 0;
303 pvr2_trace(PVR2_TRACE_BUF_POOL
,
304 "/*---TRACE_FLOW---*/ poolResize stream=%p cur=%d adj=%+d",
306 sp
->buffer_total_count
,
307 cnt
-sp
->buffer_total_count
);
310 if (cnt
> scnt
) scnt
+= 0x20;
312 if (cnt
> sp
->buffer_total_count
) {
313 if (scnt
> sp
->buffer_slot_count
) {
314 struct pvr2_buffer
**nb
;
315 nb
= kmalloc(scnt
* sizeof(*nb
),GFP_KERNEL
);
316 if (!nb
) return -ENOMEM
;
317 if (sp
->buffer_slot_count
) {
318 memcpy(nb
,sp
->buffers
,
319 sp
->buffer_slot_count
* sizeof(*nb
));
323 sp
->buffer_slot_count
= scnt
;
325 while (sp
->buffer_total_count
< cnt
) {
326 struct pvr2_buffer
*bp
;
327 bp
= kmalloc(sizeof(*bp
),GFP_KERNEL
);
328 if (!bp
) return -ENOMEM
;
329 ret
= pvr2_buffer_init(bp
,sp
,sp
->buffer_total_count
);
334 sp
->buffers
[sp
->buffer_total_count
] = bp
;
335 (sp
->buffer_total_count
)++;
336 pvr2_buffer_set_idle(bp
);
339 while (sp
->buffer_total_count
> cnt
) {
340 struct pvr2_buffer
*bp
;
341 bp
= sp
->buffers
[sp
->buffer_total_count
- 1];
343 sp
->buffers
[sp
->buffer_total_count
- 1] = NULL
;
344 (sp
->buffer_total_count
)--;
345 pvr2_buffer_done(bp
);
348 if (scnt
< sp
->buffer_slot_count
) {
349 struct pvr2_buffer
**nb
= NULL
;
351 nb
= kmemdup(sp
->buffers
, scnt
* sizeof(*nb
),
353 if (!nb
) return -ENOMEM
;
357 sp
->buffer_slot_count
= scnt
;
363 static int pvr2_stream_achieve_buffer_count(struct pvr2_stream
*sp
)
365 struct pvr2_buffer
*bp
;
368 if (sp
->buffer_total_count
== sp
->buffer_target_count
) return 0;
370 pvr2_trace(PVR2_TRACE_BUF_POOL
,
371 "/*---TRACE_FLOW---*/ poolCheck stream=%p cur=%d tgt=%d",
372 sp
,sp
->buffer_total_count
,sp
->buffer_target_count
);
374 if (sp
->buffer_total_count
< sp
->buffer_target_count
) {
375 return pvr2_stream_buffer_count(sp
,sp
->buffer_target_count
);
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;
385 pvr2_stream_buffer_count(sp
,sp
->buffer_total_count
- cnt
);
391 static void pvr2_stream_internal_flush(struct pvr2_stream
*sp
)
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
403 if (bp1
->state
!= pvr2_buffer_state_queued
) continue;
404 pvr2_buffer_set_idle(bp1
);
406 if (sp
->buffer_total_count
!= sp
->buffer_target_count
) {
407 pvr2_stream_achieve_buffer_count(sp
);
411 static void pvr2_stream_init(struct pvr2_stream
*sp
)
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
);
420 static void pvr2_stream_done(struct pvr2_stream
*sp
)
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
);
428 static void buffer_complete(struct urb
*urb
)
430 struct pvr2_buffer
*bp
= urb
->context
;
431 struct pvr2_stream
*sp
;
432 unsigned long irq_flags
;
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 (sp
->buffers_processed
)++;
446 sp
->bytes_processed
+= urb
->actual_length
;
447 bp
->used_count
= urb
->actual_length
;
448 if (sp
->fail_count
) {
449 pvr2_trace(PVR2_TRACE_TOLERANCE
,
450 "stream %p transfer ok - fail count reset",
454 } else if (sp
->fail_count
< sp
->fail_tolerance
) {
455 // We can tolerate this error, because we're below the
458 (sp
->buffers_failed
)++;
459 pvr2_trace(PVR2_TRACE_TOLERANCE
,
460 "stream %p ignoring error %d - fail count increased to %u",
461 sp
,urb
->status
,sp
->fail_count
);
463 (sp
->buffers_failed
)++;
464 bp
->status
= urb
->status
;
466 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
467 pvr2_buffer_set_ready(bp
);
468 if (sp
->callback_func
) {
469 sp
->callback_func(sp
->callback_data
);
473 struct pvr2_stream
*pvr2_stream_create(void)
475 struct pvr2_stream
*sp
;
476 sp
= kzalloc(sizeof(*sp
),GFP_KERNEL
);
478 pvr2_trace(PVR2_TRACE_INIT
,"pvr2_stream_create: sp=%p",sp
);
479 pvr2_stream_init(sp
);
483 void pvr2_stream_destroy(struct pvr2_stream
*sp
)
486 pvr2_trace(PVR2_TRACE_INIT
,"pvr2_stream_destroy: sp=%p",sp
);
487 pvr2_stream_done(sp
);
491 void pvr2_stream_setup(struct pvr2_stream
*sp
,
492 struct usb_device
*dev
,
494 unsigned int tolerance
)
496 mutex_lock(&sp
->mutex
); do {
497 pvr2_stream_internal_flush(sp
);
499 sp
->endpoint
= endpoint
;
500 sp
->fail_tolerance
= tolerance
;
501 } while(0); mutex_unlock(&sp
->mutex
);
504 void pvr2_stream_set_callback(struct pvr2_stream
*sp
,
505 pvr2_stream_callback func
,
508 unsigned long irq_flags
;
509 mutex_lock(&sp
->mutex
);
511 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
512 sp
->callback_data
= data
;
513 sp
->callback_func
= func
;
514 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
516 mutex_unlock(&sp
->mutex
);
519 void pvr2_stream_get_stats(struct pvr2_stream
*sp
,
520 struct pvr2_stream_stats
*stats
,
523 unsigned long irq_flags
;
524 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
526 stats
->buffers_in_queue
= sp
->q_count
;
527 stats
->buffers_in_idle
= sp
->i_count
;
528 stats
->buffers_in_ready
= sp
->r_count
;
529 stats
->buffers_processed
= sp
->buffers_processed
;
530 stats
->buffers_failed
= sp
->buffers_failed
;
531 stats
->bytes_processed
= sp
->bytes_processed
;
534 sp
->buffers_processed
= 0;
535 sp
->buffers_failed
= 0;
536 sp
->bytes_processed
= 0;
538 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
541 /* Query / set the nominal buffer count */
542 int pvr2_stream_get_buffer_count(struct pvr2_stream
*sp
)
544 return sp
->buffer_target_count
;
547 int pvr2_stream_set_buffer_count(struct pvr2_stream
*sp
,unsigned int cnt
)
550 if (sp
->buffer_target_count
== cnt
) return 0;
551 mutex_lock(&sp
->mutex
);
553 sp
->buffer_target_count
= cnt
;
554 ret
= pvr2_stream_achieve_buffer_count(sp
);
556 mutex_unlock(&sp
->mutex
);
560 struct pvr2_buffer
*pvr2_stream_get_idle_buffer(struct pvr2_stream
*sp
)
562 struct list_head
*lp
= sp
->idle_list
.next
;
563 if (lp
== &sp
->idle_list
) return NULL
;
564 return list_entry(lp
,struct pvr2_buffer
,list_overhead
);
567 struct pvr2_buffer
*pvr2_stream_get_ready_buffer(struct pvr2_stream
*sp
)
569 struct list_head
*lp
= sp
->ready_list
.next
;
570 if (lp
== &sp
->ready_list
) return NULL
;
571 return list_entry(lp
,struct pvr2_buffer
,list_overhead
);
574 struct pvr2_buffer
*pvr2_stream_get_buffer(struct pvr2_stream
*sp
,int id
)
576 if (id
< 0) return NULL
;
577 if (id
>= sp
->buffer_total_count
) return NULL
;
578 return sp
->buffers
[id
];
581 int pvr2_stream_get_ready_count(struct pvr2_stream
*sp
)
586 void pvr2_stream_kill(struct pvr2_stream
*sp
)
588 struct pvr2_buffer
*bp
;
589 mutex_lock(&sp
->mutex
);
591 pvr2_stream_internal_flush(sp
);
592 while ((bp
= pvr2_stream_get_ready_buffer(sp
)) != NULL
) {
593 pvr2_buffer_set_idle(bp
);
595 if (sp
->buffer_total_count
!= sp
->buffer_target_count
) {
596 pvr2_stream_achieve_buffer_count(sp
);
599 mutex_unlock(&sp
->mutex
);
602 int pvr2_buffer_queue(struct pvr2_buffer
*bp
)
610 struct pvr2_stream
*sp
;
611 if (!bp
) return -EINVAL
;
613 mutex_lock(&sp
->mutex
);
615 pvr2_buffer_wipe(bp
);
620 pvr2_buffer_set_queued(bp
);
622 for (idx
= 0; idx
< (bp
->max_count
) / 4; idx
++) {
625 ((unsigned int *)(bp
->ptr
))[idx
] = val
;
628 bp
->status
= -EINPROGRESS
;
629 usb_fill_bulk_urb(bp
->purb
, // struct urb *urb
630 sp
->dev
, // struct usb_device *dev
632 usb_rcvbulkpipe(sp
->dev
,sp
->endpoint
),
633 bp
->ptr
, // void *transfer_buffer
634 bp
->max_count
, // int buffer_length
637 usb_submit_urb(bp
->purb
,GFP_KERNEL
);
639 mutex_unlock(&sp
->mutex
);
643 int pvr2_buffer_set_buffer(struct pvr2_buffer
*bp
,void *ptr
,unsigned int cnt
)
646 unsigned long irq_flags
;
647 struct pvr2_stream
*sp
;
648 if (!bp
) return -EINVAL
;
650 mutex_lock(&sp
->mutex
);
652 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
653 if (bp
->state
!= pvr2_buffer_state_idle
) {
657 bp
->stream
->i_bcount
-= bp
->max_count
;
659 bp
->stream
->i_bcount
+= bp
->max_count
;
660 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
661 "/*---TRACE_FLOW---*/ bufferPool %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
);
666 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
668 mutex_unlock(&sp
->mutex
);
672 unsigned int pvr2_buffer_get_count(struct pvr2_buffer
*bp
)
674 return bp
->used_count
;
677 int pvr2_buffer_get_status(struct pvr2_buffer
*bp
)
682 int pvr2_buffer_get_id(struct pvr2_buffer
*bp
)