@@ -823,8 +823,8 @@ static int choose_rate(struct snd_pcm_substream *substream,
823
823
return snd_pcm_hw_param_near (substream , params , SNDRV_PCM_HW_PARAM_RATE , best_rate , NULL );
824
824
}
825
825
826
- static int snd_pcm_oss_change_params ( struct snd_pcm_substream * substream ,
827
- bool trylock )
826
+ /* call with params_lock held */
827
+ static int snd_pcm_oss_change_params_locked ( struct snd_pcm_substream * substream )
828
828
{
829
829
struct snd_pcm_runtime * runtime = substream -> runtime ;
830
830
struct snd_pcm_hw_params * params , * sparams ;
@@ -838,11 +838,8 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
838
838
const struct snd_mask * sformat_mask ;
839
839
struct snd_mask mask ;
840
840
841
- if (trylock ) {
842
- if (!(mutex_trylock (& runtime -> oss .params_lock )))
843
- return - EAGAIN ;
844
- } else if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
845
- return - ERESTARTSYS ;
841
+ if (!runtime -> oss .params )
842
+ return 0 ;
846
843
sw_params = kzalloc (sizeof (* sw_params ), GFP_KERNEL );
847
844
params = kmalloc (sizeof (* params ), GFP_KERNEL );
848
845
sparams = kmalloc (sizeof (* sparams ), GFP_KERNEL );
@@ -1068,6 +1065,23 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
1068
1065
kfree (sw_params );
1069
1066
kfree (params );
1070
1067
kfree (sparams );
1068
+ return err ;
1069
+ }
1070
+
1071
+ /* this one takes the lock by itself */
1072
+ static int snd_pcm_oss_change_params (struct snd_pcm_substream * substream ,
1073
+ bool trylock )
1074
+ {
1075
+ struct snd_pcm_runtime * runtime = substream -> runtime ;
1076
+ int err ;
1077
+
1078
+ if (trylock ) {
1079
+ if (!(mutex_trylock (& runtime -> oss .params_lock )))
1080
+ return - EAGAIN ;
1081
+ } else if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1082
+ return - ERESTARTSYS ;
1083
+
1084
+ err = snd_pcm_oss_change_params_locked (substream );
1071
1085
mutex_unlock (& runtime -> oss .params_lock );
1072
1086
return err ;
1073
1087
}
@@ -1096,11 +1110,14 @@ static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_fil
1096
1110
return 0 ;
1097
1111
}
1098
1112
1113
+ /* call with params_lock held */
1099
1114
static int snd_pcm_oss_prepare (struct snd_pcm_substream * substream )
1100
1115
{
1101
1116
int err ;
1102
1117
struct snd_pcm_runtime * runtime = substream -> runtime ;
1103
1118
1119
+ if (!runtime -> oss .prepare )
1120
+ return 0 ;
1104
1121
err = snd_pcm_kernel_ioctl (substream , SNDRV_PCM_IOCTL_PREPARE , NULL );
1105
1122
if (err < 0 ) {
1106
1123
pcm_dbg (substream -> pcm ,
@@ -1120,14 +1137,35 @@ static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
1120
1137
struct snd_pcm_runtime * runtime ;
1121
1138
int err ;
1122
1139
1123
- if (substream == NULL )
1124
- return 0 ;
1125
1140
runtime = substream -> runtime ;
1126
1141
if (runtime -> oss .params ) {
1127
1142
err = snd_pcm_oss_change_params (substream , false);
1128
1143
if (err < 0 )
1129
1144
return err ;
1130
1145
}
1146
+ if (runtime -> oss .prepare ) {
1147
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1148
+ return - ERESTARTSYS ;
1149
+ err = snd_pcm_oss_prepare (substream );
1150
+ mutex_unlock (& runtime -> oss .params_lock );
1151
+ if (err < 0 )
1152
+ return err ;
1153
+ }
1154
+ return 0 ;
1155
+ }
1156
+
1157
+ /* call with params_lock held */
1158
+ static int snd_pcm_oss_make_ready_locked (struct snd_pcm_substream * substream )
1159
+ {
1160
+ struct snd_pcm_runtime * runtime ;
1161
+ int err ;
1162
+
1163
+ runtime = substream -> runtime ;
1164
+ if (runtime -> oss .params ) {
1165
+ err = snd_pcm_oss_change_params_locked (substream );
1166
+ if (err < 0 )
1167
+ return err ;
1168
+ }
1131
1169
if (runtime -> oss .prepare ) {
1132
1170
err = snd_pcm_oss_prepare (substream );
1133
1171
if (err < 0 )
@@ -1332,13 +1370,14 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
1332
1370
if (atomic_read (& substream -> mmap_count ))
1333
1371
return - ENXIO ;
1334
1372
1335
- if ((tmp = snd_pcm_oss_make_ready (substream )) < 0 )
1336
- return tmp ;
1337
1373
while (bytes > 0 ) {
1338
1374
if (mutex_lock_interruptible (& runtime -> oss .params_lock )) {
1339
1375
tmp = - ERESTARTSYS ;
1340
1376
break ;
1341
1377
}
1378
+ tmp = snd_pcm_oss_make_ready_locked (substream );
1379
+ if (tmp < 0 )
1380
+ goto err ;
1342
1381
if (bytes < runtime -> oss .period_bytes || runtime -> oss .buffer_used > 0 ) {
1343
1382
tmp = bytes ;
1344
1383
if (tmp + runtime -> oss .buffer_used > runtime -> oss .period_bytes )
@@ -1439,13 +1478,14 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
1439
1478
if (atomic_read (& substream -> mmap_count ))
1440
1479
return - ENXIO ;
1441
1480
1442
- if ((tmp = snd_pcm_oss_make_ready (substream )) < 0 )
1443
- return tmp ;
1444
1481
while (bytes > 0 ) {
1445
1482
if (mutex_lock_interruptible (& runtime -> oss .params_lock )) {
1446
1483
tmp = - ERESTARTSYS ;
1447
1484
break ;
1448
1485
}
1486
+ tmp = snd_pcm_oss_make_ready_locked (substream );
1487
+ if (tmp < 0 )
1488
+ goto err ;
1449
1489
if (bytes < runtime -> oss .period_bytes || runtime -> oss .buffer_used > 0 ) {
1450
1490
if (runtime -> oss .buffer_used == 0 ) {
1451
1491
tmp = snd_pcm_oss_read2 (substream , runtime -> oss .buffer , runtime -> oss .period_bytes , 1 );
@@ -1501,10 +1541,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
1501
1541
continue ;
1502
1542
runtime = substream -> runtime ;
1503
1543
snd_pcm_kernel_ioctl (substream , SNDRV_PCM_IOCTL_DROP , NULL );
1544
+ mutex_lock (& runtime -> oss .params_lock );
1504
1545
runtime -> oss .prepare = 1 ;
1505
1546
runtime -> oss .buffer_used = 0 ;
1506
1547
runtime -> oss .prev_hw_ptr_period = 0 ;
1507
1548
runtime -> oss .period_ptr = 0 ;
1549
+ mutex_unlock (& runtime -> oss .params_lock );
1508
1550
}
1509
1551
return 0 ;
1510
1552
}
@@ -1590,9 +1632,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1590
1632
goto __direct ;
1591
1633
if ((err = snd_pcm_oss_make_ready (substream )) < 0 )
1592
1634
return err ;
1635
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1636
+ return - ERESTARTSYS ;
1593
1637
format = snd_pcm_oss_format_from (runtime -> oss .format );
1594
1638
width = snd_pcm_format_physical_width (format );
1595
- mutex_lock (& runtime -> oss .params_lock );
1596
1639
if (runtime -> oss .buffer_used > 0 ) {
1597
1640
#ifdef OSS_DEBUG
1598
1641
pcm_dbg (substream -> pcm , "sync: buffer_used\n" );
@@ -1643,7 +1686,9 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1643
1686
substream -> f_flags = saved_f_flags ;
1644
1687
if (err < 0 )
1645
1688
return err ;
1689
+ mutex_lock (& runtime -> oss .params_lock );
1646
1690
runtime -> oss .prepare = 1 ;
1691
+ mutex_unlock (& runtime -> oss .params_lock );
1647
1692
}
1648
1693
1649
1694
substream = pcm_oss_file -> streams [SNDRV_PCM_STREAM_CAPTURE ];
@@ -1654,8 +1699,10 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1654
1699
err = snd_pcm_kernel_ioctl (substream , SNDRV_PCM_IOCTL_DROP , NULL );
1655
1700
if (err < 0 )
1656
1701
return err ;
1702
+ mutex_lock (& runtime -> oss .params_lock );
1657
1703
runtime -> oss .buffer_used = 0 ;
1658
1704
runtime -> oss .prepare = 1 ;
1705
+ mutex_unlock (& runtime -> oss .params_lock );
1659
1706
}
1660
1707
return 0 ;
1661
1708
}
@@ -1674,10 +1721,13 @@ static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
1674
1721
rate = 1000 ;
1675
1722
else if (rate > 192000 )
1676
1723
rate = 192000 ;
1724
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1725
+ return - ERESTARTSYS ;
1677
1726
if (runtime -> oss .rate != rate ) {
1678
1727
runtime -> oss .params = 1 ;
1679
1728
runtime -> oss .rate = rate ;
1680
1729
}
1730
+ mutex_unlock (& runtime -> oss .params_lock );
1681
1731
}
1682
1732
return snd_pcm_oss_get_rate (pcm_oss_file );
1683
1733
}
@@ -1705,10 +1755,13 @@ static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsig
1705
1755
if (substream == NULL )
1706
1756
continue ;
1707
1757
runtime = substream -> runtime ;
1758
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1759
+ return - ERESTARTSYS ;
1708
1760
if (runtime -> oss .channels != channels ) {
1709
1761
runtime -> oss .params = 1 ;
1710
1762
runtime -> oss .channels = channels ;
1711
1763
}
1764
+ mutex_unlock (& runtime -> oss .params_lock );
1712
1765
}
1713
1766
return snd_pcm_oss_get_channels (pcm_oss_file );
1714
1767
}
@@ -1794,10 +1847,13 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for
1794
1847
if (substream == NULL )
1795
1848
continue ;
1796
1849
runtime = substream -> runtime ;
1850
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1851
+ return - ERESTARTSYS ;
1797
1852
if (runtime -> oss .format != format ) {
1798
1853
runtime -> oss .params = 1 ;
1799
1854
runtime -> oss .format = format ;
1800
1855
}
1856
+ mutex_unlock (& runtime -> oss .params_lock );
1801
1857
}
1802
1858
}
1803
1859
return snd_pcm_oss_get_format (pcm_oss_file );
@@ -1817,8 +1873,6 @@ static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int s
1817
1873
{
1818
1874
struct snd_pcm_runtime * runtime ;
1819
1875
1820
- if (substream == NULL )
1821
- return 0 ;
1822
1876
runtime = substream -> runtime ;
1823
1877
if (subdivide == 0 ) {
1824
1878
subdivide = runtime -> oss .subdivision ;
@@ -1842,9 +1896,16 @@ static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int
1842
1896
1843
1897
for (idx = 1 ; idx >= 0 ; -- idx ) {
1844
1898
struct snd_pcm_substream * substream = pcm_oss_file -> streams [idx ];
1899
+ struct snd_pcm_runtime * runtime ;
1900
+
1845
1901
if (substream == NULL )
1846
1902
continue ;
1847
- if ((err = snd_pcm_oss_set_subdivide1 (substream , subdivide )) < 0 )
1903
+ runtime = substream -> runtime ;
1904
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1905
+ return - ERESTARTSYS ;
1906
+ err = snd_pcm_oss_set_subdivide1 (substream , subdivide );
1907
+ mutex_unlock (& runtime -> oss .params_lock );
1908
+ if (err < 0 )
1848
1909
return err ;
1849
1910
}
1850
1911
return err ;
@@ -1854,8 +1915,6 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign
1854
1915
{
1855
1916
struct snd_pcm_runtime * runtime ;
1856
1917
1857
- if (substream == NULL )
1858
- return 0 ;
1859
1918
runtime = substream -> runtime ;
1860
1919
if (runtime -> oss .subdivision || runtime -> oss .fragshift )
1861
1920
return - EINVAL ;
@@ -1875,9 +1934,16 @@ static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsig
1875
1934
1876
1935
for (idx = 1 ; idx >= 0 ; -- idx ) {
1877
1936
struct snd_pcm_substream * substream = pcm_oss_file -> streams [idx ];
1937
+ struct snd_pcm_runtime * runtime ;
1938
+
1878
1939
if (substream == NULL )
1879
1940
continue ;
1880
- if ((err = snd_pcm_oss_set_fragment1 (substream , val )) < 0 )
1941
+ runtime = substream -> runtime ;
1942
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
1943
+ return - ERESTARTSYS ;
1944
+ err = snd_pcm_oss_set_fragment1 (substream , val );
1945
+ mutex_unlock (& runtime -> oss .params_lock );
1946
+ if (err < 0 )
1881
1947
return err ;
1882
1948
}
1883
1949
return err ;
@@ -1961,6 +2027,9 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1961
2027
}
1962
2028
if (psubstream ) {
1963
2029
runtime = psubstream -> runtime ;
2030
+ cmd = 0 ;
2031
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
2032
+ return - ERESTARTSYS ;
1964
2033
if (trigger & PCM_ENABLE_OUTPUT ) {
1965
2034
if (runtime -> oss .trigger )
1966
2035
goto _skip1 ;
@@ -1978,13 +2047,19 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1978
2047
cmd = SNDRV_PCM_IOCTL_DROP ;
1979
2048
runtime -> oss .prepare = 1 ;
1980
2049
}
1981
- err = snd_pcm_kernel_ioctl (psubstream , cmd , NULL );
1982
- if (err < 0 )
1983
- return err ;
1984
- }
1985
2050
_skip1 :
2051
+ mutex_unlock (& runtime -> oss .params_lock );
2052
+ if (cmd ) {
2053
+ err = snd_pcm_kernel_ioctl (psubstream , cmd , NULL );
2054
+ if (err < 0 )
2055
+ return err ;
2056
+ }
2057
+ }
1986
2058
if (csubstream ) {
1987
2059
runtime = csubstream -> runtime ;
2060
+ cmd = 0 ;
2061
+ if (mutex_lock_interruptible (& runtime -> oss .params_lock ))
2062
+ return - ERESTARTSYS ;
1988
2063
if (trigger & PCM_ENABLE_INPUT ) {
1989
2064
if (runtime -> oss .trigger )
1990
2065
goto _skip2 ;
@@ -1999,11 +2074,14 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr
1999
2074
cmd = SNDRV_PCM_IOCTL_DROP ;
2000
2075
runtime -> oss .prepare = 1 ;
2001
2076
}
2002
- err = snd_pcm_kernel_ioctl (csubstream , cmd , NULL );
2003
- if (err < 0 )
2004
- return err ;
2005
- }
2006
2077
_skip2 :
2078
+ mutex_unlock (& runtime -> oss .params_lock );
2079
+ if (cmd ) {
2080
+ err = snd_pcm_kernel_ioctl (csubstream , cmd , NULL );
2081
+ if (err < 0 )
2082
+ return err ;
2083
+ }
2084
+ }
2007
2085
return 0 ;
2008
2086
}
2009
2087
0 commit comments