static inline int put_v4l2_sliced_vbi_format(struct v4l2_sliced_vbi_format *kp, struct v4l2_sliced_vbi_format __user *up)
{
	if (copy_to_user(up, kp, sizeof(struct v4l2_sliced_vbi_format)))
		return -EFAULT;
	return 0;
}
Exemple #2
0
static int mtd_read(struct inode *inode,struct file *file, char *buf, int count)
#endif
{
	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
	size_t retlen=0;
	size_t total_retlen=0;
	int ret=0;
#ifndef NO_MM
	int len;
	char *kbuf;
#endif	
	DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");

	if (FILE_POS + count > mtd->size)
		count = mtd->size - FILE_POS;

	if (!count)
		return 0;
	
	/* FIXME: Use kiovec in 2.3 or 2.2+rawio, or at
	 * least split the IO into smaller chunks.
	 */
#ifdef NO_MM	
	ret = MTD_READ(mtd, FILE_POS, count, &retlen, buf);
	if (!ret) {
		FILE_POS += retlen;
		ret = retlen;
	}
	total_retlen = ret;
#else
	while (count) {
		if (count > MAX_KMALLOC_SIZE) 
			len = MAX_KMALLOC_SIZE;
		else
			len = count;

		kbuf=kmalloc(len,GFP_KERNEL);
		if (!kbuf)
			return -ENOMEM;
		
		ret = MTD_READ(mtd, FILE_POS, len, &retlen, kbuf);
		if (!ret) {
			FILE_POS += retlen;
			if (copy_to_user(buf, kbuf, retlen)) {
			        kfree(kbuf);
				return -EFAULT;
			}
			else
				total_retlen += retlen;

			count -= retlen;
			buf += retlen;
		}
		else {
			kfree(kbuf);
			return ret;
		}
		
		kfree(kbuf);
	}
	
#endif	
	return total_retlen;
} /* mtd_read */
Exemple #3
0
int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
{
	int uninitialized_var(err);
	struct net *net = sock_net(sk);
	struct ipv6_pinfo *np = inet6_sk(sk);
	struct in6_flowlabel_req freq;
	struct ipv6_fl_socklist *sfl1 = NULL;
	struct ipv6_fl_socklist *sfl;
	struct ipv6_fl_socklist __rcu **sflp;
	struct ip6_flowlabel *fl, *fl1 = NULL;


	if (optlen < sizeof(freq))
		return -EINVAL;

	if (copy_from_user(&freq, optval, sizeof(freq)))
		return -EFAULT;

	switch (freq.flr_action) {
	case IPV6_FL_A_PUT:
		if (freq.flr_flags & IPV6_FL_F_REFLECT) {
			if (sk->sk_protocol != IPPROTO_TCP)
				return -ENOPROTOOPT;
			if (!np->repflow)
				return -ESRCH;
			np->flow_label = 0;
			np->repflow = 0;
			return 0;
		}
		spin_lock_bh(&ip6_sk_fl_lock);
		for (sflp = &np->ipv6_fl_list;
		     (sfl = rcu_dereference_protected(*sflp,
						      lockdep_is_held(&ip6_sk_fl_lock))) != NULL;
		     sflp = &sfl->next) {
			if (sfl->fl->label == freq.flr_label) {
				if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
					np->flow_label &= ~IPV6_FLOWLABEL_MASK;
				*sflp = sfl->next;
				spin_unlock_bh(&ip6_sk_fl_lock);
				fl_release(sfl->fl);
				kfree_rcu(sfl, rcu);
				return 0;
			}
		}
		spin_unlock_bh(&ip6_sk_fl_lock);
		return -ESRCH;

	case IPV6_FL_A_RENEW:
		rcu_read_lock_bh();
		for_each_sk_fl_rcu(np, sfl) {
			if (sfl->fl->label == freq.flr_label) {
				err = fl6_renew(sfl->fl, freq.flr_linger, freq.flr_expires);
				rcu_read_unlock_bh();
				return err;
			}
		}
		rcu_read_unlock_bh();

		if (freq.flr_share == IPV6_FL_S_NONE &&
		    ns_capable(net->user_ns, CAP_NET_ADMIN)) {
			fl = fl_lookup(net, freq.flr_label);
			if (fl) {
				err = fl6_renew(fl, freq.flr_linger, freq.flr_expires);
				fl_release(fl);
				return err;
			}
		}
		return -ESRCH;

	case IPV6_FL_A_GET:
		if (freq.flr_flags & IPV6_FL_F_REFLECT) {
			struct net *net = sock_net(sk);
			if (net->ipv6.sysctl.flowlabel_consistency) {
				net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n");
				return -EPERM;
			}

			if (sk->sk_protocol != IPPROTO_TCP)
				return -ENOPROTOOPT;

			np->repflow = 1;
			return 0;
		}

		if (freq.flr_label & ~IPV6_FLOWLABEL_MASK)
			return -EINVAL;

		if (net->ipv6.sysctl.flowlabel_state_ranges &&
		    (freq.flr_label & IPV6_FLOWLABEL_STATELESS_FLAG))
			return -ERANGE;

		fl = fl_create(net, sk, &freq, optval, optlen, &err);
		if (!fl)
			return err;
		sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);

		if (freq.flr_label) {
			err = -EEXIST;
			rcu_read_lock_bh();
			for_each_sk_fl_rcu(np, sfl) {
				if (sfl->fl->label == freq.flr_label) {
					if (freq.flr_flags&IPV6_FL_F_EXCL) {
						rcu_read_unlock_bh();
						goto done;
					}
					fl1 = sfl->fl;
					atomic_inc(&fl1->users);
					break;
				}
			}
			rcu_read_unlock_bh();

			if (!fl1)
				fl1 = fl_lookup(net, freq.flr_label);
			if (fl1) {
recheck:
				err = -EEXIST;
				if (freq.flr_flags&IPV6_FL_F_EXCL)
					goto release;
				err = -EPERM;
				if (fl1->share == IPV6_FL_S_EXCL ||
				    fl1->share != fl->share ||
				    ((fl1->share == IPV6_FL_S_PROCESS) &&
				     (fl1->owner.pid == fl->owner.pid)) ||
				    ((fl1->share == IPV6_FL_S_USER) &&
				     uid_eq(fl1->owner.uid, fl->owner.uid)))
					goto release;

				err = -ENOMEM;
				if (!sfl1)
					goto release;
				if (fl->linger > fl1->linger)
					fl1->linger = fl->linger;
				if ((long)(fl->expires - fl1->expires) > 0)
					fl1->expires = fl->expires;
				fl_link(np, sfl1, fl1);
				fl_free(fl);
				return 0;

release:
				fl_release(fl1);
				goto done;
			}
		}
		err = -ENOENT;
		if (!(freq.flr_flags&IPV6_FL_F_CREATE))
			goto done;

		err = -ENOMEM;
		if (!sfl1)
			goto done;

		err = mem_check(sk);
		if (err != 0)
			goto done;

		fl1 = fl_intern(net, fl, freq.flr_label);
		if (fl1)
			goto recheck;

		if (!freq.flr_label) {
			if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label,
					 &fl->label, sizeof(fl->label))) {
				/* Intentionally ignore fault. */
			}
		}

		fl_link(np, sfl1, fl);
		return 0;

	default:
		return -EINVAL;
	}
