| From 01c961b9730b780c9689a480cf995b8b5238a88d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 15 Sep 2025 10:42:19 +0100 |
| Subject: ALSA: serial-generic: remove shared static buffer |
| |
| From: John Keeping <jkeeping@inmusicbrands.com> |
| |
| [ Upstream commit 84973249011fda3ff292f83439a062fec81ef982 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/drivers/serial-generic.c | 12 +++++++----- |
| 1 file changed, 7 insertions(+), 5 deletions(-) |
| |
| diff --git a/sound/drivers/serial-generic.c b/sound/drivers/serial-generic.c |
| index 36409a56c675e..d0e2e656c31c1 100644 |
| --- a/sound/drivers/serial-generic.c |
| +++ b/sound/drivers/serial-generic.c |
| @@ -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; |
| -- |
| 2.51.0 |
| |