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