aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-04-02 13:50:41 -0400
committerTakashi Iwai <tiwai@suse.de>2018-04-02 13:50:59 -0400
commitbc334cb61b9ee6e85b9bb01519989a3ae8fe03f6 (patch)
tree34424a812537fe11beeee727b30b19c67193fe36 /sound/core
parent5607dddbfca774fb38bffadcb077fe03aa4ac5c6 (diff)
parentb44d419b98fae759b4f746186b1d1c8d01d962f2 (diff)
Merge branch 'for-next' into for-linus
Preparation for 4.17 merge. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/control.c18
-rw-r--r--sound/core/init.c4
-rw-r--r--sound/core/oss/pcm_oss.c185
-rw-r--r--sound/core/pcm_lib.c8
-rw-r--r--sound/core/pcm_native.c19
-rw-r--r--sound/core/vmaster.c7
6 files changed, 179 insertions, 62 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index 8a77620a3854..69734b0eafd0 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -105,7 +105,7 @@ static void snd_ctl_empty_read_queue(struct snd_ctl_file * ctl)
105{ 105{
106 unsigned long flags; 106 unsigned long flags;
107 struct snd_kctl_event *cread; 107 struct snd_kctl_event *cread;
108 108
109 spin_lock_irqsave(&ctl->read_lock, flags); 109 spin_lock_irqsave(&ctl->read_lock, flags);
110 while (!list_empty(&ctl->events)) { 110 while (!list_empty(&ctl->events)) {
111 cread = snd_kctl_event(ctl->events.next); 111 cread = snd_kctl_event(ctl->events.next);
@@ -159,7 +159,7 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
159 unsigned long flags; 159 unsigned long flags;
160 struct snd_ctl_file *ctl; 160 struct snd_ctl_file *ctl;
161 struct snd_kctl_event *ev; 161 struct snd_kctl_event *ev;
162 162
163 if (snd_BUG_ON(!card || !id)) 163 if (snd_BUG_ON(!card || !id))
164 return; 164 return;
165 if (card->shutdown) 165 if (card->shutdown)
@@ -213,7 +213,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count,
213{ 213{
214 unsigned int size; 214 unsigned int size;
215 unsigned int idx; 215 unsigned int idx;
216 216
217 if (count == 0 || count > MAX_CONTROL_COUNT) 217 if (count == 0 || count > MAX_CONTROL_COUNT)
218 return -EINVAL; 218 return -EINVAL;
219 219
@@ -238,7 +238,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count,
238 * @ncontrol: the initialization record 238 * @ncontrol: the initialization record
239 * @private_data: the private data to set 239 * @private_data: the private data to set
240 * 240 *
241 * Allocates a new struct snd_kcontrol instance and initialize from the given 241 * Allocates a new struct snd_kcontrol instance and initialize from the given
242 * template. When the access field of ncontrol is 0, it's assumed as 242 * template. When the access field of ncontrol is 0, it's assumed as
243 * READWRITE access. When the count field is 0, it's assumes as one. 243 * READWRITE access. When the count field is 0, it's assumes as one.
244 * 244 *
@@ -251,7 +251,7 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
251 unsigned int count; 251 unsigned int count;
252 unsigned int access; 252 unsigned int access;
253 int err; 253 int err;
254 254
255 if (snd_BUG_ON(!ncontrol || !ncontrol->info)) 255 if (snd_BUG_ON(!ncontrol || !ncontrol->info))
256 return NULL; 256 return NULL;
257 257
@@ -753,7 +753,7 @@ static int snd_ctl_elem_list(struct snd_card *card,
753 struct snd_ctl_elem_id id; 753 struct snd_ctl_elem_id id;
754 unsigned int offset, space, jidx; 754 unsigned int offset, space, jidx;
755 int err = 0; 755 int err = 0;
756 756
757 if (copy_from_user(&list, _list, sizeof(list))) 757 if (copy_from_user(&list, _list, sizeof(list)))
758 return -EFAULT; 758 return -EFAULT;
759 offset = list.offset; 759 offset = list.offset;
@@ -827,7 +827,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
827 struct snd_kcontrol_volatile *vd; 827 struct snd_kcontrol_volatile *vd;
828 unsigned int index_offset; 828 unsigned int index_offset;
829 int result; 829 int result;
830 830
831 down_read(&card->controls_rwsem); 831 down_read(&card->controls_rwsem);
832 kctl = snd_ctl_find_id(card, &info->id); 832 kctl = snd_ctl_find_id(card, &info->id);
833 if (kctl == NULL) { 833 if (kctl == NULL) {
@@ -992,7 +992,7 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
992 struct snd_kcontrol *kctl; 992 struct snd_kcontrol *kctl;
993 struct snd_kcontrol_volatile *vd; 993 struct snd_kcontrol_volatile *vd;
994 int result; 994 int result;
995 995
996 if (copy_from_user(&id, _id, sizeof(id))) 996 if (copy_from_user(&id, _id, sizeof(id)))
997 return -EFAULT; 997 return -EFAULT;
998 down_write(&card->controls_rwsem); 998 down_write(&card->controls_rwsem);
@@ -1020,7 +1020,7 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
1020 struct snd_kcontrol *kctl; 1020 struct snd_kcontrol *kctl;
1021 struct snd_kcontrol_volatile *vd; 1021 struct snd_kcontrol_volatile *vd;
1022 int result; 1022 int result;
1023 1023
1024 if (copy_from_user(&id, _id, sizeof(id))) 1024 if (copy_from_user(&id, _id, sizeof(id)))
1025 return -EFAULT; 1025 return -EFAULT;
1026 down_write(&card->controls_rwsem); 1026 down_write(&card->controls_rwsem);
diff --git a/sound/core/init.c b/sound/core/init.c
index 4fa5dd955740..79b4df1c1dc7 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -670,7 +670,7 @@ card_id_show_attr(struct device *dev,
670 struct device_attribute *attr, char *buf) 670 struct device_attribute *attr, char *buf)
671{ 671{
672 struct snd_card *card = container_of(dev, struct snd_card, card_dev); 672 struct snd_card *card = container_of(dev, struct snd_card, card_dev);
673 return snprintf(buf, PAGE_SIZE, "%s\n", card->id); 673 return scnprintf(buf, PAGE_SIZE, "%s\n", card->id);
674} 674}
675 675
676static ssize_t 676static ssize_t
@@ -710,7 +710,7 @@ card_number_show_attr(struct device *dev,
710 struct device_attribute *attr, char *buf) 710 struct device_attribute *attr, char *buf)
711{ 711{
712 struct snd_card *card = container_of(dev, struct snd_card, card_dev); 712 struct snd_card *card = container_of(dev, struct snd_card, card_dev);
713 return snprintf(buf, PAGE_SIZE, "%i\n", card->number); 713 return scnprintf(buf, PAGE_SIZE, "%i\n", card->number);
714} 714}
715 715
716static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL); 716static DEVICE_ATTR(number, S_IRUGO, card_number_show_attr, NULL);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 441405081195..481ab0e94ffa 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -823,8 +823,25 @@ static int choose_rate(struct snd_pcm_substream *substream,
823 return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL); 823 return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
824} 824}
825 825
826static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, 826/* parameter locking: returns immediately if tried during streaming */
827 bool trylock) 827static int lock_params(struct snd_pcm_runtime *runtime)
828{
829 if (mutex_lock_interruptible(&runtime->oss.params_lock))
830 return -ERESTARTSYS;
831 if (atomic_read(&runtime->oss.rw_ref)) {
832 mutex_unlock(&runtime->oss.params_lock);
833 return -EBUSY;
834 }
835 return 0;
836}
837
838static void unlock_params(struct snd_pcm_runtime *runtime)
839{
840 mutex_unlock(&runtime->oss.params_lock);
841}
842
843/* call with params_lock held */
844static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
828{ 845{
829 struct snd_pcm_runtime *runtime = substream->runtime; 846 struct snd_pcm_runtime *runtime = substream->runtime;
830 struct snd_pcm_hw_params *params, *sparams; 847 struct snd_pcm_hw_params *params, *sparams;
@@ -838,11 +855,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
838 const struct snd_mask *sformat_mask; 855 const struct snd_mask *sformat_mask;
839 struct snd_mask mask; 856 struct snd_mask mask;
840 857
841 if (trylock) { 858 if (!runtime->oss.params)
842 if (!(mutex_trylock(&runtime->oss.params_lock))) 859 return 0;
843 return -EAGAIN;
844 } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
845 return -ERESTARTSYS;
846 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); 860 sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
847 params = kmalloc(sizeof(*params), GFP_KERNEL); 861 params = kmalloc(sizeof(*params), GFP_KERNEL);
848 sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); 862 sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
@@ -1068,6 +1082,23 @@ failure:
1068 kfree(sw_params); 1082 kfree(sw_params);
1069 kfree(params); 1083 kfree(params);
1070 kfree(sparams); 1084 kfree(sparams);
1085 return err;
1086}
1087
1088/* this one takes the lock by itself */
1089static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
1090 bool trylock)
1091{
1092 struct snd_pcm_runtime *runtime = substream->runtime;
1093 int err;
1094
1095 if (trylock) {
1096 if (!(mutex_trylock(&runtime->oss.params_lock)))
1097 return -EAGAIN;
1098 } else if (mutex_lock_interruptible(&runtime->oss.params_lock))
1099 return -ERESTARTSYS;
1100
1101 err = snd_pcm_oss_change_params_locked(substream);
1071 mutex_unlock(&runtime->oss.params_lock); 1102 mutex_unlock(&runtime->oss.params_lock);
1072 return err; 1103 return err;
1073} 1104}
@@ -1096,11 +1127,14 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
1096 return 0; 1127 return 0;
1097} 1128}
1098 1129
1130/* call with params_lock held */
1099static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream) 1131static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1100{ 1132{
1101 int err; 1133 int err;
1102 struct snd_pcm_runtime *runtime = substream->runtime; 1134 struct snd_pcm_runtime *runtime = substream->runtime;
1103 1135
1136 if (!runtime->oss.prepare)
1137 return 0;
1104 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL); 1138 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
1105 if (err < 0) { 1139 if (err < 0) {
1106 pcm_dbg(substream->pcm, 1140 pcm_dbg(substream->pcm,
@@ -1120,8 +1154,6 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
1120 struct snd_pcm_runtime *runtime; 1154 struct snd_pcm_runtime *runtime;
1121 int err; 1155 int err;
1122 1156
1123 if (substream == NULL)
1124 return 0;
1125 runtime = substream->runtime; 1157 runtime = substream->runtime;
1126 if (runtime->oss.params) { 1158 if (runtime->oss.params) {
1127 err = snd_pcm_oss_change_params(substream, false); 1159 err = snd_pcm_oss_change_params(substream, false);
@@ -1129,6 +1161,29 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
1129 return err; 1161 return err;
1130 } 1162 }
1131 if (runtime->oss.prepare) { 1163 if (runtime->oss.prepare) {
1164 if (mutex_lock_interruptible(&runtime->oss.params_lock))
1165 return -ERESTARTSYS;
1166 err = snd_pcm_oss_prepare(substream);
1167 mutex_unlock(&runtime->oss.params_lock);
1168 if (err < 0)
1169 return err;
1170 }
1171 return 0;
1172}
1173
1174/* call with params_lock held */
1175static int snd_pcm_oss_make_ready_locked(struct snd_pcm_substream *substream)
1176{
1177 struct snd_pcm_runtime *runtime;
1178 int err;
1179
1180 runtime = substream->runtime;
1181 if (runtime->oss.params) {
1182 err = snd_pcm_oss_change_params_locked(substream);
1183 if (err < 0)
1184 return err;
1185 }
1186 if (runtime->oss.prepare) {
1132 err = snd_pcm_oss_prepare(substream); 1187 err = snd_pcm_oss_prepare(substream);
1133 if (err < 0) 1188 if (err < 0)
1134 return err; 1189 return err;
@@ -1332,13 +1387,15 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
1332 if (atomic_read(&substream->mmap_count)) 1387 if (atomic_read(&substream->mmap_count))
1333 return -ENXIO; 1388 return -ENXIO;
1334 1389
1335 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1390 atomic_inc(&runtime->oss.rw_ref);
1336 return tmp;
1337 while (bytes > 0) { 1391 while (bytes > 0) {
1338 if (mutex_lock_interruptible(&runtime->oss.params_lock)) { 1392 if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
1339 tmp = -ERESTARTSYS; 1393 tmp = -ERESTARTSYS;
1340 break; 1394 break;
1341 } 1395 }
1396 tmp = snd_pcm_oss_make_ready_locked(substream);
1397 if (tmp < 0)
1398 goto err;
1342 if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { 1399 if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
1343 tmp = bytes; 1400 tmp = bytes;
1344 if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes) 1401 if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1394,6 +1451,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
1394 } 1451 }
1395 tmp = 0; 1452 tmp = 0;
1396 } 1453 }
1454 atomic_dec(&runtime->oss.rw_ref);
1397 return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; 1455 return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
1398} 1456}
1399 1457
@@ -1439,13 +1497,15 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
1439 if (atomic_read(&substream->mmap_count)) 1497 if (atomic_read(&substream->mmap_count))
1440 return -ENXIO; 1498 return -ENXIO;
1441 1499
1442 if ((tmp = snd_pcm_oss_make_ready(substream)) < 0) 1500 atomic_inc(&runtime->oss.rw_ref);
1443 return tmp;
1444 while (bytes > 0) { 1501 while (bytes > 0) {
1445 if (mutex_lock_interruptible(&runtime->oss.params_lock)) { 1502 if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
1446 tmp = -ERESTARTSYS; 1503 tmp = -ERESTARTSYS;
1447 break; 1504 break;
1448 } 1505 }
1506 tmp = snd_pcm_oss_make_ready_locked(substream);
1507 if (tmp < 0)
1508 goto err;
1449 if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) { 1509 if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
1450 if (runtime->oss.buffer_used == 0) { 1510 if (runtime->oss.buffer_used == 0) {
1451 tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); 1511 tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1486,6 +1546,7 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
1486 } 1546 }
1487 tmp = 0; 1547 tmp = 0;
1488 } 1548 }
1549 atomic_dec(&runtime->oss.rw_ref);
1489 return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; 1550 return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
1490} 1551}
1491 1552
@@ -1501,10 +1562,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
1501 continue; 1562 continue;
1502 runtime = substream->runtime; 1563 runtime = substream->runtime;
1503 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 1564 snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1565 mutex_lock(&runtime->oss.params_lock);
1504 runtime->oss.prepare = 1; 1566 runtime->oss.prepare = 1;
1505 runtime->oss.buffer_used = 0; 1567 runtime->oss.buffer_used = 0;
1506 runtime->oss.prev_hw_ptr_period = 0; 1568 runtime->oss.prev_hw_ptr_period = 0;
1507 runtime->oss.period_ptr = 0; 1569 runtime->oss.period_ptr = 0;
1570 mutex_unlock(&runtime->oss.params_lock);
1508 } 1571 }
1509 return 0; 1572 return 0;
1510} 1573}
@@ -1590,9 +1653,13 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1590 goto __direct; 1653 goto __direct;
1591 if ((err = snd_pcm_oss_make_ready(substream)) < 0) 1654 if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1592 return err; 1655 return err;
1656 atomic_inc(&runtime->oss.rw_ref);
1657 if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
1658 atomic_dec(&runtime->oss.rw_ref);
1659 return -ERESTARTSYS;
1660 }
1593 format = snd_pcm_oss_format_from(runtime->oss.format); 1661 format = snd_pcm_oss_format_from(runtime->oss.format);
1594 width = snd_pcm_format_physical_width(format); 1662 width = snd_pcm_format_physical_width(format);
1595 mutex_lock(&runtime->oss.params_lock);
1596 if (runtime->oss.buffer_used > 0) { 1663 if (runtime->oss.buffer_used > 0) {
1597#ifdef OSS_DEBUG 1664#ifdef OSS_DEBUG
1598 pcm_dbg(substream->pcm, "sync: buffer_used\n"); 1665 pcm_dbg(substream->pcm, "sync: buffer_used\n");
@@ -1602,10 +1669,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1602 runtime->oss.buffer + runtime->oss.buffer_used, 1669 runtime->oss.buffer + runtime->oss.buffer_used,
1603 size); 1670 size);
1604 err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes); 1671 err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
1605 if (err < 0) { 1672 if (err < 0)
1606 mutex_unlock(&runtime->oss.params_lock); 1673 goto unlock;
1607 return err;
1608 }
1609 } else if (runtime->oss.period_ptr > 0) { 1674 } else if (runtime->oss.period_ptr > 0) {
1610#ifdef OSS_DEBUG 1675#ifdef OSS_DEBUG
1611 pcm_dbg(substream->pcm, "sync: period_ptr\n"); 1676 pcm_dbg(substream->pcm, "sync: period_ptr\n");
@@ -1615,10 +1680,8 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1615 runtime->oss.buffer, 1680 runtime->oss.buffer,
1616 size * 8 / width); 1681 size * 8 / width);
1617 err = snd_pcm_oss_sync1(substream, size); 1682 err = snd_pcm_oss_sync1(substream, size);
1618 if (err < 0) { 1683 if (err < 0)
1619 mutex_unlock(&runtime->oss.params_lock); 1684 goto unlock;
1620 return err;
1621 }
1622 } 1685 }
1623 /* 1686 /*
1624 * The ALSA's period might be a bit large than OSS one. 1687 * The ALSA's period might be a bit large than OSS one.
@@ -1632,7 +1695,11 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1632 else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) 1695 else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1633 snd_pcm_lib_writev(substream, NULL, size); 1696 snd_pcm_lib_writev(substream, NULL, size);
1634 } 1697 }
1698unlock:
1635 mutex_unlock(&runtime->oss.params_lock); 1699 mutex_unlock(&runtime->oss.params_lock);
1700 atomic_dec(&runtime->oss.rw_ref);
1701 if (err < 0)
1702 return err;
1636 /* 1703 /*
1637 * finish sync: drain the buffer 1704 * finish sync: drain the buffer
1638 */ 1705 */
@@ -1643,7 +1710,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1643 substream->f_flags = saved_f_flags; 1710 substream->f_flags = saved_f_flags;
1644 if (err < 0) 1711 if (err < 0)
1645 return err; 1712 return err;
1713 mutex_lock(&runtime->oss.params_lock);
1646 runtime->oss.prepare = 1; 1714 runtime->oss.prepare = 1;
1715 mutex_unlock(&runtime->oss.params_lock);
1647 } 1716 }
1648 1717
1649 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; 1718 substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
@@ -1654,8 +1723,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1654 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); 1723 err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1655 if (err < 0) 1724 if (err < 0)
1656 return err; 1725 return err;
1726 mutex_lock(&runtime->oss.params_lock);
1657 runtime->oss.buffer_used = 0; 1727 runtime->oss.buffer_used = 0;
1658 runtime->oss.prepare = 1; 1728 runtime->oss.prepare = 1;
1729 mutex_unlock(&runtime->oss.params_lock);
1659 } 1730 }
1660 return 0; 1731 return 0;
1661} 1732}
@@ -1667,6 +1738,8 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
1667 for (idx = 1; idx >= 0; --idx) { 1738 for (idx = 1; idx >= 0; --idx) {
1668 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; 1739 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1669 struct snd_pcm_runtime *runtime; 1740 struct snd_pcm_runtime *runtime;
1741 int err;
1742
1670 if (substream == NULL) 1743 if (substream == NULL)
1671 continue; 1744 continue;
1672 runtime = substream->runtime; 1745 runtime = substream->runtime;
@@ -1674,10 +1747,14 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
1674 rate = 1000; 1747 rate = 1000;
1675 else if (rate > 192000) 1748 else if (rate > 192000)
1676 rate = 192000; 1749 rate = 192000;
1750 err = lock_params(runtime);
1751 if (err < 0)
1752 return err;
1677 if (runtime->oss.rate != rate) { 1753 if (runtime->oss.rate != rate) {
1678 runtime->oss.params = 1; 1754 runtime->oss.params = 1;
1679 runtime->oss.rate = rate; 1755 runtime->oss.rate = rate;
1680 } 1756 }
1757 unlock_params(runtime);
1681 } 1758 }
1682 return snd_pcm_oss_get_rate(pcm_oss_file); 1759 return snd_pcm_oss_get_rate(pcm_oss_file);
1683} 1760}
@@ -1702,13 +1779,19 @@ static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsig
1702 for (idx = 1; idx >= 0; --idx) { 1779 for (idx = 1; idx >= 0; --idx) {
1703 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; 1780 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1704 struct snd_pcm_runtime *runtime; 1781 struct snd_pcm_runtime *runtime;
1782 int err;
1783
1705 if (substream == NULL) 1784 if (substream == NULL)
1706 continue; 1785 continue;
1707 runtime = substream->runtime; 1786 runtime = substream->runtime;
1787 err = lock_params(runtime);
1788 if (err < 0)
1789 return err;
1708 if (runtime->oss.channels != channels) { 1790 if (runtime->oss.channels != channels) {
1709 runtime->oss.params = 1; 1791 runtime->oss.params = 1;
1710 runtime->oss.channels = channels; 1792 runtime->oss.channels = channels;
1711 } 1793 }
1794 unlock_params(runtime);
1712 } 1795 }
1713 return snd_pcm_oss_get_channels(pcm_oss_file); 1796 return snd_pcm_oss_get_channels(pcm_oss_file);
1714} 1797}
@@ -1781,6 +1864,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1781static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format) 1864static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
1782{ 1865{
1783 int formats, idx; 1866 int formats, idx;
1867 int err;
1784 1868
1785 if (format != AFMT_QUERY) { 1869 if (format != AFMT_QUERY) {
1786 formats = snd_pcm_oss_get_formats(pcm_oss_file); 1870 formats = snd_pcm_oss_get_formats(pcm_oss_file);
@@ -1794,10 +1878,14 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for
1794 if (substream == NULL) 1878 if (substream == NULL)
1795 continue; 1879 continue;
1796 runtime = substream->runtime; 1880 runtime = substream->runtime;
1881 err = lock_params(runtime);
1882 if (err < 0)
1883 return err;
1797 if (runtime->oss.format != format) { 1884 if (runtime->oss.format != format) {
1798 runtime->oss.params = 1; 1885 runtime->oss.params = 1;
1799 runtime->oss.format = format; 1886 runtime->oss.format = format;
1800 } 1887 }
1888 unlock_params(runtime);
1801 } 1889 }
1802 } 1890 }
1803 return snd_pcm_oss_get_format(pcm_oss_file); 1891 return snd_pcm_oss_get_format(pcm_oss_file);
@@ -1817,8 +1905,6 @@ static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int s
1817{ 1905{
1818 struct snd_pcm_runtime *runtime; 1906 struct snd_pcm_runtime *runtime;
1819 1907
1820 if (substream == NULL)
1821 return 0;
1822 runtime = substream->runtime; 1908 runtime = substream->runtime;
1823 if (subdivide == 0) { 1909 if (subdivide == 0) {
1824 subdivide = runtime->oss.subdivision; 1910 subdivide = runtime->oss.subdivision;
@@ -1842,9 +1928,17 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int
1842 1928
1843 for (idx = 1; idx >= 0; --idx) { 1929 for (idx = 1; idx >= 0; --idx) {
1844 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; 1930 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1931 struct snd_pcm_runtime *runtime;
1932
1845 if (substream == NULL) 1933 if (substream == NULL)
1846 continue; 1934 continue;
1847 if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0) 1935 runtime = substream->runtime;
1936 err = lock_params(runtime);
1937 if (err < 0)
1938 return err;
1939 err = snd_pcm_oss_set_subdivide1(substream, subdivide);
1940 unlock_params(runtime);
1941 if (err < 0)
1848 return err; 1942 return err;
1849 } 1943 }
1850 return err; 1944 return err;
@@ -1854,8 +1948,6 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign
1854{ 1948{
1855 struct snd_pcm_runtime *runtime; 1949 struct snd_pcm_runtime *runtime;
1856 1950
1857 if (substream == NULL)
1858 return 0;
1859 runtime = substream->runtime; 1951 runtime = substream->runtime;
1860 if (runtime->oss.subdivision || runtime->oss.fragshift) 1952 if (runtime->oss.subdivision || runtime->oss.fragshift)
1861 return -EINVAL; 1953 return -EINVAL;
@@ -1875,9 +1967,17 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig
1875 1967
1876 for (idx = 1; idx >= 0; --idx) { 1968 for (idx = 1; idx >= 0; --idx) {
1877 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx]; 1969 struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1970 struct snd_pcm_runtime *runtime;
1971
1878 if (substream == NULL) 1972 if (substream == NULL)
1879 continue; 1973 continue;
1880 if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0) 1974 runtime = substream->runtime;
1975 err = lock_params(runtime);
1976 if (err < 0)
1977 return err;
1978 err = snd_pcm_oss_set_fragment1(substream, val);
1979 unlock_params(runtime);
1980 if (err < 0)
1881 return err; 1981 return err;
1882 } 1982 }
1883 return err; 1983 return err;
@@ -1961,6 +2061,9 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1961 } 2061 }
1962 if (psubstream) { 2062 if (psubstream) {
1963 runtime = psubstream->runtime; 2063 runtime = psubstream->runtime;
2064 cmd = 0;
2065 if (mutex_lock_interruptible(&runtime->oss.params_lock))
2066 return -ERESTARTSYS;
1964 if (trigger & PCM_ENABLE_OUTPUT) { 2067 if (trigger & PCM_ENABLE_OUTPUT) {
1965 if (runtime->oss.trigger) 2068 if (runtime->oss.trigger)
1966 goto _skip1; 2069 goto _skip1;
@@ -1978,13 +2081,19 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1978 cmd = SNDRV_PCM_IOCTL_DROP; 2081 cmd = SNDRV_PCM_IOCTL_DROP;
1979 runtime->oss.prepare = 1; 2082 runtime->oss.prepare = 1;
1980 } 2083 }
1981 err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
1982 if (err < 0)
1983 return err;
1984 }
1985 _skip1: 2084 _skip1:
2085 mutex_unlock(&runtime->oss.params_lock);
2086 if (cmd) {
2087 err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
2088 if (err < 0)
2089 return err;
2090 }
2091 }
1986 if (csubstream) { 2092 if (csubstream) {
1987 runtime = csubstream->runtime; 2093 runtime = csubstream->runtime;
2094 cmd = 0;
2095 if (mutex_lock_interruptible(&runtime->oss.params_lock))
2096 return -ERESTARTSYS;
1988 if (trigger & PCM_ENABLE_INPUT) { 2097 if (trigger & PCM_ENABLE_INPUT) {
1989 if (runtime->oss.trigger) 2098 if (runtime->oss.trigger)
1990 goto _skip2; 2099 goto _skip2;
@@ -1999,11 +2108,14 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1999 cmd = SNDRV_PCM_IOCTL_DROP; 2108 cmd = SNDRV_PCM_IOCTL_DROP;
2000 runtime->oss.prepare = 1; 2109 runtime->oss.prepare = 1;
2001 } 2110 }
2002 err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
2003 if (err < 0)
2004 return err;
2005 }
2006 _skip2: 2111 _skip2:
2112 mutex_unlock(&runtime->oss.params_lock);
2113 if (cmd) {
2114 err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
2115 if (err < 0)
2116 return err;
2117 }
2118 }
2007 return 0; 2119 return 0;
2008} 2120}
2009 2121
@@ -2255,6 +2367,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
2255 runtime->oss.maxfrags = 0; 2367 runtime->oss.maxfrags = 0;
2256 runtime->oss.subdivision = 0; 2368 runtime->oss.subdivision = 0;
2257 substream->pcm_release = snd_pcm_oss_release_substream; 2369 substream->pcm_release = snd_pcm_oss_release_substream;
2370 atomic_set(&runtime->oss.rw_ref, 0);
2258} 2371}
2259 2372
2260static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) 2373static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index a83152e7d387..f4a19509cccf 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1129,16 +1129,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1129 if (constrs->rules_num >= constrs->rules_all) { 1129 if (constrs->rules_num >= constrs->rules_all) {
1130 struct snd_pcm_hw_rule *new; 1130 struct snd_pcm_hw_rule *new;
1131 unsigned int new_rules = constrs->rules_all + 16; 1131 unsigned int new_rules = constrs->rules_all + 16;
1132 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); 1132 new = krealloc(constrs->rules, new_rules * sizeof(*c),
1133 GFP_KERNEL);
1133 if (!new) { 1134 if (!new) {
1134 va_end(args); 1135 va_end(args);
1135 return -ENOMEM; 1136 return -ENOMEM;
1136 } 1137 }
1137 if (constrs->rules) {
1138 memcpy(new, constrs->rules,
1139 constrs->rules_num * sizeof(*c));
1140 kfree(constrs->rules);
1141 }
1142 constrs->rules = new; 1138 constrs->rules = new;
1143 constrs->rules_all = new_rules; 1139 constrs->rules_all = new_rules;
1144 } 1140 }
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index d18b3982548b..b84554893fab 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -323,7 +323,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_constraints *constrs = 323 struct snd_pcm_hw_constraints *constrs =
324 &substream->runtime->hw_constraints; 324 &substream->runtime->hw_constraints;
325 unsigned int k; 325 unsigned int k;
326 unsigned int rstamps[constrs->rules_num]; 326 unsigned int *rstamps;
327 unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1]; 327 unsigned int vstamps[SNDRV_PCM_HW_PARAM_LAST_INTERVAL + 1];
328 unsigned int stamp; 328 unsigned int stamp;
329 struct snd_pcm_hw_rule *r; 329 struct snd_pcm_hw_rule *r;
@@ -331,7 +331,7 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
331 struct snd_mask old_mask; 331 struct snd_mask old_mask;
332 struct snd_interval old_interval; 332 struct snd_interval old_interval;
333 bool again; 333 bool again;
334 int changed; 334 int changed, err = 0;
335 335
336 /* 336 /*
337 * Each application of rule has own sequence number. 337 * Each application of rule has own sequence number.
@@ -339,8 +339,9 @@ static int constrain_params_by_rules(struct snd_pcm_substream *substream,
339 * Each member of 'rstamps' array represents the sequence number of 339 * Each member of 'rstamps' array represents the sequence number of
340 * recent application of corresponding rule. 340 * recent application of corresponding rule.
341 */ 341 */
342 for (k = 0; k < constrs->rules_num; k++) 342 rstamps = kcalloc(constrs->rules_num, sizeof(unsigned int), GFP_KERNEL);
343 rstamps[k] = 0; 343 if (!rstamps)
344 return -ENOMEM;
344 345
345 /* 346 /*
346 * Each member of 'vstamps' array represents the sequence number of 347 * Each member of 'vstamps' array represents the sequence number of
@@ -398,8 +399,10 @@ retry:
398 } 399 }
399 400
400 changed = r->func(params, r); 401 changed = r->func(params, r);
401 if (changed < 0) 402 if (changed < 0) {
402 return changed; 403 err = changed;
404 goto out;
405 }
403 406
404 /* 407 /*
405 * When the parameter is changed, notify it to the caller 408 * When the parameter is changed, notify it to the caller
@@ -430,7 +433,9 @@ retry:
430 if (again) 433 if (again)
431 goto retry; 434 goto retry;
432 435
433 return 0; 436 out:
437 kfree(rstamps);
438 return err;
434} 439}
435 440
436static int fixup_unreferenced_params(struct snd_pcm_substream *substream, 441static int fixup_unreferenced_params(struct snd_pcm_substream *substream,
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c
index 8632301489fa..9e96186742d0 100644
--- a/sound/core/vmaster.c
+++ b/sound/core/vmaster.c
@@ -63,15 +63,18 @@ static int slave_update(struct link_slave *slave)
63 struct snd_ctl_elem_value *uctl; 63 struct snd_ctl_elem_value *uctl;
64 int err, ch; 64 int err, ch;
65 65
66 uctl = kmalloc(sizeof(*uctl), GFP_KERNEL); 66 uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
67 if (!uctl) 67 if (!uctl)
68 return -ENOMEM; 68 return -ENOMEM;
69 uctl->id = slave->slave.id; 69 uctl->id = slave->slave.id;
70 err = slave->slave.get(&slave->slave, uctl); 70 err = slave->slave.get(&slave->slave, uctl);
71 if (err < 0)
72 goto error;
71 for (ch = 0; ch < slave->info.count; ch++) 73 for (ch = 0; ch < slave->info.count; ch++)
72 slave->vals[ch] = uctl->value.integer.value[ch]; 74 slave->vals[ch] = uctl->value.integer.value[ch];
75 error:
73 kfree(uctl); 76 kfree(uctl);
74 return 0; 77 return err < 0 ? err : 0;
75} 78}
76 79
77/* get the slave ctl info and save the initial values */ 80/* get the slave ctl info and save the initial values */