Loading sound/core/pcm_lib.c +106 −106 Original line number Diff line number Diff line Loading @@ -1993,6 +1993,10 @@ static int wait_for_avail(struct snd_pcm_substream *substream, return err; } typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t size); static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, Loading @@ -2015,9 +2019,68 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, return 0; } typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t size); snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { buf = *bufs + off; if (!*bufs) { if (snd_BUG_ON(!substream->ops->fill_silence)) return -EINVAL; err = substream->ops->fill_silence(substream, c, hwoff, frames); } else { err = substream->ops->copy_user(substream, c, hwoff, buf, frames); } if (err < 0) return err; } } else { /* default transfer behaviour */ size_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); if (*bufs == NULL) { snd_pcm_format_set_silence(runtime->format, hwbuf, frames); } else { char __user *buf = *bufs + samples_to_bytes(runtime, off); if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) return -EFAULT; } } } return 0; } /* sanity-check for read/write methods */ static int pcm_sanity_check(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) return -EINVAL; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; return 0; } static int pcm_accessible_state(struct snd_pcm_runtime *runtime) { Loading Loading @@ -2118,20 +2181,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } /* sanity-check for read/write methods */ static int pcm_sanity_check(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) return -EINVAL; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; return 0; } snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) { struct snd_pcm_runtime *runtime; Loading @@ -2153,55 +2202,6 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v EXPORT_SYMBOL(snd_pcm_lib_write); static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { buf = *bufs + off; if (!*bufs) { if (snd_BUG_ON(!substream->ops->fill_silence)) return -EINVAL; err = substream->ops->fill_silence(substream, c, hwoff, frames); } else { err = substream->ops->copy_user(substream, c, hwoff, buf, frames); } if (err < 0) return err; } } else { /* default transfer behaviour */ size_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); if (*bufs == NULL) { snd_pcm_format_set_silence(runtime->format, hwbuf, frames); } else { char __user *buf = *bufs + samples_to_bytes(runtime, off); if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) return -EFAULT; } } } return 0; } snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, void __user **bufs, snd_pcm_uframes_t frames) Loading Loading @@ -2246,6 +2246,46 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, return 0; } static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; char *hwbuf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { if (!*bufs) continue; err = substream->ops->copy_user(substream, c, hwoff, *bufs + off, frames); if (err < 0) return err; } } else { snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { if (*bufs == NULL) continue; hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); buf = *bufs + samples_to_bytes(runtime, off); if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) return -EFAULT; } } return 0; } static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, unsigned long data, snd_pcm_uframes_t size, Loading Loading @@ -2354,46 +2394,6 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u EXPORT_SYMBOL(snd_pcm_lib_read); static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; char *hwbuf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { if (!*bufs) continue; err = substream->ops->copy_user(substream, c, hwoff, *bufs + off, frames); if (err < 0) return err; } } else { snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { if (*bufs == NULL) continue; hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); buf = *bufs + samples_to_bytes(runtime, off); if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) return -EFAULT; } } return 0; } snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, void __user **bufs, snd_pcm_uframes_t frames) Loading Loading
sound/core/pcm_lib.c +106 −106 Original line number Diff line number Diff line Loading @@ -1993,6 +1993,10 @@ static int wait_for_avail(struct snd_pcm_substream *substream, return err; } typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t size); static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, Loading @@ -2015,9 +2019,68 @@ static int snd_pcm_lib_write_transfer(struct snd_pcm_substream *substream, return 0; } typedef int (*transfer_f)(struct snd_pcm_substream *substream, unsigned int hwoff, static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t size); snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { buf = *bufs + off; if (!*bufs) { if (snd_BUG_ON(!substream->ops->fill_silence)) return -EINVAL; err = substream->ops->fill_silence(substream, c, hwoff, frames); } else { err = substream->ops->copy_user(substream, c, hwoff, buf, frames); } if (err < 0) return err; } } else { /* default transfer behaviour */ size_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); if (*bufs == NULL) { snd_pcm_format_set_silence(runtime->format, hwbuf, frames); } else { char __user *buf = *bufs + samples_to_bytes(runtime, off); if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) return -EFAULT; } } } return 0; } /* sanity-check for read/write methods */ static int pcm_sanity_check(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) return -EINVAL; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; return 0; } static int pcm_accessible_state(struct snd_pcm_runtime *runtime) { Loading Loading @@ -2118,20 +2181,6 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; } /* sanity-check for read/write methods */ static int pcm_sanity_check(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime; if (PCM_RUNTIME_CHECK(substream)) return -ENXIO; runtime = substream->runtime; if (snd_BUG_ON(!substream->ops->copy_user && !runtime->dma_area)) return -EINVAL; if (runtime->status->state == SNDRV_PCM_STATE_OPEN) return -EBADFD; return 0; } snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const void __user *buf, snd_pcm_uframes_t size) { struct snd_pcm_runtime *runtime; Loading @@ -2153,55 +2202,6 @@ snd_pcm_sframes_t snd_pcm_lib_write(struct snd_pcm_substream *substream, const v EXPORT_SYMBOL(snd_pcm_lib_write); static int snd_pcm_lib_writev_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { buf = *bufs + off; if (!*bufs) { if (snd_BUG_ON(!substream->ops->fill_silence)) return -EINVAL; err = substream->ops->fill_silence(substream, c, hwoff, frames); } else { err = substream->ops->copy_user(substream, c, hwoff, buf, frames); } if (err < 0) return err; } } else { /* default transfer behaviour */ size_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { char *hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); if (*bufs == NULL) { snd_pcm_format_set_silence(runtime->format, hwbuf, frames); } else { char __user *buf = *bufs + samples_to_bytes(runtime, off); if (copy_from_user(hwbuf, buf, samples_to_bytes(runtime, frames))) return -EFAULT; } } } return 0; } snd_pcm_sframes_t snd_pcm_lib_writev(struct snd_pcm_substream *substream, void __user **bufs, snd_pcm_uframes_t frames) Loading Loading @@ -2246,6 +2246,46 @@ static int snd_pcm_lib_read_transfer(struct snd_pcm_substream *substream, return 0; } static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; char *hwbuf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { if (!*bufs) continue; err = substream->ops->copy_user(substream, c, hwoff, *bufs + off, frames); if (err < 0) return err; } } else { snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { if (*bufs == NULL) continue; hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); buf = *bufs + samples_to_bytes(runtime, off); if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) return -EFAULT; } } return 0; } static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, unsigned long data, snd_pcm_uframes_t size, Loading Loading @@ -2354,46 +2394,6 @@ snd_pcm_sframes_t snd_pcm_lib_read(struct snd_pcm_substream *substream, void __u EXPORT_SYMBOL(snd_pcm_lib_read); static int snd_pcm_lib_readv_transfer(struct snd_pcm_substream *substream, unsigned int hwoff, unsigned long data, unsigned int off, snd_pcm_uframes_t frames) { struct snd_pcm_runtime *runtime = substream->runtime; int err; void __user **bufs = (void __user **)data; int channels = runtime->channels; char __user *buf; char *hwbuf; int c; if (substream->ops->copy_user) { hwoff = samples_to_bytes(runtime, hwoff); off = samples_to_bytes(runtime, off); frames = samples_to_bytes(runtime, frames); for (c = 0; c < channels; ++c, ++bufs) { if (!*bufs) continue; err = substream->ops->copy_user(substream, c, hwoff, *bufs + off, frames); if (err < 0) return err; } } else { snd_pcm_uframes_t dma_csize = runtime->dma_bytes / channels; for (c = 0; c < channels; ++c, ++bufs) { if (*bufs == NULL) continue; hwbuf = runtime->dma_area + (c * dma_csize) + samples_to_bytes(runtime, hwoff); buf = *bufs + samples_to_bytes(runtime, off); if (copy_to_user(buf, hwbuf, samples_to_bytes(runtime, frames))) return -EFAULT; } } return 0; } snd_pcm_sframes_t snd_pcm_lib_readv(struct snd_pcm_substream *substream, void __user **bufs, snd_pcm_uframes_t frames) Loading