ring-buffer: Remove unused macro RB_TIMESTAMPS_PER_PAGE
[sfrench/cifs-2.6.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.h>
47 #include <pcmcia/cistpl.h>
48 #include <pcmcia/ds.h>
49
50 #include <asm/io.h>
51 #include <asm/system.h>
52
53 #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
54
55 #ifdef DEBUG
56
57 static void regdump(struct net_device *dev)
58 {
59     int ioaddr = dev->base_addr;
60     int count;
61     
62     printk("com20020 register dump:\n");
63     for (count = ioaddr; count < ioaddr + 16; count++)
64     {
65         if (!(count % 16))
66             printk("\n%04X: ", count);
67         printk("%02X ", inb(count));
68     }
69     printk("\n");
70     
71     printk("buffer0 dump:\n");
72         /* set up the address register */
73         count = 0;
74         outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI);
75         outb(count & 0xff, _ADDR_LO);
76     
77     for (count = 0; count < 256+32; count++)
78     {
79         if (!(count % 16))
80             printk("\n%04X: ", count);
81         
82         /* copy the data */
83         printk("%02X ", inb(_MEMDATA));
84     }
85     printk("\n");
86 }
87
88 #else
89
90 static inline void regdump(struct net_device *dev) { }
91
92 #endif
93
94
95 /*====================================================================*/
96
97 /* Parameters that can be set with 'insmod' */
98
99 static int node;
100 static int timeout = 3;
101 static int backplane;
102 static int clockp;
103 static int clockm;
104
105 module_param(node, int, 0);
106 module_param(timeout, int, 0);
107 module_param(backplane, int, 0);
108 module_param(clockp, int, 0);
109 module_param(clockm, int, 0);
110
111 MODULE_LICENSE("GPL");
112
113 /*====================================================================*/
114
115 static int com20020_config(struct pcmcia_device *link);
116 static void com20020_release(struct pcmcia_device *link);
117
118 static void com20020_detach(struct pcmcia_device *p_dev);
119
120 /*====================================================================*/
121
122 typedef struct com20020_dev_t {
123     struct net_device       *dev;
124 } com20020_dev_t;
125
126 /*======================================================================
127
128     com20020_attach() creates an "instance" of the driver, allocating
129     local data structures for one device.  The device is registered
130     with Card Services.
131
132 ======================================================================*/
133
134 static int com20020_probe(struct pcmcia_device *p_dev)
135 {
136     com20020_dev_t *info;
137     struct net_device *dev;
138     struct arcnet_local *lp;
139
140     dev_dbg(&p_dev->dev, "com20020_attach()\n");
141
142     /* Create new network device */
143     info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
144     if (!info)
145         goto fail_alloc_info;
146
147     dev = alloc_arcdev("");
148     if (!dev)
149         goto fail_alloc_dev;
150
151     lp = netdev_priv(dev);
152     lp->timeout = timeout;
153     lp->backplane = backplane;
154     lp->clockp = clockp;
155     lp->clockm = clockm & 3;
156     lp->hw.owner = THIS_MODULE;
157
158     /* fill in our module parameters as defaults */
159     dev->dev_addr[0] = node;
160
161     p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
162     p_dev->resource[0]->end = 16;
163     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
164     p_dev->conf.IntType = INT_MEMORY_AND_IO;
165
166     info->dev = dev;
167     p_dev->priv = info;
168
169     return com20020_config(p_dev);
170
171 fail_alloc_dev:
172     kfree(info);
173 fail_alloc_info:
174     return -ENOMEM;
175 } /* com20020_attach */
176
177 /*======================================================================
178
179     This deletes a driver "instance".  The device is de-registered
180     with Card Services.  If it has been released, all local data
181     structures are freed.  Otherwise, the structures will be freed
182     when the device is released.
183
184 ======================================================================*/
185
186 static void com20020_detach(struct pcmcia_device *link)
187 {
188     struct com20020_dev_t *info = link->priv;
189     struct net_device *dev = info->dev;
190
191     dev_dbg(&link->dev, "detach...\n");
192
193     dev_dbg(&link->dev, "com20020_detach\n");
194
195     dev_dbg(&link->dev, "unregister...\n");
196
197     unregister_netdev(dev);
198
199     /*
200      * this is necessary because we register our IRQ separately
201      * from card services.
202      */
203     if (dev->irq)
204             free_irq(dev->irq, dev);
205
206     com20020_release(link);
207
208     /* Unlink device structure, free bits */
209     dev_dbg(&link->dev, "unlinking...\n");
210     if (link->priv)
211     {
212         dev = info->dev;
213         if (dev)
214         {
215             dev_dbg(&link->dev, "kfree...\n");
216             free_netdev(dev);
217         }
218         dev_dbg(&link->dev, "kfree2...\n");
219         kfree(info);
220     }
221
222 } /* com20020_detach */
223
224 /*======================================================================
225
226     com20020_config() is scheduled to run after a CARD_INSERTION event
227     is received, to configure the PCMCIA socket, and to make the
228     device available to the system.
229
230 ======================================================================*/
231
232 static int com20020_config(struct pcmcia_device *link)
233 {
234     struct arcnet_local *lp;
235     com20020_dev_t *info;
236     struct net_device *dev;
237     int i, ret;
238     int ioaddr;
239
240     info = link->priv;
241     dev = info->dev;
242
243     dev_dbg(&link->dev, "config...\n");
244
245     dev_dbg(&link->dev, "com20020_config\n");
246
247     dev_dbg(&link->dev, "baseport1 is %Xh\n",
248             (unsigned int) link->resource[0]->start);
249
250     i = -ENODEV;
251     link->io_lines = 16;
252
253     if (!link->resource[0]->start)
254     {
255         for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
256         {
257             link->resource[0]->start = ioaddr;
258             i = pcmcia_request_io(link);
259             if (i == 0)
260                 break;
261         }
262     }
263     else
264         i = pcmcia_request_io(link);
265     
266     if (i != 0)
267     {
268         dev_dbg(&link->dev, "requestIO failed totally!\n");
269         goto failed;
270     }
271         
272     ioaddr = dev->base_addr = link->resource[0]->start;
273     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
274
275     dev_dbg(&link->dev, "request IRQ %d\n",
276             link->irq);
277     if (!link->irq)
278     {
279         dev_dbg(&link->dev, "requestIRQ failed totally!\n");
280         goto failed;
281     }
282
283     dev->irq = link->irq;
284
285     ret = pcmcia_request_configuration(link, &link->conf);
286     if (ret)
287             goto failed;
288
289     if (com20020_check(dev))
290     {
291         regdump(dev);
292         goto failed;
293     }
294     
295     lp = netdev_priv(dev);
296     lp->card_name = "PCMCIA COM20020";
297     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
298
299     SET_NETDEV_DEV(dev, &link->dev);
300
301     i = com20020_found(dev, 0); /* calls register_netdev */
302     
303     if (i != 0) {
304         dev_printk(KERN_NOTICE, &link->dev,
305                 "com20020_cs: com20020_found() failed\n");
306         goto failed;
307     }
308
309     dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
310            dev->name, dev->base_addr, dev->irq);
311     return 0;
312
313 failed:
314     dev_dbg(&link->dev, "com20020_config failed...\n");
315     com20020_release(link);
316     return -ENODEV;
317 } /* com20020_config */
318
319 /*======================================================================
320
321     After a card is removed, com20020_release() will unregister the net
322     device, and release the PCMCIA configuration.  If the device is
323     still open, this will be postponed until it is closed.
324
325 ======================================================================*/
326
327 static void com20020_release(struct pcmcia_device *link)
328 {
329         dev_dbg(&link->dev, "com20020_release\n");
330         pcmcia_disable_device(link);
331 }
332
333 static int com20020_suspend(struct pcmcia_device *link)
334 {
335         com20020_dev_t *info = link->priv;
336         struct net_device *dev = info->dev;
337
338         if (link->open)
339                 netif_device_detach(dev);
340
341         return 0;
342 }
343
344 static int com20020_resume(struct pcmcia_device *link)
345 {
346         com20020_dev_t *info = link->priv;
347         struct net_device *dev = info->dev;
348
349         if (link->open) {
350                 int ioaddr = dev->base_addr;
351                 struct arcnet_local *lp = netdev_priv(dev);
352                 ARCRESET;
353         }
354
355         return 0;
356 }
357
358 static struct pcmcia_device_id com20020_ids[] = {
359         PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
360                         "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
361         PCMCIA_DEVICE_PROD_ID12("SoHard AG",
362                         "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
363         PCMCIA_DEVICE_NULL
364 };
365 MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
366
367 static struct pcmcia_driver com20020_cs_driver = {
368         .owner          = THIS_MODULE,
369         .drv            = {
370                 .name   = "com20020_cs",
371         },
372         .probe          = com20020_probe,
373         .remove         = com20020_detach,
374         .id_table       = com20020_ids,
375         .suspend        = com20020_suspend,
376         .resume         = com20020_resume,
377 };
378
379 static int __init init_com20020_cs(void)
380 {
381         return pcmcia_register_driver(&com20020_cs_driver);
382 }
383
384 static void __exit exit_com20020_cs(void)
385 {
386         pcmcia_unregister_driver(&com20020_cs_driver);
387 }
388
389 module_init(init_com20020_cs);
390 module_exit(exit_com20020_cs);