patch-2.1.77 linux/drivers/sound/pss.c
Next file: linux/drivers/sound/sb_audio.c
Previous file: linux/drivers/sound/pas2_pcm.c
Back to the patch index
Back to the overall index
- Lines: 434
- Date:
Tue Dec 30 10:59:17 1997
- Orig file:
v2.1.76/linux/drivers/sound/pss.c
- Orig date:
Tue Dec 23 16:31:00 1997
diff -u --recursive --new-file v2.1.76/linux/drivers/sound/pss.c linux/drivers/sound/pss.c
@@ -10,6 +10,9 @@
* Version 2 (June 1991). See the "COPYING" file distributed with this software
* for more info.
*/
+/*
+ * Thomas Sailer : ioctl code reworked (vmalloc/vfree removed)
+ */
#include <linux/config.h>
#include <linux/module.h>
@@ -498,257 +501,177 @@
return 0;
}
-static int
-pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
+static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, caddr_t arg, int local)
{
+ copr_buffer *buf;
+ copr_msg *mbuf;
+ copr_debug_buf dbuf;
+ unsigned short tmp;
+ unsigned long flags;
+ unsigned short *data;
+ int i, err;
/* printk( "PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
+
+ switch (cmd) {
+ case SNDCTL_COPR_RESET:
+ pss_coproc_reset(dev_info);
+ return 0;
- switch (cmd)
- {
- case SNDCTL_COPR_RESET:
- pss_coproc_reset(dev_info);
- return 0;
- break;
-
- case SNDCTL_COPR_LOAD:
- {
- copr_buffer *buf;
- int err;
-
- buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
- if (buf == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
- err = download_boot_block(dev_info, buf);
- vfree(buf);
- return err;
- }
- break;
-
- case SNDCTL_COPR_SENDMSG:
- {
- copr_msg *buf;
- unsigned long flags;
- unsigned short *data;
- int i;
-
- buf = (copr_msg *) vmalloc(sizeof(copr_msg));
- if (buf == NULL)
- return -ENOSPC;
-
- memcpy((char *) buf, (&((char *) arg)[0]), sizeof(*buf));
-
- data = (unsigned short *) (buf->data);
-
- save_flags(flags);
- cli();
-
- for (i = 0; i < buf->len; i++)
- {
- if (!pss_put_dspword(devc, *data++))
- {
- restore_flags(flags);
- buf->len = i; /* feed back number of WORDs sent */
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
- return -EIO;
- }
- }
-
- restore_flags(flags);
- vfree(buf);
-
- return 0;
- }
- break;
-
-
- case SNDCTL_COPR_RCVMSG:
- {
- copr_msg *buf;
- unsigned long flags;
- unsigned short *data;
- unsigned int i;
- int err = 0;
-
- buf = (copr_msg *) vmalloc(sizeof(copr_msg));
- if (buf == NULL)
- return -ENOSPC;
-
-
- data = (unsigned short *) buf->data;
-
- save_flags(flags);
- cli();
-
- for (i = 0; i < buf->len; i++)
- {
- buf->len = i; /* feed back number of WORDs read */
- if (!pss_get_dspword(devc, data++))
- {
- if (i == 0)
- err = -EIO;
- break;
- }
- }
-
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) buf, sizeof(*buf));
- vfree(buf);
-
- return err;
- }
- break;
-
-
- case SNDCTL_COPR_RDATA:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d0))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 = tmp;
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) &buf, sizeof(buf));
- return 0;
- }
- break;
-
- case SNDCTL_COPR_WDATA:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d1))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int) buf.parm2 & 0xffff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_COPR_WCODE:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d3))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = (unsigned int) buf.parm2 & 0x00ff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
- if (!pss_put_dspword(devc, tmp))
- {
- restore_flags(flags);
- return -EIO;
- }
- restore_flags(flags);
- return 0;
- }
- break;
-
- case SNDCTL_COPR_RCODE:
- {
- copr_debug_buf buf;
- unsigned long flags;
- unsigned short tmp;
-
- memcpy((char *) &buf, (&((char *) arg)[0]), sizeof(buf));
-
- save_flags(flags);
- cli();
- if (!pss_put_dspword(devc, 0x00d2))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_put_dspword(devc, (unsigned short) (buf.parm1 & 0xffff)))
- {
- restore_flags(flags);
- return -EIO;
- }
- if (!pss_get_dspword(devc, &tmp)) /* Read MSB */
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 = tmp << 8;
-
- if (!pss_get_dspword(devc, &tmp)) /* Read LSB */
- {
- restore_flags(flags);
- return -EIO;
- }
- buf.parm1 |= tmp & 0x00ff;
-
- restore_flags(flags);
-
- memcpy((&((char *) arg)[0]), (char *) &buf, sizeof(buf));
- return 0;
- }
- break;
+ case SNDCTL_COPR_LOAD:
+ buf = (copr_buffer *) vmalloc(sizeof(copr_buffer));
+ if (buf == NULL)
+ return -ENOSPC;
+ if (__copy_from_user(buf, arg, sizeof(copr_buffer))) {
+ vfree(buf);
+ return -EFAULT;
+ }
+ err = download_boot_block(dev_info, buf);
+ vfree(buf);
+ return err;
+
+ case SNDCTL_COPR_SENDMSG:
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ if (__copy_from_user(mbuf, arg, sizeof(copr_msg))) {
+ vfree(mbuf);
+ return -EFAULT;
+ }
+ data = (unsigned short *)(mbuf->data);
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ if (!pss_put_dspword(devc, *data++)) {
+ restore_flags(flags);
+ mbuf->len = i; /* feed back number of WORDs sent */
+ err = __copy_to_user(arg, mbuf, sizeof(copr_msg));
+ vfree(mbuf);
+ return err ? err : -EIO;
+ }
+ }
+ restore_flags(flags);
+ vfree(mbuf);
+ return 0;
- default:
- return -EINVAL;
- }
+ case SNDCTL_COPR_RCVMSG:
+ err = 0;
+ mbuf = (copr_msg *)vmalloc(sizeof(copr_msg));
+ if (mbuf == NULL)
+ return -ENOSPC;
+ data = (unsigned short *)mbuf->data;
+ save_flags(flags);
+ cli();
+ for (i = 0; i < mbuf->len; i++) {
+ mbuf->len = i; /* feed back number of WORDs read */
+ if (!pss_get_dspword(devc, data++)) {
+ if (i == 0)
+ err = -EIO;
+ break;
+ }
+ }
+ restore_flags(flags);
+ if (__copy_to_user(arg, mbuf, sizeof(copr_msg)))
+ err = -EFAULT;
+ vfree(mbuf);
+ return err;
+
+ case SNDCTL_COPR_RDATA:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d0)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp;
+ restore_flags(flags);
+ return __copy_to_user(arg, &dbuf, sizeof(dbuf));
+
+ case SNDCTL_COPR_WDATA:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d1)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short) (dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ restore_flags(flags);
+ return 0;
+
+ case SNDCTL_COPR_WCODE:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d3)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = (unsigned int)dbuf.parm2 & 0x00ff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ tmp = ((unsigned int)dbuf.parm2 >> 8) & 0xffff;
+ if (!pss_put_dspword(devc, tmp)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ restore_flags(flags);
+ return 0;
+
+ case SNDCTL_COPR_RCODE:
+ if (__copy_from_user(&dbuf, arg, sizeof(dbuf)))
+ return -EFAULT;
+ save_flags(flags);
+ cli();
+ if (!pss_put_dspword(devc, 0x00d2)) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_put_dspword(devc, (unsigned short)(dbuf.parm1 & 0xffff))) {
+ restore_flags(flags);
+ return -EIO;
+ }
+ if (!pss_get_dspword(devc, &tmp)) { /* Read MSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 = tmp << 8;
+ if (!pss_get_dspword(devc, &tmp)) { /* Read LSB */
+ restore_flags(flags);
+ return -EIO;
+ }
+ dbuf.parm1 |= tmp & 0x00ff;
+ restore_flags(flags);
+ return __copy_to_user(arg, &dbuf, sizeof(dbuf));
+ default:
+ return -EINVAL;
+ }
return -EINVAL;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov