]> www.infradead.org Git - users/hch/misc.git/commitdiff
ALSA: serial-generic: remove shared static buffer
authorJohn Keeping <jkeeping@inmusicbrands.com>
Mon, 15 Sep 2025 09:42:19 +0000 (10:42 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 15 Sep 2025 10:33:53 +0000 (12:33 +0200)
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>
sound/drivers/serial-generic.c

index 21ae053c0576716177b50be5b74d6dda32b614ce..766206c6ca75a87d475bf25d965847d4c99a2a32 100644 (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;