code safety improvements
This commit is contained in:
parent
87ac941e35
commit
f4b17d24c8
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,7 +181,8 @@ 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);
|
||||
{
|
||||
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)
|
||||
|
|
@ -205,7 +203,7 @@ void tascam_capture_work_handler(struct work_struct *work) {
|
|||
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,7 +211,8 @@ 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);
|
||||
{
|
||||
guard(spinlock_irqsave)(&tascam->lock);
|
||||
if (atomic_read(&tascam->capture_active)) {
|
||||
int f;
|
||||
|
||||
|
|
@ -235,7 +234,7 @@ void tascam_capture_work_handler(struct work_struct *work) {
|
|||
(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,19 +265,24 @@ void capture_urb_complete(struct urb *urb) {
|
|||
size_t write_ptr;
|
||||
size_t bytes_to_end;
|
||||
|
||||
spin_lock_irqsave(&tascam->lock, flags);
|
||||
{
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
spin_unlock_irqrestore(&tascam->lock, flags);
|
||||
tascam->capture_ring_buffer_write_ptr =
|
||||
(write_ptr + urb->actual_length) % CAPTURE_RING_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
schedule_work(&tascam->capture_work);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
{
|
||||
guard(spinlock_irqsave)(&tascam->midi_in_lock);
|
||||
kfifo_reset(&tascam->midi_in_fifo);
|
||||
spin_unlock_irqrestore(&tascam->midi_in_lock, flags);
|
||||
}
|
||||
|
||||
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);
|
||||
{
|
||||
guard(spinlock_irqsave)(&tascam->midi_out_lock);
|
||||
clear_bit(urb_index, &tascam->midi_out_urbs_in_flight);
|
||||
spin_unlock_irqrestore(&tascam->midi_out_lock, flags);
|
||||
}
|
||||
|
||||
if (atomic_read(&tascam->midi_out_active))
|
||||
schedule_work(&tascam->midi_out_work);
|
||||
|
||||
out:
|
||||
usb_put_urb(urb);
|
||||
}
|
||||
|
|
@ -231,13 +233,13 @@ 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++) {
|
||||
|
|
@ -248,7 +250,6 @@ static void tascam_midi_out_work_handler(struct work_struct *work) {
|
|||
}
|
||||
|
||||
if (urb_index < 0) {
|
||||
spin_unlock_irqrestore(&tascam->midi_out_lock, flags);
|
||||
return; /* No free URBs, will be rescheduled by completion handler */
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +258,6 @@ static void tascam_midi_out_work_handler(struct work_struct *work) {
|
|||
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 */
|
||||
}
|
||||
|
||||
|
|
@ -267,16 +267,17 @@ static void tascam_midi_out_work_handler(struct work_struct *work) {
|
|||
|
||||
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);
|
||||
{
|
||||
guard(spinlock_irqsave)(&tascam->midi_out_lock);
|
||||
clear_bit(urb_index, &tascam->midi_out_urbs_in_flight);
|
||||
spin_unlock_irqrestore(&tascam->midi_out_lock, flags);
|
||||
}
|
||||
usb_unanchor_urb(urb);
|
||||
usb_put_urb(urb);
|
||||
break; /* Stop on error */
|
||||
|
|
|
|||
|
|
@ -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,13 +312,13 @@ 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);
|
||||
{
|
||||
guard(spinlock_irqsave)(&tascam->lock);
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
|
|
@ -347,7 +341,7 @@ int tascam_pcm_trigger(struct snd_pcm_substream *substream, int cmd) {
|
|||
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,22 +399,13 @@ 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,
|
||||
|
||||
snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
|
||||
tascam->dev->dev.parent, 64 * 1024,
|
||||
tascam_pcm_hw.buffer_bytes_max);
|
||||
|
||||
|
|
@ -428,3 +413,4 @@ int tascam_init_pcm(struct snd_pcm *pcm) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,7 +179,8 @@ 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;
|
||||
|
|
@ -190,8 +188,8 @@ void playback_urb_complete(struct urb *urb) {
|
|||
|
||||
if (tascam->feedback_synced) {
|
||||
frames_for_packet =
|
||||
tascam
|
||||
->feedback_accumulator_pattern[tascam->feedback_pattern_out_idx];
|
||||
tascam->feedback_accumulator_pattern
|
||||
[tascam->feedback_pattern_out_idx];
|
||||
tascam->feedback_pattern_out_idx =
|
||||
(tascam->feedback_pattern_out_idx + 1) % FEEDBACK_ACCUMULATOR_SIZE;
|
||||
} else {
|
||||
|
|
@ -209,8 +207,7 @@ void playback_urb_complete(struct urb *urb) {
|
|||
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,11 +290,12 @@ 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;
|
||||
goto continue_unlock;
|
||||
}
|
||||
|
||||
old_in_idx = tascam->feedback_pattern_in_idx;
|
||||
|
|
@ -331,8 +328,8 @@ void feedback_urb_complete(struct urb *urb) {
|
|||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
unsigned int in_idx =
|
||||
(tascam->feedback_pattern_in_idx + i) % FEEDBACK_ACCUMULATOR_SIZE;
|
||||
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];
|
||||
|
|
@ -352,12 +349,12 @@ void feedback_urb_complete(struct urb *urb) {
|
|||
if (capture_ss)
|
||||
snd_pcm_stop(capture_ss, SNDRV_PCM_STATE_XRUN);
|
||||
tascam->feedback_synced = false;
|
||||
goto unlock_and_continue;
|
||||
goto continue_unlock;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
unsigned int in_idx =
|
||||
(tascam->feedback_pattern_in_idx + i) % FEEDBACK_ACCUMULATOR_SIZE;
|
||||
unsigned int in_idx = (tascam->feedback_pattern_in_idx + i) %
|
||||
FEEDBACK_ACCUMULATOR_SIZE;
|
||||
|
||||
tascam->feedback_accumulator_pattern[in_idx] = nominal_frames;
|
||||
total_frames_in_urb += nominal_frames;
|
||||
|
|
@ -391,8 +388,8 @@ void feedback_urb_complete(struct urb *urb) {
|
|||
}
|
||||
|
||||
if (playback_rt->period_size > 0) {
|
||||
u64 current_period =
|
||||
div_u64(tascam->playback_frames_consumed, playback_rt->period_size);
|
||||
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;
|
||||
|
|
@ -402,18 +399,17 @@ void feedback_urb_complete(struct urb *urb) {
|
|||
|
||||
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);
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue