vserver 1.9.3
[linux-2.6.git] / drivers / serial / serial_cs.c
1 /*======================================================================
2
3     A driver for PCMCIA serial devices
4
5     serial_cs.c 1.134 2002/05/04 05:48:53
6
7     The contents of this file are subject to the Mozilla Public
8     License Version 1.1 (the "License"); you may not use this file
9     except in compliance with the License. You may obtain a copy of
10     the License at http://www.mozilla.org/MPL/
11
12     Software distributed under the License is distributed on an "AS
13     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14     implied. See the License for the specific language governing
15     rights and limitations under the License.
16
17     The initial developer of the original code 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     Alternatively, the contents of this file may be used under the
22     terms of the GNU General Public License version 2 (the "GPL"), in which
23     case the provisions of the GPL are applicable instead of the
24     above.  If you wish to allow the use of your version of this file
25     only under the terms of the GPL and not to allow others to use
26     your version of this file under the MPL, indicate your decision
27     by deleting the provisions above and replace them with the notice
28     and other provisions required by the GPL.  If you do not delete
29     the provisions above, a recipient may use your version of this
30     file under either the MPL or the GPL.
31     
32 ======================================================================*/
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38 #include <linux/sched.h>
39 #include <linux/ptrace.h>
40 #include <linux/slab.h>
41 #include <linux/string.h>
42 #include <linux/timer.h>
43 #include <linux/tty.h>
44 #include <linux/serial.h>
45 #include <linux/serial_core.h>
46 #include <linux/major.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/ciscode.h>
55 #include <pcmcia/ds.h>
56 #include <pcmcia/cisreg.h>
57
58 #include "8250.h"
59
60 #ifdef PCMCIA_DEBUG
61 static int pc_debug = PCMCIA_DEBUG;
62 MODULE_PARM(pc_debug, "i");
63 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
64 static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
65 #else
66 #define DEBUG(n, args...)
67 #endif
68
69 /*====================================================================*/
70
71 /* Parameters that can be set with 'insmod' */
72
73 /* Bit map of interrupts to choose from */
74 static u_int irq_mask = 0xdeb8;
75 static int irq_list[4];
76 static unsigned int irq_list_count;
77
78 /* Enable the speaker? */
79 static int do_sound = 1;
80 /* Skip strict UART tests? */
81 static int buggy_uart;
82
83 module_param(irq_mask, uint, 0444);
84 module_param_array(irq_list, int, irq_list_count, 0444);
85 module_param(do_sound, int, 0444);
86 module_param(buggy_uart, int, 0444);
87
88 /*====================================================================*/
89
90 /* Table of multi-port card ID's */
91
92 struct multi_id {
93         u_short manfid;
94         u_short prodid;
95         int multi;              /* 1 = multifunction, > 1 = # ports */
96 };
97
98 static struct multi_id multi_id[] = {
99         { MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
100         { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
101         { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
102         { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232,    4 },
103         { MANFID_SOCKET,  PRODID_SOCKET_DUAL_RS232,     2 },
104         { MANFID_INTEL,   PRODID_INTEL_DUAL_RS232,      2 },
105         { MANFID_NATINST, PRODID_NATINST_QUAD_RS232,    4 }
106 };
107 #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
108
109 struct serial_info {
110         dev_link_t              link;
111         int                     ndev;
112         int                     multi;
113         int                     slave;
114         int                     manfid;
115         dev_node_t              node[4];
116         int                     line[4];
117 };
118
119 static void serial_config(dev_link_t * link);
120 static int serial_event(event_t event, int priority,
121                         event_callback_args_t * args);
122
123 static dev_info_t dev_info = "serial_cs";
124
125 static dev_link_t *serial_attach(void);
126 static void serial_detach(dev_link_t *);
127
128 static dev_link_t *dev_list = NULL;
129
130 /*======================================================================
131
132     After a card is removed, serial_remove() will unregister
133     the serial device(s), and release the PCMCIA configuration.
134     
135 ======================================================================*/
136
137 static void serial_remove(dev_link_t *link)
138 {
139         struct serial_info *info = link->priv;
140         int i;
141
142         link->state &= ~DEV_PRESENT;
143
144         DEBUG(0, "serial_release(0x%p)\n", link);
145
146         /*
147          * Recheck to see if the device is still configured.
148          */
149         if (info->link.state & DEV_CONFIG) {
150                 for (i = 0; i < info->ndev; i++)
151                         unregister_serial(info->line[i]);
152
153                 info->link.dev = NULL;
154
155                 if (!info->slave) {
156                         pcmcia_release_configuration(info->link.handle);
157                         pcmcia_release_io(info->link.handle, &info->link.io);
158                         pcmcia_release_irq(info->link.handle, &info->link.irq);
159                 }
160
161                 info->link.state &= ~DEV_CONFIG;
162         }
163 }
164
165 static void serial_suspend(dev_link_t *link)
166 {
167         link->state |= DEV_SUSPEND;
168
169         if (link->state & DEV_CONFIG) {
170                 struct serial_info *info = link->priv;
171                 int i;
172
173                 for (i = 0; i < info->ndev; i++)
174                         serial8250_suspend_port(info->line[i]);
175
176                 if (!info->slave)
177                         pcmcia_release_configuration(link->handle);
178         }
179 }
180
181 static void serial_resume(dev_link_t *link)
182 {
183         link->state &= ~DEV_SUSPEND;
184
185         if (DEV_OK(link)) {
186                 struct serial_info *info = link->priv;
187                 int i;
188
189                 if (!info->slave)
190                         pcmcia_request_configuration(link->handle, &link->conf);
191
192                 for (i = 0; i < info->ndev; i++)
193                         serial8250_resume_port(info->line[i]);
194         }
195 }
196
197 /*======================================================================
198
199     serial_attach() creates an "instance" of the driver, allocating
200     local data structures for one device.  The device is registered
201     with Card Services.
202
203 ======================================================================*/
204
205 static dev_link_t *serial_attach(void)
206 {
207         struct serial_info *info;
208         client_reg_t client_reg;
209         dev_link_t *link;
210         int i, ret;
211
212         DEBUG(0, "serial_attach()\n");
213
214         /* Create new serial device */
215         info = kmalloc(sizeof (*info), GFP_KERNEL);
216         if (!info)
217                 return NULL;
218         memset(info, 0, sizeof (*info));
219         link = &info->link;
220         link->priv = info;
221
222         link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
223         link->io.NumPorts1 = 8;
224         link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
225         link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
226         if (irq_list_count == 0)
227                 link->irq.IRQInfo2 = irq_mask;
228         else
229                 for (i = 0; i < irq_list_count; i++)
230                         link->irq.IRQInfo2 |= 1 << irq_list[i];
231         link->conf.Attributes = CONF_ENABLE_IRQ;
232         if (do_sound) {
233                 link->conf.Attributes |= CONF_ENABLE_SPKR;
234                 link->conf.Status = CCSR_AUDIO_ENA;
235         }
236         link->conf.IntType = INT_MEMORY_AND_IO;
237
238         /* Register with Card Services */
239         link->next = dev_list;
240         dev_list = link;
241         client_reg.dev_info = &dev_info;
242         client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
243         client_reg.EventMask =
244             CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
245             CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
246             CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
247         client_reg.event_handler = &serial_event;
248         client_reg.Version = 0x0210;
249         client_reg.event_callback_args.client_data = link;
250         ret = pcmcia_register_client(&link->handle, &client_reg);
251         if (ret != CS_SUCCESS) {
252                 cs_error(link->handle, RegisterClient, ret);
253                 serial_detach(link);
254                 return NULL;
255         }
256
257         return link;
258 }
259
260 /*======================================================================
261
262     This deletes a driver "instance".  The device is de-registered
263     with Card Services.  If it has been released, all local data
264     structures are freed.  Otherwise, the structures will be freed
265     when the device is released.
266
267 ======================================================================*/
268
269 static void serial_detach(dev_link_t * link)
270 {
271         struct serial_info *info = link->priv;
272         dev_link_t **linkp;
273         int ret;
274
275         DEBUG(0, "serial_detach(0x%p)\n", link);
276
277         /* Locate device structure */
278         for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
279                 if (*linkp == link)
280                         break;
281         if (*linkp == NULL)
282                 return;
283
284         /*
285          * Ensure any outstanding scheduled tasks are completed.
286          */
287         flush_scheduled_work();
288
289         /*
290          * Ensure that the ports have been released.
291          */
292         serial_remove(link);
293
294         if (link->handle) {
295                 ret = pcmcia_deregister_client(link->handle);
296                 if (ret != CS_SUCCESS)
297                         cs_error(link->handle, DeregisterClient, ret);
298         }
299
300         /* Unlink device structure, free bits */
301         *linkp = link->next;
302         kfree(info);
303 }
304
305 /*====================================================================*/
306
307 static int setup_serial(struct serial_info * info, ioaddr_t port, int irq)
308 {
309         struct serial_struct serial;
310         int line;
311
312         memset(&serial, 0, sizeof (serial));
313         serial.port = port;
314         serial.irq = irq;
315         serial.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ;
316         if (buggy_uart)
317                 serial.flags |= UPF_BUGGY_UART;
318         line = register_serial(&serial);
319         if (line < 0) {
320                 printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
321                        " irq %d failed\n", (u_long) serial.port, serial.irq);
322                 return -EINVAL;
323         }
324
325         info->line[info->ndev] = line;
326         sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
327         info->node[info->ndev].major = TTY_MAJOR;
328         info->node[info->ndev].minor = 0x40 + line;
329         if (info->ndev > 0)
330                 info->node[info->ndev - 1].next = &info->node[info->ndev];
331         info->ndev++;
332
333         return 0;
334 }
335
336 /*====================================================================*/
337
338 static int
339 first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
340 {
341         int i;
342         i = pcmcia_get_first_tuple(handle, tuple);
343         if (i != CS_SUCCESS)
344                 return CS_NO_MORE_ITEMS;
345         i = pcmcia_get_tuple_data(handle, tuple);
346         if (i != CS_SUCCESS)
347                 return i;
348         return pcmcia_parse_tuple(handle, tuple, parse);
349 }
350
351 static int
352 next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
353 {
354         int i;
355         i = pcmcia_get_next_tuple(handle, tuple);
356         if (i != CS_SUCCESS)
357                 return CS_NO_MORE_ITEMS;
358         i = pcmcia_get_tuple_data(handle, tuple);
359         if (i != CS_SUCCESS)
360                 return i;
361         return pcmcia_parse_tuple(handle, tuple, parse);
362 }
363
364 /*====================================================================*/
365
366 static int simple_config(dev_link_t *link)
367 {
368         static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
369         static int size_table[2] = { 8, 16 };
370         client_handle_t handle = link->handle;
371         struct serial_info *info = link->priv;
372         tuple_t tuple;
373         u_char buf[256];
374         cisparse_t parse;
375         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
376         config_info_t config;
377         int i, j, try;
378         int s;
379
380         /* If the card is already configured, look up the port and irq */
381         i = pcmcia_get_configuration_info(handle, &config);
382         if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
383                 ioaddr_t port = 0;
384                 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
385                         port = config.BasePort2;
386                         info->slave = 1;
387                 } else if ((info->manfid == MANFID_OSITECH) &&
388                            (config.NumPorts1 == 0x40)) {
389                         port = config.BasePort1 + 0x28;
390                         info->slave = 1;
391                 }
392                 if (info->slave)
393                         return setup_serial(info, port, config.AssignedIRQ);
394         }
395         link->conf.Vcc = config.Vcc;
396
397         /* First pass: look for a config entry that looks normal. */
398         tuple.TupleData = (cisdata_t *) buf;
399         tuple.TupleOffset = 0;
400         tuple.TupleDataMax = 255;
401         tuple.Attributes = 0;
402         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
403         /* Two tries: without IO aliases, then with aliases */
404         for (s = 0; s < 2; s++) {
405                 for (try = 0; try < 2; try++) {
406                         i = first_tuple(handle, &tuple, &parse);
407                         while (i != CS_NO_MORE_ITEMS) {
408                                 if (i != CS_SUCCESS)
409                                         goto next_entry;
410                                 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
411                                         link->conf.Vpp1 = link->conf.Vpp2 =
412                                             cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
413                                 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
414                                             (cf->io.win[0].base != 0)) {
415                                         link->conf.ConfigIndex = cf->index;
416                                         link->io.BasePort1 = cf->io.win[0].base;
417                                         link->io.IOAddrLines = (try == 0) ?
418                                             16 : cf->io.flags & CISTPL_IO_LINES_MASK;
419                                         i = pcmcia_request_io(link->handle, &link->io);
420                                         if (i == CS_SUCCESS)
421                                                 goto found_port;
422                                 }
423 next_entry:
424                                 i = next_tuple(handle, &tuple, &parse);
425                         }
426                 }
427         }
428         /* Second pass: try to find an entry that isn't picky about
429            its base address, then try to grab any standard serial port
430            address, and finally try to get any free port. */
431         i = first_tuple(handle, &tuple, &parse);
432         while (i != CS_NO_MORE_ITEMS) {
433                 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
434                     ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
435                         link->conf.ConfigIndex = cf->index;
436                         for (j = 0; j < 5; j++) {
437                                 link->io.BasePort1 = base[j];
438                                 link->io.IOAddrLines = base[j] ? 16 : 3;
439                                 i = pcmcia_request_io(link->handle, &link->io);
440                                 if (i == CS_SUCCESS)
441                                         goto found_port;
442                         }
443                 }
444                 i = next_tuple(handle, &tuple, &parse);
445         }
446
447       found_port:
448         if (i != CS_SUCCESS) {
449                 printk(KERN_NOTICE
450                        "serial_cs: no usable port range found, giving up\n");
451                 cs_error(link->handle, RequestIO, i);
452                 return -1;
453         }
454
455         i = pcmcia_request_irq(link->handle, &link->irq);
456         if (i != CS_SUCCESS) {
457                 cs_error(link->handle, RequestIRQ, i);
458                 link->irq.AssignedIRQ = 0;
459         }
460         if (info->multi && (info->manfid == MANFID_3COM))
461                 link->conf.ConfigIndex &= ~(0x08);
462         i = pcmcia_request_configuration(link->handle, &link->conf);
463         if (i != CS_SUCCESS) {
464                 cs_error(link->handle, RequestConfiguration, i);
465                 return -1;
466         }
467
468         return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
469 }
470
471 static int multi_config(dev_link_t * link)
472 {
473         client_handle_t handle = link->handle;
474         struct serial_info *info = link->priv;
475         tuple_t tuple;
476         u_char buf[256];
477         cisparse_t parse;
478         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
479         config_info_t config;
480         int i, base2 = 0;
481
482         i = pcmcia_get_configuration_info(handle, &config);
483         if (i != CS_SUCCESS) {
484                 cs_error(handle, GetConfigurationInfo, i);
485                 return -1;
486         }
487         link->conf.Vcc = config.Vcc;
488
489         tuple.TupleData = (cisdata_t *) buf;
490         tuple.TupleOffset = 0;
491         tuple.TupleDataMax = 255;
492         tuple.Attributes = 0;
493         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
494
495         /* First, look for a generic full-sized window */
496         link->io.NumPorts1 = info->multi * 8;
497         i = first_tuple(handle, &tuple, &parse);
498         while (i != CS_NO_MORE_ITEMS) {
499                 /* The quad port cards have bad CIS's, so just look for a
500                    window larger than 8 ports and assume it will be right */
501                 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
502                     (cf->io.win[0].len > 8)) {
503                         link->conf.ConfigIndex = cf->index;
504                         link->io.BasePort1 = cf->io.win[0].base;
505                         link->io.IOAddrLines =
506                             cf->io.flags & CISTPL_IO_LINES_MASK;
507                         i = pcmcia_request_io(link->handle, &link->io);
508                         base2 = link->io.BasePort1 + 8;
509                         if (i == CS_SUCCESS)
510                                 break;
511                 }
512                 i = next_tuple(handle, &tuple, &parse);
513         }
514
515         /* If that didn't work, look for two windows */
516         if (i != CS_SUCCESS) {
517                 link->io.NumPorts1 = link->io.NumPorts2 = 8;
518                 info->multi = 2;
519                 i = first_tuple(handle, &tuple, &parse);
520                 while (i != CS_NO_MORE_ITEMS) {
521                         if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
522                                 link->conf.ConfigIndex = cf->index;
523                                 link->io.BasePort1 = cf->io.win[0].base;
524                                 link->io.BasePort2 = cf->io.win[1].base;
525                                 link->io.IOAddrLines =
526                                     cf->io.flags & CISTPL_IO_LINES_MASK;
527                                 i = pcmcia_request_io(link->handle, &link->io);
528                                 base2 = link->io.BasePort2;
529                                 if (i == CS_SUCCESS)
530                                         break;
531                         }
532                         i = next_tuple(handle, &tuple, &parse);
533                 }
534         }
535
536         if (i != CS_SUCCESS) {
537                 cs_error(link->handle, RequestIO, i);
538                 return -1;
539         }
540
541         i = pcmcia_request_irq(link->handle, &link->irq);
542         if (i != CS_SUCCESS) {
543                 printk(KERN_NOTICE
544                        "serial_cs: no usable port range found, giving up\n");
545                 cs_error(link->handle, RequestIRQ, i);
546                 link->irq.AssignedIRQ = 0;
547         }
548         /* Socket Dual IO: this enables irq's for second port */
549         if (info->multi && (info->manfid == MANFID_SOCKET)) {
550                 link->conf.Present |= PRESENT_EXT_STATUS;
551                 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
552         }
553         i = pcmcia_request_configuration(link->handle, &link->conf);
554         if (i != CS_SUCCESS) {
555                 cs_error(link->handle, RequestConfiguration, i);
556                 return -1;
557         }
558
559         /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
560            8 registers are for the UART, the others are extra registers */
561         if (info->manfid == MANFID_OXSEMI) {
562                 if (cf->index == 1 || cf->index == 3) {
563                         setup_serial(info, base2, link->irq.AssignedIRQ);
564                         outb(12, link->io.BasePort1 + 1);
565                 } else {
566                         setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
567                         outb(12, base2 + 1);
568                 }
569                 return 0;
570         }
571
572         setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
573         /* The Nokia cards are not really multiport cards */
574         if (info->manfid == MANFID_NOKIA)
575                 return 0;
576         for (i = 0; i < info->multi - 1; i++)
577                 setup_serial(info, base2 + (8 * i), link->irq.AssignedIRQ);
578
579         return 0;
580 }
581
582 /*======================================================================
583
584     serial_config() is scheduled to run after a CARD_INSERTION event
585     is received, to configure the PCMCIA socket, and to make the
586     serial device available to the system.
587
588 ======================================================================*/
589
590 void serial_config(dev_link_t * link)
591 {
592         client_handle_t handle = link->handle;
593         struct serial_info *info = link->priv;
594         tuple_t tuple;
595         u_short buf[128];
596         cisparse_t parse;
597         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
598         int i, last_ret, last_fn;
599
600         DEBUG(0, "serial_config(0x%p)\n", link);
601
602         tuple.TupleData = (cisdata_t *) buf;
603         tuple.TupleOffset = 0;
604         tuple.TupleDataMax = 255;
605         tuple.Attributes = 0;
606         /* Get configuration register information */
607         tuple.DesiredTuple = CISTPL_CONFIG;
608         last_ret = first_tuple(handle, &tuple, &parse);
609         if (last_ret != CS_SUCCESS) {
610                 last_fn = ParseTuple;
611                 goto cs_failed;
612         }
613         link->conf.ConfigBase = parse.config.base;
614         link->conf.Present = parse.config.rmask[0];
615
616         /* Configure card */
617         link->state |= DEV_CONFIG;
618
619         /* Is this a compliant multifunction card? */
620         tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
621         tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
622         info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
623
624         /* Is this a multiport card? */
625         tuple.DesiredTuple = CISTPL_MANFID;
626         if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
627                 info->manfid = le16_to_cpu(buf[0]);
628                 for (i = 0; i < MULTI_COUNT; i++)
629                         if ((info->manfid == multi_id[i].manfid) &&
630                             (le16_to_cpu(buf[1]) == multi_id[i].prodid))
631                                 break;
632                 if (i < MULTI_COUNT)
633                         info->multi = multi_id[i].multi;
634         }
635
636         /* Another check for dual-serial cards: look for either serial or
637            multifunction cards that ask for appropriate IO port ranges */
638         tuple.DesiredTuple = CISTPL_FUNCID;
639         if ((info->multi == 0) &&
640             ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||
641              (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
642              (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
643                 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
644                 if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
645                         if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
646                                 info->multi = cf->io.win[0].len >> 3;
647                         if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
648                             (cf->io.win[1].len == 8))
649                                 info->multi = 2;
650                 }
651         }
652
653         if (info->multi > 1)
654                 multi_config(link);
655         else
656                 simple_config(link);
657
658         if (info->ndev == 0)
659                 goto failed;
660
661         if (info->manfid == MANFID_IBM) {
662                 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
663                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
664                 if (last_ret) {
665                         last_fn = AccessConfigurationRegister;
666                         goto cs_failed;
667                 }
668                 reg.Action = CS_WRITE;
669                 reg.Value = reg.Value | 1;
670                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
671                 if (last_ret) {
672                         last_fn = AccessConfigurationRegister;
673                         goto cs_failed;
674                 }
675         }
676
677         link->dev = &info->node[0];
678         link->state &= ~DEV_CONFIG_PENDING;
679         return;
680
681  cs_failed:
682         cs_error(link->handle, last_fn, last_ret);
683  failed:
684         serial_remove(link);
685         link->state &= ~DEV_CONFIG_PENDING;
686 }
687
688 /*======================================================================
689
690     The card status event handler.  Mostly, this schedules other
691     stuff to run after an event is received.  A CARD_REMOVAL event
692     also sets some flags to discourage the serial drivers from
693     talking to the ports.
694     
695 ======================================================================*/
696
697 static int
698 serial_event(event_t event, int priority, event_callback_args_t * args)
699 {
700         dev_link_t *link = args->client_data;
701         struct serial_info *info = link->priv;
702
703         DEBUG(1, "serial_event(0x%06x)\n", event);
704
705         switch (event) {
706         case CS_EVENT_CARD_REMOVAL:
707                 serial_remove(link);
708                 break;
709
710         case CS_EVENT_CARD_INSERTION:
711                 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
712                 serial_config(link);
713                 break;
714
715         case CS_EVENT_PM_SUSPEND:
716                 serial_suspend(link);
717                 break;
718
719         case CS_EVENT_RESET_PHYSICAL:
720                 if ((link->state & DEV_CONFIG) && !info->slave)
721                         pcmcia_release_configuration(link->handle);
722                 break;
723
724         case CS_EVENT_PM_RESUME:
725                 serial_resume(link);
726                 break;
727
728         case CS_EVENT_CARD_RESET:
729                 if (DEV_OK(link) && !info->slave)
730                         pcmcia_request_configuration(link->handle, &link->conf);
731                 break;
732         }
733         return 0;
734 }
735
736 static struct pcmcia_driver serial_cs_driver = {
737         .owner          = THIS_MODULE,
738         .drv            = {
739                 .name   = "serial_cs",
740         },
741         .attach         = serial_attach,
742         .detach         = serial_detach,
743 };
744
745 static int __init init_serial_cs(void)
746 {
747         return pcmcia_register_driver(&serial_cs_driver);
748 }
749
750 static void __exit exit_serial_cs(void)
751 {
752         pcmcia_unregister_driver(&serial_cs_driver);
753
754         /* XXX: this really needs to move into generic code.. */
755         while (dev_list != NULL)
756                 serial_detach(dev_list);
757 }
758
759 module_init(init_serial_cs);
760 module_exit(exit_serial_cs);
761
762 MODULE_LICENSE("GPL");