예제 #1
0
/*----------------------------------------------------------------
 * p80211knetdev_do_ioctl
 *
 * Handle an ioctl call on one of our devices.  Everything Linux
 * ioctl specific is done here.  Then we pass the contents of the
 * ifr->data to the request message handler.
 *
 * Arguments:
 *	dev	Linux kernel netdevice
 *	ifr	Our private ioctl request structure, typed for the
 *		generic struct ifreq so we can use ptr to func
 *		w/o cast.
 *
 * Returns:
 *	zero on success, a negative errno on failure.  Possible values:
 *		-ENETDOWN Device isn't up.
 *		-EBUSY	cmd already in progress
 *		-ETIME	p80211 cmd timed out (MSD may have its own timers)
 *		-EFAULT memory fault copying msg from user buffer
 *		-ENOMEM unable to allocate kernel msg buffer
 *		-EINVAL	bad magic, it the cmd really for us?
 *		-EintR	sleeping on cmd, awakened by signal, cmd cancelled.
 *
 * Call Context:
 *	Process thread (ioctl caller).  TODO: SMP support may require
 *	locks.
 *----------------------------------------------------------------
 */
static int p80211knetdev_do_ioctl(struct net_device *dev,
				  struct ifreq *ifr, int cmd)
{
	int result = 0;
	struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr;
	struct wlandevice *wlandev = dev->ml_priv;
	u8 *msgbuf;

	netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);

#ifdef SIOCETHTOOL
	if (cmd == SIOCETHTOOL) {
		result =
		    p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
		goto bail;
	}
#endif

	/* Test the magic, assume ifr is good if it's there */
	if (req->magic != P80211_IOCTL_MAGIC) {
		result = -EINVAL;
		goto bail;
	}

	if (cmd == P80211_IFTEST) {
		result = 0;
		goto bail;
	} else if (cmd != P80211_IFREQ) {
		result = -EINVAL;
		goto bail;
	}

	/* Allocate a buf of size req->len */
	msgbuf = kmalloc(req->len, GFP_KERNEL);
	if (msgbuf) {
		if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
			result = -EFAULT;
		else
			result = p80211req_dorequest(wlandev, msgbuf);

		if (result == 0) {
			if (copy_to_user
			    ((void __user *)req->data, msgbuf, req->len)) {
				result = -EFAULT;
			}
		}
		kfree(msgbuf);
	} else {
		result = -ENOMEM;
	}
bail:
	/* If allocate,copyfrom or copyto fails, return errno */
	return result;
}
예제 #2
0
/*----------------------------------------------------------------
* p80211knetdev_do_ioctl
*
* Handle an ioctl call on one of our devices.  Everything Linux
* ioctl specific is done here.  Then we pass the contents of the
* ifr->data to the request message handler.
*
* Arguments:
*	dev	Linux kernel netdevice
*	ifr	Our private ioctl request structure, typed for the
*		generic struct ifreq so we can use ptr to func
*		w/o cast.
*
* Returns:
*	zero on success, a negative errno on failure.  Possible values:
*		-ENETDOWN Device isn't up.
*		-EBUSY	cmd already in progress
*		-ETIME	p80211 cmd timed out (MSD may have its own timers)
*		-EFAULT memory fault copying msg from user buffer
*		-ENOMEM unable to allocate kernel msg buffer
*		-ENOSYS	bad magic, it the cmd really for us?
*		-EINTR	sleeping on cmd, awakened by signal, cmd cancelled.
*
* Call Context:
*	Process thread (ioctl caller).  TODO: SMP support may require
*	locks.
----------------------------------------------------------------*/
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
{
	int			result = 0;
	p80211ioctl_req_t	*req = (p80211ioctl_req_t*)ifr;
	wlandevice_t		*wlandev = (wlandevice_t*)dev->priv;
	UINT8			*msgbuf;
	DBFENTER;

	WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);

#if WIRELESS_EXT < 13
	/* Is this a wireless extensions ioctl? */
	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
		if ((result = p80211wext_support_ioctl(dev, ifr, cmd))
		    != (-EOPNOTSUPP)) {
			goto bail;
		}
	}
#endif

#ifdef SIOCETHTOOL
	if (cmd == SIOCETHTOOL) {
		result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
		goto bail;
	}
#endif

	/* Test the magic, assume ifr is good if it's there */
	if ( req->magic != P80211_IOCTL_MAGIC ) {
		result = -ENOSYS;
		goto bail;
	}

	if ( cmd == P80211_IFTEST ) {
		result = 0;
		goto bail;
	} else if ( cmd != P80211_IFREQ ) {
		result = -ENOSYS;
		goto bail;
	}

	/* Allocate a buf of size req->len */
	if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
		if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
			result = -EFAULT;
		} else {
			result = p80211req_dorequest( wlandev, msgbuf);
		}

		if ( result == 0 ) {
			if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
				result = -EFAULT;
			}
		}
		kfree(msgbuf);
	} else {
		result = -ENOMEM;
	}
bail:
	DBFEXIT;

	return result; /* If allocate,copyfrom or copyto fails, return errno */
}