5 * Copyright (C) 2005 Mike Isely <isely@pobox.com>
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
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.
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
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>
29 #define BUFFER_SIG 0x47653271
31 // #define SANITY_CHECK_BUFFERS
34 #ifdef SANITY_CHECK_BUFFERS
35 #define BUFFER_CHECK(bp) do { \
36 if ((bp)->signature != BUFFER_SIG) { \
37 pvr2_trace(PVR2_TRACE_ERROR_LEGS, \
38 "Buffer %p is bad at %s:%d", \
39 (bp),__FILE__,__LINE__); \
40 pvr2_buffer_describe(bp,"BadSig"); \
45 #define BUFFER_CHECK(bp) do {} while(0)
49 /* Buffers queued for reading */
50 struct list_head queued_list;
52 unsigned int q_bcount;
53 /* Buffers with retrieved data */
54 struct list_head ready_list;
56 unsigned int r_bcount;
57 /* Buffers available for use */
58 struct list_head idle_list;
60 unsigned int i_bcount;
61 /* Pointers to all buffers */
62 struct pvr2_buffer **buffers;
63 /* Array size of buffers */
64 unsigned int buffer_slot_count;
65 /* Total buffers actually in circulation */
66 unsigned int buffer_total_count;
67 /* Designed number of buffers to be in circulation */
68 unsigned int buffer_target_count;
69 /* Executed when ready list become non-empty */
70 pvr2_stream_callback callback_func;
72 /* Context for transfer endpoint */
73 struct usb_device *dev;
75 /* Overhead for mutex enforcement */
78 /* Tracking state for tolerating errors */
79 unsigned int fail_count;
80 unsigned int fail_tolerance;
86 enum pvr2_buffer_state state;
87 void *ptr; /* Pointer to storage area */
88 unsigned int max_count; /* Size of storage area */
89 unsigned int used_count; /* Amount of valid data in storage area */
90 int status; /* Transfer result status */
91 struct pvr2_stream *stream;
92 struct list_head list_overhead;
96 const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st)
99 case pvr2_buffer_state_none: return "none";
100 case pvr2_buffer_state_idle: return "idle";
101 case pvr2_buffer_state_queued: return "queued";
102 case pvr2_buffer_state_ready: return "ready";
107 void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg)
109 pvr2_trace(PVR2_TRACE_INFO,
110 "buffer%s%s %p state=%s id=%d status=%d"
111 " stream=%p purb=%p sig=0x%x",
115 (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"),
117 (bp ? bp->status : 0),
118 (bp ? bp->stream : 0),
120 (bp ? bp->signature : 0));
123 static void pvr2_buffer_remove(struct pvr2_buffer *bp)
128 struct pvr2_stream *sp = bp->stream;
130 case pvr2_buffer_state_idle:
132 bcnt = &sp->i_bcount;
133 ccnt = bp->max_count;
135 case pvr2_buffer_state_queued:
137 bcnt = &sp->q_bcount;
138 ccnt = bp->max_count;
140 case pvr2_buffer_state_ready:
142 bcnt = &sp->r_bcount;
143 ccnt = bp->used_count;
148 list_del_init(&bp->list_overhead);
151 pvr2_trace(PVR2_TRACE_BUF_FLOW,
152 "/*---TRACE_FLOW---*/"
153 " bufferPool %8s dec cap=%07d cnt=%02d",
154 pvr2_buffer_state_decode(bp->state),*bcnt,*cnt);
155 bp->state = pvr2_buffer_state_none;
158 static void pvr2_buffer_set_none(struct pvr2_buffer *bp)
160 unsigned long irq_flags;
161 struct pvr2_stream *sp;
164 pvr2_trace(PVR2_TRACE_BUF_FLOW,
165 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
167 pvr2_buffer_state_decode(bp->state),
168 pvr2_buffer_state_decode(pvr2_buffer_state_none));
169 spin_lock_irqsave(&sp->list_lock,irq_flags);
170 pvr2_buffer_remove(bp);
171 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
174 static int pvr2_buffer_set_ready(struct pvr2_buffer *bp)
177 unsigned long irq_flags;
178 struct pvr2_stream *sp;
181 pvr2_trace(PVR2_TRACE_BUF_FLOW,
182 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
184 pvr2_buffer_state_decode(bp->state),
185 pvr2_buffer_state_decode(pvr2_buffer_state_ready));
186 spin_lock_irqsave(&sp->list_lock,irq_flags);
187 fl = (sp->r_count == 0);
188 pvr2_buffer_remove(bp);
189 list_add_tail(&bp->list_overhead,&sp->ready_list);
190 bp->state = pvr2_buffer_state_ready;
192 sp->r_bcount += bp->used_count;
193 pvr2_trace(PVR2_TRACE_BUF_FLOW,
194 "/*---TRACE_FLOW---*/"
195 " bufferPool %8s inc cap=%07d cnt=%02d",
196 pvr2_buffer_state_decode(bp->state),
197 sp->r_bcount,sp->r_count);
198 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
202 static void pvr2_buffer_set_idle(struct pvr2_buffer *bp)
204 unsigned long irq_flags;
205 struct pvr2_stream *sp;
208 pvr2_trace(PVR2_TRACE_BUF_FLOW,
209 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
211 pvr2_buffer_state_decode(bp->state),
212 pvr2_buffer_state_decode(pvr2_buffer_state_idle));
213 spin_lock_irqsave(&sp->list_lock,irq_flags);
214 pvr2_buffer_remove(bp);
215 list_add_tail(&bp->list_overhead,&sp->idle_list);
216 bp->state = pvr2_buffer_state_idle;
218 sp->i_bcount += bp->max_count;
219 pvr2_trace(PVR2_TRACE_BUF_FLOW,
220 "/*---TRACE_FLOW---*/"
221 " bufferPool %8s inc cap=%07d cnt=%02d",
222 pvr2_buffer_state_decode(bp->state),
223 sp->i_bcount,sp->i_count);
224 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
227 static void pvr2_buffer_set_queued(struct pvr2_buffer *bp)
229 unsigned long irq_flags;
230 struct pvr2_stream *sp;
233 pvr2_trace(PVR2_TRACE_BUF_FLOW,
234 "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s",
236 pvr2_buffer_state_decode(bp->state),
237 pvr2_buffer_state_decode(pvr2_buffer_state_queued));
238 spin_lock_irqsave(&sp->list_lock,irq_flags);
239 pvr2_buffer_remove(bp);
240 list_add_tail(&bp->list_overhead,&sp->queued_list);
241 bp->state = pvr2_buffer_state_queued;
243 sp->q_bcount += bp->max_count;
244 pvr2_trace(PVR2_TRACE_BUF_FLOW,
245 "/*---TRACE_FLOW---*/"
246 " bufferPool %8s inc cap=%07d cnt=%02d",
247 pvr2_buffer_state_decode(bp->state),
248 sp->q_bcount,sp->q_count);
249 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
252 static void pvr2_buffer_wipe(struct pvr2_buffer *bp)
254 if (bp->state == pvr2_buffer_state_queued) {
255 usb_kill_urb(bp->purb);
259 static int pvr2_buffer_init(struct pvr2_buffer *bp,
260 struct pvr2_stream *sp,
263 memset(bp,0,sizeof(*bp));
264 bp->signature = BUFFER_SIG;
266 pvr2_trace(PVR2_TRACE_BUF_POOL,
267 "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp);
269 bp->state = pvr2_buffer_state_none;
270 INIT_LIST_HEAD(&bp->list_overhead);
271 bp->purb = usb_alloc_urb(0,GFP_KERNEL);
272 if (! bp->purb) return -ENOMEM;
273 #ifdef SANITY_CHECK_BUFFERS
274 pvr2_buffer_describe(bp,"create");
279 static void pvr2_buffer_done(struct pvr2_buffer *bp)
281 #ifdef SANITY_CHECK_BUFFERS
282 pvr2_buffer_describe(bp,"delete");
284 pvr2_buffer_wipe(bp);
285 pvr2_buffer_set_none(bp);
288 if (bp->purb) usb_free_urb(bp->purb);
289 pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/"
290 " bufferDone %p",bp);
293 static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
298 /* Allocate buffers pointer array in multiples of 32 entries */
299 if (cnt == sp->buffer_total_count) return 0;
301 pvr2_trace(PVR2_TRACE_BUF_POOL,
302 "/*---TRACE_FLOW---*/ poolResize "
303 " stream=%p cur=%d adj=%+d",
305 sp->buffer_total_count,
306 cnt-sp->buffer_total_count);
309 if (cnt > scnt) scnt += 0x20;
311 if (cnt > sp->buffer_total_count) {
312 if (scnt > sp->buffer_slot_count) {
313 struct pvr2_buffer **nb;
314 nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
315 if (!nb) return -ENOMEM;
316 if (sp->buffer_slot_count) {
317 memcpy(nb,sp->buffers,
318 sp->buffer_slot_count * sizeof(*nb));
322 sp->buffer_slot_count = scnt;
324 while (sp->buffer_total_count < cnt) {
325 struct pvr2_buffer *bp;
326 bp = kmalloc(sizeof(*bp),GFP_KERNEL);
327 if (!bp) return -ENOMEM;
328 ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count);
333 sp->buffers[sp->buffer_total_count] = bp;
334 (sp->buffer_total_count)++;
335 pvr2_buffer_set_idle(bp);
338 while (sp->buffer_total_count > cnt) {
339 struct pvr2_buffer *bp;
340 bp = sp->buffers[sp->buffer_total_count - 1];
342 sp->buffers[sp->buffer_total_count - 1] = 0;
343 (sp->buffer_total_count)--;
344 pvr2_buffer_done(bp);
347 if (scnt < sp->buffer_slot_count) {
348 struct pvr2_buffer **nb = 0;
350 nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL);
351 if (!nb) return -ENOMEM;
352 memcpy(nb,sp->buffers,scnt * sizeof(*nb));
356 sp->buffer_slot_count = scnt;
362 static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp)
364 struct pvr2_buffer *bp;
367 if (sp->buffer_total_count == sp->buffer_target_count) return 0;
369 pvr2_trace(PVR2_TRACE_BUF_POOL,
370 "/*---TRACE_FLOW---*/"
371 " 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, struct pt_regs *regs)
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 bp->used_count = urb->actual_length;
446 if (sp->fail_count) {
447 pvr2_trace(PVR2_TRACE_TOLERANCE,
448 "stream %p transfer ok"
449 " - fail count reset",sp);
452 } else if (sp->fail_count < sp->fail_tolerance) {
453 // We can tolerate this error, because we're below the
456 pvr2_trace(PVR2_TRACE_TOLERANCE,
457 "stream %p ignoring error %d"
458 " - fail count increased to %u",
459 sp,urb->status,sp->fail_count);
461 bp->status = urb->status;
463 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
464 pvr2_buffer_set_ready(bp);
465 if (sp && sp->callback_func) {
466 sp->callback_func(sp->callback_data);
470 struct pvr2_stream *pvr2_stream_create(void)
472 struct pvr2_stream *sp;
473 sp = kmalloc(sizeof(*sp),GFP_KERNEL);
475 memset(sp,0,sizeof(*sp));
476 pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp);
477 pvr2_stream_init(sp);
481 void pvr2_stream_destroy(struct pvr2_stream *sp)
484 pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp);
485 pvr2_stream_done(sp);
489 void pvr2_stream_setup(struct pvr2_stream *sp,
490 struct usb_device *dev,
492 unsigned int tolerance)
494 mutex_lock(&sp->mutex); do {
495 pvr2_stream_internal_flush(sp);
497 sp->endpoint = endpoint;
498 sp->fail_tolerance = tolerance;
499 } while(0); mutex_unlock(&sp->mutex);
502 void pvr2_stream_set_callback(struct pvr2_stream *sp,
503 pvr2_stream_callback func,
506 unsigned long irq_flags;
507 mutex_lock(&sp->mutex); do {
508 spin_lock_irqsave(&sp->list_lock,irq_flags);
509 sp->callback_data = data;
510 sp->callback_func = func;
511 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
512 } while(0); mutex_unlock(&sp->mutex);
515 /* Query / set the nominal buffer count */
516 int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
518 return sp->buffer_target_count;
521 int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt)
524 if (sp->buffer_target_count == cnt) return 0;
525 mutex_lock(&sp->mutex); do {
526 sp->buffer_target_count = cnt;
527 ret = pvr2_stream_achieve_buffer_count(sp);
528 } while(0); mutex_unlock(&sp->mutex);
532 struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp)
534 struct list_head *lp = sp->idle_list.next;
535 if (lp == &sp->idle_list) return 0;
536 return list_entry(lp,struct pvr2_buffer,list_overhead);
539 struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp)
541 struct list_head *lp = sp->ready_list.next;
542 if (lp == &sp->ready_list) return 0;
543 return list_entry(lp,struct pvr2_buffer,list_overhead);
546 struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id)
548 if (id < 0) return 0;
549 if (id >= sp->buffer_total_count) return 0;
550 return sp->buffers[id];
553 int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
558 int pvr2_stream_get_idle_count(struct pvr2_stream *sp)
563 void pvr2_stream_flush(struct pvr2_stream *sp)
565 mutex_lock(&sp->mutex); do {
566 pvr2_stream_internal_flush(sp);
567 } while(0); mutex_unlock(&sp->mutex);
570 void pvr2_stream_kill(struct pvr2_stream *sp)
572 struct pvr2_buffer *bp;
573 mutex_lock(&sp->mutex); do {
574 pvr2_stream_internal_flush(sp);
575 while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) {
576 pvr2_buffer_set_idle(bp);
578 if (sp->buffer_total_count != sp->buffer_target_count) {
579 pvr2_stream_achieve_buffer_count(sp);
581 } while(0); mutex_unlock(&sp->mutex);
584 int pvr2_buffer_queue(struct pvr2_buffer *bp)
592 struct pvr2_stream *sp;
593 if (!bp) return -EINVAL;
595 mutex_lock(&sp->mutex); do {
596 pvr2_buffer_wipe(bp);
601 pvr2_buffer_set_queued(bp);
603 for (idx = 0; idx < (bp->max_count) / 4; idx++) {
606 ((unsigned int *)(bp->ptr))[idx] = val;
609 bp->status = -EINPROGRESS;
610 usb_fill_bulk_urb(bp->purb, // struct urb *urb
611 sp->dev, // struct usb_device *dev
613 usb_rcvbulkpipe(sp->dev,sp->endpoint),
614 bp->ptr, // void *transfer_buffer
615 bp->max_count, // int buffer_length
618 usb_submit_urb(bp->purb,GFP_KERNEL);
619 } while(0); mutex_unlock(&sp->mutex);
623 int pvr2_buffer_idle(struct pvr2_buffer *bp)
625 struct pvr2_stream *sp;
626 if (!bp) return -EINVAL;
628 mutex_lock(&sp->mutex); do {
629 pvr2_buffer_wipe(bp);
630 pvr2_buffer_set_idle(bp);
631 if (sp->buffer_total_count != sp->buffer_target_count) {
632 pvr2_stream_achieve_buffer_count(sp);
634 } while(0); mutex_unlock(&sp->mutex);
638 int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt)
641 unsigned long irq_flags;
642 struct pvr2_stream *sp;
643 if (!bp) return -EINVAL;
645 mutex_lock(&sp->mutex); do {
646 spin_lock_irqsave(&sp->list_lock,irq_flags);
647 if (bp->state != pvr2_buffer_state_idle) {
651 bp->stream->i_bcount -= bp->max_count;
653 bp->stream->i_bcount += bp->max_count;
654 pvr2_trace(PVR2_TRACE_BUF_FLOW,
655 "/*---TRACE_FLOW---*/ bufferPool "
656 " %8s cap cap=%07d cnt=%02d",
657 pvr2_buffer_state_decode(
658 pvr2_buffer_state_idle),
659 bp->stream->i_bcount,bp->stream->i_count);
661 spin_unlock_irqrestore(&sp->list_lock,irq_flags);
662 } while(0); mutex_unlock(&sp->mutex);
666 unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
668 return bp->used_count;
671 int pvr2_buffer_get_status(struct pvr2_buffer *bp)
676 enum pvr2_buffer_state pvr2_buffer_get_state(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 ***