Exemple #4
0
static long jpeg_ioctl(struct file *file,
			unsigned int cmd, unsigned long arg)
{
	int ret;
	struct jpeg_control	*ctrl;

	ctrl  = (struct jpeg_control *)file->private_data;
	if (!ctrl) {
		jpeg_err("jpeg invalid input argument\n");
		return -1;
	}

	switch (cmd) {

	case IOCTL_JPEG_DEC_EXE:
		ret = copy_from_user(&ctrl->dec_param,
			(struct jpeg_dec_param *)arg,
			sizeof(struct jpeg_dec_param));

		jpeg_exe_dec(ctrl);
		ret = copy_to_user((void *)arg,
			(void *) &ctrl->dec_param,
			sizeof(struct jpeg_dec_param));
		break;

	case IOCTL_JPEG_ENC_EXE:
		ret = copy_from_user(&ctrl->enc_param,
			(struct jpeg_enc_param *)arg,
			sizeof(struct jpeg_enc_param));

		jpeg_exe_enc(ctrl);
		ret = copy_to_user((void *)arg,
			(void *) &ctrl->enc_param,
			sizeof(struct jpeg_enc_param));
		break;

	case IOCTL_GET_DEC_IN_BUF:
	case IOCTL_GET_ENC_OUT_BUF:
		return jpeg_get_stream_buf(arg);

	case IOCTL_GET_DEC_OUT_BUF:
	case IOCTL_GET_ENC_IN_BUF:
		return jpeg_get_frame_buf(arg);

	case IOCTL_GET_PHYADDR:
		return jpeg_ctrl->mem.frame_data_addr;

	case IOCTL_GET_PHYMEM_BASE:
#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
		if (copy_to_user((void *)arg, &jpeg_ctrl->mem.base, sizeof(unsigned int))) {
			jpeg_err("IOCTL_GET_PHYMEM_BASE:::copy_to_user error\n");
			return -1;
		}
		return 0;
#else
		return -1;
#endif

	case IOCTL_GET_PHYMEM_SIZE:
#ifdef CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG
		ret = CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG * 1024;
		if (copy_to_user((void *)arg, &ret, sizeof(unsigned int))) {
			jpeg_err("IOCTL_GET_PHYMEM_SIZE:::copy_to_user error\n");
			return -1;
		}
		return 0;
#else
		return -1;
#endif

	case IOCTL_SET_DEC_PARAM:
		ret = copy_from_user(&ctrl->dec_param,
			(struct jpeg_dec_param *)arg,
			sizeof(struct jpeg_dec_param));

		ret = jpeg_set_dec_param(ctrl);

		break;

	case IOCTL_SET_ENC_PARAM:
		ret = copy_from_user(&ctrl->enc_param,
			(struct jpeg_enc_param *)arg,
			sizeof(struct jpeg_enc_param));

		ret = jpeg_set_enc_param(ctrl);
		break;

	default:
		break;
	}
	return 0;
}
Exemple #5
0
static int ecs_ctrl_ioctl(struct inode *inode, struct file *file,
	unsigned int cmd, unsigned long arg)
{
	void __user *pa = (void __user *)arg;
	short flag;
	short delay;
	int parms[4];
	int ypr[12];

	switch (cmd) {
	case ECOMPASS_IOC_SET_MODE:
		break;
	case ECOMPASS_IOC_SET_DELAY:
		if (copy_from_user(&delay, pa, sizeof(delay)))
			return -EFAULT;
		ecompass_delay = delay;
		break;
	case ECOMPASS_IOC_GET_DELAY:
		delay = ecompass_delay;
		if (copy_to_user(pa, &delay, sizeof(delay)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_AFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&a_flag, flag);
		break;
	case ECOMPASS_IOC_GET_AFLAG:
		flag = atomic_read(&a_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_MFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&m_flag, flag);
		break;
	case ECOMPASS_IOC_GET_MFLAG:
		flag = atomic_read(&m_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;
	case ECOMPASS_IOC_SET_OFLAG:
		if (copy_from_user(&flag, pa, sizeof(flag)))
			return -EFAULT;
		if (flag < 0 || flag > 1)
			return -EINVAL;
		atomic_set(&o_flag, flag);
		break;
	case ECOMPASS_IOC_GET_OFLAG:
		flag = atomic_read(&o_flag);
		if (copy_to_user(pa, &flag, sizeof(flag)))
			return -EFAULT;
		break;

	case ECOMPASS_IOC_SET_APARMS:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* acceleration x-axis */
		input_set_abs_params(ecs_data_device, ABS_X,
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration y-axis */
		input_set_abs_params(ecs_data_device, ABS_Y,
			parms[0], parms[1], parms[2], parms[3]);
		/* acceleration z-axis */
		input_set_abs_params(ecs_data_device, ABS_Z,
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_APARMS:
		break;
	case ECOMPASS_IOC_SET_MPARMS:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* magnetic raw x-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0X,
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw y-axis */
		input_set_abs_params(ecs_data_device, ABS_HAT0Y,
			parms[0], parms[1], parms[2], parms[3]);
		/* magnetic raw z-axis */
		input_set_abs_params(ecs_data_device, ABS_BRAKE,
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_MPARMS:
		break;
	case ECOMPASS_IOC_SET_OPARMS_YAW:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation yaw */
		input_set_abs_params(ecs_data_device, ABS_RX,
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_YAW:
		break;
	case ECOMPASS_IOC_SET_OPARMS_PITCH:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation pitch */
		input_set_abs_params(ecs_data_device, ABS_RY,
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_PITCH:
		break;
	case ECOMPASS_IOC_SET_OPARMS_ROLL:
		if (copy_from_user(parms, pa, sizeof(parms)))
			return -EFAULT;
		/* orientation roll */
		input_set_abs_params(ecs_data_device, ABS_RZ,
			parms[0], parms[1], parms[2], parms[3]);
		break;
	case ECOMPASS_IOC_GET_OPARMS_ROLL:
		break;

	case ECOMPASS_IOC_SET_YPR:
		if (copy_from_user(ypr, pa, sizeof(ypr)))
			return -EFAULT;
		/* Report acceleration sensor information */
		if (atomic_read(&a_flag)) {
			input_report_abs(ecs_data_device, ABS_X, ypr[0]);
			input_report_abs(ecs_data_device, ABS_Y, ypr[1]);
			input_report_abs(ecs_data_device, ABS_Z, ypr[2]);
			input_report_abs(ecs_data_device, ABS_WHEEL, ypr[3]);
		}

		/* Report magnetic sensor information */
		if (atomic_read(&m_flag)) {
			input_report_abs(ecs_data_device, ABS_HAT0X, ypr[4]);
			input_report_abs(ecs_data_device, ABS_HAT0Y, ypr[5]);
			input_report_abs(ecs_data_device, ABS_BRAKE, ypr[6]);
			input_report_abs(ecs_data_device, ABS_GAS, ypr[7]);
		}

		/* Report orientation information */
		if (atomic_read(&o_flag)) {
			input_report_abs(ecs_data_device, ABS_RX, ypr[8]);
			input_report_abs(ecs_data_device, ABS_RY, ypr[9]);
			input_report_abs(ecs_data_device, ABS_RZ, ypr[10]);
			input_report_abs(ecs_data_device, ABS_RUDDER, ypr[11]);
		}

		input_sync(ecs_data_device);
		break;

	default:
		break;
	}

	return 0;
}
/**
 *	iowarrior_ioctl
 */
static long iowarrior_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	struct iowarrior *dev = NULL;
	__u8 *buffer;
	__u8 __user *user_buffer;
	int retval;
	int io_res;		/* checks for bytes read/written and copy_to/from_user results */

	dev = file->private_data;
	if (dev == NULL) {
		return -ENODEV;
	}

	buffer = kzalloc(dev->report_size, GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;

	/* lock this object */
	mutex_lock(&iowarrior_mutex);
	mutex_lock(&dev->mutex);

	/* verify that the device wasn't unplugged */
	if (!dev->present) {
		retval = -ENODEV;
		goto error_out;
	}

	dbg("%s - minor %d, cmd 0x%.4x, arg %ld", __func__, dev->minor, cmd,
	    arg);

	retval = 0;
	io_res = 0;
	switch (cmd) {
	case IOW_WRITE:
		if (dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW24 ||
		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV1 ||
		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOWPV2 ||
		    dev->product_id == USB_DEVICE_ID_CODEMERCS_IOW40) {
			user_buffer = (__u8 __user *)arg;
			io_res = copy_from_user(buffer, user_buffer,
						dev->report_size);
			if (io_res) {
				retval = -EFAULT;
			} else {
				io_res = usb_set_report(dev->interface, 2, 0,
							buffer,
							dev->report_size);
				if (io_res < 0)
					retval = io_res;
			}
		} else {
			retval = -EINVAL;
			dev_err(&dev->interface->dev,
				"ioctl 'IOW_WRITE' is not supported for product=0x%x.\n",
				dev->product_id);
		}
		break;
	case IOW_READ:
		user_buffer = (__u8 __user *)arg;
		io_res = usb_get_report(dev->udev,
					dev->interface->cur_altsetting, 1, 0,
					buffer, dev->report_size);
		if (io_res < 0)
			retval = io_res;
		else {
			io_res = copy_to_user(user_buffer, buffer, dev->report_size);
			if (io_res < 0)
				retval = -EFAULT;
		}
		break;
	case IOW_GETINFO:
		{
			/* Report available information for the device */
			struct iowarrior_info info;
			/* needed for power consumption */
			struct usb_config_descriptor *cfg_descriptor = &dev->udev->actconfig->desc;

			memset(&info, 0, sizeof(info));
			/* directly from the descriptor */
			info.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
			info.product = dev->product_id;
			info.revision = le16_to_cpu(dev->udev->descriptor.bcdDevice);

			/* 0==UNKNOWN, 1==LOW(usb1.1) ,2=FULL(usb1.1), 3=HIGH(usb2.0) */
			info.speed = le16_to_cpu(dev->udev->speed);
			info.if_num = dev->interface->cur_altsetting->desc.bInterfaceNumber;
			info.report_size = dev->report_size;

			/* serial number string has been read earlier 8 chars or empty string */
			memcpy(info.serial, dev->chip_serial,
			       sizeof(dev->chip_serial));
			if (cfg_descriptor == NULL) {
				info.power = -1;	/* no information available */
			} else {
				/* the MaxPower is stored in units of 2mA to make it fit into a byte-value */
				info.power = cfg_descriptor->bMaxPower * 2;
			}
			io_res = copy_to_user((struct iowarrior_info __user *)arg, &info,
					 sizeof(struct iowarrior_info));
			if (io_res < 0)
				retval = -EFAULT;
			break;
		}
	default:
		/* return that we did not understand this ioctl call */
		retval = -ENOTTY;
		break;
	}
error_out:
	/* unlock the device */
	mutex_unlock(&dev->mutex);
	mutex_unlock(&iowarrior_mutex);
	kfree(buffer);
	return retval;
}
Exemple #7
0
static int wpa_get_scan(PSDevice pDevice,
				     struct viawget_wpa_param *param)
{
	struct viawget_scan_result *scan_buf;
    PSMgmtObject    pMgmt = pDevice->pMgmt;
    PWLAN_IE_SSID   pItemSSID;
    PKnownBSS pBSS;
	unsigned char *pBuf;
	int ret = 0;
	u16 count = 0;
	u16 ii, jj;
#if 1

    unsigned char *ptempBSS;



    ptempBSS = kmalloc(sizeof(KnownBSS), (int)GFP_ATOMIC);

    if (ptempBSS == NULL) {

       printk("bubble sort kmalloc memory [email protected]@@\n");

        ret = -ENOMEM;

        return ret;

    }

    for (ii = 0; ii < MAX_BSS_NUM; ii++) {

         for(jj=0;jj<MAX_BSS_NUM-ii-1;jj++) {

           if((pMgmt->sBSSList[jj].bActive!=true) ||

                ((pMgmt->sBSSList[jj].uRSSI>pMgmt->sBSSList[jj+1].uRSSI) &&(pMgmt->sBSSList[jj+1].bActive!=false))) {

                 memcpy(ptempBSS,&pMgmt->sBSSList[jj],sizeof(KnownBSS));

                 memcpy(&pMgmt->sBSSList[jj],&pMgmt->sBSSList[jj+1],sizeof(KnownBSS));

                 memcpy(&pMgmt->sBSSList[jj+1],ptempBSS,sizeof(KnownBSS));

              }

         }

    }

  kfree(ptempBSS);

 // printk("bubble sort result:\n");

  //for (ii = 0; ii < MAX_BSS_NUM; ii++)

  //    printk("%d [%s]:RSSI=%d\n",ii,((PWLAN_IE_SSID)(pMgmt->sBSSList[ii].abySSID))->abySSID,

  //                                                                 pMgmt->sBSSList[ii].uRSSI);

 #endif

//******mike:bubble sort by stronger RSSI*****//




	count = 0;
	pBSS = &(pMgmt->sBSSList[0]);
    for (ii = 0; ii < MAX_BSS_NUM; ii++) {
        pBSS = &(pMgmt->sBSSList[ii]);
        if (!pBSS->bActive)
            continue;
        count++;
    }

    pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);

    if (pBuf == NULL) {
        ret = -ENOMEM;
        return ret;
    }
    scan_buf = (struct viawget_scan_result *)pBuf;
	pBSS = &(pMgmt->sBSSList[0]);
    for (ii = 0, jj = 0; ii < MAX_BSS_NUM ; ii++) {
        pBSS = &(pMgmt->sBSSList[ii]);
        if (pBSS->bActive) {
            if (jj >= count)
                break;
            memcpy(scan_buf->bssid, pBSS->abyBSSID, WLAN_BSSID_LEN);
            pItemSSID = (PWLAN_IE_SSID)pBSS->abySSID;
   		    memcpy(scan_buf->ssid, pItemSSID->abySSID, pItemSSID->len);
   		    scan_buf->ssid_len = pItemSSID->len;
            scan_buf->freq = frequency_list[pBSS->uChannel-1];
	  scan_buf->caps = pBSS->wCapInfo;
            //scan_buf->caps = pBSS->wCapInfo;
            //scan_buf->qual =
            //scan_buf->noise =
            //scan_buf->level =
            //scan_buf->maxrate =
            if (pBSS->wWPALen != 0) {
                scan_buf->wpa_ie_len = pBSS->wWPALen;
                memcpy(scan_buf->wpa_ie, pBSS->byWPAIE, pBSS->wWPALen);
            }
            if (pBSS->wRSNLen != 0) {
                scan_buf->rsn_ie_len = pBSS->wRSNLen;
                memcpy(scan_buf->rsn_ie, pBSS->byRSNIE, pBSS->wRSNLen);
            }
            scan_buf = (struct viawget_scan_result *)((unsigned char *)scan_buf + sizeof(struct viawget_scan_result));
            jj ++;
        }
    }

    if (jj < count)
        count = jj;

    if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
		ret = -EFAULT;
	}
	param->u.scan_results.scan_count = count;
    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)

    kfree(pBuf);
    return ret;
}
Exemple #8
0
static ssize_t
printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
{
	struct printer_dev		*dev = fd->private_data;
	unsigned long			flags;
	size_t				size;
	size_t				bytes_copied;
	struct usb_request		*req;
	/* This is a pointer to the current USB rx request. */
	struct usb_request		*current_rx_req;
	/* This is the number of bytes in the current rx buffer. */
	size_t				current_rx_bytes;
	/* This is a pointer to the current rx buffer. */
	u8				*current_rx_buf;

	if (len == 0)
		return -EINVAL;

	DBG(dev, "printer_read trying to read %d bytes\n", (int)len);

	spin_lock(&dev->lock_printer_io);
	spin_lock_irqsave(&dev->lock, flags);

	/* We will use this flag later to check if a printer reset happened
	 * after we turn interrupts back on.
	 */
	dev->reset_printer = 0;

	setup_rx_reqs(dev);

	bytes_copied = 0;
	current_rx_req = dev->current_rx_req;
	current_rx_bytes = dev->current_rx_bytes;
	current_rx_buf = dev->current_rx_buf;
	dev->current_rx_req = NULL;
	dev->current_rx_bytes = 0;
	dev->current_rx_buf = NULL;

	/* Check if there is any data in the read buffers. Please note that
	 * current_rx_bytes is the number of bytes in the current rx buffer.
	 * If it is zero then check if there are any other rx_buffers that
	 * are on the completed list. We are only out of data if all rx
	 * buffers are empty.
	 */
	if ((current_rx_bytes == 0) &&
			(likely(list_empty(&dev->rx_buffers)))) {
		/* Turn interrupts back on before sleeping. */
		spin_unlock_irqrestore(&dev->lock, flags);

		/*
		 * If no data is available check if this is a NON-Blocking
		 * call or not.
		 */
		if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
			spin_unlock(&dev->lock_printer_io);
			return -EAGAIN;
		}

		/* Sleep until data is available */
		wait_event_interruptible(dev->rx_wait,
				(likely(!list_empty(&dev->rx_buffers))));
		spin_lock_irqsave(&dev->lock, flags);
	}

	/* We have data to return then copy it to the caller's buffer.*/
	while ((current_rx_bytes || likely(!list_empty(&dev->rx_buffers)))
			&& len) {
		if (current_rx_bytes == 0) {
			req = container_of(dev->rx_buffers.next,
					struct usb_request, list);
			list_del_init(&req->list);

			if (req->actual && req->buf) {
				current_rx_req = req;
				current_rx_bytes = req->actual;
				current_rx_buf = req->buf;
			} else {
				list_add(&req->list, &dev->rx_reqs);
				continue;
			}
		}

		/* Don't leave irqs off while doing memory copies */
		spin_unlock_irqrestore(&dev->lock, flags);

		if (len > current_rx_bytes)
			size = current_rx_bytes;
		else
			size = len;

		size -= copy_to_user(buf, current_rx_buf, size);
		bytes_copied += size;
		len -= size;
		buf += size;

		spin_lock_irqsave(&dev->lock, flags);

		/* We've disconnected or reset so return. */
		if (dev->reset_printer) {
			list_add(&current_rx_req->list, &dev->rx_reqs);
			spin_unlock_irqrestore(&dev->lock, flags);
			spin_unlock(&dev->lock_printer_io);
			return -EAGAIN;
		}

		/* If we not returning all the data left in this RX request
		 * buffer then adjust the amount of data left in the buffer.
		 * Othewise if we are done with this RX request buffer then
		 * requeue it to get any incoming data from the USB host.
		 */
		if (size < current_rx_bytes) {
			current_rx_bytes -= size;
			current_rx_buf += size;
		} else {
			list_add(&current_rx_req->list, &dev->rx_reqs);
			current_rx_bytes = 0;
			current_rx_buf = NULL;
			current_rx_req = NULL;
		}
	}
Exemple #9
0
int libcfs_ioctl_popdata(void *arg, void *data, int size)
{
	if (copy_to_user((char *)arg, data, size))
		return -EFAULT;
	return 0;
}
Exemple #10
0
asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
{
	struct rtas_args args;
	unsigned long flags;
	char *buff_copy, *errbuf = NULL;
	int nargs;
	int rc;

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
		return -EFAULT;

	nargs = args.nargs;
	if (nargs > ARRAY_SIZE(args.args)
	    || args.nret > ARRAY_SIZE(args.args)
	    || nargs + args.nret > ARRAY_SIZE(args.args))
		return -EINVAL;

	/* Copy in args. */
	if (copy_from_user(args.args, uargs->args,
			   nargs * sizeof(rtas_arg_t)) != 0)
		return -EFAULT;

	if (args.token == RTAS_UNKNOWN_SERVICE)
		return -EINVAL;

	args.rets = &args.args[nargs];
	memset(args.rets, 0, args.nret * sizeof(rtas_arg_t));

	/* Need to handle ibm,suspend_me call specially */
	if (args.token == ibm_suspend_me_token) {
		rc = rtas_ibm_suspend_me(&args);
		if (rc)
			return rc;
		goto copy_return;
	}

	buff_copy = get_errorlog_buffer();

	flags = lock_rtas();

	rtas.args = args;
	enter_rtas(__pa(&rtas.args));
	args = rtas.args;

	/* A -1 return code indicates that the last command couldn't
	   be completed due to a hardware error. */
	if (args.rets[0] == -1)
		errbuf = __fetch_rtas_last_error(buff_copy);

	unlock_rtas(flags);

	if (buff_copy) {
		if (errbuf)
			log_error(errbuf, ERR_TYPE_RTAS_LOG, 0);
		kfree(buff_copy);
	}

 copy_return:
	/* Copy out args. */
	if (copy_to_user(uargs->args + nargs,
			 args.args + nargs,
			 args.nret * sizeof(rtas_arg_t)) != 0)
		return -EFAULT;

	return 0;
}
Exemple #11
0
static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
				unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static struct watchdog_info ident = {
		.options = WDIOF_KEEPALIVEPING,
		.firmware_version = 1,
		.identity = "MPC83xx",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_KEEPALIVE:
		mpc83xx_wdt_keepalive();
		return 0;
	case WDIOC_GETTIMEOUT:
		return put_user(timeout_sec, p);
	default:
		return -ENOTTY;
	}
}

static const struct file_operations mpc83xx_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= mpc83xx_wdt_write,
	.ioctl		= mpc83xx_wdt_ioctl,
	.open		= mpc83xx_wdt_open,
	.release	= mpc83xx_wdt_release,
};

static struct miscdevice mpc83xx_wdt_miscdev = {
	.minor	= WATCHDOG_MINOR,
	.name	= "watchdog",
	.fops	= &mpc83xx_wdt_fops,
};

static int __devinit mpc83xx_wdt_probe(struct platform_device *dev)
{
	struct resource *r;
	int ret;
	unsigned int *freq = dev->dev.platform_data;

	/* get a pointer to the register memory */
	r = platform_get_resource(dev, IORESOURCE_MEM, 0);

	if (!r) {
		ret = -ENODEV;
		goto err_out;
	}

	wd_base = ioremap(r->start, sizeof (struct mpc83xx_wdt));

	if (wd_base == NULL) {
		ret = -ENOMEM;
		goto err_out;
	}

	ret = misc_register(&mpc83xx_wdt_miscdev);
	if (ret) {
		printk(KERN_ERR "cannot register miscdev on minor=%d "
				"(err=%d)\n",
				WATCHDOG_MINOR, ret);
		goto err_unmap;
	}

	/* Calculate the timeout in seconds */
	if (prescale)
		timeout_sec = (timeout * 0x10000) / (*freq);
	else
		timeout_sec = timeout / (*freq);

	printk(KERN_INFO "WDT driver for MPC83xx initialized. "
		"mode:%s timeout=%d (%d seconds)\n",
		reset ? "reset":"interrupt", timeout, timeout_sec);

	spin_lock_init(&wdt_spinlock);

	return 0;

err_unmap:
	iounmap(wd_base);
err_out:
	return ret;
}

static int __devexit mpc83xx_wdt_remove(struct platform_device *dev)
{
	misc_deregister(&mpc83xx_wdt_miscdev);
	iounmap(wd_base);

	return 0;
}

static struct platform_driver mpc83xx_wdt_driver = {
	.probe		= mpc83xx_wdt_probe,
	.remove		= __devexit_p(mpc83xx_wdt_remove),
	.driver		= {
		.name	= "mpc83xx_wdt",
	},
};

static int __init mpc83xx_wdt_init(void)
{
	return platform_driver_register(&mpc83xx_wdt_driver);
}

static void __exit mpc83xx_wdt_exit(void)
{
	platform_driver_unregister(&mpc83xx_wdt_driver);
}
/******************************** the module driver ************************************************************/
static int sep0611_overlay_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	unsigned int intArg,data;
	overlay_config_t config;
	lcdc_timming timming_tmp;
	switch(cmd)
	{
#if 0
		case OVERLAY_FORBID:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			overlay_forbid = intArg;
			return 0;
#endif
#if USE_PICTURE
		case 111://GET_IMG
			//if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
			//	return -EFAULT;
			return sep0611_overlay_get_img();
#endif
		case OVERLAY_PRINT_REGS:
			dprintk("print regs:\n");
			for(intArg=0; intArg<=0xCC;intArg+=4)
			{
				printk("reg[0x%x] = (0x%x)\n", (unsigned int)io + intArg, readl(io + intArg));
			}
			break;
		case OVERLAY_GET_STARTBUF:
			dprintk("overlay_kernel ioctl get startbuffer!\n");
			if(copy_to_user((unsigned int *)arg, &over1_addr_phy, sizeof(unsigned int)))
			{
				dprintk("error while copy!\n");
				return -EFAULT;
			}else{
			//	dprintk("success get startbuf: 0x%x",over1_addr_phy);
			}
			break;
		case OVERLAY_AUTORP_CTL:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			if(intArg == 1){
				writel(0, io + SEP0611_ACSR);
				data = readl(io + SEP0611_LCDCBCR);
				data &=~(0x3<<13);
				data |=(0x2<<13);
				writel(data, io + SEP0611_LCDCBCR);
				mdelay(10);
				writel(1, io + SEP0611_ACSR);
				dprintk("ctl enable auto repair\n");
			}else{
				data = readl(io + SEP0611_LCDCBCR);
				data &=~(0x3<<13);
				writel(data, io + SEP0611_LCDCBCR);
				dprintk("ctl disable auto repair\n");
			}
			break;
		case OVERLAY_SHOW_CURSOR:
			return sep0611_overlay_drawcursor();
		case OVERLAY_SETPOS_CURSOR:
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			return sep0611_overlay_setpos_cursor(intArg);

		case OVERLAY_LAYERS_CTL://enable or disable layers
			if(copy_from_user(&intArg, (int *)arg, sizeof(int)))
				return -EFAULT;
			sep0611_overlay_layers_ctl(intArg);
			break;
		case 114://set lcdc timming
			if(copy_from_user(&timming_tmp, (lcdc_timming *)arg, sizeof(lcdc_timming)))
				return -EFAULT;
			sep0611_overlay_settimming(timming_tmp);
			break;
		case 115://set lcdc base layer size and format
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			intArg = 0;
			dprintk("set base size:(%d,%d)\n", config.width, config.height);
			intArg = XMAX(config.width)|YMAX(config.height);
			writel(intArg, io + SEP0611_BBPCR);
			writel(config.width, io + SEP0611_BASE_RAW_IMAGE_WIDTH); 
			switch(config.format)
			{
				case V4L2_PIX_FMT_RGB565:
					dprintk("use rgb565\n");
					data = readl(io + SEP0611_LCDCBCR);
					data &=~(0x3<<27);
					writel(data, io + SEP0611_LCDCBCR);
					break;
				case V4L2_PIX_FMT_RGB24:
					dprintk("use rgb888\n");
					data = readl(io + SEP0611_LCDCBCR);
					data &= ~(0x3<<27);
					data |= (0x2<<27);
					writel(data, io + SEP0611_LCDCBCR);
					break;
				default:
					dprintk("not support!\n");
					break;
			}
			break;
		case OVERLAY_GET_POSITION:
			return sep0611_overlay_get_pos((overlay_config_t*)arg);

		case OVERLAY_GET_SCREEN_INFO:
			return sep0611_overlay_get_screenInfo((overlay_config_t*)arg);

		case OVERLAY_SET_POSITION:
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			return sep0611_overlay_set_pos(config);

		case OVERLAY_QUEUE_BUFFER:
			if(copy_from_user(&intArg, (overlay_config_t *)arg, sizeof(unsigned int)))
				return -EFAULT;
			return sep0611_overlay_q_buffer((unsigned int)intArg);

		case OVERLAY_SET_CONFIGURE:
			if(copy_from_user(&config, (overlay_config_t *)arg, sizeof(overlay_config_t)))
				return -EFAULT;
			sep0611_overlay_set_configure(config);
			//sep0611_overlay_q_buffer(over1_addr_phy);
			break;

		case OVERLAY_SET_DISABLE:
			return sep0611_overlay_disable();

		case OVERLAY_SET_ENABLE:
			return sep0611_overlay_enable();

		case OVERLAY_COMMON_ENABLE:
			sep0611_common_enable();
			return 0;
		case OVERLAY_COMMON_DISABLE:
			sep0611_common_disable();
			return 0;
		case OVERLAY_SWITCHTO_VIDEO:
			sep0611_switchto_mode(0);
			break;
		case OVERLAY_SWITCHTO_HDMI:
			sep0611_switchto_mode(1);
			break;
		case OVERLAY_SWITCHTO_LCD:
			sep0611_switchto_mode(2);
			break;
		default:
			dprintk(" Unsupported IOCTL(%d)!!!\n", cmd);      
			break;			
	}
	return 0;
}
static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input32 __user *up)
{
	if (copy_to_user(up, kp, sizeof(struct v4l2_input32)))
		return -EFAULT;
	return 0;
}
static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
{
	struct v4l2_plane32 __user *uplane32;
	struct v4l2_plane __user *uplane;
	compat_caddr_t p;
	int num_planes;
	int ret;

	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
		put_user(kp->index, &up->index) ||
		put_user(kp->type, &up->type) ||
		put_user(kp->flags, &up->flags) ||
		put_user(kp->memory, &up->memory) ||
		put_user(kp->input, &up->input))
			return -EFAULT;

	if (put_user(kp->bytesused, &up->bytesused) ||
		put_user(kp->field, &up->field) ||
		put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
		put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec) ||
		copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)) ||
		put_user(kp->sequence, &up->sequence) ||
		put_user(kp->reserved, &up->reserved))
			return -EFAULT;

	if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
		num_planes = kp->length;
		if (num_planes == 0)
			return 0;

		uplane = kp->m.planes;
		if (get_user(p, &up->m.planes))
			return -EFAULT;
		uplane32 = compat_ptr(p);

		while (--num_planes >= 0) {
			ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
			if (ret)
				return ret;
			++uplane;
			++uplane32;
		}
	} else {
		switch (kp->memory) {
		case V4L2_MEMORY_MMAP:
			if (put_user(kp->length, &up->length) ||
				put_user(kp->m.offset, &up->m.offset))
				return -EFAULT;
			break;
		case V4L2_MEMORY_USERPTR:
			if (put_user(kp->length, &up->length) ||
				put_user(kp->m.userptr, &up->m.userptr))
				return -EFAULT;
			break;
		case V4L2_MEMORY_OVERLAY:
			if (put_user(kp->m.offset, &up->m.offset))
				return -EFAULT;
			break;
		}
	}

	return 0;
}
Exemple #15
0
static long epx_c3_ioctl(struct file *file, unsigned int cmd,
						unsigned long arg)
{
	int options, retval = -EINVAL;
	int __user *argp = (void __user *)arg;
	static const struct watchdog_info ident = {
		.options		= WDIOF_KEEPALIVEPING,
		.firmware_version	= 0,
		.identity		= "Winsystems EPX-C3 H/W Watchdog",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user(argp, &ident, sizeof(ident)))
			return -EFAULT;
		return 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, argp);
	case WDIOC_SETOPTIONS:
		if (get_user(options, argp))
			return -EFAULT;

		if (options & WDIOS_DISABLECARD) {
			epx_c3_stop();
			retval = 0;
		}

		if (options & WDIOS_ENABLECARD) {
			epx_c3_start();
			retval = 0;
		}

		return retval;
	case WDIOC_KEEPALIVE:
		epx_c3_pet();
		return 0;
	case WDIOC_GETTIMEOUT:
		return put_user(WATCHDOG_TIMEOUT, argp);
	default:
		return -ENOTTY;
	}
}

static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code,
				void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		epx_c3_stop();		/* Turn the WDT off */

	return NOTIFY_DONE;
}

static const struct file_operations epx_c3_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= epx_c3_write,
	.unlocked_ioctl	= epx_c3_ioctl,
	.open		= epx_c3_open,
	.release	= epx_c3_release,
};

static struct miscdevice epx_c3_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &epx_c3_fops,
};

static struct notifier_block epx_c3_notifier = {
	.notifier_call = epx_c3_notify_sys,
};

static const char banner[] __initdata = KERN_INFO PFX
	"Hardware Watchdog Timer for Winsystems EPX-C3 SBC: 0.1\n";

static int __init watchdog_init(void)
{
	int ret;

	if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog"))
		return -EBUSY;

	ret = register_reboot_notifier(&epx_c3_notifier);
	if (ret) {
//		printk(KERN_ERR PFX "cannot register reboot notifier "
;
		goto out;
	}

	ret = misc_register(&epx_c3_miscdev);
	if (ret) {
//		printk(KERN_ERR PFX "cannot register miscdev on minor=%d "
;
		unregister_reboot_notifier(&epx_c3_notifier);
		goto out;
	}

;

	return 0;

out:
	release_region(EPXC3_WATCHDOG_CTL_REG, 2);
	return ret;
}

static void __exit watchdog_exit(void)
{
	misc_deregister(&epx_c3_miscdev);
	unregister_reboot_notifier(&epx_c3_notifier);
	release_region(EPXC3_WATCHDOG_CTL_REG, 2);
}
ssize_t ar7240_i2s_read(struct file * filp, char __user * buf,size_t count, loff_t * f_pos)//gl-inet
{
#define prev_tail(t) ({ (t == 0) ? (NUM_DESC - 1) : (t - 1); })
#define next_tail(t) ({ (t == (NUM_DESC - 1)) ? 0 : (t + 1); })

	uint8_t *data;
	//ssize_t retval;
	unsigned long retval;
	struct ar7240_i2s_softc *sc = &sc_buf_var;
	i2s_dma_buf_t *dmabuf = &sc->sc_rbuf;
	i2s_buf_t *scbuf;
	ar7240_mbox_dma_desc *desc;
	unsigned int byte_cnt, mode = 1, offset = 0, tail = dmabuf->tail;
	unsigned long desc_p;
	int need_start = 0;

	byte_cnt = count;

	if (sc->ropened < 2) {
		ar7240_reg_rmw_set(MBOX_INT_ENABLE, MBOX0_TX_DMA_COMPLETE);
		need_start = 1;
	}

	sc->ropened = 2;

	scbuf = dmabuf->db_buf;
	desc = dmabuf->db_desc;
	desc_p = (unsigned long) dmabuf->db_desc_p;
	data = scbuf[0].bf_vaddr;

	desc_p += tail * sizeof(ar7240_mbox_dma_desc);

	while (byte_cnt && !desc[tail].OWN) {
		if (byte_cnt >= I2S_BUF_SIZE) {
			desc[tail].length = I2S_BUF_SIZE;
			byte_cnt -= I2S_BUF_SIZE;
		} else {
			desc[tail].length = byte_cnt;
			byte_cnt = 0;
		}
		//ar7240_dma_cache_sync(scbuf[tail].bf_vaddr, desc[tail].length);//gl-inet

		dma_cache_sync(NULL, scbuf[tail].bf_vaddr, desc[tail].length, DMA_FROM_DEVICE);//gl-inet		
		desc[tail].rsvd2 = 0;//gl-inet
		
		retval = copy_to_user((buf + offset), (scbuf[tail].bf_vaddr), I2S_BUF_SIZE);

		if (retval)
			return retval;
		desc[tail].BufPtr = (unsigned int) scbuf[tail].bf_paddr;
		desc[tail].OWN = 1;

		tail = next_tail(tail);
		offset += I2S_BUF_SIZE;
	}

	dmabuf->tail = tail;

	if (need_start) {
		ar7240_i2sound_dma_desc((unsigned long) desc_p, mode);
        if (filp) {
		    ar7240_i2sound_dma_start(mode);
        }
	} else if (!sc->rpause) {
		ar7240_i2sound_dma_resume(mode);
	}

	return offset;
}
static int rs_ioctl(struct tty_struct *tty, struct file * file,
		    unsigned int cmd, unsigned long arg)
{
	int error;
	struct cnxt_serial * info = (struct cnxt_serial *)tty->driver_data;
	int retval;

	if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
		return -ENODEV;

	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
		if (tty->flags & (1 << TTY_IO_ERROR))
		    return -EIO;
	}
	
	switch (cmd) {
		case TCSBRK:	/* SVID version: non-zero arg --> no break */
			retval = tty_check_change(tty);
			if (retval)
				return retval;
			tty_wait_until_sent(tty, 0);
			if (!arg)
				send_break(info, HZ/4);	/* 1/4 second */
			return 0;
		case TCSBRKP:	/* support for POSIX tcsendbreak() */
			retval = tty_check_change(tty);
			if (retval)
				return retval;
			tty_wait_until_sent(tty, 0);
			send_break(info, arg ? arg*(HZ/10) : HZ/4);
			return 0;
		case TIOCGSOFTCAR:
			error = verify_area(VERIFY_WRITE, (void *) arg,sizeof(long));
			if (error)
				return error;
			put_user(C_CLOCAL(tty) ? 1 : 0,
				    (unsigned long *) arg);
			return 0;
		case TIOCSSOFTCAR:
			get_user(arg, (unsigned long *) arg);
			tty->termios->c_cflag =
				((tty->termios->c_cflag & ~CLOCAL) |
				 (arg ? CLOCAL : 0));
			return 0;
		case TIOCGSERIAL:
			error = verify_area(VERIFY_WRITE, (void *) arg,
						sizeof(struct serial_struct));
			if (error)
				return error;
			return get_serial_info(info,
					       (struct serial_struct *) arg);
		case TIOCSSERIAL:
			return set_serial_info(info,
					       (struct serial_struct *) arg);
		case TIOCSERGETLSR: /* Get line status register */
			error = verify_area(VERIFY_WRITE, (void *) arg,
				sizeof(unsigned int));
			if (error)
				return error;
			else
			    return get_lsr_info(info, (unsigned int *) arg);

		case TIOCSERGSTRUCT:
			error = verify_area(VERIFY_WRITE, (void *) arg,
						sizeof(struct cnxt_serial));
			if (error)
				return error;
			copy_to_user((struct cnxt_serial *) arg,
				    info, sizeof(struct cnxt_serial));
			return 0;
			
		default:
			return -ENOIOCTLCMD;
		}
	return 0;
}
Exemple #18
0
static int
ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
{
	struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
	const struct ipv6_pinfo *inet6 = inet6_sk(sk);
	const struct inet_sock *inet = inet_sk(sk);
	const struct nf_conntrack_tuple_hash *h;
	struct sockaddr_in6 sin6;
	struct nf_conn *ct;
	__be32 flow_label;
	int bound_dev_if;

	lock_sock(sk);
	tuple.src.u3.in6 = sk->sk_v6_rcv_saddr;
	tuple.src.u.tcp.port = inet->inet_sport;
	tuple.dst.u3.in6 = sk->sk_v6_daddr;
	tuple.dst.u.tcp.port = inet->inet_dport;
	tuple.dst.protonum = sk->sk_protocol;
	bound_dev_if = sk->sk_bound_dev_if;
	flow_label = inet6->flow_label;
	release_sock(sk);

	if (tuple.dst.protonum != IPPROTO_TCP &&
	    tuple.dst.protonum != IPPROTO_SCTP)
		return -ENOPROTOOPT;

	if (*len < 0 || (unsigned int)*len < sizeof(sin6))
		return -EINVAL;

	h = nf_conntrack_find_get(sock_net(sk), &nf_ct_zone_dflt, &tuple);
	if (!h) {
		pr_debug("IP6T_SO_ORIGINAL_DST: Can't find %pI6c/%u-%pI6c/%u.\n",
			 &tuple.src.u3.ip6, ntohs(tuple.src.u.tcp.port),
			 &tuple.dst.u3.ip6, ntohs(tuple.dst.u.tcp.port));
		return -ENOENT;
	}

	ct = nf_ct_tuplehash_to_ctrack(h);

	sin6.sin6_family = AF_INET6;
	sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port;
	sin6.sin6_flowinfo = flow_label & IPV6_FLOWINFO_MASK;
	memcpy(&sin6.sin6_addr,
	       &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6,
	       sizeof(sin6.sin6_addr));

	nf_ct_put(ct);
	sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr, bound_dev_if);
	return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
}

