[PATCH] pcmcia: remove dev_link_t and client_handle_t indirection
[linux-2.6] / 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/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
73 static int pc_debug = PCMCIA_DEBUG;
74 module_param(pc_debug, int, 0);
75 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
76 static 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 */
89 static u_long mmiobase = 0xce000;
90
91 /* SRAM base address */
92 static u_long srambase = 0xd0000;
93
94 /* SRAM size 8,16,32,64 */
95 static u_long sramsize = 64;
96
97 /* Ringspeed 4,16 */
98 static int ringspeed = 16;
99
100 module_param(mmiobase, ulong, 0);
101 module_param(srambase, ulong, 0);
102 module_param(sramsize, ulong, 0);
103 module_param(ringspeed, int, 0);
104 MODULE_LICENSE("GPL");
105
106 /*====================================================================*/
107
108 static void ibmtr_config(struct pcmcia_device *link);
109 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
110 static void ibmtr_release(struct pcmcia_device *link);
111 static void ibmtr_detach(struct pcmcia_device *p_dev);
112
113 /*====================================================================*/
114
115 typedef struct ibmtr_dev_t {
116         struct pcmcia_device    *p_dev;
117     struct net_device   *dev;
118     dev_node_t          node;
119     window_handle_t     sram_win_handle;
120     struct tok_info     *ti;
121 } ibmtr_dev_t;
122
123 static void netdev_get_drvinfo(struct net_device *dev,
124                                struct ethtool_drvinfo *info)
125 {
126         strcpy(info->driver, "ibmtr_cs");
127 }
128
129 static struct ethtool_ops netdev_ethtool_ops = {
130         .get_drvinfo            = netdev_get_drvinfo,
131 };
132
133 /*======================================================================
134
135     ibmtr_attach() creates an "instance" of the driver, allocating
136     local data structures for one device.  The device is registered
137     with Card Services.
138
139 ======================================================================*/
140
141 static int ibmtr_attach(struct pcmcia_device *link)
142 {
143     ibmtr_dev_t *info;
144     struct net_device *dev;
145
146     DEBUG(0, "ibmtr_attach()\n");
147
148     /* Create new token-ring device */
149     info = kmalloc(sizeof(*info), GFP_KERNEL); 
150     if (!info) return -ENOMEM;
151     memset(info,0,sizeof(*info));
152     dev = alloc_trdev(sizeof(struct tok_info));
153     if (!dev) {
154         kfree(info);
155         return -ENOMEM;
156     }
157
158     info->p_dev = link;
159     link->priv = info;
160     info->ti = netdev_priv(dev);
161
162     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
163     link->io.NumPorts1 = 4;
164     link->io.IOAddrLines = 16;
165     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
166     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
167     link->irq.Handler = &tok_interrupt;
168     link->conf.Attributes = CONF_ENABLE_IRQ;
169     link->conf.IntType = INT_MEMORY_AND_IO;
170     link->conf.Present = PRESENT_OPTION;
171
172     link->irq.Instance = info->dev = dev;
173
174     SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
175
176     link->state |= DEV_PRESENT;
177     ibmtr_config(link);
178
179     return 0;
180 } /* ibmtr_attach */
181
182 /*======================================================================
183
184     This deletes a driver "instance".  The device is de-registered
185     with Card Services.  If it has been released, all local data
186     structures are freed.  Otherwise, the structures will be freed
187     when the device is released.
188
189 ======================================================================*/
190
191 static void ibmtr_detach(struct pcmcia_device *link)
192 {
193     struct ibmtr_dev_t *info = link->priv;
194     struct net_device *dev = info->dev;
195
196     DEBUG(0, "ibmtr_detach(0x%p)\n", link);
197
198     if (link->dev_node)
199         unregister_netdev(dev);
200
201     {
202         struct tok_info *ti = netdev_priv(dev);
203         del_timer_sync(&(ti->tr_timer));
204     }
205     if (link->state & DEV_CONFIG)
206         ibmtr_release(link);
207
208     free_netdev(dev);
209     kfree(info);
210 } /* ibmtr_detach */
211
212 /*======================================================================
213
214     ibmtr_config() is scheduled to run after a CARD_INSERTION event
215     is received, to configure the PCMCIA socket, and to make the
216     token-ring device available to the system.
217
218 ======================================================================*/
219
220 #define CS_CHECK(fn, ret) \
221 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222
223 static void ibmtr_config(struct pcmcia_device *link)
224 {
225     ibmtr_dev_t *info = link->priv;
226     struct net_device *dev = info->dev;
227     struct tok_info *ti = netdev_priv(dev);
228     tuple_t tuple;
229     cisparse_t parse;
230     win_req_t req;
231     memreq_t mem;
232     int i, last_ret, last_fn;
233     u_char buf[64];
234
235     DEBUG(0, "ibmtr_config(0x%p)\n", link);
236
237     tuple.Attributes = 0;
238     tuple.TupleData = buf;
239     tuple.TupleDataMax = 64;
240     tuple.TupleOffset = 0;
241     tuple.DesiredTuple = CISTPL_CONFIG;
242     CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
243     CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
244     CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
245     link->conf.ConfigBase = parse.config.base;
246
247     /* Configure card */
248     link->state |= DEV_CONFIG;
249
250     link->conf.ConfigIndex = 0x61;
251
252     /* Determine if this is PRIMARY or ALTERNATE. */
253
254     /* Try PRIMARY card at 0xA20-0xA23 */
255     link->io.BasePort1 = 0xA20;
256     i = pcmcia_request_io(link, &link->io);
257     if (i != CS_SUCCESS) {
258         /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
259         link->io.BasePort1 = 0xA24;
260         CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
261     }
262     dev->base_addr = link->io.BasePort1;
263
264     CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
265     dev->irq = link->irq.AssignedIRQ;
266     ti->irq = link->irq.AssignedIRQ;
267     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
268
269     /* Allocate the MMIO memory window */
270     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
271     req.Attributes |= WIN_USE_WAIT;
272     req.Base = 0; 
273     req.Size = 0x2000;
274     req.AccessSpeed = 250;
275     CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
276
277     mem.CardOffset = mmiobase;
278     mem.Page = 0;
279     CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
280     ti->mmio = ioremap(req.Base, req.Size);
281
282     /* Allocate the SRAM memory window */
283     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
284     req.Attributes |= WIN_USE_WAIT;
285     req.Base = 0;
286     req.Size = sramsize * 1024;
287     req.AccessSpeed = 250;
288     CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
289
290     mem.CardOffset = srambase;
291     mem.Page = 0;
292     CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
293
294     ti->sram_base = mem.CardOffset >> 12;
295     ti->sram_virt = ioremap(req.Base, req.Size);
296     ti->sram_phys = req.Base;
297
298     CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
299
300     /*  Set up the Token-Ring Controller Configuration Register and
301         turn on the card.  Check the "Local Area Network Credit Card
302         Adapters Technical Reference"  SC30-3585 for this info.  */
303     ibmtr_hw_setup(dev, mmiobase);
304
305     link->dev_node = &info->node;
306     link->state &= ~DEV_CONFIG_PENDING;
307     SET_NETDEV_DEV(dev, &handle_to_dev(link));
308
309     i = ibmtr_probe_card(dev);
310     if (i != 0) {
311         printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
312         link->dev_node = NULL;
313         goto failed;
314     }
315
316     strcpy(info->node.dev_name, dev->name);
317
318     printk(KERN_INFO "%s: port %#3lx, irq %d,",
319            dev->name, dev->base_addr, dev->irq);
320     printk (" mmio %#5lx,", (u_long)ti->mmio);
321     printk (" sram %#5lx,", (u_long)ti->sram_base << 12);
322     printk ("\n" KERN_INFO "  hwaddr=");
323     for (i = 0; i < TR_ALEN; i++)
324         printk("%02X", dev->dev_addr[i]);
325     printk("\n");
326     return;
327
328 cs_failed:
329     cs_error(link, last_fn, last_ret);
330 failed:
331     ibmtr_release(link);
332 } /* ibmtr_config */
333
334 /*======================================================================
335
336     After a card is removed, ibmtr_release() will unregister the net
337     device, and release the PCMCIA configuration.  If the device is
338     still open, this will be postponed until it is closed.
339
340 ======================================================================*/
341
342 static void ibmtr_release(struct pcmcia_device *link)
343 {
344         ibmtr_dev_t *info = link->priv;
345         struct net_device *dev = info->dev;
346
347         DEBUG(0, "ibmtr_release(0x%p)\n", link);
348
349         if (link->win) {
350                 struct tok_info *ti = netdev_priv(dev);
351                 iounmap(ti->mmio);
352                 pcmcia_release_window(info->sram_win_handle);
353         }
354         pcmcia_disable_device(link);
355 }
356
357 static int ibmtr_suspend(struct pcmcia_device *link)
358 {
359         ibmtr_dev_t *info = link->priv;
360         struct net_device *dev = info->dev;
361
362         if ((link->state & DEV_CONFIG) && (link->open))
363                 netif_device_detach(dev);
364
365         return 0;
366 }
367
368 static int ibmtr_resume(struct pcmcia_device *link)
369 {
370         ibmtr_dev_t *info = link->priv;
371         struct net_device *dev = info->dev;
372
373         if ((link->state & DEV_CONFIG) && (link->open)) {
374                 ibmtr_probe(dev);       /* really? */
375                 netif_device_attach(dev);
376         }
377
378         return 0;
379 }
380
381
382 /*====================================================================*/
383
384 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
385 {
386     int i;
387
388     /* Bizarre IBM behavior, there are 16 bits of information we
389        need to set, but the card only allows us to send 4 bits at a 
390        time.  For each byte sent to base_addr, bits 7-4 tell the
391        card which part of the 16 bits we are setting, bits 3-0 contain 
392        the actual information */
393
394     /* First nibble provides 4 bits of mmio */
395     i = (mmiobase >> 16) & 0x0F;
396     outb(i, dev->base_addr);
397
398     /* Second nibble provides 3 bits of mmio */
399     i = 0x10 | ((mmiobase >> 12) & 0x0E);
400     outb(i, dev->base_addr);
401
402     /* Third nibble, hard-coded values */
403     i = 0x26;
404     outb(i, dev->base_addr);
405
406     /* Fourth nibble sets shared ram page size */
407
408     /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */          
409     i = (sramsize >> 4) & 0x07;
410     i = ((i == 4) ? 3 : i) << 2;
411     i |= 0x30;
412
413     if (ringspeed == 16)
414         i |= 2;
415     if (dev->base_addr == 0xA24)
416         i |= 1;
417     outb(i, dev->base_addr);
418
419     /* 0x40 will release the card for use */
420     outb(0x40, dev->base_addr);
421
422     return;
423 }
424
425 static struct pcmcia_device_id ibmtr_ids[] = {
426         PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
427         PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
428         PCMCIA_DEVICE_NULL,
429 };
430 MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
431
432 static struct pcmcia_driver ibmtr_cs_driver = {
433         .owner          = THIS_MODULE,
434         .drv            = {
435                 .name   = "ibmtr_cs",
436         },
437         .probe          = ibmtr_attach,
438         .remove         = ibmtr_detach,
439         .id_table       = ibmtr_ids,
440         .suspend        = ibmtr_suspend,
441         .resume         = ibmtr_resume,
442 };
443
444 static int __init init_ibmtr_cs(void)
445 {
446         return pcmcia_register_driver(&ibmtr_cs_driver);
447 }
448
449 static void __exit exit_ibmtr_cs(void)
450 {
451         pcmcia_unregister_driver(&ibmtr_cs_driver);
452 }
453
454 module_init(init_ibmtr_cs);
455 module_exit(exit_ibmtr_cs);