linux/sound/usb/usx2y/usb_stream.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Copyright (C) 2007, 2008 Karsten Wiese <fzu@wemgehoertderstaat.de>
   4 */
   5
   6#include <linux/usb.h>
   7#include <linux/gfp.h>
   8
   9#include "usb_stream.h"
  10
  11
  12/*                             setup                                  */
  13
  14static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk)
  15{
  16        struct usb_stream *s = sk->s;
  17        sk->out_phase_peeked = (sk->out_phase & 0xffff) + sk->freqn;
  18        return (sk->out_phase_peeked >> 16) * s->cfg.frame_size;
  19}
  20
  21static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb)
  22{
  23        struct usb_stream *s = sk->s;
  24        int pack, lb = 0;
  25
  26        for (pack = 0; pack < sk->n_o_ps; pack++) {
  27                int l = usb_stream_next_packet_size(sk);
  28                if (s->idle_outsize + lb + l > s->period_size)
  29                        goto check;
  30
  31                sk->out_phase = sk->out_phase_peeked;
  32                urb->iso_frame_desc[pack].offset = lb;
  33                urb->iso_frame_desc[pack].length = l;
  34                lb += l;
  35        }
  36        snd_printdd(KERN_DEBUG "%i\n", lb);
  37
  38check:
  39        urb->number_of_packets = pack;
  40        urb->transfer_buffer_length = lb;
  41        s->idle_outsize += lb - s->period_size;
  42        snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize,
  43                    lb, s->period_size);
  44}
  45
  46static int init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
  47                           struct urb **urbs, char *transfer,
  48                           struct usb_device *dev, int pipe)
  49{
  50        int u, p;
  51        int maxpacket = use_packsize ?
  52                use_packsize : usb_maxpacket(dev, pipe, usb_pipeout(pipe));
  53        int transfer_length = maxpacket * sk->n_o_ps;
  54
  55        for (u = 0; u < USB_STREAM_NURBS;
  56             ++u, transfer += transfer_length) {
  57                struct urb *urb = urbs[u];
  58                struct usb_iso_packet_descriptor *desc;
  59                urb->transfer_buffer = transfer;
  60                urb->dev = dev;
  61                urb->pipe = pipe;
  62                urb->number_of_packets = sk->n_o_ps;
  63                urb->context = sk;
  64                urb->interval = 1;
  65                if (usb_pipeout(pipe))
  66                        continue;
  67                if (usb_urb_ep_type_check(urb))
  68                        return -EINVAL;
  69
  70                urb->transfer_buffer_length = transfer_length;
  71                desc = urb->iso_frame_desc;
  72                desc->offset = 0;
  73                desc->length = maxpacket;
  74                for (p = 1; p < sk->n_o_ps; ++p) {
  75                        desc[p].offset = desc[p - 1].offset + maxpacket;
  76                        desc[p].length = maxpacket;
  77                }
  78        }
  79
  80        return 0;
  81}
  82
  83static int init_urbs(struct usb_stream_kernel *sk, unsigned use_packsize,
  84                      struct usb_device *dev, int in_pipe, int out_pipe)
  85{
  86        struct usb_stream       *s = sk->s;
  87        char                    *indata = (char *)s + sizeof(*s) +
  88                                        sizeof(struct usb_stream_packet) *
  89                                        s->inpackets;
  90        int                     u;
  91
  92        for (u = 0; u < USB_STREAM_NURBS; ++u) {
  93                sk->inurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
  94                if (!sk->inurb[u])
  95                        return -ENOMEM;
  96
  97                sk->outurb[u] = usb_alloc_urb(sk->n_o_ps, GFP_KERNEL);
  98                if (!sk->outurb[u])
  99                        return -ENOMEM;
 100        }
 101
 102        if (init_pipe_urbs(sk, use_packsize, sk->inurb, indata, dev, in_pipe) ||
 103            init_pipe_urbs(sk, use_packsize, sk->outurb, sk->write_page, dev,
 104                           out_pipe))
 105                return -EINVAL;
 106
 107        return 0;
 108}
 109
 110
 111/*
 112 * convert a sampling rate into our full speed format (fs/1000 in Q16.16)
 113 * this will overflow at approx 524 kHz
 114 */
 115static inline unsigned get_usb_full_speed_rate(unsigned rate)
 116{
 117        return ((rate << 13) + 62) / 125;
 118}
 119
 120/*
 121 * convert a sampling rate into USB high speed format (fs/8000 in Q16.16)
 122 * this will overflow at approx 4 MHz
 123 */
 124static inline unsigned get_usb_high_speed_rate(unsigned rate)
 125{
 126        return ((rate << 10) + 62) / 125;
 127}
 128
 129void usb_stream_free(struct usb_stream_kernel *sk)
 130{
 131        struct usb_stream *s;
 132        unsigned u;
 133
 134        for (u = 0; u < USB_STREAM_NURBS; ++u) {
 135                usb_free_urb(sk->inurb[u]);
 136                sk->inurb[u] = NULL;
 137                usb_free_urb(sk->outurb[u]);
 138                sk->outurb[u] = NULL;
 139        }
 140
 141        s = sk->s;
 142        if (!s)
 143                return;
 144
 145        free_pages_exact(sk->write_page, s->write_size);
 146        sk->write_page = NULL;
 147        free_pages_exact(s, s->read_size);
 148        sk->s = NULL;
 149}
 150
 151struct usb_stream *usb_stream_new(struct usb_stream_kernel *sk,
 152                                  struct usb_device *dev,
 153                                  unsigned in_endpoint, unsigned out_endpoint,
 154                                  unsigned sample_rate, unsigned use_packsize,
 155                                  unsigned period_frames, unsigned frame_size)
 156{
 157        int packets, max_packsize;
 158        int in_pipe, out_pipe;
 159        int read_size = sizeof(struct usb_stream);
 160        int write_size;
 161        int usb_frames = dev->speed == USB_SPEED_HIGH ? 8000 : 1000;
 162
 163        in_pipe = usb_rcvisocpipe(dev, in_endpoint);
 164        out_pipe = usb_sndisocpipe(dev, out_endpoint);
 165
 166        max_packsize = use_packsize ?
 167                use_packsize : usb_maxpacket(dev, in_pipe, 0);
 168
 169        /*
 170                t_period = period_frames / sample_rate
 171                iso_packs = t_period / t_iso_frame
 172                        = (period_frames / sample_rate) * (1 / t_iso_frame)
 173        */
 174
 175        packets = period_frames * usb_frames / sample_rate + 1;
 176
 177        if (dev->speed == USB_SPEED_HIGH)
 178                packets = (packets + 7) & ~7;
 179
 180        read_size += packets * USB_STREAM_URBDEPTH *
 181                (max_packsize + sizeof(struct usb_stream_packet));
 182
 183        max_packsize = usb_maxpacket(dev, out_pipe, 1);
 184        write_size = max_packsize * packets * USB_STREAM_URBDEPTH;
 185
 186        if (read_size >= 256*PAGE_SIZE || write_size >= 256*PAGE_SIZE) {
 187                snd_printk(KERN_WARNING "a size exceeds 128*PAGE_SIZE\n");
 188                goto out;
 189        }
 190
 191        sk->s = alloc_pages_exact(read_size,
 192                                  GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
 193        if (!sk->s) {
 194                pr_warn("us122l: couldn't allocate read buffer\n");
 195                goto out;
 196        }
 197        sk->s->cfg.version = USB_STREAM_INTERFACE_VERSION;
 198
 199        sk->s->read_size = read_size;
 200
 201        sk->s->cfg.sample_rate = sample_rate;
 202        sk->s->cfg.frame_size = frame_size;
 203        sk->n_o_ps = packets;
 204        sk->s->inpackets = packets * USB_STREAM_URBDEPTH;
 205        sk->s->cfg.period_frames = period_frames;
 206        sk->s->period_size = frame_size * period_frames;
 207
 208        sk->s->write_size = write_size;
 209
 210        sk->write_page = alloc_pages_exact(write_size,
 211                                           GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
 212        if (!sk->write_page) {
 213                pr_warn("us122l: couldn't allocate write buffer\n");
 214                usb_stream_free(sk);
 215                return NULL;
 216        }
 217
 218        /* calculate the frequency in 16.16 format */
 219        if (dev->speed == USB_SPEED_FULL)
 220                sk->freqn = get_usb_full_speed_rate(sample_rate);
 221        else
 222                sk->freqn = get_usb_high_speed_rate(sample_rate);
 223
 224        if (init_urbs(sk, use_packsize, dev, in_pipe, out_pipe) < 0) {
 225                usb_stream_free(sk);
 226                return NULL;
 227        }
 228
 229        sk->s->state = usb_stream_stopped;
 230out:
 231        return sk->s;
 232}
 233
 234
 235/*                             start                                  */
 236
 237static bool balance_check(struct usb_stream_kernel *sk, struct urb *urb)
 238{
 239        bool r;
 240        if (unlikely(urb->status)) {
 241                if (urb->status != -ESHUTDOWN && urb->status != -ENOENT)
 242                        snd_printk(KERN_WARNING "status=%i\n", urb->status);
 243                sk->iso_frame_balance = 0x7FFFFFFF;
 244                return false;
 245        }
 246        r = sk->iso_frame_balance == 0;
 247        if (!r)
 248                sk->i_urb = urb;
 249        return r;
 250}
 251
 252static bool balance_playback(struct usb_stream_kernel *sk, struct urb *urb)
 253{
 254        sk->iso_frame_balance += urb->number_of_packets;
 255        return balance_check(sk, urb);
 256}
 257
 258static bool balance_capture(struct usb_stream_kernel *sk, struct urb *urb)
 259{
 260        sk->iso_frame_balance -= urb->number_of_packets;
 261        return balance_check(sk, urb);
 262}
 263
 264static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
 265{
 266        int u;
 267
 268        for (u = 0; u < USB_STREAM_NURBS; u++) {
 269                struct urb *urb = urbs[u];
 270                urb->complete = complete;
 271        }
 272}
 273
 274static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
 275                struct urb *inurb)
 276{
 277        struct usb_stream *s = sk->s;
 278        struct urb *io;
 279        struct usb_iso_packet_descriptor *id, *od;
 280        int p = 0, lb = 0, l = 0;
 281
 282        io = sk->idle_outurb;
 283        od = io->iso_frame_desc;
 284
 285        for (; s->sync_packet < 0; ++p, ++s->sync_packet) {
 286                struct urb *ii = sk->completed_inurb;
 287                id = ii->iso_frame_desc +
 288                        ii->number_of_packets + s->sync_packet;
 289                l = id->actual_length;
 290
 291                od[p].length = l;
 292                od[p].offset = lb;
 293                lb += l;
 294        }
 295
 296        for (;
 297             s->sync_packet < inurb->number_of_packets && p < sk->n_o_ps;
 298             ++p, ++s->sync_packet) {
 299                l = inurb->iso_frame_desc[s->sync_packet].actual_length;
 300
 301                if (s->idle_outsize + lb + l > s->period_size)
 302                        goto check_ok;
 303
 304                od[p].length = l;
 305                od[p].offset = lb;
 306                lb += l;
 307        }
 308
 309check_ok:
 310        s->sync_packet -= inurb->number_of_packets;
 311        if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) {
 312                snd_printk(KERN_WARNING "invalid sync_packet = %i;"
 313                           " p=%i nop=%i %i %x %x %x > %x\n",
 314                           s->sync_packet, p, inurb->number_of_packets,
 315                           s->idle_outsize + lb + l,
 316                           s->idle_outsize, lb,  l,
 317                           s->period_size);
 318                return -1;
 319        }
 320        if (unlikely(lb % s->cfg.frame_size)) {
 321                snd_printk(KERN_WARNING"invalid outsize = %i\n",
 322                           lb);
 323                return -1;
 324        }
 325        s->idle_outsize += lb - s->period_size;
 326        io->number_of_packets = p;
 327        io->transfer_buffer_length = lb;
 328        if (s->idle_outsize <= 0)
 329                return 0;
 330
 331        snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize);
 332        return -1;
 333}
 334
 335static void prepare_inurb(int number_of_packets, struct urb *iu)
 336{
 337        struct usb_iso_packet_descriptor *id;
 338        int p;
 339
 340        iu->number_of_packets = number_of_packets;
 341        id = iu->iso_frame_desc;
 342        id->offset = 0;
 343        for (p = 0; p < iu->number_of_packets - 1; ++p)
 344                id[p + 1].offset = id[p].offset + id[p].length;
 345
 346        iu->transfer_buffer_length =
 347                id[0].length * iu->number_of_packets;
 348}
 349
 350static int submit_urbs(struct usb_stream_kernel *sk,
 351                       struct urb *inurb, struct urb *outurb)
 352{
 353        int err;
 354        prepare_inurb(sk->idle_outurb->number_of_packets, sk->idle_inurb);
 355        err = usb_submit_urb(sk->idle_inurb, GFP_ATOMIC);
 356        if (err < 0)
 357                goto report_failure;
 358
 359        sk->idle_inurb = sk->completed_inurb;
 360        sk->completed_inurb = inurb;
 361        err = usb_submit_urb(sk->idle_outurb, GFP_ATOMIC);
 362        if (err < 0)
 363                goto report_failure;
 364
 365        sk->idle_outurb = sk->completed_outurb;
 366        sk->completed_outurb = outurb;
 367        return 0;
 368
 369report_failure:
 370        snd_printk(KERN_ERR "%i\n", err);
 371        return err;
 372}
 373
 374#ifdef DEBUG_LOOP_BACK
 375/*
 376  This loop_back() shows how to read/write the period data.
 377 */
 378static void loop_back(struct usb_stream *s)
 379{
 380        char *i, *o;
 381        int il, ol, l, p;
 382        struct urb *iu;
 383        struct usb_iso_packet_descriptor *id;
 384
 385        o = s->playback1st_to;
 386        ol = s->playback1st_size;
 387        l = 0;
 388
 389        if (s->insplit_pack >= 0) {
 390                iu = sk->idle_inurb;
 391                id = iu->iso_frame_desc;
 392                p = s->insplit_pack;
 393        } else
 394                goto second;
 395loop:
 396        for (; p < iu->number_of_packets && l < s->period_size; ++p) {
 397                i = iu->transfer_buffer + id[p].offset;
 398                il = id[p].actual_length;
 399                if (l + il > s->period_size)
 400                        il = s->period_size - l;
 401                if (il <= ol) {
 402                        memcpy(o, i, il);
 403                        o += il;
 404                        ol -= il;
 405                } else {
 406                        memcpy(o, i, ol);
 407                        singen_6pack(o, ol);
 408                        o = s->playback_to;
 409                        memcpy(o, i + ol, il - ol);
 410                        o += il - ol;
 411                        ol = s->period_size - s->playback1st_size;
 412                }
 413                l += il;
 414        }
 415        if (iu == sk->completed_inurb) {
 416                if (l != s->period_size)
 417                        printk(KERN_DEBUG"%s:%i %i\n", __func__, __LINE__,
 418                               l/(int)s->cfg.frame_size);
 419
 420                return;
 421        }
 422second:
 423        iu = sk->completed_inurb;
 424        id = iu->iso_frame_desc;
 425        p = 0;
 426        goto loop;
 427
 428}
 429#else
 430static void loop_back(struct usb_stream *s)
 431{
 432}
 433#endif
 434
 435static void stream_idle(struct usb_stream_kernel *sk,
 436                        struct urb *inurb, struct urb *outurb)
 437{
 438        struct usb_stream *s = sk->s;
 439        int l, p;
 440        int insize = s->idle_insize;
 441        int urb_size = 0;
 442
 443        s->inpacket_split = s->next_inpacket_split;
 444        s->inpacket_split_at = s->next_inpacket_split_at;
 445        s->next_inpacket_split = -1;
 446        s->next_inpacket_split_at = 0;
 447
 448        for (p = 0; p < inurb->number_of_packets; ++p) {
 449                struct usb_iso_packet_descriptor *id = inurb->iso_frame_desc;
 450                l = id[p].actual_length;
 451                if (unlikely(l == 0 || id[p].status)) {
 452                        snd_printk(KERN_WARNING "underrun, status=%u\n",
 453                                   id[p].status);
 454                        goto err_out;
 455                }
 456                s->inpacket_head++;
 457                s->inpacket_head %= s->inpackets;
 458                if (s->inpacket_split == -1)
 459                        s->inpacket_split = s->inpacket_head;
 460
 461                s->inpacket[s->inpacket_head].offset =
 462                        id[p].offset + (inurb->transfer_buffer - (void *)s);
 463                s->inpacket[s->inpacket_head].length = l;
 464                if (insize + l > s->period_size &&
 465                    s->next_inpacket_split == -1) {
 466                        s->next_inpacket_split = s->inpacket_head;
 467                        s->next_inpacket_split_at = s->period_size - insize;
 468                }
 469                insize += l;
 470                urb_size += l;
 471        }
 472        s->idle_insize += urb_size - s->period_size;
 473        if (s->idle_insize < 0) {
 474                snd_printk(KERN_WARNING "%i\n",
 475                           (s->idle_insize)/(int)s->cfg.frame_size);
 476                goto err_out;
 477        }
 478        s->insize_done += urb_size;
 479
 480        l = s->idle_outsize;
 481        s->outpacket[0].offset = (sk->idle_outurb->transfer_buffer -
 482                                  sk->write_page) - l;
 483
 484        if (usb_stream_prepare_playback(sk, inurb) < 0)
 485                goto err_out;
 486
 487        s->outpacket[0].length = sk->idle_outurb->transfer_buffer_length + l;
 488        s->outpacket[1].offset = sk->completed_outurb->transfer_buffer -
 489                sk->write_page;
 490
 491        if (submit_urbs(sk, inurb, outurb) < 0)
 492                goto err_out;
 493
 494        loop_back(s);
 495        s->periods_done++;
 496        wake_up_all(&sk->sleep);
 497        return;
 498err_out:
 499        s->state = usb_stream_xrun;
 500        wake_up_all(&sk->sleep);
 501}
 502
 503static void i_capture_idle(struct urb *urb)
 504{
 505        struct usb_stream_kernel *sk = urb->context;
 506        if (balance_capture(sk, urb))
 507                stream_idle(sk, urb, sk->i_urb);
 508}
 509
 510static void i_playback_idle(struct urb *urb)
 511{
 512        struct usb_stream_kernel *sk = urb->context;
 513        if (balance_playback(sk, urb))
 514                stream_idle(sk, sk->i_urb, urb);
 515}
 516
 517static void stream_start(struct usb_stream_kernel *sk,
 518                         struct urb *inurb, struct urb *outurb)
 519{
 520        struct usb_stream *s = sk->s;
 521        if (s->state >= usb_stream_sync1) {
 522                int l, p, max_diff, max_diff_0;
 523                int urb_size = 0;
 524                unsigned frames_per_packet, min_frames = 0;
 525                frames_per_packet = (s->period_size - s->idle_insize);
 526                frames_per_packet <<= 8;
 527                frames_per_packet /=
 528                        s->cfg.frame_size * inurb->number_of_packets;
 529                frames_per_packet++;
 530
 531                max_diff_0 = s->cfg.frame_size;
 532                if (s->cfg.period_frames >= 256)
 533                        max_diff_0 <<= 1;
 534                if (s->cfg.period_frames >= 1024)
 535                        max_diff_0 <<= 1;
 536                max_diff = max_diff_0;
 537                for (p = 0; p < inurb->number_of_packets; ++p) {
 538                        int diff;
 539                        l = inurb->iso_frame_desc[p].actual_length;
 540                        urb_size += l;
 541
 542                        min_frames += frames_per_packet;
 543                        diff = urb_size -
 544                                (min_frames >> 8) * s->cfg.frame_size;
 545                        if (diff < max_diff) {
 546                                snd_printdd(KERN_DEBUG "%i %i %i %i\n",
 547                                            s->insize_done,
 548                                            urb_size / (int)s->cfg.frame_size,
 549                                            inurb->number_of_packets, diff);
 550                                max_diff = diff;
 551                        }
 552                }
 553                s->idle_insize -= max_diff - max_diff_0;
 554                s->idle_insize += urb_size - s->period_size;
 555                if (s->idle_insize < 0) {
 556                        snd_printk(KERN_WARNING "%i %i %i\n",
 557                                   s->idle_insize, urb_size, s->period_size);
 558                        return;
 559                } else if (s->idle_insize == 0) {
 560                        s->next_inpacket_split =
 561                                (s->inpacket_head + 1) % s->inpackets;
 562                        s->next_inpacket_split_at = 0;
 563                } else {
 564                        unsigned split = s->inpacket_head;
 565                        l = s->idle_insize;
 566                        while (l > s->inpacket[split].length) {
 567                                l -= s->inpacket[split].length;
 568                                if (split == 0)
 569                                        split = s->inpackets - 1;
 570                                else
 571                                        split--;
 572                        }
 573                        s->next_inpacket_split = split;
 574                        s->next_inpacket_split_at =
 575                                s->inpacket[split].length - l;
 576                }
 577
 578                s->insize_done += urb_size;
 579
 580                if (usb_stream_prepare_playback(sk, inurb) < 0)
 581                        return;
 582
 583        } else
 584                playback_prep_freqn(sk, sk->idle_outurb);
 585
 586        if (submit_urbs(sk, inurb, outurb) < 0)
 587                return;
 588
 589        if (s->state == usb_stream_sync1 && s->insize_done > 360000) {
 590                /* just guesswork                            ^^^^^^ */
 591                s->state = usb_stream_ready;
 592                subs_set_complete(sk->inurb, i_capture_idle);
 593                subs_set_complete(sk->outurb, i_playback_idle);
 594        }
 595}
 596
 597static void i_capture_start(struct urb *urb)
 598{
 599        struct usb_iso_packet_descriptor *id = urb->iso_frame_desc;
 600        struct usb_stream_kernel *sk = urb->context;
 601        struct usb_stream *s = sk->s;
 602        int p;
 603        int empty = 0;
 604
 605        if (urb->status) {
 606                snd_printk(KERN_WARNING "status=%i\n", urb->status);
 607                return;
 608        }
 609
 610        for (p = 0; p < urb->number_of_packets; ++p) {
 611                int l = id[p].actual_length;
 612                if (l < s->cfg.frame_size) {
 613                        ++empty;
 614                        if (s->state >= usb_stream_sync0) {
 615                                snd_printk(KERN_WARNING "%i\n", l);
 616                                return;
 617                        }
 618                }
 619                s->inpacket_head++;
 620                s->inpacket_head %= s->inpackets;
 621                s->inpacket[s->inpacket_head].offset =
 622                        id[p].offset + (urb->transfer_buffer - (void *)s);
 623                s->inpacket[s->inpacket_head].length = l;
 624        }
 625#ifdef SHOW_EMPTY
 626        if (empty) {
 627                printk(KERN_DEBUG"%s:%i: %i", __func__, __LINE__,
 628                       urb->iso_frame_desc[0].actual_length);
 629                for (pack = 1; pack < urb->number_of_packets; ++pack) {
 630                        int l = urb->iso_frame_desc[pack].actual_length;
 631                        printk(KERN_CONT " %i", l);
 632                }
 633                printk(KERN_CONT "\n");
 634        }
 635#endif
 636        if (!empty && s->state < usb_stream_sync1)
 637                ++s->state;
 638
 639        if (balance_capture(sk, urb))
 640                stream_start(sk, urb, sk->i_urb);
 641}
 642
 643static void i_playback_start(struct urb *urb)
 644{
 645        struct usb_stream_kernel *sk = urb->context;
 646        if (balance_playback(sk, urb))
 647                stream_start(sk, sk->i_urb, urb);
 648}
 649
 650int usb_stream_start(struct usb_stream_kernel *sk)
 651{
 652        struct usb_stream *s = sk->s;
 653        int frame = 0, iters = 0;
 654        int u, err;
 655        int try = 0;
 656
 657        if (s->state != usb_stream_stopped)
 658                return -EAGAIN;
 659
 660        subs_set_complete(sk->inurb, i_capture_start);
 661        subs_set_complete(sk->outurb, i_playback_start);
 662        memset(sk->write_page, 0, s->write_size);
 663dotry:
 664        s->insize_done = 0;
 665        s->idle_insize = 0;
 666        s->idle_outsize = 0;
 667        s->sync_packet = -1;
 668        s->inpacket_head = -1;
 669        sk->iso_frame_balance = 0;
 670        ++try;
 671        for (u = 0; u < 2; u++) {
 672                struct urb *inurb = sk->inurb[u];
 673                struct urb *outurb = sk->outurb[u];
 674                playback_prep_freqn(sk, outurb);
 675                inurb->number_of_packets = outurb->number_of_packets;
 676                inurb->transfer_buffer_length =
 677                        inurb->number_of_packets *
 678                        inurb->iso_frame_desc[0].length;
 679
 680                if (u == 0) {
 681                        int now;
 682                        struct usb_device *dev = inurb->dev;
 683                        frame = usb_get_current_frame_number(dev);
 684                        do {
 685                                now = usb_get_current_frame_number(dev);
 686                                ++iters;
 687                        } while (now > -1 && now == frame);
 688                }
 689                err = usb_submit_urb(inurb, GFP_ATOMIC);
 690                if (err < 0) {
 691                        snd_printk(KERN_ERR"usb_submit_urb(sk->inurb[%i])"
 692                                   " returned %i\n", u, err);
 693                        return err;
 694                }
 695                err = usb_submit_urb(outurb, GFP_ATOMIC);
 696                if (err < 0) {
 697                        snd_printk(KERN_ERR"usb_submit_urb(sk->outurb[%i])"
 698                                   " returned %i\n", u, err);
 699                        return err;
 700                }
 701
 702                if (inurb->start_frame != outurb->start_frame) {
 703                        snd_printd(KERN_DEBUG
 704                                   "u[%i] start_frames differ in:%u out:%u\n",
 705                                   u, inurb->start_frame, outurb->start_frame);
 706                        goto check_retry;
 707                }
 708        }
 709        snd_printdd(KERN_DEBUG "%i %i\n", frame, iters);
 710        try = 0;
 711check_retry:
 712        if (try) {
 713                usb_stream_stop(sk);
 714                if (try < 5) {
 715                        msleep(1500);
 716                        snd_printd(KERN_DEBUG "goto dotry;\n");
 717                        goto dotry;
 718                }
 719                snd_printk(KERN_WARNING"couldn't start"
 720                           " all urbs on the same start_frame.\n");
 721                return -EFAULT;
 722        }
 723
 724        sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
 725        sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
 726        sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
 727        sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
 728
 729/* wait, check */
 730        {
 731                int wait_ms = 3000;
 732                while (s->state != usb_stream_ready && wait_ms > 0) {
 733                        snd_printdd(KERN_DEBUG "%i\n", s->state);
 734                        msleep(200);
 735                        wait_ms -= 200;
 736                }
 737        }
 738
 739        return s->state == usb_stream_ready ? 0 : -EFAULT;
 740}
 741
 742
 743/*                             stop                                   */
 744
 745void usb_stream_stop(struct usb_stream_kernel *sk)
 746{
 747        int u;
 748        if (!sk->s)
 749                return;
 750        for (u = 0; u < USB_STREAM_NURBS; ++u) {
 751                usb_kill_urb(sk->inurb[u]);
 752                usb_kill_urb(sk->outurb[u]);
 753        }
 754        sk->s->state = usb_stream_stopped;
 755        msleep(400);
 756}
 757