Synchronization: rtnl_lock() semaphore.
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:
Synchronization: rtnl_lock() semaphore.
Context: process
* called by network layer to process IOCTL call to network device
*
* dev pointer to network device structure
- * ifr pointer to network interface request structure
- * cmd IOCTL command code
+ * ifs pointer to network interface settings structure
*
* 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);
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);
unsigned int flags;
if (info->port.count)
return -EBUSY;
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
memset(&new_line, 0, size);
- switch(ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE: /* return current sync_serial_settings */
- ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_SYNC_SERIAL;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
tty_kref_put(tty);
}
return 0;
-
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_siocwandev = hdlcdev_wan_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
};
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);
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);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_SYNC_SERIAL;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(line, &port->settings, size))
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = c101_open,
.ndo_stop = c101_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = c101_ioctl,
+ .ndo_siocwandev = c101_ioctl,
.ndo_siocdevprivate = c101_siocdevprivate,
};
.ndo_open = cosa_net_open,
.ndo_stop = cosa_net_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = hdlc_ioctl,
+ .ndo_siocwandev = hdlc_ioctl,
.ndo_tx_timeout = cosa_net_timeout,
};
static int
fst_set_iface(struct fst_card_info *card, struct fst_port_info *port,
- struct ifreq *ifr)
+ struct if_settings *ifs)
{
sync_serial_settings sync;
int i;
- if (ifr->ifr_settings.size != sizeof(sync))
+ if (ifs->size != sizeof(sync))
return -ENOMEM;
- if (copy_from_user
- (&sync, ifr->ifr_settings.ifs_ifsu.sync, sizeof(sync)))
+ if (copy_from_user(&sync, ifs->ifs_ifsu.sync, sizeof(sync)))
return -EFAULT;
if (sync.loopback)
i = port->index;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_IFACE_V35:
FST_WRW(card, portConfig[i].lineInterface, V35);
port->hwif = V35;
static int
fst_get_iface(struct fst_card_info *card, struct fst_port_info *port,
- struct ifreq *ifr)
+ struct if_settings *ifs)
{
sync_serial_settings sync;
int i;
*/
switch (port->hwif) {
case E1:
- ifr->ifr_settings.type = IF_IFACE_E1;
+ ifs->type = IF_IFACE_E1;
break;
case T1:
- ifr->ifr_settings.type = IF_IFACE_T1;
+ ifs->type = IF_IFACE_T1;
break;
case V35:
- ifr->ifr_settings.type = IF_IFACE_V35;
+ ifs->type = IF_IFACE_V35;
break;
case V24:
- ifr->ifr_settings.type = IF_IFACE_V24;
+ ifs->type = IF_IFACE_V24;
break;
case X21D:
- ifr->ifr_settings.type = IF_IFACE_X21D;
+ ifs->type = IF_IFACE_X21D;
break;
case X21:
default:
- ifr->ifr_settings.type = IF_IFACE_X21;
+ ifs->type = IF_IFACE_X21;
break;
}
- if (ifr->ifr_settings.size == 0)
+ if (!ifs->size)
return 0; /* only type requested */
- if (ifr->ifr_settings.size < sizeof(sync))
+ if (ifs->size < sizeof(sync))
return -ENOMEM;
i = port->index;
INTCLK ? CLOCK_INT : CLOCK_EXT;
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;
- ifr->ifr_settings.size = sizeof(sync);
+ ifs->size = sizeof(sync);
return 0;
}
}
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_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);
card = port->card;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- switch (cmd) {
- case SIOCWANDEV:
- switch (ifr->ifr_settings.type) {
- case IF_GET_IFACE:
- return fst_get_iface(card, port, ifr);
-
- case IF_IFACE_SYNC_SERIAL:
- case IF_IFACE_V35:
- case IF_IFACE_V24:
- case IF_IFACE_X21:
- case IF_IFACE_X21D:
- case IF_IFACE_T1:
- case IF_IFACE_E1:
- return fst_set_iface(card, port, ifr);
-
- case IF_PROTO_RAW:
- port->mode = FST_RAW;
- return 0;
+ switch (ifs->type) {
+ case IF_GET_IFACE:
+ return fst_get_iface(card, port, ifs);
- case IF_GET_PROTO:
- if (port->mode == FST_RAW) {
- ifr->ifr_settings.type = IF_PROTO_RAW;
- return 0;
- }
- return hdlc_ioctl(dev, ifr, cmd);
+ case IF_IFACE_SYNC_SERIAL:
+ case IF_IFACE_V35:
+ case IF_IFACE_V24:
+ case IF_IFACE_X21:
+ case IF_IFACE_X21D:
+ case IF_IFACE_T1:
+ case IF_IFACE_E1:
+ return fst_set_iface(card, port, ifs);
- default:
- port->mode = FST_GEN_HDLC;
- dbg(DBG_IOCTL, "Passing this type to hdlc %x\n",
- ifr->ifr_settings.type);
- return hdlc_ioctl(dev, ifr, cmd);
+ case IF_PROTO_RAW:
+ port->mode = FST_RAW;
+ return 0;
+
+ case IF_GET_PROTO:
+ if (port->mode == FST_RAW) {
+ ifs->type = IF_PROTO_RAW;
+ return 0;
}
+ return hdlc_ioctl(dev, ifs);
default:
- /* Not one of ours. Pass through to HDLC package */
- return hdlc_ioctl(dev, ifr, cmd);
+ port->mode = FST_GEN_HDLC;
+ dbg(DBG_IOCTL, "Passing this type to hdlc %x\n",
+ ifs->type);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = fst_open,
.ndo_stop = fst_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = fst_ioctl,
+ .ndo_siocwandev = fst_ioctl,
.ndo_siocdevprivate = fst_siocdevprivate,
.ndo_tx_timeout = fst_tx_timeout,
};
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);
te1_settings line;
struct ucc_hdlc_private *priv = netdev_priv(dev);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_E1;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_E1;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
memset(&line, 0, sizeof(line));
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 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = uhdlc_open,
.ndo_stop = uhdlc_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = uhdlc_ioctl,
+ .ndo_siocwandev = uhdlc_ioctl,
.ndo_tx_timeout = uhdlc_tx_timeout,
};
}
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;
int result;
- if (cmd != SIOCWANDEV)
- return -EINVAL;
-
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)
return result;
}
/* Not handled by currently attached protocol (if any) */
while (proto) {
- result = proto->ioctl(dev, ifr);
+ result = proto->ioctl(dev, ifs);
if (result != -EINVAL)
return result;
proto = proto->next;
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)
{
.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);
cisco_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_CISCO;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_PROTO_CISCO;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(cisco_s, &state(hdlc)->settings, size))
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)
{
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;
fr_proto_pvc_info info;
- if (cmd != SIOCWANDEV)
- return -EOPNOTSUPP;
-
- if (ifr->ifr_settings.type == IF_GET_PROTO) {
+ if (ifs->type == IF_GET_PROTO) {
if (dev->type == ARPHRD_ETHER)
- ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
+ ifs->type = IF_PROTO_FR_ETH_PVC;
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 */
- ifr->ifr_settings.size = sizeof(info);
+ ifs->size = sizeof(info);
return -ENOBUFS;
}
info.dlci = pvc->dlci;
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)))
return -EFAULT;
return 0;
.ndo_open = pvc_open,
.ndo_stop = pvc_close,
.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)
.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);
fr_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
fr_proto_pvc pvc;
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_FR;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_PROTO_FR;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(fr_s, &state(hdlc)->settings, size))
if (!capable(CAP_NET_ADMIN))
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)))
return -EFAULT;
if (pvc.dlci <= 0 || pvc.dlci >= 1024)
return -EINVAL; /* Only 10 bits, DLCI 0 reserved */
- if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC ||
- ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC)
+ if (ifs->type == IF_PROTO_FR_ADD_ETH_PVC ||
+ ifs->type == IF_PROTO_FR_DEL_ETH_PVC)
result = ARPHRD_ETHER; /* bridged Ethernet device */
else
result = ARPHRD_DLCI;
- if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC ||
- ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC)
+ if (ifs->type == IF_PROTO_FR_ADD_PVC ||
+ ifs->type == IF_PROTO_FR_ADD_ETH_PVC)
return fr_add_pvc(dev, pvc.dlci, result);
else
return fr_del_pvc(hdlc, pvc.dlci, result);
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)
{
.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);
struct ppp *ppp;
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_PPP;
+ ifs->type = IF_PROTO_PPP;
return 0; /* return protocol only, no settable parameters */
case IF_PROTO_PPP:
#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 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);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_HDLC;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_PROTO_HDLC;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(raw_s, hdlc->state, size))
#include <linux/rtnetlink.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 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);
raw_hdlc_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
unsigned int old_qlen;
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_HDLC_ETH;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_PROTO_HDLC_ETH;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(raw_s, hdlc->state, size))
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)
{
.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);
hdlc_device *hdlc = dev_to_hdlc(dev);
x25_hdlc_proto new_settings;
int result;
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_PROTO:
if (dev_to_hdlc(dev)->proto != &proto)
return -EINVAL;
- ifr->ifr_settings.type = IF_PROTO_X25;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_PROTO_X25;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(x25_s, &state(hdlc)->settings, size))
return -EBUSY;
/* backward compatibility */
- if (ifr->ifr_settings.size == 0) {
+ if (ifs->size == 0) {
new_settings.dce = 0;
new_settings.modulo = 8;
new_settings.window = 7;
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.
*/
.ndo_open = hostess_open,
.ndo_stop = hostess_close,
.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 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);
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);
unsigned long flags;
int clk;
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_V35;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_V35;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
memset(&new_line, 0, sizeof(new_line));
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = hss_hdlc_open,
.ndo_stop = hss_hdlc_close,
.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)
void lmc_gpio_mkinput(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_ssi_media;
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*/
.ndo_open = lmc_open,
.ndo_stop = lmc_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = lmc_ioctl,
+ .ndo_siocwandev = hdlc_ioctl,
.ndo_siocdevprivate = lmc_siocdevprivate,
.ndo_tx_timeout = lmc_driver_timeout,
.ndo_get_stats = lmc_get_stats,
}
}
-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 ret = 0;
#include <linux/hdlc.h>
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);
void lmc_proto_close(lmc_softc_t *sc);
__be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
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);
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);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_SYNC_SERIAL;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(line, &port->settings, size))
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = n2_open,
.ndo_stop = n2_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = n2_ioctl,
+ .ndo_siocwandev = n2_ioctl,
.ndo_siocdevprivate = n2_siocdevprivate,
};
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);
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;
port_t *port = dev_to_port(dev);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- if (ifr->ifr_settings.type == IF_GET_IFACE) {
- ifr->ifr_settings.type = port->iface;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ if (ifs->type == IF_GET_IFACE) {
+ ifs->type = port->iface;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(line, &port->settings, size))
}
if (port->card->type == PC300_X21 &&
- (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL ||
- ifr->ifr_settings.type == IF_IFACE_X21))
+ (ifs->type == IF_IFACE_SYNC_SERIAL ||
+ ifs->type == IF_IFACE_X21))
new_type = IF_IFACE_X21;
else if (port->card->type == PC300_RSV &&
- (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL ||
- ifr->ifr_settings.type == IF_IFACE_V35))
+ (ifs->type == IF_IFACE_SYNC_SERIAL ||
+ ifs->type == IF_IFACE_V35))
new_type = IF_IFACE_V35;
else if (port->card->type == PC300_RSV &&
- ifr->ifr_settings.type == IF_IFACE_V24)
+ ifs->type == IF_IFACE_V24)
new_type = IF_IFACE_V24;
else
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
.ndo_open = pc300_open,
.ndo_stop = pc300_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = pc300_ioctl,
+ .ndo_siocwandev = pc300_ioctl,
.ndo_siocdevprivate = pc300_siocdevprivate,
};
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);
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);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_V35;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_V35;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
if (copy_to_user(line, &port->settings, size))
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = pci200_open,
.ndo_stop = pci200_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = pci200_ioctl,
+ .ndo_siocwandev = pci200_ioctl,
.ndo_siocdevprivate = pci200_siocdevprivate,
};
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. */
static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb,
.ndo_open = sealevel_open,
.ndo_stop = sealevel_close,
.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)
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);
sync_serial_settings line;
struct port *port = dev_to_port(dev);
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
- switch (ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE:
- ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_SYNC_SERIAL;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
memset(&line, 0, sizeof(line));
line.clock_rate = 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 0;
if (dev->flags & IFF_UP)
return -EBUSY;
- if (copy_from_user(&line, ifr->ifr_settings.ifs_ifsu.sync,
+ if (copy_from_user(&line, ifs->ifs_ifsu.sync,
size))
return -EFAULT;
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = wanxl_open,
.ndo_stop = wanxl_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = wanxl_ioctl,
+ .ndo_siocwandev = wanxl_ioctl,
.ndo_get_stats = wanxl_get_stats,
};
*
* 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);
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);
unsigned int flags;
if (info->port.count)
return -EBUSY;
- if (cmd != SIOCWANDEV)
- return hdlc_ioctl(dev, ifr, cmd);
-
memset(&new_line, 0, sizeof(new_line));
- switch(ifr->ifr_settings.type) {
+ switch (ifs->type) {
case IF_GET_IFACE: /* return current sync_serial_settings */
- ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL;
- if (ifr->ifr_settings.size < size) {
- ifr->ifr_settings.size = size; /* data size wanted */
+ ifs->type = IF_IFACE_SYNC_SERIAL;
+ if (ifs->size < size) {
+ ifs->size = size; /* data size wanted */
return -ENOBUFS;
}
return 0;
default:
- return hdlc_ioctl(dev, ifr, cmd);
+ return hdlc_ioctl(dev, ifs);
}
}
.ndo_open = hdlcdev_open,
.ndo_stop = hdlcdev_close,
.ndo_start_xmit = hdlc_start_xmit,
- .ndo_do_ioctl = hdlcdev_ioctl,
+ .ndo_siocwandev = hdlcdev_ioctl,
.ndo_tx_timeout = hdlcdev_tx_timeout,
};
void (*start)(struct net_device *dev); /* if open & DCD */
void (*stop)(struct net_device *dev); /* if open & !DCD */
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);
int (*netif_rx)(struct sk_buff *skb);
netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
/* Exported from hdlc module */
/* 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 */
#define register_hdlc_device(dev) register_netdev(dev)
struct ifreq *ifr, int cmd);
int (*ndo_eth_ioctl)(struct net_device *dev,
struct ifreq *ifr, int cmd);
+ int (*ndo_siocwandev)(struct net_device *dev,
+ struct if_settings *ifs);
int (*ndo_siocdevprivate)(struct net_device *dev,
struct ifreq *ifr,
void __user *data, int 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()
*/
ifr->ifr_newname[IFNAMSIZ-1] = '\0';
return dev_change_name(dev, ifr->ifr_newname);
+ case SIOCWANDEV:
+ return dev_siocwandev(dev, &ifr->ifr_settings);
+
case SIOCSHWTSTAMP:
err = net_hwtstamp_validate(ifr);
if (err)
cmd == SIOCBONDINFOQUERY ||
cmd == SIOCBONDCHANGEACTIVE ||
cmd == SIOCBRADDIF ||
- cmd == SIOCBRDELIF ||
- cmd == SIOCWANDEV) {
+ cmd == SIOCBRDELIF) {
err = dev_do_ioctl(dev, ifr, cmd);
} else
err = -EINVAL;