Commit 73d74f61 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller
Browse files

wan: use ndo_siocdevprivate



The wan drivers each support some custom SIOCDEVPRIVATE
ioctls, plus the common SIOCWANDEV command.

Split these so the ioctl callback only deals with SIOCWANDEV
and the rest is handled by ndo_siocdevprivate.

It might make sense to also split out SIOCWANDEV into a
separate callback in order to eventually remove ndo_do_ioctl
entirely.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Cc: Kevin Curtis <kevin.curtis@farsite.co.uk>
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 34f7cac0
Loading
Loading
Loading
Loading
+15 −5
Original line number Original line Diff line number Diff line
@@ -208,14 +208,12 @@ static int c101_close(struct net_device *dev)
	return 0;
	return 0;
}
}


static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int c101_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
			       void __user *data, int cmd)
{
{
	const size_t size = sizeof(sync_serial_settings);
#ifdef DEBUG_RINGS
	sync_serial_settings new_line;
	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
	port_t *port = dev_to_port(dev);
	port_t *port = dev_to_port(dev);


#ifdef DEBUG_RINGS
	if (cmd == SIOCDEVPRIVATE) {
	if (cmd == SIOCDEVPRIVATE) {
		sca_dump_rings(dev);
		sca_dump_rings(dev);
		printk(KERN_DEBUG "MSCI1: ST: %02x %02x %02x %02x\n",
		printk(KERN_DEBUG "MSCI1: ST: %02x %02x %02x %02x\n",
@@ -226,6 +224,17 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		return 0;
		return 0;
	}
	}
#endif
#endif

	return -EOPNOTSUPP;
}

static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	const size_t size = sizeof(sync_serial_settings);
	sync_serial_settings new_line;
	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
	port_t *port = dev_to_port(dev);

	if (cmd != SIOCWANDEV)
	if (cmd != SIOCWANDEV)
		return hdlc_ioctl(dev, ifr, cmd);
		return hdlc_ioctl(dev, ifr, cmd);


@@ -287,6 +296,7 @@ static const struct net_device_ops c101_ops = {
	.ndo_stop       = c101_close,
	.ndo_stop       = c101_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_do_ioctl   = c101_ioctl,
	.ndo_do_ioctl   = c101_ioctl,
	.ndo_siocdevprivate = c101_siocdevprivate,
};
};


static int __init c101_run(unsigned long irq, unsigned long winbase)
static int __init c101_run(unsigned long irq, unsigned long winbase)
+29 −10
Original line number Original line Diff line number Diff line
@@ -1909,7 +1909,7 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
}
}


static int
static int
fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
fst_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd)
{
{
	struct fst_card_info *card;
	struct fst_card_info *card;
	struct fst_port_info *port;
	struct fst_port_info *port;
@@ -1918,7 +1918,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
	unsigned long flags;
	unsigned long flags;
	void *buf;
	void *buf;


	dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, ifr->ifr_data);
	dbg(DBG_IOCTL, "ioctl: %x, %p\n", cmd, data);


	port = dev_to_port(dev);
	port = dev_to_port(dev);
	card = port->card;
	card = port->card;
@@ -1942,11 +1942,10 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		/* First copy in the header with the length and offset of data
		/* First copy in the header with the length and offset of data
		 * to write
		 * to write
		 */
		 */
		if (!ifr->ifr_data)
		if (!data)
			return -EINVAL;
			return -EINVAL;


		if (copy_from_user(&wrthdr, ifr->ifr_data,
		if (copy_from_user(&wrthdr, data, sizeof(struct fstioc_write)))
				   sizeof(struct fstioc_write)))
			return -EFAULT;
			return -EFAULT;


		/* Sanity check the parameters. We don't support partial writes
		/* Sanity check the parameters. We don't support partial writes
@@ -1958,7 +1957,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)


		/* Now copy the data to the card. */
		/* Now copy the data to the card. */


		buf = memdup_user(ifr->ifr_data + sizeof(struct fstioc_write),
		buf = memdup_user(data + sizeof(struct fstioc_write),
				  wrthdr.size);
				  wrthdr.size);
		if (IS_ERR(buf))
		if (IS_ERR(buf))
			return PTR_ERR(buf);
			return PTR_ERR(buf);
@@ -1991,12 +1990,12 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
			}
			}
		}
		}


		if (!ifr->ifr_data)
		if (!data)
			return -EINVAL;
			return -EINVAL;


		gather_conf_info(card, port, &info);
		gather_conf_info(card, port, &info);


		if (copy_to_user(ifr->ifr_data, &info, sizeof(info)))
		if (copy_to_user(data, &info, sizeof(info)))
			return -EFAULT;
			return -EFAULT;


		return 0;
		return 0;
