22 |
#if 0 |
#if 0 |
23 |
#define PLUGIN_DEBUG |
#define PLUGIN_DEBUG |
24 |
#endif |
#endif |
25 |
|
#if 0 |
26 |
|
#define OSS_DEBUG |
27 |
|
#endif |
28 |
|
|
29 |
#include <sound/driver.h> |
#include <sound/driver.h> |
30 |
#include <linux/version.h> |
#include <linux/version.h> |
445 |
} else { |
} else { |
446 |
sw_params->start_threshold = runtime->boundary; |
sw_params->start_threshold = runtime->boundary; |
447 |
} |
} |
448 |
if (atomic_read(&runtime->mmap_count)) |
if (atomic_read(&runtime->mmap_count) || substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
449 |
sw_params->stop_threshold = runtime->boundary; |
sw_params->stop_threshold = runtime->boundary; |
450 |
else |
else |
451 |
sw_params->stop_threshold = runtime->buffer_size; |
sw_params->stop_threshold = runtime->buffer_size; |
454 |
sw_params->sleep_min = 0; |
sw_params->sleep_min = 0; |
455 |
sw_params->avail_min = runtime->period_size; |
sw_params->avail_min = runtime->period_size; |
456 |
sw_params->xfer_align = 1; |
sw_params->xfer_align = 1; |
457 |
sw_params->silence_threshold = 0; |
if (atomic_read(&runtime->mmap_count) || |
458 |
sw_params->silence_size = 0; |
(substream->oss.setup && substream->oss.setup->nosilence)) { |
459 |
|
sw_params->silence_threshold = 0; |
460 |
|
sw_params->silence_size = 0; |
461 |
|
} else { |
462 |
|
snd_pcm_uframes_t frames; |
463 |
|
frames = runtime->period_size + 16; |
464 |
|
if (frames > runtime->buffer_size) |
465 |
|
frames = runtime->buffer_size; |
466 |
|
sw_params->silence_threshold = frames; |
467 |
|
sw_params->silence_size = frames; |
468 |
|
} |
469 |
|
|
470 |
if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) { |
if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) { |
471 |
snd_printd("SW_PARAMS failed: %i\n", err); |
snd_printd("SW_PARAMS failed: %i\n", err); |
580 |
return 0; |
return 0; |
581 |
} |
} |
582 |
|
|
583 |
|
static int snd_pcm_oss_capture_position_fixup(snd_pcm_substream_t *substream, snd_pcm_sframes_t *delay) |
584 |
|
{ |
585 |
|
snd_pcm_runtime_t *runtime; |
586 |
|
snd_pcm_uframes_t frames; |
587 |
|
int err = 0; |
588 |
|
|
589 |
|
while (1) { |
590 |
|
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, delay); |
591 |
|
if (err < 0) |
592 |
|
break; |
593 |
|
runtime = substream->runtime; |
594 |
|
if (*delay <= (snd_pcm_sframes_t)runtime->buffer_size) |
595 |
|
break; |
596 |
|
/* in case of overrun, skip whole periods like OSS/Linux driver does */ |
597 |
|
/* until avail(delay) <= buffer_size */ |
598 |
|
frames = (*delay - runtime->buffer_size) + runtime->period_size - 1; |
599 |
|
frames /= runtime->period_size; |
600 |
|
frames *= runtime->period_size; |
601 |
|
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_FORWARD, &frames); |
602 |
|
if (err < 0) |
603 |
|
break; |
604 |
|
} |
605 |
|
return err; |
606 |
|
} |
607 |
|
|
608 |
snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel) |
snd_pcm_sframes_t snd_pcm_oss_write3(snd_pcm_substream_t *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel) |
609 |
{ |
{ |
610 |
snd_pcm_runtime_t *runtime = substream->runtime; |
snd_pcm_runtime_t *runtime = substream->runtime; |
612 |
while (1) { |
while (1) { |
613 |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
614 |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
615 |
|
#ifdef OSS_DEBUG |
616 |
|
if (runtime->status->state == SNDRV_PCM_STATE_XRUN) |
617 |
|
printk("pcm_oss: write: recovering from XRUN\n"); |
618 |
|
else |
619 |
|
printk("pcm_oss: write: recovering from SUSPEND\n"); |
620 |
|
#endif |
621 |
ret = snd_pcm_oss_prepare(substream); |
ret = snd_pcm_oss_prepare(substream); |
622 |
if (ret < 0) |
if (ret < 0) |
623 |
break; |
break; |
643 |
snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel) |
snd_pcm_sframes_t snd_pcm_oss_read3(snd_pcm_substream_t *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel) |
644 |
{ |
{ |
645 |
snd_pcm_runtime_t *runtime = substream->runtime; |
snd_pcm_runtime_t *runtime = substream->runtime; |
646 |
|
snd_pcm_sframes_t delay; |
647 |
int ret; |
int ret; |
648 |
while (1) { |
while (1) { |
649 |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
650 |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
651 |
|
#ifdef OSS_DEBUG |
652 |
|
if (runtime->status->state == SNDRV_PCM_STATE_XRUN) |
653 |
|
printk("pcm_oss: read: recovering from XRUN\n"); |
654 |
|
else |
655 |
|
printk("pcm_oss: read: recovering from SUSPEND\n"); |
656 |
|
#endif |
657 |
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0); |
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0); |
658 |
if (ret < 0) |
if (ret < 0) |
659 |
break; |
break; |
662 |
if (ret < 0) |
if (ret < 0) |
663 |
break; |
break; |
664 |
} |
} |
665 |
|
ret = snd_pcm_oss_capture_position_fixup(substream, &delay); |
666 |
|
if (ret < 0) |
667 |
|
break; |
668 |
if (in_kernel) { |
if (in_kernel) { |
669 |
mm_segment_t fs; |
mm_segment_t fs; |
670 |
fs = snd_enter_user(); |
fs = snd_enter_user(); |
694 |
while (1) { |
while (1) { |
695 |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
696 |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
697 |
|
#ifdef OSS_DEBUG |
698 |
|
if (runtime->status->state == SNDRV_PCM_STATE_XRUN) |
699 |
|
printk("pcm_oss: writev: recovering from XRUN\n"); |
700 |
|
else |
701 |
|
printk("pcm_oss: writev: recovering from SUSPEND\n"); |
702 |
|
#endif |
703 |
ret = snd_pcm_oss_prepare(substream); |
ret = snd_pcm_oss_prepare(substream); |
704 |
if (ret < 0) |
if (ret < 0) |
705 |
break; |
break; |
730 |
while (1) { |
while (1) { |
731 |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
if (runtime->status->state == SNDRV_PCM_STATE_XRUN || |
732 |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) { |
733 |
|
#ifdef OSS_DEBUG |
734 |
|
if (runtime->status->state == SNDRV_PCM_STATE_XRUN) |
735 |
|
printk("pcm_oss: readv: recovering from XRUN\n"); |
736 |
|
else |
737 |
|
printk("pcm_oss: readv: recovering from SUSPEND\n"); |
738 |
|
#endif |
739 |
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0); |
ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, 0); |
740 |
if (ret < 0) |
if (ret < 0) |
741 |
break; |
break; |
812 |
buf += tmp; |
buf += tmp; |
813 |
bytes -= tmp; |
bytes -= tmp; |
814 |
xfer += tmp; |
xfer += tmp; |
815 |
if (runtime->oss.buffer_used == runtime->oss.period_bytes) { |
if (substream->oss.setup == NULL || !substream->oss.setup->wholefrag || |
816 |
tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1); |
runtime->oss.buffer_used == runtime->oss.period_bytes) { |
817 |
|
tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer, runtime->oss.buffer_used, 1); |
818 |
if (tmp <= 0) |
if (tmp <= 0) |
819 |
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; |
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp; |
820 |
runtime->oss.bytes += tmp; |
runtime->oss.bytes += tmp; |
922 |
return 0; |
return 0; |
923 |
} |
} |
924 |
|
|
925 |
|
static int snd_pcm_oss_post(snd_pcm_oss_file_t *pcm_oss_file) |
926 |
|
{ |
927 |
|
snd_pcm_substream_t *substream; |
928 |
|
int err; |
929 |
|
|
930 |
|
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
931 |
|
if (substream != NULL) { |
932 |
|
if ((err = snd_pcm_oss_make_ready(substream)) < 0) |
933 |
|
return err; |
934 |
|
snd_pcm_kernel_playback_ioctl(substream, SNDRV_PCM_IOCTL_START, 0); |
935 |
|
} |
936 |
|
/* note: all errors from the start action are ignored */ |
937 |
|
/* OSS apps do not know, how to handle them */ |
938 |
|
return 0; |
939 |
|
} |
940 |
|
|
941 |
static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file) |
static int snd_pcm_oss_sync(snd_pcm_oss_file_t *pcm_oss_file) |
942 |
{ |
{ |
943 |
int err = 0; |
int err = 0; |
1271 |
snd_pcm_runtime_t *runtime; |
snd_pcm_runtime_t *runtime; |
1272 |
snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL; |
snd_pcm_substream_t *psubstream = NULL, *csubstream = NULL; |
1273 |
int err, cmd; |
int err, cmd; |
1274 |
|
|
1275 |
|
#ifdef OSS_DEBUG |
1276 |
|
printk("pcm_oss: trigger = 0x%x\n", trigger); |
1277 |
|
#endif |
1278 |
|
|
1279 |
psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
1280 |
csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
1375 |
{ |
{ |
1376 |
snd_pcm_substream_t *substream; |
snd_pcm_substream_t *substream; |
1377 |
snd_pcm_runtime_t *runtime; |
snd_pcm_runtime_t *runtime; |
1378 |
snd_pcm_status_t status; |
snd_pcm_sframes_t delay; |
1379 |
struct count_info info; |
struct count_info info; |
1380 |
int err; |
int err; |
1381 |
|
|
1393 |
return -EFAULT; |
return -EFAULT; |
1394 |
return 0; |
return 0; |
1395 |
} |
} |
1396 |
memset(&status, 0, sizeof(status)); |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1397 |
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status); |
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay); |
1398 |
|
} else { |
1399 |
|
err = snd_pcm_oss_capture_position_fixup(substream, &delay); |
1400 |
|
} |
1401 |
if (err < 0) |
if (err < 0) |
1402 |
return err; |
return err; |
1403 |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1404 |
info.bytes = runtime->oss.bytes - snd_pcm_oss_bytes(substream, runtime->buffer_size - status.avail); |
info.bytes = runtime->oss.bytes - snd_pcm_oss_bytes(substream, delay); |
1405 |
} else { |
} else { |
1406 |
info.bytes = runtime->oss.bytes + snd_pcm_oss_bytes(substream, status.avail); |
info.bytes = runtime->oss.bytes + snd_pcm_oss_bytes(substream, delay); |
1407 |
} |
} |
1408 |
info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); |
info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size); |
1409 |
if (atomic_read(&runtime->mmap_count)) { |
if (atomic_read(&runtime->mmap_count)) { |
1416 |
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1417 |
snd_pcm_oss_simulate_fill(substream); |
snd_pcm_oss_simulate_fill(substream); |
1418 |
} else { |
} else { |
1419 |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
info.blocks = delay / runtime->period_size; |
|
info.blocks = (runtime->buffer_size - status.avail) / runtime->period_size; |
|
|
else |
|
|
info.blocks = status.avail / runtime->period_size; |
|
1420 |
} |
} |
1421 |
if (copy_to_user(_info, &info, sizeof(info))) |
if (copy_to_user(_info, &info, sizeof(info))) |
1422 |
return -EFAULT; |
return -EFAULT; |
1427 |
{ |
{ |
1428 |
snd_pcm_substream_t *substream; |
snd_pcm_substream_t *substream; |
1429 |
snd_pcm_runtime_t *runtime; |
snd_pcm_runtime_t *runtime; |
1430 |
snd_pcm_status_t status; |
snd_pcm_sframes_t avail; |
1431 |
struct audio_buf_info info; |
struct audio_buf_info info; |
1432 |
int err; |
int err; |
1433 |
|
|
1444 |
|
|
1445 |
info.fragsize = runtime->oss.period_bytes; |
info.fragsize = runtime->oss.period_bytes; |
1446 |
info.fragstotal = runtime->periods; |
info.fragstotal = runtime->periods; |
|
memset(&status, 0, sizeof(status)); |
|
1447 |
if (runtime->oss.prepare) { |
if (runtime->oss.prepare) { |
1448 |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1449 |
info.bytes = runtime->oss.period_bytes * runtime->periods; |
info.bytes = runtime->oss.period_bytes * runtime->periods; |
1453 |
info.fragments = 0; |
info.fragments = 0; |
1454 |
} |
} |
1455 |
} else { |
} else { |
1456 |
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_STATUS, &status); |
if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1457 |
|
err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &avail); |
1458 |
|
avail = runtime->buffer_size - avail; |
1459 |
|
} else { |
1460 |
|
err = snd_pcm_oss_capture_position_fixup(substream, &avail); |
1461 |
|
} |
1462 |
if (err < 0) |
if (err < 0) |
1463 |
return err; |
return err; |
1464 |
info.bytes = snd_pcm_oss_bytes(substream, status.avail); |
info.bytes = snd_pcm_oss_bytes(substream, avail); |
1465 |
info.fragments = status.avail / runtime->period_size; |
info.fragments = avail / runtime->period_size; |
1466 |
} |
} |
1467 |
|
|
1468 |
#if 0 |
#ifdef OSS_DEBUG |
1469 |
/* very experimental stuff to get Quake2 working */ |
printk("pcm_oss: space: bytes = %i, fragments = %i, fragstotal = %i, fragsize = %i\n", info.bytes, info.fragments, info.fragstotal, info.fragsize); |
|
runtime->oss.period = (info.periods - 1) << 16; |
|
|
for (tmp = info.fragsize; tmp > 1; tmp >>= 1) |
|
|
runtime->oss.period++; |
|
|
runtime->oss.subdivision = 1; /* disable SUBDIVIDE */ |
|
1470 |
#endif |
#endif |
|
// printk("space: bytes = %i, periods = %i, fragstotal = %i, fragsize = %i\n", info.bytes, info.periods, info.fragstotal, info.fragsize); |
|
1471 |
if (copy_to_user(_info, &info, sizeof(info))) |
if (copy_to_user(_info, &info, sizeof(info))) |
1472 |
return -EFAULT; |
return -EFAULT; |
1473 |
return 0; |
return 0; |
1813 |
#endif |
#endif |
1814 |
if (((cmd >> 8) & 0xff) != 'P') |
if (((cmd >> 8) & 0xff) != 'P') |
1815 |
return -EINVAL; |
return -EINVAL; |
1816 |
|
#ifdef OSS_DEBUG |
1817 |
|
printk("pcm_oss: ioctl = 0x%x\n", cmd); |
1818 |
|
#endif |
1819 |
switch (cmd) { |
switch (cmd) { |
1820 |
case SNDCTL_DSP_RESET: |
case SNDCTL_DSP_RESET: |
1821 |
return snd_pcm_oss_reset(pcm_oss_file); |
return snd_pcm_oss_reset(pcm_oss_file); |
1871 |
case SOUND_PCM_WRITE_FILTER: |
case SOUND_PCM_WRITE_FILTER: |
1872 |
case SOUND_PCM_READ_FILTER: |
case SOUND_PCM_READ_FILTER: |
1873 |
return -EIO; |
return -EIO; |
1874 |
case SNDCTL_DSP_POST: /* to do */ |
case SNDCTL_DSP_POST: |
1875 |
return 0; |
return snd_pcm_oss_post(pcm_oss_file); |
1876 |
case SNDCTL_DSP_SUBDIVIDE: |
case SNDCTL_DSP_SUBDIVIDE: |
1877 |
if (get_user(res, (int *)arg)) |
if (get_user(res, (int *)arg)) |
1878 |
return -EFAULT; |
return -EFAULT; |
1955 |
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
1956 |
if (substream == NULL) |
if (substream == NULL) |
1957 |
return -ENXIO; |
return -ENXIO; |
1958 |
|
#ifndef OSS_DEBUG |
1959 |
return snd_pcm_oss_read1(substream, buf, count); |
return snd_pcm_oss_read1(substream, buf, count); |
1960 |
|
#else |
1961 |
|
{ |
1962 |
|
ssize_t res = snd_pcm_oss_read1(substream, buf, count); |
1963 |
|
printk("pcm_oss: read %li bytes (returned %li bytes)\n", (long)count, (long)res); |
1964 |
|
return res; |
1965 |
|
} |
1966 |
|
#endif |
1967 |
} |
} |
1968 |
|
|
1969 |
static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset) |
static ssize_t snd_pcm_oss_write(struct file *file, const char *buf, size_t count, loff_t *offset) |
1979 |
up(&file->f_dentry->d_inode->i_sem); |
up(&file->f_dentry->d_inode->i_sem); |
1980 |
result = snd_pcm_oss_write1(substream, buf, count); |
result = snd_pcm_oss_write1(substream, buf, count); |
1981 |
down(&file->f_dentry->d_inode->i_sem); |
down(&file->f_dentry->d_inode->i_sem); |
1982 |
|
#ifdef OSS_DEBUG |
1983 |
|
printk("pcm_oss: write %li bytes (wrote %li bytes)\n", (long)count, (long)result); |
1984 |
|
#endif |
1985 |
return result; |
return result; |
1986 |
} |
} |
1987 |
|
|
2027 |
} |
} |
2028 |
if (csubstream != NULL) { |
if (csubstream != NULL) { |
2029 |
snd_pcm_runtime_t *runtime = csubstream->runtime; |
snd_pcm_runtime_t *runtime = csubstream->runtime; |
2030 |
|
enum sndrv_pcm_state ostate; |
2031 |
poll_wait(file, &runtime->sleep, wait); |
poll_wait(file, &runtime->sleep, wait); |
2032 |
snd_pcm_stream_lock_irq(csubstream); |
snd_pcm_stream_lock_irq(csubstream); |
2033 |
if (runtime->status->state != SNDRV_PCM_STATE_RUNNING || |
if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING || |
2034 |
snd_pcm_oss_capture_ready(csubstream)) |
snd_pcm_oss_capture_ready(csubstream)) |
2035 |
mask |= POLLIN | POLLRDNORM; |
mask |= POLLIN | POLLRDNORM; |
2036 |
snd_pcm_stream_unlock_irq(csubstream); |
snd_pcm_stream_unlock_irq(csubstream); |
2037 |
|
if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) { |
2038 |
|
snd_pcm_oss_file_t ofile; |
2039 |
|
memset(&ofile, 0, sizeof(ofile)); |
2040 |
|
ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE]; |
2041 |
|
runtime->oss.trigger = 0; |
2042 |
|
snd_pcm_oss_set_trigger(&ofile, PCM_ENABLE_INPUT); |
2043 |
|
} |
2044 |
} |
} |
2045 |
|
|
2046 |
return mask; |
return mask; |
2053 |
snd_pcm_runtime_t *runtime; |
snd_pcm_runtime_t *runtime; |
2054 |
int err; |
int err; |
2055 |
|
|
2056 |
|
#ifdef OSS_DEBUG |
2057 |
|
printk("pcm_oss: mmap begin\n"); |
2058 |
|
#endif |
2059 |
pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO); |
pcm_oss_file = snd_magic_cast(snd_pcm_oss_file_t, file->private_data, return -ENXIO); |
2060 |
switch ((area->vm_flags & (VM_READ | VM_WRITE))) { |
switch ((area->vm_flags & (VM_READ | VM_WRITE))) { |
2061 |
case VM_READ | VM_WRITE: |
case VM_READ | VM_WRITE: |
2099 |
if (err < 0) |
if (err < 0) |
2100 |
return err; |
return err; |
2101 |
runtime->oss.mmap_bytes = area->vm_end - area->vm_start; |
runtime->oss.mmap_bytes = area->vm_end - area->vm_start; |
2102 |
|
#ifdef OSS_DEBUG |
2103 |
|
printk("pcm_oss: mmap ok, bytes = 0x%x\n", runtime->oss.mmap_bytes); |
2104 |
|
#endif |
2105 |
/* In mmap mode we never stop */ |
/* In mmap mode we never stop */ |
2106 |
runtime->stop_threshold = runtime->boundary; |
runtime->stop_threshold = runtime->boundary; |
2107 |
|
|
2119 |
snd_pcm_oss_setup_t *setup = pstr->oss.setup_list; |
snd_pcm_oss_setup_t *setup = pstr->oss.setup_list; |
2120 |
down(&pstr->oss.setup_mutex); |
down(&pstr->oss.setup_mutex); |
2121 |
while (setup) { |
while (setup) { |
2122 |
snd_iprintf(buffer, "%s %u %u%s%s%s%s\n", |
snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n", |
2123 |
setup->task_name, |
setup->task_name, |
2124 |
setup->periods, |
setup->periods, |
2125 |
setup->period_size, |
setup->period_size, |
2126 |
setup->disable ? " disable" : "", |
setup->disable ? " disable" : "", |
2127 |
setup->direct ? " direct" : "", |
setup->direct ? " direct" : "", |
2128 |
setup->block ? " block" : "", |
setup->block ? " block" : "", |
2129 |
setup->nonblock ? " non-block" : ""); |
setup->nonblock ? " non-block" : "", |
2130 |
|
setup->wholefrag ? " whole-frag" : "", |
2131 |
|
setup->nosilence ? " no-silence" : ""); |
2132 |
setup = setup->next; |
setup = setup->next; |
2133 |
} |
} |
2134 |
up(&pstr->oss.setup_mutex); |
up(&pstr->oss.setup_mutex); |
2194 |
template.block = 1; |
template.block = 1; |
2195 |
} else if (!strcmp(str, "non-block")) { |
} else if (!strcmp(str, "non-block")) { |
2196 |
template.nonblock = 1; |
template.nonblock = 1; |
2197 |
|
} else if (!strcmp(str, "whole-frag")) { |
2198 |
|
template.wholefrag = 1; |
2199 |
|
} else if (!strcmp(str, "no-silence")) { |
2200 |
|
template.nosilence = 1; |
2201 |
} |
} |
2202 |
} while (*str); |
} while (*str); |
2203 |
if (setup == NULL) { |
if (setup == NULL) { |
2389 |
|
|
2390 |
module_init(alsa_pcm_oss_init) |
module_init(alsa_pcm_oss_init) |
2391 |
module_exit(alsa_pcm_oss_exit) |
module_exit(alsa_pcm_oss_exit) |
2392 |
|
|
2393 |
|
#ifndef MODULE |
2394 |
|
|
2395 |
|
/* format is: snd-pcm-oss=dsp_map,adsp_map[,nonblock_open] */ |
2396 |
|
|
2397 |
|
static int __init alsa_pcm_oss_setup(char *str) |
2398 |
|
{ |
2399 |
|
static unsigned __initdata nr_dev = 0; |
2400 |
|
|
2401 |
|
if (nr_dev >= SNDRV_CARDS) |
2402 |
|
return 0; |
2403 |
|
(void)(get_option(&str,&dsp_map[nr_dev]) == 2 && |
2404 |
|
get_option(&str,&adsp_map[nr_dev]) == 2); |
2405 |
|
(void)(get_option(&str,&nonblock_open) == 2); |
2406 |
|
nr_dev++; |
2407 |
|
return 1; |
2408 |
|
} |
2409 |
|
|
2410 |
|
__setup("snd-pcm-oss=", alsa_pcm_oss_setup); |
2411 |
|
|
2412 |
|
#endif /* !MODULE */ |