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

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