aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/trident.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/trident.c')
-rw-r--r--sound/oss/trident.c62
1 files changed, 32 insertions, 30 deletions
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index a21c663e7e12..e61a454a8150 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -190,7 +190,7 @@
190 * 190 *
191 * Lock order (high->low) 191 * Lock order (high->low)
192 * lock - hardware lock 192 * lock - hardware lock
193 * open_sem - guard opens 193 * open_mutex - guard opens
194 * sem - guard dmabuf, write re-entry etc 194 * sem - guard dmabuf, write re-entry etc
195 */ 195 */
196 196
@@ -216,6 +216,8 @@
216#include <linux/pm.h> 216#include <linux/pm.h>
217#include <linux/gameport.h> 217#include <linux/gameport.h>
218#include <linux/kernel.h> 218#include <linux/kernel.h>
219#include <linux/mutex.h>
220
219#include <asm/uaccess.h> 221#include <asm/uaccess.h>
220#include <asm/io.h> 222#include <asm/io.h>
221#include <asm/dma.h> 223#include <asm/dma.h>
@@ -349,7 +351,7 @@ struct trident_state {
349 unsigned chans_num; 351 unsigned chans_num;
350 unsigned long fmt_flag; 352 unsigned long fmt_flag;
351 /* Guard against mmap/write/read races */ 353 /* Guard against mmap/write/read races */
352 struct semaphore sem; 354 struct mutex sem;
353 355
354}; 356};
355 357
@@ -402,7 +404,7 @@ struct trident_card {
402 struct trident_card *next; 404 struct trident_card *next;
403 405
404 /* single open lock mechanism, only used for recording */ 406 /* single open lock mechanism, only used for recording */
405 struct semaphore open_sem; 407 struct mutex open_mutex;
406 408
407 /* The trident has a certain amount of cross channel interaction 409 /* The trident has a certain amount of cross channel interaction
408 so we use a single per card lock */ 410 so we use a single per card lock */
@@ -1881,7 +1883,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
1881 if (!access_ok(VERIFY_WRITE, buffer, count)) 1883 if (!access_ok(VERIFY_WRITE, buffer, count))
1882 return -EFAULT; 1884 return -EFAULT;
1883 1885
1884 down(&state->sem); 1886 mutex_lock(&state->sem);
1885 if (!dmabuf->ready && (ret = prog_dmabuf_record(state))) 1887 if (!dmabuf->ready && (ret = prog_dmabuf_record(state)))
1886 goto out; 1888 goto out;
1887 1889
@@ -1913,7 +1915,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
1913 goto out; 1915 goto out;
1914 } 1916 }
1915 1917
1916 up(&state->sem); 1918 mutex_unlock(&state->sem);
1917 /* No matter how much space left in the buffer, */ 1919 /* No matter how much space left in the buffer, */
1918 /* we have to wait until CSO == ESO/2 or CSO == ESO */ 1920 /* we have to wait until CSO == ESO/2 or CSO == ESO */
1919 /* when address engine interrupts */ 1921 /* when address engine interrupts */
@@ -1940,7 +1942,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
1940 ret = -ERESTARTSYS; 1942 ret = -ERESTARTSYS;
1941 goto out; 1943 goto out;
1942 } 1944 }
1943 down(&state->sem); 1945 mutex_lock(&state->sem);
1944 if (dmabuf->mapped) { 1946 if (dmabuf->mapped) {
1945 if (!ret) 1947 if (!ret)
1946 ret = -ENXIO; 1948 ret = -ENXIO;
@@ -1968,7 +1970,7 @@ trident_read(struct file *file, char __user *buffer, size_t count, loff_t * ppos
1968 start_adc(state); 1970 start_adc(state);
1969 } 1971 }
1970out: 1972out:
1971 up(&state->sem); 1973 mutex_unlock(&state->sem);
1972 return ret; 1974 return ret;
1973} 1975}
1974 1976
@@ -1996,7 +1998,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
1996 * Guard against an mmap or ioctl while writing 1998 * Guard against an mmap or ioctl while writing
1997 */ 1999 */
1998 2000
1999 down(&state->sem); 2001 mutex_lock(&state->sem);
2000 2002
2001 if (dmabuf->mapped) { 2003 if (dmabuf->mapped) {
2002 ret = -ENXIO; 2004 ret = -ENXIO;
@@ -2045,7 +2047,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
2045 tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2); 2047 tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
2046 tmo >>= sample_shift[dmabuf->fmt]; 2048 tmo >>= sample_shift[dmabuf->fmt];
2047 unlock_set_fmt(state); 2049 unlock_set_fmt(state);
2048 up(&state->sem); 2050 mutex_unlock(&state->sem);
2049 2051
2050 /* There are two situations when sleep_on_timeout */ 2052 /* There are two situations when sleep_on_timeout */
2051 /* returns, one is when the interrupt is serviced */ 2053 /* returns, one is when the interrupt is serviced */
@@ -2073,7 +2075,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
2073 ret = -ERESTARTSYS; 2075 ret = -ERESTARTSYS;
2074 goto out_nolock; 2076 goto out_nolock;
2075 } 2077 }
2076 down(&state->sem); 2078 mutex_lock(&state->sem);
2077 if (dmabuf->mapped) { 2079 if (dmabuf->mapped) {
2078 if (!ret) 2080 if (!ret)
2079 ret = -ENXIO; 2081 ret = -ENXIO;
@@ -2131,7 +2133,7 @@ trident_write(struct file *file, const char __user *buffer, size_t count, loff_t
2131 start_dac(state); 2133 start_dac(state);
2132 } 2134 }
2133out: 2135out:
2134 up(&state->sem); 2136 mutex_unlock(&state->sem);
2135out_nolock: 2137out_nolock:
2136 return ret; 2138 return ret;
2137} 2139}
@@ -2152,24 +2154,24 @@ trident_poll(struct file *file, struct poll_table_struct *wait)
2152 * prog_dmabuf events 2154 * prog_dmabuf events
2153 */ 2155 */
2154 2156
2155 down(&state->sem); 2157 mutex_lock(&state->sem);
2156 2158
2157 if (file->f_mode & FMODE_WRITE) { 2159 if (file->f_mode & FMODE_WRITE) {
2158 if (!dmabuf->ready && prog_dmabuf_playback(state)) { 2160 if (!dmabuf->ready && prog_dmabuf_playback(state)) {
2159 up(&state->sem); 2161 mutex_unlock(&state->sem);
2160 return 0; 2162 return 0;
2161 } 2163 }
2162 poll_wait(file, &dmabuf->wait, wait); 2164 poll_wait(file, &dmabuf->wait, wait);
2163 } 2165 }
2164 if (file->f_mode & FMODE_READ) { 2166 if (file->f_mode & FMODE_READ) {
2165 if (!dmabuf->ready && prog_dmabuf_record(state)) { 2167 if (!dmabuf->ready && prog_dmabuf_record(state)) {
2166 up(&state->sem); 2168 mutex_unlock(&state->sem);
2167 return 0; 2169 return 0;
2168 } 2170 }
2169 poll_wait(file, &dmabuf->wait, wait); 2171 poll_wait(file, &dmabuf->wait, wait);
2170 } 2172 }
2171 2173
2172 up(&state->sem); 2174 mutex_unlock(&state->sem);
2173 2175
2174 spin_lock_irqsave(&state->card->lock, flags); 2176 spin_lock_irqsave(&state->card->lock, flags);
2175 trident_update_ptr(state); 2177 trident_update_ptr(state);
@@ -2207,7 +2209,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma)
2207 * a read or write against an mmap. 2209 * a read or write against an mmap.
2208 */ 2210 */
2209 2211
2210 down(&state->sem); 2212 mutex_lock(&state->sem);
2211 2213
2212 if (vma->vm_flags & VM_WRITE) { 2214 if (vma->vm_flags & VM_WRITE) {
2213 if ((ret = prog_dmabuf_playback(state)) != 0) 2215 if ((ret = prog_dmabuf_playback(state)) != 0)
@@ -2232,7 +2234,7 @@ trident_mmap(struct file *file, struct vm_area_struct *vma)
2232 dmabuf->mapped = 1; 2234 dmabuf->mapped = 1;
2233 ret = 0; 2235 ret = 0;
2234out: 2236out:
2235 up(&state->sem); 2237 mutex_unlock(&state->sem);
2236 return ret; 2238 return ret;
2237} 2239}
2238 2240
@@ -2429,15 +2431,15 @@ trident_ioctl(struct inode *inode, struct file *file,
2429 unlock_set_fmt(state); 2431 unlock_set_fmt(state);
2430 break; 2432 break;
2431 } 2433 }
2432 down(&state->card->open_sem); 2434 mutex_lock(&state->card->open_mutex);
2433 ret = ali_allocate_other_states_resources(state, 6); 2435 ret = ali_allocate_other_states_resources(state, 6);
2434 if (ret < 0) { 2436 if (ret < 0) {
2435 up(&state->card->open_sem); 2437 mutex_unlock(&state->card->open_mutex);
2436 unlock_set_fmt(state); 2438 unlock_set_fmt(state);
2437 break; 2439 break;
2438 } 2440 }
2439 state->card->multi_channel_use_count++; 2441 state->card->multi_channel_use_count++;
2440 up(&state->card->open_sem); 2442 mutex_unlock(&state->card->open_mutex);
2441 } else 2443 } else
2442 val = 2; /*yield to 2-channels */ 2444 val = 2; /*yield to 2-channels */
2443 } else 2445 } else
@@ -2727,11 +2729,11 @@ trident_open(struct inode *inode, struct file *file)
2727 2729
2728 /* find an available virtual channel (instance of /dev/dsp) */ 2730 /* find an available virtual channel (instance of /dev/dsp) */
2729 while (card != NULL) { 2731 while (card != NULL) {
2730 down(&card->open_sem); 2732 mutex_lock(&card->open_mutex);
2731 if (file->f_mode & FMODE_READ) { 2733 if (file->f_mode & FMODE_READ) {
2732 /* Skip opens on cards that are in 6 channel mode */ 2734 /* Skip opens on cards that are in 6 channel mode */
2733 if (card->multi_channel_use_count > 0) { 2735 if (card->multi_channel_use_count > 0) {
2734 up(&card->open_sem); 2736 mutex_unlock(&card->open_mutex);
2735 card = card->next; 2737 card = card->next;
2736 continue; 2738 continue;
2737 } 2739 }
@@ -2740,16 +2742,16 @@ trident_open(struct inode *inode, struct file *file)
2740 if (card->states[i] == NULL) { 2742 if (card->states[i] == NULL) {
2741 state = card->states[i] = kmalloc(sizeof(*state), GFP_KERNEL); 2743 state = card->states[i] = kmalloc(sizeof(*state), GFP_KERNEL);
2742 if (state == NULL) { 2744 if (state == NULL) {
2743 up(&card->open_sem); 2745 mutex_unlock(&card->open_mutex);
2744 return -ENOMEM; 2746 return -ENOMEM;
2745 } 2747 }
2746 memset(state, 0, sizeof(*state)); 2748 memset(state, 0, sizeof(*state));
2747 init_MUTEX(&state->sem); 2749 mutex_init(&state->sem);
2748 dmabuf = &state->dmabuf; 2750 dmabuf = &state->dmabuf;
2749 goto found_virt; 2751 goto found_virt;
2750 } 2752 }
2751 } 2753 }
2752 up(&card->open_sem); 2754 mutex_unlock(&card->open_mutex);
2753 card = card->next; 2755 card = card->next;
2754 } 2756 }
2755 /* no more virtual channel avaiable */ 2757 /* no more virtual channel avaiable */
@@ -2816,7 +2818,7 @@ trident_open(struct inode *inode, struct file *file)
2816 } 2818 }
2817 2819
2818 state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); 2820 state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
2819 up(&card->open_sem); 2821 mutex_unlock(&card->open_mutex);
2820 2822
2821 pr_debug("trident: open virtual channel %d, hard channel %d\n", 2823 pr_debug("trident: open virtual channel %d, hard channel %d\n",
2822 state->virt, dmabuf->channel->num); 2824 state->virt, dmabuf->channel->num);
@@ -2845,7 +2847,7 @@ trident_release(struct inode *inode, struct file *file)
2845 state->virt, dmabuf->channel->num); 2847 state->virt, dmabuf->channel->num);
2846 2848
2847 /* stop DMA state machine and free DMA buffers/channels */ 2849 /* stop DMA state machine and free DMA buffers/channels */
2848 down(&card->open_sem); 2850 mutex_lock(&card->open_mutex);
2849 2851
2850 if (file->f_mode & FMODE_WRITE) { 2852 if (file->f_mode & FMODE_WRITE) {
2851 stop_dac(state); 2853 stop_dac(state);
@@ -2878,8 +2880,8 @@ trident_release(struct inode *inode, struct file *file)
2878 card->states[state->virt] = NULL; 2880 card->states[state->virt] = NULL;
2879 kfree(state); 2881 kfree(state);
2880 2882
2881 /* we're covered by the open_sem */ 2883 /* we're covered by the open_mutex */
2882 up(&card->open_sem); 2884 mutex_unlock(&card->open_mutex);
2883 2885
2884 return 0; 2886 return 0;
2885} 2887}
@@ -4405,7 +4407,7 @@ trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
4405 card->banks[BANK_B].addresses = &bank_b_addrs; 4407 card->banks[BANK_B].addresses = &bank_b_addrs;
4406 card->banks[BANK_B].bitmap = 0UL; 4408 card->banks[BANK_B].bitmap = 0UL;
4407 4409
4408 init_MUTEX(&card->open_sem); 4410 mutex_init(&card->open_mutex);
4409 spin_lock_init(&card->lock); 4411 spin_lock_init(&card->lock);
4410 init_timer(&card->timer); 4412 init_timer(&card->timer);
4411 4413