patch-1.3.34 linux/drivers/sound/audio.c
Next file: linux/drivers/sound/configure.c
Previous file: linux/drivers/sound/aedsp16.c
Back to the patch index
Back to the overall index
- Lines: 364
- Date:
Wed Oct 11 07:55:38 1995
- Orig file:
v1.3.33/linux/drivers/sound/audio.c
- Orig date:
Sun Aug 13 14:45:33 1995
diff -u --recursive --new-file v1.3.33/linux/drivers/sound/audio.c linux/drivers/sound/audio.c
@@ -74,7 +74,7 @@
else
fmt = AFMT_U8; /* This is always supported */
- audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, fmt, 1);
+ audio_format[dev] = DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, (ioctl_arg) fmt, 1);
}
if (local_conversion[dev]) /* This shadows the HW format */
@@ -113,10 +113,10 @@
local_conversion[dev] = 0;
- if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, bits, 1) != bits)
+ if (DMAbuf_ioctl (dev, SNDCTL_DSP_SETFMT, (ioctl_arg) bits, 1) != bits)
{
audio_release (dev, file);
- return RET_ERROR (ENXIO);
+ return -ENXIO;
}
if (dev_type == SND_DEV_AUDIO)
@@ -156,31 +156,37 @@
#ifdef NO_INLINE_ASM
static void
-translate_bytes (const unsigned char *table, unsigned char *buff, unsigned long n)
+translate_bytes (const unsigned char *table, unsigned char *buff, int n)
{
unsigned long i;
+ if (n <= 0)
+ return;
+
for (i = 0; i < n; ++i)
buff[i] = table[buff[i]];
}
#else
extern inline void
-translate_bytes (const void *table, void *buff, unsigned long n)
+translate_bytes (const void *table, void *buff, int n)
{
- __asm__ ("cld\n"
- "1:\tlodsb\n\t"
- "xlatb\n\t"
- "stosb\n\t"
-"loop 1b\n\t":
-: "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
-: "bx", "cx", "di", "si", "ax");
+ if (n > 0)
+ {
+ __asm__ ("cld\n"
+ "1:\tlodsb\n\t"
+ "xlatb\n\t"
+ "stosb\n\t"
+ "loop 1b\n\t":
+ : "b" ((long) table), "c" (n), "D" ((long) buff), "S" ((long) buff)
+ : "bx", "cx", "di", "si", "ax");
+ }
}
#endif
int
-audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
+audio_write (int dev, struct fileinfo *file, const snd_rw_buf * buf, int count)
{
int c, p, l;
int err;
@@ -190,14 +196,15 @@
p = 0;
c = count;
- if (audio_mode[dev] == AM_READ) /*
- * Direction changed
- */
- {
+ if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ { /* Direction change */
wr_buff_no[dev] = -1;
}
- audio_mode[dev] = AM_WRITE;
+ if (audio_devs[dev]->flags & DMA_DUPLEX)
+ audio_mode[dev] |= AM_WRITE;
+ else
+ audio_mode[dev] = AM_WRITE;
if (!count) /*
* Flush output
@@ -225,7 +232,7 @@
dev_nblock[dev])) < 0)
{
/* Handle nonblocking mode */
- if (dev_nblock[dev] && wr_buff_no[dev] == RET_ERROR (EAGAIN))
+ if (dev_nblock[dev] && wr_buff_no[dev] == -EAGAIN)
return p; /* No more space. Return # of accepted bytes */
return wr_buff_no[dev];
}
@@ -240,7 +247,7 @@
{ /*
* No device specific copy routine
*/
- COPY_FROM_USER (&wr_dma_buf[dev][wr_buff_ptr[dev]], buf, p, l);
+ memcpy_fromfs ((&wr_dma_buf[dev][wr_buff_ptr[dev]]), &((buf)[p]), (l));
}
else
audio_devs[dev]->copy_from_user (dev,
@@ -253,12 +260,10 @@
if (local_conversion[dev] == AFMT_MU_LAW)
{
-#ifdef linux
/*
* This just allows interrupts while the conversion is running
*/
__asm__ ("sti");
-#endif
translate_bytes (ulaw_dsp, (unsigned char *) &wr_dma_buf[dev][wr_buff_ptr[dev]], l);
}
@@ -292,17 +297,21 @@
p = 0;
c = count;
- if (audio_mode[dev] == AM_WRITE)
+ if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
{
if (wr_buff_no[dev] >= 0)
{
DMAbuf_start_output (dev, wr_buff_no[dev], wr_buff_ptr[dev]);
- wr_buff_no[dev] = -1;
+ if (!(audio_devs[dev]->flags & DMA_DUPLEX))
+ wr_buff_no[dev] = -1;
}
}
- audio_mode[dev] = AM_READ;
+ if (audio_devs[dev]->flags & DMA_DUPLEX)
+ audio_mode[dev] |= AM_READ;
+ else
+ audio_mode[dev] = AM_READ;
while (c)
{
@@ -311,7 +320,7 @@
{
/* Nonblocking mode handling. Return current # of bytes */
- if (dev_nblock[dev] && buff_no == RET_ERROR (EAGAIN))
+ if (dev_nblock[dev] && buff_no == -EAGAIN)
return p;
return buff_no;
@@ -326,17 +335,15 @@
if (local_conversion[dev] == AFMT_MU_LAW)
{
-#ifdef linux
/*
* This just allows interrupts while the conversion is running
*/
__asm__ ("sti");
-#endif
translate_bytes (dsp_ulaw, (unsigned char *) dmabuf, l);
}
- COPY_TO_USER (buf, p, dmabuf, l);
+ memcpy_tofs (&((buf)[p]), (dmabuf), (l));
DMAbuf_rmchars (dev, buff_no, l);
@@ -349,7 +356,7 @@
int
audio_ioctl (int dev, struct fileinfo *file,
- unsigned int cmd, unsigned int arg)
+ unsigned int cmd, ioctl_arg arg)
{
dev = dev >> 4;
@@ -361,7 +368,7 @@
else
printk ("/dev/dsp%d: No coprocessor for this device\n", dev);
- return RET_ERROR (EREMOTEIO);
+ return -ENXIO;
}
else
switch (cmd)
@@ -388,40 +395,41 @@
case SNDCTL_DSP_RESET:
wr_buff_no[dev] = -1;
+ audio_mode[dev] = AM_NONE;
return DMAbuf_ioctl (dev, cmd, arg, 0);
break;
case SNDCTL_DSP_GETFMTS:
- return IOCTL_OUT (arg, audio_devs[dev]->format_mask);
+ return snd_ioctl_return ((int *) arg, audio_devs[dev]->format_mask);
break;
case SNDCTL_DSP_SETFMT:
- return IOCTL_OUT (arg, set_format (dev, IOCTL_IN (arg)));
+ return snd_ioctl_return ((int *) arg, set_format (dev, get_fs_long ((long *) arg)));
case SNDCTL_DSP_GETISPACE:
- if (audio_mode[dev] == AM_WRITE)
- return RET_ERROR (EBUSY);
+ if ((audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
{
audio_buf_info info;
- int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
+ int err = DMAbuf_ioctl (dev, cmd, (ioctl_arg) & info, 1);
if (err < 0)
return err;
- IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
+ memcpy_tofs (&(((char *) arg)[0]), ((char *) &info), (sizeof (info)));
return 0;
}
case SNDCTL_DSP_GETOSPACE:
- if (audio_mode[dev] == AM_READ)
- return RET_ERROR (EBUSY);
+ if ((audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return -EBUSY;
{
audio_buf_info info;
- int err = DMAbuf_ioctl (dev, cmd, (unsigned long) &info, 1);
+ int err = DMAbuf_ioctl (dev, cmd, (ioctl_arg) & info, 1);
if (err < 0)
return err;
@@ -429,7 +437,7 @@
if (wr_buff_no[dev] != -1)
info.bytes += wr_buff_size[dev] - wr_buff_ptr[dev];
- IOCTL_TO_USER ((char *) arg, 0, (char *) &info, sizeof (info));
+ memcpy_tofs (&(((char *) arg)[0]), ((char *) &info), (sizeof (info)));
return 0;
}
@@ -438,6 +446,27 @@
return 0;
break;
+ case SNDCTL_DSP_GETCAPS:
+ {
+ int info = 1; /* Revision level of this ioctl() */
+
+ if (audio_devs[dev]->flags & DMA_DUPLEX)
+ info |= DSP_CAP_DUPLEX;
+
+ if (audio_devs[dev]->coproc)
+ info |= DSP_CAP_COPROC;
+
+ if (audio_devs[dev]->local_qlen) /* Device has hidden buffers */
+ info |= DSP_CAP_BATCH;
+
+ if (audio_devs[dev]->trigger) /* Supports SETTRIGGER */
+ info |= DSP_CAP_TRIGGER;
+
+ memcpy_tofs (&(((char *) arg)[0]), ((char *) &info), (sizeof (info)));
+ return 0;
+ }
+ break;
+
default:
return DMAbuf_ioctl (dev, cmd, arg, 0);
}
@@ -452,31 +481,25 @@
return mem_start;
}
-#ifdef ALLOW_SELECT
int
audio_select (int dev, struct fileinfo *file, int sel_type, select_table * wait)
{
- int l;
- char *dmabuf;
dev = dev >> 4;
switch (sel_type)
{
case SEL_IN:
- if (audio_mode[dev] != AM_READ) /* Wrong direction */
- return 0;
+ if (!(audio_mode[dev] & AM_READ) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return 0; /* Not recording */
- if (DMAbuf_getrdbuffer (dev, &dmabuf, &l,
- 1 /* Don't block */ ) >= 0)
- return 1; /* We have data */
return DMAbuf_select (dev, file, sel_type, wait);
break;
case SEL_OUT:
- if (audio_mode[dev] == AM_READ) /* Wrong direction */
- return 0;
+ if (!(audio_mode[dev] & AM_WRITE) && !(audio_devs[dev]->flags & DMA_DUPLEX))
+ return 0; /* Wrong direction */
if (wr_buff_no[dev] != -1)
return 1; /* There is space in the current buffer */
@@ -491,7 +514,6 @@
return 0;
}
-#endif /* ALLOW_SELECT */
#else /* EXCLUDE_AUDIO */
/*
@@ -501,19 +523,19 @@
int
audio_read (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
{
- return RET_ERROR (EIO);
+ return -EIO;
}
int
audio_write (int dev, struct fileinfo *file, snd_rw_buf * buf, int count)
{
- return RET_ERROR (EIO);
+ return -EIO;
}
int
audio_open (int dev, struct fileinfo *file)
{
- return RET_ERROR (ENXIO);
+ return -ENXIO;
}
void
@@ -524,13 +546,13 @@
audio_ioctl (int dev, struct fileinfo *file,
unsigned int cmd, unsigned int arg)
{
- return RET_ERROR (EIO);
+ return -EIO;
}
int
audio_lseek (int dev, struct fileinfo *file, off_t offset, int orig)
{
- return RET_ERROR (EIO);
+ return -EIO;
}
long
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this