pcmcia: do not use io_req_t when calling pcmcia_request_io()
[deliverable/linux.git] / drivers / net / pcmcia / com20020_cs.c
CommitLineData
1da177e4
LT
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
1da177e4
LT
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
dd0fab5b 55#ifdef DEBUG
1da177e4
LT
56
57static 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
1da177e4
LT
90static inline void regdump(struct net_device *dev) { }
91
92#endif
93
94
95/*====================================================================*/
96
97/* Parameters that can be set with 'insmod' */
98
99static int node;
100static int timeout = 3;
101static int backplane;
102static int clockp;
103static int clockm;
104
105module_param(node, int, 0);
106module_param(timeout, int, 0);
107module_param(backplane, int, 0);
108module_param(clockp, int, 0);
109module_param(clockm, int, 0);
110
111MODULE_LICENSE("GPL");
112
113/*====================================================================*/
114
15b99ac1 115static int com20020_config(struct pcmcia_device *link);
fba395ee 116static void com20020_release(struct pcmcia_device *link);
1da177e4 117
cc3b4866 118static void com20020_detach(struct pcmcia_device *p_dev);
1da177e4 119
1da177e4
LT
120/*====================================================================*/
121
122typedef struct com20020_dev_t {
123 struct net_device *dev;
1da177e4
LT
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
15b99ac1 134static int com20020_probe(struct pcmcia_device *p_dev)
1da177e4 135{
1da177e4
LT
136 com20020_dev_t *info;
137 struct net_device *dev;
1da177e4 138 struct arcnet_local *lp;
f8cfa618 139
dd0fab5b 140 dev_dbg(&p_dev->dev, "com20020_attach()\n");
1da177e4
LT
141
142 /* Create new network device */
dd00cc48 143 info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
1da177e4
LT
144 if (!info)
145 goto fail_alloc_info;
146
147 dev = alloc_arcdev("");
148 if (!dev)
149 goto fail_alloc_dev;
150
4cf1653a 151 lp = netdev_priv(dev);
1da177e4
LT
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
90abdc3b
DB
161 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
162 p_dev->resource[0]->end = 16;
fd238232
DB
163 p_dev->conf.Attributes = CONF_ENABLE_IRQ;
164 p_dev->conf.IntType = INT_MEMORY_AND_IO;
1da177e4 165
5fa9167a 166 info->dev = dev;
fd238232 167 p_dev->priv = info;
1da177e4 168
15b99ac1 169 return com20020_config(p_dev);
1da177e4
LT
170
171fail_alloc_dev:
172 kfree(info);
173fail_alloc_info:
f8cfa618 174 return -ENOMEM;
1da177e4
LT
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
fba395ee 186static void com20020_detach(struct pcmcia_device *link)
1da177e4
LT
187{
188 struct com20020_dev_t *info = link->priv;
b4635811
DB
189 struct net_device *dev = info->dev;
190
dd0fab5b 191 dev_dbg(&link->dev, "detach...\n");
1da177e4 192
dd0fab5b 193 dev_dbg(&link->dev, "com20020_detach\n");
1da177e4 194
c7c2fa07 195 dev_dbg(&link->dev, "unregister...\n");
1da177e4 196
c7c2fa07 197 unregister_netdev(dev);
b4635811 198
c7c2fa07
DB
199 /*
200 * this is necessary because we register our IRQ separately
201 * from card services.
202 */
203 if (dev->irq)
1da177e4 204 free_irq(dev->irq, dev);
1da177e4 205
e2d40963 206 com20020_release(link);
1da177e4 207
1da177e4 208 /* Unlink device structure, free bits */
dd0fab5b 209 dev_dbg(&link->dev, "unlinking...\n");
1da177e4
LT
210 if (link->priv)
211 {
212 dev = info->dev;
213 if (dev)
214 {
dd0fab5b 215 dev_dbg(&link->dev, "kfree...\n");
1da177e4
LT
216 free_netdev(dev);
217 }
dd0fab5b 218 dev_dbg(&link->dev, "kfree2...\n");
1da177e4
LT
219 kfree(info);
220 }
1da177e4
LT
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
15b99ac1 232static int com20020_config(struct pcmcia_device *link)
1da177e4
LT
233{
234 struct arcnet_local *lp;
1da177e4
LT
235 com20020_dev_t *info;
236 struct net_device *dev;
dd0fab5b 237 int i, ret;
1da177e4
LT
238 int ioaddr;
239
1da177e4
LT
240 info = link->priv;
241 dev = info->dev;
242
dd0fab5b 243 dev_dbg(&link->dev, "config...\n");
1da177e4 244
dd0fab5b 245 dev_dbg(&link->dev, "com20020_config\n");
1da177e4 246
90abdc3b
DB
247 dev_dbg(&link->dev, "baseport1 is %Xh\n",
248 (unsigned int) link->resource[0]->start);
249
4c89e88b 250 i = -ENODEV;
90abdc3b
DB
251 link->io_lines = 16;
252
253 if (!link->resource[0]->start)
1da177e4
LT
254 {
255 for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
256 {
90abdc3b
DB
257 link->resource[0]->start = ioaddr;
258 i = pcmcia_request_io(link);
4c89e88b 259 if (i == 0)
1da177e4
LT
260 break;
261 }
262 }
263 else
90abdc3b 264 i = pcmcia_request_io(link);
1da177e4 265
4c89e88b 266 if (i != 0)
1da177e4 267 {
dd0fab5b 268 dev_dbg(&link->dev, "requestIO failed totally!\n");
1da177e4
LT
269 goto failed;
270 }
271
9a017a91 272 ioaddr = dev->base_addr = link->resource[0]->start;
dd0fab5b 273 dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
1da177e4 274
5fa9167a 275 dev_dbg(&link->dev, "request IRQ %d\n",
eb14120f
DB
276 link->irq);
277 if (!link->irq)
1da177e4 278 {
dd0fab5b 279 dev_dbg(&link->dev, "requestIRQ failed totally!\n");
1da177e4
LT
280 goto failed;
281 }
282
eb14120f 283 dev->irq = link->irq;
1da177e4 284
dd0fab5b
DB
285 ret = pcmcia_request_configuration(link, &link->conf);
286 if (ret)
287 goto failed;
1da177e4
LT
288
289 if (com20020_check(dev))
290 {
291 regdump(dev);
292 goto failed;
293 }
294
4cf1653a 295 lp = netdev_priv(dev);
1da177e4
LT
296 lp->card_name = "PCMCIA COM20020";
297 lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
298
dd2e5a15 299 SET_NETDEV_DEV(dev, &link->dev);
1da177e4
LT
300
301 i = com20020_found(dev, 0); /* calls register_netdev */
302
303 if (i != 0) {
dd0fab5b
DB
304 dev_printk(KERN_NOTICE, &link->dev,
305 "com20020_cs: com20020_found() failed\n");
1da177e4
LT
306 goto failed;
307 }
308
dd0fab5b 309 dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
1da177e4 310 dev->name, dev->base_addr, dev->irq);
15b99ac1 311 return 0;
1da177e4 312
1da177e4 313failed:
dd0fab5b 314 dev_dbg(&link->dev, "com20020_config failed...\n");
1da177e4 315 com20020_release(link);
15b99ac1 316 return -ENODEV;
1da177e4
LT
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
fba395ee 327static void com20020_release(struct pcmcia_device *link)
1da177e4 328{
dd0fab5b 329 dev_dbg(&link->dev, "com20020_release\n");
fba395ee 330 pcmcia_disable_device(link);
1da177e4
LT
331}
332
fba395ee 333static int com20020_suspend(struct pcmcia_device *link)
98e4c28b 334{
98e4c28b
DB
335 com20020_dev_t *info = link->priv;
336 struct net_device *dev = info->dev;
337
e2d40963 338 if (link->open)
8661bb5b 339 netif_device_detach(dev);
98e4c28b
DB
340
341 return 0;
342}
343
fba395ee 344static int com20020_resume(struct pcmcia_device *link)
98e4c28b 345{
98e4c28b
DB
346 com20020_dev_t *info = link->priv;
347 struct net_device *dev = info->dev;
348
e2d40963 349 if (link->open) {
8661bb5b 350 int ioaddr = dev->base_addr;
4cf1653a 351 struct arcnet_local *lp = netdev_priv(dev);
8661bb5b
DB
352 ARCRESET;
353 }
98e4c28b
DB
354
355 return 0;
356}
357
7fb22bb4 358static struct pcmcia_device_id com20020_ids[] = {
6bb1c39a
MS
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),
7fb22bb4
DB
363 PCMCIA_DEVICE_NULL
364};
365MODULE_DEVICE_TABLE(pcmcia, com20020_ids);
1da177e4
LT
366
367static struct pcmcia_driver com20020_cs_driver = {
368 .owner = THIS_MODULE,
369 .drv = {
370 .name = "com20020_cs",
371 },
15b99ac1 372 .probe = com20020_probe,
cc3b4866 373 .remove = com20020_detach,
7fb22bb4 374 .id_table = com20020_ids,
98e4c28b
DB
375 .suspend = com20020_suspend,
376 .resume = com20020_resume,
1da177e4
LT
377};
378
379static int __init init_com20020_cs(void)
380{
381 return pcmcia_register_driver(&com20020_cs_driver);
382}
383
384static void __exit exit_com20020_cs(void)
385{
386 pcmcia_unregister_driver(&com20020_cs_driver);
1da177e4
LT
387}
388
389module_init(init_com20020_cs);
390module_exit(exit_com20020_cs);
This page took 0.573603 seconds and 5 git commands to generate.