Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

John Keeping and committed by
Takashi Iwai
84973249 c29287bb

+7 -5
+7 -5
sound/drivers/serial-generic.c
··· 37 37 #define SERIAL_TX_STATE_ACTIVE 1 38 38 #define SERIAL_TX_STATE_WAKEUP 2 39 39 40 + #define INTERNAL_BUF_SIZE 256 41 + 40 42 struct snd_serial_generic { 41 43 struct serdev_device *serdev; 42 44 ··· 53 51 struct work_struct tx_work; 54 52 unsigned long tx_state; 55 53 54 + char tx_buf[INTERNAL_BUF_SIZE]; 56 55 }; 57 56 58 57 static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata) ··· 64 61 schedule_work(&drvdata->tx_work); 65 62 } 66 63 67 - #define INTERNAL_BUF_SIZE 256 68 - 69 64 static void snd_serial_generic_tx_work(struct work_struct *work) 70 65 { 71 - static char buf[INTERNAL_BUF_SIZE]; 72 66 int num_bytes; 73 67 struct snd_serial_generic *drvdata = container_of(work, struct snd_serial_generic, 74 68 tx_work); ··· 78 78 if (!test_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode)) 79 79 break; 80 80 81 - num_bytes = snd_rawmidi_transmit_peek(substream, buf, INTERNAL_BUF_SIZE); 82 - num_bytes = serdev_device_write_buf(drvdata->serdev, buf, num_bytes); 81 + num_bytes = snd_rawmidi_transmit_peek(substream, drvdata->tx_buf, 82 + INTERNAL_BUF_SIZE); 83 + num_bytes = serdev_device_write_buf(drvdata->serdev, drvdata->tx_buf, 84 + num_bytes); 83 85 84 86 if (!num_bytes) 85 87 break;