if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) retval = -EFAULT; 
{ char arg_str[100]; snprintf(arg_str, sizeof(arg_str), "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); if (copy_to_user(argp, arg_str, strlen(arg_str))) retval = -EFAULT; } 
static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg){	IXJ_TONE ti;	IXJ_FILTER jf;	IXJ_FILTER_RAW jfr;	void __user *argp = (void __user *)arg;	unsigned int raise, mant;	unsigned int minor = iminor(inode);	int board = NUM(inode);	IXJ *j = get_ixj(NUM(inode));	int retval = 0;	/*	 *    Set up locks to ensure that only one process is talking to the DSP at a time.	 *    This is necessary to keep the DSP from locking up.	 */	while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {		set_current_state(TASK_INTERRUPTIBLE);		schedule_timeout(1);	}	if (ixjdebug & 0x0040)		printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);	if (minor >= IXJMAX) {		clear_bit(board, &j->busyflags);		return -ENODEV;	}	/*	 *    Check ioctls only root can use.	 */	if (!capable(CAP_SYS_ADMIN)) {		switch (cmd) {		case IXJCTL_TESTRAM:		case IXJCTL_HZ:			retval = -EPERM;		}	}	switch (cmd) {	case IXJCTL_TESTRAM:		ixj_testram(j);		retval = (j->ssr.high << 8) + j->ssr.low;		break;	case IXJCTL_CARDTYPE:		retval = j->cardtype;		break;	case IXJCTL_SERIAL:		retval = j->serial;		break;	case IXJCTL_VERSION:		if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) 			retval = -EFAULT;		break;	case PHONE_RING_CADENCE:		j->ring_cadence = arg;		break;	case IXJCTL_CIDCW:		if(arg) {			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {				retval = -EFAULT;				break;			}		} else {			memset(&j->cid_send, 0, sizeof(PHONE_CID));		}		ixj_write_cidcw(j);		break;        /* Binary compatbility */        case OLD_PHONE_RING_START:                arg = 0;                /* Fall through */ 	case PHONE_RING_START:		if(arg) {			if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {				retval = -EFAULT;				break;			}			ixj_write_cid(j);		} else {			memset(&j->cid_send, 0, sizeof(PHONE_CID));		}		ixj_ring_start(j);		break;	case PHONE_RING_STOP:		j->flags.cringing = 0;		if(j->cadence_f[5].enable) {			j->cadence_f[5].state = 0;		}		ixj_ring_off(j);		break;	case PHONE_RING:		retval = ixj_ring(j);		break;	case PHONE_EXCEPTION:		retval = j->ex.bytes;		if(j->ex.bits.flash) {			j->flash_end = 0;			j->ex.bits.flash = 0;		}		j->ex.bits.pstn_ring = 0;		j->ex.bits.caller_id = 0;		j->ex.bits.pstn_wink = 0;		j->ex.bits.f0 = 0;		j->ex.bits.f1 = 0;		j->ex.bits.f2 = 0;		j->ex.bits.f3 = 0;		j->ex.bits.fc0 = 0;		j->ex.bits.fc1 = 0;		j->ex.bits.fc2 = 0;		j->ex.bits.fc3 = 0;		j->ex.bits.reserved = 0;		break;	case PHONE_HOOKSTATE:		j->ex.bits.hookstate = 0;		retval = j->hookstate;  //j->r_hook;		break;	case IXJCTL_SET_LED:		LED_SetState(arg, j);		break;	case PHONE_FRAME:		retval = set_base_frame(j, arg);		break;	case PHONE_REC_CODEC:		retval = set_rec_codec(j, arg);		break;	case PHONE_VAD:		ixj_vad(j, arg);		break;	case PHONE_REC_START:		ixj_record_start(j);		break;	case PHONE_REC_STOP:		ixj_record_stop(j);		break;	case PHONE_REC_DEPTH:		set_rec_depth(j, arg);		break;	case PHONE_REC_VOLUME:		if(arg == -1) {			retval = get_rec_volume(j);		}		else {			set_rec_volume(j, arg);			retval = arg;		}		break;	case PHONE_REC_VOLUME_LINEAR:		if(arg == -1) {			retval = get_rec_volume_linear(j);		}		else {			set_rec_volume_linear(j, arg);			retval = arg;		}		break;	case IXJCTL_DTMF_PRESCALE:		if(arg == -1) {			retval = get_dtmf_prescale(j);		}		else {			set_dtmf_prescale(j, arg);			retval = arg;		}		break;	case PHONE_REC_LEVEL:		retval = get_rec_level(j);		break;	case IXJCTL_SC_RXG:		retval = ixj_siadc(j, arg);		break;	case IXJCTL_SC_TXG:		retval = ixj_sidac(j, arg);		break;	case IXJCTL_AEC_START:		ixj_aec_start(j, arg);		break;	case IXJCTL_AEC_STOP:		aec_stop(j);		break;	case IXJCTL_AEC_GET_LEVEL:		retval = j->aec_level;		break;	case PHONE_PLAY_CODEC:		retval = set_play_codec(j, arg);		break;	case PHONE_PLAY_START:		retval = ixj_play_start(j);		break;	case PHONE_PLAY_STOP:		ixj_play_stop(j);		break;	case PHONE_PLAY_DEPTH:		set_play_depth(j, arg);		break;	case PHONE_PLAY_VOLUME:		if(arg == -1) {			retval = get_play_volume(j);		}		else {			set_play_volume(j, arg);			retval = arg;		}		break;	case PHONE_PLAY_VOLUME_LINEAR:		if(arg == -1) {			retval = get_play_volume_linear(j);		}		else {			set_play_volume_linear(j, arg);			retval = arg;		}		break;	case PHONE_PLAY_LEVEL:		retval = get_play_level(j);		break;	case IXJCTL_DSP_TYPE:		retval = (j->dsp.high << 8) + j->dsp.low;		break;	case IXJCTL_DSP_VERSION:		retval = (j->ver.high << 8) + j->ver.low;		break;	case IXJCTL_HZ:		hertz = arg;		break;	case IXJCTL_RATE:		if (arg > hertz)			retval = -1;		else			samplerate = arg;		break;	case IXJCTL_DRYBUFFER_READ:		put_user(j->drybuffer, (unsigned long __user *) argp);		break;	case IXJCTL_DRYBUFFER_CLEAR:		j->drybuffer = 0;		break;	case IXJCTL_FRAMES_READ:		put_user(j->framesread, (unsigned long __user *) argp);		break;	case IXJCTL_FRAMES_WRITTEN:		put_user(j->frameswritten, (unsigned long __user *) argp);		break;	case IXJCTL_READ_WAIT:		put_user(j->read_wait, (unsigned long __user *) argp);		break;	case IXJCTL_WRITE_WAIT:		put_user(j->write_wait, (unsigned long __user *) argp);		break;	case PHONE_MAXRINGS:		j->maxrings = arg;		break;	case PHONE_SET_TONE_ON_TIME:		ixj_set_tone_on(arg, j);		break;	case PHONE_SET_TONE_OFF_TIME:		ixj_set_tone_off(arg, j);		break;	case PHONE_GET_TONE_ON_TIME:		if (ixj_get_tone_on(j)) {			retval = -1;		} else {			retval = (j->ssr.high << 8) + j->ssr.low;		}		break;	case PHONE_GET_TONE_OFF_TIME:		if (ixj_get_tone_off(j)) {			retval = -1;		} else {			retval = (j->ssr.high << 8) + j->ssr.low;		}		break;	case PHONE_PLAY_TONE:		if (!j->tone_state)			retval = ixj_play_tone(j, arg);		else			retval = -1;		break;	case PHONE_GET_TONE_STATE:		retval = j->tone_state;		break;	case PHONE_DTMF_READY:		retval = j->ex.bits.dtmf_ready;		break;	case PHONE_GET_DTMF:		if (ixj_hookstate(j)) {			if (j->dtmf_rp != j->dtmf_wp) {				retval = j->dtmfbuffer[j->dtmf_rp];				j->dtmf_rp++;				if (j->dtmf_rp == 79)					j->dtmf_rp = 0;				if (j->dtmf_rp == j->dtmf_wp) {					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;				}			}		}		break;	case PHONE_GET_DTMF_ASCII:		if (ixj_hookstate(j)) {			if (j->dtmf_rp != j->dtmf_wp) {				switch (j->dtmfbuffer[j->dtmf_rp]) {				case 10:					retval = 42;	/* '*'; */					break;				case 11:					retval = 48;	/*'0'; */					break;				case 12:					retval = 35;	/*'#'; */					break;				case 28:					retval = 65;	/*'A'; */					break;				case 29:					retval = 66;	/*'B'; */					break;				case 30:					retval = 67;	/*'C'; */					break;				case 31:					retval = 68;	/*'D'; */					break;				default:					retval = 48 + j->dtmfbuffer[j->dtmf_rp];					break;				}				j->dtmf_rp++;				if (j->dtmf_rp == 79)					j->dtmf_rp = 0;				if(j->dtmf_rp == j->dtmf_wp)				{					j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;				}			}		}		break;	case PHONE_DTMF_OOB:		j->flags.dtmf_oob = arg;		break;	case PHONE_DIALTONE:		ixj_dialtone(j);		break;	case PHONE_BUSY:		ixj_busytone(j);		break;	case PHONE_RINGBACK:		ixj_ringback(j);		break;	case PHONE_WINK:		if(j->cardtype == QTI_PHONEJACK) 			retval = -1;		else 			retval = ixj_wink(j);		break;	case PHONE_CPT_STOP:		ixj_cpt_stop(j);		break;        case PHONE_QUERY_CODEC:        {                struct phone_codec_data pd;                int val;                int proto_size[] = {                        -1,                        12, 10, 16, 9, 8, 48, 5,                        40, 40, 80, 40, 40, 6                };                if(copy_from_user(&pd, argp, sizeof(pd))) {                        retval = -EFAULT;			break;		}                if(pd.type<1 || pd.type>13) {                        retval = -EPROTONOSUPPORT;			break;		}                if(pd.type<G729)                        val=proto_size[pd.type];                else switch(j->baseframe.low)                {                        case 0xA0:val=2*proto_size[pd.type];break;                        case 0x50:val=proto_size[pd.type];break;                        default:val=proto_size[pd.type]*3;break;                }                pd.buf_min=pd.buf_max=pd.buf_opt=val;                if(copy_to_user(argp, &pd, sizeof(pd)))                        retval = -EFAULT;        	break;        }	case IXJCTL_DSP_IDLE:		idle(j);		break;	case IXJCTL_MIXER:                if ((arg & 0xff) == 0xff)			retval = ixj_get_mixer(arg, j);                else			ixj_mixer(arg, j);		break;	case IXJCTL_DAA_COEFF_SET:		switch (arg) {		case DAA_US:			DAA_Coeff_US(j);			retval = ixj_daa_write(j);			break;		case DAA_UK:			DAA_Coeff_UK(j);			retval = ixj_daa_write(j);			break;		case DAA_FRANCE:			DAA_Coeff_France(j);			retval = ixj_daa_write(j);			break;		case DAA_GERMANY:			DAA_Coeff_Germany(j);			retval = ixj_daa_write(j);			break;		case DAA_AUSTRALIA:			DAA_Coeff_Australia(j);			retval = ixj_daa_write(j);			break;		case DAA_JAPAN:			DAA_Coeff_Japan(j);			retval = ixj_daa_write(j);			break;		default:			retval = 1;			break;		}		break;	case IXJCTL_DAA_AGAIN:		ixj_daa_cr4(j, arg | 0x02);		break;	case IXJCTL_PSTN_LINETEST:		retval = ixj_linetest(j);		break;	case IXJCTL_VMWI:		ixj_write_vmwi(j, arg);		break;	case IXJCTL_CID:		if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID))) 			retval = -EFAULT;		j->ex.bits.caller_id = 0;		break;	case IXJCTL_WINK_DURATION:		j->winktime = arg;		break;	case IXJCTL_PORT:		if (arg)			retval = ixj_set_port(j, arg);		else			retval = j->port;		break;	case IXJCTL_POTS_PSTN:		retval = ixj_set_pots(j, arg);		break;	case PHONE_CAPABILITIES:		add_caps(j);		retval = j->caps;		break;	case PHONE_CAPABILITIES_LIST:		add_caps(j);		if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps)) 			retval = -EFAULT;		break;	case PHONE_CAPABILITIES_CHECK:		{			struct phone_capability cap;			if (copy_from_user(&cap, argp, sizeof(cap))) 				retval = -EFAULT;			else {				add_caps(j);				retval = capabilities_check(j, &cap);			}		}		break;	case PHONE_PSTN_SET_STATE:		daa_set_mode(j, arg);		break;	case PHONE_PSTN_GET_STATE:		retval = j->daa_mode;		j->ex.bits.pstn_ring = 0;		break;	case IXJCTL_SET_FILTER:		if (copy_from_user(&jf, argp, sizeof(jf))) 			retval = -EFAULT;		retval = ixj_init_filter(j, &jf);		break;	case IXJCTL_SET_FILTER_RAW:		if (copy_from_user(&jfr, argp, sizeof(jfr))) 			retval = -EFAULT;		else			retval = ixj_init_filter_raw(j, &jfr);		break;	case IXJCTL_GET_FILTER_HIST:		if(arg<0||arg>3)			retval = -EINVAL;		else			retval = j->filter_hist[arg];		break;	case IXJCTL_INIT_TONE:		if (copy_from_user(&ti, argp, sizeof(ti)))			retval = -EFAULT;		else			retval = ixj_init_tone(j, &ti);		break;	case IXJCTL_TONE_CADENCE:		retval = ixj_build_cadence(j, argp);		break;	case IXJCTL_FILTER_CADENCE:		retval = ixj_build_filter_cadence(j, argp);		break;	case IXJCTL_SIGCTL:		if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {			retval = -EFAULT;			break;		}		j->ixj_signals[j->sigdef.event] = j->sigdef.signal;		if(j->sigdef.event < 33) {			raise = 1;			for(mant = 0; mant < j->sigdef.event; mant++){				raise *= 2;			}			if(j->sigdef.signal)				j->ex_sig.bytes |= raise; 			else				j->ex_sig.bytes &= (raise^0xffff); 		}		break;	case IXJCTL_INTERCOM_STOP:		if(arg < 0 || arg >= IXJMAX)			return -EINVAL;		j->intercom = -1;		ixj_record_stop(j);		ixj_play_stop(j);		idle(j);		get_ixj(arg)->intercom = -1;		ixj_record_stop(get_ixj(arg));		ixj_play_stop(get_ixj(arg));		idle(get_ixj(arg));		break;	case IXJCTL_INTERCOM_START:		if(arg < 0 || arg >= IXJMAX)			return -EINVAL;		j->intercom = arg;		ixj_record_start(j);		ixj_play_start(j);		get_ixj(arg)->intercom = board;		ixj_play_start(get_ixj(arg));		ixj_record_start(get_ixj(arg));		break;	}	if (ixjdebug & 0x0040)		printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);	clear_bit(board, &j->busyflags);	return retval;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/fba478b1719c39ea67f15c6158ff4993933e9d18/ixj.c/buggy/drivers/telephony/ixj.c