diff options
Diffstat (limited to 'sound/oss/es1371.c')
-rw-r--r-- | sound/oss/es1371.c | 71 |
1 files changed, 36 insertions, 35 deletions
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c index 5c697f162579..4400c8538686 100644 --- a/sound/oss/es1371.c +++ b/sound/oss/es1371.c | |||
@@ -129,6 +129,7 @@ | |||
129 | #include <linux/gameport.h> | 129 | #include <linux/gameport.h> |
130 | #include <linux/wait.h> | 130 | #include <linux/wait.h> |
131 | #include <linux/dma-mapping.h> | 131 | #include <linux/dma-mapping.h> |
132 | #include <linux/mutex.h> | ||
132 | 133 | ||
133 | #include <asm/io.h> | 134 | #include <asm/io.h> |
134 | #include <asm/page.h> | 135 | #include <asm/page.h> |
@@ -419,7 +420,7 @@ struct es1371_state { | |||
419 | unsigned dac1rate, dac2rate, adcrate; | 420 | unsigned dac1rate, dac2rate, adcrate; |
420 | 421 | ||
421 | spinlock_t lock; | 422 | spinlock_t lock; |
422 | struct semaphore open_sem; | 423 | struct mutex open_mutex; |
423 | mode_t open_mode; | 424 | mode_t open_mode; |
424 | wait_queue_head_t open_wait; | 425 | wait_queue_head_t open_wait; |
425 | 426 | ||
@@ -462,7 +463,7 @@ struct es1371_state { | |||
462 | struct gameport *gameport; | 463 | struct gameport *gameport; |
463 | #endif | 464 | #endif |
464 | 465 | ||
465 | struct semaphore sem; | 466 | struct mutex sem; |
466 | }; | 467 | }; |
467 | 468 | ||
468 | /* --------------------------------------------------------------------- */ | 469 | /* --------------------------------------------------------------------- */ |
@@ -1346,7 +1347,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, | |||
1346 | return -ENXIO; | 1347 | return -ENXIO; |
1347 | if (!access_ok(VERIFY_WRITE, buffer, count)) | 1348 | if (!access_ok(VERIFY_WRITE, buffer, count)) |
1348 | return -EFAULT; | 1349 | return -EFAULT; |
1349 | down(&s->sem); | 1350 | mutex_lock(&s->sem); |
1350 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) | 1351 | if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) |
1351 | goto out2; | 1352 | goto out2; |
1352 | 1353 | ||
@@ -1370,14 +1371,14 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, | |||
1370 | ret = -EAGAIN; | 1371 | ret = -EAGAIN; |
1371 | goto out; | 1372 | goto out; |
1372 | } | 1373 | } |
1373 | up(&s->sem); | 1374 | mutex_unlock(&s->sem); |
1374 | schedule(); | 1375 | schedule(); |
1375 | if (signal_pending(current)) { | 1376 | if (signal_pending(current)) { |
1376 | if (!ret) | 1377 | if (!ret) |
1377 | ret = -ERESTARTSYS; | 1378 | ret = -ERESTARTSYS; |
1378 | goto out2; | 1379 | goto out2; |
1379 | } | 1380 | } |
1380 | down(&s->sem); | 1381 | mutex_lock(&s->sem); |
1381 | if (s->dma_adc.mapped) | 1382 | if (s->dma_adc.mapped) |
1382 | { | 1383 | { |
1383 | ret = -ENXIO; | 1384 | ret = -ENXIO; |
@@ -1402,7 +1403,7 @@ static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, | |||
1402 | start_adc(s); | 1403 | start_adc(s); |
1403 | } | 1404 | } |
1404 | out: | 1405 | out: |
1405 | up(&s->sem); | 1406 | mutex_unlock(&s->sem); |
1406 | out2: | 1407 | out2: |
1407 | remove_wait_queue(&s->dma_adc.wait, &wait); | 1408 | remove_wait_queue(&s->dma_adc.wait, &wait); |
1408 | set_current_state(TASK_RUNNING); | 1409 | set_current_state(TASK_RUNNING); |
@@ -1423,7 +1424,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t | |||
1423 | return -ENXIO; | 1424 | return -ENXIO; |
1424 | if (!access_ok(VERIFY_READ, buffer, count)) | 1425 | if (!access_ok(VERIFY_READ, buffer, count)) |
1425 | return -EFAULT; | 1426 | return -EFAULT; |
1426 | down(&s->sem); | 1427 | mutex_lock(&s->sem); |
1427 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) | 1428 | if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) |
1428 | goto out3; | 1429 | goto out3; |
1429 | ret = 0; | 1430 | ret = 0; |
@@ -1451,14 +1452,14 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t | |||
1451 | ret = -EAGAIN; | 1452 | ret = -EAGAIN; |
1452 | goto out; | 1453 | goto out; |
1453 | } | 1454 | } |
1454 | up(&s->sem); | 1455 | mutex_unlock(&s->sem); |
1455 | schedule(); | 1456 | schedule(); |
1456 | if (signal_pending(current)) { | 1457 | if (signal_pending(current)) { |
1457 | if (!ret) | 1458 | if (!ret) |
1458 | ret = -ERESTARTSYS; | 1459 | ret = -ERESTARTSYS; |
1459 | goto out2; | 1460 | goto out2; |
1460 | } | 1461 | } |
1461 | down(&s->sem); | 1462 | mutex_lock(&s->sem); |
1462 | if (s->dma_dac2.mapped) | 1463 | if (s->dma_dac2.mapped) |
1463 | { | 1464 | { |
1464 | ret = -ENXIO; | 1465 | ret = -ENXIO; |
@@ -1484,7 +1485,7 @@ static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t | |||
1484 | start_dac2(s); | 1485 | start_dac2(s); |
1485 | } | 1486 | } |
1486 | out: | 1487 | out: |
1487 | up(&s->sem); | 1488 | mutex_unlock(&s->sem); |
1488 | out2: | 1489 | out2: |
1489 | remove_wait_queue(&s->dma_dac2.wait, &wait); | 1490 | remove_wait_queue(&s->dma_dac2.wait, &wait); |
1490 | out3: | 1491 | out3: |
@@ -1538,7 +1539,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma) | |||
1538 | 1539 | ||
1539 | VALIDATE_STATE(s); | 1540 | VALIDATE_STATE(s); |
1540 | lock_kernel(); | 1541 | lock_kernel(); |
1541 | down(&s->sem); | 1542 | mutex_lock(&s->sem); |
1542 | 1543 | ||
1543 | if (vma->vm_flags & VM_WRITE) { | 1544 | if (vma->vm_flags & VM_WRITE) { |
1544 | if ((ret = prog_dmabuf_dac2(s)) != 0) { | 1545 | if ((ret = prog_dmabuf_dac2(s)) != 0) { |
@@ -1571,7 +1572,7 @@ static int es1371_mmap(struct file *file, struct vm_area_struct *vma) | |||
1571 | } | 1572 | } |
1572 | db->mapped = 1; | 1573 | db->mapped = 1; |
1573 | out: | 1574 | out: |
1574 | up(&s->sem); | 1575 | mutex_unlock(&s->sem); |
1575 | unlock_kernel(); | 1576 | unlock_kernel(); |
1576 | return ret; | 1577 | return ret; |
1577 | } | 1578 | } |
@@ -1938,21 +1939,21 @@ static int es1371_open(struct inode *inode, struct file *file) | |||
1938 | VALIDATE_STATE(s); | 1939 | VALIDATE_STATE(s); |
1939 | file->private_data = s; | 1940 | file->private_data = s; |
1940 | /* wait for device to become free */ | 1941 | /* wait for device to become free */ |
1941 | down(&s->open_sem); | 1942 | mutex_lock(&s->open_mutex); |
1942 | while (s->open_mode & file->f_mode) { | 1943 | while (s->open_mode & file->f_mode) { |
1943 | if (file->f_flags & O_NONBLOCK) { | 1944 | if (file->f_flags & O_NONBLOCK) { |
1944 | up(&s->open_sem); | 1945 | mutex_unlock(&s->open_mutex); |
1945 | return -EBUSY; | 1946 | return -EBUSY; |
1946 | } | 1947 | } |
1947 | add_wait_queue(&s->open_wait, &wait); | 1948 | add_wait_queue(&s->open_wait, &wait); |
1948 | __set_current_state(TASK_INTERRUPTIBLE); | 1949 | __set_current_state(TASK_INTERRUPTIBLE); |
1949 | up(&s->open_sem); | 1950 | mutex_unlock(&s->open_mutex); |
1950 | schedule(); | 1951 | schedule(); |
1951 | remove_wait_queue(&s->open_wait, &wait); | 1952 | remove_wait_queue(&s->open_wait, &wait); |
1952 | set_current_state(TASK_RUNNING); | 1953 | set_current_state(TASK_RUNNING); |
1953 | if (signal_pending(current)) | 1954 | if (signal_pending(current)) |
1954 | return -ERESTARTSYS; | 1955 | return -ERESTARTSYS; |
1955 | down(&s->open_sem); | 1956 | mutex_lock(&s->open_mutex); |
1956 | } | 1957 | } |
1957 | if (file->f_mode & FMODE_READ) { | 1958 | if (file->f_mode & FMODE_READ) { |
1958 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; | 1959 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; |
@@ -1982,8 +1983,8 @@ static int es1371_open(struct inode *inode, struct file *file) | |||
1982 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | 1983 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); |
1983 | spin_unlock_irqrestore(&s->lock, flags); | 1984 | spin_unlock_irqrestore(&s->lock, flags); |
1984 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | 1985 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); |
1985 | up(&s->open_sem); | 1986 | mutex_unlock(&s->open_mutex); |
1986 | init_MUTEX(&s->sem); | 1987 | mutex_init(&s->sem); |
1987 | return nonseekable_open(inode, file); | 1988 | return nonseekable_open(inode, file); |
1988 | } | 1989 | } |
1989 | 1990 | ||
@@ -1995,7 +1996,7 @@ static int es1371_release(struct inode *inode, struct file *file) | |||
1995 | lock_kernel(); | 1996 | lock_kernel(); |
1996 | if (file->f_mode & FMODE_WRITE) | 1997 | if (file->f_mode & FMODE_WRITE) |
1997 | drain_dac2(s, file->f_flags & O_NONBLOCK); | 1998 | drain_dac2(s, file->f_flags & O_NONBLOCK); |
1998 | down(&s->open_sem); | 1999 | mutex_lock(&s->open_mutex); |
1999 | if (file->f_mode & FMODE_WRITE) { | 2000 | if (file->f_mode & FMODE_WRITE) { |
2000 | stop_dac2(s); | 2001 | stop_dac2(s); |
2001 | dealloc_dmabuf(s, &s->dma_dac2); | 2002 | dealloc_dmabuf(s, &s->dma_dac2); |
@@ -2005,7 +2006,7 @@ static int es1371_release(struct inode *inode, struct file *file) | |||
2005 | dealloc_dmabuf(s, &s->dma_adc); | 2006 | dealloc_dmabuf(s, &s->dma_adc); |
2006 | } | 2007 | } |
2007 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); | 2008 | s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); |
2008 | up(&s->open_sem); | 2009 | mutex_unlock(&s->open_mutex); |
2009 | wake_up(&s->open_wait); | 2010 | wake_up(&s->open_wait); |
2010 | unlock_kernel(); | 2011 | unlock_kernel(); |
2011 | return 0; | 2012 | return 0; |
@@ -2377,21 +2378,21 @@ static int es1371_open_dac(struct inode *inode, struct file *file) | |||
2377 | return -EINVAL; | 2378 | return -EINVAL; |
2378 | file->private_data = s; | 2379 | file->private_data = s; |
2379 | /* wait for device to become free */ | 2380 | /* wait for device to become free */ |
2380 | down(&s->open_sem); | 2381 | mutex_lock(&s->open_mutex); |
2381 | while (s->open_mode & FMODE_DAC) { | 2382 | while (s->open_mode & FMODE_DAC) { |
2382 | if (file->f_flags & O_NONBLOCK) { | 2383 | if (file->f_flags & O_NONBLOCK) { |
2383 | up(&s->open_sem); | 2384 | mutex_unlock(&s->open_mutex); |
2384 | return -EBUSY; | 2385 | return -EBUSY; |
2385 | } | 2386 | } |
2386 | add_wait_queue(&s->open_wait, &wait); | 2387 | add_wait_queue(&s->open_wait, &wait); |
2387 | __set_current_state(TASK_INTERRUPTIBLE); | 2388 | __set_current_state(TASK_INTERRUPTIBLE); |
2388 | up(&s->open_sem); | 2389 | mutex_unlock(&s->open_mutex); |
2389 | schedule(); | 2390 | schedule(); |
2390 | remove_wait_queue(&s->open_wait, &wait); | 2391 | remove_wait_queue(&s->open_wait, &wait); |
2391 | set_current_state(TASK_RUNNING); | 2392 | set_current_state(TASK_RUNNING); |
2392 | if (signal_pending(current)) | 2393 | if (signal_pending(current)) |
2393 | return -ERESTARTSYS; | 2394 | return -ERESTARTSYS; |
2394 | down(&s->open_sem); | 2395 | mutex_lock(&s->open_mutex); |
2395 | } | 2396 | } |
2396 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; | 2397 | s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; |
2397 | s->dma_dac1.enabled = 1; | 2398 | s->dma_dac1.enabled = 1; |
@@ -2405,7 +2406,7 @@ static int es1371_open_dac(struct inode *inode, struct file *file) | |||
2405 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); | 2406 | outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); |
2406 | spin_unlock_irqrestore(&s->lock, flags); | 2407 | spin_unlock_irqrestore(&s->lock, flags); |
2407 | s->open_mode |= FMODE_DAC; | 2408 | s->open_mode |= FMODE_DAC; |
2408 | up(&s->open_sem); | 2409 | mutex_unlock(&s->open_mutex); |
2409 | return nonseekable_open(inode, file); | 2410 | return nonseekable_open(inode, file); |
2410 | } | 2411 | } |
2411 | 2412 | ||
@@ -2416,11 +2417,11 @@ static int es1371_release_dac(struct inode *inode, struct file *file) | |||
2416 | VALIDATE_STATE(s); | 2417 | VALIDATE_STATE(s); |
2417 | lock_kernel(); | 2418 | lock_kernel(); |
2418 | drain_dac1(s, file->f_flags & O_NONBLOCK); | 2419 | drain_dac1(s, file->f_flags & O_NONBLOCK); |
2419 | down(&s->open_sem); | 2420 | mutex_lock(&s->open_mutex); |
2420 | stop_dac1(s); | 2421 | stop_dac1(s); |
2421 | dealloc_dmabuf(s, &s->dma_dac1); | 2422 | dealloc_dmabuf(s, &s->dma_dac1); |
2422 | s->open_mode &= ~FMODE_DAC; | 2423 | s->open_mode &= ~FMODE_DAC; |
2423 | up(&s->open_sem); | 2424 | mutex_unlock(&s->open_mutex); |
2424 | wake_up(&s->open_wait); | 2425 | wake_up(&s->open_wait); |
2425 | unlock_kernel(); | 2426 | unlock_kernel(); |
2426 | return 0; | 2427 | return 0; |
@@ -2608,21 +2609,21 @@ static int es1371_midi_open(struct inode *inode, struct file *file) | |||
2608 | VALIDATE_STATE(s); | 2609 | VALIDATE_STATE(s); |
2609 | file->private_data = s; | 2610 | file->private_data = s; |
2610 | /* wait for device to become free */ | 2611 | /* wait for device to become free */ |
2611 | down(&s->open_sem); | 2612 | mutex_lock(&s->open_mutex); |
2612 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { | 2613 | while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { |
2613 | if (file->f_flags & O_NONBLOCK) { | 2614 | if (file->f_flags & O_NONBLOCK) { |
2614 | up(&s->open_sem); | 2615 | mutex_unlock(&s->open_mutex); |
2615 | return -EBUSY; | 2616 | return -EBUSY; |
2616 | } | 2617 | } |
2617 | add_wait_queue(&s->open_wait, &wait); | 2618 | add_wait_queue(&s->open_wait, &wait); |
2618 | __set_current_state(TASK_INTERRUPTIBLE); | 2619 | __set_current_state(TASK_INTERRUPTIBLE); |
2619 | up(&s->open_sem); | 2620 | mutex_unlock(&s->open_mutex); |
2620 | schedule(); | 2621 | schedule(); |
2621 | remove_wait_queue(&s->open_wait, &wait); | 2622 | remove_wait_queue(&s->open_wait, &wait); |
2622 | set_current_state(TASK_RUNNING); | 2623 | set_current_state(TASK_RUNNING); |
2623 | if (signal_pending(current)) | 2624 | if (signal_pending(current)) |
2624 | return -ERESTARTSYS; | 2625 | return -ERESTARTSYS; |
2625 | down(&s->open_sem); | 2626 | mutex_lock(&s->open_mutex); |
2626 | } | 2627 | } |
2627 | spin_lock_irqsave(&s->lock, flags); | 2628 | spin_lock_irqsave(&s->lock, flags); |
2628 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2629 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
@@ -2643,7 +2644,7 @@ static int es1371_midi_open(struct inode *inode, struct file *file) | |||
2643 | es1371_handle_midi(s); | 2644 | es1371_handle_midi(s); |
2644 | spin_unlock_irqrestore(&s->lock, flags); | 2645 | spin_unlock_irqrestore(&s->lock, flags); |
2645 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); | 2646 | s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); |
2646 | up(&s->open_sem); | 2647 | mutex_unlock(&s->open_mutex); |
2647 | return nonseekable_open(inode, file); | 2648 | return nonseekable_open(inode, file); |
2648 | } | 2649 | } |
2649 | 2650 | ||
@@ -2676,7 +2677,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) | |||
2676 | remove_wait_queue(&s->midi.owait, &wait); | 2677 | remove_wait_queue(&s->midi.owait, &wait); |
2677 | set_current_state(TASK_RUNNING); | 2678 | set_current_state(TASK_RUNNING); |
2678 | } | 2679 | } |
2679 | down(&s->open_sem); | 2680 | mutex_lock(&s->open_mutex); |
2680 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); | 2681 | s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); |
2681 | spin_lock_irqsave(&s->lock, flags); | 2682 | spin_lock_irqsave(&s->lock, flags); |
2682 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { | 2683 | if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { |
@@ -2684,7 +2685,7 @@ static int es1371_midi_release(struct inode *inode, struct file *file) | |||
2684 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); | 2685 | outl(s->ctrl, s->io+ES1371_REG_CONTROL); |
2685 | } | 2686 | } |
2686 | spin_unlock_irqrestore(&s->lock, flags); | 2687 | spin_unlock_irqrestore(&s->lock, flags); |
2687 | up(&s->open_sem); | 2688 | mutex_unlock(&s->open_mutex); |
2688 | wake_up(&s->open_wait); | 2689 | wake_up(&s->open_wait); |
2689 | unlock_kernel(); | 2690 | unlock_kernel(); |
2690 | return 0; | 2691 | return 0; |
@@ -2884,7 +2885,7 @@ static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_devic | |||
2884 | init_waitqueue_head(&s->open_wait); | 2885 | init_waitqueue_head(&s->open_wait); |
2885 | init_waitqueue_head(&s->midi.iwait); | 2886 | init_waitqueue_head(&s->midi.iwait); |
2886 | init_waitqueue_head(&s->midi.owait); | 2887 | init_waitqueue_head(&s->midi.owait); |
2887 | init_MUTEX(&s->open_sem); | 2888 | mutex_init(&s->open_mutex); |
2888 | spin_lock_init(&s->lock); | 2889 | spin_lock_init(&s->lock); |
2889 | s->magic = ES1371_MAGIC; | 2890 | s->magic = ES1371_MAGIC; |
2890 | s->dev = pcidev; | 2891 | s->dev = pcidev; |