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