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