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