diff options
Diffstat (limited to 'sound/oss/dmasound/dmasound_core.c')
| -rw-r--r-- | sound/oss/dmasound/dmasound_core.c | 93 |
1 files changed, 34 insertions, 59 deletions
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index bac43b5b6e95..dea2d9b18fc9 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -182,8 +182,9 @@ #include <linux/soundcard.h> #include <linux/poll.h> #include <linux/mutex.h> +#include <linux/sched/signal.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include "dmasound.h" @@ -203,14 +204,13 @@ module_param(numWriteBufs, int, 0); static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ module_param(writeBufSize, int, 0); +MODULE_DESCRIPTION("Atari/Amiga/Q40 core DMA sound driver"); MODULE_LICENSE("GPL"); -#ifdef MODULE static int sq_unit = -1; static int mixer_unit = -1; static int state_unit = -1; static int irq_installed; -#endif /* MODULE */ /* control over who can modify resources shared between play/record */ static fmode_t shared_resource_owner; @@ -354,8 +354,8 @@ static int mixer_ioctl(struct file *file, u_int cmd, u_long arg) { mixer_info info; memset(&info, 0, sizeof(info)); - strlcpy(info.id, dmasound.mach.name2, sizeof(info.id)); - strlcpy(info.name, dmasound.mach.name2, sizeof(info.name)); + strscpy(info.id, dmasound.mach.name2, sizeof(info.id)); + strscpy(info.name, dmasound.mach.name2, sizeof(info.name)); info.modify_counter = mixer.modify_counter; if (copy_to_user((void __user *)arg, &info, sizeof(info))) return -EFAULT; @@ -381,17 +381,14 @@ static long mixer_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) static const struct file_operations mixer_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .unlocked_ioctl = mixer_unlocked_ioctl, + .compat_ioctl = compat_ptr_ioctl, .open = mixer_open, .release = mixer_release, }; static void mixer_init(void) { -#ifndef MODULE - int mixer_unit; -#endif mixer_unit = register_sound_mixer(&mixer_fops, -1); if (mixer_unit < 0) return; @@ -419,7 +416,7 @@ static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) return 0; sq->numBufs = num; sq->bufSize = size; - sq->buffers = kmalloc (num * sizeof(char *), GFP_KERNEL); + sq->buffers = kmalloc_array (num, sizeof(char *), GFP_KERNEL); if (!sq->buffers) return -ENOMEM; for (i = 0; i < num; i++) { @@ -619,15 +616,27 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft, } while (uLeft) { + DEFINE_WAIT(wait); + while (write_sq.count >= write_sq.max_active) { + prepare_to_wait(&write_sq.action_queue, &wait, TASK_INTERRUPTIBLE); sq_play(); - if (write_sq.non_blocking) + if (write_sq.non_blocking) { + finish_wait(&write_sq.action_queue, &wait); return uWritten > 0 ? uWritten : -EAGAIN; - SLEEP(write_sq.action_queue); - if (signal_pending(current)) + } + if (write_sq.count < write_sq.max_active) + break; + + schedule_timeout(HZ); + if (signal_pending(current)) { + finish_wait(&write_sq.action_queue, &wait); return uWritten > 0 ? uWritten : -EINTR; + } } + finish_wait(&write_sq.action_queue, &wait); + /* Here, we can avoid disabling the interrupt by first * copying and translating the data, and then updating * the write_sq variables. Until this is done, the interrupt @@ -657,9 +666,9 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft, return uUsed < 0? uUsed: uWritten; } -static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) +static __poll_t sq_poll(struct file *file, struct poll_table_struct *wait) { - unsigned int mask = 0; + __poll_t mask = 0; int retVal; if (write_sq.locked == 0) { @@ -671,7 +680,7 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) poll_wait(file, &write_sq.action_queue, wait); if (file->f_mode & FMODE_WRITE) if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0) - mask |= POLLOUT | POLLWRNORM; + mask |= EPOLLOUT | EPOLLWRNORM; return mask; } @@ -707,11 +716,8 @@ static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, if (file->f_flags & O_NONBLOCK) return rc; rc = -EINTR; - while (sq->busy) { - SLEEP(sq->open_queue); - if (signal_pending(current)) - return rc; - } + if (wait_event_interruptible(sq->open_queue, !sq->busy)) + return rc; rc = 0; #else /* OSS manual says we will return EBUSY regardless @@ -844,7 +850,8 @@ static int sq_fsync(void) sq_play(); /* there may be an incomplete frame waiting */ while (write_sq.active) { - SLEEP(write_sq.sync_queue); + wait_event_interruptible_timeout(write_sq.sync_queue, + !write_sq.active, HZ); if (signal_pending(current)) { /* While waiting for audio output to drain, an * interrupt occurred. Stop audio output immediately @@ -987,11 +994,9 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) case SNDCTL_DSP_RESET: sq_reset(); return 0; - break ; case SNDCTL_DSP_GETFMTS: fmt = dmasound.mach.hardware_afmts ; /* this is what OSS says.. */ return IOCTL_OUT(arg, fmt); - break ; case SNDCTL_DSP_GETBLKSIZE: /* this should tell the caller about bytes that the app can read/write - the app doesn't care about our internal buffers. @@ -1008,7 +1013,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) size = write_sq.user_frag_size ; } return IOCTL_OUT(arg, size); - break ; case SNDCTL_DSP_POST: /* all we are going to do is to tell the LL that any partial frags can be queued for output. @@ -1032,7 +1036,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) if (file->f_mode & shared_resource_owner) shared_resources_initialised = 0 ; return result ; - break ; case SOUND_PCM_READ_RATE: return IOCTL_OUT(arg, dmasound.soft.speed); case SNDCTL_DSP_SPEED: @@ -1111,7 +1114,6 @@ static int sq_ioctl(struct file *file, u_int cmd, u_long arg) the value is 'random' and that the user _must_ check the actual frags values using SNDCTL_DSP_GETBLKSIZE or similar */ return IOCTL_OUT(arg, data); - break ; case SNDCTL_DSP_GETOSPACE: /* */ @@ -1152,10 +1154,10 @@ static long sq_unlocked_ioctl(struct file *file, u_int cmd, u_long arg) static const struct file_operations sq_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .write = sq_write, .poll = sq_poll, .unlocked_ioctl = sq_unlocked_ioctl, + .compat_ioctl = compat_ptr_ioctl, .open = sq_open, .release = sq_release, }; @@ -1163,9 +1165,6 @@ static const struct file_operations sq_fops = static int sq_init(void) { const struct file_operations *fops = &sq_fops; -#ifndef MODULE - int sq_unit; -#endif sq_unit = register_sound_dsp(fops, -1); if (sq_unit < 0) { @@ -1221,31 +1220,22 @@ static char *get_afmt_string(int afmt) switch(afmt) { case AFMT_MU_LAW: return "mu-law"; - break; case AFMT_A_LAW: return "A-law"; - break; case AFMT_U8: return "unsigned 8 bit"; - break; case AFMT_S8: return "signed 8 bit"; - break; case AFMT_S16_BE: return "signed 16 bit BE"; - break; case AFMT_U16_BE: return "unsigned 16 bit BE"; - break; case AFMT_S16_LE: return "signed 16 bit LE"; - break; case AFMT_U16_LE: return "unsigned 16 bit LE"; - break; case 0: return "format not set" ; - break ; default: break ; } @@ -1359,7 +1349,6 @@ static ssize_t state_read(struct file *file, char __user *buf, size_t count, static const struct file_operations state_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, .read = state_read, .open = state_open, .release = state_release, @@ -1367,9 +1356,6 @@ static const struct file_operations state_fops = { static int state_init(void) { -#ifndef MODULE - int state_unit; -#endif state_unit = register_sound_special(&state_fops, SND_DEV_STATUS); if (state_unit < 0) return state_unit ; @@ -1387,10 +1373,9 @@ static int state_init(void) int dmasound_init(void) { int res ; -#ifdef MODULE + if (irq_installed) return -EBUSY; -#endif /* Set up sound queue, /dev/audio and /dev/dsp. */ @@ -1409,9 +1394,7 @@ int dmasound_init(void) printk(KERN_ERR "DMA sound driver: Interrupt initialization failed\n"); return -ENODEV; } -#ifdef MODULE irq_installed = 1; -#endif printk(KERN_INFO "%s DMA sound driver rev %03d installed\n", dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) + @@ -1425,8 +1408,6 @@ int dmasound_init(void) return 0; } -#ifdef MODULE - void dmasound_deinit(void) { if (irq_installed) { @@ -1445,9 +1426,7 @@ void dmasound_deinit(void) unregister_sound_dsp(sq_unit); } -#else /* !MODULE */ - -static int dmasound_setup(char *str) +static int __maybe_unused dmasound_setup(char *str) { int ints[6], size; @@ -1465,13 +1444,13 @@ static int dmasound_setup(char *str) printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); else catchRadius = ints[3]; - /* fall through */ + fallthrough; case 2: if (ints[1] < MIN_BUFFERS) printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); else numWriteBufs = ints[1]; - /* fall through */ + fallthrough; case 1: if ((size = ints[2]) < 256) /* check for small buffer specs */ size <<= 10 ; @@ -1490,8 +1469,6 @@ static int dmasound_setup(char *str) __setup("dmasound=", dmasound_setup); -#endif /* !MODULE */ - /* * Conversion tables */ @@ -1578,9 +1555,7 @@ char dmasound_alaw2dma8[] = { EXPORT_SYMBOL(dmasound); EXPORT_SYMBOL(dmasound_init); -#ifdef MODULE EXPORT_SYMBOL(dmasound_deinit); -#endif EXPORT_SYMBOL(dmasound_write_sq); EXPORT_SYMBOL(dmasound_catchRadius); #ifdef HAS_8BIT_TABLES |
