X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=sound%2Fcore%2Foss%2Fpcm_oss.c;h=7fd072392c7e89ad0eec524a51563c42477fcbf9;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=0691aca5115ac251e399841da9fcf9012a952bf8;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 0691aca51..7fd072392 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -78,7 +78,6 @@ static inline void snd_leave_user(mm_segment_t fs) set_fs(fs); } -#ifdef CONFIG_SND_PCM_OSS_PLUGINS static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -123,7 +122,6 @@ int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin) } return 0; } -#endif /* CONFIG_SND_PCM_OSS_PLUGINS */ static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames) { @@ -208,8 +206,9 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, oss_buffer_size = runtime->oss.mmap_bytes; } - if (substream->oss.setup.period_size > 16) - oss_period_size = substream->oss.setup.period_size; + if (substream->oss.setup && + substream->oss.setup->period_size > 16) + oss_period_size = substream->oss.setup->period_size; else if (runtime->oss.fragshift) { oss_period_size = 1 << runtime->oss.fragshift; if (oss_period_size > oss_buffer_size / 2) @@ -251,8 +250,10 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream, oss_periods = oss_buffer_size / oss_period_size; - if (substream->oss.setup.periods > 1) - oss_periods = substream->oss.setup.periods; + if (substream->oss.setup) { + if (substream->oss.setup->periods > 1) + oss_periods = substream->oss.setup->periods; + } s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); if (runtime->oss.maxfrags && s > runtime->oss.maxfrags) @@ -338,10 +339,12 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) goto failure; } - if (atomic_read(&runtime->mmap_count)) + if (atomic_read(&runtime->mmap_count)) { direct = 1; - else - direct = substream->oss.setup.direct; + } else { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + direct = (setup != NULL && setup->direct); + } _snd_pcm_hw_params_any(sparams); _snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS); @@ -409,7 +412,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) oss_frame_size = snd_pcm_format_physical_width(params_format(params)) * params_channels(params) / 8; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS snd_pcm_oss_plugin_clear(substream); if (!direct) { /* add necessary plugins */ @@ -439,7 +441,6 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) } } } -#endif err = snd_pcm_oss_period_size(substream, params, sparams); if (err < 0) @@ -477,7 +478,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) 1 : runtime->period_size; sw_params->xfer_align = 1; if (atomic_read(&runtime->mmap_count) || - substream->oss.setup.nosilence) { + (substream->oss.setup && substream->oss.setup->nosilence)) { sw_params->silence_threshold = 0; sw_params->silence_size = 0; } else { @@ -497,13 +498,11 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) runtime->oss.periods = params_periods(sparams); oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams)); snd_assert(oss_period_size >= 0, err = -EINVAL; goto failure); -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { err = snd_pcm_plug_alloc(substream, oss_period_size); if (err < 0) goto failure; } -#endif oss_period_size *= oss_frame_size; oss_buffer_size = oss_period_size * runtime->oss.periods; @@ -785,7 +784,6 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8; @@ -802,9 +800,7 @@ static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const cha if (frames1 <= 0) return frames1; bytes = frames1 * oss_frame_bytes; - } else -#endif - { + } else { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -838,7 +834,7 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha buf += tmp; bytes -= tmp; xfer += tmp; - if (substream->oss.setup.partialfrag || + if ((substream->oss.setup != NULL && substream->oss.setup->partialfrag) || runtime->oss.buffer_used == runtime->oss.period_bytes) { tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr, runtime->oss.buffer_used - runtime->oss.period_ptr, 1); @@ -875,7 +871,6 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_sframes_t frames, frames1; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS char __user *final_dst = (char __user *)buf; if (runtime->oss.plugin_first) { struct snd_pcm_plugin_channel *channels; @@ -892,9 +887,7 @@ static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, bytes = frames1 * oss_frame_bytes; if (!in_kernel && copy_to_user(final_dst, buf, bytes)) return -EFAULT; - } else -#endif - { + } else { frames = bytes_to_frames(runtime, bytes); frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel); if (frames1 <= 0) @@ -954,12 +947,12 @@ static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file) substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; if (substream != NULL) { - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); substream->runtime->oss.prepare = 1; } substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; if (substream != NULL) { - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); substream->runtime->oss.prepare = 1; } return 0; @@ -974,7 +967,7 @@ static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file) if (substream != NULL) { if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; - snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL); + snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL); } /* note: all errors from the start action are ignored */ /* OSS apps do not know, how to handle them */ @@ -1103,7 +1096,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) __direct: saved_f_flags = substream->ffile->f_flags; substream->ffile->f_flags &= ~O_NONBLOCK; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); + err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL); substream->ffile->f_flags = saved_f_flags; if (err < 0) return err; @@ -1115,7 +1108,7 @@ static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file) if ((err = snd_pcm_oss_make_ready(substream)) < 0) return err; runtime = substream->runtime; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); + err = snd_pcm_kernel_capture_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL); if (err < 0) return err; runtime->oss.buffer_used = 0; @@ -1209,10 +1202,12 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0) return err; - if (atomic_read(&substream->runtime->mmap_count)) + if (atomic_read(&substream->runtime->mmap_count)) { direct = 1; - else - direct = substream->oss.setup.direct; + } else { + struct snd_pcm_oss_setup *setup = substream->oss.setup; + direct = (setup != NULL && setup->direct); + } if (!direct) return AFMT_MU_LAW | AFMT_U8 | AFMT_S16_LE | AFMT_S16_BE | @@ -1242,8 +1237,6 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for if (format != AFMT_QUERY) { formats = snd_pcm_oss_get_formats(pcm_oss_file); - if (formats < 0) - return formats; if (!(formats & format)) format = AFMT_U8; for (idx = 1; idx >= 0; --idx) { @@ -1432,7 +1425,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL); + err = snd_pcm_kernel_playback_ioctl(psubstream, cmd, NULL); if (err < 0) return err; } @@ -1453,7 +1446,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr cmd = SNDRV_PCM_IOCTL_DROP; runtime->oss.prepare = 1; } - err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL); + err = snd_pcm_kernel_capture_ioctl(csubstream, cmd, NULL); if (err < 0) return err; } @@ -1490,7 +1483,7 @@ static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file) runtime = substream->runtime; if (runtime->oss.params || runtime->oss.prepare) return 0; - err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); + err = snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); if (err == -EPIPE) delay = 0; /* hack for broken OSS applications */ else if (err < 0) @@ -1550,7 +1543,8 @@ static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream } else { delay = snd_pcm_oss_bytes(substream, delay); if (stream == SNDRV_PCM_STREAM_PLAYBACK) { - if (substream->oss.setup.buggyptr) + struct snd_pcm_oss_setup *setup = substream->oss.setup; + if (setup && setup->buggyptr) info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes; else info.blocks = (delay + fixup) / runtime->oss.period_bytes; @@ -1632,46 +1626,37 @@ static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int str return -EINVAL; } -static const char *strip_task_path(const char *path) +static struct snd_pcm_oss_setup *snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, const char *task_name) { - const char *ptr, *ptrl = NULL; - for (ptr = path; *ptr; ptr++) { + const char *ptr, *ptrl; + struct snd_pcm_oss_setup *setup; + + down(&pcm->streams[stream].oss.setup_mutex); + for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { + if (!strcmp(setup->task_name, task_name)) { + up(&pcm->streams[stream].oss.setup_mutex); + return setup; + } + } + ptr = ptrl = task_name; + while (*ptr) { if (*ptr == '/') ptrl = ptr + 1; + ptr++; } - return ptrl; -} - -static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream, - const char *task_name, - struct snd_pcm_oss_setup *rsetup) -{ - struct snd_pcm_oss_setup *setup; - - mutex_lock(&pcm->streams[stream].oss.setup_mutex); - do { - for (setup = pcm->streams[stream].oss.setup_list; setup; - setup = setup->next) { - if (!strcmp(setup->task_name, task_name)) - goto out; + if (ptrl == task_name) { + goto __not_found; + return NULL; + } + for (setup = pcm->streams[stream].oss.setup_list; setup; setup = setup->next) { + if (!strcmp(setup->task_name, ptrl)) { + up(&pcm->streams[stream].oss.setup_mutex); + return setup; } - } while ((task_name = strip_task_path(task_name)) != NULL); - out: - if (setup) - *rsetup = *setup; - mutex_unlock(&pcm->streams[stream].oss.setup_mutex); -} - -static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - vfree(runtime->oss.buffer); - runtime->oss.buffer = NULL; -#ifdef CONFIG_SND_PCM_OSS_PLUGINS - snd_pcm_oss_plugin_clear(substream); -#endif - substream->oss.oss = 0; + } + __not_found: + up(&pcm->streams[stream].oss.setup_mutex); + return NULL; } static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, @@ -1681,11 +1666,7 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime; substream->oss.oss = 1; - substream->oss.setup = *setup; - if (setup->nonblock) - substream->ffile->f_flags |= O_NONBLOCK; - else if (setup->block) - substream->ffile->f_flags &= ~O_NONBLOCK; + substream->oss.setup = setup; runtime = substream->runtime; runtime->oss.params = 1; runtime->oss.trigger = 1; @@ -1704,7 +1685,16 @@ static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream, runtime->oss.fragshift = 0; runtime->oss.maxfrags = 0; runtime->oss.subdivision = 0; - substream->pcm_release = snd_pcm_oss_release_substream; +} + +static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime; + runtime = substream->runtime; + vfree(runtime->oss.buffer); + snd_pcm_oss_plugin_clear(substream); + substream->oss.file = NULL; + substream->oss.oss = 0; } static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) @@ -1713,8 +1703,23 @@ static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file) snd_assert(pcm_oss_file != NULL, return -ENXIO); for (cidx = 0; cidx < 2; ++cidx) { struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx]; - if (substream) - snd_pcm_release_substream(substream); + struct snd_pcm_runtime *runtime; + if (substream == NULL) + continue; + runtime = substream->runtime; + + snd_pcm_stream_lock_irq(substream); + if (snd_pcm_running(substream)) + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + snd_pcm_stream_unlock_irq(substream); + if (substream->ffile != NULL) { + if (substream->ops->hw_free != NULL) + substream->ops->hw_free(substream); + substream->ops->close(substream); + substream->ffile = NULL; + } + snd_pcm_oss_release_substream(substream); + snd_pcm_release_substream(substream); } kfree(pcm_oss_file); return 0; @@ -1724,11 +1729,12 @@ static int snd_pcm_oss_open_file(struct file *file, struct snd_pcm *pcm, struct snd_pcm_oss_file **rpcm_oss_file, int minor, - struct snd_pcm_oss_setup *setup) + struct snd_pcm_oss_setup *psetup, + struct snd_pcm_oss_setup *csetup) { - int idx, err; + int err = 0; struct snd_pcm_oss_file *pcm_oss_file; - struct snd_pcm_substream *substream; + struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL; unsigned int f_mode = file->f_mode; snd_assert(rpcm_oss_file != NULL, return -EINVAL); @@ -1741,34 +1747,73 @@ static int snd_pcm_oss_open_file(struct file *file, if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) && (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX)) f_mode = FMODE_WRITE; - - for (idx = 0; idx < 2; idx++) { - if (setup[idx].disable) - continue; - if (! pcm->streams[idx].substream_count) - continue; /* no matching substream */ - if (idx == SNDRV_PCM_STREAM_PLAYBACK) { - if (! (f_mode & FMODE_WRITE)) - continue; - } else { - if (! (f_mode & FMODE_READ)) - continue; - } - err = snd_pcm_open_substream(pcm, idx, file, &substream); - if (err < 0) { + if ((f_mode & FMODE_WRITE) && !(psetup && psetup->disable)) { + if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &psubstream)) < 0) { snd_pcm_oss_release_file(pcm_oss_file); return err; } - - pcm_oss_file->streams[idx] = substream; - substream->file = pcm_oss_file; - snd_pcm_oss_init_substream(substream, &setup[idx], minor); + pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK] = psubstream; + } + if ((f_mode & FMODE_READ) && !(csetup && csetup->disable)) { + if ((err = snd_pcm_open_substream(pcm, SNDRV_PCM_STREAM_CAPTURE, + &csubstream)) < 0) { + if (!(f_mode & FMODE_WRITE) || err != -ENODEV) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } else { + csubstream = NULL; + } + } + pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE] = csubstream; } - if (!pcm_oss_file->streams[0] && !pcm_oss_file->streams[1]) { + if (psubstream == NULL && csubstream == NULL) { snd_pcm_oss_release_file(pcm_oss_file); return -EINVAL; } + if (psubstream != NULL) { + psubstream->oss.file = pcm_oss_file; + err = snd_pcm_hw_constraints_init(psubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_init failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + if ((err = psubstream->ops->open(psubstream)) < 0) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + psubstream->ffile = file; + err = snd_pcm_hw_constraints_complete(psubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_complete failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + snd_pcm_oss_init_substream(psubstream, psetup, minor); + } + if (csubstream != NULL) { + csubstream->oss.file = pcm_oss_file; + err = snd_pcm_hw_constraints_init(csubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_init failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + if ((err = csubstream->ops->open(csubstream)) < 0) { + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + csubstream->ffile = file; + err = snd_pcm_hw_constraints_complete(csubstream); + if (err < 0) { + snd_printd("snd_pcm_hw_constraint_complete failed\n"); + snd_pcm_oss_release_file(pcm_oss_file); + return err; + } + snd_pcm_oss_init_substream(csubstream, csetup, minor); + } file->private_data = pcm_oss_file; *rpcm_oss_file = pcm_oss_file; @@ -1793,16 +1838,9 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) char task_name[32]; struct snd_pcm *pcm; struct snd_pcm_oss_file *pcm_oss_file; - struct snd_pcm_oss_setup setup[2]; + struct snd_pcm_oss_setup *psetup = NULL, *csetup = NULL; int nonblock; wait_queue_t wait; - static char printed_comm[16]; - - if (strncmp(printed_comm, current->comm, 16)) { - printk(KERN_DEBUG "application %s uses obsolete OSS audio interface\n", - current->comm); - memcpy(printed_comm, current->comm, 16); - } pcm = snd_lookup_oss_minor_data(iminor(inode), SNDRV_OSS_DEVICE_TYPE_PCM); @@ -1821,24 +1859,32 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) err = -EFAULT; goto __error; } - memset(setup, 0, sizeof(setup)); if (file->f_mode & FMODE_WRITE) - snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, - task_name, &setup[0]); + psetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK, task_name); if (file->f_mode & FMODE_READ) - snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, - task_name, &setup[1]); + csetup = snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE, task_name); nonblock = !!(file->f_flags & O_NONBLOCK); + if (psetup && !psetup->disable) { + if (psetup->nonblock) + nonblock = 1; + else if (psetup->block) + nonblock = 0; + } else if (csetup && !csetup->disable) { + if (csetup->nonblock) + nonblock = 1; + else if (csetup->block) + nonblock = 0; + } if (!nonblock) nonblock = nonblock_open; init_waitqueue_entry(&wait, current); add_wait_queue(&pcm->open_wait, &wait); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); while (1) { err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file, - iminor(inode), setup); + iminor(inode), psetup, csetup); if (err >= 0) break; if (err == -EAGAIN) { @@ -1849,16 +1895,16 @@ static int snd_pcm_oss_open(struct inode *inode, struct file *file) } else break; set_current_state(TASK_INTERRUPTIBLE); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); schedule(); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); if (signal_pending(current)) { err = -ERESTARTSYS; break; } } remove_wait_queue(&pcm->open_wait, &wait); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); if (err < 0) goto __error; return err; @@ -1884,9 +1930,9 @@ static int snd_pcm_oss_release(struct inode *inode, struct file *file) snd_assert(substream != NULL, return -ENXIO); pcm = substream->pcm; snd_pcm_oss_sync(pcm_oss_file); - mutex_lock(&pcm->open_mutex); + down(&pcm->open_mutex); snd_pcm_oss_release_file(pcm_oss_file); - mutex_unlock(&pcm->open_mutex); + up(&pcm->open_mutex); wake_up(&pcm->open_wait); module_put(pcm->card->module); snd_card_file_remove(pcm->card, file); @@ -2200,10 +2246,8 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) if ((err = snd_pcm_oss_change_params(substream)) < 0) return err; } -#ifdef CONFIG_SND_PCM_OSS_PLUGINS if (runtime->oss.plugin_first != NULL) return -EIO; -#endif if (area->vm_pgoff != 0) return -EINVAL; @@ -2223,7 +2267,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area) return 0; } -#ifdef CONFIG_SND_VERBOSE_PROCFS +#ifdef CONFIG_PROC_FS /* * /proc interface */ @@ -2233,7 +2277,7 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, { struct snd_pcm_str *pstr = entry->private_data; struct snd_pcm_oss_setup *setup = pstr->oss.setup_list; - mutex_lock(&pstr->oss.setup_mutex); + down(&pstr->oss.setup_mutex); while (setup) { snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", setup->task_name, @@ -2247,13 +2291,18 @@ static void snd_pcm_oss_proc_read(struct snd_info_entry *entry, setup->nosilence ? " no-silence" : ""); setup = setup->next; } - mutex_unlock(&pstr->oss.setup_mutex); + up(&pstr->oss.setup_mutex); } static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr) { + unsigned int idx; + struct snd_pcm_substream *substream; struct snd_pcm_oss_setup *setup, *setupn; + for (idx = 0, substream = pstr->substream; + idx < pstr->substream_count; idx++, substream = substream->next) + substream->oss.setup = NULL; for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL; setup; setup = setupn) { setupn = setup->next; @@ -2272,12 +2321,12 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, struct snd_pcm_oss_setup *setup, *setup1, template; while (!snd_info_get_line(buffer, line, sizeof(line))) { - mutex_lock(&pstr->oss.setup_mutex); + down(&pstr->oss.setup_mutex); memset(&template, 0, sizeof(template)); ptr = snd_info_get_str(task_name, line, sizeof(task_name)); if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) { snd_pcm_oss_proc_free_setup_list(pstr); - mutex_unlock(&pstr->oss.setup_mutex); + up(&pstr->oss.setup_mutex); continue; } for (setup = pstr->oss.setup_list; setup; setup = setup->next) { @@ -2314,29 +2363,22 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, } } while (*str); if (setup == NULL) { - setup = kmalloc(sizeof(*setup), GFP_KERNEL); - if (! setup) { - buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); - return; - } - if (pstr->oss.setup_list == NULL) - pstr->oss.setup_list = setup; - else { - for (setup1 = pstr->oss.setup_list; - setup1->next; setup1 = setup1->next); - setup1->next = setup; - } - template.task_name = kstrdup(task_name, GFP_KERNEL); - if (! template.task_name) { - kfree(setup); + setup = kmalloc(sizeof(struct snd_pcm_oss_setup), GFP_KERNEL); + if (setup) { + if (pstr->oss.setup_list == NULL) { + pstr->oss.setup_list = setup; + } else { + for (setup1 = pstr->oss.setup_list; setup1->next; setup1 = setup1->next); + setup1->next = setup; + } + template.task_name = kstrdup(task_name, GFP_KERNEL); + } else { buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); - return; } } - *setup = template; - mutex_unlock(&pstr->oss.setup_mutex); + if (setup) + *setup = template; + up(&pstr->oss.setup_mutex); } } @@ -2377,10 +2419,10 @@ static void snd_pcm_oss_proc_done(struct snd_pcm *pcm) } } } -#else /* !CONFIG_SND_VERBOSE_PROCFS */ +#else /* !CONFIG_PROC_FS */ #define snd_pcm_oss_proc_init(pcm) #define snd_pcm_oss_proc_done(pcm) -#endif /* CONFIG_SND_VERBOSE_PROCFS */ +#endif /* CONFIG_PROC_FS */ /* * ENTRY functions