ALSA: serial-generic: remove shared static buffer

If multiple instances of this driver are instantiated and try to send
concurrently then the single static buffer snd_serial_generic_tx_work()
will cause corruption in the data output.

Move the buffer into the per-instance driver data to avoid this.

Signed-off-by: John Keeping <jkeeping@inmusicbrands.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
John Keeping
2025-09-15 10:42:19 +01:00
committed by Takashi Iwai
parent c29287bb32
commit 8497324901

View File

@@ -37,6 +37,8 @@ MODULE_LICENSE("GPL");
#define SERIAL_TX_STATE_ACTIVE 1
#define SERIAL_TX_STATE_WAKEUP 2
#define INTERNAL_BUF_SIZE 256
struct snd_serial_generic {
struct serdev_device *serdev;
@@ -51,6 +53,7 @@ struct snd_serial_generic {
struct work_struct tx_work;
unsigned long tx_state;
char tx_buf[INTERNAL_BUF_SIZE];
};
static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
@@ -61,11 +64,8 @@ static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
schedule_work(&drvdata->tx_work);
}
#define INTERNAL_BUF_SIZE 256
static void snd_serial_generic_tx_work(struct work_struct *work)
{
static char buf[INTERNAL_BUF_SIZE];
int num_bytes;
struct snd_serial_generic *drvdata = container_of(work, struct snd_serial_generic,
tx_work);
@@ -78,8 +78,10 @@ static void snd_serial_generic_tx_work(struct work_struct *work)
if (!test_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode))
break;
num_bytes = snd_rawmidi_transmit_peek(substream, buf, INTERNAL_BUF_SIZE);
num_bytes = serdev_device_write_buf(drvdata->serdev, buf, num_bytes);
num_bytes = snd_rawmidi_transmit_peek(substream, drvdata->tx_buf,
INTERNAL_BUF_SIZE);
num_bytes = serdev_device_write_buf(drvdata->serdev, drvdata->tx_buf,
num_bytes);
if (!num_bytes)
break;