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