@@ -2011,11 +2010,30 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
			       card->card_no, card->state);
			       card->card_no, card->state);
			return -EIO;
			return -EIO;
		}
		}
		if (copy_from_user(&info, ifr->ifr_data, sizeof(info)))
		if (copy_from_user(&info, data, sizeof(info)))
			return -EFAULT;
			return -EFAULT;


		return set_conf_from_info(card, port, &info);
		return set_conf_from_info(card, port, &info);
	default:
		return -EINVAL;
	}
}


static int
fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct fst_card_info *card;
	struct fst_port_info *port;

	dbg(DBG_IOCTL, "ioctl: %x, %x\n", cmd, ifr->ifr_settings.type);

	port = dev_to_port(dev);
	card = port->card;

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

	switch (cmd) {
	case SIOCWANDEV:
	case SIOCWANDEV:
		switch (ifr->ifr_settings.type) {
		switch (ifr->ifr_settings.type) {
		case IF_GET_IFACE:
		case IF_GET_IFACE:
@@ -2311,6 +2329,7 @@ static const struct net_device_ops fst_ops = {
	.ndo_stop       = fst_close,
	.ndo_stop       = fst_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_do_ioctl	= fst_ioctl,
	.ndo_do_ioctl	= fst_ioctl,
	.ndo_siocdevprivate = fst_siocdevprivate,
	.ndo_tx_timeout = fst_tx_timeout,
	.ndo_tx_timeout = fst_tx_timeout,
};
};


+3 −0
Original line number Original line Diff line number Diff line
@@ -362,6 +362,9 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
	struct pvc_device *pvc = dev->ml_priv;
	struct pvc_device *pvc = dev->ml_priv;
	fr_proto_pvc_info info;
	fr_proto_pvc_info info;


	if (cmd != SIOCWANDEV)
		return -EOPNOTSUPP;

	if (ifr->ifr_settings.type == IF_GET_PROTO) {
	if (ifr->ifr_settings.type == IF_GET_PROTO) {
		if (dev->type == ARPHRD_ETHER)
		if (dev->type == ARPHRD_ETHER)
			ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
			ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
+23 −16
Original line number Original line Diff line number Diff line
@@ -105,7 +105,8 @@ static void lmc_driver_timeout(struct net_device *dev, unsigned int txqueue);
 * linux reserves 16 device specific IOCTLs.  We call them
 * linux reserves 16 device specific IOCTLs.  We call them
 * LMCIOC* to control various bits of our world.
 * LMCIOC* to control various bits of our world.
 */
 */
int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
static int lmc_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
			      void __user *data, int cmd) /*fold00*/
{
{
    lmc_softc_t *sc = dev_to_sc(dev);
    lmc_softc_t *sc = dev_to_sc(dev);
    lmc_ctl_t ctl;
    lmc_ctl_t ctl;
@@ -124,7 +125,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
         * To date internally, just copy this out to the user.
         * To date internally, just copy this out to the user.
         */
         */
    case LMCIOCGINFO: /*fold01*/
    case LMCIOCGINFO: /*fold01*/
	if (copy_to_user(ifr->ifr_data, &sc->ictl, sizeof(lmc_ctl_t)))
	if (copy_to_user(data, &sc->ictl, sizeof(lmc_ctl_t)))
		ret = -EFAULT;
		ret = -EFAULT;
	else
	else
		ret = 0;
		ret = 0;
@@ -141,7 +142,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
            break;
            break;
        }
        }


	if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
	if (copy_from_user(&ctl, data, sizeof(lmc_ctl_t))) {
		ret = -EFAULT;
		ret = -EFAULT;
		break;
		break;
	}
	}
@@ -171,7 +172,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
		break;
		break;
	    }
	    }


	    if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) {
	    if (copy_from_user(&new_type, data, sizeof(u16))) {
		ret = -EFAULT;
		ret = -EFAULT;
		break;
		break;
	    }
	    }
@@ -211,8 +212,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/


        sc->lmc_xinfo.Magic1 = 0xDEADBEEF;
        sc->lmc_xinfo.Magic1 = 0xDEADBEEF;


        if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo,
	if (copy_to_user(data, &sc->lmc_xinfo, sizeof(struct lmc_xinfo)))
			 sizeof(struct lmc_xinfo)))
		ret = -EFAULT;
		ret = -EFAULT;
	else
	else
		ret = 0;
		ret = 0;
