aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/core/control_compat.c90
-rw-r--r--sound/core/pcm_compat.c177
-rw-r--r--sound/core/rawmidi_compat.c56
-rw-r--r--sound/core/seq/oss/seq_oss.c2
-rw-r--r--sound/core/seq/oss/seq_oss_device.h1
-rw-r--r--sound/core/seq/oss/seq_oss_init.c16
-rw-r--r--sound/core/timer_compat.c18
-rw-r--r--sound/pci/hda/patch_hdmi.c19
-rw-r--r--sound/pci/hda/patch_realtek.c1
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c16
-rw-r--r--sound/usb/quirks.c1
12 files changed, 348 insertions, 53 deletions
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
index b9c0910fb8c4..0608f216f359 100644
--- a/sound/core/control_compat.c
+++ b/sound/core/control_compat.c
@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
170 unsigned char reserved[128]; 170 unsigned char reserved[128];
171}; 171};
172 172
173#ifdef CONFIG_X86_X32
174/* x32 has a different alignment for 64bit values from ia32 */
175struct snd_ctl_elem_value_x32 {
176 struct snd_ctl_elem_id id;
177 unsigned int indirect; /* bit-field causes misalignment */
178 union {
179 s32 integer[128];
180 unsigned char data[512];
181 s64 integer64[64];
182 } value;
183 unsigned char reserved[128];
184};
185#endif /* CONFIG_X86_X32 */
173 186
174/* get the value type and count of the control */ 187/* get the value type and count of the control */
175static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, 188static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
@@ -219,9 +232,11 @@ static int get_elem_size(int type, int count)
219 232
220static int copy_ctl_value_from_user(struct snd_card *card, 233static int copy_ctl_value_from_user(struct snd_card *card,
221 struct snd_ctl_elem_value *data, 234 struct snd_ctl_elem_value *data,
222 struct snd_ctl_elem_value32 __user *data32, 235 void __user *userdata,
236 void __user *valuep,
223 int *typep, int *countp) 237 int *typep, int *countp)
224{ 238{
239 struct snd_ctl_elem_value32 __user *data32 = userdata;
225 int i, type, size; 240 int i, type, size;
226 int uninitialized_var(count); 241 int uninitialized_var(count);
227 unsigned int indirect; 242 unsigned int indirect;
@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(struct snd_card *card,
239 if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || 254 if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
240 type == SNDRV_CTL_ELEM_TYPE_INTEGER) { 255 type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
241 for (i = 0; i < count; i++) { 256 for (i = 0; i < count; i++) {
257 s32 __user *intp = valuep;
242 int val; 258 int val;
243 if (get_user(val, &data32->value.integer[i])) 259 if (get_user(val, &intp[i]))
244 return -EFAULT; 260 return -EFAULT;
245 data->value.integer.value[i] = val; 261 data->value.integer.value[i] = val;
246 } 262 }
@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
250 dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type); 266 dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
251 return -EINVAL; 267 return -EINVAL;
252 } 268 }
253 if (copy_from_user(data->value.bytes.data, 269 if (copy_from_user(data->value.bytes.data, valuep, size))
254 data32->value.data, size))
255 return -EFAULT; 270 return -EFAULT;
256 } 271 }
257 272
@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
261} 276}
262 277
263/* restore the value to 32bit */ 278/* restore the value to 32bit */
264static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32, 279static int copy_ctl_value_to_user(void __user *userdata,
280 void __user *valuep,
265 struct snd_ctl_elem_value *data, 281 struct snd_ctl_elem_value *data,
266 int type, int count) 282 int type, int count)
267{ 283{
@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
270 if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || 286 if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
271 type == SNDRV_CTL_ELEM_TYPE_INTEGER) { 287 type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
272 for (i = 0; i < count; i++) { 288 for (i = 0; i < count; i++) {
289 s32 __user *intp = valuep;
273 int val; 290 int val;
274 val = data->value.integer.value[i]; 291 val = data->value.integer.value[i];
275 if (put_user(val, &data32->value.integer[i])) 292 if (put_user(val, &intp[i]))
276 return -EFAULT; 293 return -EFAULT;
277 } 294 }
278 } else { 295 } else {
279 size = get_elem_size(type, count); 296 size = get_elem_size(type, count);
280 if (copy_to_user(data32->value.data, 297 if (copy_to_user(valuep, data->value.bytes.data, size))
281 data->value.bytes.data, size))
282 return -EFAULT; 298 return -EFAULT;
283 } 299 }
284 return 0; 300 return 0;
285} 301}
286 302
287static int snd_ctl_elem_read_user_compat(struct snd_card *card, 303static int ctl_elem_read_user(struct snd_card *card,
288 struct snd_ctl_elem_value32 __user *data32) 304 void __user *userdata, void __user *valuep)
289{ 305{
290 struct snd_ctl_elem_value *data; 306 struct snd_ctl_elem_value *data;
291 int err, type, count; 307 int err, type, count;
@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
294 if (data == NULL) 310 if (data == NULL)
295 return -ENOMEM; 311 return -ENOMEM;
296 312
297 if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) 313 err = copy_ctl_value_from_user(card, data, userdata, valuep,
314 &type, &count);
315 if (err < 0)
298 goto error; 316 goto error;
299 317
300 snd_power_lock(card); 318 snd_power_lock(card);
@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
303 err = snd_ctl_elem_read(card, data); 321 err = snd_ctl_elem_read(card, data);
304 snd_power_unlock(card); 322 snd_power_unlock(card);
305 if (err >= 0) 323 if (err >= 0)
306 err = copy_ctl_value_to_user(data32, data, type, count); 324 err = copy_ctl_value_to_user(userdata, valuep, data,
325 type, count);
307 error: 326 error:
308 kfree(data); 327 kfree(data);
309 return err; 328 return err;
310} 329}
311 330
312static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file, 331static int ctl_elem_write_user(struct snd_ctl_file *file,
313 struct snd_ctl_elem_value32 __user *data32) 332 void __user *userdata, void __user *valuep)
314{ 333{
315 struct snd_ctl_elem_value *data; 334 struct snd_ctl_elem_value *data;
316 struct snd_card *card = file->card; 335 struct snd_card *card = file->card;
@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
320 if (data == NULL) 339 if (data == NULL)
321 return -ENOMEM; 340 return -ENOMEM;
322 341
323 if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0) 342 err = copy_ctl_value_from_user(card, data, userdata, valuep,
343 &type, &count);
344 if (err < 0)
324 goto error; 345 goto error;
325 346
326 snd_power_lock(card); 347 snd_power_lock(card);
@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
329 err = snd_ctl_elem_write(card, file, data); 350 err = snd_ctl_elem_write(card, file, data);
330 snd_power_unlock(card); 351 snd_power_unlock(card);
331 if (err >= 0) 352 if (err >= 0)
332 err = copy_ctl_value_to_user(data32, data, type, count); 353 err = copy_ctl_value_to_user(userdata, valuep, data,
354 type, count);
333 error: 355 error:
334 kfree(data); 356 kfree(data);
335 return err; 357 return err;
336} 358}
337 359
360static int snd_ctl_elem_read_user_compat(struct snd_card *card,
361 struct snd_ctl_elem_value32 __user *data32)
362{
363 return ctl_elem_read_user(card, data32, &data32->value);
364}
365
366static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
367 struct snd_ctl_elem_value32 __user *data32)
368{
369 return ctl_elem_write_user(file, data32, &data32->value);
370}
371
372#ifdef CONFIG_X86_X32
373static int snd_ctl_elem_read_user_x32(struct snd_card *card,
374 struct snd_ctl_elem_value_x32 __user *data32)
375{
376 return ctl_elem_read_user(card, data32, &data32->value);
377}
378
379static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
380 struct snd_ctl_elem_value_x32 __user *data32)
381{
382 return ctl_elem_write_user(file, data32, &data32->value);
383}
384#endif /* CONFIG_X86_X32 */
385
338/* add or replace a user control */ 386/* add or replace a user control */
339static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, 387static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
340 struct snd_ctl_elem_info32 __user *data32, 388 struct snd_ctl_elem_info32 __user *data32,
@@ -393,6 +441,10 @@ enum {
393 SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32), 441 SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
394 SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32), 442 SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
395 SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32), 443 SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
444#ifdef CONFIG_X86_X32
445 SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
446 SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
447#endif /* CONFIG_X86_X32 */
396}; 448};
397 449
398static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 450static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
431 return snd_ctl_elem_add_compat(ctl, argp, 0); 483 return snd_ctl_elem_add_compat(ctl, argp, 0);
432 case SNDRV_CTL_IOCTL_ELEM_REPLACE32: 484 case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
433 return snd_ctl_elem_add_compat(ctl, argp, 1); 485 return snd_ctl_elem_add_compat(ctl, argp, 1);
486#ifdef CONFIG_X86_X32
487 case SNDRV_CTL_IOCTL_ELEM_READ_X32:
488 return snd_ctl_elem_read_user_x32(ctl->card, argp);
489 case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
490 return snd_ctl_elem_write_user_x32(ctl, argp);
491#endif /* CONFIG_X86_X32 */
434 } 492 }
435 493
436 down_read(&snd_ioctl_rwsem); 494 down_read(&snd_ioctl_rwsem);
diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
index 9630e9f72b7b..1f64ab0c2a95 100644
--- a/sound/core/pcm_compat.c
+++ b/sound/core/pcm_compat.c
@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
183 return err; 183 return err;
184} 184}
185 185
186#ifdef CONFIG_X86_X32
187/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
188static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
189 struct snd_pcm_channel_info __user *src);
190#define snd_pcm_ioctl_channel_info_x32(s, p) \
191 snd_pcm_channel_info_user(s, p)
192#endif /* CONFIG_X86_X32 */
193
186struct snd_pcm_status32 { 194struct snd_pcm_status32 {
187 s32 state; 195 s32 state;
188 struct compat_timespec trigger_tstamp; 196 struct compat_timespec trigger_tstamp;
@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
243 return err; 251 return err;
244} 252}
245 253
254#ifdef CONFIG_X86_X32
255/* X32 ABI has 64bit timespec and 64bit alignment */
256struct snd_pcm_status_x32 {
257 s32 state;
258 u32 rsvd; /* alignment */
259 struct timespec trigger_tstamp;
260 struct timespec tstamp;
261 u32 appl_ptr;
262 u32 hw_ptr;
263 s32 delay;
264 u32 avail;
265 u32 avail_max;
266 u32 overrange;
267 s32 suspended_state;
268 u32 audio_tstamp_data;
269 struct timespec audio_tstamp;
270 struct timespec driver_tstamp;
271 u32 audio_tstamp_accuracy;
272 unsigned char reserved[52-2*sizeof(struct timespec)];
273} __packed;
274
275#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
276
277static int snd_pcm_status_user_x32(struct snd_pcm_substream *substream,
278 struct snd_pcm_status_x32 __user *src,
279 bool ext)
280{
281 struct snd_pcm_status status;
282 int err;
283
284 memset(&status, 0, sizeof(status));
285 /*
286 * with extension, parameters are read/write,
287 * get audio_tstamp_data from user,
288 * ignore rest of status structure
289 */
290 if (ext && get_user(status.audio_tstamp_data,
291 (u32 __user *)(&src->audio_tstamp_data)))
292 return -EFAULT;
293 err = snd_pcm_status(substream, &status);
294 if (err < 0)
295 return err;
296
297 if (clear_user(src, sizeof(*src)))
298 return -EFAULT;
299 if (put_user(status.state, &src->state) ||
300 put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
301 put_timespec(&status.tstamp, &src->tstamp) ||
302 put_user(status.appl_ptr, &src->appl_ptr) ||
303 put_user(status.hw_ptr, &src->hw_ptr) ||
304 put_user(status.delay, &src->delay) ||
305 put_user(status.avail, &src->avail) ||
306 put_user(status.avail_max, &src->avail_max) ||
307 put_user(status.overrange, &src->overrange) ||
308 put_user(status.suspended_state, &src->suspended_state) ||
309 put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
310 put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
311 put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
312 put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
313 return -EFAULT;
314
315 return err;
316}
317#endif /* CONFIG_X86_X32 */
318
246/* both for HW_PARAMS and HW_REFINE */ 319/* both for HW_PARAMS and HW_REFINE */
247static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, 320static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
248 int refine, 321 int refine,
@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
469 return 0; 542 return 0;
470} 543}
471 544
545#ifdef CONFIG_X86_X32
546/* X32 ABI has 64bit timespec and 64bit alignment */
547struct snd_pcm_mmap_status_x32 {
548 s32 state;
549 s32 pad1;
550 u32 hw_ptr;
551 u32 pad2; /* alignment */
552 struct timespec tstamp;
553 s32 suspended_state;
554 struct timespec audio_tstamp;
555} __packed;
556
557struct snd_pcm_mmap_control_x32 {
558 u32 appl_ptr;
559 u32 avail_min;
560};
561
562struct snd_pcm_sync_ptr_x32 {
563 u32 flags;
564 u32 rsvd; /* alignment */
565 union {
566 struct snd_pcm_mmap_status_x32 status;
567 unsigned char reserved[64];
568 } s;
569 union {
570 struct snd_pcm_mmap_control_x32 control;
571 unsigned char reserved[64];
572 } c;
573} __packed;
574
575static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
576 struct snd_pcm_sync_ptr_x32 __user *src)
577{
578 struct snd_pcm_runtime *runtime = substream->runtime;
579 volatile struct snd_pcm_mmap_status *status;
580 volatile struct snd_pcm_mmap_control *control;
581 u32 sflags;
582 struct snd_pcm_mmap_control scontrol;
583 struct snd_pcm_mmap_status sstatus;
584 snd_pcm_uframes_t boundary;
585 int err;
586
587 if (snd_BUG_ON(!runtime))
588 return -EINVAL;
589
590 if (get_user(sflags, &src->flags) ||
591 get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
592 get_user(scontrol.avail_min, &src->c.control.avail_min))
593 return -EFAULT;
594 if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
595 err = snd_pcm_hwsync(substream);
596 if (err < 0)
597 return err;
598 }
599 status = runtime->status;
600 control = runtime->control;
601 boundary = recalculate_boundary(runtime);
602 if (!boundary)
603 boundary = 0x7fffffff;
604 snd_pcm_stream_lock_irq(substream);
605 /* FIXME: we should consider the boundary for the sync from app */
606 if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
607 control->appl_ptr = scontrol.appl_ptr;
608 else
609 scontrol.appl_ptr = control->appl_ptr % boundary;
610 if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
611 control->avail_min = scontrol.avail_min;
612 else
613 scontrol.avail_min = control->avail_min;
614 sstatus.state = status->state;
615 sstatus.hw_ptr = status->hw_ptr % boundary;
616 sstatus.tstamp = status->tstamp;
617 sstatus.suspended_state = status->suspended_state;
618 sstatus.audio_tstamp = status->audio_tstamp;
619 snd_pcm_stream_unlock_irq(substream);
620 if (put_user(sstatus.state, &src->s.status.state) ||
621 put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
622 put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
623 put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
624 put_timespec(&sstatus.audio_tstamp, &src->s.status.audio_tstamp) ||
625 put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
626 put_user(scontrol.avail_min, &src->c.control.avail_min))
627 return -EFAULT;
628
629 return 0;
630}
631#endif /* CONFIG_X86_X32 */
472 632
473/* 633/*
474 */ 634 */
@@ -487,7 +647,12 @@ enum {
487 SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32), 647 SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
488 SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32), 648 SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
489 SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32), 649 SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
490 650#ifdef CONFIG_X86_X32
651 SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
652 SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32),
653 SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32),
654 SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
655#endif /* CONFIG_X86_X32 */
491}; 656};
492 657
493static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 658static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
559 return snd_pcm_ioctl_rewind_compat(substream, argp); 724 return snd_pcm_ioctl_rewind_compat(substream, argp);
560 case SNDRV_PCM_IOCTL_FORWARD32: 725 case SNDRV_PCM_IOCTL_FORWARD32:
561 return snd_pcm_ioctl_forward_compat(substream, argp); 726 return snd_pcm_ioctl_forward_compat(substream, argp);
727#ifdef CONFIG_X86_X32
728 case SNDRV_PCM_IOCTL_STATUS_X32:
729 return snd_pcm_status_user_x32(substream, argp, false);
730 case SNDRV_PCM_IOCTL_STATUS_EXT_X32:
731 return snd_pcm_status_user_x32(substream, argp, true);
732 case SNDRV_PCM_IOCTL_SYNC_PTR_X32:
733 return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
734 case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
735 return snd_pcm_ioctl_channel_info_x32(substream, argp);
736#endif /* CONFIG_X86_X32 */
562 } 737 }
563 738
564 return -ENOIOCTLCMD; 739 return -ENOIOCTLCMD;
diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
index 5268c1f58c25..f69764d7cdd7 100644
--- a/sound/core/rawmidi_compat.c
+++ b/sound/core/rawmidi_compat.c
@@ -85,8 +85,7 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
85 if (err < 0) 85 if (err < 0)
86 return err; 86 return err;
87 87
88 if (put_user(status.tstamp.tv_sec, &src->tstamp.tv_sec) || 88 if (compat_put_timespec(&status.tstamp, &src->tstamp) ||
89 put_user(status.tstamp.tv_nsec, &src->tstamp.tv_nsec) ||
90 put_user(status.avail, &src->avail) || 89 put_user(status.avail, &src->avail) ||
91 put_user(status.xruns, &src->xruns)) 90 put_user(status.xruns, &src->xruns))
92 return -EFAULT; 91 return -EFAULT;
@@ -94,9 +93,58 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
94 return 0; 93 return 0;
95} 94}
96 95
96#ifdef CONFIG_X86_X32
97/* X32 ABI has 64bit timespec and 64bit alignment */
98struct snd_rawmidi_status_x32 {
99 s32 stream;
100 u32 rsvd; /* alignment */
101 struct timespec tstamp;
102 u32 avail;
103 u32 xruns;
104 unsigned char reserved[16];
105} __attribute__((packed));
106
107#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
108
109static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
110 struct snd_rawmidi_status_x32 __user *src)
111{
112 int err;
113 struct snd_rawmidi_status status;
114
115 if (rfile->output == NULL)
116 return -EINVAL;
117 if (get_user(status.stream, &src->stream))
118 return -EFAULT;
119
120 switch (status.stream) {
121 case SNDRV_RAWMIDI_STREAM_OUTPUT:
122 err = snd_rawmidi_output_status(rfile->output, &status);
123 break;
124 case SNDRV_RAWMIDI_STREAM_INPUT:
125 err = snd_rawmidi_input_status(rfile->input, &status);
126 break;
127 default:
128 return -EINVAL;
129 }
130 if (err < 0)
131 return err;
132
133 if (put_timespec(&status.tstamp, &src->tstamp) ||
134 put_user(status.avail, &src->avail) ||
135 put_user(status.xruns, &src->xruns))
136 return -EFAULT;
137
138 return 0;
139}
140#endif /* CONFIG_X86_X32 */
141
97enum { 142enum {
98 SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32), 143 SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
99 SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32), 144 SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
145#ifdef CONFIG_X86_X32
146 SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32),
147#endif /* CONFIG_X86_X32 */
100}; 148};
101 149
102static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 150static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -115,6 +163,10 @@ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsign
115 return snd_rawmidi_ioctl_params_compat(rfile, argp); 163 return snd_rawmidi_ioctl_params_compat(rfile, argp);
116 case SNDRV_RAWMIDI_IOCTL_STATUS32: 164 case SNDRV_RAWMIDI_IOCTL_STATUS32:
117 return snd_rawmidi_ioctl_status_compat(rfile, argp); 165 return snd_rawmidi_ioctl_status_compat(rfile, argp);
166#ifdef CONFIG_X86_X32
167 case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
168 return snd_rawmidi_ioctl_status_x32(rfile, argp);
169#endif /* CONFIG_X86_X32 */
118 } 170 }
119 return -ENOIOCTLCMD; 171 return -ENOIOCTLCMD;
120} 172}
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 8db156b207f1..8cdf489df80e 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -149,8 +149,6 @@ odev_release(struct inode *inode, struct file *file)
149 if ((dp = file->private_data) == NULL) 149 if ((dp = file->private_data) == NULL)
150 return 0; 150 return 0;
151 151
152 snd_seq_oss_drain_write(dp);
153
154 mutex_lock(&register_mutex); 152 mutex_lock(&register_mutex);
155 snd_seq_oss_release(dp); 153 snd_seq_oss_release(dp);
156 mutex_unlock(&register_mutex); 154 mutex_unlock(&register_mutex);
diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
index b43924325249..d7b4d016b547 100644
--- a/sound/core/seq/oss/seq_oss_device.h
+++ b/sound/core/seq/oss/seq_oss_device.h
@@ -127,7 +127,6 @@ int snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int co
127unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait); 127unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
128 128
129void snd_seq_oss_reset(struct seq_oss_devinfo *dp); 129void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
130void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
131 130
132/* */ 131/* */
133void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time); 132void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
index 6779e82b46dd..92c96a95a903 100644
--- a/sound/core/seq/oss/seq_oss_init.c
+++ b/sound/core/seq/oss/seq_oss_init.c
@@ -436,22 +436,6 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp)
436 436
437 437
438/* 438/*
439 * Wait until the queue is empty (if we don't have nonblock)
440 */
441void
442snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
443{
444 if (! dp->timer->running)
445 return;
446 if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
447 dp->writeq) {
448 while (snd_seq_oss_writeq_sync(dp->writeq))
449 ;
450 }
451}
452
453
454/*
455 * reset sequencer devices 439 * reset sequencer devices
456 */ 440 */
457void 441void
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index e05802ae6e1b..2e908225d754 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(struct file *file,
70 struct snd_timer_status32 __user *_status) 70 struct snd_timer_status32 __user *_status)
71{ 71{
72 struct snd_timer_user *tu; 72 struct snd_timer_user *tu;
73 struct snd_timer_status status; 73 struct snd_timer_status32 status;
74 74
75 tu = file->private_data; 75 tu = file->private_data;
76 if (snd_BUG_ON(!tu->timeri)) 76 if (snd_BUG_ON(!tu->timeri))
77 return -ENXIO; 77 return -ENXIO;
78 memset(&status, 0, sizeof(status)); 78 memset(&status, 0, sizeof(status));
79 status.tstamp = tu->tstamp; 79 status.tstamp.tv_sec = tu->tstamp.tv_sec;
80 status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
80 status.resolution = snd_timer_resolution(tu->timeri); 81 status.resolution = snd_timer_resolution(tu->timeri);
81 status.lost = tu->timeri->lost; 82 status.lost = tu->timeri->lost;
82 status.overrun = tu->overrun; 83 status.overrun = tu->overrun;
@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(struct file *file,
88 return 0; 89 return 0;
89} 90}
90 91
92#ifdef CONFIG_X86_X32
93/* X32 ABI has the same struct as x86-64 */
94#define snd_timer_user_status_x32(file, s) \
95 snd_timer_user_status(file, s)
96#endif /* CONFIG_X86_X32 */
97
91/* 98/*
92 */ 99 */
93 100
94enum { 101enum {
95 SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32), 102 SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
96 SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32), 103 SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
104#ifdef CONFIG_X86_X32
105 SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status),
106#endif /* CONFIG_X86_X32 */
97}; 107};
98 108
99static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg) 109static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
122 return snd_timer_user_info_compat(file, argp); 132 return snd_timer_user_info_compat(file, argp);
123 case SNDRV_TIMER_IOCTL_STATUS32: 133 case SNDRV_TIMER_IOCTL_STATUS32:
124 return snd_timer_user_status_compat(file, argp); 134 return snd_timer_user_status_compat(file, argp);
135#ifdef CONFIG_X86_X32
136 case SNDRV_TIMER_IOCTL_STATUS_X32:
137 return snd_timer_user_status_x32(file, argp);
138#endif /* CONFIG_X86_X32 */
125 } 139 }
126 return -ENOIOCTLCMD; 140 return -ENOIOCTLCMD;
127} 141}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8ee78dbd4c60..bcbc4ee10130 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2477,13 +2477,6 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2477 is_broxton(codec)) 2477 is_broxton(codec))
2478 codec->core.link_power_control = 1; 2478 codec->core.link_power_control = 1;
2479 2479
2480 if (codec_has_acomp(codec)) {
2481 codec->depop_delay = 0;
2482 spec->i915_audio_ops.audio_ptr = codec;
2483 spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
2484 snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
2485 }
2486
2487 if (hdmi_parse_codec(codec) < 0) { 2480 if (hdmi_parse_codec(codec) < 0) {
2488 if (spec->i915_bound) 2481 if (spec->i915_bound)
2489 snd_hdac_i915_exit(&codec->bus->core); 2482 snd_hdac_i915_exit(&codec->bus->core);
@@ -2505,6 +2498,18 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2505 2498
2506 init_channel_allocations(); 2499 init_channel_allocations();
2507 2500
2501 if (codec_has_acomp(codec)) {
2502 codec->depop_delay = 0;
2503 spec->i915_audio_ops.audio_ptr = codec;
2504 /* intel_audio_codec_enable() or intel_audio_codec_disable()
2505 * will call pin_eld_notify with using audio_ptr pointer
2506 * We need make sure audio_ptr is really setup
2507 */
2508 wmb();
2509 spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
2510 snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
2511 }
2512
2508 return 0; 2513 return 0;
2509} 2514}
2510 2515
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1f357cd72d9c..93d2156b6241 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5412,6 +5412,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5412 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), 5412 SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
5413 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 5413 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
5414 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 5414 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
5415 SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5415 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), 5416 SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
5416 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), 5417 SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
5417 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK), 5418 SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 2875b4f6d8c9..7c8941b8b2de 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -2879,7 +2879,7 @@ static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
2879{ 2879{
2880 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); 2880 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
2881 2881
2882 ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); 2882 ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
2883 return 0; 2883 return 0;
2884} 2884}
2885 2885
@@ -2891,7 +2891,7 @@ static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
2891 2891
2892 if (!snd_hdsp_use_is_exclusive(hdsp)) 2892 if (!snd_hdsp_use_is_exclusive(hdsp))
2893 return -EBUSY; 2893 return -EBUSY;
2894 val = ucontrol->value.enumerated.item[0]; 2894 val = ucontrol->value.integer.value[0];
2895 spin_lock_irq(&hdsp->lock); 2895 spin_lock_irq(&hdsp->lock);
2896 if (val != hdsp_dds_offset(hdsp)) 2896 if (val != hdsp_dds_offset(hdsp))
2897 change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; 2897 change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 8bc8016c173d..a4a999a0317e 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1601,6 +1601,9 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
1601{ 1601{
1602 u64 n; 1602 u64 n;
1603 1603
1604 if (snd_BUG_ON(rate <= 0))
1605 return;
1606
1604 if (rate >= 112000) 1607 if (rate >= 112000)
1605 rate /= 4; 1608 rate /= 4;
1606 else if (rate >= 56000) 1609 else if (rate >= 56000)
@@ -2215,6 +2218,8 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
2215 } else { 2218 } else {
2216 /* slave mode, return external sample rate */ 2219 /* slave mode, return external sample rate */
2217 rate = hdspm_external_sample_rate(hdspm); 2220 rate = hdspm_external_sample_rate(hdspm);
2221 if (!rate)
2222 rate = hdspm->system_sample_rate;
2218 } 2223 }
2219 } 2224 }
2220 2225
@@ -2260,8 +2265,11 @@ static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
2260 ucontrol) 2265 ucontrol)
2261{ 2266{
2262 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2267 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2268 int rate = ucontrol->value.integer.value[0];
2263 2269
2264 hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]); 2270 if (rate < 27000 || rate > 207000)
2271 return -EINVAL;
2272 hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
2265 return 0; 2273 return 0;
2266} 2274}
2267 2275
@@ -4449,7 +4457,7 @@ static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
4449{ 4457{
4450 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 4458 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4451 4459
4452 ucontrol->value.enumerated.item[0] = hdspm->tco->term; 4460 ucontrol->value.integer.value[0] = hdspm->tco->term;
4453 4461
4454 return 0; 4462 return 0;
4455} 4463}
@@ -4460,8 +4468,8 @@ static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
4460{ 4468{
4461 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 4469 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
4462 4470
4463 if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) { 4471 if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
4464 hdspm->tco->term = ucontrol->value.enumerated.item[0]; 4472 hdspm->tco->term = ucontrol->value.integer.value[0];
4465 4473
4466 hdspm_tco_write(hdspm); 4474 hdspm_tco_write(hdspm);
4467 4475
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 4f6ce1cac8e2..c458d60d5030 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1124,6 +1124,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
1124 case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ 1124 case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
1125 case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ 1125 case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
1126 case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ 1126 case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
1127 case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
1127 case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */ 1128 case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
1128 case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ 1129 case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
1129 case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */ 1130 case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */