kernel safety fixes

This commit is contained in:
Šerif Rami 2025-12-05 17:52:26 +01:00
parent d199e9ccaf
commit 7716f17b21
5 changed files with 39 additions and 26 deletions

View File

@ -157,9 +157,6 @@ void tascam_stop_work_handler(struct work_struct *work)
usb_kill_anchored_urbs(&tascam->playback_anchor);
usb_kill_anchored_urbs(&tascam->feedback_anchor);
usb_kill_anchored_urbs(&tascam->capture_anchor);
usb_kill_anchored_urbs(&tascam->midi_anchor);
atomic_set(&tascam->active_urbs, 0);
}
static void tascam_card_private_free(struct snd_card *card)

View File

@ -195,11 +195,6 @@ void capture_urb_complete(struct urb *urb)
return;
}
if (!atomic_read(&tascam->capture_active)) {
atomic_dec(&tascam->active_urbs);
return;
}
substream = tascam->capture_substream;
if (!substream || !substream->runtime) {
atomic_dec(&tascam->active_urbs);
@ -220,8 +215,14 @@ void capture_urb_complete(struct urb *urb)
if (frames_received > 0) {
spin_lock_irqsave(&tascam->lock, flags);
if (!atomic_read(&tascam->capture_active)) {
spin_unlock_irqrestore(&tascam->lock, flags);
atomic_dec(&tascam->active_urbs);
return;
}
write_pos = tascam->driver_capture_pos;
spin_unlock_irqrestore(&tascam->lock, flags);
u32 *dma_ptr = (u32 *)(runtime->dma_area + frames_to_bytes(runtime, write_pos));
@ -235,7 +236,6 @@ void capture_urb_complete(struct urb *urb)
tascam_decode_capture_chunk(urb->transfer_buffer + (part1 * 64), (u32 *)runtime->dma_area, part2);
}
spin_lock_irqsave(&tascam->lock, flags);
tascam->driver_capture_pos += frames_received;
if (tascam->driver_capture_pos >= buffer_size)
tascam->driver_capture_pos -= buffer_size;

View File

@ -6,6 +6,7 @@
static void tascam_midi_out_complete(struct urb *urb)
{
struct tascam_card *tascam = urb->context;
struct snd_rawmidi_substream *substream;
unsigned long flags;
int count;
bool submit = false;
@ -13,19 +14,20 @@ static void tascam_midi_out_complete(struct urb *urb)
spin_lock_irqsave(&tascam->midi_lock, flags);
if (urb->status || !tascam->midi_output) {
substream = tascam->midi_output;
active = tascam->midi_out_active;
if (urb->status || !substream) {
tascam->midi_out_active = false;
spin_unlock_irqrestore(&tascam->midi_lock, flags);
return;
}
active = tascam->midi_out_active;
spin_unlock_irqrestore(&tascam->midi_lock, flags);
if (!active)
return;
count = snd_rawmidi_transmit(tascam->midi_output, tascam->midi_out_buf, MIDI_PAYLOAD_SIZE);
count = snd_rawmidi_transmit(substream, tascam->midi_out_buf, MIDI_PAYLOAD_SIZE);
if (count > 0) {
if (count < MIDI_PAYLOAD_SIZE)
memset(tascam->midi_out_buf + count, 0xFD, MIDI_PAYLOAD_SIZE - count);
@ -98,18 +100,24 @@ static void tascam_midi_output_trigger(struct snd_rawmidi_substream *substream,
static void tascam_midi_in_complete(struct urb *urb)
{
struct tascam_card *tascam = urb->context;
struct snd_rawmidi_substream *substream;
unsigned long flags;
int i;
if (urb->status)
return;
if (urb->actual_length == MIDI_PACKET_SIZE && tascam->midi_input) {
spin_lock_irqsave(&tascam->midi_lock, flags);
substream = tascam->midi_input;
spin_unlock_irqrestore(&tascam->midi_lock, flags);
if (urb->actual_length == MIDI_PACKET_SIZE && substream) {
u8 *data = urb->transfer_buffer;
for (i = 0; i < MIDI_PAYLOAD_SIZE; i++) {
if (data[i] == 0xFD)
break;
snd_rawmidi_receive(tascam->midi_input, &data[i], 1);
snd_rawmidi_receive(substream, &data[i], 1);
}
}
@ -121,11 +129,14 @@ static void tascam_midi_in_complete(struct urb *urb)
static void tascam_midi_input_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct tascam_card *tascam = substream->rmidi->private_data;
unsigned long flags;
spin_lock_irqsave(&tascam->midi_lock, flags);
if (up)
tascam->midi_input = substream;
else
tascam->midi_input = NULL;
spin_unlock_irqrestore(&tascam->midi_lock, flags);
}
static int tascam_midi_open(struct snd_rawmidi_substream *substream)
@ -238,15 +249,15 @@ int tascam_create_midi(struct tascam_card *tascam)
return 0;
err_in_buf:
err_in_buf:
usb_free_coherent(tascam->dev, MIDI_PACKET_SIZE,
tascam->midi_out_buf, tascam->midi_out_urb->transfer_dma);
err_out_buf:
err_out_buf:
usb_free_urb(tascam->midi_in_urb);
tascam->midi_in_urb = NULL;
err_in_urb:
err_in_urb:
usb_free_urb(tascam->midi_out_urb);
tascam->midi_out_urb = NULL;
err_out_urb:
err_out_urb:
return err;
}

View File

@ -122,6 +122,10 @@ int tascam_pcm_hw_params(struct snd_pcm_substream *substream,
int err;
if (tascam->current_rate != rate) {
if (atomic_read(&tascam->playback_active) ||
atomic_read(&tascam->capture_active)) {
return -EBUSY;
}
usb_kill_anchored_urbs(&tascam->playback_anchor);
usb_kill_anchored_urbs(&tascam->feedback_anchor);

View File

@ -214,10 +214,6 @@ void playback_urb_complete(struct urb *urb)
atomic_dec(&tascam->active_urbs);
return;
}
if (!atomic_read(&tascam->playback_active)) {
atomic_dec(&tascam->active_urbs);
return;
}
substream = tascam->playback_substream;
if (!substream || !substream->runtime) {
@ -234,6 +230,13 @@ void playback_urb_complete(struct urb *urb)
period_size = runtime->period_size;
spin_lock_irqsave(&tascam->lock, flags);
if (!atomic_read(&tascam->playback_active)) {
spin_unlock_irqrestore(&tascam->lock, flags);
atomic_dec(&tascam->active_urbs);
return;
}
for (i = 0; i < urb->number_of_packets; i++) {
unsigned int frames_for_packet;
@ -249,7 +252,6 @@ void playback_urb_complete(struct urb *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) % buffer_size;
spin_unlock_irqrestore(&tascam->lock, flags);
if (total_bytes_for_urb > 0) {
u8 *dst_buf = urb->transfer_buffer;
@ -265,7 +267,6 @@ void playback_urb_complete(struct urb *urb)
}
}
spin_lock_irqsave(&tascam->lock, flags);
tascam->playback_frames_consumed += frames_to_copy;
if (period_size > 0) {