Commit 84973249 authored by John Keeping's avatar John Keeping Committed by Takashi Iwai
Browse files

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: default avatarJohn Keeping <jkeeping@inmusicbrands.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c29287bb
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -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;