static struct nf_sockopt_ops so_getorigdst6 = {
	.pf		= NFPROTO_IPV6,
	.get_optmin	= IP6T_SO_ORIGINAL_DST,
	.get_optmax	= IP6T_SO_ORIGINAL_DST + 1,
	.get		= ipv6_getorigdst,
	.owner		= THIS_MODULE,
};

static unsigned int ipv6_confirm(void *priv,
				 struct sk_buff *skb,
				 const struct nf_hook_state *state)
{
	struct nf_conn *ct;
	enum ip_conntrack_info ctinfo;
	unsigned char pnum = ipv6_hdr(skb)->nexthdr;
	int protoff;
	__be16 frag_off;

	ct = nf_ct_get(skb, &ctinfo);
	if (!ct || ctinfo == IP_CT_RELATED_REPLY)
		goto out;

	protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &pnum,
				   &frag_off);
	if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
		pr_debug("proto header not found\n");
		goto out;
	}

	/* adjust seqs for loopback traffic only in outgoing direction */
	if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
	    !nf_is_loopback_packet(skb)) {
		if (!nf_ct_seq_adjust(skb, ct, ctinfo, protoff)) {
			NF_CT_STAT_INC_ATOMIC(nf_ct_net(ct), drop);
			return NF_DROP;
		}
	}
out:
	/* We've seen it coming out the other side: confirm it */
	return nf_conntrack_confirm(skb);
}

static unsigned int ipv6_conntrack_in(void *priv,
				      struct sk_buff *skb,
				      const struct nf_hook_state *state)
{
	return nf_conntrack_in(state->net, PF_INET6, state->hook, skb);
}

static unsigned int ipv6_conntrack_local(void *priv,
					 struct sk_buff *skb,
					 const struct nf_hook_state *state)
{
	return nf_conntrack_in(state->net, PF_INET6, state->hook, skb);
}

static unsigned int ipv6_helper(void *priv,
				struct sk_buff *skb,
				const struct nf_hook_state *state)
{
	struct nf_conn *ct;
	const struct nf_conn_help *help;
	const struct nf_conntrack_helper *helper;
	enum ip_conntrack_info ctinfo;
	__be16 frag_off;
	int protoff;
	u8 nexthdr;

	/* This is where we call the helper: as the packet goes out. */
	ct = nf_ct_get(skb, &ctinfo);
	if (!ct || ctinfo == IP_CT_RELATED_REPLY)
		return NF_ACCEPT;

	help = nfct_help(ct);
	if (!help)
		return NF_ACCEPT;
	/* rcu_read_lock()ed by nf_hook_thresh */
	helper = rcu_dereference(help->helper);
	if (!helper)
		return NF_ACCEPT;

	nexthdr = ipv6_hdr(skb)->nexthdr;
	protoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
				   &frag_off);
	if (protoff < 0 || (frag_off & htons(~0x7)) != 0) {
		pr_debug("proto header not found\n");
		return NF_ACCEPT;
	}

	return helper->help(skb, protoff, ct, ctinfo);
}

static const struct nf_hook_ops ipv6_conntrack_ops[] = {
	{
		.hook		= ipv6_conntrack_in,
		.pf		= NFPROTO_IPV6,
		.hooknum	= NF_INET_PRE_ROUTING,
		.priority	= NF_IP6_PRI_CONNTRACK,
	},
	{
		.hook		= ipv6_conntrack_local,
		.pf		= NFPROTO_IPV6,
		.hooknum	= NF_INET_LOCAL_OUT,
		.priority	= NF_IP6_PRI_CONNTRACK,
	},
	{
		.hook		= ipv6_helper,
Exemple #19
0
static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
				 unsigned long arg, void __user *p)
{
	int			retval;
	struct uinput_device	*udev = file->private_data;
	struct uinput_ff_upload ff_up;
	struct uinput_ff_erase  ff_erase;
	struct uinput_request   *req;
	int                     length;
	char			*phys;

	retval = mutex_lock_interruptible(&udev->mutex);
	if (retval)
		return retval;

	if (!udev->dev) {
		retval = uinput_allocate_device(udev);
		if (retval)
			goto out;
	}

	switch (cmd) {
		case UI_DEV_CREATE:
			retval = uinput_create_device(udev);
			break;

		case UI_DEV_DESTROY:
			uinput_destroy_device(udev);
			break;

		case UI_SET_EVBIT:
			retval = uinput_set_bit(arg, evbit, EV_MAX);
			break;

		case UI_SET_KEYBIT:
			retval = uinput_set_bit(arg, keybit, KEY_MAX);
			break;

		case UI_SET_RELBIT:
			retval = uinput_set_bit(arg, relbit, REL_MAX);
			break;

		case UI_SET_ABSBIT:
			retval = uinput_set_bit(arg, absbit, ABS_MAX);
			break;

		case UI_SET_MSCBIT:
			retval = uinput_set_bit(arg, mscbit, MSC_MAX);
			break;

		case UI_SET_LEDBIT:
			retval = uinput_set_bit(arg, ledbit, LED_MAX);
			break;

		case UI_SET_SNDBIT:
			retval = uinput_set_bit(arg, sndbit, SND_MAX);
			break;

		case UI_SET_FFBIT:
			retval = uinput_set_bit(arg, ffbit, FF_MAX);
			break;

		case UI_SET_SWBIT:
			retval = uinput_set_bit(arg, swbit, SW_MAX);
			break;

		case UI_SET_PROPBIT:
			retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
			break;

		case UI_SET_PHYS:
			if (udev->state == UIST_CREATED) {
				retval = -EINVAL;
				goto out;
			}
			length = strnlen_user(p, 1024);
			if (length <= 0) {
				retval = -EFAULT;
				break;
			}
			kfree(udev->dev->phys);
			udev->dev->phys = phys = kmalloc(length, GFP_KERNEL);
			if (!phys) {
				retval = -ENOMEM;
				break;
			}
			if (copy_from_user(phys, p, length)) {
				udev->dev->phys = NULL;
				kfree(phys);
				retval = -EFAULT;
				break;
			}
			phys[length - 1] = '\0';
			break;

		case UI_BEGIN_FF_UPLOAD:
			retval = uinput_ff_upload_from_user(p, &ff_up);
			if (retval)
				break;

			req = uinput_request_find(udev, ff_up.request_id);
			if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) {
				retval = -EINVAL;
				break;
			}

			ff_up.retval = 0;
			ff_up.effect = *req->u.upload.effect;
			if (req->u.upload.old)
				ff_up.old = *req->u.upload.old;
			else
				memset(&ff_up.old, 0, sizeof(struct ff_effect));

			retval = uinput_ff_upload_to_user(p, &ff_up);
			break;

		case UI_BEGIN_FF_ERASE:
			if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			req = uinput_request_find(udev, ff_erase.request_id);
			if (!req || req->code != UI_FF_ERASE) {
				retval = -EINVAL;
				break;
			}

			ff_erase.retval = 0;
			ff_erase.effect_id = req->u.effect_id;
			if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			break;

		case UI_END_FF_UPLOAD:
			retval = uinput_ff_upload_from_user(p, &ff_up);
			if (retval)
				break;

			req = uinput_request_find(udev, ff_up.request_id);
			if (!req || req->code != UI_FF_UPLOAD ||
			    !req->u.upload.effect) {
				retval = -EINVAL;
				break;
			}

			req->retval = ff_up.retval;
			uinput_request_done(udev, req);
			break;

		case UI_END_FF_ERASE:
			if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
				retval = -EFAULT;
				break;
			}

			req = uinput_request_find(udev, ff_erase.request_id);
			if (!req || req->code != UI_FF_ERASE) {
				retval = -EINVAL;
				break;
			}

			req->retval = ff_erase.retval;
			uinput_request_done(udev, req);
			break;

		default:
			retval = -EINVAL;
	}

 out:
	mutex_unlock(&udev->mutex);
	return retval;
}
Exemple #20
0
/**
 * mei_read - the read function.
 *
 * @file: pointer to file structure
 * @ubuf: pointer to user buffer
 * @length: buffer length
 * @offset: data offset in buffer
 *
 * Return: >=0 data length on success , <0 on error
 */
