static void read_completed(struct urb *urb) { struct snd_usb_caiaq_cb_info *info = urb->context; struct snd_usb_caiaqdev *dev; struct urb *out; int frame, len, send_it = 0, outframe = 0; if (urb->status || !info) return; dev = info->dev; if (!dev->streaming) return; out = dev->data_urbs_out[info->index]; /* read the recently received packet and send back one which has * the same layout */ for (frame = 0; frame < FRAMES_PER_URB; frame++) { if (urb->iso_frame_desc[frame].status) continue; len = urb->iso_frame_desc[outframe].actual_length; out->iso_frame_desc[outframe].length = len; out->iso_frame_desc[outframe].actual_length = 0; out->iso_frame_desc[outframe].offset = BYTES_PER_FRAME * frame; if (len > 0) { spin_lock(&dev->spinlock); fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); spin_unlock(&dev->spinlock); check_for_elapsed_periods(dev, dev->sub_playback); check_for_elapsed_periods(dev, dev->sub_capture); send_it = 1; } outframe++; } if (send_it) { out->number_of_packets = FRAMES_PER_URB; out->transfer_flags = URB_ISO_ASAP; usb_submit_urb(out, GFP_ATOMIC); } /* re-submit inbound urb */ for (frame = 0; frame < FRAMES_PER_URB; frame++) { urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; urb->iso_frame_desc[frame].actual_length = 0; } urb->number_of_packets = FRAMES_PER_URB; urb->transfer_flags = URB_ISO_ASAP; usb_submit_urb(urb, GFP_ATOMIC); }
static void read_completed(struct urb *urb) { struct snd_usb_caiaq_cb_info *info = urb->context; struct snd_usb_caiaqdev *dev; struct urb *out = NULL; int i, frame, len, send_it = 0, outframe = 0; size_t offset = 0; if (urb->status || !info) return; dev = info->dev; if (!dev->streaming) return; /* find an unused output urb that is unused */ for (i = 0; i < N_URBS; i++) if (test_and_set_bit(i, &dev->outurb_active_mask) == 0) { out = dev->data_urbs_out[i]; break; } if (!out) { log("Unable to find an output urb to use\n"); goto requeue; } /* read the recently received packet and send back one which has * the same layout */ for (frame = 0; frame < FRAMES_PER_URB; frame++) { if (urb->iso_frame_desc[frame].status) continue; len = urb->iso_frame_desc[outframe].actual_length; out->iso_frame_desc[outframe].length = len; out->iso_frame_desc[outframe].actual_length = 0; out->iso_frame_desc[outframe].offset = offset; offset += len; if (len > 0) { spin_lock(&dev->spinlock); fill_out_urb(dev, out, &out->iso_frame_desc[outframe]); read_in_urb(dev, urb, &urb->iso_frame_desc[frame]); spin_unlock(&dev->spinlock); check_for_elapsed_periods(dev, dev->sub_playback); check_for_elapsed_periods(dev, dev->sub_capture); send_it = 1; } outframe++; } if (send_it) { out->number_of_packets = outframe; out->transfer_flags = URB_ISO_ASAP; usb_submit_urb(out, GFP_ATOMIC); } else { struct snd_usb_caiaq_cb_info *oinfo = out->context; clear_bit(oinfo->index, &dev->outurb_active_mask); } requeue: /* re-submit inbound urb */ for (frame = 0; frame < FRAMES_PER_URB; frame++) { urb->iso_frame_desc[frame].offset = BYTES_PER_FRAME * frame; urb->iso_frame_desc[frame].length = BYTES_PER_FRAME; urb->iso_frame_desc[frame].actual_length = 0; } urb->number_of_packets = FRAMES_PER_URB; urb->transfer_flags = URB_ISO_ASAP; usb_submit_urb(urb, GFP_ATOMIC); }