Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / drivers / net / pcmcia / com20020_cs.c
1 /*
2  * Linux ARCnet driver - COM20020 PCMCIA support
3  * 
4  * Written 1994-1999 by Avery Pennarun,
5  *    based on an ISA version by David Woodhouse.
6  * Derived from ibmtr_cs.c by Steve Kipisz (pcmcia-cs 3.1.4)
7  *    which was derived from pcnet_cs.c by David Hinds.
8  * Some additional portions derived from skeleton.c by Donald Becker.
9  *
10  * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
11  *  for sponsoring the further development of this driver.
12  *
13  * **********************
14  *
15  * The original copyright of skeleton.c was as follows:
16  *
17  * skeleton.c Written 1993 by Donald Becker.
18  * Copyright 1993 United States Government as represented by the
19  * Director, National Security Agency.  This software may only be used
20  * and distributed according to the terms of the GNU General Public License as
21  * modified by SRC, incorporated herein by reference.
22  * 
23  * **********************
24  * Changes:
25  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
26  * - reorganize kmallocs in com20020_attach, checking all for failure
27  *   and releasing the previous allocations if one fails
28  * **********************
29  * 
30  * For more details, see drivers/net/arcnet.c
31  *
32  * **********************
33  */
34 #include <linux/kernel.h>
35 #include <linux/init.h>
36 #include <linux/ptrace.h>
37 #include <linux/slab.h>
38 #include <linux/string.h>
39 #include <linux/timer.h>
40 #include <linux/delay.h>
41 #include <linux/module.h>
42 #include <linux/netdevice.h>
43 #include <linux/arcdevice.h>
44 #include <linux/com20020.h>
45
46 #include <pcmcia/cs_types.h>
47 #include <pcmcia/cs.h>
48 #include <pcmcia/cistpl.h>
49 #include <pcmcia/ds.h>
50
51 #include <asm/io.h>
52 #include <asm/system.h>
53
54 #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
55
56 #ifdef DEBUG
57
58 static void regdump(struct net_device *dev)
59 {
60     int ioaddr = dev->base_addr;
61     int count;
62     
63     printk("com20020 register dump:\n");
64     for (count = ioaddr; count < ioaddr + 16; count++)
65     {
66         if (!(count % 16))
67             printk("\n%04X: ", count);
68         printk("%02X ", inb(count));
69     }
70     printk("\n");
71     
72     printk("buffer0 dump:\n");
73         /* set up the address register */
74         count = 0;
75         outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
76         outb(count & 0xff, _ADDR_LO);
77     
78     for (count = 0; count < 256+32; count++)
79     {
80         if (!(count % 16))
81             printk("\n%04X: ", count);
82         
83         /* copy the data */
84         printk("%02X ", inb(_MEMDATA));
85     }
86     printk("\n");
87 }
88
89 #else
90
91 static inline void regdump(struct net_device *dev) { }
92
93 #endif
94
95
96 /*====================================================================*/
97
98 /* Parameters that can be set with 'insmod' */
99
100 static int node;
101 static int timeout = 3;
102 static int backplane;
103 static int clockp;
104 static int clockm;
105
106 module_param(node, int, 0);
107 module_param(timeout, int, 0);
108 module_param(backplane, int, 0);
109 module_param(clockp, int, 0);
110 module_param(clockm, int, 0);
111
112 MODULE_LICENSE("GPL");
113
114 /*====================================================================*/
115
116 static int com20020_config(struct pcmcia_device *link);
117 static void com20020_release(struct pcmcia_device *link);
118
119 static void com20020_detach(struct pcmcia_device *p_dev);
120
121 /*====================================================================*/
122
123 typedef struct com20020_dev_t {
124     struct net_device       *dev;
125 } com20020_dev_t;
126
127 /*======================================================================
128
129     com20020_attach() creates an "instance" of the driver, allocating
130     local data structures for one device.  The device is registered
131     with Card Services.
132
133 ======================================================================*/
134
135 static int com20020_probe(struct pcmcia_device *p_dev)
136 {
137     com20020_dev_t *info;
138     struct net_device *dev;
139     struct arcnet_local *lp;
140
141     dev_dbg(&p_dev->dev, "com20020_attach()\n");
142
143     /* Create new network device */
144     info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
145     if (!info)
146         goto fail_alloc_info;
147
148     dev = alloc_arcdev("");
149     if (!dev)
150         goto fail_alloc_dev;
151
152     lp = netdev_priv(dev);
153     lp->timeout = timeout;
154     lp->backplane = backplane;
155     lp->clockp = clockp;
156     lp->clockm = clockm & 3;
157     lp->hw.owner = THIS_MODULE;
158
159     /* fill in our module parameters as defaults */
160     dev->dev_addr[0] = node;
161
162     p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
163     p_dev->io.NumPorts1 = 16;
164     p_dev->io.IOAddrLines = 16;
165     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
166     p_dev->conf.IntType = INT_MEMORY_AND_IO;
167
168     info->dev = dev;
169     p_dev->priv = info;
170
171     return com20020_config(p_dev);
172
173 fail_alloc_dev:
174     kfree(info);
175 fail_alloc_info:
176     return -ENOMEM;
177 } /* com20020_attach */
178
179 /*======================================================================
180
181     This deletes a driver "instance".  The device is de-registered
182     with Card Services.  If it has been released, all local data
183     structures are freed.  Otherwise, the structures will be freed
184     when the device is released.
185
186 ======================================================================*/
187
188 static void com20020_detach(struct pcmcia_device *link)
189 {
190     struct com20020_dev_t *info = link->priv;
191     struct net_device *dev = info->dev;
192
193     dev_dbg(&link->dev, "detach...\n");
194
195     dev_dbg(&link->dev, "com20020_detach\n");
196
197     dev_dbg(&link->dev, "unregister...\n");
198
199     unregister_netdev(dev);
200
201     /*
202      * this is necessary because we register our IRQ separately
203      * from card services.
204      */
205     if (dev->irq)
206             free_irq(dev->irq, dev);
207
208     com20020_release(link);
209
210     /* Unlink device structure, free bits */
211     dev_dbg(&link->dev, "unlinking...\n");
212     if (link->priv)
213     {
214         dev = info->dev;
215         if (dev)
216         {
217             dev_dbg(&link->dev, "kfree...\n");
218             free_netdev(dev);
219         }
220         dev_dbg(&link->dev, "kfree2...\n");
221         kfree(info);
222     }
223
224 } /* com20020_detach */
225
226 /*======================================================================
227
228     com20020_config() is scheduled to run after a CARD_INSERTION event
229     is received, to configure the PCMCIA socket, and to make the
230     device available to the system.
231
232 ======================================================================*/
233
234 static int com20020_config(struct pcmcia_device *link)
235 {
236     struct arcnet_local *lp;
237     com20020_dev_t *info;
238     struct net_device *dev;
239     int i, ret;
240     int ioaddr;
241
242     info = link->priv;
243     dev = info->dev;
244
245     dev_dbg(&link->dev, "config...\n");
246
247     dev_dbg(&link->dev, "com20020_config\n");
248
249     dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
250     i = -ENODEV;
251     if (!link->io.BasePort1)
252     {
253         for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
254         {
255             link->io.BasePort1 = ioaddr;
256             i = pcmcia_request_io(link, &link->io);
257             if (i == 0)
258                 break;
259         }
260     }
261     else
262         i = pcmcia_request_io(link, &link->io);
263     
264     if (i != 0)
265     {
266         dev_dbg(&link->dev, "requestIO failed totally!\n");
267         goto failed;
268     }
269         
270     ioaddr = dev->base_addr = link->io.BasePort1;
271     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
272
273     dev_dbg(&link->dev, "request IRQ %d\n",
274             link->irq);
275     if (!link->irq)
276     {
277         dev_dbg(&link->dev, "requestIRQ failed totally!\n");
278         goto failed;
279     }
280
281     dev->irq = link->irq;
282
283     ret = pcmcia_request_configuration(link, &link->conf);
284     if (ret)
285             goto failed;
286
287     if (com20020_check(dev))
288     {
289         regdump(dev);
290         goto failed;
291     }
292     
293     lp = netdev_priv(dev);
294     lp->card_name = "PCMCIA COM20020";
295     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
296
297     SET_NETDEV_DEV(dev, &link->dev);
298
299     i = com20020_found(dev, 0); /* calls register_netdev */
300     
301     if (i != 0) {
302         dev_printk(KERN_NOTICE, &link->dev,
303                 "com20020_cs: com20020_found() failed\n");
304         goto failed;
305     }
306
307     dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
308            dev->name, dev->base_addr, dev->irq);
309     return 0;
310
311 failed:
312     dev_dbg(&link->dev, "com20020_config failed...\n");
313     com20020_release(link);
314     return -ENODEV;
315 } /* com20020_config */
316
317 /*======================================================================
318
319     After a card is removed, com20020_release() will unregister the net
320     device, and release the PCMCIA configuration.  If the device is
321     still open, this will be postponed until it is closed.
322
323 ======================================================================*/
324
325 static void com20020_release(struct pcmcia_device *link)
326 {
327         dev_dbg(&link->dev, "com20020_release\n");
328         pcmcia_disable_device(link);
329 }
330
331 static int com20020_suspend(struct pcmcia_device *link)
332 {
333         com20020_dev_t *info = link->priv;
334         struct net_device *dev = info->dev;
335
336         if (link->open)
337                 netif_device_detach(dev);
338
339         return 0;
340 }
341
342 static int com20020_resume(struct pcmcia_device *link)
343 {
344         com20020_dev_t *info = link->priv;
345         struct net_device *dev = info->dev;
346
347         if (link->open) {
348                 int ioaddr = dev->base_addr;
349                 struct arcnet_local *lp = netdev_priv(dev);
350                 ARCRESET;
351         }
352
353         return 0;
354 }
355
356 static struct pcmcia_device_id com20020_ids[] = {
357         PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
358                         "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
359         PCMCIA_DEVICE_PROD_ID12("SoHard AG",
360                         "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
361         PCMCIA_DEVICE_NULL
362 };
363 MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
364
365 static struct pcmcia_driver com20020_cs_driver = {
366         .owner          = THIS_MODULE,
367         .drv            = {
368                 .name   = "com20020_cs",
369         },
370         .probe          = com20020_probe,
371         .remove         = com20020_detach,
372         .id_table       = com20020_ids,
373         .suspend        = com20020_suspend,
374         .resume         = com20020_resume,
375 };
376
377 static int __init init_com20020_cs(void)
378 {
379         return pcmcia_register_driver(&com20020_cs_driver);
380 }
381
382 static void __exit exit_com20020_cs(void)
383 {
384         pcmcia_unregister_driver(&com20020_cs_driver);
385 }
386
387 module_init(init_com20020_cs);
388 module_exit(exit_com20020_cs);