Commit ad7eab2a authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

net: split out ndo_siowandev ioctl

In order to further reduce the scope of ndo_do_ioctl(), move
out the SIOCWANDEV handling into a new network device operation
function.

Adjust the prototype to only pass the if_settings sub-structure
in place of the ifreq, and remove the redundant 'cmd' argument
in the process.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Cc: "Jan \"Yenya\" Kasprzak" <kas@fi.muni.cz>
Cc: Kevin Curtis <kevin.curtis@farsite.co.uk>
Cc: Zhao Qiang <qiang.zhao@nxp.com>
Cc: Martin Schiller <ms@dev.tdt.de>
Cc: Jiri Slaby <jirislaby@kernel.org>
Cc: linux-x25@vger.kernel.org
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a7605370
...@@ -222,6 +222,13 @@ ndo_do_ioctl: ...@@ -222,6 +222,13 @@ ndo_do_ioctl:
Synchronization: rtnl_lock() semaphore. Synchronization: rtnl_lock() semaphore.
Context: process Context: process
ndo_siocwandev:
Synchronization: rtnl_lock() semaphore.
Context: process
Used by the drivers/net/wan framework to handle
the SIOCWANDEV ioctl with the if_settings structure.
ndo_siocdevprivate: ndo_siocdevprivate:
Synchronization: rtnl_lock() semaphore. Synchronization: rtnl_lock() semaphore.
Context: process Context: process
......
...@@ -4050,16 +4050,15 @@ static int hdlcdev_close(struct net_device *dev) ...@@ -4050,16 +4050,15 @@ static int hdlcdev_close(struct net_device *dev)
* called by network layer to process IOCTL call to network device * called by network layer to process IOCTL call to network device
* *
* dev pointer to network device structure * dev pointer to network device structure
* ifr pointer to network interface request structure * ifs pointer to network interface settings structure
* cmd IOCTL command code
* *
* returns 0 if success, otherwise error code * returns 0 if success, otherwise error code
*/ */
static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int hdlcdev_wan_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
MGSLPC_INFO *info = dev_to_port(dev); MGSLPC_INFO *info = dev_to_port(dev);
unsigned int flags; unsigned int flags;
...@@ -4070,17 +4069,14 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -4070,17 +4069,14 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (info->port.count) if (info->port.count)
return -EBUSY; return -EBUSY;
if (cmd != SIOCWANDEV)
return hdlc_ioctl(dev, ifr, cmd);
memset(&new_line, 0, size); memset(&new_line, 0, size);
switch(ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_IFACE: /* return current sync_serial_settings */ case IF_GET_IFACE: /* return current sync_serial_settings */
ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; ifs->type = IF_IFACE_SYNC_SERIAL;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
...@@ -4148,9 +4144,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -4148,9 +4144,8 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
tty_kref_put(tty); tty_kref_put(tty);
} }
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -4225,7 +4220,7 @@ static const struct net_device_ops hdlcdev_ops = { ...@@ -4225,7 +4220,7 @@ static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open, .ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close, .ndo_stop = hdlcdev_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl, .ndo_siocwandev = hdlcdev_wan_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout, .ndo_tx_timeout = hdlcdev_tx_timeout,
}; };
......
...@@ -228,21 +228,18 @@ static int c101_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -228,21 +228,18 @@ static int c101_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int c101_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
port_t *port = dev_to_port(dev); port_t *port = dev_to_port(dev);
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; ifs->type = IF_IFACE_SYNC_SERIAL;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(line, &port->settings, size)) if (copy_to_user(line, &port->settings, size))
...@@ -270,7 +267,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -270,7 +267,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -295,7 +292,7 @@ static const struct net_device_ops c101_ops = { ...@@ -295,7 +292,7 @@ static const struct net_device_ops c101_ops = {
.ndo_open = c101_open, .ndo_open = c101_open,
.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_siocwandev = c101_ioctl,
.ndo_siocdevprivate = c101_siocdevprivate, .ndo_siocdevprivate = c101_siocdevprivate,
}; };
......
...@@ -414,7 +414,7 @@ static const struct net_device_ops cosa_ops = { ...@@ -414,7 +414,7 @@ static const struct net_device_ops cosa_ops = {
.ndo_open = cosa_net_open, .ndo_open = cosa_net_open,
.ndo_stop = cosa_net_close, .ndo_stop = cosa_net_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlc_ioctl, .ndo_siocwandev = hdlc_ioctl,
.ndo_tx_timeout = cosa_net_timeout, .ndo_tx_timeout = cosa_net_timeout,
}; };
......
...@@ -1784,16 +1784,15 @@ gather_conf_info(struct fst_card_info *card, struct fst_port_info *port, ...@@ -1784,16 +1784,15 @@ gather_conf_info(struct fst_card_info *card, struct fst_port_info *port,
static int static int
fst_set_iface(struct fst_card_info *card, struct fst_port_info *port, fst_set_iface(struct fst_card_info *card, struct fst_port_info *port,
struct ifreq *ifr) struct if_settings *ifs)
{ {
sync_serial_settings sync; sync_serial_settings sync;
int i; int i;
if (ifr->ifr_settings.size != sizeof(sync)) if (ifs->size != sizeof(sync))
return -ENOMEM; return -ENOMEM;
if (copy_from_user if (copy_from_user(&sync, ifs->ifs_ifsu.sync, sizeof(sync)))
(&sync, ifr->ifr_settings.ifs_ifsu.sync, sizeof(sync)))
return -EFAULT; return -EFAULT;
if (sync.loopback) if (sync.loopback)
...@@ -1801,7 +1800,7 @@ fst_set_iface(struct fst_card_info *card, struct fst_port_info *port, ...@@ -1801,7 +1800,7 @@ fst_set_iface(struct fst_card_info *card, struct fst_port_info *port,
i = port->index; i = port->index;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_IFACE_V35: case IF_IFACE_V35:
FST_WRW(card, portConfig[i].lineInterface, V35); FST_WRW(card, portConfig[i].lineInterface, V35);
port->hwif = V35; port->hwif = V35;
...@@ -1857,7 +1856,7 @@ fst_set_iface(struct fst_card_info *card, struct fst_port_info *port, ...@@ -1857,7 +1856,7 @@ fst_set_iface(struct fst_card_info *card, struct fst_port_info *port,
static int static int
fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
struct ifreq *ifr) struct if_settings *ifs)
{ {
sync_serial_settings sync; sync_serial_settings sync;
int i; int i;
...@@ -1868,29 +1867,29 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, ...@@ -1868,29 +1867,29 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
*/ */
switch (port->hwif) { switch (port->hwif) {
case E1: case E1:
ifr->ifr_settings.type = IF_IFACE_E1; ifs->type = IF_IFACE_E1;
break; break;
case T1: case T1:
ifr->ifr_settings.type = IF_IFACE_T1; ifs->type = IF_IFACE_T1;
break; break;
case V35: case V35:
ifr->ifr_settings.type = IF_IFACE_V35; ifs->type = IF_IFACE_V35;
break; break;
case V24: case V24:
ifr->ifr_settings.type = IF_IFACE_V24; ifs->type = IF_IFACE_V24;
break; break;
case X21D: case X21D:
ifr->ifr_settings.type = IF_IFACE_X21D; ifs->type = IF_IFACE_X21D;
break; break;
case X21: case X21:
default: default:
ifr->ifr_settings.type = IF_IFACE_X21; ifs->type = IF_IFACE_X21;
break; break;
} }
if (ifr->ifr_settings.size == 0) if (!ifs->size)
return 0; /* only type requested */ return 0; /* only type requested */
if (ifr->ifr_settings.size < sizeof(sync)) if (ifs->size < sizeof(sync))
return -ENOMEM; return -ENOMEM;
i = port->index; i = port->index;
...@@ -1901,10 +1900,10 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, ...@@ -1901,10 +1900,10 @@ fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
INTCLK ? CLOCK_INT : CLOCK_EXT; INTCLK ? CLOCK_INT : CLOCK_EXT;
sync.loopback = 0; sync.loopback = 0;
if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &sync, sizeof(sync))) if (copy_to_user(ifs->ifs_ifsu.sync, &sync, sizeof(sync)))
return -EFAULT; return -EFAULT;
ifr->ifr_settings.size = sizeof(sync); ifs->size = sizeof(sync);
return 0; return 0;
} }
...@@ -2020,12 +2019,12 @@ fst_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, ...@@ -2020,12 +2019,12 @@ fst_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data,
} }
static int static int
fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) fst_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
struct fst_card_info *card; struct fst_card_info *card;
struct fst_port_info *port; struct fst_port_info *port;
dbg(DBG_IOCTL, "ioctl: %x, %x\n", cmd, ifr->ifr_settings.type); dbg(DBG_IOCTL, "SIOCDEVPRIVATE, %x\n", ifs->type);
port = dev_to_port(dev); port = dev_to_port(dev);
card = port->card; card = port->card;
...@@ -2033,11 +2032,9 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -2033,11 +2032,9 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
switch (cmd) { switch (ifs->type) {
case SIOCWANDEV:
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
return fst_get_iface(card, port, ifr); return fst_get_iface(card, port, ifs);
case IF_IFACE_SYNC_SERIAL: case IF_IFACE_SYNC_SERIAL:
case IF_IFACE_V35: case IF_IFACE_V35:
...@@ -2046,7 +2043,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -2046,7 +2043,7 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case IF_IFACE_X21D: case IF_IFACE_X21D:
case IF_IFACE_T1: case IF_IFACE_T1:
case IF_IFACE_E1: case IF_IFACE_E1:
return fst_set_iface(card, port, ifr); return fst_set_iface(card, port, ifs);
case IF_PROTO_RAW: case IF_PROTO_RAW:
port->mode = FST_RAW; port->mode = FST_RAW;
...@@ -2054,21 +2051,16 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -2054,21 +2051,16 @@ fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
case IF_GET_PROTO: case IF_GET_PROTO:
if (port->mode == FST_RAW) { if (port->mode == FST_RAW) {
ifr->ifr_settings.type = IF_PROTO_RAW; ifs->type = IF_PROTO_RAW;
return 0; return 0;
} }
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
default: default:
port->mode = FST_GEN_HDLC; port->mode = FST_GEN_HDLC;
dbg(DBG_IOCTL, "Passing this type to hdlc %x\n", dbg(DBG_IOCTL, "Passing this type to hdlc %x\n",
ifr->ifr_settings.type); ifs->type);
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
}
default:
/* Not one of ours. Pass through to HDLC package */
return hdlc_ioctl(dev, ifr, cmd);
} }
} }
...@@ -2328,7 +2320,7 @@ static const struct net_device_ops fst_ops = { ...@@ -2328,7 +2320,7 @@ static const struct net_device_ops fst_ops = {
.ndo_open = fst_open, .ndo_open = fst_open,
.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_siocwandev = fst_ioctl,
.ndo_siocdevprivate = fst_siocdevprivate, .ndo_siocdevprivate = fst_siocdevprivate,
.ndo_tx_timeout = fst_tx_timeout, .ndo_tx_timeout = fst_tx_timeout,
}; };
......
...@@ -674,31 +674,28 @@ static irqreturn_t ucc_hdlc_irq_handler(int irq, void *dev_id) ...@@ -674,31 +674,28 @@ static irqreturn_t ucc_hdlc_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int uhdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int uhdlc_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(te1_settings); const size_t size = sizeof(te1_settings);
te1_settings line; te1_settings line;
struct ucc_hdlc_private *priv = netdev_priv(dev); struct ucc_hdlc_private *priv = netdev_priv(dev);
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_E1; ifs->type = IF_IFACE_E1;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
line.clock_type = priv->clocking; line.clock_type = priv->clocking;
if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size)) if (copy_to_user(ifs->ifs_ifsu.sync, &line, size))
return -EFAULT; return -EFAULT;
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -1053,7 +1050,7 @@ static const struct net_device_ops uhdlc_ops = { ...@@ -1053,7 +1050,7 @@ static const struct net_device_ops uhdlc_ops = {
.ndo_open = uhdlc_open, .ndo_open = uhdlc_open,
.ndo_stop = uhdlc_close, .ndo_stop = uhdlc_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = uhdlc_ioctl, .ndo_siocwandev = uhdlc_ioctl,
.ndo_tx_timeout = uhdlc_tx_timeout, .ndo_tx_timeout = uhdlc_tx_timeout,
}; };
......
...@@ -196,16 +196,13 @@ void hdlc_close(struct net_device *dev) ...@@ -196,16 +196,13 @@ void hdlc_close(struct net_device *dev)
} }
EXPORT_SYMBOL(hdlc_close); EXPORT_SYMBOL(hdlc_close);
int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
struct hdlc_proto *proto = first_proto; struct hdlc_proto *proto = first_proto;
int result; int result;
if (cmd != SIOCWANDEV)
return -EINVAL;
if (dev_to_hdlc(dev)->proto) { if (dev_to_hdlc(dev)->proto) {
result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); result = dev_to_hdlc(dev)->proto->ioctl(dev, ifs);
if (result != -EINVAL) if (result != -EINVAL)
return result; return result;
} }
...@@ -213,7 +210,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -213,7 +210,7 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* Not handled by currently attached protocol (if any) */ /* Not handled by currently attached protocol (if any) */
while (proto) { while (proto) {
result = proto->ioctl(dev, ifr); result = proto->ioctl(dev, ifs);
if (result != -EINVAL) if (result != -EINVAL)
return result; return result;
proto = proto->next; proto = proto->next;
......
...@@ -56,7 +56,7 @@ struct cisco_state { ...@@ -56,7 +56,7 @@ struct cisco_state {
u32 rxseq; /* RX sequence number */ u32 rxseq; /* RX sequence number */
}; };
static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr); static int cisco_ioctl(struct net_device *dev, struct if_settings *ifs);
static inline struct cisco_state *state(hdlc_device *hdlc) static inline struct cisco_state *state(hdlc_device *hdlc)
{ {
...@@ -306,21 +306,21 @@ static const struct header_ops cisco_header_ops = { ...@@ -306,21 +306,21 @@ static const struct header_ops cisco_header_ops = {
.create = cisco_hard_header, .create = cisco_hard_header,
}; };
static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) static int cisco_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; cisco_proto __user *cisco_s = ifs->ifs_ifsu.cisco;
const size_t size = sizeof(cisco_proto); const size_t size = sizeof(cisco_proto);
cisco_proto new_settings; cisco_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_CISCO; ifs->type = IF_PROTO_CISCO;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(cisco_s, &state(hdlc)->settings, size)) if (copy_to_user(cisco_s, &state(hdlc)->settings, size))
......
...@@ -146,7 +146,7 @@ struct frad_state { ...@@ -146,7 +146,7 @@ struct frad_state {
u8 rxseq; /* RX sequence number */ u8 rxseq; /* RX sequence number */
}; };
static int fr_ioctl(struct net_device *dev, struct ifreq *ifr); static int fr_ioctl(struct net_device *dev, struct if_settings *ifs);
static inline u16 q922_to_dlci(u8 *hdr) static inline u16 q922_to_dlci(u8 *hdr)
{ {
...@@ -357,29 +357,26 @@ static int pvc_close(struct net_device *dev) ...@@ -357,29 +357,26 @@ static int pvc_close(struct net_device *dev)
return 0; return 0;
} }
static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int pvc_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
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) if (ifs->type == IF_GET_PROTO) {
return -EOPNOTSUPP;
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; ifs->type = IF_PROTO_FR_ETH_PVC;
else else
ifr->ifr_settings.type = IF_PROTO_FR_PVC; ifs->type = IF_PROTO_FR_PVC;
if (ifr->ifr_settings.size < sizeof(info)) { if (ifs->size < sizeof(info)) {
/* data size wanted */ /* data size wanted */
ifr->ifr_settings.size = sizeof(info); ifs->size = sizeof(info);
return -ENOBUFS; return -ENOBUFS;
} }
info.dlci = pvc->dlci; info.dlci = pvc->dlci;
memcpy(info.master, pvc->frad->name, IFNAMSIZ); memcpy(info.master, pvc->frad->name, IFNAMSIZ);
if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, if (copy_to_user(ifs->ifs_ifsu.fr_pvc_info,
&info, sizeof(info))) &info, sizeof(info)))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -1059,7 +1056,7 @@ static const struct net_device_ops pvc_ops = { ...@@ -1059,7 +1056,7 @@ static const struct net_device_ops pvc_ops = {
.ndo_open = pvc_open, .ndo_open = pvc_open,
.ndo_stop = pvc_close, .ndo_stop = pvc_close,
.ndo_start_xmit = pvc_xmit, .ndo_start_xmit = pvc_xmit,
.ndo_do_ioctl = pvc_ioctl, .ndo_siocwandev = pvc_ioctl,
}; };
static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
...@@ -1182,22 +1179,22 @@ static struct hdlc_proto proto = { ...@@ -1182,22 +1179,22 @@ static struct hdlc_proto proto = {
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) static int fr_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; fr_proto __user *fr_s = ifs->ifs_ifsu.fr;
const size_t size = sizeof(fr_proto); const size_t size = sizeof(fr_proto);
fr_proto new_settings; fr_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
fr_proto_pvc pvc; fr_proto_pvc pvc;
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_FR; ifs->type = IF_PROTO_FR;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(fr_s, &state(hdlc)->settings, size)) if (copy_to_user(fr_s, &state(hdlc)->settings, size))
...@@ -1259,21 +1256,21 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -1259,21 +1256,21 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc, if (copy_from_user(&pvc, ifs->ifs_ifsu.fr_pvc,
sizeof(fr_proto_pvc))) sizeof(fr_proto_pvc)))
return -EFAULT; return -EFAULT;
if (pvc.dlci <= 0 || pvc.dlci >= 1024) if (pvc.dlci <= 0 || pvc.dlci >= 1024)
return -EINVAL; /* Only 10 bits, DLCI 0 reserved */ return -EINVAL; /* Only 10 bits, DLCI 0 reserved */
if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC || if (ifs->type == IF_PROTO_FR_ADD_ETH_PVC ||
ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC) ifs->type == IF_PROTO_FR_DEL_ETH_PVC)
result = ARPHRD_ETHER; /* bridged Ethernet device */ result = ARPHRD_ETHER; /* bridged Ethernet device */
else else
result = ARPHRD_DLCI; result = ARPHRD_DLCI;
if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC || if (ifs->type == IF_PROTO_FR_ADD_PVC ||
ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC) ifs->type == IF_PROTO_FR_ADD_ETH_PVC)
return fr_add_pvc(dev, pvc.dlci, result); return fr_add_pvc(dev, pvc.dlci, result);
else else
return fr_del_pvc(hdlc, pvc.dlci, result); return fr_del_pvc(hdlc, pvc.dlci, result);
......
...@@ -100,7 +100,7 @@ static const char *const event_names[EVENTS] = { ...@@ -100,7 +100,7 @@ static const char *const event_names[EVENTS] = {
static struct sk_buff_head tx_queue; /* used when holding the spin lock */ static struct sk_buff_head tx_queue; /* used when holding the spin lock */
static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr); static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs);
static inline struct ppp *get_ppp(struct net_device *dev) static inline struct ppp *get_ppp(struct net_device *dev)
{ {
...@@ -655,17 +655,17 @@ static const struct header_ops ppp_header_ops = { ...@@ -655,17 +655,17 @@ static const struct header_ops ppp_header_ops = {
.create = ppp_hard_header, .create = ppp_hard_header,
}; };
static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
struct ppp *ppp; struct ppp *ppp;
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_PPP; ifs->type = IF_PROTO_PPP;
return 0; /* return protocol only, no settable parameters */ return 0; /* return protocol only, no settable parameters */
case IF_PROTO_PPP: case IF_PROTO_PPP:
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); static int raw_ioctl(struct net_device *dev, struct if_settings *ifs);
static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
{ {
...@@ -33,21 +33,21 @@ static struct hdlc_proto proto = { ...@@ -33,21 +33,21 @@ static struct hdlc_proto proto = {
}; };
static int raw_ioctl(struct net_device *dev, struct ifreq *ifr) static int raw_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; raw_hdlc_proto __user *raw_s = ifs->ifs_ifsu.raw_hdlc;
const size_t size = sizeof(raw_hdlc_proto); const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings; raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_HDLC; ifs->type = IF_PROTO_HDLC;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(raw_s, hdlc->state, size)) if (copy_to_user(raw_s, hdlc->state, size))
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs);
static netdev_tx_t eth_tx(struct sk_buff *skb, struct net_device *dev) static netdev_tx_t eth_tx(struct sk_buff *skb, struct net_device *dev)
{ {
...@@ -48,22 +48,22 @@ static struct hdlc_proto proto = { ...@@ -48,22 +48,22 @@ static struct hdlc_proto proto = {
}; };
static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; raw_hdlc_proto __user *raw_s = ifs->ifs_ifsu.raw_hdlc;
const size_t size = sizeof(raw_hdlc_proto); const size_t size = sizeof(raw_hdlc_proto);
raw_hdlc_proto new_settings; raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
unsigned int old_qlen; unsigned int old_qlen;
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; ifs->type = IF_PROTO_HDLC_ETH;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(raw_s, hdlc->state, size)) if (copy_to_user(raw_s, hdlc->state, size))
......
...@@ -29,7 +29,7 @@ struct x25_state { ...@@ -29,7 +29,7 @@ struct x25_state {
struct tasklet_struct rx_tasklet; struct tasklet_struct rx_tasklet;
}; };
static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); static int x25_ioctl(struct net_device *dev, struct if_settings *ifs);
static struct x25_state *state(hdlc_device *hdlc) static struct x25_state *state(hdlc_device *hdlc)
{ {
...@@ -274,21 +274,21 @@ static struct hdlc_proto proto = { ...@@ -274,21 +274,21 @@ static struct hdlc_proto proto = {
.module = THIS_MODULE, .module = THIS_MODULE,
}; };
static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) static int x25_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
x25_hdlc_proto __user *x25_s = ifr->ifr_settings.ifs_ifsu.x25; x25_hdlc_proto __user *x25_s = ifs->ifs_ifsu.x25;
const size_t size = sizeof(x25_hdlc_proto); const size_t size = sizeof(x25_hdlc_proto);
hdlc_device *hdlc = dev_to_hdlc(dev); hdlc_device *hdlc = dev_to_hdlc(dev);
x25_hdlc_proto new_settings; x25_hdlc_proto new_settings;
int result; int result;
switch (ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_PROTO: case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL; return -EINVAL;
ifr->ifr_settings.type = IF_PROTO_X25; ifs->type = IF_PROTO_X25;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(x25_s, &state(hdlc)->settings, size)) if (copy_to_user(x25_s, &state(hdlc)->settings, size))
...@@ -303,7 +303,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) ...@@ -303,7 +303,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
return -EBUSY; return -EBUSY;
/* backward compatibility */ /* backward compatibility */
if (ifr->ifr_settings.size == 0) { if (ifs->size == 0) {
new_settings.dce = 0; new_settings.dce = 0;
new_settings.modulo = 8; new_settings.modulo = 8;
new_settings.window = 7; new_settings.window = 7;
......
...@@ -142,11 +142,6 @@ static int hostess_close(struct net_device *d) ...@@ -142,11 +142,6 @@ static int hostess_close(struct net_device *d)
return 0; return 0;
} }
static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
{
return hdlc_ioctl(d, ifr, cmd);
}
/* Passed network frames, fire them downwind. /* Passed network frames, fire them downwind.
*/ */
...@@ -171,7 +166,7 @@ static const struct net_device_ops hostess_ops = { ...@@ -171,7 +166,7 @@ static const struct net_device_ops hostess_ops = {
.ndo_open = hostess_open, .ndo_open = hostess_open,
.ndo_stop = hostess_close, .ndo_stop = hostess_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hostess_ioctl, .ndo_siocwandev = hdlc_ioctl,
}; };
static struct z8530_dev *sv11_init(int iobase, int irq) static struct z8530_dev *sv11_init(int iobase, int irq)
......
...@@ -1254,23 +1254,20 @@ static void find_best_clock(u32 timer_freq, u32 rate, u32 *best, u32 *reg) ...@@ -1254,23 +1254,20 @@ static void find_best_clock(u32 timer_freq, u32 rate, u32 *best, u32 *reg)
} }
} }
static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int hss_hdlc_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
struct port *port = dev_to_port(dev); struct port *port = dev_to_port(dev);
unsigned long flags; unsigned long flags;
int clk; int clk;
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_V35; ifs->type = IF_IFACE_V35;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
memset(&new_line, 0, sizeof(new_line)); memset(&new_line, 0, sizeof(new_line));
...@@ -1323,7 +1320,7 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1323,7 +1320,7 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -1335,7 +1332,7 @@ static const struct net_device_ops hss_hdlc_ops = { ...@@ -1335,7 +1332,7 @@ static const struct net_device_ops hss_hdlc_ops = {
.ndo_open = hss_hdlc_open, .ndo_open = hss_hdlc_open,
.ndo_stop = hss_hdlc_close, .ndo_stop = hss_hdlc_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hss_hdlc_ioctl, .ndo_siocwandev = hss_hdlc_ioctl,
}; };
static int hss_init_one(struct platform_device *pdev) static int hss_init_one(struct platform_device *pdev)
......
...@@ -19,7 +19,7 @@ void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned); ...@@ -19,7 +19,7 @@ void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned);
void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits); void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits);
void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits); void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits);
int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int lmc_ioctl(struct net_device *dev, struct if_settings *ifs);
extern lmc_media_t lmc_ds3_media; extern lmc_media_t lmc_ds3_media;
extern lmc_media_t lmc_ssi_media; extern lmc_media_t lmc_ssi_media;
......
...@@ -616,14 +616,6 @@ static int lmc_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -616,14 +616,6 @@ static int lmc_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
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*/
...@@ -794,7 +786,7 @@ static const struct net_device_ops lmc_ops = { ...@@ -794,7 +786,7 @@ static const struct net_device_ops lmc_ops = {
.ndo_open = lmc_open, .ndo_open = lmc_open,
.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_siocwandev = hdlc_ioctl,
.ndo_siocdevprivate = lmc_siocdevprivate, .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,
......
...@@ -58,13 +58,6 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/ ...@@ -58,13 +58,6 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
} }
} }
int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd)
{
if (sc->if_type == LMC_PPP)
return hdlc_ioctl(sc->lmc_device, ifr, cmd);
return -EOPNOTSUPP;
}
int lmc_proto_open(lmc_softc_t *sc) int lmc_proto_open(lmc_softc_t *sc)
{ {
int ret = 0; int ret = 0;
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include <linux/hdlc.h> #include <linux/hdlc.h>
void lmc_proto_attach(lmc_softc_t *sc); void lmc_proto_attach(lmc_softc_t *sc);
int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd);
int lmc_proto_open(lmc_softc_t *sc); int lmc_proto_open(lmc_softc_t *sc);
void lmc_proto_close(lmc_softc_t *sc); void lmc_proto_close(lmc_softc_t *sc);
__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb); __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
......
...@@ -239,21 +239,18 @@ static int n2_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -239,21 +239,18 @@ static int n2_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int n2_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
port_t *port = dev_to_port(dev); port_t *port = dev_to_port(dev);
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; ifs->type = IF_IFACE_SYNC_SERIAL;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(line, &port->settings, size)) if (copy_to_user(line, &port->settings, size))
...@@ -281,7 +278,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -281,7 +278,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -317,7 +314,7 @@ static const struct net_device_ops n2_ops = { ...@@ -317,7 +314,7 @@ static const struct net_device_ops n2_ops = {
.ndo_open = n2_open, .ndo_open = n2_open,
.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_siocwandev = n2_ioctl,
.ndo_siocdevprivate = n2_siocdevprivate, .ndo_siocdevprivate = n2_siocdevprivate,
}; };
......
...@@ -186,21 +186,18 @@ static int pc300_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -186,21 +186,18 @@ static int pc300_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int pc300_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
int new_type; int new_type;
port_t *port = dev_to_port(dev); port_t *port = dev_to_port(dev);
if (cmd != SIOCWANDEV) if (ifs->type == IF_GET_IFACE) {
return hdlc_ioctl(dev, ifr, cmd); ifs->type = port->iface;
if (ifs->size < size) {
if (ifr->ifr_settings.type == IF_GET_IFACE) { ifs->size = size; /* data size wanted */
ifr->ifr_settings.type = port->iface;
if (ifr->ifr_settings.size < size) {
ifr->ifr_settings.size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(line, &port->settings, size)) if (copy_to_user(line, &port->settings, size))
...@@ -209,21 +206,21 @@ static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -209,21 +206,21 @@ static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
} }
if (port->card->type == PC300_X21 && if (port->card->type == PC300_X21 &&
(ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || (ifs->type == IF_IFACE_SYNC_SERIAL ||
ifr->ifr_settings.type == IF_IFACE_X21)) ifs->type == IF_IFACE_X21))
new_type = IF_IFACE_X21; new_type = IF_IFACE_X21;
else if (port->card->type == PC300_RSV && else if (port->card->type == PC300_RSV &&
(ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || (ifs->type == IF_IFACE_SYNC_SERIAL ||
ifr->ifr_settings.type == IF_IFACE_V35)) ifs->type == IF_IFACE_V35))
new_type = IF_IFACE_V35; new_type = IF_IFACE_V35;
else if (port->card->type == PC300_RSV && else if (port->card->type == PC300_RSV &&
ifr->ifr_settings.type == IF_IFACE_V24) ifs->type == IF_IFACE_V24)
new_type = IF_IFACE_V24; new_type = IF_IFACE_V24;
else else
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
if (!capable(CAP_NET_ADMIN)) if (!capable(CAP_NET_ADMIN))
return -EPERM; return -EPERM;
...@@ -278,7 +275,7 @@ static const struct net_device_ops pc300_ops = { ...@@ -278,7 +275,7 @@ static const struct net_device_ops pc300_ops = {
.ndo_open = pc300_open, .ndo_open = pc300_open,
.ndo_stop = pc300_close, .ndo_stop = pc300_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pc300_ioctl, .ndo_siocwandev = pc300_ioctl,
.ndo_siocdevprivate = pc300_siocdevprivate, .ndo_siocdevprivate = pc300_siocdevprivate,
}; };
......
...@@ -179,21 +179,18 @@ static int pci200_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -179,21 +179,18 @@ static int pci200_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int pci200_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
port_t *port = dev_to_port(dev); port_t *port = dev_to_port(dev);
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_V35; ifs->type = IF_IFACE_V35;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
if (copy_to_user(line, &port->settings, size)) if (copy_to_user(line, &port->settings, size))
...@@ -223,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -223,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -259,7 +256,7 @@ static const struct net_device_ops pci200_ops = { ...@@ -259,7 +256,7 @@ static const struct net_device_ops pci200_ops = {
.ndo_open = pci200_open, .ndo_open = pci200_open,
.ndo_stop = pci200_close, .ndo_stop = pci200_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = pci200_ioctl, .ndo_siocwandev = pci200_ioctl,
.ndo_siocdevprivate = pci200_siocdevprivate, .ndo_siocdevprivate = pci200_siocdevprivate,
}; };
......
...@@ -124,14 +124,6 @@ static int sealevel_close(struct net_device *d) ...@@ -124,14 +124,6 @@ static int sealevel_close(struct net_device *d)
return 0; return 0;
} }
static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
{
/* struct slvl_device *slvl=dev_to_chan(d);
* z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd)
*/
return hdlc_ioctl(d, ifr, cmd);
}
/* Passed network frames, fire them downwind. */ /* Passed network frames, fire them downwind. */
static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb, static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb,
...@@ -152,7 +144,7 @@ static const struct net_device_ops sealevel_ops = { ...@@ -152,7 +144,7 @@ static const struct net_device_ops sealevel_ops = {
.ndo_open = sealevel_open, .ndo_open = sealevel_open,
.ndo_stop = sealevel_close, .ndo_stop = sealevel_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = sealevel_ioctl, .ndo_siocwandev = hdlc_ioctl,
}; };
static int slvl_setup(struct slvl_device *sv, int iobase, int irq) static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
......
...@@ -343,20 +343,17 @@ static int wanxl_attach(struct net_device *dev, unsigned short encoding, ...@@ -343,20 +343,17 @@ static int wanxl_attach(struct net_device *dev, unsigned short encoding,
return 0; return 0;
} }
static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int wanxl_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings line; sync_serial_settings line;
struct port *port = dev_to_port(dev); struct port *port = dev_to_port(dev);
if (cmd != SIOCWANDEV) switch (ifs->type) {
return hdlc_ioctl(dev, ifr, cmd);
switch (ifr->ifr_settings.type) {
case IF_GET_IFACE: case IF_GET_IFACE:
ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; ifs->type = IF_IFACE_SYNC_SERIAL;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
memset(&line, 0, sizeof(line)); memset(&line, 0, sizeof(line));
...@@ -364,7 +361,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -364,7 +361,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
line.clock_rate = 0; line.clock_rate = 0;
line.loopback = 0; line.loopback = 0;
if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size)) if (copy_to_user(ifs->ifs_ifsu.sync, &line, size))
return -EFAULT; return -EFAULT;
return 0; return 0;
...@@ -374,7 +371,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -374,7 +371,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (dev->flags & IFF_UP) if (dev->flags & IFF_UP)
return -EBUSY; return -EBUSY;
if (copy_from_user(&line, ifr->ifr_settings.ifs_ifsu.sync, if (copy_from_user(&line, ifs->ifs_ifsu.sync,
size)) size))
return -EFAULT; return -EFAULT;
...@@ -389,7 +386,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -389,7 +386,7 @@ static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -545,7 +542,7 @@ static const struct net_device_ops wanxl_ops = { ...@@ -545,7 +542,7 @@ static const struct net_device_ops wanxl_ops = {
.ndo_open = wanxl_open, .ndo_open = wanxl_open,
.ndo_stop = wanxl_close, .ndo_stop = wanxl_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = wanxl_ioctl, .ndo_siocwandev = wanxl_ioctl,
.ndo_get_stats = wanxl_get_stats, .ndo_get_stats = wanxl_get_stats,
}; };
......
...@@ -1524,11 +1524,11 @@ static int hdlcdev_close(struct net_device *dev) ...@@ -1524,11 +1524,11 @@ static int hdlcdev_close(struct net_device *dev)
* *
* Return: 0 if success, otherwise error code * Return: 0 if success, otherwise error code
*/ */
static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int hdlcdev_ioctl(struct net_device *dev, struct if_settings *ifs)
{ {
const size_t size = sizeof(sync_serial_settings); const size_t size = sizeof(sync_serial_settings);
sync_serial_settings new_line; sync_serial_settings new_line;
sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; sync_serial_settings __user *line = ifs->ifs_ifsu.sync;
struct slgt_info *info = dev_to_port(dev); struct slgt_info *info = dev_to_port(dev);
unsigned int flags; unsigned int flags;
...@@ -1538,17 +1538,14 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1538,17 +1538,14 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (info->port.count) if (info->port.count)
return -EBUSY; return -EBUSY;
if (cmd != SIOCWANDEV)
return hdlc_ioctl(dev, ifr, cmd);
memset(&new_line, 0, sizeof(new_line)); memset(&new_line, 0, sizeof(new_line));
switch(ifr->ifr_settings.type) { switch (ifs->type) {
case IF_GET_IFACE: /* return current sync_serial_settings */ case IF_GET_IFACE: /* return current sync_serial_settings */
ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; ifs->type = IF_IFACE_SYNC_SERIAL;
if (ifr->ifr_settings.size < size) { if (ifs->size < size) {
ifr->ifr_settings.size = size; /* data size wanted */ ifs->size = size; /* data size wanted */
return -ENOBUFS; return -ENOBUFS;
} }
...@@ -1615,7 +1612,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1615,7 +1612,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return 0; return 0;
default: default:
return hdlc_ioctl(dev, ifr, cmd); return hdlc_ioctl(dev, ifs);
} }
} }
...@@ -1688,7 +1685,7 @@ static const struct net_device_ops hdlcdev_ops = { ...@@ -1688,7 +1685,7 @@ static const struct net_device_ops hdlcdev_ops = {
.ndo_open = hdlcdev_open, .ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close, .ndo_stop = hdlcdev_close,
.ndo_start_xmit = hdlc_start_xmit, .ndo_start_xmit = hdlc_start_xmit,
.ndo_do_ioctl = hdlcdev_ioctl, .ndo_siocwandev = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout, .ndo_tx_timeout = hdlcdev_tx_timeout,
}; };
......
...@@ -22,7 +22,7 @@ struct hdlc_proto { ...@@ -22,7 +22,7 @@ struct hdlc_proto {
void (*start)(struct net_device *dev); /* if open & DCD */ void (*start)(struct net_device *dev); /* if open & DCD */
void (*stop)(struct net_device *dev); /* if open & !DCD */ void (*stop)(struct net_device *dev); /* if open & !DCD */
void (*detach)(struct net_device *dev); void (*detach)(struct net_device *dev);
int (*ioctl)(struct net_device *dev, struct ifreq *ifr); int (*ioctl)(struct net_device *dev, struct if_settings *ifs);
__be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev); __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
int (*netif_rx)(struct sk_buff *skb); int (*netif_rx)(struct sk_buff *skb);
netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev); netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
...@@ -54,7 +54,7 @@ typedef struct hdlc_device { ...@@ -54,7 +54,7 @@ typedef struct hdlc_device {
/* Exported from hdlc module */ /* Exported from hdlc module */
/* Called by hardware driver when a user requests HDLC service */ /* Called by hardware driver when a user requests HDLC service */
int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs);
/* Must be used by hardware driver on module startup/exit */ /* Must be used by hardware driver on module startup/exit */
#define register_hdlc_device(dev) register_netdev(dev) #define register_hdlc_device(dev) register_netdev(dev)
......
...@@ -1367,6 +1367,8 @@ struct net_device_ops { ...@@ -1367,6 +1367,8 @@ struct net_device_ops {
struct ifreq *ifr, int cmd); struct ifreq *ifr, int cmd);
int (*ndo_eth_ioctl)(struct net_device *dev, int (*ndo_eth_ioctl)(struct net_device *dev,
struct ifreq *ifr, int cmd); struct ifreq *ifr, int cmd);
int (*ndo_siocwandev)(struct net_device *dev,
struct if_settings *ifs);
int (*ndo_siocdevprivate)(struct net_device *dev, int (*ndo_siocdevprivate)(struct net_device *dev,
struct ifreq *ifr, struct ifreq *ifr,
void __user *data, int cmd); void __user *data, int cmd);
......
...@@ -291,6 +291,20 @@ static int dev_siocdevprivate(struct net_device *dev, struct ifreq *ifr, ...@@ -291,6 +291,20 @@ static int dev_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
return dev_do_ioctl(dev, ifr, cmd); return dev_do_ioctl(dev, ifr, cmd);
} }
static int dev_siocwandev(struct net_device *dev, struct if_settings *ifs)
{
const struct net_device_ops *ops = dev->netdev_ops;
if (ops->ndo_siocwandev) {
if (netif_device_present(dev))
return ops->ndo_siocwandev(dev, ifs);
else
return -ENODEV;
}
return -EOPNOTSUPP;
}
/* /*
* Perform the SIOCxIFxxx calls, inside rtnl_lock() * Perform the SIOCxIFxxx calls, inside rtnl_lock()
*/ */
...@@ -359,6 +373,9 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, ...@@ -359,6 +373,9 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
ifr->ifr_newname[IFNAMSIZ-1] = '\0'; ifr->ifr_newname[IFNAMSIZ-1] = '\0';
return dev_change_name(dev, ifr->ifr_newname); return dev_change_name(dev, ifr->ifr_newname);
case SIOCWANDEV:
return dev_siocwandev(dev, &ifr->ifr_settings);
case SIOCSHWTSTAMP: case SIOCSHWTSTAMP:
err = net_hwtstamp_validate(ifr); err = net_hwtstamp_validate(ifr);
if (err) if (err)
...@@ -386,8 +403,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data, ...@@ -386,8 +403,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, void __user *data,
cmd == SIOCBONDINFOQUERY || cmd == SIOCBONDINFOQUERY ||
cmd == SIOCBONDCHANGEACTIVE || cmd == SIOCBONDCHANGEACTIVE ||
cmd == SIOCBRADDIF || cmd == SIOCBRADDIF ||
cmd == SIOCBRDELIF || cmd == SIOCBRDELIF) {
cmd == SIOCWANDEV) {
err = dev_do_ioctl(dev, ifr, cmd); err = dev_do_ioctl(dev, ifr, cmd);
} else } else
err = -EINVAL; err = -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment