linux/drivers/media/usb/pvrusb2/pvrusb2-io.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   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
  14static const char *pvr2_buffer_state_decode(enum pvr2_buffer_state);
  15
  16#define BUFFER_SIG 0x47653271
  17
  18// #define SANITY_CHECK_BUFFERS
  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
  35struct pvr2_stream {
  36        /* Buffers queued for reading */
  37        struct list_head queued_list;
  38        unsigned int q_count;
  39        unsigned int q_bcount;
  40        /* Buffers with retrieved data */
  41        struct list_head ready_list;
  42        unsigned int r_count;
  43        unsigned int r_bcount;
  44        /* Buffers available for use */
  45        struct list_head idle_list;
  46        unsigned int i_count;
  47        unsigned int i_bcount;
  48        /* Pointers to all buffers */
  49        struct pvr2_buffer **buffers;
  50        /* Array size of buffers */
  51        unsigned int buffer_slot_count;
  52        /* Total buffers actually in circulation */
  53        unsigned int buffer_total_count;
  54        /* Designed number of buffers to be in circulation */
  55        unsigned int buffer_target_count;
  56        /* Executed when ready list become non-empty */
  57        pvr2_stream_callback callback_func;
  58        void *callback_data;
  59        /* Context for transfer endpoint */
  60        struct usb_device *dev;
  61        int endpoint;
  62        /* Overhead for mutex enforcement */
  63        spinlock_t list_lock;
  64        struct mutex mutex;
  65        /* Tracking state for tolerating errors */
  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
  74struct pvr2_buffer {
  75        int id;
  76        int signature;
  77        enum pvr2_buffer_state state;
  78        void *ptr;               /* Pointer to storage area */
  79        unsigned int max_count;  /* Size of storage area */
  80        unsigned int used_count; /* Amount of valid data in storage area */
  81        int status;              /* Transfer result status */
  82        struct pvr2_stream *stream;
  83        struct list_head list_overhead;
  84        struct urb *purb;
  85};
  86
  87static 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
  99static 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  /*  SANITY_CHECK_BUFFERS  */
 114
 115static 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
 149static 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
 165static 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
 192static 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
 216static 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
 240static 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
 247static 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
 267static 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
 281static int pvr2_stream_buffer_count(struct pvr2_stream *sp, unsigned int cnt)
 282{
 283        int ret;
 284        unsigned int scnt;
 285
 286        /* Allocate buffers pointer array in multiples of 32 entries */
 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                        /* Paranoia */
 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
 350static 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
 378static 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                /* At this point, we should be guaranteed that no
 386                   completion callback may happen on this buffer.  But it's
 387                   possible that it might have completed after we noticed
 388                   it but before we wiped it.  So double check its status
 389                   here first. */
 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
 398static 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
 407static 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
 415static 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                // We can tolerate this error, because we're below the
 443                // threshold...
 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
 460struct 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
 470void 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
 478void 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
 491void 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
 506void 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/* Query / set the nominal buffer count */
 529int pvr2_stream_get_buffer_count(struct pvr2_stream *sp)
 530{
 531        return sp->buffer_target_count;
 532}
 533
 534int 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
 547struct 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
 554struct 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
 561struct 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
 568int pvr2_stream_get_ready_count(struct pvr2_stream *sp)
 569{
 570        return sp->r_count;
 571}
 572
 573void 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
 589int 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,      // struct urb *urb
 617                                  sp->dev,       // struct usb_device *dev
 618                                  // endpoint (below)
 619                                  usb_rcvbulkpipe(sp->dev, sp->endpoint),
 620                                  bp->ptr,       // void *transfer_buffer
 621                                  bp->max_count, // int buffer_length
 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
 630int 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
 659unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp)
 660{
 661        return bp->used_count;
 662}
 663
 664int pvr2_buffer_get_status(struct pvr2_buffer *bp)
 665{
 666        return bp->status;
 667}
 668
 669int pvr2_buffer_get_id(struct pvr2_buffer *bp)
 670{
 671        return bp->id;
 672}
 673