pcmcia: do not use io_req_t after call to pcmcia_request_io()
[linux-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->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
162     p_dev->io.NumPorts1 = 16;
163     p_dev->io.IOAddrLines = 16;
164     p_dev->conf.Attributes = CONF_ENABLE_IRQ;
165     p_dev->conf.IntType = INT_MEMORY_AND_IO;
166
167     info->dev = dev;
168     p_dev->priv = info;
169
170     return com20020_config(p_dev);
171
172 fail_alloc_dev:
173     kfree(info);
174 fail_alloc_info:
175     return -ENOMEM;
176 } /* com20020_attach */
177
178 /*======================================================================
179
180     This deletes a driver "instance".  The device is de-registered
181     with Card Services.  If it has been released, all local data
182     structures are freed.  Otherwise, the structures will be freed
183     when the device is released.
184
185 ======================================================================*/
186
187 static void com20020_detach(struct pcmcia_device *link)
188 {
189     struct com20020_dev_t *info = link->priv;
190     struct net_device *dev = info->dev;
191
192     dev_dbg(&link->dev, "detach...\n");
193
194     dev_dbg(&link->dev, "com20020_detach\n");
195
196     dev_dbg(&link->dev, "unregister...\n");
197
198     unregister_netdev(dev);
199
200     /*
201      * this is necessary because we register our IRQ separately
202      * from card services.
203      */
204     if (dev->irq)
205             free_irq(dev->irq, dev);
206
207     com20020_release(link);
208
209     /* Unlink device structure, free bits */
210     dev_dbg(&link->dev, "unlinking...\n");
211     if (link->priv)
212     {
213         dev = info->dev;
214         if (dev)
215         {
216             dev_dbg(&link->dev, "kfree...\n");
217             free_netdev(dev);
218         }
219         dev_dbg(&link->dev, "kfree2...\n");
220         kfree(info);
221     }
222
223 } /* com20020_detach */
224
225 /*======================================================================
226
227     com20020_config() is scheduled to run after a CARD_INSERTION event
228     is received, to configure the PCMCIA socket, and to make the
229     device available to the system.
230
231 ======================================================================*/
232
233 static int com20020_config(struct pcmcia_device *link)
234 {
235     struct arcnet_local *lp;
236     com20020_dev_t *info;
237     struct net_device *dev;
238     int i, ret;
239     int ioaddr;
240
241     info = link->priv;
242     dev = info->dev;
243
244     dev_dbg(&link->dev, "config...\n");
245
246     dev_dbg(&link->dev, "com20020_config\n");
247
248     dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
249     i = -ENODEV;
250     if (!link->io.BasePort1)
251     {
252         for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
253         {
254             link->io.BasePort1 = ioaddr;
255             i = pcmcia_request_io(link, &link->io);
256             if (i == 0)
257                 break;
258         }
259     }
260     else
261         i = pcmcia_request_io(link, &link->io);
262     
263     if (i != 0)
264     {
265         dev_dbg(&link->dev, "requestIO failed totally!\n");
266         goto failed;
267     }
268         
269     ioaddr = dev->base_addr = link->resource[0]->start;
270     dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
271
272     dev_dbg(&link->dev, "request IRQ %d\n",
273             link->irq);
274     if (!link->irq)
275     {
276         dev_dbg(&link->dev, "requestIRQ failed totally!\n");
277         goto failed;
278     }
279
280     dev->irq = link->irq;
281
282     ret = pcmcia_request_configuration(link, &link->conf);
283     if (ret)
284             goto failed;
285
286     if (com20020_check(dev))
287     {
288         regdump(dev);
289         goto failed;
290     }
291     
292     lp = netdev_priv(dev);
293     lp->card_name = "PCMCIA COM20020";
294     lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
295
296     SET_NETDEV_DEV(dev, &link->dev);
297
298     i = com20020_found(dev, 0); /* calls register_netdev */
299     
300     if (i != 0) {
301         dev_printk(KERN_NOTICE, &link->dev,
302                 "com20020_cs: com20020_found() failed\n");
303         goto failed;
304     }
305
306     dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
307            dev->name, dev->base_addr, dev->irq);
308     return 0;
309
310 failed:
311     dev_dbg(&link->dev, "com20020_config failed...\n");
312     com20020_release(link);
313     return -ENODEV;
314 } /* com20020_config */
315
316 /*======================================================================
317
318     After a card is removed, com20020_release() will unregister the net
319     device, and release the PCMCIA configuration.  If the device is
320     still open, this will be postponed until it is closed.
321
322 ======================================================================*/
323
324 static void com20020_release(struct pcmcia_device *link)
325 {
326         dev_dbg(&link->dev, "com20020_release\n");
327         pcmcia_disable_device(link);
328 }
329
330 static int com20020_suspend(struct pcmcia_device *link)
331 {
332         com20020_dev_t *info = link->priv;
333         struct net_device *dev = info->dev;
334
335         if (link->open)
336                 netif_device_detach(dev);
337
338         return 0;
339 }
340
341 static int com20020_resume(struct pcmcia_device *link)
342 {
343         com20020_dev_t *info = link->priv;
344         struct net_device *dev = info->dev;
345
346         if (link->open) {
347                 int ioaddr = dev->base_addr;
348                 struct arcnet_local *lp = netdev_priv(dev);
349                 ARCRESET;
350         }
351
352         return 0;
353 }
354
355 static struct pcmcia_device_id com20020_ids[] = {
356         PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
357                         "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
358         PCMCIA_DEVICE_PROD_ID12("SoHard AG",
359                         "SH ARC PCMCIA", 0xf8991729, 0x69dff0c7),
360         PCMCIA_DEVICE_NULL
361 };
362 MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
363
364 static struct pcmcia_driver com20020_cs_driver = {
365         .owner          = THIS_MODULE,
366         .drv            = {
367                 .name   = "com20020_cs",
368         },
369         .probe          = com20020_probe,
370         .remove         = com20020_detach,
371         .id_table       = com20020_ids,
372         .suspend        = com20020_suspend,
373         .resume         = com20020_resume,
374 };
375
376 static int __init init_com20020_cs(void)
377 {
378         return pcmcia_register_driver(&com20020_cs_driver);
379 }
380
381 static void __exit exit_com20020_cs(void)
382 {
383         pcmcia_unregister_driver(&com20020_cs_driver);
384 }
385
386 module_init(init_com20020_cs);
387 module_exit(exit_com20020_cs);