static ssize_t mei_read(struct file *file, char __user *ubuf,
			size_t length, loff_t *offset)
{
	struct mei_cl *cl = file->private_data;
	struct mei_device *dev;
	struct mei_cl_cb *cb = NULL;
	int rets;
	int err;


	if (WARN_ON(!cl || !cl->dev))
		return -ENODEV;

	dev = cl->dev;


	mutex_lock(&dev->device_lock);
	if (dev->dev_state != MEI_DEV_ENABLED) {
		rets = -ENODEV;
		goto out;
	}

	if (length == 0) {
		rets = 0;
		goto out;
	}

	if (cl == &dev->iamthif_cl) {
		rets = mei_amthif_read(dev, file, ubuf, length, offset);
		goto out;
	}

	cb = mei_cl_read_cb(cl, file);
	if (cb) {
		/* read what left */
		if (cb->buf_idx > *offset)
			goto copy_buffer;
		/* offset is beyond buf_idx we have no more data return 0 */
		if (cb->buf_idx > 0 && cb->buf_idx <= *offset) {
			rets = 0;
			goto free;
		}
		/* Offset needs to be cleaned for contiguous reads*/
		if (cb->buf_idx == 0 && *offset > 0)
			*offset = 0;
	} else if (*offset > 0) {
		*offset = 0;
	}

	err = mei_cl_read_start(cl, length, file);
	if (err && err != -EBUSY) {
		cl_dbg(dev, cl, "mei start read failure status = %d\n", err);
		rets = err;
		goto out;
	}

	if (list_empty(&cl->rd_completed) && !waitqueue_active(&cl->rx_wait)) {
		if (file->f_flags & O_NONBLOCK) {
			rets = -EAGAIN;
			goto out;
		}

		mutex_unlock(&dev->device_lock);

		if (wait_event_interruptible(cl->rx_wait,
				(!list_empty(&cl->rd_completed)) ||
				(!mei_cl_is_connected(cl)))) {

			if (signal_pending(current))
				return -EINTR;
			return -ERESTARTSYS;
		}

		mutex_lock(&dev->device_lock);
		if (!mei_cl_is_connected(cl)) {
			rets = -EBUSY;
			goto out;
		}
	}

	cb = mei_cl_read_cb(cl, file);
	if (!cb) {
		if (mei_cl_is_fixed_address(cl) && dev->allow_fixed_address) {
			cb = mei_cl_read_cb(cl, NULL);
			if (cb)
				goto copy_buffer;
		}
		rets = 0;
		goto out;
	}

copy_buffer:
	/* now copy the data to user space */
	if (cb->status) {
		rets = cb->status;
		cl_dbg(dev, cl, "read operation failed %d\n", rets);
		goto free;
	}

	cl_dbg(dev, cl, "buf.size = %d buf.idx = %ld\n",
	    cb->buf.size, cb->buf_idx);
	if (length == 0 || ubuf == NULL || *offset > cb->buf_idx) {
		rets = -EMSGSIZE;
		goto free;
	}

	/* length is being truncated to PAGE_SIZE,
	 * however buf_idx may point beyond that */
	length = min_t(size_t, length, cb->buf_idx - *offset);

	if (copy_to_user(ubuf, cb->buf.data + *offset, length)) {
		dev_dbg(dev->dev, "failed to copy data to userland\n");
		rets = -EFAULT;
		goto free;
	}

	rets = length;
	*offset += length;
	if ((unsigned long)*offset < cb->buf_idx)
		goto out;

free:
	mei_io_cb_free(cb);

out:
	cl_dbg(dev, cl, "end mei read rets = %d\n", rets);
	mutex_unlock(&dev->device_lock);
	return rets;
}
Exemple #21
0
int wpa_ioctl(PSDevice pDevice, struct iw_point *p)
{
	struct viawget_wpa_param *param;
	int ret = 0;
	int wpa_ioctl = 0;

	if (p->length < sizeof(struct viawget_wpa_param) ||
	    p->length > VIAWGET_WPA_MAX_BUF_SIZE || !p->pointer)
		return -EINVAL;

	param = kmalloc((int)p->length, (int)GFP_KERNEL);
	if (param == NULL)
		return -ENOMEM;

	if (copy_from_user(param, p->pointer, p->length)) {
		ret = -EFAULT;
		goto out;
	}

	switch (param->cmd) {
	case VIAWGET_SET_WPA:
        ret = wpa_set_wpa(pDevice, param);
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA \n");
		break;

	case VIAWGET_SET_KEY:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY \n");
	    spin_lock_irq(&pDevice->lock);
        ret = wpa_set_keys(pDevice, param, false);
        spin_unlock_irq(&pDevice->lock);
		break;

	case VIAWGET_SET_SCAN:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN \n");
        ret = wpa_set_scan(pDevice, param);
		break;

	case VIAWGET_GET_SCAN:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n");
        ret = wpa_get_scan(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_SSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID \n");
        ret = wpa_get_ssid(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_GET_BSSID:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID \n");
        ret = wpa_get_bssid(pDevice, param);
		wpa_ioctl = 1;
		break;

	case VIAWGET_SET_ASSOCIATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE \n");
        ret = wpa_set_associate(pDevice, param);
		break;

	case VIAWGET_SET_DISASSOCIATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE \n");
        ret = wpa_set_disassociate(pDevice, param);
		break;

	case VIAWGET_SET_DROP_UNENCRYPT:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT \n");
		break;

    case VIAWGET_SET_DEAUTHENTICATE:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE \n");
		break;

	default:
	    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n",
		       param->cmd);
		return -EOPNOTSUPP;
		break;
	}

	if ((ret == 0) && wpa_ioctl) {
		if (copy_to_user(p->pointer, param, p->length)) {
			ret = -EFAULT;
			goto out;
		}
	}

out:
	kfree(param);

	return ret;
}
static int dn_def_dev_handler(struct ctl_table *table, int write,
				void __user *buffer,
				size_t *lenp, loff_t *ppos)
{
	size_t len;
	struct net_device *dev;
	char devname[17];

	if (!*lenp || (*ppos && !write)) {
		*lenp = 0;
		return 0;
	}

	if (write) {
		if (*lenp > 16)
			return -E2BIG;

		if (copy_from_user(devname, buffer, *lenp))
			return -EFAULT;

		devname[*lenp] = 0;
		strip_it(devname);

		dev = dev_get_by_name(&init_net, devname);
		if (dev == NULL)
			return -ENODEV;

		if (dev->dn_ptr == NULL) {
			dev_put(dev);
			return -ENODEV;
		}

		if (dn_dev_set_default(dev, 1)) {
			dev_put(dev);
			return -ENODEV;
		}
		*ppos += *lenp;

		return 0;
	}

	dev = dn_dev_get_default();
	if (dev == NULL) {
		*lenp = 0;
		return 0;
	}

	strcpy(devname, dev->name);
	dev_put(dev);
	len = strlen(devname);
	devname[len++] = '\n';

	if (len > *lenp) len = *lenp;

	if (len > sizeof devname || copy_to_user(buffer, devname, len))
		return -EFAULT;

	*lenp = len;
	*ppos += len;

	return 0;
}
/*
 * Return dasd information. Used for BIODASDINFO and BIODASDINFO2.
 */
static int
dasd_ioctl_information(struct dasd_device *device,
		unsigned int cmd, void __user *argp)
{
	struct dasd_information2_t *dasd_info;
	unsigned long flags;
	int rc;
	struct ccw_device *cdev;

	if (!device->discipline->fill_info)
		return -EINVAL;

	dasd_info = kzalloc(sizeof(struct dasd_information2_t), GFP_KERNEL);
	if (dasd_info == NULL)
		return -ENOMEM;

	rc = device->discipline->fill_info(device, dasd_info);
	if (rc) {
		kfree(dasd_info);
		return rc;
	}

	cdev = device->cdev;

	dasd_info->devno = _ccw_device_get_device_number(device->cdev);
	dasd_info->schid = _ccw_device_get_subchannel_number(device->cdev);
	dasd_info->cu_type = cdev->id.cu_type;
	dasd_info->cu_model = cdev->id.cu_model;
	dasd_info->dev_type = cdev->id.dev_type;
	dasd_info->dev_model = cdev->id.dev_model;
	dasd_info->status = device->state;
	/*
	 * The open_count is increased for every opener, that includes
	 * the blkdev_get in dasd_scan_partitions.
	 * This must be hidden from user-space.
	 */
	dasd_info->open_count = atomic_read(&device->open_count);
	if (!device->bdev)
		dasd_info->open_count++;

	/*
	 * check if device is really formatted
	 * LDL / CDL was returned by 'fill_info'
	 */
	if ((device->state < DASD_STATE_READY) ||
	    (dasd_check_blocksize(device->bp_block)))
		dasd_info->format = DASD_FORMAT_NONE;

	dasd_info->features |=
		((device->features & DASD_FEATURE_READONLY) != 0);

	if (device->discipline)
		memcpy(dasd_info->type, device->discipline->name, 4);
	else
		memcpy(dasd_info->type, "none", 4);

	if (device->request_queue->request_fn) {
		struct list_head *l;
#ifdef DASD_EXTENDED_PROFILING
		{
			struct list_head *l;
			spin_lock_irqsave(&device->lock, flags);
			list_for_each(l, &device->request_queue->queue_head)
				dasd_info->req_queue_len++;
			spin_unlock_irqrestore(&device->lock, flags);
		}
#endif				/* DASD_EXTENDED_PROFILING */
		spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
		list_for_each(l, &device->ccw_queue)
			dasd_info->chanq_len++;
		spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
				       flags);
	}

	rc = 0;
	if (copy_to_user(argp, dasd_info,
			 ((cmd == (unsigned int) BIODASDINFO2) ?
			  sizeof (struct dasd_information2_t) :
			  sizeof (struct dasd_information_t))))
		rc = -EFAULT;
	kfree(dasd_info);
	return rc;
}
Exemple #24
0
static long fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	static const struct watchdog_info ident = {
		.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
							WDIOF_MAGICCLOSE,
		.firmware_version = 1,
		.identity = "SBC60xx",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, p);
	case WDIOC_SETOPTIONS:
	{
		int new_options, retval = -EINVAL;
		if (get_user(new_options, p))
			return -EFAULT;
		if (new_options & WDIOS_DISABLECARD) {
			wdt_turnoff();
			retval = 0;
		}
		if (new_options & WDIOS_ENABLECARD) {
			wdt_startup();
			retval = 0;
		}
		return retval;
	}
	case WDIOC_KEEPALIVE:
		wdt_keepalive();
		return 0;
	case WDIOC_SETTIMEOUT:
	{
		int new_timeout;
		if (get_user(new_timeout, p))
			return -EFAULT;
		/* arbitrary upper limit */
		if (new_timeout < 1 || new_timeout > 3600)
			return -EINVAL;

		timeout = new_timeout;
		wdt_keepalive();
	}
		/* Fall through */
	case WDIOC_GETTIMEOUT:
		return put_user(timeout, p);
	default:
		return -ENOTTY;
	}
}

static const struct file_operations wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= fop_write,
	.open		= fop_open,
	.release	= fop_close,
	.unlocked_ioctl	= fop_ioctl,
};

static struct miscdevice wdt_miscdev = {
	.minor = WATCHDOG_MINOR,
	.name = "watchdog",
	.fops = &wdt_fops,
};

/*
 *	Notifier for system down
 */

static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
	void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		wdt_turnoff();
	return NOTIFY_DONE;
}

/*
 *	The WDT needs to learn about soft shutdowns in order to
 *	turn the timebomb registers off.
 */

static struct notifier_block wdt_notifier = {
	.notifier_call = wdt_notify_sys,
};

