patch-pre2.0.4 linux/drivers/net/dlci.c
Next file: linux/drivers/scsi/scsi.c
Previous file: linux/drivers/net/Space.c
Back to the patch index
Back to the overall index
- Lines: 411
- Date:
Mon May 13 23:23:07 1996
- Orig file:
pre2.0.3/linux/drivers/net/dlci.c
- Orig date:
Tue May 7 16:22:27 1996
diff -u --recursive --new-file pre2.0.3/linux/drivers/net/dlci.c linux/drivers/net/dlci.c
@@ -5,7 +5,7 @@
* interfaces. Requires 'dlcicfg' program to create usable
* interfaces, the initial one, 'dlci' is for IOCTL use only.
*
- * Version: @(#)dlci.c 0.20 13 Apr 1996
+ * Version: @(#)dlci.c 0.25 13 May 1996
*
* Author: Mike McLagan <mike.mclagan@linux.org>
*
@@ -20,6 +20,8 @@
* returned from the FRAD, the packet is
* sent back to Linux for re-transmission
*
+ * 0.25 Mike McLagan Converted to use SIOC IOCTL calls
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
@@ -52,7 +54,7 @@
#include <net/sock.h>
static const char *devname = "dlci";
-static const char *version = "DLCI driver v0.20, 13 Apr 1996, mike.mclagan@linux.org";
+static const char *version = "DLCI driver v0.25, 13 May 1996, mike.mclagan@linux.org";
static struct device *open_dev[CONFIG_DLCI_COUNT];
@@ -277,135 +279,6 @@
return(ret);
}
-int dlci_add(struct dlci_add *new)
-{
- struct device *master, *slave;
- struct dlci_local *dlp;
- struct frad_local *flp;
- struct dlci_add dlci;
- int err, i;
- char buf[10];
-
- err = verify_area(VERIFY_WRITE, new, sizeof(*new));
- if (err)
- return(err);
-
- memcpy_fromfs(&dlci, new, sizeof(dlci));
-
- /* validate slave device */
- slave = dev_get(dlci.devname);
- if (!slave)
- return(-ENODEV);
-
- if (slave->type != ARPHRD_FRAD)
- return(-EINVAL);
-
- /* check for registration */
- for (i=0;i<sizeof(basename) / sizeof(char *); i++)
- if ((basename[i]) &&
- (strncmp(dlci.devname, basename[i], strlen(basename[i])) == 0) &&
- (strlen(dlci.devname) > strlen(basename[i])))
- break;
-
- if (i == sizeof(basename) / sizeof(char *))
- return(-EINVAL);
-
- /* check for too many open devices : should this be dynamic ? */
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (!open_dev[i])
- break;
-
- if (i == CONFIG_DLCI_COUNT)
- return(-ENOSPC); /* #### Alan: Comments on this?? */
-
- /* create device name */
- sprintf(buf, "%s%02i", devname, i);
-
- master = kmalloc(sizeof(*master), GFP_KERNEL);
- if (!master)
- return(-ENOMEM);
-
- memset(master, 0, sizeof(*master));
- master->name = kmalloc(strlen(buf) + 1, GFP_KERNEL);
-
- if (!master->name)
- {
- kfree(master);
- return(-ENOMEM);
- }
-
- strcpy(master->name, buf);
- master->init = dlci_init;
- master->flags = 0;
-
- err = register_netdev(master);
- if (err < 0)
- {
- kfree(master->name);
- kfree(master);
- return(err);
- }
-
- *(short *)(master->dev_addr) = dlci.dlci;
-
- dlp = (struct dlci_local *) master->priv;
- dlp->slave = slave;
-
- flp = slave->priv;
- err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
- if (err < 0)
- {
- unregister_netdev(master);
- kfree(master->priv);
- kfree(master->name);
- kfree(master);
- return(err);
- }
-
- memcpy_tofs(new->devname, buf, strlen(buf) + 1);
- open_dev[i] = master;
-
- MOD_INC_USE_COUNT;
-
- return(0);
-}
-
-int dlci_del(struct device *master)
-{
- struct dlci_local *dlp;
- struct frad_local *flp;
- struct device *slave;
- int i, err;
-
- if (master->start)
- return(-EBUSY);
-
- dlp = master->priv;
- slave = dlp->slave;
- flp = slave->priv;
-
- err = (*flp->deassoc)(slave, master);
- if (err)
- return(err);
-
- unregister_netdev(master);
-
- for(i=0;i<CONFIG_DLCI_COUNT;i++)
- if (master == open_dev[i])
- break;
-
- if (i<CONFIG_DLCI_COUNT)
- open_dev[i] = NULL;
-
- kfree(master->priv);
- kfree(master->name);
- kfree(master);
-
- MOD_DEC_USE_COUNT;
-
- return(0);
-}
-
int dlci_config(struct device *dev, struct dlci_conf *conf, int get)
{
struct dlci_conf config;
@@ -446,9 +319,10 @@
return(0);
}
-int dlci_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
+int dlci_dev_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
{
struct dlci_local *dlp;
+ int err, len;
if (!suser())
return(-EPERM);
@@ -461,26 +335,12 @@
if (!*(short *)(dev->dev_addr))
return(-EINVAL);
- strcpy(ifr->ifr_slave, dlp->slave->name);
- break;
-
- case DLCI_DEVADD:
- /* can only add on the primary device */
- if (*(short *)(dev->dev_addr))
- return(-EINVAL);
-
- return(dlci_add((struct dlci_add *) ifr->ifr_data));
- break;
-
- case DLCI_DEVDEL:
- /* can't delete the primary device */
- if (!*(short *)(dev->dev_addr))
- return(-EINVAL);
-
- if (dev->start)
- return(-EBUSY);
+ len = strlen(dlp->slave->name) + 1;
+ err = verify_area(VERIFY_WRITE, ifr->ifr_slave, len);
+ if (err)
+ return err;
- return(dlci_del(dev));
+ memcpy_tofs(ifr->ifr_slave, dlp->slave->name, len);
break;
case DLCI_GET_CONF:
@@ -559,6 +419,169 @@
return(&dlp->stats);
}
+int dlci_add(struct dlci_add *dlci)
+{
+ struct device *master, *slave;
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ int err, i;
+ char buf[10];
+
+ /* validate slave device */
+ slave = dev_get(dlci->devname);
+ if (!slave)
+ return(-ENODEV);
+
+ if (slave->type != ARPHRD_FRAD)
+ return(-EINVAL);
+
+ /* check for registration */
+ for (i=0;i<sizeof(basename) / sizeof(char *); i++)
+ if ((basename[i]) &&
+ (strncmp(dlci->devname, basename[i], strlen(basename[i])) == 0) &&
+ (strlen(dlci->devname) > strlen(basename[i])))
+ break;
+
+ if (i == sizeof(basename) / sizeof(char *))
+ return(-EINVAL);
+
+ /* check for too many open devices : should this be dynamic ? */
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ if (!open_dev[i])
+ break;
+
+ if (i == CONFIG_DLCI_COUNT)
+ return(-ENOSPC); /* #### Alan: Comments on this?? */
+
+ /* create device name */
+ sprintf(buf, "%s%02i", devname, i);
+
+ master = kmalloc(sizeof(*master), GFP_KERNEL);
+ if (!master)
+ return(-ENOMEM);
+
+ memset(master, 0, sizeof(*master));
+ master->name = kmalloc(strlen(buf) + 1, GFP_KERNEL);
+
+ if (!master->name)
+ {
+ kfree(master);
+ return(-ENOMEM);
+ }
+
+ strcpy(master->name, buf);
+ master->init = dlci_init;
+ master->flags = 0;
+
+ err = register_netdev(master);
+ if (err < 0)
+ {
+ kfree(master->name);
+ kfree(master);
+ return(err);
+ }
+
+ *(short *)(master->dev_addr) = dlci->dlci;
+
+ dlp = (struct dlci_local *) master->priv;
+ dlp->slave = slave;
+
+ flp = slave->priv;
+ err = flp ? (*flp->assoc)(slave, master) : -EINVAL;
+ if (err < 0)
+ {
+ unregister_netdev(master);
+ kfree(master->priv);
+ kfree(master->name);
+ kfree(master);
+ return(err);
+ }
+
+ strcpy(dlci->devname, buf);
+ open_dev[i] = master;
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+int dlci_del(struct dlci_add *dlci)
+{
+ struct dlci_local *dlp;
+ struct frad_local *flp;
+ struct device *master, *slave;
+ int i, err;
+
+ /* validate slave device */
+ master = dev_get(dlci->devname);
+ if (!master)
+ return(-ENODEV);
+
+ if (master->start)
+ return(-EBUSY);
+
+ dlp = master->priv;
+ slave = dlp->slave;
+ flp = slave->priv;
+
+ err = (*flp->deassoc)(slave, master);
+ if (err)
+ return(err);
+
+ unregister_netdev(master);
+
+ for(i=0;i<CONFIG_DLCI_COUNT;i++)
+ if (master == open_dev[i])
+ break;
+
+ if (i<CONFIG_DLCI_COUNT)
+ open_dev[i] = NULL;
+
+ kfree(master->priv);
+ kfree(master->name);
+ kfree(master);
+
+ MOD_DEC_USE_COUNT;
+
+ return(0);
+}
+
+int dlci_ioctl(unsigned int cmd, void *arg)
+{
+ int err;
+ struct dlci_add add;
+
+ if (!suser())
+ return(-EPERM);
+
+ err=verify_area(VERIFY_READ, arg, sizeof(struct dlci_add));
+ if (err)
+ return(err);
+
+ memcpy_fromfs(&add, arg, sizeof(struct dlci_add));
+
+ switch (cmd)
+ {
+ case SIOCADDDLCI:
+ err = verify_area(VERIFY_WRITE, arg, sizeof(struct dlci_add));
+ if (err)
+ return(err);
+
+ err = dlci_add(&add);
+
+ if (!err)
+ memcpy_tofs(arg, &add, sizeof(struct dlci_add));
+ break;
+
+ case SIOCDELDLCI:
+ err = dlci_del(&add);
+ break;
+
+ default:
+ err = -EINVAL;
+ }
+
+ return(err);
+}
+
int dlci_init(struct device *dev)
{
struct dlci_local *dlp;
@@ -574,7 +597,7 @@
dev->flags = 0;
dev->open = dlci_open;
dev->stop = dlci_close;
- dev->do_ioctl = dlci_ioctl;
+ dev->do_ioctl = dlci_dev_ioctl;
dev->hard_start_xmit = dlci_transmit;
dev->hard_header = dlci_header;
dev->get_stats = dlci_get_stats;
@@ -622,18 +645,18 @@
}
#ifdef MODULE
-static struct device dlci = {"dlci", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, dlci_init, };
+
+extern int (*dlci_ioctl_hook)(unsigned int, void *);
int init_module(void)
{
- dlci_setup();
- return(register_netdev(&dlci));
+ dlci_ioctl_hook = dlci_ioctl;
+
+ return(dlci_setup());
}
void cleanup_module(void)
{
- unregister_netdev(&dlci);
- if (dlci.priv)
- kfree(dlci.priv);
+ dlci_ioctl_hook = NULL;
}
#endif /* MODULE */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this