[PATCH] pcmcia: remove dev_list from drivers
[linux-2.6-block.git] / drivers / net / pcmcia / ibmtr_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 A PCMCIA token-ring driver for IBM-based cards
4
5 This driver supports the IBM PCMCIA Token-Ring Card.
6 Written by Steve Kipisz, kipisz@vnet.ibm.com or
7 bungy@ibm.net
8
9 Written 1995,1996.
10
11 This code is based on pcnet_cs.c from David Hinds.
12
13 V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com
14
15 Linux V2.2.x presented significant changes to the underlying
16 ibmtr.c code. Mainly the code became a lot more organized and
17 modular.
18
19 This caused the old PCMCIA Token Ring driver to give up and go
20 home early. Instead of just patching the old code to make it
21 work, the PCMCIA code has been streamlined, updated and possibly
22 improved.
23
24 This code now only contains code required for the Card Services.
25 All we do here is set the card up enough so that the real ibmtr.c
26 driver can find it and work with it properly.
27
28 i.e. We set up the io port, irq, mmio memory and shared ram
29 memory. This enables ibmtr_probe in ibmtr.c to find the card and
30 configure it as though it was a normal ISA and/or PnP card.
31
32 CHANGES
33
34 v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com)
35 Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c
36
37 v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com)
38 Updated to version 2.2.7 to match the first version of the kernel
39 that the modification to ibmtr.c were incorporated into.
40
41 v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com)
42 Address translation feature of PCMCIA controller is usable so
43 memory windows can be placed in High memory (meaning above
44 0xFFFFF.)
45
46======================================================================*/
47
48#include <linux/kernel.h>
49#include <linux/init.h>
50#include <linux/ptrace.h>
51#include <linux/slab.h>
52#include <linux/string.h>
53#include <linux/timer.h>
54#include <linux/module.h>
55#include <linux/ethtool.h>
56#include <linux/netdevice.h>
57#include <linux/trdevice.h>
58#include <linux/ibmtr.h>
59
1da177e4
LT
60#include <pcmcia/cs_types.h>
61#include <pcmcia/cs.h>
62#include <pcmcia/cistpl.h>
63#include <pcmcia/ds.h>
64
65#include <asm/uaccess.h>
66#include <asm/io.h>
67#include <asm/system.h>
68
69#define PCMCIA
70#include "../tokenring/ibmtr.c"
71
72#ifdef PCMCIA_DEBUG
73static int pc_debug = PCMCIA_DEBUG;
74module_param(pc_debug, int, 0);
75#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
76static char *version =
77"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
78" 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
79" 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
80#else
81#define DEBUG(n, args...)
82#endif
83
84/*====================================================================*/
85
86/* Parameters that can be set with 'insmod' */
87
88/* MMIO base address */
89static u_long mmiobase = 0xce000;
90
91/* SRAM base address */
92static u_long srambase = 0xd0000;
93
94/* SRAM size 8,16,32,64 */
95static u_long sramsize = 64;
96
97/* Ringspeed 4,16 */
98static int ringspeed = 16;
99
100module_param(mmiobase, ulong, 0);
101module_param(srambase, ulong, 0);
102module_param(sramsize, ulong, 0);
103module_param(ringspeed, int, 0);
104MODULE_LICENSE("GPL");
105
106/*====================================================================*/
107
108static void ibmtr_config(dev_link_t *link);
109static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
110static void ibmtr_release(dev_link_t *link);
111static int ibmtr_event(event_t event, int priority,
112 event_callback_args_t *args);
113
114static dev_info_t dev_info = "ibmtr_cs";
115
116static dev_link_t *ibmtr_attach(void);
cc3b4866 117static void ibmtr_detach(struct pcmcia_device *p_dev);
1da177e4 118
1da177e4
LT
119/*====================================================================*/
120
121typedef struct ibmtr_dev_t {
122 dev_link_t link;
123 struct net_device *dev;
124 dev_node_t node;
125 window_handle_t sram_win_handle;
126 struct tok_info *ti;
127} ibmtr_dev_t;
128
129static void netdev_get_drvinfo(struct net_device *dev,
130 struct ethtool_drvinfo *info)
131{
132 strcpy(info->driver, "ibmtr_cs");
133}
134
135static struct ethtool_ops netdev_ethtool_ops = {
136 .get_drvinfo = netdev_get_drvinfo,
137};
138
139/*======================================================================
140
141 ibmtr_attach() creates an "instance" of the driver, allocating
142 local data structures for one device. The device is registered
143 with Card Services.
144
145======================================================================*/
146
147static dev_link_t *ibmtr_attach(void)
148{
149 ibmtr_dev_t *info;
150 dev_link_t *link;
151 struct net_device *dev;
152 client_reg_t client_reg;
153 int ret;
154
155 DEBUG(0, "ibmtr_attach()\n");
156
157 /* Create new token-ring device */
158 info = kmalloc(sizeof(*info), GFP_KERNEL);
159 if (!info) return NULL;
160 memset(info,0,sizeof(*info));
161 dev = alloc_trdev(sizeof(struct tok_info));
162 if (!dev) {
163 kfree(info);
164 return NULL;
165 }
166
167 link = &info->link;
168 link->priv = info;
169 info->ti = netdev_priv(dev);
170
171 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
172 link->io.NumPorts1 = 4;
173 link->io.IOAddrLines = 16;
174 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
175 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
176 link->irq.Handler = &tok_interrupt;
177 link->conf.Attributes = CONF_ENABLE_IRQ;
178 link->conf.Vcc = 50;
179 link->conf.IntType = INT_MEMORY_AND_IO;
180 link->conf.Present = PRESENT_OPTION;
181
182 link->irq.Instance = info->dev = dev;
183
184 SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
185
186 /* Register with Card Services */
b4635811 187 link->next = NULL;
1da177e4 188 client_reg.dev_info = &dev_info;
1da177e4
LT
189 client_reg.Version = 0x0210;
190 client_reg.event_callback_args.client_data = link;
191 ret = pcmcia_register_client(&link->handle, &client_reg);
192 if (ret != 0) {
193 cs_error(link->handle, RegisterClient, ret);
194 goto out_detach;
195 }
196
197out:
198 return link;
199
200out_detach:
cc3b4866 201 ibmtr_detach(link->handle);
1da177e4
LT
202 link = NULL;
203 goto out;
204} /* ibmtr_attach */
205
206/*======================================================================
207
208 This deletes a driver "instance". The device is de-registered
209 with Card Services. If it has been released, all local data
210 structures are freed. Otherwise, the structures will be freed
211 when the device is released.
212
213======================================================================*/
214
cc3b4866 215static void ibmtr_detach(struct pcmcia_device *p_dev)
1da177e4 216{
cc3b4866 217 dev_link_t *link = dev_to_instance(p_dev);
1da177e4 218 struct ibmtr_dev_t *info = link->priv;
b4635811 219 struct net_device *dev = info->dev;
1da177e4
LT
220
221 DEBUG(0, "ibmtr_detach(0x%p)\n", link);
222
1da177e4
LT
223 if (link->dev)
224 unregister_netdev(dev);
225
226 {
227 struct tok_info *ti = netdev_priv(dev);
228 del_timer_sync(&(ti->tr_timer));
229 }
230 if (link->state & DEV_CONFIG)
231 ibmtr_release(link);
232
1da177e4 233 free_netdev(dev);
b4635811 234 kfree(info);
1da177e4
LT
235} /* ibmtr_detach */
236
237/*======================================================================
238
239 ibmtr_config() is scheduled to run after a CARD_INSERTION event
240 is received, to configure the PCMCIA socket, and to make the
241 token-ring device available to the system.
242
243======================================================================*/
244
245#define CS_CHECK(fn, ret) \
246do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
247
248static void ibmtr_config(dev_link_t *link)
249{
250 client_handle_t handle = link->handle;
251 ibmtr_dev_t *info = link->priv;
252 struct net_device *dev = info->dev;
253 struct tok_info *ti = netdev_priv(dev);
254 tuple_t tuple;
255 cisparse_t parse;
256 win_req_t req;
257 memreq_t mem;
258 int i, last_ret, last_fn;
259 u_char buf[64];
260
261 DEBUG(0, "ibmtr_config(0x%p)\n", link);
262
263 tuple.Attributes = 0;
264 tuple.TupleData = buf;
265 tuple.TupleDataMax = 64;
266 tuple.TupleOffset = 0;
267 tuple.DesiredTuple = CISTPL_CONFIG;
268 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
269 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
270 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
271 link->conf.ConfigBase = parse.config.base;
272
273 /* Configure card */
274 link->state |= DEV_CONFIG;
275
276 link->conf.ConfigIndex = 0x61;
277
278 /* Determine if this is PRIMARY or ALTERNATE. */
279
280 /* Try PRIMARY card at 0xA20-0xA23 */
281 link->io.BasePort1 = 0xA20;
282 i = pcmcia_request_io(link->handle, &link->io);
283 if (i != CS_SUCCESS) {
284 /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
285 link->io.BasePort1 = 0xA24;
286 CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
287 }
288 dev->base_addr = link->io.BasePort1;
289
290 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
291 dev->irq = link->irq.AssignedIRQ;
292 ti->irq = link->irq.AssignedIRQ;
293 ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
294
295 /* Allocate the MMIO memory window */
296 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
297 req.Attributes |= WIN_USE_WAIT;
298 req.Base = 0;
299 req.Size = 0x2000;
300 req.AccessSpeed = 250;
301 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
302
303 mem.CardOffset = mmiobase;
304 mem.Page = 0;
305 CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
306 ti->mmio = ioremap(req.Base, req.Size);
307
308 /* Allocate the SRAM memory window */
309 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
310 req.Attributes |= WIN_USE_WAIT;
311 req.Base = 0;
312 req.Size = sramsize * 1024;
313 req.AccessSpeed = 250;
314 CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
315
316 mem.CardOffset = srambase;
317 mem.Page = 0;
318 CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
319
320 ti->sram_base = mem.CardOffset >> 12;
321 ti->sram_virt = ioremap(req.Base, req.Size);
322 ti->sram_phys = req.Base;
323
324 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
325
326 /* Set up the Token-Ring Controller Configuration Register and
327 turn on the card. Check the "Local Area Network Credit Card
328 Adapters Technical Reference" SC30-3585 for this info. */
329 ibmtr_hw_setup(dev, mmiobase);
330
331 link->dev = &info->node;
332 link->state &= ~DEV_CONFIG_PENDING;
333 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
334
335 i = ibmtr_probe_card(dev);
336 if (i != 0) {
337 printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
338 link->dev = NULL;
339 goto failed;
340 }
341
342 strcpy(info->node.dev_name, dev->name);
343
344 printk(KERN_INFO "%s: port %#3lx, irq %d,",
345 dev->name, dev->base_addr, dev->irq);
346 printk (" mmio %#5lx,", (u_long)ti->mmio);
347 printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
348 printk ("\n" KERN_INFO " hwaddr=");
349 for (i = 0; i < TR_ALEN; i++)
350 printk("%02X", dev->dev_addr[i]);
351 printk("\n");
352 return;
353
354cs_failed:
355 cs_error(link->handle, last_fn, last_ret);
356failed:
357 ibmtr_release(link);
358} /* ibmtr_config */
359
360/*======================================================================
361
362 After a card is removed, ibmtr_release() will unregister the net
363 device, and release the PCMCIA configuration. If the device is
364 still open, this will be postponed until it is closed.
365
366======================================================================*/
367
368static void ibmtr_release(dev_link_t *link)
369{
370 ibmtr_dev_t *info = link->priv;
371 struct net_device *dev = info->dev;
372
373 DEBUG(0, "ibmtr_release(0x%p)\n", link);
374
375 pcmcia_release_configuration(link->handle);
376 pcmcia_release_io(link->handle, &link->io);
377 pcmcia_release_irq(link->handle, &link->irq);
378 if (link->win) {
379 struct tok_info *ti = netdev_priv(dev);
380 iounmap(ti->mmio);
381 pcmcia_release_window(link->win);
382 pcmcia_release_window(info->sram_win_handle);
383 }
384
385 link->state &= ~DEV_CONFIG;
386}
387
98e4c28b
DB
388static int ibmtr_suspend(struct pcmcia_device *p_dev)
389{
390 dev_link_t *link = dev_to_instance(p_dev);
391 ibmtr_dev_t *info = link->priv;
392 struct net_device *dev = info->dev;
393
394 link->state |= DEV_SUSPEND;
395 if (link->state & DEV_CONFIG) {
396 if (link->open)
397 netif_device_detach(dev);
398 pcmcia_release_configuration(link->handle);
399 }
400
401 return 0;
402}
403
404static int ibmtr_resume(struct pcmcia_device *p_dev)
405{
406 dev_link_t *link = dev_to_instance(p_dev);
407 ibmtr_dev_t *info = link->priv;
408 struct net_device *dev = info->dev;
409
410 link->state &= ~DEV_SUSPEND;
411 if (link->state & DEV_CONFIG) {
412 pcmcia_request_configuration(link->handle, &link->conf);
413 if (link->open) {
414 ibmtr_probe(dev); /* really? */
415 netif_device_attach(dev);
416 }
417 }
418
419 return 0;
420}
421
422
1da177e4
LT
423/*======================================================================
424
425 The card status event handler. Mostly, this schedules other
426 stuff to run after an event is received. A CARD_REMOVAL event
427 also sets some flags to discourage the net drivers from trying
428 to talk to the card any more.
429
430======================================================================*/
431
432static int ibmtr_event(event_t event, int priority,
433 event_callback_args_t *args)
434{
435 dev_link_t *link = args->client_data;
1da177e4
LT
436
437 DEBUG(1, "ibmtr_event(0x%06x)\n", event);
438
439 switch (event) {
1da177e4
LT
440 case CS_EVENT_CARD_INSERTION:
441 link->state |= DEV_PRESENT;
442 ibmtr_config(link);
443 break;
1da177e4
LT
444 }
445 return 0;
446} /* ibmtr_event */
447
448/*====================================================================*/
449
450static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
451{
452 int i;
453
454 /* Bizarre IBM behavior, there are 16 bits of information we
455 need to set, but the card only allows us to send 4 bits at a
456 time. For each byte sent to base_addr, bits 7-4 tell the
457 card which part of the 16 bits we are setting, bits 3-0 contain
458 the actual information */
459
460 /* First nibble provides 4 bits of mmio */
461 i = (mmiobase >> 16) & 0x0F;
462 outb(i, dev->base_addr);
463
464 /* Second nibble provides 3 bits of mmio */
465 i = 0x10 | ((mmiobase >> 12) & 0x0E);
466 outb(i, dev->base_addr);
467
468 /* Third nibble, hard-coded values */
469 i = 0x26;
470 outb(i, dev->base_addr);
471
472 /* Fourth nibble sets shared ram page size */
473
474 /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */
475 i = (sramsize >> 4) & 0x07;
476 i = ((i == 4) ? 3 : i) << 2;
477 i |= 0x30;
478
479 if (ringspeed == 16)
480 i |= 2;
481 if (dev->base_addr == 0xA24)
482 i |= 1;
483 outb(i, dev->base_addr);
484
485 /* 0x40 will release the card for use */
486 outb(0x40, dev->base_addr);
487
488 return;
489}
490
469bf2b9
DB
491static struct pcmcia_device_id ibmtr_ids[] = {
492 PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
493 PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
494 PCMCIA_DEVICE_NULL,
495};
496MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
497
1da177e4
LT
498static struct pcmcia_driver ibmtr_cs_driver = {
499 .owner = THIS_MODULE,
500 .drv = {
501 .name = "ibmtr_cs",
502 },
503 .attach = ibmtr_attach,
1e212f36 504 .event = ibmtr_event,
cc3b4866 505 .remove = ibmtr_detach,
469bf2b9 506 .id_table = ibmtr_ids,
98e4c28b
DB
507 .suspend = ibmtr_suspend,
508 .resume = ibmtr_resume,
1da177e4
LT
509};
510
511static int __init init_ibmtr_cs(void)
512{
513 return pcmcia_register_driver(&ibmtr_cs_driver);
514}
515
516static void __exit exit_ibmtr_cs(void)
517{
518 pcmcia_unregister_driver(&ibmtr_cs_driver);
1da177e4
LT
519}
520
521module_init(init_ibmtr_cs);
522module_exit(exit_ibmtr_cs);