Home | History | Annotate | Line # | Download | only in ossaudio
ossaudio.c revision 1.3
      1 /*	$NetBSD: ossaudio.c,v 1.3 1997/03/19 05:12:13 mycroft Exp $	*/
      2 #include <sys/param.h>
      3 #include <sys/proc.h>
      4 #include <sys/systm.h>
      5 #include <sys/file.h>
      6 #include <sys/filedesc.h>
      7 #include <sys/ioctl.h>
      8 #include <sys/mount.h>
      9 #include <sys/audioio.h>
     10 
     11 #include <sys/syscallargs.h>
     12 
     13 #include <compat/linux/linux_types.h>
     14 #include <compat/linux/linux_ioctl.h>
     15 #include <compat/linux/linux_signal.h>
     16 #include <compat/linux/linux_syscallargs.h>
     17 #include <compat/linux/linux_audio.h>
     18 
     19 int
     20 linux_ioctl_audio(p, uap, retval)
     21 	register struct proc *p;
     22 	register struct linux_sys_ioctl_args /* {
     23 		syscallarg(int) fd;
     24 		syscallarg(u_long) com;
     25 		syscallarg(caddr_t) data;
     26 	} */ *uap;
     27 	register_t *retval;
     28 {
     29 	register struct file *fp;
     30 	register struct filedesc *fdp;
     31 	u_long com;
     32 	struct audio_info tmpinfo;
     33 	int idat;
     34 	int error;
     35 
     36 	fdp = p->p_fd;
     37 	if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
     38 	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
     39 		return (EBADF);
     40 
     41 	if ((fp->f_flag & (FREAD | FWRITE)) == 0)
     42 		return (EBADF);
     43 
     44 	com = SCARG(uap, com);
     45 	retval[0] = 0;
     46 
     47 	switch (com) {
     48 	case LINUX_SNDCTL_DSP_RESET:
     49 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_FLUSH, (caddr_t)0, p);
     50 		if (error)
     51 			return error;
     52 		break;
     53 	case LINUX_SNDCTL_DSP_SYNC:
     54 	case LINUX_SNDCTL_DSP_POST:
     55 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_DRAIN, (caddr_t)0, p);
     56 		if (error)
     57 			return error;
     58 		break;
     59 	case LINUX_SNDCTL_DSP_SPEED:
     60 		AUDIO_INITINFO(&tmpinfo);
     61 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
     62 		if (error)
     63 			return error;
     64 		tmpinfo.play.sample_rate =
     65 		tmpinfo.record.sample_rate = idat;
     66 		(void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
     67 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
     68 		if (error)
     69 			return error;
     70 		idat = tmpinfo.play.sample_rate;
     71 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
     72 		if (error)
     73 			return error;
     74 		break;
     75 	case LINUX_SNDCTL_DSP_STEREO:
     76 		AUDIO_INITINFO(&tmpinfo);
     77 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
     78 		if (error)
     79 			return error;
     80 		tmpinfo.play.channels =
     81 		tmpinfo.record.channels = idat ? 2 : 1;
     82 		(void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
     83 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
     84 		if (error)
     85 			return error;
     86 		idat = tmpinfo.play.channels - 1;
     87 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
     88 		if (error)
     89 			return error;
     90 		break;
     91 	case LINUX_SOUND_PCM_WRITE_CHANNELS:
     92 		AUDIO_INITINFO(&tmpinfo);
     93 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
     94 		if (error)
     95 			return error;
     96 		tmpinfo.play.channels =
     97 		tmpinfo.record.channels = idat;
     98 		(void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
     99 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
    100 		if (error)
    101 			return error;
    102 		idat = tmpinfo.play.channels;
    103 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
    104 		if (error)
    105 			return error;
    106 		break;
    107 	case LINUX_SNDCTL_DSP_GETBLKSIZE:
    108 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
    109 		if (error)
    110 			return error;
    111 		idat = tmpinfo.blocksize;
    112 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
    113 		if (error)
    114 			return error;
    115 		break;
    116 	case LINUX_SNDCTL_DSP_SETFMT:
    117 		AUDIO_INITINFO(&tmpinfo);
    118 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
    119 		if (error)
    120 			return error;
    121 		switch (idat) {
    122 		case LINUX_AFMT_MU_LAW:
    123 			tmpinfo.play.precision =
    124 			tmpinfo.record.precision = 8;
    125 			tmpinfo.play.encoding =
    126 			tmpinfo.record.encoding = AUDIO_ENCODING_ULAW;
    127 			break;
    128 		case LINUX_AFMT_A_LAW:
    129 			tmpinfo.play.precision =
    130 			tmpinfo.record.precision = 8;
    131 			tmpinfo.play.encoding =
    132 			tmpinfo.record.encoding = AUDIO_ENCODING_ALAW;
    133 			break;
    134 		case LINUX_AFMT_U8:
    135 			tmpinfo.play.precision =
    136 			tmpinfo.record.precision = 8;
    137 			tmpinfo.play.encoding =
    138 			tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
    139 			break;
    140 		case LINUX_AFMT_S16_LE:
    141 			tmpinfo.play.precision =
    142 			tmpinfo.record.precision = 16;
    143 			tmpinfo.play.encoding =
    144 			tmpinfo.record.encoding = AUDIO_ENCODING_LINEAR;
    145 			break;
    146 		default:
    147 			return EINVAL;
    148 		}
    149 		(void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
    150 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
    151 		if (error)
    152 			return error;
    153 		/*XXXX*/
    154 		break;
    155 	case LINUX_SNDCTL_DSP_SETFRAGMENT:
    156 		AUDIO_INITINFO(&tmpinfo);
    157 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
    158 		if (error)
    159 			return error;
    160 		if ((idat & 0xffff) < 4 || (idat & 0xffff) > 17)
    161 			return EINVAL;
    162 		tmpinfo.blocksize = 1 << (idat & 0xffff);
    163 		tmpinfo.hiwat = (idat >> 16) & 0xffff;
    164 		(void) (*fp->f_ops->fo_ioctl)(fp, AUDIO_SETINFO, (caddr_t)&tmpinfo, p);
    165 		error = (*fp->f_ops->fo_ioctl)(fp, AUDIO_GETINFO, (caddr_t)&tmpinfo, p);
    166 		if (error)
    167 			return error;
    168 		idat = tmpinfo.blocksize;
    169 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
    170 		if (error)
    171 			return error;
    172 		break;
    173 	case LINUX_SNDCTL_DSP_GETFMTS:
    174 		idat = LINUX_AFMT_MU_LAW | LINUX_AFMT_U8 | LINUX_AFMT_S16_LE;
    175 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
    176 		if (error)
    177 			return error;
    178 		break;
    179 	default:
    180 		return EINVAL;
    181 	}
    182 
    183 	return 0;
    184 }
    185 
    186 int
    187 linux_ioctl_mixer(p, uap, retval)
    188 	register struct proc *p;
    189 	register struct linux_sys_ioctl_args /* {
    190 		syscallarg(int) fd;
    191 		syscallarg(u_long) com;
    192 		syscallarg(caddr_t) data;
    193 	} */ *uap;
    194 	register_t *retval;
    195 {
    196 	register struct file *fp;
    197 	register struct filedesc *fdp;
    198 	u_long com;
    199 #if 0
    200 	struct audio_info tmpinfo;
    201 	int idat;
    202 	int error;
    203 #endif
    204 
    205 	fdp = p->p_fd;
    206 	if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||
    207 	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
    208 		return (EBADF);
    209 
    210 	if ((fp->f_flag & (FREAD | FWRITE)) == 0)
    211 		return (EBADF);
    212 
    213 	com = SCARG(uap, com);
    214 	retval[0] = 0;
    215 
    216 	switch (com) {
    217 	default:
    218 		return EINVAL;
    219 	}
    220 }
    221