@@ -245,9 +245,9 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
			    regVal & T1FRAMER_SEF_MASK;
			    regVal & T1FRAMER_SEF_MASK;
	    }
	    }
	    spin_unlock_irqrestore(&sc->lmc_lock, flags);
	    spin_unlock_irqrestore(&sc->lmc_lock, flags);
	    if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
	    if (copy_to_user(data, &sc->lmc_device->stats,
			     sizeof(sc->lmc_device->stats)) ||
			     sizeof(sc->lmc_device->stats)) ||
		copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
		copy_to_user(data + sizeof(sc->lmc_device->stats),
			     &sc->extra_stats, sizeof(sc->extra_stats)))
			     &sc->extra_stats, sizeof(sc->extra_stats)))
		    ret = -EFAULT;
		    ret = -EFAULT;
	    else
	    else
@@ -282,7 +282,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
            break;
            break;
        }
        }


	if (copy_from_user(&ctl, ifr->ifr_data, sizeof(lmc_ctl_t))) {
	if (copy_from_user(&ctl, data, sizeof(lmc_ctl_t))) {
		ret = -EFAULT;
		ret = -EFAULT;
		break;
		break;
	}
	}
@@ -314,11 +314,11 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/


#ifdef DEBUG
#ifdef DEBUG
    case LMCIOCDUMPEVENTLOG:
    case LMCIOCDUMPEVENTLOG:
	if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof(u32))) {
	if (copy_to_user(data, &lmcEventLogIndex, sizeof(u32))) {
		ret = -EFAULT;
		ret = -EFAULT;
		break;
		break;
	}
	}
	if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
	if (copy_to_user(data + sizeof(u32), lmcEventLogBuf,
			 sizeof(lmcEventLogBuf)))
			 sizeof(lmcEventLogBuf)))
		ret = -EFAULT;
		ret = -EFAULT;
	else
	else
@@ -346,7 +346,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
             */
             */
            netif_stop_queue(dev);
            netif_stop_queue(dev);


	    if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) {
	    if (copy_from_user(&xc, data, sizeof(struct lmc_xilinx_control))) {
		ret = -EFAULT;
		ret = -EFAULT;
		break;
		break;
	    }
	    }
@@ -609,15 +609,21 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/


        }
        }
        break;
        break;
    default: /*fold01*/
    default:
        /* If we don't know what to do, give the protocol a shot. */
        ret = lmc_proto_ioctl (sc, ifr, cmd);
	break;
	break;
    }
    }


    return ret;
    return ret;
}
}


int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	if (cmd != SIOCWANDEV)
		return -EOPNOTSUPP;

	return lmc_proto_ioctl(dev_to_sc(dev), ifr, cmd);
}



/* the watchdog process that cruises around */
/* the watchdog process that cruises around */
static void lmc_watchdog(struct timer_list *t) /*fold00*/
static void lmc_watchdog(struct timer_list *t) /*fold00*/
@@ -789,6 +795,7 @@ static const struct net_device_ops lmc_ops = {
	.ndo_stop       = lmc_close,
	.ndo_stop       = lmc_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_do_ioctl   = lmc_ioctl,
	.ndo_do_ioctl   = lmc_ioctl,
	.ndo_siocdevprivate = lmc_siocdevprivate,
	.ndo_tx_timeout = lmc_driver_timeout,
	.ndo_tx_timeout = lmc_driver_timeout,
	.ndo_get_stats  = lmc_get_stats,
	.ndo_get_stats  = lmc_get_stats,
};
};
+13 −6
Original line number Original line Diff line number Diff line
@@ -227,19 +227,25 @@ static int n2_close(struct net_device *dev)
	return 0;
	return 0;
}
}


static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int n2_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
			     void __user *data, int cmd)
{
{
	const size_t size = sizeof(sync_serial_settings);
	sync_serial_settings new_line;
	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
	port_t *port = dev_to_port(dev);

#ifdef DEBUG_RINGS
#ifdef DEBUG_RINGS
	if (cmd == SIOCDEVPRIVATE) {
	if (cmd == SIOCDEVPRIVATE) {
		sca_dump_rings(dev);
		sca_dump_rings(dev);
		return 0;
		return 0;
	}
	}
#endif
#endif
	return -EOPNOTSUPP;
}

static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	const size_t size = sizeof(sync_serial_settings);
	sync_serial_settings new_line;
	sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
	port_t *port = dev_to_port(dev);

	if (cmd != SIOCWANDEV)
	if (cmd != SIOCWANDEV)
		return hdlc_ioctl(dev, ifr, cmd);
		return hdlc_ioctl(dev, ifr, cmd);


@@ -312,6 +318,7 @@ static const struct net_device_ops n2_ops = {
	.ndo_stop       = n2_close,
	.ndo_stop       = n2_close,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_start_xmit = hdlc_start_xmit,
	.ndo_do_ioctl   = n2_ioctl,
	.ndo_do_ioctl   = n2_ioctl,
	.ndo_siocdevprivate = n2_siocdevprivate,
};
};


static int __init n2_run(unsigned long io, unsigned long irq,
static int __init n2_run(unsigned long io, unsigned long irq,
Loading