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"
117 " stream=%p purb=%p sig=0x%x",
121 (bp
? pvr2_buffer_state_decode(bp
->state
) : "(invalid)"),
123 (bp
? bp
->status
: 0),
124 (bp
? bp
->stream
: NULL
),
125 (bp
? bp
->purb
: NULL
),
126 (bp
? bp
->signature
: 0));
128 #endif /* SANITY_CHECK_BUFFERS */
130 static void pvr2_buffer_remove(struct pvr2_buffer
*bp
)
135 struct pvr2_stream
*sp
= bp
->stream
;
137 case pvr2_buffer_state_idle
:
139 bcnt
= &sp
->i_bcount
;
140 ccnt
= bp
->max_count
;
142 case pvr2_buffer_state_queued
:
144 bcnt
= &sp
->q_bcount
;
145 ccnt
= bp
->max_count
;
147 case pvr2_buffer_state_ready
:
149 bcnt
= &sp
->r_bcount
;
150 ccnt
= bp
->used_count
;
155 list_del_init(&bp
->list_overhead
);
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
;
165 static void pvr2_buffer_set_none(struct pvr2_buffer
*bp
)
167 unsigned long irq_flags
;
168 struct pvr2_stream
*sp
;
171 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
172 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
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
);
181 static int pvr2_buffer_set_ready(struct pvr2_buffer
*bp
)
184 unsigned long irq_flags
;
185 struct pvr2_stream
*sp
;
188 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
189 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
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
;
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
);
209 static void pvr2_buffer_set_idle(struct pvr2_buffer
*bp
)
211 unsigned long irq_flags
;
212 struct pvr2_stream
*sp
;
215 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
216 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
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
;
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
);
234 static void pvr2_buffer_set_queued(struct pvr2_buffer
*bp
)
236 unsigned long irq_flags
;
237 struct pvr2_stream
*sp
;
240 pvr2_trace(PVR2_TRACE_BUF_FLOW
,
241 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
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
;
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
);
259 static void pvr2_buffer_wipe(struct pvr2_buffer
*bp
)
261 if (bp
->state
== pvr2_buffer_state_queued
) {
262 usb_kill_urb(bp
->purb
);
266 static int pvr2_buffer_init(struct pvr2_buffer
*bp
,
267 struct pvr2_stream
*sp
,
270 memset(bp
,0,sizeof(*bp
));
271 bp
->signature
= BUFFER_SIG
;
273 pvr2_trace(PVR2_TRACE_BUF_POOL
,
274 "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp
,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");
286 static void pvr2_buffer_done(struct pvr2_buffer
*bp
)
288 #ifdef SANITY_CHECK_BUFFERS
289 pvr2_buffer_describe(bp
,"delete");
291 pvr2_buffer_wipe(bp
);
292 pvr2_buffer_set_none(bp
);
295 usb_free_urb(bp
->purb
);
296 pvr2_trace(PVR2_TRACE_BUF_POOL
,"/*---TRACE_FLOW---*/"
297 " bufferDone %p",bp
);
300 static int pvr2_stream_buffer_count(struct pvr2_stream
*sp
,unsigned int cnt
)
305 /* Allocate buffers pointer array in multiples of 32 entries */
306 if (cnt
== sp
->buffer_total_count
) return 0;
308 pvr2_trace(PVR2_TRACE_BUF_POOL
,
309 "/*---TRACE_FLOW---*/ poolResize "
310 " stream=%p cur=%d adj=%+d",
312 sp
->buffer_total_count
,
313 cnt
-sp
->buffer_total_count
);
316 if (cnt
> scnt
) scnt
+= 0x20;
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
));
329 sp
->buffer_slot_count
= scnt
;
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
);
340 sp
->buffers
[sp
->buffer_total_count
] = bp
;
341 (sp
->buffer_total_count
)++;
342 pvr2_buffer_set_idle(bp
);
345 while (sp
->buffer_total_count
> cnt
) {
346 struct pvr2_buffer
*bp
;
347 bp
= sp
->buffers
[sp
->buffer_total_count
- 1];
349 sp
->buffers
[sp
->buffer_total_count
- 1] = NULL
;
350 (sp
->buffer_total_count
)--;
351 pvr2_buffer_done(bp
);
354 if (scnt
< sp
->buffer_slot_count
) {
355 struct pvr2_buffer
**nb
= NULL
;
357 nb
= kmemdup(sp
->buffers
, scnt
* sizeof(*nb
),
359 if (!nb
) return -ENOMEM
;
363 sp
->buffer_slot_count
= scnt
;
369 static int pvr2_stream_achieve_buffer_count(struct pvr2_stream
*sp
)
371 struct pvr2_buffer
*bp
;
374 if (sp
->buffer_total_count
== sp
->buffer_target_count
) return 0;
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
);
381 if (sp
->buffer_total_count
< sp
->buffer_target_count
) {
382 return pvr2_stream_buffer_count(sp
,sp
->buffer_target_count
);
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;
392 pvr2_stream_buffer_count(sp
,sp
->buffer_total_count
- cnt
);
398 static void pvr2_stream_internal_flush(struct pvr2_stream
*sp
)
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
410 if (bp1
->state
!= pvr2_buffer_state_queued
) continue;
411 pvr2_buffer_set_idle(bp1
);
413 if (sp
->buffer_total_count
!= sp
->buffer_target_count
) {
414 pvr2_stream_achieve_buffer_count(sp
);
418 static void pvr2_stream_init(struct pvr2_stream
*sp
)
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
);
427 static void pvr2_stream_done(struct pvr2_stream
*sp
)
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
);
435 static void buffer_complete(struct urb
*urb
)
437 struct pvr2_buffer
*bp
= urb
->context
;
438 struct pvr2_stream
*sp
;
439 unsigned long irq_flags
;
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
);
461 } else if (sp
->fail_count
< sp
->fail_tolerance
) {
462 // We can tolerate this error, because we're below the
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
);
471 (sp
->buffers_failed
)++;
472 bp
->status
= urb
->status
;
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
);
481 struct pvr2_stream
*pvr2_stream_create(void)
483 struct pvr2_stream
*sp
;
484 sp
= kzalloc(sizeof(*sp
),GFP_KERNEL
);
486 pvr2_trace(PVR2_TRACE_INIT
,"pvr2_stream_create: sp=%p",sp
);
487 pvr2_stream_init(sp
);
491 void pvr2_stream_destroy(struct pvr2_stream
*sp
)
494 pvr2_trace(PVR2_TRACE_INIT
,"pvr2_stream_destroy: sp=%p",sp
);
495 pvr2_stream_done(sp
);
499 void pvr2_stream_setup(struct pvr2_stream
*sp
,
500 struct usb_device
*dev
,
502 unsigned int tolerance
)
504 mutex_lock(&sp
->mutex
); do {
505 pvr2_stream_internal_flush(sp
);
507 sp
->endpoint
= endpoint
;
508 sp
->fail_tolerance
= tolerance
;
509 } while(0); mutex_unlock(&sp
->mutex
);
512 void pvr2_stream_set_callback(struct pvr2_stream
*sp
,
513 pvr2_stream_callback func
,
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
);
525 void pvr2_stream_get_stats(struct pvr2_stream
*sp
,
526 struct pvr2_stream_stats
*stats
,
529 unsigned long irq_flags
;
530 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
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
;
540 sp
->buffers_processed
= 0;
541 sp
->buffers_failed
= 0;
542 sp
->bytes_processed
= 0;
544 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
547 /* Query / set the nominal buffer count */
548 int pvr2_stream_get_buffer_count(struct pvr2_stream
*sp
)
550 return sp
->buffer_target_count
;
553 int pvr2_stream_set_buffer_count(struct pvr2_stream
*sp
,unsigned int cnt
)
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
);
564 struct pvr2_buffer
*pvr2_stream_get_idle_buffer(struct pvr2_stream
*sp
)
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
);
571 struct pvr2_buffer
*pvr2_stream_get_ready_buffer(struct pvr2_stream
*sp
)
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
);
578 struct pvr2_buffer
*pvr2_stream_get_buffer(struct pvr2_stream
*sp
,int id
)
580 if (id
< 0) return NULL
;
581 if (id
>= sp
->buffer_total_count
) return NULL
;
582 return sp
->buffers
[id
];
585 int pvr2_stream_get_ready_count(struct pvr2_stream
*sp
)
590 void pvr2_stream_kill(struct pvr2_stream
*sp
)
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
);
598 if (sp
->buffer_total_count
!= sp
->buffer_target_count
) {
599 pvr2_stream_achieve_buffer_count(sp
);
601 } while(0); mutex_unlock(&sp
->mutex
);
604 int pvr2_buffer_queue(struct pvr2_buffer
*bp
)
612 struct pvr2_stream
*sp
;
613 if (!bp
) return -EINVAL
;
615 mutex_lock(&sp
->mutex
); do {
616 pvr2_buffer_wipe(bp
);
621 pvr2_buffer_set_queued(bp
);
623 for (idx
= 0; idx
< (bp
->max_count
) / 4; idx
++) {
626 ((unsigned int *)(bp
->ptr
))[idx
] = val
;
629 bp
->status
= -EINPROGRESS
;
630 usb_fill_bulk_urb(bp
->purb
, // struct urb *urb
631 sp
->dev
, // struct usb_device *dev
633 usb_rcvbulkpipe(sp
->dev
,sp
->endpoint
),
634 bp
->ptr
, // void *transfer_buffer
635 bp
->max_count
, // int buffer_length
638 usb_submit_urb(bp
->purb
,GFP_KERNEL
);
639 } while(0); 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
); do {
651 spin_lock_irqsave(&sp
->list_lock
,irq_flags
);
652 if (bp
->state
!= pvr2_buffer_state_idle
) {
656 bp
->stream
->i_bcount
-= bp
->max_count
;
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
);
666 spin_unlock_irqrestore(&sp
->list_lock
,irq_flags
);
667 } while(0); mutex_unlock(&sp
->mutex
);
671 unsigned int pvr2_buffer_get_count(struct pvr2_buffer
*bp
)
673 return bp
->used_count
;
676 int pvr2_buffer_get_status(struct pvr2_buffer
*bp
)
681 int pvr2_buffer_get_id(struct pvr2_buffer
*bp
)
688 Stuff for Emacs to see, in order to encourage consistent editing style:
689 *** Local Variables: ***
691 *** fill-column: 75 ***
693 *** c-basic-offset: 8 ***