diff --git a/us144mkii.c b/us144mkii.c index 313d2ff..373270c 100644 --- a/us144mkii.c +++ b/us144mkii.c @@ -415,7 +415,7 @@ static int tascam_probe(struct usb_interface *intf, struct snd_card *card; struct tascam_card *tascam; int err; - char *handshake_buf; + char *handshake_buf __free(kfree); if (dev->speed != USB_SPEED_HIGH) dev_info(&dev->dev, @@ -449,17 +449,15 @@ static int tascam_probe(struct usb_interface *intf, handshake_buf, 1, USB_CTRL_TIMEOUT_MS); if (err < 0) { dev_err(&dev->dev, "Handshake read failed with %d\n", err); - kfree(handshake_buf); return err; } if (handshake_buf[0] != 0x12 && handshake_buf[0] != 0x16 && handshake_buf[0] != 0x30) { dev_err(&dev->dev, "Unexpected handshake value: 0x%x\n", handshake_buf[0]); - kfree(handshake_buf); return -ENODEV; } - kfree(handshake_buf); + err = usb_set_interface(dev, 0, 1); if (err < 0) { diff --git a/us144mkii_capture.c b/us144mkii_capture.c index c28b573..5ea3538 100644 --- a/us144mkii_capture.c +++ b/us144mkii_capture.c @@ -73,14 +73,12 @@ tascam_capture_pointer(struct snd_pcm_substream *substream) { struct tascam_card *tascam = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; u64 pos; - unsigned long flags; if (!atomic_read(&tascam->capture_active)) return 0; - spin_lock_irqsave(&tascam->lock, flags); + guard(spinlock_irqsave)(&tascam->lock); pos = tascam->capture_frames_processed; - spin_unlock_irqrestore(&tascam->lock, flags); if (runtime->buffer_size == 0) return 0; @@ -165,7 +163,6 @@ void tascam_capture_work_handler(struct work_struct *work) { container_of(work, struct tascam_card, capture_work); struct snd_pcm_substream *substream = tascam->capture_substream; struct snd_pcm_runtime *runtime; - unsigned long flags; u8 *raw_block = tascam->capture_decode_raw_block; s32 *decoded_block = tascam->capture_decode_dst_block; s32 *routed_block = tascam->capture_routing_buffer; @@ -184,28 +181,29 @@ void tascam_capture_work_handler(struct work_struct *work) { size_t write_ptr, read_ptr, available_data; bool can_process; - spin_lock_irqsave(&tascam->lock, flags); - write_ptr = tascam->capture_ring_buffer_write_ptr; - read_ptr = tascam->capture_ring_buffer_read_ptr; - available_data = (write_ptr >= read_ptr) - ? (write_ptr - read_ptr) - : (CAPTURE_RING_BUFFER_SIZE - read_ptr + write_ptr); - can_process = (available_data >= RAW_BYTES_PER_DECODE_BLOCK); + { + guard(spinlock_irqsave)(&tascam->lock); + write_ptr = tascam->capture_ring_buffer_write_ptr; + read_ptr = tascam->capture_ring_buffer_read_ptr; + available_data = (write_ptr >= read_ptr) + ? (write_ptr - read_ptr) + : (CAPTURE_RING_BUFFER_SIZE - read_ptr + write_ptr); + can_process = (available_data >= RAW_BYTES_PER_DECODE_BLOCK); - if (can_process) { - size_t bytes_to_end = CAPTURE_RING_BUFFER_SIZE - read_ptr; - if (bytes_to_end >= RAW_BYTES_PER_DECODE_BLOCK) { - memcpy(raw_block, tascam->capture_ring_buffer + read_ptr, - RAW_BYTES_PER_DECODE_BLOCK); - } else { - memcpy(raw_block, tascam->capture_ring_buffer + read_ptr, bytes_to_end); - memcpy(raw_block + bytes_to_end, tascam->capture_ring_buffer, - RAW_BYTES_PER_DECODE_BLOCK - bytes_to_end); + if (can_process) { + size_t bytes_to_end = CAPTURE_RING_BUFFER_SIZE - read_ptr; + if (bytes_to_end >= RAW_BYTES_PER_DECODE_BLOCK) { + memcpy(raw_block, tascam->capture_ring_buffer + read_ptr, + RAW_BYTES_PER_DECODE_BLOCK); + } else { + memcpy(raw_block, tascam->capture_ring_buffer + read_ptr, bytes_to_end); + memcpy(raw_block + bytes_to_end, tascam->capture_ring_buffer, + RAW_BYTES_PER_DECODE_BLOCK - bytes_to_end); + } + tascam->capture_ring_buffer_read_ptr = + (read_ptr + RAW_BYTES_PER_DECODE_BLOCK) % CAPTURE_RING_BUFFER_SIZE; } - tascam->capture_ring_buffer_read_ptr = - (read_ptr + RAW_BYTES_PER_DECODE_BLOCK) % CAPTURE_RING_BUFFER_SIZE; } - spin_unlock_irqrestore(&tascam->lock, flags); if (!can_process) break; @@ -213,29 +211,30 @@ void tascam_capture_work_handler(struct work_struct *work) { decode_tascam_capture_block(raw_block, decoded_block); process_capture_routing_us144mkii(tascam, decoded_block, routed_block); - spin_lock_irqsave(&tascam->lock, flags); - if (atomic_read(&tascam->capture_active)) { - int f; + { + guard(spinlock_irqsave)(&tascam->lock); + if (atomic_read(&tascam->capture_active)) { + int f; - for (f = 0; f < FRAMES_PER_DECODE_BLOCK; ++f) { - u8 *dst_frame_start = - runtime->dma_area + - frames_to_bytes(runtime, tascam->driver_capture_pos); - s32 *routed_frame_start = routed_block + (f * NUM_CHANNELS); - int c; + for (f = 0; f < FRAMES_PER_DECODE_BLOCK; ++f) { + u8 *dst_frame_start = + runtime->dma_area + + frames_to_bytes(runtime, tascam->driver_capture_pos); + s32 *routed_frame_start = routed_block + (f * NUM_CHANNELS); + int c; - for (c = 0; c < NUM_CHANNELS; c++) { - u8 *dst_channel = dst_frame_start + (c * BYTES_PER_SAMPLE); - s32 *src_channel_s32 = routed_frame_start + c; + for (c = 0; c < NUM_CHANNELS; c++) { + u8 *dst_channel = dst_frame_start + (c * BYTES_PER_SAMPLE); + s32 *src_channel_s32 = routed_frame_start + c; - memcpy(dst_channel, ((char *)src_channel_s32) + 1, 3); + memcpy(dst_channel, ((char *)src_channel_s32) + 1, 3); + } + + tascam->driver_capture_pos = + (tascam->driver_capture_pos + 1) % runtime->buffer_size; } - - tascam->driver_capture_pos = - (tascam->driver_capture_pos + 1) % runtime->buffer_size; } } - spin_unlock_irqrestore(&tascam->lock, flags); } } @@ -250,7 +249,6 @@ void tascam_capture_work_handler(struct work_struct *work) { void capture_urb_complete(struct urb *urb) { struct tascam_card *tascam = urb->context; int ret; - unsigned long flags; if (urb->status) { if (urb->status != -ENOENT && urb->status != -ECONNRESET && @@ -267,20 +265,25 @@ void capture_urb_complete(struct urb *urb) { size_t write_ptr; size_t bytes_to_end; - spin_lock_irqsave(&tascam->lock, flags); - write_ptr = tascam->capture_ring_buffer_write_ptr; - bytes_to_end = CAPTURE_RING_BUFFER_SIZE - write_ptr; + { + guard(spinlock_irqsave)(&tascam->lock); + write_ptr = tascam->capture_ring_buffer_write_ptr; + bytes_to_end = CAPTURE_RING_BUFFER_SIZE - write_ptr; - if (urb->actual_length > bytes_to_end) { - memcpy(tascam->capture_ring_buffer + write_ptr, urb->transfer_buffer, bytes_to_end); - memcpy(tascam->capture_ring_buffer, urb->transfer_buffer + bytes_to_end, urb->actual_length - bytes_to_end); - } else { - memcpy(tascam->capture_ring_buffer + write_ptr, urb->transfer_buffer, urb->actual_length); + if (urb->actual_length > bytes_to_end) { + memcpy(tascam->capture_ring_buffer + write_ptr, urb->transfer_buffer, + bytes_to_end); + memcpy(tascam->capture_ring_buffer, urb->transfer_buffer + bytes_to_end, + urb->actual_length - bytes_to_end); + } else { + memcpy(tascam->capture_ring_buffer + write_ptr, urb->transfer_buffer, + urb->actual_length); + } + + tascam->capture_ring_buffer_write_ptr = + (write_ptr + urb->actual_length) % CAPTURE_RING_BUFFER_SIZE; } - tascam->capture_ring_buffer_write_ptr = (write_ptr + urb->actual_length) % CAPTURE_RING_BUFFER_SIZE; - spin_unlock_irqrestore(&tascam->lock, flags); - schedule_work(&tascam->capture_work); } diff --git a/us144mkii_controls.c b/us144mkii_controls.c index 05deb40..02e0f8a 100644 --- a/us144mkii_controls.c +++ b/us144mkii_controls.c @@ -34,15 +34,7 @@ static const char *const capture_source_texts[] = {"Analog In", "Digital In"}; */ static int tascam_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= 2) - uinfo->value.enumerated.item = 1; - strscpy(uinfo->value.enumerated.name, - playback_source_texts[uinfo->value.enumerated.item], - sizeof(uinfo->value.enumerated.name)); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, playback_source_texts); } /** @@ -179,15 +171,7 @@ static const struct snd_kcontrol_new tascam_digital_out_control = { */ static int tascam_capture_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= 2) - uinfo->value.enumerated.item = 1; - strscpy(uinfo->value.enumerated.name, - capture_source_texts[uinfo->value.enumerated.item], - sizeof(uinfo->value.enumerated.name)); - return 0; + return snd_ctl_enum_info(uinfo, 1, 2, capture_source_texts); } /** @@ -349,7 +333,7 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct tascam_card *tascam = (struct tascam_card *)snd_kcontrol_chip(kcontrol); - u8 *buf; + u8 *buf __free(kfree); int err; u32 rate = 0; @@ -370,7 +354,6 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol, rate = buf[0] | (buf[1] << 8) | (buf[2] << 16); ucontrol->value.integer.value[0] = rate; - kfree(buf); return 0; } diff --git a/us144mkii_midi.c b/us144mkii_midi.c index 6cfb5cf..e21cbb1 100644 --- a/us144mkii_midi.c +++ b/us144mkii_midi.c @@ -124,13 +124,13 @@ static void tascam_midi_in_trigger(struct snd_rawmidi_substream *substream, int up) { struct tascam_card *tascam = substream->rmidi->private_data; int i, err; - unsigned long flags; if (up) { if (atomic_xchg(&tascam->midi_in_active, 1) == 0) { - spin_lock_irqsave(&tascam->midi_in_lock, flags); - kfifo_reset(&tascam->midi_in_fifo); - spin_unlock_irqrestore(&tascam->midi_in_lock, flags); + { + guard(spinlock_irqsave)(&tascam->midi_in_lock); + kfifo_reset(&tascam->midi_in_fifo); + } for (i = 0; i < NUM_MIDI_IN_URBS; i++) { usb_get_urb(tascam->midi_in_urbs[i]); @@ -175,7 +175,6 @@ static const struct snd_rawmidi_ops tascam_midi_in_ops = { */ void tascam_midi_out_urb_complete(struct urb *urb) { struct tascam_card *tascam = urb->context; - unsigned long flags; int i, urb_index = -1; if (urb->status) { @@ -184,6 +183,7 @@ void tascam_midi_out_urb_complete(struct urb *urb) { dev_err_ratelimited(tascam->card->dev, "MIDI OUT URB failed: %d\n", urb->status); } + goto out; } if (!tascam) @@ -201,12 +201,14 @@ void tascam_midi_out_urb_complete(struct urb *urb) { goto out; } - spin_lock_irqsave(&tascam->midi_out_lock, flags); - clear_bit(urb_index, &tascam->midi_out_urbs_in_flight); - spin_unlock_irqrestore(&tascam->midi_out_lock, flags); + { + guard(spinlock_irqsave)(&tascam->midi_out_lock); + clear_bit(urb_index, &tascam->midi_out_urbs_in_flight); + } if (atomic_read(&tascam->midi_out_active)) schedule_work(&tascam->midi_out_work); + out: usb_put_urb(urb); } @@ -231,52 +233,51 @@ static void tascam_midi_out_work_handler(struct work_struct *work) { return; while (snd_rawmidi_transmit_peek(substream, (u8[]){0}, 1) == 1) { - unsigned long flags; int urb_index; struct urb *urb; u8 *buf; int bytes_to_send; - spin_lock_irqsave(&tascam->midi_out_lock, flags); + { + guard(spinlock_irqsave)(&tascam->midi_out_lock); - urb_index = -1; - for (i = 0; i < NUM_MIDI_OUT_URBS; i++) { - if (!test_bit(i, &tascam->midi_out_urbs_in_flight)) { - urb_index = i; - break; + urb_index = -1; + for (i = 0; i < NUM_MIDI_OUT_URBS; i++) { + if (!test_bit(i, &tascam->midi_out_urbs_in_flight)) { + urb_index = i; + break; + } } + + if (urb_index < 0) { + return; /* No free URBs, will be rescheduled by completion handler */ + } + + urb = tascam->midi_out_urbs[urb_index]; + buf = urb->transfer_buffer; + bytes_to_send = snd_rawmidi_transmit(substream, buf, 8); + + if (bytes_to_send <= 0) { + break; /* No more data */ + } + + if (bytes_to_send < 9) + memset(buf + bytes_to_send, 0xfd, 9 - bytes_to_send); + buf[8] = 0x00; + + set_bit(urb_index, &tascam->midi_out_urbs_in_flight); + urb->transfer_buffer_length = 9; } - if (urb_index < 0) { - spin_unlock_irqrestore(&tascam->midi_out_lock, flags); - return; /* No free URBs, will be rescheduled by completion handler */ - } - - urb = tascam->midi_out_urbs[urb_index]; - buf = urb->transfer_buffer; - bytes_to_send = snd_rawmidi_transmit(substream, buf, 8); - - if (bytes_to_send <= 0) { - spin_unlock_irqrestore(&tascam->midi_out_lock, flags); - break; /* No more data */ - } - - if (bytes_to_send < 9) - memset(buf + bytes_to_send, 0xfd, 9 - bytes_to_send); - buf[8] = 0x00; - - set_bit(urb_index, &tascam->midi_out_urbs_in_flight); - urb->transfer_buffer_length = 9; - spin_unlock_irqrestore(&tascam->midi_out_lock, flags); - usb_get_urb(urb); usb_anchor_urb(urb, &tascam->midi_out_anchor); if (usb_submit_urb(urb, GFP_KERNEL) < 0) { dev_err_ratelimited(tascam->card->dev, "Failed to submit MIDI OUT URB %d\n", urb_index); - spin_lock_irqsave(&tascam->midi_out_lock, flags); - clear_bit(urb_index, &tascam->midi_out_urbs_in_flight); - spin_unlock_irqrestore(&tascam->midi_out_lock, flags); + { + guard(spinlock_irqsave)(&tascam->midi_out_lock); + clear_bit(urb_index, &tascam->midi_out_urbs_in_flight); + } usb_unanchor_urb(urb); usb_put_urb(urb); break; /* Stop on error */ @@ -402,4 +403,4 @@ int tascam_create_midi(struct tascam_card *tascam) { INIT_WORK(&tascam->midi_out_work, tascam_midi_out_work_handler); return 0; -} +} \ No newline at end of file diff --git a/us144mkii_pcm.c b/us144mkii_pcm.c index 159e26c..4697c2c 100644 --- a/us144mkii_pcm.c +++ b/us144mkii_pcm.c @@ -259,10 +259,6 @@ int tascam_pcm_hw_params(struct snd_pcm_substream *substream, int err; unsigned int rate = params_rate(params); - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (err < 0) - return err; - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { tascam->fpo.sample_rate_khz = rate / 1000; tascam->fpo.base_feedback_value = tascam->fpo.sample_rate_khz; @@ -300,9 +296,7 @@ int tascam_pcm_hw_params(struct snd_pcm_substream *substream, * * Return: 0 on success. */ -int tascam_pcm_hw_free(struct snd_pcm_substream *substream) { - return snd_pcm_lib_free_pages(substream); -} +int tascam_pcm_hw_free(struct snd_pcm_substream *substream) { return 0; } /** * tascam_pcm_trigger() - Triggers the start or stop of PCM streams. @@ -318,36 +312,36 @@ int tascam_pcm_hw_free(struct snd_pcm_substream *substream) { */ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct tascam_card *tascam = snd_pcm_substream_chip(substream); - unsigned long flags; int err = 0; int i; bool do_start = false; bool do_stop = false; - spin_lock_irqsave(&tascam->lock, flags); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - if (!atomic_read(&tascam->playback_active)) { - atomic_set(&tascam->playback_active, 1); - atomic_set(&tascam->capture_active, 1); - do_start = true; + { + guard(spinlock_irqsave)(&tascam->lock); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + if (!atomic_read(&tascam->playback_active)) { + atomic_set(&tascam->playback_active, 1); + atomic_set(&tascam->capture_active, 1); + do_start = true; + } + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (atomic_read(&tascam->playback_active)) { + atomic_set(&tascam->playback_active, 0); + atomic_set(&tascam->capture_active, 0); + do_stop = true; + } + break; + default: + err = -EINVAL; + break; } - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (atomic_read(&tascam->playback_active)) { - atomic_set(&tascam->playback_active, 0); - atomic_set(&tascam->capture_active, 0); - do_stop = true; - } - break; - default: - err = -EINVAL; - break; } - spin_unlock_irqrestore(&tascam->lock, flags); if (do_start) { if (atomic_read(&tascam->active_urbs) > 0) { @@ -362,7 +356,7 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { if (err < 0) { usb_unanchor_urb(tascam->feedback_urbs[i]); usb_put_urb(tascam->feedback_urbs[i]); - atomic_dec(&tascam->active_urbs); /* Decrement on failed submission */ + atomic_dec(&tascam->active_urbs); goto start_rollback; } atomic_inc(&tascam->active_urbs); @@ -374,7 +368,7 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { if (err < 0) { usb_unanchor_urb(tascam->playback_urbs[i]); usb_put_urb(tascam->playback_urbs[i]); - atomic_dec(&tascam->active_urbs); /* Decrement on failed submission */ + atomic_dec(&tascam->active_urbs); goto start_rollback; } atomic_inc(&tascam->active_urbs); @@ -386,7 +380,7 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { if (err < 0) { usb_unanchor_urb(tascam->capture_urbs[i]); usb_put_urb(tascam->capture_urbs[i]); - atomic_dec(&tascam->active_urbs); /* Decrement on failed submission */ + atomic_dec(&tascam->active_urbs); goto start_rollback; } atomic_inc(&tascam->active_urbs); @@ -405,26 +399,18 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { return err; } -/** - * tascam_init_pcm() - Initializes the ALSA PCM device. - * @pcm: Pointer to the ALSA PCM device to initialize. - * - * This function sets up the PCM operations for playback and capture, - * preallocates pages for the PCM buffer, and initializes the workqueue - * for deferred capture processing. - * - * Return: 0 on success. - */ int tascam_init_pcm(struct snd_pcm *pcm) { struct tascam_card *tascam = pcm->private_data; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &tascam_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tascam_capture_ops); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - tascam->dev->dev.parent, 64 * 1024, - tascam_pcm_hw.buffer_bytes_max); + + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, + tascam->dev->dev.parent, 64 * 1024, + tascam_pcm_hw.buffer_bytes_max); INIT_WORK(&tascam->capture_work, tascam_capture_work_handler); return 0; } + diff --git a/us144mkii_playback.c b/us144mkii_playback.c index 30b328f..16e5d54 100644 --- a/us144mkii_playback.c +++ b/us144mkii_playback.c @@ -113,14 +113,12 @@ tascam_playback_pointer(struct snd_pcm_substream *substream) { struct tascam_card *tascam = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; u64 pos; - unsigned long flags; if (!atomic_read(&tascam->playback_active)) return 0; - spin_lock_irqsave(&tascam->lock, flags); + guard(spinlock_irqsave)(&tascam->lock); pos = tascam->playback_frames_consumed; - spin_unlock_irqrestore(&tascam->lock, flags); if (runtime->buffer_size == 0) return 0; @@ -160,7 +158,6 @@ void playback_urb_complete(struct urb *urb) { struct tascam_card *tascam = urb->context; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; - unsigned long flags; size_t total_bytes_for_urb = 0; snd_pcm_uframes_t offset_frames; @@ -182,35 +179,35 @@ void playback_urb_complete(struct urb *urb) { goto out; runtime = substream->runtime; - spin_lock_irqsave(&tascam->lock, flags); + { + guard(spinlock_irqsave)(&tascam->lock); - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int frames_for_packet; - size_t bytes_for_packet; + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int frames_for_packet; + size_t bytes_for_packet; - if (tascam->feedback_synced) { - frames_for_packet = - tascam - ->feedback_accumulator_pattern[tascam->feedback_pattern_out_idx]; - tascam->feedback_pattern_out_idx = - (tascam->feedback_pattern_out_idx + 1) % FEEDBACK_ACCUMULATOR_SIZE; - } else { - frames_for_packet = runtime->rate / 8000; + if (tascam->feedback_synced) { + frames_for_packet = + tascam->feedback_accumulator_pattern + [tascam->feedback_pattern_out_idx]; + tascam->feedback_pattern_out_idx = + (tascam->feedback_pattern_out_idx + 1) % FEEDBACK_ACCUMULATOR_SIZE; + } else { + frames_for_packet = runtime->rate / 8000; + } + bytes_for_packet = frames_for_packet * BYTES_PER_FRAME; + + urb->iso_frame_desc[i].offset = total_bytes_for_urb; + urb->iso_frame_desc[i].length = bytes_for_packet; + total_bytes_for_urb += bytes_for_packet; } - bytes_for_packet = frames_for_packet * BYTES_PER_FRAME; + urb->transfer_buffer_length = total_bytes_for_urb; - urb->iso_frame_desc[i].offset = total_bytes_for_urb; - urb->iso_frame_desc[i].length = bytes_for_packet; - total_bytes_for_urb += bytes_for_packet; + offset_frames = tascam->driver_playback_pos; + frames_to_copy = bytes_to_frames(runtime, total_bytes_for_urb); + tascam->driver_playback_pos = + (offset_frames + frames_to_copy) % runtime->buffer_size; } - urb->transfer_buffer_length = total_bytes_for_urb; - - offset_frames = tascam->driver_playback_pos; - frames_to_copy = bytes_to_frames(runtime, total_bytes_for_urb); - tascam->driver_playback_pos = - (offset_frames + frames_to_copy) % runtime->buffer_size; - - spin_unlock_irqrestore(&tascam->lock, flags); if (total_bytes_for_urb > 0) { u8 *dst_buf = urb->transfer_buffer; @@ -267,7 +264,6 @@ void feedback_urb_complete(struct urb *urb) { struct tascam_card *tascam = urb->context; struct snd_pcm_substream *playback_ss, *capture_ss; struct snd_pcm_runtime *playback_rt, *capture_rt; - unsigned long flags; u64 total_frames_in_urb = 0; int ret, p; unsigned int old_in_idx, new_in_idx; @@ -294,126 +290,126 @@ void feedback_urb_complete(struct urb *urb) { capture_ss = tascam->capture_substream; capture_rt = capture_ss ? capture_ss->runtime : NULL; - spin_lock_irqsave(&tascam->lock, flags); + { + guard(spinlock_irqsave)(&tascam->lock); - if (tascam->feedback_urb_skip_count > 0) { - tascam->feedback_urb_skip_count--; - goto unlock_and_continue; - } + if (tascam->feedback_urb_skip_count > 0) { + tascam->feedback_urb_skip_count--; + goto continue_unlock; + } - old_in_idx = tascam->feedback_pattern_in_idx; + old_in_idx = tascam->feedback_pattern_in_idx; - for (p = 0; p < urb->number_of_packets; p++) { - u8 feedback_value = 0; - const unsigned int *pattern; - bool packet_ok = (urb->iso_frame_desc[p].status == 0 && - urb->iso_frame_desc[p].actual_length >= 1); + for (p = 0; p < urb->number_of_packets; p++) { + u8 feedback_value = 0; + const unsigned int *pattern; + bool packet_ok = (urb->iso_frame_desc[p].status == 0 && + urb->iso_frame_desc[p].actual_length >= 1); - if (packet_ok) - feedback_value = - *((u8 *)urb->transfer_buffer + urb->iso_frame_desc[p].offset); + if (packet_ok) + feedback_value = + *((u8 *)urb->transfer_buffer + urb->iso_frame_desc[p].offset); - if (packet_ok) { - int delta = feedback_value - tascam->fpo.base_feedback_value + - tascam->fpo.feedback_offset; - int pattern_idx; + if (packet_ok) { + int delta = feedback_value - tascam->fpo.base_feedback_value + + tascam->fpo.feedback_offset; + int pattern_idx; - if (delta < 0) { - pattern_idx = 0; // Clamp to the lowest pattern - } else if (delta >= 5) { - pattern_idx = 4; // Clamp to the highest pattern + if (delta < 0) { + pattern_idx = 0; // Clamp to the lowest pattern + } else if (delta >= 5) { + pattern_idx = 4; // Clamp to the highest pattern + } else { + pattern_idx = delta; + } + + pattern = tascam->fpo.full_frame_patterns[pattern_idx]; + tascam->feedback_consecutive_errors = 0; + int i; + + for (i = 0; i < 8; i++) { + unsigned int in_idx = (tascam->feedback_pattern_in_idx + i) % + FEEDBACK_ACCUMULATOR_SIZE; + + tascam->feedback_accumulator_pattern[in_idx] = pattern[i]; + total_frames_in_urb += pattern[i]; + } } else { - pattern_idx = delta; - } + unsigned int nominal_frames = playback_rt->rate / 8000; + int i; - pattern = tascam->fpo.full_frame_patterns[pattern_idx]; - tascam->feedback_consecutive_errors = 0; - int i; + if (tascam->feedback_synced) { + tascam->feedback_consecutive_errors++; + if (tascam->feedback_consecutive_errors > + FEEDBACK_SYNC_LOSS_THRESHOLD) { + dev_err(tascam->card->dev, + "Fatal: Feedback sync lost. Stopping stream.\n"); + if (playback_ss) + snd_pcm_stop(playback_ss, SNDRV_PCM_STATE_XRUN); + if (capture_ss) + snd_pcm_stop(capture_ss, SNDRV_PCM_STATE_XRUN); + tascam->feedback_synced = false; + goto continue_unlock; + } + } + for (i = 0; i < 8; i++) { + unsigned int in_idx = (tascam->feedback_pattern_in_idx + i) % + FEEDBACK_ACCUMULATOR_SIZE; - for (i = 0; i < 8; i++) { - unsigned int in_idx = - (tascam->feedback_pattern_in_idx + i) % FEEDBACK_ACCUMULATOR_SIZE; - - tascam->feedback_accumulator_pattern[in_idx] = pattern[i]; - total_frames_in_urb += pattern[i]; - } - } else { - unsigned int nominal_frames = playback_rt->rate / 8000; - int i; - - if (tascam->feedback_synced) { - tascam->feedback_consecutive_errors++; - if (tascam->feedback_consecutive_errors > - FEEDBACK_SYNC_LOSS_THRESHOLD) { - dev_err(tascam->card->dev, - "Fatal: Feedback sync lost. Stopping stream.\n"); - if (playback_ss) - snd_pcm_stop(playback_ss, SNDRV_PCM_STATE_XRUN); - if (capture_ss) - snd_pcm_stop(capture_ss, SNDRV_PCM_STATE_XRUN); - tascam->feedback_synced = false; - goto unlock_and_continue; + tascam->feedback_accumulator_pattern[in_idx] = nominal_frames; + total_frames_in_urb += nominal_frames; } } - for (i = 0; i < 8; i++) { - unsigned int in_idx = - (tascam->feedback_pattern_in_idx + i) % FEEDBACK_ACCUMULATOR_SIZE; + tascam->feedback_pattern_in_idx = + (tascam->feedback_pattern_in_idx + 8) % FEEDBACK_ACCUMULATOR_SIZE; + } - tascam->feedback_accumulator_pattern[in_idx] = nominal_frames; - total_frames_in_urb += nominal_frames; + new_in_idx = tascam->feedback_pattern_in_idx; + + if (!tascam->feedback_synced) { + unsigned int out_idx = tascam->feedback_pattern_out_idx; + bool is_ahead = (new_in_idx - out_idx) % FEEDBACK_ACCUMULATOR_SIZE < + (FEEDBACK_ACCUMULATOR_SIZE / 2); + bool was_behind = (old_in_idx - out_idx) % FEEDBACK_ACCUMULATOR_SIZE >= + (FEEDBACK_ACCUMULATOR_SIZE / 2); + + if (is_ahead && was_behind) { + dev_dbg(tascam->card->dev, "Sync Acquired! (in: %u, out: %u)\n", + new_in_idx, out_idx); + tascam->feedback_synced = true; + tascam->feedback_consecutive_errors = 0; } } - tascam->feedback_pattern_in_idx = - (tascam->feedback_pattern_in_idx + 8) % FEEDBACK_ACCUMULATOR_SIZE; - } - new_in_idx = tascam->feedback_pattern_in_idx; + if (total_frames_in_urb > 0) { + tascam->playback_frames_consumed += total_frames_in_urb; + if (atomic_read(&tascam->capture_active)) + tascam->capture_frames_processed += total_frames_in_urb; + } - if (!tascam->feedback_synced) { - unsigned int out_idx = tascam->feedback_pattern_out_idx; - bool is_ahead = (new_in_idx - out_idx) % FEEDBACK_ACCUMULATOR_SIZE < - (FEEDBACK_ACCUMULATOR_SIZE / 2); - bool was_behind = (old_in_idx - out_idx) % FEEDBACK_ACCUMULATOR_SIZE >= - (FEEDBACK_ACCUMULATOR_SIZE / 2); + if (playback_rt->period_size > 0) { + u64 current_period = div_u64(tascam->playback_frames_consumed, + playback_rt->period_size); - if (is_ahead && was_behind) { - dev_dbg(tascam->card->dev, "Sync Acquired! (in: %u, out: %u)\n", - new_in_idx, out_idx); - tascam->feedback_synced = true; - tascam->feedback_consecutive_errors = 0; + if (current_period > tascam->last_period_pos) { + tascam->last_period_pos = current_period; + playback_period_elapsed = true; + } + } + + if (atomic_read(&tascam->capture_active) && capture_rt && + capture_rt->period_size > 0) { + u64 current_capture_period = div_u64(tascam->capture_frames_processed, + capture_rt->period_size); + + if (current_capture_period > tascam->last_capture_period_pos) { + tascam->last_capture_period_pos = current_capture_period; + capture_period_elapsed = true; + } } } - if (total_frames_in_urb > 0) { - tascam->playback_frames_consumed += total_frames_in_urb; - if (atomic_read(&tascam->capture_active)) - tascam->capture_frames_processed += total_frames_in_urb; - } - - if (playback_rt->period_size > 0) { - u64 current_period = - div_u64(tascam->playback_frames_consumed, playback_rt->period_size); - - if (current_period > tascam->last_period_pos) { - tascam->last_period_pos = current_period; - playback_period_elapsed = true; - } - } - - if (atomic_read(&tascam->capture_active) && capture_rt && - capture_rt->period_size > 0) { - u64 current_capture_period = - div_u64(tascam->capture_frames_processed, capture_rt->period_size); - - if (current_capture_period > tascam->last_capture_period_pos) { - tascam->last_capture_period_pos = current_capture_period; - capture_period_elapsed = true; - } - } - -unlock_and_continue: - spin_unlock_irqrestore(&tascam->lock, flags); - +continue_unlock: if (playback_period_elapsed) snd_pcm_period_elapsed(playback_ss); if (capture_period_elapsed)