diff options
Diffstat (limited to 'sound/usb/usx2y/usb_stream.c')
-rw-r--r-- | sound/usb/usx2y/usb_stream.c | 67 |
1 files changed, 30 insertions, 37 deletions
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c index 24393dafcb6e..12ae0340adc0 100644 --- a/sound/usb/usx2y/usb_stream.c +++ b/sound/usb/usx2y/usb_stream.c | |||
@@ -33,32 +33,26 @@ static unsigned usb_stream_next_packet_size(struct usb_stream_kernel *sk) | |||
33 | static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) | 33 | static void playback_prep_freqn(struct usb_stream_kernel *sk, struct urb *urb) |
34 | { | 34 | { |
35 | struct usb_stream *s = sk->s; | 35 | struct usb_stream *s = sk->s; |
36 | unsigned l = 0; | 36 | int pack, lb = 0; |
37 | int pack; | 37 | |
38 | 38 | for (pack = 0; pack < sk->n_o_ps; pack++) { | |
39 | urb->iso_frame_desc[0].offset = 0; | 39 | int l = usb_stream_next_packet_size(sk); |
40 | urb->iso_frame_desc[0].length = usb_stream_next_packet_size(sk); | 40 | if (s->idle_outsize + lb + l > s->period_size) |
41 | sk->out_phase = sk->out_phase_peeked; | ||
42 | urb->transfer_buffer_length = urb->iso_frame_desc[0].length; | ||
43 | |||
44 | for (pack = 1; pack < sk->n_o_ps; pack++) { | ||
45 | l = usb_stream_next_packet_size(sk); | ||
46 | if (s->idle_outsize + urb->transfer_buffer_length + l > | ||
47 | s->period_size) | ||
48 | goto check; | 41 | goto check; |
49 | 42 | ||
50 | sk->out_phase = sk->out_phase_peeked; | 43 | sk->out_phase = sk->out_phase_peeked; |
51 | urb->iso_frame_desc[pack].offset = urb->transfer_buffer_length; | 44 | urb->iso_frame_desc[pack].offset = lb; |
52 | urb->iso_frame_desc[pack].length = l; | 45 | urb->iso_frame_desc[pack].length = l; |
53 | urb->transfer_buffer_length += l; | 46 | lb += l; |
54 | } | 47 | } |
55 | snd_printdd(KERN_DEBUG "%i\n", urb->transfer_buffer_length); | 48 | snd_printdd(KERN_DEBUG "%i\n", lb); |
56 | 49 | ||
57 | check: | 50 | check: |
58 | urb->number_of_packets = pack; | 51 | urb->number_of_packets = pack; |
59 | s->idle_outsize += urb->transfer_buffer_length - s->period_size; | 52 | urb->transfer_buffer_length = lb; |
53 | s->idle_outsize += lb - s->period_size; | ||
60 | snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize, | 54 | snd_printdd(KERN_DEBUG "idle=%i ul=%i ps=%i\n", s->idle_outsize, |
61 | urb->transfer_buffer_length, s->period_size); | 55 | lb, s->period_size); |
62 | } | 56 | } |
63 | 57 | ||
64 | static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, | 58 | static void init_pipe_urbs(struct usb_stream_kernel *sk, unsigned use_packsize, |
@@ -282,21 +276,20 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk, | |||
282 | struct usb_stream *s = sk->s; | 276 | struct usb_stream *s = sk->s; |
283 | struct urb *io; | 277 | struct urb *io; |
284 | struct usb_iso_packet_descriptor *id, *od; | 278 | struct usb_iso_packet_descriptor *id, *od; |
285 | int p, l = 0; | 279 | int p = 0, lb = 0, l = 0; |
286 | 280 | ||
287 | io = sk->idle_outurb; | 281 | io = sk->idle_outurb; |
288 | od = io->iso_frame_desc; | 282 | od = io->iso_frame_desc; |
289 | io->transfer_buffer_length = 0; | ||
290 | 283 | ||
291 | for (p = 0; s->sync_packet < 0; ++p, ++s->sync_packet) { | 284 | for (; s->sync_packet < 0; ++p, ++s->sync_packet) { |
292 | struct urb *ii = sk->completed_inurb; | 285 | struct urb *ii = sk->completed_inurb; |
293 | id = ii->iso_frame_desc + | 286 | id = ii->iso_frame_desc + |
294 | ii->number_of_packets + s->sync_packet; | 287 | ii->number_of_packets + s->sync_packet; |
295 | l = id->actual_length; | 288 | l = id->actual_length; |
296 | 289 | ||
297 | od[p].length = l; | 290 | od[p].length = l; |
298 | od[p].offset = io->transfer_buffer_length; | 291 | od[p].offset = lb; |
299 | io->transfer_buffer_length += l; | 292 | lb += l; |
300 | } | 293 | } |
301 | 294 | ||
302 | for (; | 295 | for (; |
@@ -304,38 +297,38 @@ static int usb_stream_prepare_playback(struct usb_stream_kernel *sk, | |||
304 | ++p, ++s->sync_packet) { | 297 | ++p, ++s->sync_packet) { |
305 | l = inurb->iso_frame_desc[s->sync_packet].actual_length; | 298 | l = inurb->iso_frame_desc[s->sync_packet].actual_length; |
306 | 299 | ||
307 | if (s->idle_outsize + io->transfer_buffer_length + l > | 300 | if (s->idle_outsize + lb + l > s->period_size) |
308 | s->period_size) | ||
309 | goto check_ok; | 301 | goto check_ok; |
310 | 302 | ||
311 | od[p].length = l; | 303 | od[p].length = l; |
312 | od[p].offset = io->transfer_buffer_length; | 304 | od[p].offset = lb; |
313 | io->transfer_buffer_length += l; | 305 | lb += l; |
314 | } | 306 | } |
315 | 307 | ||
316 | check_ok: | 308 | check_ok: |
317 | s->sync_packet -= inurb->number_of_packets; | 309 | s->sync_packet -= inurb->number_of_packets; |
318 | if (s->sync_packet < -2 || s->sync_packet > 0) { | 310 | if (unlikely(s->sync_packet < -2 || s->sync_packet > 0)) { |
319 | snd_printk(KERN_WARNING "invalid sync_packet = %i;" | 311 | snd_printk(KERN_WARNING "invalid sync_packet = %i;" |
320 | " p=%i nop=%i %i %x %x %x > %x\n", | 312 | " p=%i nop=%i %i %x %x %x > %x\n", |
321 | s->sync_packet, p, inurb->number_of_packets, | 313 | s->sync_packet, p, inurb->number_of_packets, |
322 | s->idle_outsize + io->transfer_buffer_length + l, | 314 | s->idle_outsize + lb + l, |
323 | s->idle_outsize, io->transfer_buffer_length, l, | 315 | s->idle_outsize, lb, l, |
324 | s->period_size); | 316 | s->period_size); |
325 | return -1; | 317 | return -1; |
326 | } | 318 | } |
327 | if (io->transfer_buffer_length % s->cfg.frame_size) { | 319 | if (unlikely(lb % s->cfg.frame_size)) { |
328 | snd_printk(KERN_WARNING"invalid outsize = %i\n", | 320 | snd_printk(KERN_WARNING"invalid outsize = %i\n", |
329 | io->transfer_buffer_length); | 321 | lb); |
330 | return -1; | 322 | return -1; |
331 | } | 323 | } |
332 | s->idle_outsize += io->transfer_buffer_length - s->period_size; | 324 | s->idle_outsize += lb - s->period_size; |
333 | io->number_of_packets = p; | 325 | io->number_of_packets = p; |
334 | if (s->idle_outsize > 0) { | 326 | io->transfer_buffer_length = lb; |
335 | snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize); | 327 | if (s->idle_outsize <= 0) |
336 | return -1; | 328 | return 0; |
337 | } | 329 | |
338 | return 0; | 330 | snd_printk(KERN_WARNING "idle=%i\n", s->idle_outsize); |
331 | return -1; | ||
339 | } | 332 | } |
340 | 333 | ||
341 | static void prepare_inurb(int number_of_packets, struct urb *iu) | 334 | static void prepare_inurb(int number_of_packets, struct urb *iu) |