| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Linux ARCnet driver - COM20020 PCMCIA support | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Written 1994-1999 by Avery Pennarun, | 
					
						
							|  |  |  |  *    based on an ISA version by David Woodhouse. | 
					
						
							|  |  |  |  * Derived from ibmtr_cs.c by Steve Kipisz (pcmcia-cs 3.1.4) | 
					
						
							|  |  |  |  *    which was derived from pcnet_cs.c by David Hinds. | 
					
						
							|  |  |  |  * Some additional portions derived from skeleton.c by Donald Becker. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com) | 
					
						
							|  |  |  |  *  for sponsoring the further development of this driver. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ********************** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The original copyright of skeleton.c was as follows: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * skeleton.c Written 1993 by Donald Becker. | 
					
						
							|  |  |  |  * Copyright 1993 United States Government as represented by the | 
					
						
							|  |  |  |  * Director, National Security Agency.  This software may only be used | 
					
						
							|  |  |  |  * and distributed according to the terms of the GNU General Public License as | 
					
						
							|  |  |  |  * modified by SRC, incorporated herein by reference. | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * ********************** | 
					
						
							|  |  |  |  * Changes: | 
					
						
							|  |  |  |  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000 | 
					
						
							|  |  |  |  * - reorganize kmallocs in com20020_attach, checking all for failure | 
					
						
							|  |  |  |  *   and releasing the previous allocations if one fails | 
					
						
							|  |  |  |  * ********************** | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * For more details, see drivers/net/arcnet.c | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ********************** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <linux/kernel.h>
 | 
					
						
							|  |  |  | #include <linux/init.h>
 | 
					
						
							|  |  |  | #include <linux/ptrace.h>
 | 
					
						
							|  |  |  | #include <linux/slab.h>
 | 
					
						
							|  |  |  | #include <linux/string.h>
 | 
					
						
							|  |  |  | #include <linux/timer.h>
 | 
					
						
							|  |  |  | #include <linux/delay.h>
 | 
					
						
							|  |  |  | #include <linux/module.h>
 | 
					
						
							|  |  |  | #include <linux/netdevice.h>
 | 
					
						
							|  |  |  | #include <linux/arcdevice.h>
 | 
					
						
							|  |  |  | #include <linux/com20020.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <pcmcia/cistpl.h>
 | 
					
						
							|  |  |  | #include <pcmcia/ds.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <asm/io.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void regdump(struct net_device *dev) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     int ioaddr = dev->base_addr; | 
					
						
							|  |  |  |     int count; | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  |     netdev_dbg(dev, "register dump:\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     for (count = ioaddr; count < ioaddr + 16; count++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	if (!(count % 16)) | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  | 	    pr_cont("%04X:", count); | 
					
						
							|  |  |  | 	pr_cont(" %02X", inb(count)); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  |     pr_cont("\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  |     netdev_dbg(dev, "buffer0 dump:\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	/* set up the address register */ | 
					
						
							|  |  |  |         count = 0; | 
					
						
							|  |  |  | 	outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI); | 
					
						
							|  |  |  | 	outb(count & 0xff, _ADDR_LO); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     for (count = 0; count < 256+32; count++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	if (!(count % 16)) | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  | 	    pr_cont("%04X:", count); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* copy the data */ | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  | 	pr_cont(" %02X", inb(_MEMDATA)); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  |     pr_cont("\n"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*====================================================================*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Parameters that can be set with 'insmod' */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int node; | 
					
						
							|  |  |  | static int timeout = 3; | 
					
						
							|  |  |  | static int backplane; | 
					
						
							|  |  |  | static int clockp; | 
					
						
							|  |  |  | static int clockm; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module_param(node, int, 0); | 
					
						
							|  |  |  | module_param(timeout, int, 0); | 
					
						
							|  |  |  | module_param(backplane, int, 0); | 
					
						
							|  |  |  | module_param(clockp, int, 0); | 
					
						
							|  |  |  | module_param(clockm, int, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MODULE_LICENSE("GPL"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*====================================================================*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  | static int com20020_config(struct pcmcia_device *link); | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | static void com20020_release(struct pcmcia_device *link); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-14 21:23:14 +01:00
										 |  |  | static void com20020_detach(struct pcmcia_device *p_dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*====================================================================*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct com20020_dev_t { | 
					
						
							|  |  |  |     struct net_device       *dev; | 
					
						
							|  |  |  | } com20020_dev_t; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  | static int com20020_probe(struct pcmcia_device *p_dev) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     com20020_dev_t *info; | 
					
						
							|  |  |  |     struct net_device *dev; | 
					
						
							|  |  |  |     struct arcnet_local *lp; | 
					
						
							| 
									
										
										
										
											2005-11-14 21:25:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&p_dev->dev, "com20020_attach()\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Create new network device */ | 
					
						
							| 
									
										
											  
											
												some kmalloc/memset ->kzalloc (tree wide)
Transform some calls to kmalloc/memset to a single kzalloc (or kcalloc).
Here is a short excerpt of the semantic patch performing
this transformation:
@@
type T2;
expression x;
identifier f,fld;
expression E;
expression E1,E2;
expression e1,e2,e3,y;
statement S;
@@
 x =
- kmalloc
+ kzalloc
  (E1,E2)
  ...  when != \(x->fld=E;\|y=f(...,x,...);\|f(...,x,...);\|x=E;\|while(...) S\|for(e1;e2;e3) S\)
- memset((T2)x,0,E1);
@@
expression E1,E2,E3;
@@
- kzalloc(E1 * E2,E3)
+ kcalloc(E1,E2,E3)
[akpm@linux-foundation.org: get kcalloc args the right way around]
Signed-off-by: Yoann Padioleau <padator@wanadoo.fr>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Acked-by: Russell King <rmk@arm.linux.org.uk>
Cc: Bryan Wu <bryan.wu@analog.com>
Acked-by: Jiri Slaby <jirislaby@gmail.com>
Cc: Dave Airlie <airlied@linux.ie>
Acked-by: Roland Dreier <rolandd@cisco.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Acked-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Acked-by: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: Jeff Garzik <jeff@garzik.org>
Cc: "David S. Miller" <davem@davemloft.net>
Acked-by: Greg KH <greg@kroah.com>
Cc: James Bottomley <James.Bottomley@steeleye.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
											
										 
											2007-07-19 01:49:03 -07:00
										 |  |  |     info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     if (!info) | 
					
						
							|  |  |  | 	goto fail_alloc_info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dev = alloc_arcdev(""); | 
					
						
							|  |  |  |     if (!dev) | 
					
						
							|  |  |  | 	goto fail_alloc_dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-12 23:38:14 -08:00
										 |  |  |     lp = netdev_priv(dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     lp->timeout = timeout; | 
					
						
							|  |  |  |     lp->backplane = backplane; | 
					
						
							|  |  |  |     lp->clockp = clockp; | 
					
						
							|  |  |  |     lp->clockm = clockm & 3; | 
					
						
							|  |  |  |     lp->hw.owner = THIS_MODULE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* fill in our module parameters as defaults */ | 
					
						
							|  |  |  |     dev->dev_addr[0] = node; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-24 17:23:51 +02:00
										 |  |  |     p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | 
					
						
							|  |  |  |     p_dev->resource[0]->end = 16; | 
					
						
							| 
									
										
										
										
											2010-07-29 19:27:09 +02:00
										 |  |  |     p_dev->config_flags |= CONF_ENABLE_IRQ; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 17:24:46 +01:00
										 |  |  |     info->dev = dev; | 
					
						
							| 
									
										
										
										
											2006-03-05 10:45:09 +01:00
										 |  |  |     p_dev->priv = info; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  |     return com20020_config(p_dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | fail_alloc_dev: | 
					
						
							|  |  |  |     kfree(info); | 
					
						
							|  |  |  | fail_alloc_info: | 
					
						
							| 
									
										
										
										
											2005-11-14 21:25:51 +01:00
										 |  |  |     return -ENOMEM; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } /* com20020_attach */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | static void com20020_detach(struct pcmcia_device *link) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     struct com20020_dev_t *info = link->priv; | 
					
						
							| 
									
										
										
										
											2005-11-14 21:25:35 +01:00
										 |  |  |     struct net_device *dev = info->dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "detach...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "com20020_detach\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-20 19:39:26 +01:00
										 |  |  |     dev_dbg(&link->dev, "unregister...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-20 19:39:26 +01:00
										 |  |  |     unregister_netdev(dev); | 
					
						
							| 
									
										
										
										
											2005-11-14 21:25:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-20 19:39:26 +01:00
										 |  |  |     /*
 | 
					
						
							|  |  |  |      * this is necessary because we register our IRQ separately | 
					
						
							|  |  |  |      * from card services. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     if (dev->irq) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	    free_irq(dev->irq, dev); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-02 00:09:29 +01:00
										 |  |  |     com20020_release(link); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* Unlink device structure, free bits */ | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "unlinking...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     if (link->priv) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	dev = info->dev; | 
					
						
							|  |  |  | 	if (dev) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  | 	    dev_dbg(&link->dev, "kfree...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	    free_netdev(dev); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  | 	dev_dbg(&link->dev, "kfree2...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	kfree(info); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } /* com20020_detach */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  | static int com20020_config(struct pcmcia_device *link) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							|  |  |  |     struct arcnet_local *lp; | 
					
						
							|  |  |  |     com20020_dev_t *info; | 
					
						
							|  |  |  |     struct net_device *dev; | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     int i, ret; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     int ioaddr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     info = link->priv; | 
					
						
							|  |  |  |     dev = info->dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "config...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "com20020_config\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-24 17:23:51 +02:00
										 |  |  |     dev_dbg(&link->dev, "baseport1 is %Xh\n", | 
					
						
							|  |  |  | 	    (unsigned int) link->resource[0]->start); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-03 10:07:45 +02:00
										 |  |  |     i = -ENODEV; | 
					
						
							| 
									
										
										
										
											2010-07-24 17:23:51 +02:00
										 |  |  |     link->io_lines = 16; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!link->resource[0]->start) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     { | 
					
						
							|  |  |  | 	for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2010-07-24 17:23:51 +02:00
										 |  |  | 	    link->resource[0]->start = ioaddr; | 
					
						
							|  |  |  | 	    i = pcmcia_request_io(link); | 
					
						
							| 
									
										
										
										
											2008-08-03 10:07:45 +02:00
										 |  |  | 	    if (i == 0) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2010-07-24 17:23:51 +02:00
										 |  |  | 	i = pcmcia_request_io(link); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2008-08-03 10:07:45 +02:00
										 |  |  |     if (i != 0) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  | 	dev_dbg(&link->dev, "requestIO failed totally!\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	goto failed; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-07-24 15:58:54 +02:00
										 |  |  |     ioaddr = dev->base_addr = link->resource[0]->start; | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-08 17:24:46 +01:00
										 |  |  |     dev_dbg(&link->dev, "request IRQ %d\n", | 
					
						
							| 
									
										
										
										
											2010-03-07 12:21:16 +01:00
										 |  |  | 	    link->irq); | 
					
						
							|  |  |  |     if (!link->irq) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  | 	dev_dbg(&link->dev, "requestIRQ failed totally!\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	goto failed; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-07 12:21:16 +01:00
										 |  |  |     dev->irq = link->irq; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-29 19:27:09 +02:00
										 |  |  |     ret = pcmcia_enable_device(link); | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     if (ret) | 
					
						
							|  |  |  | 	    goto failed; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (com20020_check(dev)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  | 	regdump(dev); | 
					
						
							|  |  |  | 	goto failed; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							| 
									
										
										
										
											2008-11-12 23:38:14 -08:00
										 |  |  |     lp = netdev_priv(dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     lp->card_name = "PCMCIA COM20020"; | 
					
						
							|  |  |  |     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-03 10:27:34 +01:00
										 |  |  |     SET_NETDEV_DEV(dev, &link->dev); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     i = com20020_found(dev, 0);	/* calls register_netdev */ | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if (i != 0) { | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  | 	dev_notice(&link->dev, | 
					
						
							|  |  |  | 		   "com20020_found() failed\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	goto failed; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-12 12:22:51 +00:00
										 |  |  |     netdev_dbg(dev, "port %#3lx, irq %d\n", | 
					
						
							|  |  |  | 	       dev->base_addr, dev->irq); | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | failed: | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  |     dev_dbg(&link->dev, "com20020_config failed...\n"); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |     com20020_release(link); | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  |     return -ENODEV; | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } /* com20020_config */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | static void com20020_release(struct pcmcia_device *link) | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-24 15:51:05 +02:00
										 |  |  | 	dev_dbg(&link->dev, "com20020_release\n"); | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | 	pcmcia_disable_device(link); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | static int com20020_suspend(struct pcmcia_device *link) | 
					
						
							| 
									
										
										
										
											2005-11-14 21:21:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	com20020_dev_t *info = link->priv; | 
					
						
							|  |  |  | 	struct net_device *dev = info->dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-02 00:09:29 +01:00
										 |  |  | 	if (link->open) | 
					
						
							| 
									
										
										
										
											2006-03-02 00:02:33 +01:00
										 |  |  | 		netif_device_detach(dev); | 
					
						
							| 
									
										
										
										
											2005-11-14 21:21:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-31 17:21:06 +02:00
										 |  |  | static int com20020_resume(struct pcmcia_device *link) | 
					
						
							| 
									
										
										
										
											2005-11-14 21:21:18 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	com20020_dev_t *info = link->priv; | 
					
						
							|  |  |  | 	struct net_device *dev = info->dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-02 00:09:29 +01:00
										 |  |  | 	if (link->open) { | 
					
						
							| 
									
										
										
										
											2006-03-02 00:02:33 +01:00
										 |  |  | 		int ioaddr = dev->base_addr; | 
					
						
							| 
									
										
										
										
											2008-11-12 23:38:14 -08:00
										 |  |  | 		struct arcnet_local *lp = netdev_priv(dev); | 
					
						
							| 
									
										
										
										
											2006-03-02 00:02:33 +01:00
										 |  |  | 		ARCRESET; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-11-14 21:21:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-03 19:29:01 -07:00
										 |  |  | static const struct pcmcia_device_id com20020_ids[] = { | 
					
						
							| 
									
										
										
										
											2006-06-25 01:56:24 -07:00
										 |  |  | 	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", | 
					
						
							|  |  |  | 			"PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), | 
					
						
							|  |  |  | 	PCMCIA_DEVICE_PROD_ID12("SoHard AG", | 
					
						
							|  |  |  | 			"SH ARC PCMCIA", 0xf8991729, 0x69dff0c7), | 
					
						
							| 
									
										
										
										
											2005-06-27 16:28:38 -07:00
										 |  |  | 	PCMCIA_DEVICE_NULL | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | MODULE_DEVICE_TABLE(pcmcia, com20020_ids); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | static struct pcmcia_driver com20020_cs_driver = { | 
					
						
							|  |  |  | 	.owner		= THIS_MODULE, | 
					
						
							| 
									
										
										
										
											2010-08-08 11:36:26 +02:00
										 |  |  | 	.name		= "com20020_cs", | 
					
						
							| 
									
										
										
										
											2006-03-31 17:26:06 +02:00
										 |  |  | 	.probe		= com20020_probe, | 
					
						
							| 
									
										
										
										
											2005-11-14 21:23:14 +01:00
										 |  |  | 	.remove		= com20020_detach, | 
					
						
							| 
									
										
										
										
											2005-06-27 16:28:38 -07:00
										 |  |  | 	.id_table	= com20020_ids, | 
					
						
							| 
									
										
										
										
											2005-11-14 21:21:18 +01:00
										 |  |  | 	.suspend	= com20020_suspend, | 
					
						
							|  |  |  | 	.resume		= com20020_resume, | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __init init_com20020_cs(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return pcmcia_register_driver(&com20020_cs_driver); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __exit exit_com20020_cs(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	pcmcia_unregister_driver(&com20020_cs_driver); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module_init(init_com20020_cs); | 
					
						
							|  |  |  | module_exit(exit_com20020_cs); |