Skip to content

Commit

Permalink
wan: use ndo_siocdevprivate
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Arnd Bergmann authored and David S. Miller committed Jul 27, 2021
1 parent 34f7cac commit 73d74f6
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 56 deletions.
20 changes: 15 additions & 5 deletions drivers/net/wan/c101.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,14 +208,12 @@ static int c101_close(struct net_device *dev)
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);
sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync;
#ifdef DEBUG_RINGS
port_t *port = dev_to_port(dev);

#ifdef DEBUG_RINGS
if (cmd == SIOCDEVPRIVATE) {
sca_dump_rings(dev);
printk(KERN_DEBUG "MSCI1: ST: %02x %02x %02x %02x\n",
Expand All @@ -226,6 +224,17 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0;
}
#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)
return hdlc_ioctl(dev, ifr, cmd);

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

static int __init c101_run(unsigned long irq, unsigned long winbase)
Expand Down
39 changes: 29 additions & 10 deletions drivers/net/wan/farsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -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,
};

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wan/hdlc_fr.c
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,9 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
struct pvc_device *pvc = dev->ml_priv;
fr_proto_pvc_info info;

if (cmd != SIOCWANDEV)
return -EOPNOTSUPP;

if (ifr->ifr_settings.type == IF_GET_PROTO) {
if (dev->type == ARPHRD_ETHER)
ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
Expand Down
39 changes: 23 additions & 16 deletions drivers/net/wan/lmc/lmc_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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_ctl_t ctl;
Expand All @@ -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.
*/
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;
else
ret = 0;
Expand All @@ -141,7 +142,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
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;
break;
}
Expand Down Expand Up @@ -171,7 +172,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
}

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

sc->lmc_xinfo.Magic1 = 0xDEADBEEF;

if (copy_to_user(ifr->ifr_data, &sc->lmc_xinfo,
sizeof(struct lmc_xinfo)))
if (copy_to_user(data, &sc->lmc_xinfo, sizeof(struct lmc_xinfo)))
ret = -EFAULT;
else
ret = 0;
Expand Down Expand Up @@ -245,9 +245,9 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
regVal & T1FRAMER_SEF_MASK;
}
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)) ||
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)))
ret = -EFAULT;
else
Expand Down Expand Up @@ -282,7 +282,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
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;
break;
}
Expand Down Expand Up @@ -314,11 +314,11 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/

#ifdef DEBUG
case LMCIOCDUMPEVENTLOG:
if (copy_to_user(ifr->ifr_data, &lmcEventLogIndex, sizeof(u32))) {
if (copy_to_user(data, &lmcEventLogIndex, sizeof(u32))) {
ret = -EFAULT;
break;
}
if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
if (copy_to_user(data + sizeof(u32), lmcEventLogBuf,
sizeof(lmcEventLogBuf)))
ret = -EFAULT;
else
Expand Down Expand Up @@ -346,7 +346,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
*/
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;
break;
}
Expand Down Expand Up @@ -609,15 +609,21 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/

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

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 */
static void lmc_watchdog(struct timer_list *t) /*fold00*/
Expand Down Expand Up @@ -789,6 +795,7 @@ static const struct net_device_ops lmc_ops = {
.ndo_stop = lmc_close,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = lmc_ioctl,
.ndo_siocdevprivate = lmc_siocdevprivate,
.ndo_tx_timeout = lmc_driver_timeout,
.ndo_get_stats = lmc_get_stats,
};
Expand Down
19 changes: 13 additions & 6 deletions drivers/net/wan/n2.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,19 +227,25 @@ static int n2_close(struct net_device *dev)
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
if (cmd == SIOCDEVPRIVATE) {
sca_dump_rings(dev);
return 0;
}
#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)
return hdlc_ioctl(dev, ifr, cmd);

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

static int __init n2_run(unsigned long io, unsigned long irq,
Expand Down
19 changes: 13 additions & 6 deletions drivers/net/wan/pc300too.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ static int pc300_close(struct net_device *dev)
return 0;
}

static int pc300_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
void __user *data, int cmd)
{
#ifdef DEBUG_RINGS
if (cmd == SIOCDEVPRIVATE) {
sca_dump_rings(dev);
return 0;
}
#endif
return -EOPNOTSUPP;
}

static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
const size_t size = sizeof(sync_serial_settings);
Expand All @@ -182,12 +194,6 @@ static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
int new_type;
port_t *port = dev_to_port(dev);

#ifdef DEBUG_RINGS
if (cmd == SIOCDEVPRIVATE) {
sca_dump_rings(dev);
return 0;
}
#endif
if (cmd != SIOCWANDEV)
return hdlc_ioctl(dev, ifr, cmd);

Expand Down Expand Up @@ -273,6 +279,7 @@ static const struct net_device_ops pc300_ops = {
.ndo_stop = pc300_close,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pc300_ioctl,
.ndo_siocdevprivate = pc300_siocdevprivate,
};

static int pc300_pci_init_one(struct pci_dev *pdev,
Expand Down
19 changes: 13 additions & 6 deletions drivers/net/wan/pci200syn.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,25 @@ static int pci200_close(struct net_device *dev)
return 0;
}

static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
static int pci200_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
if (cmd == SIOCDEVPRIVATE) {
sca_dump_rings(dev);
return 0;
}
#endif
return -EOPNOTSUPP;
}

static int pci200_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)
return hdlc_ioctl(dev, ifr, cmd);

Expand Down Expand Up @@ -254,6 +260,7 @@ static const struct net_device_ops pci200_ops = {
.ndo_stop = pci200_close,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pci200_ioctl,
.ndo_siocdevprivate = pci200_siocdevprivate,
};

static int pci200_pci_init_one(struct pci_dev *pdev,
Expand Down
Loading

0 comments on commit 73d74f6

Please sign in to comment.