summaryrefslogtreecommitdiffstats
path: root/drivers/net/wan/farsync.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2021-07-27 15:45:10 +0200
committerDavid S. Miller <davem@davemloft.net>2021-07-27 20:11:44 +0100
commit73d74f61a559d8fc2266abfb95085bb7d1917a3e (patch)
tree086113aa0ca17a1291b79cdd3d37d6fd7e83084a /drivers/net/wan/farsync.c
parent34f7cac07c4e1a8fe64bd09334ecb49f21e98bf8 (diff)
downloadlinux-stable-73d74f61a559d8fc2266abfb95085bb7d1917a3e.tar.gz
linux-stable-73d74f61a559d8fc2266abfb95085bb7d1917a3e.tar.bz2
linux-stable-73d74f61a559d8fc2266abfb95085bb7d1917a3e.zip
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: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wan/farsync.c')
-rw-r--r--drivers/net/wan/farsync.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index b3466e084e84..d0e3cab98645 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -1909,7 +1909,7 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
}
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_port_info *port;
@@ -1918,7 +1918,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
unsigned long flags;
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);
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
* to write
*/
- if (!ifr->ifr_data)
+ if (!data)
return -EINVAL;
- if (copy_from_user(&wrthdr, ifr->ifr_data,
- sizeof(struct fstioc_write)))
+ if (copy_from_user(&wrthdr, data, sizeof(struct fstioc_write)))
return -EFAULT;
/* 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. */
- buf = memdup_user(ifr->ifr_data + sizeof(struct fstioc_write),
+ buf = memdup_user(data + sizeof(struct fstioc_write),
wrthdr.size);
if (IS_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;
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 0;
@@ -2011,11 +2010,30 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
card->card_no, card->state);
return -EIO;
}
- if (copy_from_user(&info, ifr->ifr_data, sizeof(info)))
+ if (copy_from_user(&info, data, sizeof(info)))
return -EFAULT;
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:
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE:
@@ -2310,7 +2328,8 @@ static const struct net_device_ops fst_ops = {
.ndo_open = fst_open,
.ndo_stop = fst_close,
.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,
};