import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / drivers / isdn / hisax / sedlbauer_cs.c
1 /*======================================================================
2
3     A Sedlbauer PCMCIA client driver
4
5     This driver is for the Sedlbauer Speed Star and Speed Star II, 
6     which are ISDN PCMCIA Cards.
7     
8     The contents of this file are subject to the Mozilla Public
9     License Version 1.1 (the "License"); you may not use this file
10     except in compliance with the License. You may obtain a copy of
11     the License at http://www.mozilla.org/MPL/
12
13     Software distributed under the License is distributed on an "AS
14     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
15     implied. See the License for the specific language governing
16     rights and limitations under the License.
17
18     The initial developer of the original code is David A. Hinds
19     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
20     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
21
22     Modifications from dummy_cs.c are Copyright (C) 1999-2001 Marcus Niemann
23     <maniemann@users.sourceforge.net>. All Rights Reserved.
24
25     Alternatively, the contents of this file may be used under the
26     terms of the GNU General Public License version 2 (the "GPL"), in
27     which case the provisions of the GPL are applicable instead of the
28     above.  If you wish to allow the use of your version of this file
29     only under the terms of the GPL and not to allow others to use
30     your version of this file under the MPL, indicate your decision
31     by deleting the provisions above and replace them with the notice
32     and other provisions required by the GPL.  If you do not delete
33     the provisions above, a recipient may use your version of this
34     file under either the MPL or the GPL.
35     
36 ======================================================================*/
37
38 #include <linux/kernel.h>
39 #include <linux/module.h>
40 #include <linux/init.h>
41 #include <linux/sched.h>
42 #include <linux/ptrace.h>
43 #include <linux/slab.h>
44 #include <linux/string.h>
45 #include <linux/timer.h>
46 #include <linux/ioport.h>
47 #include <asm/io.h>
48 #include <asm/system.h>
49
50 #include <pcmcia/version.h>
51 #include <pcmcia/cs_types.h>
52 #include <pcmcia/cs.h>
53 #include <pcmcia/cistpl.h>
54 #include <pcmcia/cisreg.h>
55 #include <pcmcia/ds.h>
56 #include <pcmcia/bus_ops.h>
57
58 MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
59 MODULE_AUTHOR("Marcus Niemann");
60 MODULE_LICENSE("Dual MPL/GPL");
61
62 /*
63    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
64    you do not define PCMCIA_DEBUG at all, all the debug code will be
65    left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
66    be present but disabled -- but it can then be enabled for specific
67    modules at load time with a 'pc_debug=#' option to insmod.
68 */
69
70 #ifdef PCMCIA_DEBUG
71 static int pc_debug = PCMCIA_DEBUG;
72 MODULE_PARM(pc_debug, "i");
73 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args); 
74 static char *version =
75 "sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
76 #else
77 #define DEBUG(n, args...)
78 #endif
79
80
81 /*====================================================================*/
82
83 /* Parameters that can be set with 'insmod' */
84
85 /* The old way: bit map of interrupts to choose from */
86 /* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
87 static u_int irq_mask = 0xdeb8;
88 /* Newer, simpler way of listing specific interrupts */
89 static int irq_list[4] = { -1 };
90
91 MODULE_PARM(irq_mask, "i");
92 MODULE_PARM(irq_list, "1-4i");
93
94 static int protocol = 2;        /* EURO-ISDN Default */
95 MODULE_PARM(protocol, "i");
96
97 extern int sedl_init_pcmcia(int, int, int*, int);
98
99 /*====================================================================*/
100
101 /*
102    The event() function is this driver's Card Services event handler.
103    It will be called by Card Services when an appropriate card status
104    event is received.  The config() and release() entry points are
105    used to configure or release a socket, in response to card
106    insertion and ejection events.  They are invoked from the sedlbauer
107    event handler. 
108 */
109
110 static void sedlbauer_config(dev_link_t *link);
111 static void sedlbauer_release(u_long arg);
112 static int sedlbauer_event(event_t event, int priority,
113                        event_callback_args_t *args);
114
115 /*
116    The attach() and detach() entry points are used to create and destroy
117    "instances" of the driver, where each instance represents everything
118    needed to manage one actual PCMCIA card.
119 */
120
121 static dev_link_t *sedlbauer_attach(void);
122 static void sedlbauer_detach(dev_link_t *);
123
124 /*
125    You'll also need to prototype all the functions that will actually
126    be used to talk to your device.  See 'memory_cs' for a good example
127    of a fully self-sufficient driver; the other drivers rely more or
128    less on other parts of the kernel.
129 */
130
131 /*
132    The dev_info variable is the "key" that is used to match up this
133    device driver with appropriate cards, through the card configuration
134    database.
135 */
136
137 static dev_info_t dev_info = "sedlbauer_cs";
138
139 /*
140    A linked list of "instances" of the sedlbauer device.  Each actual
141    PCMCIA card corresponds to one device instance, and is described
142    by one dev_link_t structure (defined in ds.h).
143
144    You may not want to use a linked list for this -- for example, the
145    memory card driver uses an array of dev_link_t pointers, where minor
146    device numbers are used to derive the corresponding array index.
147 */
148
149 static dev_link_t *dev_list = NULL;
150
151 /*
152    A dev_link_t structure has fields for most things that are needed
153    to keep track of a socket, but there will usually be some device
154    specific information that also needs to be kept track of.  The
155    'priv' pointer in a dev_link_t structure can be used to point to
156    a device-specific private data structure, like this.
157
158    To simplify the data structure handling, we actually include the
159    dev_link_t structure in the device's private data structure.
160
161    A driver needs to provide a dev_node_t structure for each device
162    on a card.  In some cases, there is only one device per card (for
163    example, ethernet cards, modems).  In other cases, there may be
164    many actual or logical devices (SCSI adapters, memory cards with
165    multiple partitions).  The dev_node_t structures need to be kept
166    in a linked list starting at the 'dev' field of a dev_link_t
167    structure.  We allocate them in the card's private data structure,
168    because they generally shouldn't be allocated dynamically.
169
170    In this case, we also provide a flag to indicate if a device is
171    "stopped" due to a power management event, or card ejection.  The
172    device IO routines can use a flag like this to throttle IO to a
173    card that is not ready to accept it.
174
175    The bus_operations pointer is used on platforms for which we need
176    to use special socket-specific versions of normal IO primitives
177    (inb, outb, readb, writeb, etc) for card IO.
178 */
179    
180 typedef struct local_info_t {
181     dev_link_t          link;
182     dev_node_t          node;
183     int                 stop;
184     struct bus_operations *bus;
185 } local_info_t;
186
187 /*====================================================================*/
188
189 static void cs_error(client_handle_t handle, int func, int ret)
190 {
191     error_info_t err = { func, ret };
192     CardServices(ReportError, handle, &err);
193 }
194
195 /*======================================================================
196
197     sedlbauer_attach() creates an "instance" of the driver, allocating
198     local data structures for one device.  The device is registered
199     with Card Services.
200
201     The dev_link structure is initialized, but we don't actually
202     configure the card at this point -- we wait until we receive a
203     card insertion event.
204     
205 ======================================================================*/
206
207 static dev_link_t *sedlbauer_attach(void)
208 {
209     local_info_t *local;
210     dev_link_t *link;
211     client_reg_t client_reg;
212     int ret, i;
213     
214     DEBUG(0, "sedlbauer_attach()\n");
215
216     /* Allocate space for private device-specific data */
217     local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
218     if (!local) return NULL;
219     memset(local, 0, sizeof(local_info_t));
220     link = &local->link; link->priv = local;
221     
222     /* Initialize the dev_link_t structure */
223     link->release.function = &sedlbauer_release;
224     link->release.data = (u_long)link;
225
226     /* Interrupt setup */
227     link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
228     link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
229     if (irq_list[0] == -1)
230         link->irq.IRQInfo2 = irq_mask;
231     else
232         for (i = 0; i < 4; i++)
233             link->irq.IRQInfo2 |= 1 << irq_list[i];
234     link->irq.Handler = NULL;
235     
236     /*
237       General socket configuration defaults can go here.  In this
238       client, we assume very little, and rely on the CIS for almost
239       everything.  In most clients, many details (i.e., number, sizes,
240       and attributes of IO windows) are fixed by the nature of the
241       device, and can be hard-wired here.
242     */
243
244     /* from old sedl_cs 
245     */
246     /* The io structure describes IO port mapping */
247     link->io.NumPorts1 = 8;
248     link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
249     link->io.IOAddrLines = 3;
250
251
252     link->conf.Attributes = 0;
253     link->conf.Vcc = 50;
254     link->conf.IntType = INT_MEMORY_AND_IO;
255
256     /* Register with Card Services */
257     link->next = dev_list;
258     dev_list = link;
259     client_reg.dev_info = &dev_info;
260     client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
261     client_reg.EventMask =
262         CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
263         CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
264         CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
265     client_reg.event_handler = &sedlbauer_event;
266     client_reg.Version = 0x0210;
267     client_reg.event_callback_args.client_data = link;
268     ret = CardServices(RegisterClient, &link->handle, &client_reg);
269     if (ret != CS_SUCCESS) {
270         cs_error(link->handle, RegisterClient, ret);
271         sedlbauer_detach(link);
272         return NULL;
273     }
274
275     return link;
276 } /* sedlbauer_attach */
277
278 /*======================================================================
279
280     This deletes a driver "instance".  The device is de-registered
281     with Card Services.  If it has been released, all local data
282     structures are freed.  Otherwise, the structures will be freed
283     when the device is released.
284
285 ======================================================================*/
286
287 static void sedlbauer_detach(dev_link_t *link)
288 {
289     dev_link_t **linkp;
290
291     DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
292     
293     /* Locate device structure */
294     for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
295         if (*linkp == link) break;
296     if (*linkp == NULL)
297         return;
298
299     /*
300        If the device is currently configured and active, we won't
301        actually delete it yet.  Instead, it is marked so that when
302        the release() function is called, that will trigger a proper
303        detach().
304     */
305     if (link->state & DEV_CONFIG) {
306 #ifdef PCMCIA_DEBUG
307         printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' "
308                "still locked\n", link->dev->dev_name);
309 #endif
310         link->state |= DEV_STALE_LINK;
311         return;
312     }
313
314     /* Break the link with Card Services */
315     if (link->handle)
316         CardServices(DeregisterClient, link->handle);
317     
318     /* Unlink device structure, and free it */
319     *linkp = link->next;
320     /* This points to the parent local_info_t struct */
321     kfree(link->priv);
322 } /* sedlbauer_detach */
323
324 /*======================================================================
325
326     sedlbauer_config() is scheduled to run after a CARD_INSERTION event
327     is received, to configure the PCMCIA socket, and to make the
328     device available to the system.
329     
330 ======================================================================*/
331
332 #define CS_CHECK(fn, args...) \
333 while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
334
335 #define CFG_CHECK(fn, args...) \
336 if (CardServices(fn, args) != 0) goto next_entry
337
338 static void sedlbauer_config(dev_link_t *link)
339 {
340     client_handle_t handle = link->handle;
341     local_info_t *dev = link->priv;
342     tuple_t tuple;
343     cisparse_t parse;
344     int last_fn, last_ret;
345     u_char buf[64];
346     config_info_t conf;
347     win_req_t req;
348     memreq_t map;
349     
350
351     DEBUG(0, "sedlbauer_config(0x%p)\n", link);
352
353     /*
354        This reads the card's CONFIG tuple to find its configuration
355        registers.
356     */
357     tuple.DesiredTuple = CISTPL_CONFIG;
358     tuple.Attributes = 0;
359     tuple.TupleData = buf;
360     tuple.TupleDataMax = sizeof(buf);
361     tuple.TupleOffset = 0;
362     CS_CHECK(GetFirstTuple, handle, &tuple);
363     CS_CHECK(GetTupleData, handle, &tuple);
364     CS_CHECK(ParseTuple, handle, &tuple, &parse);
365     link->conf.ConfigBase = parse.config.base;
366     link->conf.Present = parse.config.rmask[0];
367     
368     /* Configure card */
369     link->state |= DEV_CONFIG;
370
371     /* Look up the current Vcc */
372     CS_CHECK(GetConfigurationInfo, handle, &conf);
373     link->conf.Vcc = conf.Vcc;
374
375     /*
376       In this loop, we scan the CIS for configuration table entries,
377       each of which describes a valid card configuration, including
378       voltage, IO window, memory window, and interrupt settings.
379
380       We make no assumptions about the card to be configured: we use
381       just the information available in the CIS.  In an ideal world,
382       this would work for any PCMCIA card, but it requires a complete
383       and accurate CIS.  In practice, a driver usually "knows" most of
384       these things without consulting the CIS, and most client drivers
385       will only use the CIS to fill in implementation-defined details.
386     */
387     tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
388     CS_CHECK(GetFirstTuple, handle, &tuple);
389     while (1) {
390         cistpl_cftable_entry_t dflt = { 0 };
391         cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
392         CFG_CHECK(GetTupleData, handle, &tuple);
393         CFG_CHECK(ParseTuple, handle, &tuple, &parse);
394
395         if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
396         if (cfg->index == 0) goto next_entry;
397         link->conf.ConfigIndex = cfg->index;
398         
399         /* Does this card need audio output? */
400         if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
401             link->conf.Attributes |= CONF_ENABLE_SPKR;
402             link->conf.Status = CCSR_AUDIO_ENA;
403         }
404         
405         /* Use power settings for Vcc and Vpp if present */
406         /*  Note that the CIS values need to be rescaled */
407         if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
408             if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000)
409                 goto next_entry;
410         } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
411             if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000)
412                 goto next_entry;
413         }
414             
415         if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
416             link->conf.Vpp1 = link->conf.Vpp2 =
417                 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
418         else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
419             link->conf.Vpp1 = link->conf.Vpp2 =
420                 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
421         
422         /* Do we need to allocate an interrupt? */
423         if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
424             link->conf.Attributes |= CONF_ENABLE_IRQ;
425         
426         /* IO window settings */
427         link->io.NumPorts1 = link->io.NumPorts2 = 0;
428         if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
429             cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
430             link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
431             if (!(io->flags & CISTPL_IO_8BIT))
432                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
433             if (!(io->flags & CISTPL_IO_16BIT))
434                 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
435 /* new in dummy.cs 2001/01/28 MN 
436             link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
437 */
438             link->io.BasePort1 = io->win[0].base;
439             link->io.NumPorts1 = io->win[0].len;
440             if (io->nwin > 1) {
441                 link->io.Attributes2 = link->io.Attributes1;
442                 link->io.BasePort2 = io->win[1].base;
443                 link->io.NumPorts2 = io->win[1].len;
444             }
445             /* This reserves IO space but doesn't actually enable it */
446             CFG_CHECK(RequestIO, link->handle, &link->io);
447         }
448
449         /*
450           Now set up a common memory window, if needed.  There is room
451           in the dev_link_t structure for one memory window handle,
452           but if the base addresses need to be saved, or if multiple
453           windows are needed, the info should go in the private data
454           structure for this device.
455
456           Note that the memory window base is a physical address, and
457           needs to be mapped to virtual space with ioremap() before it
458           is used.
459         */
460         if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
461             cistpl_mem_t *mem =
462                 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
463             req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
464             req.Attributes |= WIN_ENABLE;
465             req.Base = mem->win[0].host_addr;
466             req.Size = mem->win[0].len;
467 /* new in dummy.cs 2001/01/28 MN 
468             if (req.Size < 0x1000)
469                 req.Size = 0x1000;
470 */
471             req.AccessSpeed = 0;
472             link->win = (window_handle_t)link->handle;
473             CFG_CHECK(RequestWindow, &link->win, &req);
474             map.Page = 0; map.CardOffset = mem->win[0].card_addr;
475             CFG_CHECK(MapMemPage, link->win, &map);
476         }
477         /* If we got this far, we're cool! */
478         break;
479         
480     next_entry:
481 /* new in dummy.cs 2001/01/28 MN 
482         if (link->io.NumPorts1)
483            CardServices(ReleaseIO, link->handle, &link->io);
484 */
485         CS_CHECK(GetNextTuple, handle, &tuple);
486     }
487     
488     /*
489        Allocate an interrupt line.  Note that this does not assign a
490        handler to the interrupt, unless the 'Handler' member of the
491        irq structure is initialized.
492     */
493     if (link->conf.Attributes & CONF_ENABLE_IRQ)
494         CS_CHECK(RequestIRQ, link->handle, &link->irq);
495         
496     /*
497        This actually configures the PCMCIA socket -- setting up
498        the I/O windows and the interrupt mapping, and putting the
499        card and host interface into "Memory and IO" mode.
500     */
501     CS_CHECK(RequestConfiguration, link->handle, &link->conf);
502
503     /*
504       At this point, the dev_node_t structure(s) need to be
505       initialized and arranged in a linked list at link->dev.
506     */
507     sprintf(dev->node.dev_name, "sedlbauer");
508     dev->node.major = dev->node.minor = 0;
509     link->dev = &dev->node;
510
511     /* Finally, report what we've done */
512     printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
513            dev->node.dev_name, link->conf.ConfigIndex,
514            link->conf.Vcc/10, link->conf.Vcc%10);
515     if (link->conf.Vpp1)
516         printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
517     if (link->conf.Attributes & CONF_ENABLE_IRQ)
518         printk(", irq %d", link->irq.AssignedIRQ);
519     if (link->io.NumPorts1)
520         printk(", io 0x%04x-0x%04x", link->io.BasePort1,
521                link->io.BasePort1+link->io.NumPorts1-1);
522     if (link->io.NumPorts2)
523         printk(" & 0x%04x-0x%04x", link->io.BasePort2,
524                link->io.BasePort2+link->io.NumPorts2-1);
525     if (link->win)
526         printk(", mem 0x%06lx-0x%06lx", req.Base,
527                req.Base+req.Size-1);
528     printk("\n");
529     
530     link->state &= ~DEV_CONFIG_PENDING;
531  
532     sedl_init_pcmcia(link->io.BasePort1, link->irq.AssignedIRQ,
533                      &(((local_info_t*)link->priv)->stop),
534                      protocol);
535
536     return;
537
538 cs_failed:
539     cs_error(link->handle, last_fn, last_ret);
540     sedlbauer_release((u_long)link);
541
542 } /* sedlbauer_config */
543
544 /*======================================================================
545
546     After a card is removed, sedlbauer_release() will unregister the
547     device, and release the PCMCIA configuration.  If the device is
548     still open, this will be postponed until it is closed.
549     
550 ======================================================================*/
551
552 static void sedlbauer_release(u_long arg)
553 {
554     dev_link_t *link = (dev_link_t *)arg;
555
556     DEBUG(0, "sedlbauer_release(0x%p)\n", link);
557
558     /*
559        If the device is currently in use, we won't release until it
560        is actually closed, because until then, we can't be sure that
561        no one will try to access the device or its data structures.
562     */
563     if (link->open) {
564         DEBUG(1, "sedlbauer_cs: release postponed, '%s' still open\n",
565               link->dev->dev_name);
566         link->state |= DEV_STALE_CONFIG;
567         return;
568     }
569
570     /* Unlink the device chain */
571     link->dev = NULL;
572
573     /*
574       In a normal driver, additional code may be needed to release
575       other kernel data structures associated with this device. 
576     */
577     
578     /* Don't bother checking to see if these succeed or not */
579     if (link->win)
580         CardServices(ReleaseWindow, link->win);
581     CardServices(ReleaseConfiguration, link->handle);
582     if (link->io.NumPorts1)
583         CardServices(ReleaseIO, link->handle, &link->io);
584     if (link->irq.AssignedIRQ)
585         CardServices(ReleaseIRQ, link->handle, &link->irq);
586     link->state &= ~DEV_CONFIG;
587     
588     if (link->state & DEV_STALE_LINK)
589         sedlbauer_detach(link);
590     
591 } /* sedlbauer_release */
592
593 /*======================================================================
594
595     The card status event handler.  Mostly, this schedules other
596     stuff to run after an event is received.
597
598     When a CARD_REMOVAL event is received, we immediately set a
599     private flag to block future accesses to this device.  All the
600     functions that actually access the device should check this flag
601     to make sure the card is still present.
602     
603 ======================================================================*/
604
605 static int sedlbauer_event(event_t event, int priority,
606                        event_callback_args_t *args)
607 {
608     dev_link_t *link = args->client_data;
609     local_info_t *dev = link->priv;
610     
611     DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
612     
613     switch (event) {
614     case CS_EVENT_CARD_REMOVAL:
615         link->state &= ~DEV_PRESENT;
616         if (link->state & DEV_CONFIG) {
617             ((local_info_t *)link->priv)->stop = 1;
618             mod_timer(&link->release, jiffies + HZ/20);
619         }
620         break;
621     case CS_EVENT_CARD_INSERTION:
622         link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
623         dev->bus = args->bus;
624         sedlbauer_config(link);
625         break;
626     case CS_EVENT_PM_SUSPEND:
627         link->state |= DEV_SUSPEND;
628         /* Fall through... */
629     case CS_EVENT_RESET_PHYSICAL:
630         /* Mark the device as stopped, to block IO until later */
631         dev->stop = 1;
632         if (link->state & DEV_CONFIG)
633             CardServices(ReleaseConfiguration, link->handle);
634         break;
635     case CS_EVENT_PM_RESUME:
636         link->state &= ~DEV_SUSPEND;
637         /* Fall through... */
638     case CS_EVENT_CARD_RESET:
639         if (link->state & DEV_CONFIG)
640             CardServices(RequestConfiguration, link->handle, &link->conf);
641         dev->stop = 0;
642         /*
643           In a normal driver, additional code may go here to restore
644           the device state and restart IO. 
645         */
646         break;
647     }
648     return 0;
649 } /* sedlbauer_event */
650
651 /*====================================================================*/
652
653 static int __init init_sedlbauer_cs(void)
654 {
655     servinfo_t serv;
656     DEBUG(0, "%s\n", version);
657     CardServices(GetCardServicesInfo, &serv);
658     if (serv.Revision != CS_RELEASE_CODE) {
659         printk(KERN_NOTICE "sedlbauer_cs: Card Services release "
660                "does not match!\n");
661         return -1;
662     }
663     register_pccard_driver(&dev_info, &sedlbauer_attach, &sedlbauer_detach);
664     return 0;
665 }
666
667 static void __exit exit_sedlbauer_cs(void)
668 {
669     DEBUG(0, "sedlbauer_cs: unloading\n");
670     unregister_pccard_driver(&dev_info);
671     while (dev_list != NULL) {
672         del_timer(&dev_list->release);
673         if (dev_list->state & DEV_CONFIG)
674             sedlbauer_release((u_long)dev_list);
675         sedlbauer_detach(dev_list);
676     }
677 }
678
679 module_init(init_sedlbauer_cs);
680 module_exit(exit_sedlbauer_cs);
681