aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/cs46xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/cs46xx.c')
-rw-r--r--sound/oss/cs46xx.c75
1 files changed, 38 insertions, 37 deletions
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index 58e25c82eaf2..53881bc91bba 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -90,6 +90,7 @@
90#include <linux/init.h> 90#include <linux/init.h>
91#include <linux/poll.h> 91#include <linux/poll.h>
92#include <linux/ac97_codec.h> 92#include <linux/ac97_codec.h>
93#include <linux/mutex.h>
93 94
94#include <asm/io.h> 95#include <asm/io.h>
95#include <asm/dma.h> 96#include <asm/dma.h>
@@ -238,7 +239,7 @@ struct cs_state {
238 struct cs_card *card; /* Card info */ 239 struct cs_card *card; /* Card info */
239 240
240 /* single open lock mechanism, only used for recording */ 241 /* single open lock mechanism, only used for recording */
241 struct semaphore open_sem; 242 struct mutex open_mutex;
242 wait_queue_head_t open_wait; 243 wait_queue_head_t open_wait;
243 244
244 /* file mode */ 245 /* file mode */
@@ -297,7 +298,7 @@ struct cs_state {
297 unsigned subdivision; 298 unsigned subdivision;
298 } dmabuf; 299 } dmabuf;
299 /* Guard against mmap/write/read races */ 300 /* Guard against mmap/write/read races */
300 struct semaphore sem; 301 struct mutex sem;
301}; 302};
302 303
303struct cs_card { 304struct cs_card {
@@ -375,7 +376,7 @@ struct cs_card {
375 unsigned char ibuf[CS_MIDIINBUF]; 376 unsigned char ibuf[CS_MIDIINBUF];
376 unsigned char obuf[CS_MIDIOUTBUF]; 377 unsigned char obuf[CS_MIDIOUTBUF];
377 mode_t open_mode; 378 mode_t open_mode;
378 struct semaphore open_sem; 379 struct mutex open_mutex;
379 } midi; 380 } midi;
380 struct cs46xx_pm pm; 381 struct cs46xx_pm pm;
381}; 382};
@@ -1428,9 +1429,9 @@ static int prog_dmabuf(struct cs_state *state)
1428{ 1429{
1429 int ret; 1430 int ret;
1430 1431
1431 down(&state->sem); 1432 mutex_lock(&state->sem);
1432 ret = __prog_dmabuf(state); 1433 ret = __prog_dmabuf(state);
1433 up(&state->sem); 1434 mutex_unlock(&state->sem);
1434 1435
1435 return ret; 1436 return ret;
1436} 1437}
@@ -1831,17 +1832,17 @@ static int cs_midi_open(struct inode *inode, struct file *file)
1831 1832
1832 file->private_data = card; 1833 file->private_data = card;
1833 /* wait for device to become free */ 1834 /* wait for device to become free */
1834 down(&card->midi.open_sem); 1835 mutex_lock(&card->midi.open_mutex);
1835 while (card->midi.open_mode & file->f_mode) { 1836 while (card->midi.open_mode & file->f_mode) {
1836 if (file->f_flags & O_NONBLOCK) { 1837 if (file->f_flags & O_NONBLOCK) {
1837 up(&card->midi.open_sem); 1838 mutex_unlock(&card->midi.open_mutex);
1838 return -EBUSY; 1839 return -EBUSY;
1839 } 1840 }
1840 up(&card->midi.open_sem); 1841 mutex_unlock(&card->midi.open_mutex);
1841 interruptible_sleep_on(&card->midi.open_wait); 1842 interruptible_sleep_on(&card->midi.open_wait);
1842 if (signal_pending(current)) 1843 if (signal_pending(current))
1843 return -ERESTARTSYS; 1844 return -ERESTARTSYS;
1844 down(&card->midi.open_sem); 1845 mutex_lock(&card->midi.open_mutex);
1845 } 1846 }
1846 spin_lock_irqsave(&card->midi.lock, flags); 1847 spin_lock_irqsave(&card->midi.lock, flags);
1847 if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) { 1848 if (!(card->midi.open_mode & (FMODE_READ | FMODE_WRITE))) {
@@ -1859,7 +1860,7 @@ static int cs_midi_open(struct inode *inode, struct file *file)
1859 } 1860 }
1860 spin_unlock_irqrestore(&card->midi.lock, flags); 1861 spin_unlock_irqrestore(&card->midi.lock, flags);
1861 card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE)); 1862 card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
1862 up(&card->midi.open_sem); 1863 mutex_unlock(&card->midi.open_mutex);
1863 return 0; 1864 return 0;
1864} 1865}
1865 1866
@@ -1891,9 +1892,9 @@ static int cs_midi_release(struct inode *inode, struct file *file)
1891 remove_wait_queue(&card->midi.owait, &wait); 1892 remove_wait_queue(&card->midi.owait, &wait);
1892 current->state = TASK_RUNNING; 1893 current->state = TASK_RUNNING;
1893 } 1894 }
1894 down(&card->midi.open_sem); 1895 mutex_lock(&card->midi.open_mutex);
1895 card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE))); 1896 card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE)));
1896 up(&card->midi.open_sem); 1897 mutex_unlock(&card->midi.open_mutex);
1897 wake_up(&card->midi.open_wait); 1898 wake_up(&card->midi.open_wait);
1898 return 0; 1899 return 0;
1899} 1900}
@@ -2081,7 +2082,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
2081 if (!access_ok(VERIFY_WRITE, buffer, count)) 2082 if (!access_ok(VERIFY_WRITE, buffer, count))
2082 return -EFAULT; 2083 return -EFAULT;
2083 2084
2084 down(&state->sem); 2085 mutex_lock(&state->sem);
2085 if (!dmabuf->ready && (ret = __prog_dmabuf(state))) 2086 if (!dmabuf->ready && (ret = __prog_dmabuf(state)))
2086 goto out2; 2087 goto out2;
2087 2088
@@ -2114,13 +2115,13 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
2114 if (!ret) ret = -EAGAIN; 2115 if (!ret) ret = -EAGAIN;
2115 goto out; 2116 goto out;
2116 } 2117 }
2117 up(&state->sem); 2118 mutex_unlock(&state->sem);
2118 schedule(); 2119 schedule();
2119 if (signal_pending(current)) { 2120 if (signal_pending(current)) {
2120 if(!ret) ret = -ERESTARTSYS; 2121 if(!ret) ret = -ERESTARTSYS;
2121 goto out; 2122 goto out;
2122 } 2123 }
2123 down(&state->sem); 2124 mutex_lock(&state->sem);
2124 if (dmabuf->mapped) 2125 if (dmabuf->mapped)
2125 { 2126 {
2126 if(!ret) 2127 if(!ret)
@@ -2155,7 +2156,7 @@ static ssize_t cs_read(struct file *file, char __user *buffer, size_t count, lof
2155out: 2156out:
2156 remove_wait_queue(&state->dmabuf.wait, &wait); 2157 remove_wait_queue(&state->dmabuf.wait, &wait);
2157out2: 2158out2:
2158 up(&state->sem); 2159 mutex_unlock(&state->sem);
2159 set_current_state(TASK_RUNNING); 2160 set_current_state(TASK_RUNNING);
2160 CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4, 2161 CS_DBGOUT(CS_WAVE_READ | CS_FUNCTION, 4,
2161 printk("cs46xx: cs_read()- %zd\n",ret) ); 2162 printk("cs46xx: cs_read()- %zd\n",ret) );
@@ -2184,7 +2185,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
2184 return -EFAULT; 2185 return -EFAULT;
2185 dmabuf = &state->dmabuf; 2186 dmabuf = &state->dmabuf;
2186 2187
2187 down(&state->sem); 2188 mutex_lock(&state->sem);
2188 if (dmabuf->mapped) 2189 if (dmabuf->mapped)
2189 { 2190 {
2190 ret = -ENXIO; 2191 ret = -ENXIO;
@@ -2240,13 +2241,13 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
2240 if (!ret) ret = -EAGAIN; 2241 if (!ret) ret = -EAGAIN;
2241 goto out; 2242 goto out;
2242 } 2243 }
2243 up(&state->sem); 2244 mutex_unlock(&state->sem);
2244 schedule(); 2245 schedule();
2245 if (signal_pending(current)) { 2246 if (signal_pending(current)) {
2246 if(!ret) ret = -ERESTARTSYS; 2247 if(!ret) ret = -ERESTARTSYS;
2247 goto out; 2248 goto out;
2248 } 2249 }
2249 down(&state->sem); 2250 mutex_lock(&state->sem);
2250 if (dmabuf->mapped) 2251 if (dmabuf->mapped)
2251 { 2252 {
2252 if(!ret) 2253 if(!ret)
@@ -2278,7 +2279,7 @@ static ssize_t cs_write(struct file *file, const char __user *buffer, size_t cou
2278 start_dac(state); 2279 start_dac(state);
2279 } 2280 }
2280out: 2281out:
2281 up(&state->sem); 2282 mutex_unlock(&state->sem);
2282 remove_wait_queue(&state->dmabuf.wait, &wait); 2283 remove_wait_queue(&state->dmabuf.wait, &wait);
2283 set_current_state(TASK_RUNNING); 2284 set_current_state(TASK_RUNNING);
2284 2285
@@ -2411,7 +2412,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
2411 goto out; 2412 goto out;
2412 } 2413 }
2413 2414
2414 down(&state->sem); 2415 mutex_lock(&state->sem);
2415 dmabuf = &state->dmabuf; 2416 dmabuf = &state->dmabuf;
2416 if (cs4x_pgoff(vma) != 0) 2417 if (cs4x_pgoff(vma) != 0)
2417 { 2418 {
@@ -2438,7 +2439,7 @@ static int cs_mmap(struct file *file, struct vm_area_struct *vma)
2438 2439
2439 CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") ); 2440 CS_DBGOUT(CS_FUNCTION, 2, printk("cs46xx: cs_mmap()-\n") );
2440out: 2441out:
2441 up(&state->sem); 2442 mutex_unlock(&state->sem);
2442 return ret; 2443 return ret;
2443} 2444}
2444 2445
@@ -3200,7 +3201,7 @@ static int cs_open(struct inode *inode, struct file *file)
3200 if (state == NULL) 3201 if (state == NULL)
3201 return -ENOMEM; 3202 return -ENOMEM;
3202 memset(state, 0, sizeof(struct cs_state)); 3203 memset(state, 0, sizeof(struct cs_state));
3203 init_MUTEX(&state->sem); 3204 mutex_init(&state->sem);
3204 dmabuf = &state->dmabuf; 3205 dmabuf = &state->dmabuf;
3205 dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 3206 dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
3206 if(dmabuf->pbuf==NULL) 3207 if(dmabuf->pbuf==NULL)
@@ -3241,10 +3242,10 @@ static int cs_open(struct inode *inode, struct file *file)
3241 state->virt = 0; 3242 state->virt = 0;
3242 state->magic = CS_STATE_MAGIC; 3243 state->magic = CS_STATE_MAGIC;
3243 init_waitqueue_head(&dmabuf->wait); 3244 init_waitqueue_head(&dmabuf->wait);
3244 init_MUTEX(&state->open_sem); 3245 mutex_init(&state->open_mutex);
3245 file->private_data = card; 3246 file->private_data = card;
3246 3247
3247 down(&state->open_sem); 3248 mutex_lock(&state->open_mutex);
3248 3249
3249 /* set default sample format. According to OSS Programmer's Guide /dev/dsp 3250 /* set default sample format. According to OSS Programmer's Guide /dev/dsp
3250 should be default to unsigned 8-bits, mono, with sample rate 8kHz and 3251 should be default to unsigned 8-bits, mono, with sample rate 8kHz and
@@ -3260,7 +3261,7 @@ static int cs_open(struct inode *inode, struct file *file)
3260 cs_set_divisor(dmabuf); 3261 cs_set_divisor(dmabuf);
3261 3262
3262 state->open_mode |= FMODE_READ; 3263 state->open_mode |= FMODE_READ;
3263 up(&state->open_sem); 3264 mutex_unlock(&state->open_mutex);
3264 } 3265 }
3265 if(file->f_mode & FMODE_WRITE) 3266 if(file->f_mode & FMODE_WRITE)
3266 { 3267 {
@@ -3271,7 +3272,7 @@ static int cs_open(struct inode *inode, struct file *file)
3271 if (state == NULL) 3272 if (state == NULL)
3272 return -ENOMEM; 3273 return -ENOMEM;
3273 memset(state, 0, sizeof(struct cs_state)); 3274 memset(state, 0, sizeof(struct cs_state));
3274 init_MUTEX(&state->sem); 3275 mutex_init(&state->sem);
3275 dmabuf = &state->dmabuf; 3276 dmabuf = &state->dmabuf;
3276 dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); 3277 dmabuf->pbuf = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
3277 if(dmabuf->pbuf==NULL) 3278 if(dmabuf->pbuf==NULL)
@@ -3312,10 +3313,10 @@ static int cs_open(struct inode *inode, struct file *file)
3312 state->virt = 1; 3313 state->virt = 1;
3313 state->magic = CS_STATE_MAGIC; 3314 state->magic = CS_STATE_MAGIC;
3314 init_waitqueue_head(&dmabuf->wait); 3315 init_waitqueue_head(&dmabuf->wait);
3315 init_MUTEX(&state->open_sem); 3316 mutex_init(&state->open_mutex);
3316 file->private_data = card; 3317 file->private_data = card;
3317 3318
3318 down(&state->open_sem); 3319 mutex_lock(&state->open_mutex);
3319 3320
3320 /* set default sample format. According to OSS Programmer's Guide /dev/dsp 3321 /* set default sample format. According to OSS Programmer's Guide /dev/dsp
3321 should be default to unsigned 8-bits, mono, with sample rate 8kHz and 3322 should be default to unsigned 8-bits, mono, with sample rate 8kHz and
@@ -3331,7 +3332,7 @@ static int cs_open(struct inode *inode, struct file *file)
3331 cs_set_divisor(dmabuf); 3332 cs_set_divisor(dmabuf);
3332 3333
3333 state->open_mode |= FMODE_WRITE; 3334 state->open_mode |= FMODE_WRITE;
3334 up(&state->open_sem); 3335 mutex_unlock(&state->open_mutex);
3335 if((ret = prog_dmabuf(state))) 3336 if((ret = prog_dmabuf(state)))
3336 return ret; 3337 return ret;
3337 } 3338 }
@@ -3363,14 +3364,14 @@ static int cs_release(struct inode *inode, struct file *file)
3363 cs_clear_tail(state); 3364 cs_clear_tail(state);
3364 drain_dac(state, file->f_flags & O_NONBLOCK); 3365 drain_dac(state, file->f_flags & O_NONBLOCK);
3365 /* stop DMA state machine and free DMA buffers/channels */ 3366 /* stop DMA state machine and free DMA buffers/channels */
3366 down(&state->open_sem); 3367 mutex_lock(&state->open_mutex);
3367 stop_dac(state); 3368 stop_dac(state);
3368 dealloc_dmabuf(state); 3369 dealloc_dmabuf(state);
3369 state->card->free_pcm_channel(state->card, dmabuf->channel->num); 3370 state->card->free_pcm_channel(state->card, dmabuf->channel->num);
3370 free_page((unsigned long)state->dmabuf.pbuf); 3371 free_page((unsigned long)state->dmabuf.pbuf);
3371 3372
3372 /* we're covered by the open_sem */ 3373 /* we're covered by the open_mutex */
3373 up(&state->open_sem); 3374 mutex_unlock(&state->open_mutex);
3374 state->card->states[state->virt] = NULL; 3375 state->card->states[state->virt] = NULL;
3375 state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); 3376 state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
3376 3377
@@ -3395,14 +3396,14 @@ static int cs_release(struct inode *inode, struct file *file)
3395 { 3396 {
3396 CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") ); 3397 CS_DBGOUT(CS_RELEASE, 2, printk("cs46xx: cs_release() FMODE_READ\n") );
3397 dmabuf = &state->dmabuf; 3398 dmabuf = &state->dmabuf;
3398 down(&state->open_sem); 3399 mutex_lock(&state->open_mutex);
3399 stop_adc(state); 3400 stop_adc(state);
3400 dealloc_dmabuf(state); 3401 dealloc_dmabuf(state);
3401 state->card->free_pcm_channel(state->card, dmabuf->channel->num); 3402 state->card->free_pcm_channel(state->card, dmabuf->channel->num);
3402 free_page((unsigned long)state->dmabuf.pbuf); 3403 free_page((unsigned long)state->dmabuf.pbuf);
3403 3404
3404 /* we're covered by the open_sem */ 3405 /* we're covered by the open_mutex */
3405 up(&state->open_sem); 3406 mutex_unlock(&state->open_mutex);
3406 state->card->states[state->virt] = NULL; 3407 state->card->states[state->virt] = NULL;
3407 state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE); 3408 state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
3408 3409
@@ -5507,7 +5508,7 @@ static int __devinit cs46xx_probe(struct pci_dev *pci_dev,
5507 } 5508 }
5508 5509
5509 init_waitqueue_head(&card->midi.open_wait); 5510 init_waitqueue_head(&card->midi.open_wait);
5510 init_MUTEX(&card->midi.open_sem); 5511 mutex_init(&card->midi.open_mutex);
5511 init_waitqueue_head(&card->midi.iwait); 5512 init_waitqueue_head(&card->midi.iwait);
5512 init_waitqueue_head(&card->midi.owait); 5513 init_waitqueue_head(&card->midi.owait);
5513 cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST); 5514 cs461x_pokeBA0(card, BA0_MIDCR, MIDCR_MRST);