ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / net / wireless / airo_cs.c
1 /*======================================================================
2
3     Aironet driver for 4500 and 4800 series cards
4
5     This code is released under both the GPL version 2 and BSD licenses.
6     Either license may be used.  The respective licenses are found at
7     the end of this file.
8
9     This code was developed by Benjamin Reed <breed@users.sourceforge.net>
10     including portions of which come from the Aironet PC4500
11     Developer's Reference Manual and used with permission.  Copyright
12     (C) 1999 Benjamin Reed.  All Rights Reserved.  Permission to use
13     code in the Developer's manual was granted for this driver by
14     Aironet.
15
16     In addition this module was derived from dummy_cs.
17     The initial developer of dummy_cs is David A. Hinds
18     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
19     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.    
20     
21 ======================================================================*/
22
23 #include <linux/config.h>
24 #ifdef __IN_PCMCIA_PACKAGE__
25 #include <pcmcia/k_compat.h>
26 #endif
27 #include <linux/init.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/ptrace.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/netdevice.h>
35
36 #include <pcmcia/version.h>
37 #include <pcmcia/cs_types.h>
38 #include <pcmcia/cs.h>
39 #include <pcmcia/cistpl.h>
40 #include <pcmcia/cisreg.h>
41 #include <pcmcia/ds.h>
42
43 #include <asm/io.h>
44 #include <asm/system.h>
45
46 /*
47    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
48    you do not define PCMCIA_DEBUG at all, all the debug code will be
49    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
50    be present but disabled -- but it can then be enabled for specific
51    modules at load time with a 'pc_debug=#' option to insmod.
52 */
53 #ifdef PCMCIA_DEBUG
54 static int pc_debug = PCMCIA_DEBUG;
55 MODULE_PARM(pc_debug, "i");
56 static char *version = "$Revision: 1.2 $";
57 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
58 #else
59 #define DEBUG(n, args...)
60 #endif
61
62 /*====================================================================*/
63
64 /* Parameters that can be set with 'insmod' */
65
66 /* The old way: bit map of interrupts to choose from */
67 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
68 static u_int irq_mask = 0xdeb8;
69 /* Newer, simpler way of listing specific interrupts */
70 static int irq_list[4] = { -1 };
71
72 MODULE_AUTHOR("Benjamin Reed");
73 MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
74                    cards.  This is the module that links the PCMCIA card \
75                    with the airo module.");
76 MODULE_LICENSE("Dual BSD/GPL");
77 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");
78 MODULE_PARM(irq_mask, "i");
79 MODULE_PARM(irq_list, "1-4i");
80
81 /*====================================================================*/
82
83 /*
84    The event() function is this driver's Card Services event handler.
85    It will be called by Card Services when an appropriate card status
86    event is received.  The config() and release() entry points are
87    used to configure or release a socket, in response to card
88    insertion and ejection events.  They are invoked from the airo_cs
89    event handler. 
90 */
91
92 struct net_device *init_airo_card( int, int, int );
93 void stop_airo_card( struct net_device *, int );
94 int reset_airo_card( struct net_device * );
95
96 static void airo_config(dev_link_t *link);
97 static void airo_release(dev_link_t *link);
98 static int airo_event(event_t event, int priority,
99                        event_callback_args_t *args);
100
101 /*
102    The attach() and detach() entry points are used to create and destroy
103    "instances" of the driver, where each instance represents everything
104    needed to manage one actual PCMCIA card.
105 */
106
107 static dev_link_t *airo_attach(void);
108 static void airo_detach(dev_link_t *);
109
110 /*
111    You'll also need to prototype all the functions that will actually
112    be used to talk to your device.  See 'pcmem_cs' for a good example
113    of a fully self-sufficient driver; the other drivers rely more or
114    less on other parts of the kernel.
115 */
116
117 /*
118    The dev_info variable is the "key" that is used to match up this
119    device driver with appropriate cards, through the card configuration
120    database.
121 */
122
123 static dev_info_t dev_info = "airo_cs";
124
125 /*
126    A linked list of "instances" of the  aironet device.  Each actual
127    PCMCIA card corresponds to one device instance, and is described
128    by one dev_link_t structure (defined in ds.h).
129
130    You may not want to use a linked list for this -- for example, the
131    memory card driver uses an array of dev_link_t pointers, where minor
132    device numbers are used to derive the corresponding array index.
133 */
134
135 static dev_link_t *dev_list = NULL;
136
137 /*
138    A dev_link_t structure has fields for most things that are needed
139    to keep track of a socket, but there will usually be some device
140    specific information that also needs to be kept track of.  The
141    'priv' pointer in a dev_link_t structure can be used to point to
142    a device-specific private data structure, like this.
143
144    A driver needs to provide a dev_node_t structure for each device
145    on a card.  In some cases, there is only one device per card (for
146    example, ethernet cards, modems).  In other cases, there may be
147    many actual or logical devices (SCSI adapters, memory cards with
148    multiple partitions).  The dev_node_t structures need to be kept
149    in a linked list starting at the 'dev' field of a dev_link_t
150    structure.  We allocate them in the card's private data structure,
151    because they generally shouldn't be allocated dynamically.
152
153    In this case, we also provide a flag to indicate if a device is
154    "stopped" due to a power management event, or card ejection.  The
155    device IO routines can use a flag like this to throttle IO to a
156    card that is not ready to accept it.
157 */
158    
159 typedef struct local_info_t {
160         dev_node_t      node;
161         struct net_device *eth_dev;
162 } local_info_t;
163
164 /*======================================================================
165   
166   airo_attach() creates an "instance" of the driver, allocating
167   local data structures for one device.  The device is registered
168   with Card Services.
169   
170   The dev_link structure is initialized, but we don't actually
171   configure the card at this point -- we wait until we receive a
172   card insertion event.
173   
174   ======================================================================*/
175
176 static dev_link_t *airo_attach(void)
177 {
178         client_reg_t client_reg;
179         dev_link_t *link;
180         local_info_t *local;
181         int ret, i;
182         
183         DEBUG(0, "airo_attach()\n");
184
185         /* Initialize the dev_link_t structure */
186         link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
187         if (!link) {
188                 printk(KERN_ERR "airo_cs: no memory for new device\n");
189                 return NULL;
190         }
191         memset(link, 0, sizeof(struct dev_link_t));
192         
193         /* Interrupt setup */
194         link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
195         link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
196         if (irq_list[0] == -1)
197                 link->irq.IRQInfo2 = irq_mask;
198         else
199                 for (i = 0; i < 4; i++)
200                         link->irq.IRQInfo2 |= 1 << irq_list[i];
201         link->irq.Handler = NULL;
202         
203         /*
204           General socket configuration defaults can go here.  In this
205           client, we assume very little, and rely on the CIS for almost
206           everything.  In most clients, many details (i.e., number, sizes,
207           and attributes of IO windows) are fixed by the nature of the
208           device, and can be hard-wired here.
209         */
210         link->conf.Attributes = 0;
211         link->conf.Vcc = 50;
212         link->conf.IntType = INT_MEMORY_AND_IO;
213         
214         /* Allocate space for private device-specific data */
215         local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
216         if (!local) {
217                 printk(KERN_ERR "airo_cs: no memory for new device\n");
218                 kfree (link);
219                 return NULL;
220         }
221         memset(local, 0, sizeof(local_info_t));
222         link->priv = local;
223         
224         /* Register with Card Services */
225         link->next = dev_list;
226         dev_list = link;
227         client_reg.dev_info = &dev_info;
228         client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
229         client_reg.EventMask =
230                 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
231                 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
232                 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
233         client_reg.event_handler = &airo_event;
234         client_reg.Version = 0x0210;
235         client_reg.event_callback_args.client_data = link;
236         ret = pcmcia_register_client(&link->handle, &client_reg);
237         if (ret != 0) {
238                 cs_error(link->handle, RegisterClient, ret);
239                 airo_detach(link);
240                 return NULL;
241         }
242         
243         return link;
244 } /* airo_attach */
245
246 /*======================================================================
247   
248   This deletes a driver "instance".  The device is de-registered
249   with Card Services.  If it has been released, all local data
250   structures are freed.  Otherwise, the structures will be freed
251   when the device is released.
252   
253   ======================================================================*/
254
255 static void airo_detach(dev_link_t *link)
256 {
257         dev_link_t **linkp;
258         
259         DEBUG(0, "airo_detach(0x%p)\n", link);
260         
261         /* Locate device structure */
262         for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
263                 if (*linkp == link) break;
264         if (*linkp == NULL)
265                 return;
266         
267         if (link->state & DEV_CONFIG)
268                 airo_release(link);
269         
270         if ( ((local_info_t*)link->priv)->eth_dev ) {
271                 stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
272         }
273         ((local_info_t*)link->priv)->eth_dev = 0;   
274         
275         /* Break the link with Card Services */
276         if (link->handle)
277                 pcmcia_deregister_client(link->handle);
278         
279         
280         
281         /* Unlink device structure, free pieces */
282         *linkp = link->next;
283         if (link->priv) {
284                 kfree(link->priv);
285         }
286         kfree(link);
287         
288 } /* airo_detach */
289
290 /*======================================================================
291   
292   airo_config() is scheduled to run after a CARD_INSERTION event
293   is received, to configure the PCMCIA socket, and to make the
294   device available to the system.
295   
296   ======================================================================*/
297
298 #define CS_CHECK(fn, ret) \
299 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
300
301 static void airo_config(dev_link_t *link)
302 {
303         client_handle_t handle;
304         tuple_t tuple;
305         cisparse_t parse;
306         local_info_t *dev;
307         int last_fn, last_ret;
308         u_char buf[64];
309         win_req_t req;
310         memreq_t map;
311         
312         handle = link->handle;
313         dev = link->priv;
314
315         DEBUG(0, "airo_config(0x%p)\n", link);
316         
317         /*
318           This reads the card's CONFIG tuple to find its configuration
319           registers.
320         */
321         tuple.DesiredTuple = CISTPL_CONFIG;
322         tuple.Attributes = 0;
323         tuple.TupleData = buf;
324         tuple.TupleDataMax = sizeof(buf);
325         tuple.TupleOffset = 0;
326         CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
327         CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
328         CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
329         link->conf.ConfigBase = parse.config.base;
330         link->conf.Present = parse.config.rmask[0];
331         
332         /* Configure card */
333         link->state |= DEV_CONFIG;
334         
335         /*
336           In this loop, we scan the CIS for configuration table entries,
337           each of which describes a valid card configuration, including
338           voltage, IO window, memory window, and interrupt settings.
339           
340           We make no assumptions about the card to be configured: we use
341           just the information available in the CIS.  In an ideal world,
342           this would work for any PCMCIA card, but it requires a complete
343           and accurate CIS.  In practice, a driver usually "knows" most of
344           these things without consulting the CIS, and most client drivers
345           will only use the CIS to fill in implementation-defined details.
346         */
347         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
348         CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
349         while (1) {
350                 cistpl_cftable_entry_t dflt = { 0 };
351                 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
352                 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
353                                 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
354                         goto next_entry;
355                 
356                 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
357                 if (cfg->index == 0) goto next_entry;
358                 link->conf.ConfigIndex = cfg->index;
359                 
360                 /* Does this card need audio output? */
361                 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
362                         link->conf.Attributes |= CONF_ENABLE_SPKR;
363                         link->conf.Status = CCSR_AUDIO_ENA;
364                 }
365                 
366                 /* Use power settings for Vcc and Vpp if present */
367                 /*  Note that the CIS values need to be rescaled */
368                 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
369                         link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
370                 else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
371                         link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
372                 
373                 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
374                         link->conf.Vpp1 = link->conf.Vpp2 =
375                                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
376                 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
377                         link->conf.Vpp1 = link->conf.Vpp2 =
378                                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
379                 
380                 /* Do we need to allocate an interrupt? */
381                 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
382                         link->conf.Attributes |= CONF_ENABLE_IRQ;
383                 
384                 /* IO window settings */
385                 link->io.NumPorts1 = link->io.NumPorts2 = 0;
386                 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
387                         cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
388                         link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
389                         if (!(io->flags & CISTPL_IO_8BIT))
390                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
391                         if (!(io->flags & CISTPL_IO_16BIT))
392                                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
393                         link->io.BasePort1 = io->win[0].base;
394                         link->io.NumPorts1 = io->win[0].len;
395                         if (io->nwin > 1) {
396                                 link->io.Attributes2 = link->io.Attributes1;
397                                 link->io.BasePort2 = io->win[1].base;
398                                 link->io.NumPorts2 = io->win[1].len;
399                         }
400                 }
401                 
402                 /* This reserves IO space but doesn't actually enable it */
403                 if (pcmcia_request_io(link->handle, &link->io) != 0)
404                         goto next_entry;
405                 
406                 /*
407                   Now set up a common memory window, if needed.  There is room
408                   in the dev_link_t structure for one memory window handle,
409                   but if the base addresses need to be saved, or if multiple
410                   windows are needed, the info should go in the private data
411                   structure for this device.
412                   
413                   Note that the memory window base is a physical address, and
414                   needs to be mapped to virtual space with ioremap() before it
415                   is used.
416                 */
417                 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
418                         cistpl_mem_t *mem =
419                                 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
420                         req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
421                         req.Base = mem->win[0].host_addr;
422                         req.Size = mem->win[0].len;
423                         req.AccessSpeed = 0;
424                         if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
425                                 goto next_entry;
426                         map.Page = 0; map.CardOffset = mem->win[0].card_addr;
427                         if (pcmcia_map_mem_page(link->win, &map) != 0)
428                                 goto next_entry;
429                 }
430                 /* If we got this far, we're cool! */
431                 break;
432                 
433         next_entry:
434                 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
435         }
436         
437     /*
438       Allocate an interrupt line.  Note that this does not assign a
439       handler to the interrupt, unless the 'Handler' member of the
440       irq structure is initialized.
441     */
442         if (link->conf.Attributes & CONF_ENABLE_IRQ)
443                 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
444         
445         /*
446           This actually configures the PCMCIA socket -- setting up
447           the I/O windows and the interrupt mapping, and putting the
448           card and host interface into "Memory and IO" mode.
449         */
450         CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
451         ((local_info_t*)link->priv)->eth_dev = 
452                 init_airo_card( link->irq.AssignedIRQ,
453                                 link->io.BasePort1, 1 );
454         if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
455         
456         /*
457           At this point, the dev_node_t structure(s) need to be
458           initialized and arranged in a linked list at link->dev.
459         */
460         strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
461         dev->node.major = dev->node.minor = 0;
462         link->dev = &dev->node;
463         
464         /* Finally, report what we've done */
465         printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
466                dev->node.dev_name, link->conf.ConfigIndex,
467                link->conf.Vcc/10, link->conf.Vcc%10);
468         if (link->conf.Vpp1)
469                 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
470         if (link->conf.Attributes & CONF_ENABLE_IRQ)
471                 printk(", irq %d", link->irq.AssignedIRQ);
472         if (link->io.NumPorts1)
473                 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
474                        link->io.BasePort1+link->io.NumPorts1-1);
475         if (link->io.NumPorts2)
476                 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
477                        link->io.BasePort2+link->io.NumPorts2-1);
478         if (link->win)
479                 printk(", mem 0x%06lx-0x%06lx", req.Base,
480                        req.Base+req.Size-1);
481         printk("\n");
482         
483         link->state &= ~DEV_CONFIG_PENDING;
484         return;
485         
486  cs_failed:
487         cs_error(link->handle, last_fn, last_ret);
488         airo_release(link);
489         
490 } /* airo_config */
491
492 /*======================================================================
493   
494   After a card is removed, airo_release() will unregister the
495   device, and release the PCMCIA configuration.  If the device is
496   still open, this will be postponed until it is closed.
497   
498   ======================================================================*/
499
500 static void airo_release(dev_link_t *link)
501 {
502         DEBUG(0, "airo_release(0x%p)\n", link);
503         
504         /* Unlink the device chain */
505         link->dev = NULL;
506         
507         /*
508           In a normal driver, additional code may be needed to release
509           other kernel data structures associated with this device. 
510         */
511         
512         /* Don't bother checking to see if these succeed or not */
513         if (link->win)
514                 pcmcia_release_window(link->win);
515         pcmcia_release_configuration(link->handle);
516         if (link->io.NumPorts1)
517                 pcmcia_release_io(link->handle, &link->io);
518         if (link->irq.AssignedIRQ)
519                 pcmcia_release_irq(link->handle, &link->irq);
520         link->state &= ~DEV_CONFIG;
521 }
522
523 /*======================================================================
524   
525   The card status event handler.  Mostly, this schedules other
526   stuff to run after an event is received.
527
528   When a CARD_REMOVAL event is received, we immediately set a
529   private flag to block future accesses to this device.  All the
530   functions that actually access the device should check this flag
531   to make sure the card is still present.
532   
533   ======================================================================*/
534
535 static int airo_event(event_t event, int priority,
536                       event_callback_args_t *args)
537 {
538         dev_link_t *link = args->client_data;
539         local_info_t *local = link->priv;
540         
541         DEBUG(1, "airo_event(0x%06x)\n", event);
542         
543         switch (event) {
544         case CS_EVENT_CARD_REMOVAL:
545                 link->state &= ~DEV_PRESENT;
546                 if (link->state & DEV_CONFIG) {
547                         netif_device_detach(local->eth_dev);
548                         airo_release(link);
549                 }
550                 break;
551         case CS_EVENT_CARD_INSERTION:
552                 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
553                 airo_config(link);
554                 break;
555         case CS_EVENT_PM_SUSPEND:
556                 link->state |= DEV_SUSPEND;
557                 /* Fall through... */
558         case CS_EVENT_RESET_PHYSICAL:
559                 if (link->state & DEV_CONFIG) {
560                         netif_device_detach(local->eth_dev);
561                         pcmcia_release_configuration(link->handle);
562                 }
563                 break;
564         case CS_EVENT_PM_RESUME:
565                 link->state &= ~DEV_SUSPEND;
566                 /* Fall through... */
567         case CS_EVENT_CARD_RESET:
568                 if (link->state & DEV_CONFIG) {
569                         pcmcia_request_configuration(link->handle, &link->conf);
570                         reset_airo_card(local->eth_dev);
571                         netif_device_attach(local->eth_dev);
572                 }
573                 break;
574         }
575         return 0;
576 } /* airo_event */
577
578 static struct pcmcia_driver airo_driver = {
579         .owner          = THIS_MODULE,
580         .drv            = {
581                 .name   = "airo_cs",
582         },
583         .attach         = airo_attach,
584         .detach         = airo_detach,
585 };
586
587 static int airo_cs_init(void)
588 {
589         return pcmcia_register_driver(&airo_driver);
590 }
591
592 static void airo_cs_cleanup(void)
593 {
594         pcmcia_unregister_driver(&airo_driver);
595
596         /* XXX: this really needs to move into generic code.. */
597         while (dev_list != NULL) {
598                 if (dev_list->state & DEV_CONFIG)
599                         airo_release(dev_list);
600                 airo_detach(dev_list);
601         }
602 }
603
604 /*
605     This program is free software; you can redistribute it and/or
606     modify it under the terms of the GNU General Public License
607     as published by the Free Software Foundation; either version 2
608     of the License, or (at your option) any later version.
609
610     This program is distributed in the hope that it will be useful,
611     but WITHOUT ANY WARRANTY; without even the implied warranty of
612     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
613     GNU General Public License for more details.
614
615     In addition:
616
617     Redistribution and use in source and binary forms, with or without
618     modification, are permitted provided that the following conditions
619     are met:
620
621     1. Redistributions of source code must retain the above copyright
622        notice, this list of conditions and the following disclaimer.
623     2. Redistributions in binary form must reproduce the above copyright
624        notice, this list of conditions and the following disclaimer in the
625        documentation and/or other materials provided with the distribution.
626     3. The name of the author may not be used to endorse or promote
627        products derived from this software without specific prior written
628        permission.
629
630     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
631     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
632     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
633     ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
634     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
635     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
636     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
637     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
638     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
639     IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
640     POSSIBILITY OF SUCH DAMAGE.    
641 */
642
643 module_init(airo_cs_init);
644 module_exit(airo_cs_cleanup);