Linux-2.6.12-rc2
[pandora-kernel.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(client_handle_t handle, struct serial_info * info,
293                         kio_addr_t iobase, int irq)
294 {
295         struct uart_port port;
296         int line;
297
298         memset(&port, 0, sizeof (struct uart_port));
299         port.iobase = iobase;
300         port.irq = irq;
301         port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
302         port.uartclk = 1843200;
303         port.dev = &handle_to_dev(handle);
304         if (buggy_uart)
305                 port.flags |= UPF_BUGGY_UART;
306         line = serial8250_register_port(&port);
307         if (line < 0) {
308                 printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
309                        "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
310                 return -EINVAL;
311         }
312
313         info->line[info->ndev] = line;
314         sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
315         info->node[info->ndev].major = TTY_MAJOR;
316         info->node[info->ndev].minor = 0x40 + line;
317         if (info->ndev > 0)
318                 info->node[info->ndev - 1].next = &info->node[info->ndev];
319         info->ndev++;
320
321         return 0;
322 }
323
324 /*====================================================================*/
325
326 static int
327 first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
328 {
329         int i;
330         i = pcmcia_get_first_tuple(handle, tuple);
331         if (i != CS_SUCCESS)
332                 return CS_NO_MORE_ITEMS;
333         i = pcmcia_get_tuple_data(handle, tuple);
334         if (i != CS_SUCCESS)
335                 return i;
336         return pcmcia_parse_tuple(handle, tuple, parse);
337 }
338
339 static int
340 next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
341 {
342         int i;
343         i = pcmcia_get_next_tuple(handle, tuple);
344         if (i != CS_SUCCESS)
345                 return CS_NO_MORE_ITEMS;
346         i = pcmcia_get_tuple_data(handle, tuple);
347         if (i != CS_SUCCESS)
348                 return i;
349         return pcmcia_parse_tuple(handle, tuple, parse);
350 }
351
352 /*====================================================================*/
353
354 static int simple_config(dev_link_t *link)
355 {
356         static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
357         static int size_table[2] = { 8, 16 };
358         client_handle_t handle = link->handle;
359         struct serial_info *info = link->priv;
360         tuple_t tuple;
361         u_char buf[256];
362         cisparse_t parse;
363         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
364         config_info_t config;
365         int i, j, try;
366         int s;
367
368         /* If the card is already configured, look up the port and irq */
369         i = pcmcia_get_configuration_info(handle, &config);
370         if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
371                 kio_addr_t port = 0;
372                 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
373                         port = config.BasePort2;
374                         info->slave = 1;
375                 } else if ((info->manfid == MANFID_OSITECH) &&
376                            (config.NumPorts1 == 0x40)) {
377                         port = config.BasePort1 + 0x28;
378                         info->slave = 1;
379                 }
380                 if (info->slave)
381                         return setup_serial(handle, info, port, config.AssignedIRQ);
382         }
383         link->conf.Vcc = config.Vcc;
384
385         /* First pass: look for a config entry that looks normal. */
386         tuple.TupleData = (cisdata_t *) buf;
387         tuple.TupleOffset = 0;
388         tuple.TupleDataMax = 255;
389         tuple.Attributes = 0;
390         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
391         /* Two tries: without IO aliases, then with aliases */
392         for (s = 0; s < 2; s++) {
393                 for (try = 0; try < 2; try++) {
394                         i = first_tuple(handle, &tuple, &parse);
395                         while (i != CS_NO_MORE_ITEMS) {
396                                 if (i != CS_SUCCESS)
397                                         goto next_entry;
398                                 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
399                                         link->conf.Vpp1 = link->conf.Vpp2 =
400                                             cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
401                                 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
402                                             (cf->io.win[0].base != 0)) {
403                                         link->conf.ConfigIndex = cf->index;
404                                         link->io.BasePort1 = cf->io.win[0].base;
405                                         link->io.IOAddrLines = (try == 0) ?
406                                             16 : cf->io.flags & CISTPL_IO_LINES_MASK;
407                                         i = pcmcia_request_io(link->handle, &link->io);
408                                         if (i == CS_SUCCESS)
409                                                 goto found_port;
410                                 }
411 next_entry:
412                                 i = next_tuple(handle, &tuple, &parse);
413                         }
414                 }
415         }
416         /* Second pass: try to find an entry that isn't picky about
417            its base address, then try to grab any standard serial port
418            address, and finally try to get any free port. */
419         i = first_tuple(handle, &tuple, &parse);
420         while (i != CS_NO_MORE_ITEMS) {
421                 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
422                     ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
423                         link->conf.ConfigIndex = cf->index;
424                         for (j = 0; j < 5; j++) {
425                                 link->io.BasePort1 = base[j];
426                                 link->io.IOAddrLines = base[j] ? 16 : 3;
427                                 i = pcmcia_request_io(link->handle, &link->io);
428                                 if (i == CS_SUCCESS)
429                                         goto found_port;
430                         }
431                 }
432                 i = next_tuple(handle, &tuple, &parse);
433         }
434
435       found_port:
436         if (i != CS_SUCCESS) {
437                 printk(KERN_NOTICE
438                        "serial_cs: no usable port range found, giving up\n");
439                 cs_error(link->handle, RequestIO, i);
440                 return -1;
441         }
442
443         i = pcmcia_request_irq(link->handle, &link->irq);
444         if (i != CS_SUCCESS) {
445                 cs_error(link->handle, RequestIRQ, i);
446                 link->irq.AssignedIRQ = 0;
447         }
448         if (info->multi && (info->manfid == MANFID_3COM))
449                 link->conf.ConfigIndex &= ~(0x08);
450         i = pcmcia_request_configuration(link->handle, &link->conf);
451         if (i != CS_SUCCESS) {
452                 cs_error(link->handle, RequestConfiguration, i);
453                 return -1;
454         }
455
456         return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
457 }
458
459 static int multi_config(dev_link_t * link)
460 {
461         client_handle_t handle = link->handle;
462         struct serial_info *info = link->priv;
463         tuple_t tuple;
464         u_char buf[256];
465         cisparse_t parse;
466         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
467         config_info_t config;
468         int i, base2 = 0;
469
470         i = pcmcia_get_configuration_info(handle, &config);
471         if (i != CS_SUCCESS) {
472                 cs_error(handle, GetConfigurationInfo, i);
473                 return -1;
474         }
475         link->conf.Vcc = config.Vcc;
476
477         tuple.TupleData = (cisdata_t *) buf;
478         tuple.TupleOffset = 0;
479         tuple.TupleDataMax = 255;
480         tuple.Attributes = 0;
481         tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
482
483         /* First, look for a generic full-sized window */
484         link->io.NumPorts1 = info->multi * 8;
485         i = first_tuple(handle, &tuple, &parse);
486         while (i != CS_NO_MORE_ITEMS) {
487                 /* The quad port cards have bad CIS's, so just look for a
488                    window larger than 8 ports and assume it will be right */
489                 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
490                     (cf->io.win[0].len > 8)) {
491                         link->conf.ConfigIndex = cf->index;
492                         link->io.BasePort1 = cf->io.win[0].base;
493                         link->io.IOAddrLines =
494                             cf->io.flags & CISTPL_IO_LINES_MASK;
495                         i = pcmcia_request_io(link->handle, &link->io);
496                         base2 = link->io.BasePort1 + 8;
497                         if (i == CS_SUCCESS)
498                                 break;
499                 }
500                 i = next_tuple(handle, &tuple, &parse);
501         }
502
503         /* If that didn't work, look for two windows */
504         if (i != CS_SUCCESS) {
505                 link->io.NumPorts1 = link->io.NumPorts2 = 8;
506                 info->multi = 2;
507                 i = first_tuple(handle, &tuple, &parse);
508                 while (i != CS_NO_MORE_ITEMS) {
509                         if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
510                                 link->conf.ConfigIndex = cf->index;
511                                 link->io.BasePort1 = cf->io.win[0].base;
512                                 link->io.BasePort2 = cf->io.win[1].base;
513                                 link->io.IOAddrLines =
514                                     cf->io.flags & CISTPL_IO_LINES_MASK;
515                                 i = pcmcia_request_io(link->handle, &link->io);
516                                 base2 = link->io.BasePort2;
517                                 if (i == CS_SUCCESS)
518                                         break;
519                         }
520                         i = next_tuple(handle, &tuple, &parse);
521                 }
522         }
523
524         if (i != CS_SUCCESS) {
525                 cs_error(link->handle, RequestIO, i);
526                 return -1;
527         }
528
529         i = pcmcia_request_irq(link->handle, &link->irq);
530         if (i != CS_SUCCESS) {
531                 printk(KERN_NOTICE
532                        "serial_cs: no usable port range found, giving up\n");
533                 cs_error(link->handle, RequestIRQ, i);
534                 link->irq.AssignedIRQ = 0;
535         }
536         /* Socket Dual IO: this enables irq's for second port */
537         if (info->multi && (info->manfid == MANFID_SOCKET)) {
538                 link->conf.Present |= PRESENT_EXT_STATUS;
539                 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
540         }
541         i = pcmcia_request_configuration(link->handle, &link->conf);
542         if (i != CS_SUCCESS) {
543                 cs_error(link->handle, RequestConfiguration, i);
544                 return -1;
545         }
546
547         /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
548            8 registers are for the UART, the others are extra registers */
549         if (info->manfid == MANFID_OXSEMI) {
550                 if (cf->index == 1 || cf->index == 3) {
551                         setup_serial(handle, info, base2, link->irq.AssignedIRQ);
552                         outb(12, link->io.BasePort1 + 1);
553                 } else {
554                         setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
555                         outb(12, base2 + 1);
556                 }
557                 return 0;
558         }
559
560         setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
561         /* The Nokia cards are not really multiport cards */
562         if (info->manfid == MANFID_NOKIA)
563                 return 0;
564         for (i = 0; i < info->multi - 1; i++)
565                 setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ);
566
567         return 0;
568 }
569
570 /*======================================================================
571
572     serial_config() is scheduled to run after a CARD_INSERTION event
573     is received, to configure the PCMCIA socket, and to make the
574     serial device available to the system.
575
576 ======================================================================*/
577
578 void serial_config(dev_link_t * link)
579 {
580         client_handle_t handle = link->handle;
581         struct serial_info *info = link->priv;
582         tuple_t tuple;
583         u_short buf[128];
584         cisparse_t parse;
585         cistpl_cftable_entry_t *cf = &parse.cftable_entry;
586         int i, last_ret, last_fn;
587
588         DEBUG(0, "serial_config(0x%p)\n", link);
589
590         tuple.TupleData = (cisdata_t *) buf;
591         tuple.TupleOffset = 0;
592         tuple.TupleDataMax = 255;
593         tuple.Attributes = 0;
594         /* Get configuration register information */
595         tuple.DesiredTuple = CISTPL_CONFIG;
596         last_ret = first_tuple(handle, &tuple, &parse);
597         if (last_ret != CS_SUCCESS) {
598                 last_fn = ParseTuple;
599                 goto cs_failed;
600         }
601         link->conf.ConfigBase = parse.config.base;
602         link->conf.Present = parse.config.rmask[0];
603
604         /* Configure card */
605         link->state |= DEV_CONFIG;
606
607         /* Is this a compliant multifunction card? */
608         tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
609         tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
610         info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
611
612         /* Is this a multiport card? */
613         tuple.DesiredTuple = CISTPL_MANFID;
614         if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
615                 info->manfid = le16_to_cpu(buf[0]);
616                 for (i = 0; i < MULTI_COUNT; i++)
617                         if ((info->manfid == multi_id[i].manfid) &&
618                             (le16_to_cpu(buf[1]) == multi_id[i].prodid))
619                                 break;
620                 if (i < MULTI_COUNT)
621                         info->multi = multi_id[i].multi;
622         }
623
624         /* Another check for dual-serial cards: look for either serial or
625            multifunction cards that ask for appropriate IO port ranges */
626         tuple.DesiredTuple = CISTPL_FUNCID;
627         if ((info->multi == 0) &&
628             ((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||
629              (parse.funcid.func == CISTPL_FUNCID_MULTI) ||
630              (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {
631                 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
632                 if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
633                         if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
634                                 info->multi = cf->io.win[0].len >> 3;
635                         if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
636                             (cf->io.win[1].len == 8))
637                                 info->multi = 2;
638                 }
639         }
640
641         if (info->multi > 1)
642                 multi_config(link);
643         else
644                 simple_config(link);
645
646         if (info->ndev == 0)
647                 goto failed;
648
649         if (info->manfid == MANFID_IBM) {
650                 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
651                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
652                 if (last_ret) {
653                         last_fn = AccessConfigurationRegister;
654                         goto cs_failed;
655                 }
656                 reg.Action = CS_WRITE;
657                 reg.Value = reg.Value | 1;
658                 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
659                 if (last_ret) {
660                         last_fn = AccessConfigurationRegister;
661                         goto cs_failed;
662                 }
663         }
664
665         link->dev = &info->node[0];
666         link->state &= ~DEV_CONFIG_PENDING;
667         return;
668
669  cs_failed:
670         cs_error(link->handle, last_fn, last_ret);
671  failed:
672         serial_remove(link);
673         link->state &= ~DEV_CONFIG_PENDING;
674 }
675
676 /*======================================================================
677
678     The card status event handler.  Mostly, this schedules other
679     stuff to run after an event is received.  A CARD_REMOVAL event
680     also sets some flags to discourage the serial drivers from
681     talking to the ports.
682     
683 ======================================================================*/
684
685 static int
686 serial_event(event_t event, int priority, event_callback_args_t * args)
687 {
688         dev_link_t *link = args->client_data;
689         struct serial_info *info = link->priv;
690
691         DEBUG(1, "serial_event(0x%06x)\n", event);
692
693         switch (event) {
694         case CS_EVENT_CARD_REMOVAL:
695                 serial_remove(link);
696                 break;
697
698         case CS_EVENT_CARD_INSERTION:
699                 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
700                 serial_config(link);
701                 break;
702
703         case CS_EVENT_PM_SUSPEND:
704                 serial_suspend(link);
705                 break;
706
707         case CS_EVENT_RESET_PHYSICAL:
708                 if ((link->state & DEV_CONFIG) && !info->slave)
709                         pcmcia_release_configuration(link->handle);
710                 break;
711
712         case CS_EVENT_PM_RESUME:
713                 serial_resume(link);
714                 break;
715
716         case CS_EVENT_CARD_RESET:
717                 if (DEV_OK(link) && !info->slave)
718                         pcmcia_request_configuration(link->handle, &link->conf);
719                 break;
720         }
721         return 0;
722 }
723
724 static struct pcmcia_driver serial_cs_driver = {
725         .owner          = THIS_MODULE,
726         .drv            = {
727                 .name   = "serial_cs",
728         },
729         .attach         = serial_attach,
730         .detach         = serial_detach,
731 };
732
733 static int __init init_serial_cs(void)
734 {
735         return pcmcia_register_driver(&serial_cs_driver);
736 }
737
738 static void __exit exit_serial_cs(void)
739 {
740         pcmcia_unregister_driver(&serial_cs_driver);
741         BUG_ON(dev_list != NULL);
742 }
743
744 module_init(init_serial_cs);
745 module_exit(exit_serial_cs);
746
747 MODULE_LICENSE("GPL");