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