Commit 71041520 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Clean up creating ISDN net devices

parent e991a288
......@@ -1267,10 +1267,9 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
int ret;
int i;
char *p;
char *s;
union iocpar {
char name[10];
char bname[22];
char bname[20];
isdn_ioctl_struct iocts;
isdn_net_ioctl_phone phone;
isdn_net_ioctl_cfg cfg;
......@@ -1298,42 +1297,24 @@ isdn_ctrl_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
#ifdef CONFIG_NETDEVICES
case IIOCNETAIF:
/* Add a network-interface */
if (arg) {
if (copy_from_user(name, (char *) arg, sizeof(name)))
if (copy_from_user(name, (char *) arg, sizeof(name) - 1))
return -EFAULT;
s = name;
} else {
s = NULL;
}
name[sizeof(name)-1] = 0;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
if ((s = isdn_net_new(s, NULL))) {
if (copy_to_user((char *) arg, s, strlen(s) + 1)){
ret = -EFAULT;
} else {
ret = 0;
}
} else
ret = -ENODEV;
if (ret)
return ret;
ret = isdn_net_new(name, NULL);
up(&dev->sem);
return ret;
case IIOCNETASL:
/* Add a slave to a network-interface */
if (arg) {
if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1))
return -EFAULT;
} else
return -EINVAL;
bname[sizeof(bname)-1] = 0;
ret = down_interruptible(&dev->sem);
if( ret ) return ret;
if ((s = isdn_net_newslave(bname))) {
if (copy_to_user((char *) arg, s, strlen(s) + 1)){
ret = -EFAULT;
} else {
ret = 0;
}
} else
ret = -ENODEV;
if (ret)
return ret;
ret = isdn_net_newslave(bname);
up(&dev->sem);
return ret;
case IIOCNETDIF:
......
......@@ -2579,26 +2579,24 @@ isdn_net_force_dial(char *name)
/*
* Allocate a new network-interface and initialize its data structures.
*/
char *
int
isdn_net_new(char *name, struct net_device *master)
{
int retval;
isdn_net_dev *netdev;
/* Avoid creating an existing interface */
if (isdn_net_findif(name)) {
printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
return NULL;
return -EEXIST;
}
if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
if (!(netdev = kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
return NULL;
return -ENOMEM;
}
memset(netdev, 0, sizeof(isdn_net_dev));
if (name == NULL)
strcpy(netdev->local.name, " ");
else
strcpy(netdev->local.name, name);
strcpy(netdev->dev.name, netdev->local.name);
strcpy(netdev->dev.name, name);
netdev->dev.priv = &netdev->local;
netdev->dev.init = isdn_net_init;
netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP;
......@@ -2621,10 +2619,11 @@ isdn_net_new(char *name, struct net_device *master)
*/
netdev->dev.tx_timeout = isdn_net_tx_timeout;
netdev->dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT;
if (register_netdev(&netdev->dev) != 0) {
retval = register_netdev(&netdev->dev);
if (retval) {
printk(KERN_WARNING "isdn_net: Could not register net-device\n");
kfree(netdev);
return NULL;
return retval;
}
}
netdev->local.magic = ISDN_NET_MAGIC;
......@@ -2665,34 +2664,31 @@ isdn_net_new(char *name, struct net_device *master)
/* Put into to netdev-chain */
list_add(&netdev->global_list, &isdn_net_devs);
return netdev->dev.name;
return 0;
}
char *
int
isdn_net_newslave(char *parm)
{
char *p = strchr(parm, ',');
isdn_net_dev *n;
char newname[10];
isdn_net_dev *m;
if (p) {
/* Slave-Name MUST not be empty */
if (!strlen(p + 1))
return NULL;
strcpy(newname, p + 1);
if (!p || !p[1])
return -EINVAL;
*p = 0;
/* Master must already exist */
if (!(n = isdn_net_findif(parm)))
return NULL;
if (!(m = isdn_net_findif(parm)))
return -ESRCH;
/* Master must be a real interface, not a slave */
if (n->local.master)
return NULL;
if (m->local.master)
return -ENXIO;
/* Master must not be started yet */
if (isdn_net_device_started(n))
return NULL;
return (isdn_net_new(newname, &(n->dev)));
}
return NULL;
if (isdn_net_device_started(m))
return -EBUSY;
return isdn_net_new(p+1, &m->dev);
}
/*
......
......@@ -31,8 +31,8 @@
#define CISCO_SLARP_REPLY 1
#define CISCO_SLARP_KEEPALIVE 2
extern char *isdn_net_new(char *, struct net_device *);
extern char *isdn_net_newslave(char *);
extern int isdn_net_new(char *, struct net_device *);
extern int isdn_net_newslave(char *);
extern int isdn_net_rm(char *);
extern int isdn_net_rmall(void);
extern int isdn_net_stat_callback(int, isdn_ctrl *);
......
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