Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10a07d81 authored by Artem Egorkine's avatar Artem Egorkine Committed by Greg Kroah-Hartman
Browse files

ALSA: line6: correct midi status byte when receiving data from podxt



commit 8508fa2e7472f673edbeedf1b1d2b7a6bb898ecc upstream.

A PODxt device sends 0xb2, 0xc2 or 0xf2 as a status byte for MIDI
messages over USB that should otherwise have a 0xb0, 0xc0 or 0xf0
status byte. This is usually corrected by the driver on other OSes.

This fixes MIDI sysex messages sent by PODxt.

[ tiwai: fixed white spaces ]

Signed-off-by: default avatarArtem Egorkine <arteme@gmail.com>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20221225105728.1153989-1-arteme@gmail.com


Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 0e727c32
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -303,7 +303,8 @@ static void line6_data_received(struct urb *urb)
		for (;;) {
			done =
				line6_midibuf_read(mb, line6->buffer_message,
						LINE6_MIDI_MESSAGE_MAXLEN);
						   LINE6_MIDI_MESSAGE_MAXLEN,
						   LINE6_MIDIBUF_READ_RX);

			if (done <= 0)
				break;
+2 −1
Original line number Diff line number Diff line
@@ -56,7 +56,8 @@ static void line6_midi_transmit(struct snd_rawmidi_substream *substream)

	for (;;) {
		done = line6_midibuf_read(mb, chunk,
					  LINE6_FALLBACK_MAXPACKETSIZE);
					  LINE6_FALLBACK_MAXPACKETSIZE,
					  LINE6_MIDIBUF_READ_TX);

		if (done == 0)
			break;
+17 −8
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include "midibuf.h"


static int midibuf_message_length(unsigned char code)
{
	int message_length;
@@ -20,12 +21,7 @@ static int midibuf_message_length(unsigned char code)

		message_length = length[(code >> 4) - 8];
	} else {
		/*
		   Note that according to the MIDI specification 0xf2 is
		   the "Song Position Pointer", but this is used by Line 6
		   to send sysex messages to the host.
		 */
		static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
		static const int length[] = { -1, 2, 2, 2, -1, -1, 1, 1, 1, -1,
			1, 1, 1, -1, 1, 1
		};
		message_length = length[code & 0x0f];
@@ -125,7 +121,7 @@ int line6_midibuf_write(struct midi_buffer *this, unsigned char *data,
}

int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,
		       int length)
		       int length, int read_type)
{
	int bytes_used;
	int length1, length2;
@@ -148,9 +144,22 @@ int line6_midibuf_read(struct midi_buffer *this, unsigned char *data,

	length1 = this->size - this->pos_read;

	/* check MIDI command length */
	command = this->buf[this->pos_read];
	/*
	   PODxt always has status byte lower nibble set to 0010,
	   when it means to send 0000, so we correct if here so
	   that control/program changes come on channel 1 and
	   sysex message status byte is correct
	 */
	if (read_type == LINE6_MIDIBUF_READ_RX) {
		if (command == 0xb2 || command == 0xc2 || command == 0xf2) {
			unsigned char fixed = command & 0xf0;
			this->buf[this->pos_read] = fixed;
			command = fixed;
		}
	}

	/* check MIDI command length */
	if (command & 0x80) {
		midi_length = midibuf_message_length(command);
		this->command_prev = command;
+4 −1
Original line number Diff line number Diff line
@@ -8,6 +8,9 @@
#ifndef MIDIBUF_H
#define MIDIBUF_H

#define LINE6_MIDIBUF_READ_TX 0
#define LINE6_MIDIBUF_READ_RX 1

struct midi_buffer {
	unsigned char *buf;
	int size;
@@ -23,7 +26,7 @@ extern void line6_midibuf_destroy(struct midi_buffer *mb);
extern int line6_midibuf_ignore(struct midi_buffer *mb, int length);
extern int line6_midibuf_init(struct midi_buffer *mb, int size, int split);
extern int line6_midibuf_read(struct midi_buffer *mb, unsigned char *data,
			      int length);
			      int length, int read_type);
extern void line6_midibuf_reset(struct midi_buffer *mb);
extern int line6_midibuf_write(struct midi_buffer *mb, unsigned char *data,
			       int length);
+2 −1
Original line number Diff line number Diff line
@@ -159,8 +159,9 @@ static struct line6_pcm_properties pod_pcm_properties = {
	.bytes_per_channel = 3 /* SNDRV_PCM_FMTBIT_S24_3LE */
};


static const char pod_version_header[] = {
	0xf2, 0x7e, 0x7f, 0x06, 0x02
	0xf0, 0x7e, 0x7f, 0x06, 0x02
};

static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code,