1
2
3
4
5
6#include <linux/usb.h>
7#include <linux/gfp.h>
8
9#include "usb_stream.h"
10
11
12
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
113
114
115static inline unsigned get_usb_full_speed_rate(unsigned rate)
116{
117 return ((rate << 13) + 62) / 125;
118}
119
120
121
122
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
171
172
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
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
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
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
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
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
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