]> bbs.cooldavid.org Git - net-next-2.6.git/blob - drivers/net/pcmcia/ibmtr_cs.c
net/sched: remove unneeded NULL check
[net-next-2.6.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/netdevice.h>
56 #include <linux/trdevice.h>
57 #include <linux/ibmtr.h>
58
59 #include <pcmcia/cs.h>
60 #include <pcmcia/cistpl.h>
61 #include <pcmcia/ds.h>
62
63 #include <asm/uaccess.h>
64 #include <asm/io.h>
65 #include <asm/system.h>
66
67 #define PCMCIA
68 #include "../tokenring/ibmtr.c"
69
70
71 /*====================================================================*/
72
73 /* Parameters that can be set with 'insmod' */
74
75 /* MMIO base address */
76 static u_long mmiobase = 0xce000;
77
78 /* SRAM base address */
79 static u_long srambase = 0xd0000;
80
81 /* SRAM size 8,16,32,64 */
82 static u_long sramsize = 64;
83
84 /* Ringspeed 4,16 */
85 static int ringspeed = 16;
86
87 module_param(mmiobase, ulong, 0);
88 module_param(srambase, ulong, 0);
89 module_param(sramsize, ulong, 0);
90 module_param(ringspeed, int, 0);
91 MODULE_LICENSE("GPL");
92
93 /*====================================================================*/
94
95 static int ibmtr_config(struct pcmcia_device *link);
96 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
97 static void ibmtr_release(struct pcmcia_device *link);
98 static void ibmtr_detach(struct pcmcia_device *p_dev);
99
100 /*====================================================================*/
101
102 typedef struct ibmtr_dev_t {
103         struct pcmcia_device    *p_dev;
104     struct net_device   *dev;
105     window_handle_t     sram_win_handle;
106     struct tok_info     *ti;
107 } ibmtr_dev_t;
108
109 static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
110         ibmtr_dev_t *info = dev_id;
111         struct net_device *dev = info->dev;
112         return tok_interrupt(irq, dev);
113 };
114
115 /*======================================================================
116
117     ibmtr_attach() creates an "instance" of the driver, allocating
118     local data structures for one device.  The device is registered
119     with Card Services.
120
121 ======================================================================*/
122
123 static int __devinit ibmtr_attach(struct pcmcia_device *link)
124 {
125     ibmtr_dev_t *info;
126     struct net_device *dev;
127
128     dev_dbg(&link->dev, "ibmtr_attach()\n");
129
130     /* Create new token-ring device */
131     info = kzalloc(sizeof(*info), GFP_KERNEL);
132     if (!info) return -ENOMEM;
133     dev = alloc_trdev(sizeof(struct tok_info));
134     if (!dev) {
135         kfree(info);
136         return -ENOMEM;
137     }
138
139     info->p_dev = link;
140     link->priv = info;
141     info->ti = netdev_priv(dev);
142
143     link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
144     link->resource[0]->end = 4;
145     link->conf.Attributes = CONF_ENABLE_IRQ;
146     link->conf.IntType = INT_MEMORY_AND_IO;
147     link->conf.Present = PRESENT_OPTION;
148
149     info->dev = dev;
150
151     return ibmtr_config(link);
152 } /* ibmtr_attach */
153
154 /*======================================================================
155
156     This deletes a driver "instance".  The device is de-registered
157     with Card Services.  If it has been released, all local data
158     structures are freed.  Otherwise, the structures will be freed
159     when the device is released.
160
161 ======================================================================*/
162
163 static void ibmtr_detach(struct pcmcia_device *link)
164 {
165     struct ibmtr_dev_t *info = link->priv;
166     struct net_device *dev = info->dev;
167      struct tok_info *ti = netdev_priv(dev);
168
169     dev_dbg(&link->dev, "ibmtr_detach\n");
170     
171     /* 
172      * When the card removal interrupt hits tok_interrupt(), 
173      * bail out early, so we don't crash the machine 
174      */
175     ti->sram_phys |= 1;
176
177     unregister_netdev(dev);
178     
179     del_timer_sync(&(ti->tr_timer));
180
181     ibmtr_release(link);
182
183     free_netdev(dev);
184     kfree(info);
185 } /* ibmtr_detach */
186
187 /*======================================================================
188
189     ibmtr_config() is scheduled to run after a CARD_INSERTION event
190     is received, to configure the PCMCIA socket, and to make the
191     token-ring device available to the system.
192
193 ======================================================================*/
194
195 static int __devinit ibmtr_config(struct pcmcia_device *link)
196 {
197     ibmtr_dev_t *info = link->priv;
198     struct net_device *dev = info->dev;
199     struct tok_info *ti = netdev_priv(dev);
200     win_req_t req;
201     int i, ret;
202
203     dev_dbg(&link->dev, "ibmtr_config\n");
204
205     link->conf.ConfigIndex = 0x61;
206     link->io_lines = 16;
207
208     /* Determine if this is PRIMARY or ALTERNATE. */
209
210     /* Try PRIMARY card at 0xA20-0xA23 */
211     link->resource[0]->start = 0xA20;
212     i = pcmcia_request_io(link);
213     if (i != 0) {
214         /* Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. */
215         link->resource[0]->start = 0xA24;
216         ret = pcmcia_request_io(link);
217         if (ret)
218                 goto failed;
219     }
220     dev->base_addr = link->resource[0]->start;
221
222     ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
223     if (ret)
224             goto failed;
225     dev->irq = link->irq;
226     ti->irq = link->irq;
227     ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
228
229     /* Allocate the MMIO memory window */
230     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
231     req.Attributes |= WIN_USE_WAIT;
232     req.Base = 0; 
233     req.Size = 0x2000;
234     req.AccessSpeed = 250;
235     ret = pcmcia_request_window(link, &req, &link->win);
236     if (ret)
237             goto failed;
238
239     ret = pcmcia_map_mem_page(link, link->win, mmiobase);
240     if (ret)
241             goto failed;
242     ti->mmio = ioremap(req.Base, req.Size);
243
244     /* Allocate the SRAM memory window */
245     req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
246     req.Attributes |= WIN_USE_WAIT;
247     req.Base = 0;
248     req.Size = sramsize * 1024;
249     req.AccessSpeed = 250;
250     ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
251     if (ret)
252             goto failed;
253
254     ret = pcmcia_map_mem_page(link, info->sram_win_handle, srambase);
255     if (ret)
256             goto failed;
257
258     ti->sram_base = srambase >> 12;
259     ti->sram_virt = ioremap(req.Base, req.Size);
260     ti->sram_phys = req.Base;
261
262     ret = pcmcia_request_configuration(link, &link->conf);
263     if (ret)
264             goto failed;
265
266     /*  Set up the Token-Ring Controller Configuration Register and
267         turn on the card.  Check the "Local Area Network Credit Card
268         Adapters Technical Reference"  SC30-3585 for this info.  */
269     ibmtr_hw_setup(dev, mmiobase);
270
271     SET_NETDEV_DEV(dev, &link->dev);
272
273     i = ibmtr_probe_card(dev);
274     if (i != 0) {
275         printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n");
276         goto failed;
277     }
278
279     printk(KERN_INFO
280            "%s: port %#3lx, irq %d,  mmio %#5lx, sram %#5lx, hwaddr=%pM\n",
281            dev->name, dev->base_addr, dev->irq,
282            (u_long)ti->mmio, (u_long)(ti->sram_base << 12),
283            dev->dev_addr);
284     return 0;
285
286 failed:
287     ibmtr_release(link);
288     return -ENODEV;
289 } /* ibmtr_config */
290
291 /*======================================================================
292
293     After a card is removed, ibmtr_release() will unregister the net
294     device, and release the PCMCIA configuration.  If the device is
295     still open, this will be postponed until it is closed.
296
297 ======================================================================*/
298
299 static void ibmtr_release(struct pcmcia_device *link)
300 {
301         ibmtr_dev_t *info = link->priv;
302         struct net_device *dev = info->dev;
303
304         dev_dbg(&link->dev, "ibmtr_release\n");
305
306         if (link->win) {
307                 struct tok_info *ti = netdev_priv(dev);
308                 iounmap(ti->mmio);
309         }
310         pcmcia_disable_device(link);
311 }
312
313 static int ibmtr_suspend(struct pcmcia_device *link)
314 {
315         ibmtr_dev_t *info = link->priv;
316         struct net_device *dev = info->dev;
317
318         if (link->open)
319                 netif_device_detach(dev);
320
321         return 0;
322 }
323
324 static int __devinit ibmtr_resume(struct pcmcia_device *link)
325 {
326         ibmtr_dev_t *info = link->priv;
327         struct net_device *dev = info->dev;
328
329         if (link->open) {
330                 ibmtr_probe(dev);       /* really? */
331                 netif_device_attach(dev);
332         }
333
334         return 0;
335 }
336
337
338 /*====================================================================*/
339
340 static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase)
341 {
342     int i;
343
344     /* Bizarre IBM behavior, there are 16 bits of information we
345        need to set, but the card only allows us to send 4 bits at a 
346        time.  For each byte sent to base_addr, bits 7-4 tell the
347        card which part of the 16 bits we are setting, bits 3-0 contain 
348        the actual information */
349
350     /* First nibble provides 4 bits of mmio */
351     i = (mmiobase >> 16) & 0x0F;
352     outb(i, dev->base_addr);
353
354     /* Second nibble provides 3 bits of mmio */
355     i = 0x10 | ((mmiobase >> 12) & 0x0E);
356     outb(i, dev->base_addr);
357
358     /* Third nibble, hard-coded values */
359     i = 0x26;
360     outb(i, dev->base_addr);
361
362     /* Fourth nibble sets shared ram page size */
363
364     /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */          
365     i = (sramsize >> 4) & 0x07;
366     i = ((i == 4) ? 3 : i) << 2;
367     i |= 0x30;
368
369     if (ringspeed == 16)
370         i |= 2;
371     if (dev->base_addr == 0xA24)
372         i |= 1;
373     outb(i, dev->base_addr);
374
375     /* 0x40 will release the card for use */
376     outb(0x40, dev->base_addr);
377 }
378
379 static struct pcmcia_device_id ibmtr_ids[] = {
380         PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
381         PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
382         PCMCIA_DEVICE_NULL,
383 };
384 MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids);
385
386 static struct pcmcia_driver ibmtr_cs_driver = {
387         .owner          = THIS_MODULE,
388         .drv            = {
389                 .name   = "ibmtr_cs",
390         },
391         .probe          = ibmtr_attach,
392         .remove         = ibmtr_detach,
393         .id_table       = ibmtr_ids,
394         .suspend        = ibmtr_suspend,
395         .resume         = ibmtr_resume,
396 };
397
398 static int __init init_ibmtr_cs(void)
399 {
400         return pcmcia_register_driver(&ibmtr_cs_driver);
401 }
402
403 static void __exit exit_ibmtr_cs(void)
404 {
405         pcmcia_unregister_driver(&ibmtr_cs_driver);
406 }
407
408 module_init(init_ibmtr_cs);
409 module_exit(exit_ibmtr_cs);