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