static void __exit sbc60xxwdt_unload(void)
{
	wdt_turnoff();

	/* Deregister */
	misc_deregister(&wdt_miscdev);

	unregister_reboot_notifier(&wdt_notifier);
	if ((wdt_stop != 0x45) && (wdt_stop != wdt_start))
		release_region(wdt_stop, 1);
	release_region(wdt_start, 1);
}

static int __init sbc60xxwdt_init(void)
{
	int rc = -EBUSY;

	if (timeout < 1 || timeout > 3600) { /* arbitrary upper limit */
		timeout = WATCHDOG_TIMEOUT;
		pr_info("timeout value must be 1 <= x <= 3600, using %d\n",
			timeout);
	}

	if (!request_region(wdt_start, 1, "SBC 60XX WDT")) {
		pr_err("I/O address 0x%04x already in use\n", wdt_start);
		rc = -EIO;
		goto err_out;
	}

	/* We cannot reserve 0x45 - the kernel already has! */
	if (wdt_stop != 0x45 && wdt_stop != wdt_start) {
		if (!request_region(wdt_stop, 1, "SBC 60XX WDT")) {
			pr_err("I/O address 0x%04x already in use\n", wdt_stop);
			rc = -EIO;
			goto err_out_region1;
		}
	}

	rc = register_reboot_notifier(&wdt_notifier);
	if (rc) {
		pr_err("cannot register reboot notifier (err=%d)\n", rc);
		goto err_out_region2;
	}

	rc = misc_register(&wdt_miscdev);
	if (rc) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       wdt_miscdev.minor, rc);
		goto err_out_reboot;
	}
	pr_info("WDT driver for 60XX single board computer initialised. timeout=%d sec (nowayout=%d)\n",
		timeout, nowayout);

	return 0;

err_out_reboot:
	unregister_reboot_notifier(&wdt_notifier);
err_out_region2:
	if (wdt_stop != 0x45 && wdt_stop != wdt_start)
		release_region(wdt_stop, 1);
err_out_region1:
	release_region(wdt_start, 1);
err_out:
	return rc;
}
Exemple #25
0
static int 
ar2315_wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
		 unsigned long arg)
{
	void __user *argp = (void __user *)arg;
	int __user *p = argp;
	int new_heartbeat;
	int status = 0;

	static struct watchdog_info ident = {
		.options =		WDIOF_SETTIMEOUT |
					WDIOF_MAGICCLOSE |
					WDIOF_KEEPALIVEPING,
		.firmware_version =	1,
		.identity =		"ar2315",
	};

	switch(cmd)
	{
		default:
			return -ENOIOCTLCMD;
		case WDIOC_GETSUPPORT:
			return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
		case WDIOC_GETSTATUS:
			//wdt_get_status(&status);
			return put_user(status, p);
		case WDIOC_GETBOOTSTATUS:
			return put_user(0, p);
		case WDIOC_KEEPALIVE:
			ar2315_wdt_ping();
			return 0;
		case WDIOC_SETTIMEOUT:
			if (get_user(new_heartbeat, p))
				return -EFAULT;

			if (ar2315_wdt_set_heartbeat(new_heartbeat))
				return -EINVAL;

			ar2315_wdt_ping();
			/* fallthrough */
		case WDIOC_GETTIMEOUT:
			return put_user(heartbeat, p);
	}
}

static struct file_operations ar2315_wdt_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= ar2315_wdt_write,
	.ioctl		= ar2315_wdt_ioctl,
	.open		= ar2315_wdt_open,
	.release	= ar2315_wdt_release,
};

static struct miscdevice ar2315_wdt_miscdev = {
	.minor	= WATCHDOG_MINOR,
	.name	= "watchdog",
	.fops	= &ar2315_wdt_fops,
};

static int __init 
ar2315_wdt_init(void)
{
	int ret = 0;

	if (ar2315_wdt_set_heartbeat(heartbeat)) {
		ar2315_wdt_set_heartbeat(5);
		printk(KERN_INFO "%s: heartbeat value must be 0<heartbeat<90, using %d\n",
		       __func__, 5);
	}
	ar2315_wdt_print_info();
	ar2315_wdt_ping();
	printk("%s using heartbeat %d s cycles %u\n", __func__, heartbeat, S_TO_CYCLES(heartbeat));
	ret = request_irq(AR531X_MISC_IRQ_WATCHDOG, ar2315_wdt_interrupt, SA_INTERRUPT, "ar2315_wdt", NULL);
	ar2315_wdt_print_info();
	if (ret) {
		printk(KERN_ERR "wdt: IRQ %d is not free.\n", AR531X_MISC_IRQ_WATCHDOG);
		goto out;
	}
	ret = misc_register(&ar2315_wdt_miscdev);
	if (ret) {
		printk(KERN_ERR "%s: cannot register miscdev on minor=%d (err=%d)\n",
		       __func__, WATCHDOG_MINOR, ret);
		goto out1;
	}
 out:
	return ret;
 out1:
	misc_deregister(&ar2315_wdt_miscdev);
	return ret;
}

static void __exit 
ar2315_wdt_exit(void)
{
	printk("%s\n", __func__);
	misc_deregister(&ar2315_wdt_miscdev);
	free_irq(AR531X_MISC_IRQ_WATCHDOG, NULL);
}
Exemple #26
0
static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	int rv = 0;
	unsigned long flags;
	struct timespec new_alarm_time;
	struct timespec new_rtc_time;
	struct timespec tmp_time;
	enum android_alarm_type alarm_type = ANDROID_ALARM_IOCTL_TO_TYPE(cmd);
	uint32_t alarm_type_mask = 1U << alarm_type;

	if (alarm_type >= ANDROID_ALARM_TYPE_COUNT)
		return -EINVAL;

	if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_GET_TIME(0)) {
		if ((file->f_flags & O_ACCMODE) == O_RDONLY)
			return -EPERM;
		if (file->private_data == NULL &&
		    cmd != ANDROID_ALARM_SET_RTC) {
			spin_lock_irqsave(&alarm_slock, flags);
			if (alarm_opened) {
				spin_unlock_irqrestore(&alarm_slock, flags);
				return -EBUSY;
			}
			alarm_opened = 1;
			file->private_data = (void *)1;
			spin_unlock_irqrestore(&alarm_slock, flags);
		}
	}

	switch (ANDROID_ALARM_BASE_CMD(cmd)) {
	case ANDROID_ALARM_CLEAR(0):
		spin_lock_irqsave(&alarm_slock, flags);
		pr_alarm(IO, "alarm %d clear\n", alarm_type);
		alarm_try_to_cancel(&alarms[alarm_type]);
		if (alarm_pending) {
			alarm_pending &= ~alarm_type_mask;
			if (!alarm_pending && !wait_pending)
				wake_unlock(&alarm_wake_lock);
		}
		alarm_enabled &= ~alarm_type_mask;
		spin_unlock_irqrestore(&alarm_slock, flags);
		break;

	case ANDROID_ALARM_SET_OLD:
	case ANDROID_ALARM_SET_AND_WAIT_OLD:
		if (get_user(new_alarm_time.tv_sec, (int __user *)arg)) {
			rv = -EFAULT;
			goto err1;
		}
		new_alarm_time.tv_nsec = 0;
		goto from_old_alarm_set;

	case ANDROID_ALARM_SET_AND_WAIT(0):
	case ANDROID_ALARM_SET(0):
		if (copy_from_user(&new_alarm_time, (void __user *)arg,
		    sizeof(new_alarm_time))) {
			rv = -EFAULT;
			goto err1;
		}
from_old_alarm_set:
		spin_lock_irqsave(&alarm_slock, flags);
		pr_alarm(INFO, "alarm %d set %ld.%09ld\n", alarm_type,
			new_alarm_time.tv_sec, new_alarm_time.tv_nsec);
		alarm_enabled |= alarm_type_mask;
		alarm_start_range(&alarms[alarm_type],
			timespec_to_ktime(new_alarm_time),
			timespec_to_ktime(new_alarm_time));
		spin_unlock_irqrestore(&alarm_slock, flags);
		if (ANDROID_ALARM_BASE_CMD(cmd) != ANDROID_ALARM_SET_AND_WAIT(0)
		    && cmd != ANDROID_ALARM_SET_AND_WAIT_OLD)
			break;
		/* fall though */
	case ANDROID_ALARM_WAIT:
		spin_lock_irqsave(&alarm_slock, flags);
		pr_alarm(IO, "alarm wait\n");
		if (!alarm_pending && wait_pending) {
			wake_unlock(&alarm_wake_lock);
			wait_pending = 0;
		}
		spin_unlock_irqrestore(&alarm_slock, flags);
		rv = wait_event_interruptible(alarm_wait_queue, alarm_pending);
		if (rv)
			goto err1;
		spin_lock_irqsave(&alarm_slock, flags);
		rv = alarm_pending;
		wait_pending = 1;
		alarm_pending = 0;
		spin_unlock_irqrestore(&alarm_slock, flags);
		break;
	case ANDROID_ALARM_SET_RTC:
		if (copy_from_user(&new_rtc_time, (void __user *)arg,
		    sizeof(new_rtc_time))) {
			rv = -EFAULT;
			goto err1;
		}
		rv = alarm_set_rtc(new_rtc_time);
		spin_lock_irqsave(&alarm_slock, flags);
		alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;
		wake_up(&alarm_wait_queue);
		spin_unlock_irqrestore(&alarm_slock, flags);
		if (rv < 0)
			goto err1;
		break;
	case ANDROID_ALARM_GET_TIME(0):
		switch (alarm_type) {
		case ANDROID_ALARM_RTC_WAKEUP:
		case ANDROID_ALARM_RTC:
			getnstimeofday(&tmp_time);
			break;
		case ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP:
		case ANDROID_ALARM_ELAPSED_REALTIME:
			tmp_time =
				ktime_to_timespec(alarm_get_elapsed_realtime());
			break;
		case ANDROID_ALARM_TYPE_COUNT:
		case ANDROID_ALARM_SYSTEMTIME:
			ktime_get_ts(&tmp_time);
			break;
		}
		if (copy_to_user((void __user *)arg, &tmp_time,
		    sizeof(tmp_time))) {
			rv = -EFAULT;
			goto err1;
		}
		break;

	default:
		rv = -EINVAL;
		goto err1;
	}
