patch-2.4.0-test6 linux/drivers/net/pcmcia/ray_cs.c

Next file: linux/drivers/net/pppoe.c
Previous file: linux/drivers/net/pcmcia/com20020_cs.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/drivers/net/pcmcia/ray_cs.c linux/drivers/net/pcmcia/ray_cs.c
@@ -19,6 +19,12 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
+ * - reorganize kmallocs in ray_attach, checking all for failure
+ *   and releasing the previous allocations if one fails
+ *
  * 
 =============================================================================*/
 
@@ -333,7 +339,25 @@
 
     /* Initialize the dev_link_t structure */
     link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+
+    if (!link)
+	    return NULL;
+
+    /* Allocate space for private device-specific data */
+    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+
+    if (!dev)
+	    goto fail_alloc_dev;
+
+    local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
+
+    if (!local)
+	    goto fail_alloc_local;
+
     memset(link, 0, sizeof(struct dev_link_t));
+    memset(dev, 0, sizeof(struct net_device));
+    memset(local, 0, sizeof(ray_dev_t));
+
     link->release.function = &ray_release;
     link->release.data = (u_long)link;
 
@@ -355,14 +379,9 @@
     link->conf.ConfigIndex = 1;
     link->conf.Present = PRESENT_OPTION;
 
-    /* Allocate space for private device-specific data */
-    dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-    memset(dev, 0, sizeof(struct net_device));
     link->priv = dev;
     link->irq.Instance = dev;
     
-    local = kmalloc(sizeof(ray_dev_t), GFP_KERNEL);
-    memset(local, 0, sizeof(ray_dev_t));
     dev->priv = local;
     local->finder = link;
     link->dev = &local->node;
@@ -385,7 +404,6 @@
 
     DEBUG(2,"ray_cs ray_attach calling ether_setup.)\n");
     ether_setup(dev);
-    strcpy(dev->name, local->node.dev_name);
     dev->init = &ray_dev_init;
     dev->open = &ray_open;
     dev->stop = &ray_dev_close;
@@ -417,6 +435,12 @@
     }
     DEBUG(2,"ray_cs ray_attach ending\n");
     return link;
+
+fail_alloc_local:
+    kfree(dev);
+fail_alloc_dev:
+    kfree(link);
+    return NULL;
 } /* ray_attach */
 /*=============================================================================
     This deletes a driver "instance".  The device is de-registered
@@ -581,6 +605,8 @@
         return;
     }
 
+    strcpy(local->node.dev_name, dev->name);
+
     link->state &= ~DEV_CONFIG_PENDING;
     printk(KERN_INFO "%s: RayLink, irq %d, hw_addr ",
        dev->name, dev->irq);
@@ -2663,7 +2689,7 @@
 } /* End build_auth_frame */
 
 /*===========================================================================*/
-
+#ifdef CONFIG_PROC_FS
 static void raycs_write(const char *name, write_proc_t *w, void *data)
 {
 	struct proc_dir_entry * entry = create_proc_entry(name, S_IFREG | S_IWUSR, NULL);
@@ -2713,6 +2739,7 @@
 	*(int *)data = nr;
 	return count;
 }
+#endif
 
 static int __init init_ray_cs(void)
 {
@@ -2722,12 +2749,14 @@
     rc = register_pcmcia_driver(&dev_info, &ray_attach, &ray_detach);
     DEBUG(1, "raylink init_module register_pcmcia_driver returns 0x%x\n",rc);
 
+#ifdef CONFIG_PROC_FS
     proc_mkdir("driver/ray_cs", 0);
 
-    create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, ray_cs_proc_read);
+    create_proc_info_entry("driver/ray_cs/ray_cs", 0, NULL, &ray_cs_proc_read);
     raycs_write("driver/ray_cs/essid", write_essid, NULL);
     raycs_write("driver/ray_cs/net_type", write_int, &net_type);
     raycs_write("driver/ray_cs/translate", write_int, &translate);
+#endif
     if (translate != 0) translate = 1;
     return 0;
 } /* init_ray_cs */
@@ -2739,17 +2768,22 @@
     DEBUG(0, "ray_cs: cleanup_module\n");
 
 
+#ifdef CONFIG_PROC_FS
     remove_proc_entry("ray_cs", proc_root_driver);
+#endif
+
     unregister_pcmcia_driver(&dev_info);
     while (dev_list != NULL) {
         if (dev_list->state & DEV_CONFIG) ray_release((u_long)dev_list);
         ray_detach(dev_list);
     }
+#ifdef CONFIG_PROC_FS
     remove_proc_entry("driver/ray_cs/ray_cs", NULL);
     remove_proc_entry("driver/ray_cs/essid", NULL);
     remove_proc_entry("driver/ray_cs/net_type", NULL);
     remove_proc_entry("driver/ray_cs/translate", NULL);
     remove_proc_entry("driver/ray_cs", NULL);
+#endif
 } /* exit_ray_cs */
 
 module_init(init_ray_cs);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)