]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - drivers/serial/serial_cs.c
drm: merge in Linus mainline
[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/serial_core.h>
44 #include <linux/major.h>
45 #include <asm/io.h>
46 #include <asm/system.h>
47
48 #include <pcmcia/cs_types.h>
49 #include <pcmcia/cs.h>
50 #include <pcmcia/cistpl.h>
51 #include <pcmcia/ciscode.h>
52 #include <pcmcia/ds.h>
53 #include <pcmcia/cisreg.h>
54
55 #include "8250.h"
56
57 #ifdef PCMCIA_DEBUG
58 static int pc_debug = PCMCIA_DEBUG;
59 module_param(pc_debug, int, 0644);
60 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
61 static char *version = "serial_cs.c 1.134 2002/05/04 05:48:53 (David Hinds)";
62 #else
63 #define DEBUG(n, args...)
64 #endif
65
66 /*====================================================================*/
67
68 /* Parameters that can be set with 'insmod' */
69
70 /* Enable the speaker? */
71 static int do_sound = 1;
72 /* Skip strict UART tests? */
73 static int buggy_uart;
74
75 module_param(do_sound, int, 0444);
76 module_param(buggy_uart, int, 0444);
77
78 /*====================================================================*/
79
80 /* Table of multi-port card ID's */
81
82 struct multi_id {
83         u_short manfid;
84         u_short prodid;
85         int multi;              /* 1 = multifunction, > 1 = # ports */
86 };
87
88 static const struct multi_id multi_id[] = {
89         { MANFID_OMEGA,   PRODID_OMEGA_QSP_100,         4 },
90         { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232,    2 },
91         { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
92         { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232,    4 },
93         { MANFID_SOCKET,  PRODID_SOCKET_DUAL_RS232,     2 },
94         { MANFID_INTEL,   PRODID_INTEL_DUAL_RS232,      2 },
95         { MANFID_NATINST, PRODID_NATINST_QUAD_RS232,    4 }
96 };
97 #define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
98
99 struct serial_info {
100         dev_link_t              link;
101         int                     ndev;
102         int                     multi;
103         int                     slave;
104         int                     manfid;
105         dev_node_t              node[4];
106         int                     line[4];
107 };
108
109 struct serial_cfg_mem {
110         tuple_t tuple;
111         cisparse_t parse;
112         u_char buf[256];
113 };
114
115
116 static void serial_config(dev_link_t * link);
117 static int serial_event(event_t event, int priority,
118                         event_callback_args_t * args);
119
120 static dev_info_t dev_info = "serial_cs";
121
122 static dev_link_t *serial_attach(void);
123 static void serial_detach(dev_link_t *);
124
125 static dev_link_t *dev_list = NULL;
126
127 /*======================================================================
128
129     After a card is removed, serial_remove() will unregister
130     the serial device(s), and release the PCMCIA configuration.
131     
132 ======================================================================*/
133
134 static void serial_remove(dev_link_t *link)
135 {
136         struct serial_info *info = link->priv;
137         int i;
138
139         link->state &= ~DEV_PRESENT;
140
141         DEBUG(0, "serial_release(0x%p)\n", link);
142
143         /*
144          * Recheck to see if the device is still configured.
145          */
146         if (info->link.state & DEV_CONFIG) {
147                 for (i = 0; i < info->ndev; i++)
148                         serial8250_unregister_port(info->line[i]);
149
150                 info->link.dev = NULL;
151
152                 if (!info->slave) {
153                         pcmcia_release_configuration(info->link.handle);
154                         pcmcia_release_io(info->link.handle, &info->link.io);
155                         pcmcia_release_irq(info->link.handle, &info->link.irq);
156                 }
157
158                 info->link.state &= ~DEV_CONFIG;
159         }
160 }
161
162 static void serial_suspend(dev_link_t *link)
163 {
164         link->state |= DEV_SUSPEND;
165
166         if (link->state & DEV_CONFIG) {
167                 struct serial_info *info = link->priv;
168                 int i;
169
170                 for (i = 0; i < info->ndev; i++)
171                         serial8250_suspend_port(info->line[i]);
172
173                 if (!info->slave)
174                         pcmcia_release_configuration(link->handle);
175         }
176 }
177
178 static void serial_resume(dev_link_t *link)
179 {
180         link->state &= ~DEV_SUSPEND;
181
182         if (DEV_OK(link)) {
183                 struct serial_info *info = link->priv;
184                 int i;
185
186                 if (!info->slave)
187                         pcmcia_request_configuration(link->handle, &link->conf);
188
189                 for (i = 0; i < info->ndev; i++)
190                         serial8250_resume_port(info->line[i]);
191         }
192 }
193
194 /*======================================================================
195
196     serial_attach() creates an "instance" of the driver, allocating
197     local data structures for one device.  The device is registered
198     with Card Services.
199
200 ======================================================================*/
201
202 static dev_link_t *serial_attach(void)
203 {
204         struct serial_info *info;
205         client_reg_t client_reg;
206         dev_link_t *link;
207         int ret;
208
209         DEBUG(0, "serial_attach()\n");
210
211         /* Create new serial device */
212         info = kmalloc(sizeof (*info), GFP_KERNEL);
213         if (!info)
214                 return NULL;
215         memset(info, 0, sizeof (*info));
216         link = &info->link;
217         link->priv = info;
218
219         link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
220         link->io.NumPorts1 = 8;
221         link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
222         link->irq.IRQInfo1 = IRQ_LEVEL_ID;
223         link->conf.Attributes = CONF_ENABLE_IRQ;
224         if (do_sound) {
225                 link->conf.Attributes |= CONF_ENABLE_SPKR;
226                 link->conf.Status = CCSR_AUDIO_ENA;
227         }
228         link->conf.IntType = INT_MEMORY_AND_IO;
229
230         /* Register with Card Services */
231         link->next = dev_list;
232         dev_list = link;
233         client_reg.dev_info = &dev_info;
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 != CS_SUCCESS) {
238                 cs_error(link->handle, RegisterClient, ret);
239                 serial_detach(link);
240                 return NULL;
241         }
242
243         return link;
244 }
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 serial_detach(dev_link_t * link)
256 {
257         struct serial_info *info = link->priv;
258         dev_link_t **linkp;
259         int ret;
260
261         DEBUG(0, "serial_detach(0x%p)\n", link);
262
263         /* Locate device structure */
264         for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
265                 if (*linkp == link)
266                         break;
267         if (*linkp == NULL)
268                 return;
269
270         /*
271          * Ensure any outstanding scheduled tasks are completed.
272          */
273         flush_scheduled_work();
274
275         /*
276          * Ensure that the ports have been released.
277          */
278         serial_remove(link);
279
280         if (link->handle) {
281                 ret = pcmcia_deregister_client(link->handle);
282                 if (ret != CS_SUCCESS)
283                         cs_error(link->handle, DeregisterClient, ret);
284         }
285
286         /* Unlink device structure, free bits */
287         *linkp = link->next;
288         kfree(info);
289 }
290
291 /*====================================================================*/
292
293 static int setup_serial(client_handle_t handle, struct serial_info * info,
294                         kio_addr_t iobase, int irq)
295 {
296         struct uart_port port;
297         int line;
298
299         memset(&port, 0, sizeof (struct uart_port));
300         port.iobase = iobase;
301         port.irq = irq;
302         port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
303         port.uartclk = 1843200;
304         port.dev = &handle_to_dev(handle);
305         if (buggy_uart)
306                 port.flags |= UPF_BUGGY_UART;
307         line = serial8250_register_port(&port);
308         if (line < 0) {
309                 printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
310                        "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
311                 return -EINVAL;
312         }
313
314         info->line[info->ndev] = line;
315         sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
316         info->node[info->ndev].major = TTY_MAJOR;
317         info->node[info->ndev].minor = 0x40 + line;
318         if (info->ndev > 0)
319                 info->node[info->ndev - 1].next = &info->node[info->ndev];
320         info->ndev++;
321
322         return 0;
323 }
324
325 /*====================================================================*/
326
327 static int
328 first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
329 {
330         int i;
331         i = pcmcia_get_first_tuple(handle, tuple);
332         if (i != CS_SUCCESS)
333                 return CS_NO_MORE_ITEMS;
334         i = pcmcia_get_tuple_data(handle, tuple);
335         if (i != CS_SUCCESS)
336                 return i;
337         return pcmcia_parse_tuple(handle, tuple, parse);
338 }
339
340 static int
341 next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
342 {
343         int i;
344         i = pcmcia_get_next_tuple(handle, tuple);
345         if (i != CS_SUCCESS)
346                 return CS_NO_MORE_ITEMS;
347         i = pcmcia_get_tuple_data(handle, tuple);
348         if (i != CS_SUCCESS)
349                 return i;
350         return pcmcia_parse_tuple(handle, tuple, parse);
351 }
352
353 /*====================================================================*/
354
355 static int simple_config(dev_link_t *link)
356 {
357         static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
358         static const int size_table[2] = { 8, 16 };
359         client_handle_t handle = link->handle;
360         struct serial_info *info = link->priv;
361         struct serial_cfg_mem *cfg_mem;
362         tuple_t *tuple;
363         u_char *buf;
364         cisparse_t *parse;
365         cistpl_cftable_entry_t *cf;
366         config_info_t config;
367         int i, j, try;
368         int s;
369
370         cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
371         if (!cfg_mem)
372                 return -1;
373
374         tuple = &cfg_mem->tuple;
375         parse = &cfg_mem->parse;
376         cf = &parse->cftable_entry;
377         buf = cfg_mem->buf;
378
379         /* If the card is already configured, look up the port and irq */
380         i = pcmcia_get_configuration_info(handle, &config);
381         if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
382                 kio_addr_t port = 0;
383                 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
384                         port = config.BasePort2;
385                         info->slave = 1;
386                 } else if ((info->manfid == MANFID_OSITECH) &&
387                            (config.NumPorts1 == 0x40)) {
388                         port = config.BasePort1 + 0x28;
389                         info->slave = 1;
390                 }
391                 if (info->slave) {
392                         kfree(cfg_mem);
393                         return setup_serial(handle, info, port, config.AssignedIRQ);
394                 }
395         }
396         link->conf.Vcc = config.Vcc;
397
398         /* First pass: look for a config entry that looks normal. */
399         tuple->TupleData = (cisdata_t *) buf;
400         tuple->TupleOffset = 0;
401         tuple->TupleDataMax = 255;
402         tuple->Attributes = 0;
403         tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
404         /* Two tries: without IO aliases, then with aliases */
405         for (s = 0; s < 2; s++) {
406                 for (try = 0; try < 2; try++) {
407                         i = first_tuple(handle, tuple, parse);
408                         while (i != CS_NO_MORE_ITEMS) {
409                                 if (i != CS_SUCCESS)
410                                         goto next_entry;
411                                 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
412                                         link->conf.Vpp1 = link->conf.Vpp2 =
413                                             cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
414                                 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
415                                             (cf->io.win[0].base != 0)) {
416                                         link->conf.ConfigIndex = cf->index;
417                                         link->io.BasePort1 = cf->io.win[0].base;
418                                         link->io.IOAddrLines = (try == 0) ?
419                                             16 : cf->io.flags & CISTPL_IO_LINES_MASK;
420                                         i = pcmcia_request_io(link->handle, &link->io);
421                                         if (i == CS_SUCCESS)
422                                                 goto found_port;
423                                 }
424 next_entry:
425                                 i = next_tuple(handle, tuple, parse);
426                         }
427                 }
428         }
429         /* Second pass: try to find an entry that isn't picky about
430            its base address, then try to grab any standard serial port
431            address, and finally try to get any free port. */
432         i = first_tuple(handle, tuple, parse);
433         while (i != CS_NO_MORE_ITEMS) {
434                 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
435                     ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
436                         link->conf.ConfigIndex = cf->index;
437                         for (j = 0; j < 5; j++) {
438                                 link->io.BasePort1 = base[j];
439                                 link->io.IOAddrLines = base[j] ? 16 : 3;
440                                 i = pcmcia_request_io(link->handle, &link->io);
441                                 if (i == CS_SUCCESS)
442                                         goto found_port;
443                         }
444                 }
445                 i = next_tuple(handle, tuple, parse);
446         }
447
448       found_port:
449         if (i != CS_SUCCESS) {
450                 printk(KERN_NOTICE
451                        "serial_cs: no usable port range found, giving up\n");
452                 cs_error(link->handle, RequestIO, i);
453                 kfree(cfg_mem);
454                 return -1;
455         }
456
457         i = pcmcia_request_irq(link->handle, &link->irq);
458         if (i != CS_SUCCESS) {
459                 cs_error(link->handle, RequestIRQ, i);
460                 link->irq.AssignedIRQ = 0;
461         }
462         if (info->multi && (info->manfid == MANFID_3COM))
463                 link->conf.ConfigIndex &= ~(0x08);
464         i = pcmcia_request_configuration(link->handle, &link->conf);
465         if (i != CS_SUCCESS) {
466                 cs_error(link->handle, RequestConfiguration, i);
467                 kfree(cfg_mem);
468                 return -1;
469         }
470         kfree(cfg_mem);
471         return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
472 }
473
474 static int multi_config(dev_link_t * link)
475 {
476         client_handle_t handle = link->handle;
477         struct serial_info *info = link->priv;
478         struct serial_cfg_mem *cfg_mem;
479         tuple_t *tuple;
480         u_char *buf;
481         cisparse_t *parse;
482         cistpl_cftable_entry_t *cf;
483         config_info_t config;
484         int i, rc, base2 = 0;
485
486         cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
487         if (!cfg_mem)
488                 return -1;
489         tuple = &cfg_mem->tuple;
490         parse = &cfg_mem->parse;
491         cf = &parse->cftable_entry;
492         buf = cfg_mem->buf;
493
494         i = pcmcia_get_configuration_info(handle, &config);
495         if (i != CS_SUCCESS) {
496                 cs_error(handle, GetConfigurationInfo, i);
497                 rc = -1;
498                 goto free_cfg_mem;
499         }
500         link->conf.Vcc = config.Vcc;
501
502         tuple->TupleData = (cisdata_t *) buf;
503         tuple->TupleOffset = 0;
504         tuple->TupleDataMax = 255;
505         tuple->Attributes = 0;
506         tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
507
508         /* First, look for a generic full-sized window */
509         link->io.NumPorts1 = info->multi * 8;
510         i = first_tuple(handle, tuple, parse);
511         while (i != CS_NO_MORE_ITEMS) {
512                 /* The quad port cards have bad CIS's, so just look for a
513                    window larger than 8 ports and assume it will be right */
514                 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
515                     (cf->io.win[0].len > 8)) {
516                         link->conf.ConfigIndex = cf->index;
517                         link->io.BasePort1 = cf->io.win[0].base;
518                         link->io.IOAddrLines =
519                             cf->io.flags & CISTPL_IO_LINES_MASK;
520                         i = pcmcia_request_io(link->handle, &link->io);
521                         base2 = link->io.BasePort1 + 8;
522                         if (i == CS_SUCCESS)
523                                 break;
524                 }
525                 i = next_tuple(handle, tuple, parse);
526         }
527
528         /* If that didn't work, look for two windows */
529         if (i != CS_SUCCESS) {
530                 link->io.NumPorts1 = link->io.NumPorts2 = 8;
531                 info->multi = 2;
532                 i = first_tuple(handle, tuple, parse);
533                 while (i != CS_NO_MORE_ITEMS) {
534                         if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
535                                 link->conf.ConfigIndex = cf->index;
536                                 link->io.BasePort1 = cf->io.win[0].base;
537                                 link->io.BasePort2 = cf->io.win[1].base;
538                                 link->io.IOAddrLines =
539                                     cf->io.flags & CISTPL_IO_LINES_MASK;
540                                 i = pcmcia_request_io(link->handle, &link->io);
541                                 base2 = link->io.BasePort2;
542                                 if (i == CS_SUCCESS)
543                                         break;
544                         }
545                         i = next_tuple(handle, tuple, parse);
546                 }
547         }
548
549         if (i != CS_SUCCESS) {
550                 cs_error(link->handle, RequestIO, i);
551                 rc = -1;
552                 goto free_cfg_mem;
553         }
554
555         i = pcmcia_request_irq(link->handle, &link->irq);
556         if (i != CS_SUCCESS) {
557                 printk(KERN_NOTICE
558                        "serial_cs: no usable port range found, giving up\n");
559                 cs_error(link->handle, RequestIRQ, i);
560                 link->irq.AssignedIRQ = 0;
561         }
562         /* Socket Dual IO: this enables irq's for second port */
563         if (info->multi && (info->manfid == MANFID_SOCKET)) {
564                 link->conf.Present |= PRESENT_EXT_STATUS;
565                 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
566         }
567         i = pcmcia_request_configuration(link->handle, &link->conf);
568         if (i != CS_SUCCESS) {
569                 cs_error(link->handle, RequestConfiguration, i);
570                 rc = -1;
571                 goto free_cfg_mem;
572         }
573
574         /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
575            8 registers are for the UART, the others are extra registers */
576         if (info->manfid == MANFID_OXSEMI) {
577                 if (cf->index == 1 || cf->index == 3) {
578                         setup_serial(handle, info, base2, link->irq.AssignedIRQ);
579                         outb(12, link->io.BasePort1 + 1);
580                 } else {
581                         setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
582                         outb(12, base2 + 1);
583                 }
584                 rc = 0;
585                 goto free_cfg_mem;
586         }
587
588         setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
589         /* The Nokia cards are not really multiport cards */
590         if (info->manfid == MANFID_NOKIA) {
591                 rc = 0;
592                 goto free_cfg_mem;
593         }
594         for (i = 0; i < info->multi - 1; i++)
595                 setup_serial(handle, info, base2 + (8 * i),
596                                 link->irq.AssignedIRQ);
597         rc = 0;
598 free_cfg_mem:
599         kfree(cfg_mem);
600         return rc;
601 }
602
603 /*======================================================================
604
605     serial_config() is scheduled to run after a CARD_INSERTION event
606     is received, to configure the PCMCIA socket, and to make the
607     serial device available to the system.
608
609 ======================================================================*/
610
611 void serial_config(dev_link_t * link)
612 {
613         client_handle_t handle = link->handle;
614         struct serial_info *info = link->priv;
615         struct serial_cfg_mem *cfg_mem;
616         tuple_t *tuple;
617         u_char *buf;
618         cisparse_t *parse;
619         cistpl_cftable_entry_t *cf;
620         int i, last_ret, last_fn;
621
622         DEBUG(0, "serial_config(0x%p)\n", link);
623
624         cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
625         if (!cfg_mem)
626                 goto failed;
627
628         tuple = &cfg_mem->tuple;
629         parse = &cfg_mem->parse;
630         cf = &parse->cftable_entry;
631         buf = cfg_mem->buf;
632
633         tuple->TupleData = (cisdata_t *) buf;
634         tuple->TupleOffset = 0;
635         tuple->TupleDataMax = 255;
636         tuple->Attributes = 0;
637         /* Get configuration register information */
638         tuple->DesiredTuple = CISTPL_CONFIG;
639         last_ret = first_tuple(handle, tuple, parse);
640         if (last_ret != CS_SUCCESS) {
641                 last_fn = ParseTuple;
642                 goto cs_failed;
643         }
644         link->conf.ConfigBase = parse->config.base;
645         link->conf.Present = parse->config.rmask[0];
646
647         /* Configure card */
648         link->state |= DEV_CONFIG;
649
650         /* Is this a compliant multifunction card? */
651         tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
652         tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
653         info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS);
654
655         /* Is this a multiport card? */
656         tuple->DesiredTuple = CISTPL_MANFID;
657         if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
658                 info->manfid = parse->manfid.manf;
659                 for (i = 0; i < MULTI_COUNT; i++)
660                         if ((info->manfid == multi_id[i].manfid) &&
661                             (parse->manfid.card == multi_id[i].prodid))
662                                 break;
663                 if (i < MULTI_COUNT)
664                         info->multi = multi_id[i].multi;
665         }
666
667         /* Another check for dual-serial cards: look for either serial or
668            multifunction cards that ask for appropriate IO port ranges */
669         tuple->DesiredTuple = CISTPL_FUNCID;
670         if ((info->multi == 0) &&
671             ((first_tuple(handle, tuple, parse) != CS_SUCCESS) ||
672              (parse->funcid.func == CISTPL_FUNCID_MULTI) ||
673              (parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
674                 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
675                 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
676                         if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
677                                 info->multi = cf->io.win[0].len >> 3;
678                         if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
679                             (cf->io.win[1].len == 8))
680                                 info->multi = 2;
681                 }
682         }
683
684         if (info->multi > 1)
685                 multi_config(link);
686         else
687                 simple_config(link);
688
689         if (info->ndev == 0)
690                 goto failed;
691
692         if (info->manfid == MANFID_IBM) {
693                 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
694                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
695                 if (last_ret) {
696                         last_fn = AccessConfigurationRegister;
697                         goto cs_failed;
698                 }
699                 reg.Action = CS_WRITE;
700                 reg.Value = reg.Value | 1;
701                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
702                 if (last_ret) {
703                         last_fn = AccessConfigurationRegister;
704                         goto cs_failed;
705                 }
706         }
707
708         link->dev = &info->node[0];
709         link->state &= ~DEV_CONFIG_PENDING;
710         kfree(cfg_mem);
711         return;
712
713  cs_failed:
714         cs_error(link->handle, last_fn, last_ret);
715  failed:
716         serial_remove(link);
717         link->state &= ~DEV_CONFIG_PENDING;
718         kfree(cfg_mem);
719 }
720
721 /*======================================================================
722
723     The card status event handler.  Mostly, this schedules other
724     stuff to run after an event is received.  A CARD_REMOVAL event
725     also sets some flags to discourage the serial drivers from
726     talking to the ports.
727     
728 ======================================================================*/
729
730 static int
731 serial_event(event_t event, int priority, event_callback_args_t * args)
732 {
733         dev_link_t *link = args->client_data;
734         struct serial_info *info = link->priv;
735
736         DEBUG(1, "serial_event(0x%06x)\n", event);
737
738         switch (event) {
739         case CS_EVENT_CARD_REMOVAL:
740                 serial_remove(link);
741                 break;
742
743         case CS_EVENT_CARD_INSERTION:
744                 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
745                 serial_config(link);
746                 break;
747
748         case CS_EVENT_PM_SUSPEND:
749                 serial_suspend(link);
750                 break;
751
752         case CS_EVENT_RESET_PHYSICAL:
753                 if ((link->state & DEV_CONFIG) && !info->slave)
754                         pcmcia_release_configuration(link->handle);
755                 break;
756
757         case CS_EVENT_PM_RESUME:
758                 serial_resume(link);
759                 break;
760
761         case CS_EVENT_CARD_RESET:
762                 if (DEV_OK(link) && !info->slave)
763                         pcmcia_request_configuration(link->handle, &link->conf);
764                 break;
765         }
766         return 0;
767 }
768
769 static struct pcmcia_device_id serial_ids[] = {
770         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
771         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
772         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
773         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
774         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
775         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
776         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
777         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
778         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
779         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
780         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
781         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
782         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
783         PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
784         PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
785         PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
786         PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
787         PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
788         PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
789         PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
790         PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
791         PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
792         PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
793         PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
794         PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
795         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
796         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
797         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
798         PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
799         PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
800         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
801         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
802         PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
803         PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
804         PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
805         PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
806         PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
807         PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
808         PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
809         PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
810         PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
811         PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
812         PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
813         PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
814         PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
815         PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
816         PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
817         PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
818         PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
819         PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
820         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
821         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
822         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
823         PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
824         PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
825         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
826         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
827         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
828         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
829         PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
830         PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
831         PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
832         PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
833         PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
834         PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
835         PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
836         PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
837         PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
838         PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
839         PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
840         PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
841         PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
842         PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
843         PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
844         PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
845         PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
846         PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
847         PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
848         PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
849         PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
850         PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
851         PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
852         PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
853         PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
854         PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
855         PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
856         PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
857         PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
858         PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
859         PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
860         PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
861         PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
862         PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
863         PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
864         PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
865         PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
866         PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
867         /* too generic */
868         /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
869         /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
870         PCMCIA_DEVICE_FUNC_ID(2),
871         PCMCIA_DEVICE_NULL,
872 };
873 MODULE_DEVICE_TABLE(pcmcia, serial_ids);
874
875 static struct pcmcia_driver serial_cs_driver = {
876         .owner          = THIS_MODULE,
877         .drv            = {
878                 .name   = "serial_cs",
879         },
880         .attach         = serial_attach,
881         .event          = serial_event,
882         .detach         = serial_detach,
883         .id_table       = serial_ids,
884 };
885
886 static int __init init_serial_cs(void)
887 {
888         return pcmcia_register_driver(&serial_cs_driver);
889 }
890
891 static void __exit exit_serial_cs(void)
892 {
893         pcmcia_unregister_driver(&serial_cs_driver);
894         BUG_ON(dev_list != NULL);
895 }
896
897 module_init(init_serial_cs);
898 module_exit(exit_serial_cs);
899
900 MODULE_LICENSE("GPL");