diff options
author | Takashi Iwai <tiwai@suse.de> | 2019-05-28 08:39:44 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2019-05-28 08:42:45 +0200 |
commit | 0b074ab7fc0d575247b9cc9f93bb7e007ca38840 (patch) | |
tree | aa64c8c81a16725f8f7e88199f095539e9f17365 /sound/usb/line6/driver.h | |
parent | fa763f1b2858752e6150ffff46886a1b7faffc82 (diff) | |
download | linux-0b074ab7fc0d575247b9cc9f93bb7e007ca38840.tar.gz linux-0b074ab7fc0d575247b9cc9f93bb7e007ca38840.tar.bz2 linux-0b074ab7fc0d575247b9cc9f93bb7e007ca38840.zip |
ALSA: line6: Assure canceling delayed work at disconnection
The current code performs the cancel of a delayed work at the late
stage of disconnection procedure, which may lead to the access to the
already cleared state.
This patch assures to call cancel_delayed_work_sync() at the beginning
of the disconnection procedure for avoiding that race. The delayed
work object is now assigned in the common line6 object instead of its
derivative, so that we can call cancel_delayed_work_sync().
Along with the change, the startup function is called via the new
callback instead. This will make it easier to port other LINE6
drivers to use the delayed work for startup in later patches.
Reported-by: syzbot+5255458d5e0a2b10bbb9@syzkaller.appspotmail.com
Fixes: 7f84ff68be05 ("ALSA: line6: toneport: Fix broken usage of timer for delayed execution")
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/line6/driver.h')
-rw-r--r-- | sound/usb/line6/driver.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/sound/usb/line6/driver.h b/sound/usb/line6/driver.h index 61425597eb61..650d909c9c4f 100644 --- a/sound/usb/line6/driver.h +++ b/sound/usb/line6/driver.h @@ -178,11 +178,15 @@ struct usb_line6 { fifo; } messages; + /* Work for delayed PCM startup */ + struct delayed_work startup_work; + /* If MIDI is supported, buffer_message contains the pre-processed data; * otherwise the data is only in urb_listen (buffer_incoming). */ void (*process_message)(struct usb_line6 *); void (*disconnect)(struct usb_line6 *line6); + void (*startup)(struct usb_line6 *line6); }; extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, |