summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-09 12:58:11 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-09 12:58:11 -0500
commitd93d4ce103fdd6c6689e94cfbd0316b027d6ead2 (patch)
tree7d28acab8905fc77005b0d09ef4c8bcb0ff45a29
parentd1041cdc60bc122aac09f822aad1ff6c5cb84406 (diff)
parent75ee94b20b46459e3d29f5ac2c3af3cebdeef777 (diff)
Merge tag 'sound-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "The amount of the changes isn't as quite small as wished, nevertheless they are straight fixes that deserve merging to 4.14 final. Most of fixes are about ALSA core bugs spotted by fuzzer: a follow-up fix for the previous nested rwsem patch, a fix to avoid the resource hogs due to too many concurrent ALSA timer invocations, and a fix for a crash with SYSEX MIDI transfer over OSS sequencer emulation that is used by none but fuzzer. The rest are usual HD-audio and USB-audio device-specific quirks, which are safe to apply" * tag 'sound-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda - fix headset mic problem for Dell machines with alc274 ALSA: seq: Fix OSS sysex delivery in OSS emulation ALSA: seq: Avoid invalid lockdep class warning ALSA: timer: Limit max instances per timer ALSA: usb-audio: support new Amanero Combo384 firmware version
-rw-r--r--include/sound/seq_kernel.h3
-rw-r--r--include/sound/timer.h2
-rw-r--r--sound/core/hrtimer.c1
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c4
-rw-r--r--sound/core/seq/oss/seq_oss_readq.c29
-rw-r--r--sound/core/seq/oss/seq_oss_readq.h2
-rw-r--r--sound/core/timer.c67
-rw-r--r--sound/pci/hda/patch_realtek.c5
-rw-r--r--sound/usb/quirks.c1
9 files changed, 97 insertions, 17 deletions
diff --git a/include/sound/seq_kernel.h b/include/sound/seq_kernel.h
index feb58d455560..4b9ee3009aa0 100644
--- a/include/sound/seq_kernel.h
+++ b/include/sound/seq_kernel.h
@@ -49,7 +49,8 @@ typedef union snd_seq_timestamp snd_seq_timestamp_t;
49#define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200 49#define SNDRV_SEQ_DEFAULT_CLIENT_EVENTS 200
50 50
51/* max delivery path length */ 51/* max delivery path length */
52#define SNDRV_SEQ_MAX_HOPS 10 52/* NOTE: this shouldn't be greater than MAX_LOCKDEP_SUBCLASSES */
53#define SNDRV_SEQ_MAX_HOPS 8
53 54
54/* max size of event size */ 55/* max size of event size */
55#define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff 56#define SNDRV_SEQ_MAX_EVENT_LEN 0x3fffffff
diff --git a/include/sound/timer.h b/include/sound/timer.h
index c4d76ff056c6..7ae226ab6990 100644
--- a/include/sound/timer.h
+++ b/include/sound/timer.h
@@ -90,6 +90,8 @@ struct snd_timer {
90 struct list_head ack_list_head; 90 struct list_head ack_list_head;
91 struct list_head sack_list_head; /* slow ack list head */ 91 struct list_head sack_list_head; /* slow ack list head */
92 struct tasklet_struct task_queue; 92 struct tasklet_struct task_queue;
93 int max_instances; /* upper limit of timer instances */
94 int num_instances; /* current number of timer instances */
93}; 95};
94 96
95struct snd_timer_instance { 97struct snd_timer_instance {
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 1ac0c423903e..6e47b823bcaa 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -159,6 +159,7 @@ static int __init snd_hrtimer_init(void)
159 timer->hw = hrtimer_hw; 159 timer->hw = hrtimer_hw;
160 timer->hw.resolution = resolution; 160 timer->hw.resolution = resolution;
161 timer->hw.ticks = NANO_SEC / resolution; 161 timer->hw.ticks = NANO_SEC / resolution;
162 timer->max_instances = 100; /* lower the limit */
162 163
163 err = snd_timer_global_register(timer); 164 err = snd_timer_global_register(timer);
164 if (err < 0) { 165 if (err < 0) {
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index aaff9ee32695..b30b2139e3f0 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -612,9 +612,7 @@ send_midi_event(struct seq_oss_devinfo *dp, struct snd_seq_event *ev, struct seq
612 if (!dp->timer->running) 612 if (!dp->timer->running)
613 len = snd_seq_oss_timer_start(dp->timer); 613 len = snd_seq_oss_timer_start(dp->timer);
614 if (ev->type == SNDRV_SEQ_EVENT_SYSEX) { 614 if (ev->type == SNDRV_SEQ_EVENT_SYSEX) {
615 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) == SNDRV_SEQ_EVENT_LENGTH_VARIABLE) 615 snd_seq_oss_readq_sysex(dp->readq, mdev->seq_device, ev);
616 snd_seq_oss_readq_puts(dp->readq, mdev->seq_device,
617 ev->data.ext.ptr, ev->data.ext.len);
618 } else { 616 } else {
619 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev); 617 len = snd_midi_event_decode(mdev->coder, msg, sizeof(msg), ev);
620 if (len > 0) 618 if (len > 0)
diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c
index 046cb586fb2f..06b21226b4e7 100644
--- a/sound/core/seq/oss/seq_oss_readq.c
+++ b/sound/core/seq/oss/seq_oss_readq.c
@@ -118,6 +118,35 @@ snd_seq_oss_readq_puts(struct seq_oss_readq *q, int dev, unsigned char *data, in
118} 118}
119 119
120/* 120/*
121 * put MIDI sysex bytes; the event buffer may be chained, thus it has
122 * to be expanded via snd_seq_dump_var_event().
123 */
124struct readq_sysex_ctx {
125 struct seq_oss_readq *readq;
126 int dev;
127};
128
129static int readq_dump_sysex(void *ptr, void *buf, int count)
130{
131 struct readq_sysex_ctx *ctx = ptr;
132
133 return snd_seq_oss_readq_puts(ctx->readq, ctx->dev, buf, count);
134}
135
136int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
137 struct snd_seq_event *ev)
138{
139 struct readq_sysex_ctx ctx = {
140 .readq = q,
141 .dev = dev
142 };
143
144 if ((ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) != SNDRV_SEQ_EVENT_LENGTH_VARIABLE)
145 return 0;
146 return snd_seq_dump_var_event(ev, readq_dump_sysex, &ctx);
147}
148
149/*
121 * copy an event to input queue: 150 * copy an event to input queue:
122 * return zero if enqueued 151 * return zero if enqueued
123 */ 152 */
diff --git a/sound/core/seq/oss/seq_oss_readq.h b/sound/core/seq/oss/seq_oss_readq.h
index f1463f1f449e..8d033ca2d23f 100644
--- a/sound/core/seq/oss/seq_oss_readq.h
+++ b/sound/core/seq/oss/seq_oss_readq.h
@@ -44,6 +44,8 @@ void snd_seq_oss_readq_delete(struct seq_oss_readq *q);
44void snd_seq_oss_readq_clear(struct seq_oss_readq *readq); 44void snd_seq_oss_readq_clear(struct seq_oss_readq *readq);
45unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait); 45unsigned int snd_seq_oss_readq_poll(struct seq_oss_readq *readq, struct file *file, poll_table *wait);
46int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len); 46int snd_seq_oss_readq_puts(struct seq_oss_readq *readq, int dev, unsigned char *data, int len);
47int snd_seq_oss_readq_sysex(struct seq_oss_readq *q, int dev,
48 struct snd_seq_event *ev);
47int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev); 49int snd_seq_oss_readq_put_event(struct seq_oss_readq *readq, union evrec *ev);
48int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode); 50int snd_seq_oss_readq_put_timestamp(struct seq_oss_readq *readq, unsigned long curt, int seq_mode);
49int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec); 51int snd_seq_oss_readq_pick(struct seq_oss_readq *q, union evrec *rec);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 6cdd04a45962..15e82a656d96 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -180,7 +180,7 @@ static void snd_timer_request(struct snd_timer_id *tid)
180 * 180 *
181 * call this with register_mutex down. 181 * call this with register_mutex down.
182 */ 182 */
183static void snd_timer_check_slave(struct snd_timer_instance *slave) 183static int snd_timer_check_slave(struct snd_timer_instance *slave)
184{ 184{
185 struct snd_timer *timer; 185 struct snd_timer *timer;
186 struct snd_timer_instance *master; 186 struct snd_timer_instance *master;
@@ -190,16 +190,21 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
190 list_for_each_entry(master, &timer->open_list_head, open_list) { 190 list_for_each_entry(master, &timer->open_list_head, open_list) {
191 if (slave->slave_class == master->slave_class && 191 if (slave->slave_class == master->slave_class &&
192 slave->slave_id == master->slave_id) { 192 slave->slave_id == master->slave_id) {
193 if (master->timer->num_instances >=
194 master->timer->max_instances)
195 return -EBUSY;
193 list_move_tail(&slave->open_list, 196 list_move_tail(&slave->open_list,
194 &master->slave_list_head); 197 &master->slave_list_head);
198 master->timer->num_instances++;
195 spin_lock_irq(&slave_active_lock); 199 spin_lock_irq(&slave_active_lock);
196 slave->master = master; 200 slave->master = master;
197 slave->timer = master->timer; 201 slave->timer = master->timer;
198 spin_unlock_irq(&slave_active_lock); 202 spin_unlock_irq(&slave_active_lock);
199 return; 203 return 0;
200 } 204 }
201 } 205 }
202 } 206 }
207 return 0;
203} 208}
204 209
205/* 210/*
@@ -208,7 +213,7 @@ static void snd_timer_check_slave(struct snd_timer_instance *slave)
208 * 213 *
209 * call this with register_mutex down. 214 * call this with register_mutex down.
210 */ 215 */
211static void snd_timer_check_master(struct snd_timer_instance *master) 216static int snd_timer_check_master(struct snd_timer_instance *master)
212{ 217{
213 struct snd_timer_instance *slave, *tmp; 218 struct snd_timer_instance *slave, *tmp;
214 219
@@ -216,7 +221,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
216 list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) { 221 list_for_each_entry_safe(slave, tmp, &snd_timer_slave_list, open_list) {
217 if (slave->slave_class == master->slave_class && 222 if (slave->slave_class == master->slave_class &&
218 slave->slave_id == master->slave_id) { 223 slave->slave_id == master->slave_id) {
224 if (master->timer->num_instances >=
225 master->timer->max_instances)
226 return -EBUSY;
219 list_move_tail(&slave->open_list, &master->slave_list_head); 227 list_move_tail(&slave->open_list, &master->slave_list_head);
228 master->timer->num_instances++;
220 spin_lock_irq(&slave_active_lock); 229 spin_lock_irq(&slave_active_lock);
221 spin_lock(&master->timer->lock); 230 spin_lock(&master->timer->lock);
222 slave->master = master; 231 slave->master = master;
@@ -228,8 +237,11 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
228 spin_unlock_irq(&slave_active_lock); 237 spin_unlock_irq(&slave_active_lock);
229 } 238 }
230 } 239 }
240 return 0;
231} 241}
232 242
243static int snd_timer_close_locked(struct snd_timer_instance *timeri);
244
233/* 245/*
234 * open a timer instance 246 * open a timer instance
235 * when opening a master, the slave id must be here given. 247 * when opening a master, the slave id must be here given.
@@ -240,6 +252,7 @@ int snd_timer_open(struct snd_timer_instance **ti,
240{ 252{
241 struct snd_timer *timer; 253 struct snd_timer *timer;
242 struct snd_timer_instance *timeri = NULL; 254 struct snd_timer_instance *timeri = NULL;
255 int err;
243 256
244 if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) { 257 if (tid->dev_class == SNDRV_TIMER_CLASS_SLAVE) {
245 /* open a slave instance */ 258 /* open a slave instance */
@@ -259,10 +272,14 @@ int snd_timer_open(struct snd_timer_instance **ti,
259 timeri->slave_id = tid->device; 272 timeri->slave_id = tid->device;
260 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE; 273 timeri->flags |= SNDRV_TIMER_IFLG_SLAVE;
261 list_add_tail(&timeri->open_list, &snd_timer_slave_list); 274 list_add_tail(&timeri->open_list, &snd_timer_slave_list);
262 snd_timer_check_slave(timeri); 275 err = snd_timer_check_slave(timeri);
276 if (err < 0) {
277 snd_timer_close_locked(timeri);
278 timeri = NULL;
279 }
263 mutex_unlock(&register_mutex); 280 mutex_unlock(&register_mutex);
264 *ti = timeri; 281 *ti = timeri;
265 return 0; 282 return err;
266 } 283 }
267 284
268 /* open a master instance */ 285 /* open a master instance */
@@ -288,6 +305,10 @@ int snd_timer_open(struct snd_timer_instance **ti,
288 return -EBUSY; 305 return -EBUSY;
289 } 306 }
290 } 307 }
308 if (timer->num_instances >= timer->max_instances) {
309 mutex_unlock(&register_mutex);
310 return -EBUSY;
311 }
291 timeri = snd_timer_instance_new(owner, timer); 312 timeri = snd_timer_instance_new(owner, timer);
292 if (!timeri) { 313 if (!timeri) {
293 mutex_unlock(&register_mutex); 314 mutex_unlock(&register_mutex);
@@ -314,25 +335,27 @@ int snd_timer_open(struct snd_timer_instance **ti,
314 } 335 }
315 336
316 list_add_tail(&timeri->open_list, &timer->open_list_head); 337 list_add_tail(&timeri->open_list, &timer->open_list_head);
317 snd_timer_check_master(timeri); 338 timer->num_instances++;
339 err = snd_timer_check_master(timeri);
340 if (err < 0) {
341 snd_timer_close_locked(timeri);
342 timeri = NULL;
343 }
318 mutex_unlock(&register_mutex); 344 mutex_unlock(&register_mutex);
319 *ti = timeri; 345 *ti = timeri;
320 return 0; 346 return err;
321} 347}
322EXPORT_SYMBOL(snd_timer_open); 348EXPORT_SYMBOL(snd_timer_open);
323 349
324/* 350/*
325 * close a timer instance 351 * close a timer instance
352 * call this with register_mutex down.
326 */ 353 */
327int snd_timer_close(struct snd_timer_instance *timeri) 354static int snd_timer_close_locked(struct snd_timer_instance *timeri)
328{ 355{
329 struct snd_timer *timer = NULL; 356 struct snd_timer *timer = NULL;
330 struct snd_timer_instance *slave, *tmp; 357 struct snd_timer_instance *slave, *tmp;
331 358
332 if (snd_BUG_ON(!timeri))
333 return -ENXIO;
334
335 mutex_lock(&register_mutex);
336 list_del(&timeri->open_list); 359 list_del(&timeri->open_list);
337 360
338 /* force to stop the timer */ 361 /* force to stop the timer */
@@ -340,6 +363,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
340 363
341 timer = timeri->timer; 364 timer = timeri->timer;
342 if (timer) { 365 if (timer) {
366 timer->num_instances--;
343 /* wait, until the active callback is finished */ 367 /* wait, until the active callback is finished */
344 spin_lock_irq(&timer->lock); 368 spin_lock_irq(&timer->lock);
345 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { 369 while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) {
@@ -355,6 +379,7 @@ int snd_timer_close(struct snd_timer_instance *timeri)
355 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head, 379 list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
356 open_list) { 380 open_list) {
357 list_move_tail(&slave->open_list, &snd_timer_slave_list); 381 list_move_tail(&slave->open_list, &snd_timer_slave_list);
382 timer->num_instances--;
358 slave->master = NULL; 383 slave->master = NULL;
359 slave->timer = NULL; 384 slave->timer = NULL;
360 list_del_init(&slave->ack_list); 385 list_del_init(&slave->ack_list);
@@ -382,9 +407,24 @@ int snd_timer_close(struct snd_timer_instance *timeri)
382 module_put(timer->module); 407 module_put(timer->module);
383 } 408 }
384 409
385 mutex_unlock(&register_mutex);
386 return 0; 410 return 0;
387} 411}
412
413/*
414 * close a timer instance
415 */
416int snd_timer_close(struct snd_timer_instance *timeri)
417{
418 int err;
419
420 if (snd_BUG_ON(!timeri))
421 return -ENXIO;
422
423 mutex_lock(&register_mutex);
424 err = snd_timer_close_locked(timeri);
425 mutex_unlock(&register_mutex);
426 return err;
427}
388EXPORT_SYMBOL(snd_timer_close); 428EXPORT_SYMBOL(snd_timer_close);
389 429
390unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) 430unsigned long snd_timer_resolution(struct snd_timer_instance *timeri)
@@ -856,6 +896,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
856 spin_lock_init(&timer->lock); 896 spin_lock_init(&timer->lock);
857 tasklet_init(&timer->task_queue, snd_timer_tasklet, 897 tasklet_init(&timer->task_queue, snd_timer_tasklet,
858 (unsigned long)timer); 898 (unsigned long)timer);
899 timer->max_instances = 1000; /* default limit per timer */
859 if (card != NULL) { 900 if (card != NULL) {
860 timer->module = card->module; 901 timer->module = card->module;
861 err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops); 902 err = snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 546d515f3c1f..dce0682c5001 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6544,6 +6544,11 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
6544 {0x14, 0x90170110}, 6544 {0x14, 0x90170110},
6545 {0x1b, 0x90a70130}, 6545 {0x1b, 0x90a70130},
6546 {0x21, 0x03211020}), 6546 {0x21, 0x03211020}),
6547 SND_HDA_PIN_QUIRK(0x10ec0274, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
6548 {0x12, 0xb7a60130},
6549 {0x13, 0xb8a61140},
6550 {0x16, 0x90170110},
6551 {0x21, 0x04211020}),
6547 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, 6552 SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
6548 {0x12, 0x90a60130}, 6553 {0x12, 0x90a60130},
6549 {0x14, 0x90170110}, 6554 {0x14, 0x90170110},
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 4f5f18f22974..20624320b753 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1375,6 +1375,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1375 case 0x199: 1375 case 0x199:
1376 return SNDRV_PCM_FMTBIT_DSD_U32_LE; 1376 return SNDRV_PCM_FMTBIT_DSD_U32_LE;
1377 case 0x19b: 1377 case 0x19b:
1378 case 0x203:
1378 return SNDRV_PCM_FMTBIT_DSD_U32_BE; 1379 return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1379 default: 1380 default:
1380 break; 1381 break;