diff options
Diffstat (limited to 'sound/oss/es1370.c')
-rw-r--r-- | sound/oss/es1370.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/sound/oss/es1370.c b/sound/oss/es1370.c index ae55c536613a..094f569cc6e0 100644 --- a/sound/oss/es1370.c +++ b/sound/oss/es1370.c | |||
@@ -157,6 +157,7 @@ | |||
157 | #include <linux/gameport.h> | 157 | #include <linux/gameport.h> |
158 | #include <linux/wait.h> | 158 | #include <linux/wait.h> |
159 | #include <linux/dma-mapping.h> | 159 | #include <linux/dma-mapping.h> |
160 | #include <linux/mutex.h> | ||
160 | 161 | ||
161 | #include <asm/io.h> | 162 | #include <asm/io.h> |
162 | #include <asm/page.h> | 163 | #include <asm/page.h> |
@@ -346,7 +347,7 @@ struct es1370_state { | |||
346 | unsigned sctrl; | 347 | unsigned sctrl; |
347 | 348 | ||
348 | spinlock_t lock; | 349 | spinlock_t lock; |
349 | struct semaphore open_sem; | 350 | struct mutex open_mutex; |
350 | mode_t open_mode; | 351 | mode_t open_mode; |
351 | wait_queue_head_t open_wait; | 352 | wait_queue_head_t open_wait; |
352 | 353 | ||
@@ -393,7 +394,7 @@ struct es1370_state { | |||
393 | struct gameport *gameport; | 394 | struct gameport *gameport; |
394 | #endif | 395 | #endif |
395 | 396 | ||
396 | struct semaphore sem; | 397 | struct mutex mutex; |
397 | }; | 398 | }; |
398 | 399 | ||
399 | /* --------------------------------------------------------------------- */ | 400 | /* --------------------------------------------------------------------- */ |
@@ -1159,7 +1160,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, | |||
1159 | return -ENXIO; | 1160 | return -ENXIO; |
1160 | if (!access_ok(VERIFY_WRITE, buffer, count)) | 1161 | if (!access_ok(VERIFY_WRITE, buffer, count)) |
1161 | return -EFAULT; | 1162 | return -EFAULT; |
1162 | down(&s->sem); | 1163 | mutex_lock(&s->mutex); |
1163 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | 1164 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) |
1164 | goto out; | 1165 | goto out; |
1165 | 1166 | ||
@@ -1183,14 +1184,14 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, | |||
1183 | ret = -EAGAIN; | 1184 | ret = -EAGAIN; |
1184 | goto out; | 1185 | goto out; |
1185 | } | 1186 | } |
1186 | up(&s->sem); | 1187 | mutex_unlock(&s->mutex); |
1187 | schedule(); | 1188 | schedule(); |
1188 | if (signal_pending(current)) { | 1189 | if (signal_pending(current)) { |
1189 | if (!ret) | 1190 | if (!ret) |
1190 | ret = -ERESTARTSYS; | 1191 | ret = -ERESTARTSYS; |
1191 | goto out; | 1192 | goto out; |
1192 | } | 1193 | } |
1193 | down(&s->sem); | 1194 | mutex_lock(&s->mutex); |
1194 | if (s->dma_adc.mapped) | 1195 | if (s->dma_adc.mapped) |
1195 | { | 1196 | { |
1196 | ret = -ENXIO; | 1197 | ret = -ENXIO; |
@@ -1215,7 +1216,7 @@ static ssize_t es1370_read(struct file *file, char __user *buffer, size_t count, | |||
1215 | start_adc(s); | 1216 | start_adc(s); |
1216 | } | 1217 | } |
1217 | out: | 1218 | out: |
1218 | up(&s->sem); | 1219 | mutex_unlock(&s->mutex); |
1219 | remove_wait_queue(&s->dma_adc.wait, &wait); | 1220 | remove_wait_queue(&s->dma_adc.wait, &wait); |
1220 | set_current_state(TASK_RUNNING); | 1221 | set_current_state(TASK_RUNNING); |
1221 | return ret; | 1222 | return ret; |
@@ -1235,7 +1236,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t | |||
1235 | return -ENXIO; | 1236 | return -ENXIO; |
1236 | if (!access_ok(VERIFY_READ, buffer, count)) | 1237 | if (!access_ok(VERIFY_READ, buffer, count)) |
1237 | return -EFAULT; | 1238 | return -EFAULT; |
1238 | down(&s->sem); | 1239 | mutex_lock(&s->mutex); |
1239 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | 1240 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) |
1240 | goto out; | 1241 | goto out; |
1241 | ret = 0; | 1242 | ret = 0; |
@@ -1263,14 +1264,14 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t | |||
1263 | ret = -EAGAIN; | 1264 | ret = -EAGAIN; |
1264 | goto out; | 1265 | goto out; |
1265 | } | 1266 | } |
1266 | up(&s->sem); | 1267 | mutex_unlock(&s->mutex); |
1267 | schedule(); | 1268 | schedule(); |
1268 | if (signal_pending(current)) { | 1269 | if (signal_pending(current)) { |
1269 | if (!ret) | 1270 | if (!ret) |
1270 | ret = -ERESTARTSYS; | 1271 | ret = -ERESTARTSYS; |
1271 | goto out; | 1272 | goto out; |
1272 | } | 1273 | } |
1273 | down(&s->sem); | 1274 | mutex_lock(&s->mutex); |
1274 | if (s->dma_dac2.mapped) | 1275 | if (s->dma_dac2.mapped) |
1275 | { | 1276 | { |
1276 | ret = -ENXIO; | 1277 | ret = -ENXIO; |
@@ -1296,7 +1297,7 @@ static ssize_t es1370_write(struct file *file, const char __user *buffer, size_t | |||
1296 | start_dac2(s); | 1297 | start_dac2(s); |
1297 | } | 1298 | } |
1298 | out: | 1299 | out: |
1299 | up(&s->sem); | 1300 | mutex_unlock(&s->mutex); |
1300 | remove_wait_queue(&s->dma_dac2.wait, &wait); | 1301 | remove_wait_queue(&s->dma_dac2.wait, &wait); |
1301 | set_current_state(TASK_RUNNING); | 1302 | set_current_state(TASK_RUNNING); |
1302 | return ret; | 1303 | return ret; |
@@ -1348,7 +1349,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma) | |||
1348 | 1349 | ||
1349 | VALIDATE_STATE(s); | 1350 | VALIDATE_STATE(s); |
1350 | lock_kernel(); | 1351 | lock_kernel(); |
1351 | down(&s->sem); | 1352 | mutex_lock(&s->mutex); |
1352 | if (vma->vm_flags & VM_WRITE) { | 1353 | if (vma->vm_flags & VM_WRITE) { |
1353 | if ((ret = prog_dmabuf_dac2(s)) != 0) { | 1354 | if ((ret = prog_dmabuf_dac2(s)) != 0) { |
1354 | goto out; | 1355 | goto out; |
@@ -1380,7 +1381,7 @@ static int es1370_mmap(struct file *file, struct vm_area_struct *vma) | |||
1380 | } | 1381 | } |
1381 | db->mapped = 1; | 1382 | db->mapped = 1; |
1382 | out: | 1383 | out: |
1383 | up(&s->sem); | 1384 | mutex_unlock(&s->mutex); |
1384 | unlock_kernel(); | 1385 | unlock_kernel(); |
1385 | return ret; | 1386 | return ret; |
1386 | } | 1387 | } |
@@ -1752,21 +1753,21 @@ static int es1370_open(struct inode *inode, struct file *file) | |||
1752 | VALIDATE_STATE(s); | 1753 | VALIDATE_STATE(s); |
1753 | file->private_data = s; | 1754 | file->private_data = s; |
1754 | /* wait for device to become free */ | 1755 | /* wait for device to become free */ |
1755 | down(&s->open_sem); | 1756 | mutex_lock(&s->open_mutex); |
1756 | while (s->open_mode & file->f_mode) { | 1757 | while (s->open_mode & file->f_mode) { |
1757 | if (file->f_flags & O_NONBLOCK) { | 1758 | if (file->f_flags & O_NONBLOCK) { |
1758 | up(&s->open_sem); | 1759 | mutex_unlock(&s->open_mutex); |
1759 | return -EBUSY; | 1760 | return -EBUSY; |
1760 | } | 1761 | } |
1761 | add_wait_queue(&s->open_wait, &wait); | 1762 | add_wait_queue(&s->open_wait, &wait); |
1762 | __set_current_state(TASK_INTERRUPTIBLE); | 1763 | __set_current_state(TASK_INTERRUPTIBLE); |
1763 | up(&s->open_sem); | 1764 | mutex_unlock(&s->open_mutex); |
1764 | schedule(); | 1765 | schedule(); |
1765 | remove_wait_queue(&s->open_wait, &wait); | 1766 | remove_wait_queue(&s->open_wait, &wait); |
1766 | set_current_state(TASK_RUNNING); | 1767 | set_current_state(TASK_RUNNING); |
1767 | if (signal_pending(current)) | 1768 | if (signal_pending(current)) |
1768 | return -ERESTARTSYS; | 1769 | return -ERESTARTSYS; |
1769 | down(&s->open_sem); | 1770 | mutex_lock(&s->open_mutex); |
1770 | } | 1771 | } |
1771 | spin_lock_irqsave(&s->lock, flags); | 1772 | spin_lock_irqsave(&s->lock, flags); |
1772 | if (!(s->open_mode & (FMODE_READ|FMODE_WRITE))) | 1773 | if (!(s->open_mode & (FMODE_READ|FMODE_WRITE))) |
@@ -1793,8 +1794,8 @@ static int es1370_open(struct inode *inode, struct file *file) | |||
1793 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | 1794 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); |
1794 | spin_unlock_irqrestore(&s->lock, flags); | 1795 | spin_unlock_irqrestore(&s->lock, flags); |
1795 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | 1796 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); |
1796 | up(&s->open_sem); | 1797 | mutex_unlock(&s->open_mutex); |
1797 | init_MUTEX(&s->sem); | 1798 | mutex_init(&s->mutex); |
1798 | return nonseekable_open(inode, file); | 1799 | return nonseekable_open(inode, file); |
1799 | } | 1800 | } |
1800 | 1801 | ||
@@ -1806,7 +1807,7 @@ static int es1370_release(struct inode *inode, struct file *file) | |||
1806 | lock_kernel(); | 1807 | lock_kernel(); |
1807 | if (file->f_mode & FMODE_WRITE) | 1808 | if (file->f_mode & FMODE_WRITE) |
1808 | drain_dac2(s, file->f_flags & O_NONBLOCK); | 1809 | drain_dac2(s, file->f_flags & O_NONBLOCK); |
1809 | down(&s->open_sem); | 1810 | mutex_lock(&s->open_mutex); |
1810 | if (file->f_mode & FMODE_WRITE) { | 1811 | if (file->f_mode & FMODE_WRITE) { |
1811 | stop_dac2(s); | 1812 | stop_dac2(s); |
1812 | synchronize_irq(s->irq); | 1813 | synchronize_irq(s->irq); |
@@ -1818,7 +1819,7 @@ static int es1370_release(struct inode *inode, struct file *file) | |||
1818 | } | 1819 | } |
1819 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | 1820 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); |
1820 | wake_up(&s->open_wait); | 1821 | wake_up(&s->open_wait); |
1821 | up(&s->open_sem); | 1822 | mutex_unlock(&s->open_mutex); |
1822 | unlock_kernel(); | 1823 | unlock_kernel(); |
1823 | return 0; | 1824 | return 0; |
1824 | } | 1825 | } |
@@ -2198,21 +2199,21 @@ static int es1370_open_dac(struct inode *inode, struct file *file) | |||
2198 | return -EINVAL; | 2199 | return -EINVAL; |
2199 | file->private_data = s; | 2200 | file->private_data = s; |
2200 | /* wait for device to become free */ | 2201 | /* wait for device to become free */ |
2201 | down(&s->open_sem); | 2202 | mutex_lock(&s->open_mutex); |
2202 | while (s->open_mode & FMODE_DAC) { | 2203 | while (s->open_mode & FMODE_DAC) { |
2203 | if (file->f_flags & O_NONBLOCK) { | 2204 | if (file->f_flags & O_NONBLOCK) { |
2204 | up(&s->open_sem); | 2205 | mutex_unlock(&s->open_mutex); |
2205 | return -EBUSY; | 2206 | return -EBUSY; |
2206 | } | 2207 | } |
2207 | add_wait_queue(&s->open_wait, &wait); | 2208 | add_wait_queue(&s->open_wait, &wait); |
2208 | __set_current_state(TASK_INTERRUPTIBLE); | 2209 | __set_current_state(TASK_INTERRUPTIBLE); |
2209 | up(&s->open_sem); | 2210 | mutex_unlock(&s->open_mutex); |
2210 | schedule(); | 2211 | schedule(); |
2211 | remove_wait_queue(&s->open_wait, &wait); | 2212 | remove_wait_queue(&s->open_wait, &wait); |
2212 | set_current_state(TASK_RUNNING); | 2213 | set_current_state(TASK_RUNNING); |
2213 | if (signal_pending(current)) | 2214 | if (signal_pending(current)) |
2214 | return -ERESTARTSYS; | 2215 | return -ERESTARTSYS; |
2215 | down(&s->open_sem); | 2216 | mutex_lock(&s->open_mutex); |
2216 | } | 2217 | } |
2217 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; | 2218 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; |
2218 | s->dma_dac1.enabled = 1; | 2219 | s->dma_dac1.enabled = 1; |
@@ -2227,7 +2228,7 @@ static int es1370_open_dac(struct inode *inode, struct file *file) | |||
2227 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); | 2228 | outl(s->ctrl, s->io+ES1370_REG_CONTROL); |
2228 | spin_unlock_irqrestore(&s->lock, flags); | 2229 | spin_unlock_irqrestore(&s->lock, flags); |
2229 | s->open_mode |= FMODE_DAC; | 2230 | s->open_mode |= FMODE_DAC; |
2230 | up(&s->open_sem); | 2231 | mutex_unlock(&s->open_mutex); |
2231 | return nonseekable_open(inode, file); | 2232 | return nonseekable_open(inode, file); |
2232 | } | 2233 | } |
2233 | 2234 | ||
@@ -2238,12 +2239,12 @@ static int es1370_release_dac(struct inode *inode, struct file *file) | |||
2238 | VALIDATE_STATE(s); | 2239 | VALIDATE_STATE(s); |
2239 | lock_kernel(); | 2240 | lock_kernel(); |
2240 | drain_dac1(s, file->f_flags & O_NONBLOCK); | 2241 | drain_dac1(s, file->f_flags & O_NONBLOCK); |
2241 | down(&s->open_sem); | 2242 | mutex_lock(&s->open_mutex); |
2242 | stop_dac1(s); | 2243 | stop_dac1(s); |
2243 | dealloc_dmabuf(s, &s->dma_dac1); | 2244 | dealloc_dmabuf(s, &s->dma_dac1); |
2244 | s->open_mode &= ~FMODE_DAC; | 2245 | s->open_mode &= ~FMODE_DAC; |
2245 | wake_up(&s->open_wait); | 2246 | wake_up(&s->open_wait); |
2246 | up(&s->open_sem); | 2247 | mutex_unlock(&s->open_mutex); |
2247 | unlock_kernel(); | 2248 | unlock_kernel(); |
2248 | return 0; | 2249 | return 0; |
2249 | } | 2250 | } |
@@ -2430,21 +2431,21 @@ static int es1370_midi_open(struct inode *inode, struct file *file) | |||
2430 | VALIDATE_STATE(s); | 2431 | VALIDATE_STATE(s); |
2431 | file->private_data = s; | 2432 | file->private_data = s; |
2432 | /* wait for device to become free */ | 2433 | /* wait for device to become free */ |
2433 | down(&s->open_sem); | 2434 | mutex_lock(&s->open_mutex); |
2434 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | 2435 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { |
2435 | if (file->f_flags & O_NONBLOCK) { | 2436 | if (file->f_flags & O_NONBLOCK) { |
2436 | up(&s->open_sem); | 2437 | mutex_unlock(&s->open_mutex); |
2437 | return -EBUSY; | 2438 | return -EBUSY; |
2438 | } | 2439 | } |
2439 | add_wait_queue(&s->open_wait, &wait); | 2440 | add_wait_queue(&s->open_wait, &wait); |
2440 | __set_current_state(TASK_INTERRUPTIBLE); | 2441 | __set_current_state(TASK_INTERRUPTIBLE); |
2441 | up(&s->open_sem); | 2442 | mutex_unlock(&s->open_mutex); |
2442 | schedule(); | 2443 | schedule(); |
2443 | remove_wait_queue(&s->open_wait, &wait); | 2444 | remove_wait_queue(&s->open_wait, &wait); |
2444 | set_current_state(TASK_RUNNING); | 2445 | set_current_state(TASK_RUNNING); |
2445 | if (signal_pending(current)) | 2446 | if (signal_pending(current)) |
2446 | return -ERESTARTSYS; | 2447 | return -ERESTARTSYS; |
2447 | down(&s->open_sem); | 2448 | mutex_lock(&s->open_mutex); |
2448 | } | 2449 | } |
2449 | spin_lock_irqsave(&s->lock, flags); | 2450 | spin_lock_irqsave(&s->lock, flags); |
2450 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2451 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
@@ -2465,7 +2466,7 @@ static int es1370_midi_open(struct inode *inode, struct file *file) | |||
2465 | es1370_handle_midi(s); | 2466 | es1370_handle_midi(s); |
2466 | spin_unlock_irqrestore(&s->lock, flags); | 2467 | spin_unlock_irqrestore(&s->lock, flags); |
2467 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | 2468 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); |
2468 | up(&s->open_sem); | 2469 | mutex_unlock(&s->open_mutex); |
2469 | return nonseekable_open(inode, file); | 2470 | return nonseekable_open(inode, file); |
2470 | } | 2471 | } |
2471 | 2472 | ||
@@ -2499,7 +2500,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) | |||
2499 | remove_wait_queue(&s->midi.owait, &wait); | 2500 | remove_wait_queue(&s->midi.owait, &wait); |
2500 | set_current_state(TASK_RUNNING); | 2501 | set_current_state(TASK_RUNNING); |
2501 | } | 2502 | } |
2502 | down(&s->open_sem); | 2503 | mutex_lock(&s->open_mutex); |
2503 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | 2504 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); |
2504 | spin_lock_irqsave(&s->lock, flags); | 2505 | spin_lock_irqsave(&s->lock, flags); |
2505 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2506 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
@@ -2508,7 +2509,7 @@ static int es1370_midi_release(struct inode *inode, struct file *file) | |||
2508 | } | 2509 | } |
2509 | spin_unlock_irqrestore(&s->lock, flags); | 2510 | spin_unlock_irqrestore(&s->lock, flags); |
2510 | wake_up(&s->open_wait); | 2511 | wake_up(&s->open_wait); |
2511 | up(&s->open_sem); | 2512 | mutex_unlock(&s->open_mutex); |
2512 | unlock_kernel(); | 2513 | unlock_kernel(); |
2513 | return 0; | 2514 | return 0; |
2514 | } | 2515 | } |
@@ -2638,7 +2639,7 @@ static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2638 | init_waitqueue_head(&s->open_wait); | 2639 | init_waitqueue_head(&s->open_wait); |
2639 | init_waitqueue_head(&s->midi.iwait); | 2640 | init_waitqueue_head(&s->midi.iwait); |
2640 | init_waitqueue_head(&s->midi.owait); | 2641 | init_waitqueue_head(&s->midi.owait); |
2641 | init_MUTEX(&s->open_sem); | 2642 | mutex_init(&s->open_mutex); |
2642 | spin_lock_init(&s->lock); | 2643 | spin_lock_init(&s->lock); |
2643 | s->magic = ES1370_MAGIC; | 2644 | s->magic = ES1370_MAGIC; |
2644 | s->dev = pcidev; | 2645 | s->dev = pcidev; |