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