root/sound/usb/usx2y/usb_stream.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. usb_stream_next_packet_size
  2. playback_prep_freqn
  3. init_pipe_urbs
  4. init_urbs
  5. get_usb_full_speed_rate
  6. get_usb_high_speed_rate
  7. usb_stream_free
  8. usb_stream_new
  9. balance_check
  10. balance_playback
  11. balance_capture
  12. subs_set_complete
  13. usb_stream_prepare_playback
  14. prepare_inurb
  15. submit_urbs
  16. loop_back
  17. loop_back
  18. stream_idle
  19. i_capture_idle
  20. i_playback_idle
  21. stream_start
  22. i_capture_start
  23. i_playback_start
  24. usb_stream_start
  25. usb_stream_stop

   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 
  14 static 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 
  21 static 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 
  38 check:
  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 
  46 static 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 
  83 static 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  */
 115 static 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  */
 124 static inline unsigned get_usb_high_speed_rate(unsigned rate)
 125 {
 126         return ((rate << 10) + 62) / 125;
 127 }
 128 
 129 void 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 
 151 struct 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;
 230 out:
 231         return sk->s;
 232 }
 233 
 234 
 235 /*                             start                                  */
 236 
 237 static 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 
 252 static 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 
 258 static 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 
 264 static 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 
 274 static 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 
 309 check_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 
 335 static 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 
 350 static 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 
 369 report_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  */
 378 static 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;
 395 loop:
 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         }
 422 second:
 423         iu = sk->completed_inurb;
 424         id = iu->iso_frame_desc;
 425         p = 0;
 426         goto loop;
 427 
 428 }
 429 #else
 430 static void loop_back(struct usb_stream *s)
 431 {
 432 }
 433 #endif
 434 
 435 static 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;
 498 err_out:
 499         s->state = usb_stream_xrun;
 500         wake_up_all(&sk->sleep);
 501 }
 502 
 503 static 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 
 510 static 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 
 517 static 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 
 597 static 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 
 643 static 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 
 650 int 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);
 663 dotry:
 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;
 711 check_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 
 745 void 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 }

/* [<][>][^][v][top][bottom][index][help] */