err1:
	return rv;
}
Exemple #27
0
static int mtd_ioctl(struct inode *inode, struct file *file,
		     u_int cmd, u_long arg)
{
	struct mtd_info *mtd = (struct mtd_info *)file->private_data;
	int ret = 0;
	u_long size;
	
	DEBUG(MTD_DEBUG_LEVEL0, "MTD_ioctl\n");

	size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
	if (cmd & IOC_IN) {
		ret = verify_area(VERIFY_READ, (char *)arg, size);
		if (ret) return ret;
	}
	if (cmd & IOC_OUT) {
		ret = verify_area(VERIFY_WRITE, (char *)arg, size);
		if (ret) return ret;
	}
	
	switch (cmd) {
	case MEMGETREGIONCOUNT:
		if (copy_to_user((int *) arg, &(mtd->numeraseregions), sizeof(int)))
			return -EFAULT;
		break;

	case MEMGETREGIONINFO:
	{
		struct region_info_user ur;

		if (copy_from_user(	&ur, 
					(struct region_info_user *)arg, 
					sizeof(struct region_info_user))) {
			return -EFAULT;
		}

		if (ur.regionindex >= mtd->numeraseregions)
			return -EINVAL;
		if (copy_to_user((struct mtd_erase_region_info *) arg, 
				&(mtd->eraseregions[ur.regionindex]),
				sizeof(struct mtd_erase_region_info)))
			return -EFAULT;
		break;
	}

	case MEMGETINFO:
		if (copy_to_user((struct mtd_info *)arg, mtd,
				 sizeof(struct mtd_info_user)))
			return -EFAULT;
		break;

	case MEMERASE:
	{
		struct erase_info *erase=kmalloc(sizeof(struct erase_info),GFP_KERNEL);
		if (!erase)
			ret = -ENOMEM;
		else {
			wait_queue_head_t waitq;
			DECLARE_WAITQUEUE(wait, current);

			init_waitqueue_head(&waitq);

			memset (erase,0,sizeof(struct erase_info));
			if (copy_from_user(&erase->addr, (u_long *)arg,
					   2 * sizeof(u_long))) {
				kfree(erase);
				return -EFAULT;
			}
			erase->mtd = mtd;
			erase->callback = mtd_erase_callback;
			erase->priv = (unsigned long)&waitq;

			/*
			  FIXME: Allow INTERRUPTIBLE. Which means
			  not having the wait_queue head on the stack.
			  
			  If the wq_head is on the stack, and we
			  leave because we got interrupted, then the
			  wq_head is no longer there when the
			  callback routine tries to wake us up.
			*/
			ret = mtd->erase(mtd, erase);
			if (!ret) {
				set_current_state(TASK_UNINTERRUPTIBLE);
				add_wait_queue(&waitq, &wait);
				if (erase->state != MTD_ERASE_DONE &&
				    erase->state != MTD_ERASE_FAILED)
					schedule();
				remove_wait_queue(&waitq, &wait);
				set_current_state(TASK_RUNNING);

				ret = (erase->state == MTD_ERASE_FAILED)?-EIO:0;
			}
			kfree(erase);
		}
		break;
	}

	case MEMWRITEOOB:
	{
		struct mtd_oob_buf buf;
		void *databuf;
		ssize_t retlen;
		
		if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
			return -EFAULT;
		
		if (buf.length > 0x4096)
			return -EINVAL;

		if (!mtd->write_oob)
			ret = -EOPNOTSUPP;
		else
			ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length);

		if (ret)
			return ret;

		databuf = kmalloc(buf.length, GFP_KERNEL);
		if (!databuf)
			return -ENOMEM;
		
		if (copy_from_user(databuf, buf.ptr, buf.length)) {
			kfree(databuf);
			return -EFAULT;
		}

		ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf);

		if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
			ret = -EFAULT;

		kfree(databuf);
		break;

	}

	case MEMREADOOB:
	{
		struct mtd_oob_buf buf;
		void *databuf;
		ssize_t retlen;

		if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
			return -EFAULT;
		
		if (buf.length > 0x4096)
			return -EINVAL;

		if (!mtd->read_oob)
			ret = -EOPNOTSUPP;
		else
			ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length);

		if (ret)
			return ret;

		databuf = kmalloc(buf.length, GFP_KERNEL);
		if (!databuf)
			return -ENOMEM;
		
		ret = (mtd->read_oob)(mtd, buf.start, buf.length, &retlen, databuf);

		if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
			ret = -EFAULT;
		else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
			ret = -EFAULT;
		
		kfree(databuf);
		break;
	}

	case MEMLOCK:
	{
		unsigned long adrs[2];

		if (copy_from_user(adrs ,(void *)arg, 2* sizeof(unsigned long)))
			return -EFAULT;

		if (!mtd->lock)
			ret = -EOPNOTSUPP;
		else
			ret = mtd->lock(mtd, adrs[0], adrs[1]);
		break;
	}

	case MEMUNLOCK:
	{
		unsigned long adrs[2];

		if (copy_from_user(adrs, (void *)arg, 2* sizeof(unsigned long)))
			return -EFAULT;

		if (!mtd->unlock)
			ret = -EOPNOTSUPP;
		else
			ret = mtd->unlock(mtd, adrs[0], adrs[1]);
		break;
	}

		
	default:
		DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
		ret = -ENOTTY;
	}

	return ret;
} /* memory_ioctl */
Exemple #28
0
ssize_t wmt_dbg_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{

	INT32 retval = 0;
	INT32 i_ret = 0;
	CHAR *warn_msg = "no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n";
	
    if(*f_pos > 0){
        retval = 0;
    } else {
        /*len = sprintf(page, "%d\n", g_psm_enable);*/
        if ( gCoexBuf.availSize <= 0)
        {
            WMT_INFO_FUNC("no data available, please run echo 15 xx > /proc/driver/wmt_psm first\n");
			retval = osal_strlen(warn_msg) + 1;
			if (count < retval)
			{
				retval = count;
			}
			i_ret = copy_to_user(buf, warn_msg, retval);
	        if (i_ret)
	        {
	        	WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
	        	retval = -EFAULT;
	        	goto err_exit;
	        }
			*f_pos += retval;
        }
        else
        {
            INT32 i = 0;
			INT32 len = 0;
			CHAR msg_info[128];
			INT32 max_num = 0;
            /*we do not check page buffer, because there are only 100 bytes in g_coex_buf, no reason page buffer is not enough, a bomb is placed here on unexpected condition*/
			
			WMT_INFO_FUNC("%d bytes avaliable\n", gCoexBuf.availSize);
			max_num = ((osal_sizeof(msg_info) > count ? osal_sizeof(msg_info) : count) -1) / 5;
			
			if (max_num > gCoexBuf.availSize)
			{
				max_num = gCoexBuf.availSize;
			}
			else
			{
				WMT_INFO_FUNC("round to %d bytes due to local buffer size limitation\n", max_num);
			}
			
			
			for (i = 0; i < max_num; i++)
            {
                len += osal_sprintf(msg_info + len, "0x%02x ", gCoexBuf.buffer[i]);
            }
			
			len += osal_sprintf(msg_info + len, "\n");
			retval = len;
			
			i_ret = copy_to_user(buf, msg_info, retval);
	        if (i_ret)
	        {
	        	WMT_ERR_FUNC("copy to buffer failed, ret:%d\n", retval);
	        	retval = -EFAULT;
	        	goto err_exit;
	        }
			*f_pos += retval;
            
        }
    }
    gCoexBuf.availSize = 0;
err_exit:

    return retval;
}
Exemple #29
0
static long indydog_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
	int options, retval = -EINVAL;
	static const struct watchdog_info ident = {
		.options		= WDIOF_KEEPALIVEPING,
		.firmware_version	= 0,
		.identity		= "Hardware Watchdog for SGI IP22",
	};

	switch (cmd) {
	case WDIOC_GETSUPPORT:
		if (copy_to_user((struct watchdog_info *)arg,
				 &ident, sizeof(ident)))
			return -EFAULT;
		return 0;
	case WDIOC_GETSTATUS:
	case WDIOC_GETBOOTSTATUS:
		return put_user(0, (int *)arg);
	case WDIOC_SETOPTIONS:
	{
		if (get_user(options, (int *)arg))
			return -EFAULT;
		if (options & WDIOS_DISABLECARD) {
			indydog_stop();
			retval = 0;
		}
		if (options & WDIOS_ENABLECARD) {
			indydog_start();
			retval = 0;
		}
		return retval;
	}
	case WDIOC_KEEPALIVE:
		indydog_ping();
		return 0;
	case WDIOC_GETTIMEOUT:
		return put_user(WATCHDOG_TIMEOUT, (int *)arg);
	default:
		return -ENOTTY;
	}
}

static int indydog_notify_sys(struct notifier_block *this,
					unsigned long code, void *unused)
{
	if (code == SYS_DOWN || code == SYS_HALT)
		indydog_stop();		/* Turn the WDT off */

	return NOTIFY_DONE;
}

static const struct file_operations indydog_fops = {
	.owner		= THIS_MODULE,
	.llseek		= no_llseek,
	.write		= indydog_write,
	.unlocked_ioctl	= indydog_ioctl,
	.open		= indydog_open,
	.release	= indydog_release,
};

static struct miscdevice indydog_miscdev = {
	.minor		= WATCHDOG_MINOR,
	.name		= "watchdog",
	.fops		= &indydog_fops,
};

static struct notifier_block indydog_notifier = {
	.notifier_call = indydog_notify_sys,
};

static int __init watchdog_init(void)
{
	int ret;

	ret = register_reboot_notifier(&indydog_notifier);
	if (ret) {
		pr_err("cannot register reboot notifier (err=%d)\n", ret);
		return ret;
	}

	ret = misc_register(&indydog_miscdev);
	if (ret) {
		pr_err("cannot register miscdev on minor=%d (err=%d)\n",
		       WATCHDOG_MINOR, ret);
		unregister_reboot_notifier(&indydog_notifier);
		return ret;
	}

	pr_info("Hardware Watchdog Timer for SGI IP22: 0.3\n");

	return 0;
}

static void __exit watchdog_exit(void)
{
	misc_deregister(&indydog_miscdev);
	unregister_reboot_notifier(&indydog_notifier);
}
Exemple #30
0
static long tcc_dxb_ctrl_ioctl(struct file *filp,
                               unsigned int cmd, unsigned long arg)
{
    int ret;
    unsigned int deviceIdx;
    unsigned int uiboardtype;
    unsigned int uirfpathctrl;
    ST_CTRLINFO_ARG stCtrlInfo;

    struct tcc_dxb_platform_data *dxb_dev;
    dxb_dev = (struct tcc_dxb_platform_data *)pdev_dxb->platform_data;

    switch (cmd) {
    case IOCTL_DXB_CTRL_OFF:
        if(arg!=0)
        {
            deviceIdx = *(unsigned int *)arg;
            dxb_dev->power_off(deviceIdx);
        }
        else
        {
            dxb_dev->power_off(0);
        }
        break;
    case IOCTL_DXB_CTRL_ON:
        if(arg!=0)
        {
            deviceIdx = *(unsigned int *)arg;
            dxb_dev->power_on(deviceIdx);
        }
        else
        {
            dxb_dev->power_on(0);
        }
        break;
    case IOCTL_DXB_CTRL_RF_PATH:
        ret = copy_from_user((void*)&uirfpathctrl, (const void*)arg, sizeof(unsigned long));
        dxb_dev->rf_path(uirfpathctrl);
        break;
    case IOCTL_DXB_CTRL_RESET:
        if(arg!=0)
        {
            deviceIdx = *(unsigned int *)arg;
            dxb_dev->power_reset(deviceIdx);
        }
        else
        {
            dxb_dev->power_reset(0);
        }
        break;
    case IOCTL_DXB_CTRL_SET_BOARD:
        ret = copy_from_user((void *)&uiboardtype, (const void *)arg, sizeof(unsigned long));
        if(uiboardtype < BOARD_MAX)
        {
            dxb_dev->set_board(uiboardtype);
        }
        break;
    case IOCTL_DXB_CTRL_GET_CTLINFO:
        dxb_dev->get_info(&stCtrlInfo);
        ret = copy_to_user((ST_CTRLINFO_ARG *)arg, &stCtrlInfo, sizeof(ST_CTRLINFO_ARG));
        break;
    default:
        printk("bl: unrecognized ioctl (0x%x)\n", cmd);
        return -EINVAL;
        break;
    }

    return 0;
}