[PATCH] pcmcia: move event handler
[deliverable/linux.git] / drivers / serial / serial_cs.c
1 /*======================================================================
2
3 A driver for PCMCIA serial devices
4
5 serial_cs.c 1.134 2002/05/04 05:48:53
6
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
11
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
16
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in which
23 case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
31
32 ======================================================================*/
33
34 #include <linux/module.h>
35 #include <linux/moduleparam.h>
36 #include <linux/kernel.h>
37 #include <linux/init.h>
38 #include <linux/sched.h>
39 #include <linux/ptrace.h>
40 #include <linux/slab.h>
41 #include <linux/string.h>
42 #include <linux/timer.h>
43 #include <linux/serial_core.h>
44 #include <linux/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 struct serial_cfg_mem {
111 tuple_t tuple;
112 cisparse_t parse;
113 u_char buf[256];
114 };
115
116
117 static void serial_config(dev_link_t * link);
118 static int serial_event(event_t event, int priority,
119 event_callback_args_t * args);
120
121 static dev_info_t dev_info = "serial_cs";
122
123 static dev_link_t *serial_attach(void);
124 static void serial_detach(dev_link_t *);
125
126 static dev_link_t *dev_list = NULL;
127
128 /*======================================================================
129
130 After a card is removed, serial_remove() will unregister
131 the serial device(s), and release the PCMCIA configuration.
132
133 ======================================================================*/
134
135 static void serial_remove(dev_link_t *link)
136 {
137 struct serial_info *info = link->priv;
138 int i;
139
140 link->state &= ~DEV_PRESENT;
141
142 DEBUG(0, "serial_release(0x%p)\n", link);
143
144 /*
145 * Recheck to see if the device is still configured.
146 */
147 if (info->link.state & DEV_CONFIG) {
148 for (i = 0; i < info->ndev; i++)
149 serial8250_unregister_port(info->line[i]);
150
151 info->link.dev = NULL;
152
153 if (!info->slave) {
154 pcmcia_release_configuration(info->link.handle);
155 pcmcia_release_io(info->link.handle, &info->link.io);
156 pcmcia_release_irq(info->link.handle, &info->link.irq);
157 }
158
159 info->link.state &= ~DEV_CONFIG;
160 }
161 }
162
163 static void serial_suspend(dev_link_t *link)
164 {
165 link->state |= DEV_SUSPEND;
166
167 if (link->state & DEV_CONFIG) {
168 struct serial_info *info = link->priv;
169 int i;
170
171 for (i = 0; i < info->ndev; i++)
172 serial8250_suspend_port(info->line[i]);
173
174 if (!info->slave)
175 pcmcia_release_configuration(link->handle);
176 }
177 }
178
179 static void serial_resume(dev_link_t *link)
180 {
181 link->state &= ~DEV_SUSPEND;
182
183 if (DEV_OK(link)) {
184 struct serial_info *info = link->priv;
185 int i;
186
187 if (!info->slave)
188 pcmcia_request_configuration(link->handle, &link->conf);
189
190 for (i = 0; i < info->ndev; i++)
191 serial8250_resume_port(info->line[i]);
192 }
193 }
194
195 /*======================================================================
196
197 serial_attach() creates an "instance" of the driver, allocating
198 local data structures for one device. The device is registered
199 with Card Services.
200
201 ======================================================================*/
202
203 static dev_link_t *serial_attach(void)
204 {
205 struct serial_info *info;
206 client_reg_t client_reg;
207 dev_link_t *link;
208 int ret;
209
210 DEBUG(0, "serial_attach()\n");
211
212 /* Create new serial device */
213 info = kmalloc(sizeof (*info), GFP_KERNEL);
214 if (!info)
215 return NULL;
216 memset(info, 0, sizeof (*info));
217 link = &info->link;
218 link->priv = info;
219
220 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
221 link->io.NumPorts1 = 8;
222 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
223 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
224 link->conf.Attributes = CONF_ENABLE_IRQ;
225 if (do_sound) {
226 link->conf.Attributes |= CONF_ENABLE_SPKR;
227 link->conf.Status = CCSR_AUDIO_ENA;
228 }
229 link->conf.IntType = INT_MEMORY_AND_IO;
230
231 /* Register with Card Services */
232 link->next = dev_list;
233 dev_list = link;
234 client_reg.dev_info = &dev_info;
235 client_reg.Version = 0x0210;
236 client_reg.event_callback_args.client_data = link;
237 ret = pcmcia_register_client(&link->handle, &client_reg);
238 if (ret != CS_SUCCESS) {
239 cs_error(link->handle, RegisterClient, ret);
240 serial_detach(link);
241 return NULL;
242 }
243
244 return link;
245 }
246
247 /*======================================================================
248
249 This deletes a driver "instance". The device is de-registered
250 with Card Services. If it has been released, all local data
251 structures are freed. Otherwise, the structures will be freed
252 when the device is released.
253
254 ======================================================================*/
255
256 static void serial_detach(dev_link_t * link)
257 {
258 struct serial_info *info = link->priv;
259 dev_link_t **linkp;
260 int ret;
261
262 DEBUG(0, "serial_detach(0x%p)\n", link);
263
264 /* Locate device structure */
265 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
266 if (*linkp == link)
267 break;
268 if (*linkp == NULL)
269 return;
270
271 /*
272 * Ensure any outstanding scheduled tasks are completed.
273 */
274 flush_scheduled_work();
275
276 /*
277 * Ensure that the ports have been released.
278 */
279 serial_remove(link);
280
281 if (link->handle) {
282 ret = pcmcia_deregister_client(link->handle);
283 if (ret != CS_SUCCESS)
284 cs_error(link->handle, DeregisterClient, ret);
285 }
286
287 /* Unlink device structure, free bits */
288 *linkp = link->next;
289 kfree(info);
290 }
291
292 /*====================================================================*/
293
294 static int setup_serial(client_handle_t handle, struct serial_info * info,
295 kio_addr_t iobase, int irq)
296 {
297 struct uart_port port;
298 int line;
299
300 memset(&port, 0, sizeof (struct uart_port));
301 port.iobase = iobase;
302 port.irq = irq;
303 port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
304 port.uartclk = 1843200;
305 port.dev = &handle_to_dev(handle);
306 if (buggy_uart)
307 port.flags |= UPF_BUGGY_UART;
308 line = serial8250_register_port(&port);
309 if (line < 0) {
310 printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
311 "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
312 return -EINVAL;
313 }
314
315 info->line[info->ndev] = line;
316 sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
317 info->node[info->ndev].major = TTY_MAJOR;
318 info->node[info->ndev].minor = 0x40 + line;
319 if (info->ndev > 0)
320 info->node[info->ndev - 1].next = &info->node[info->ndev];
321 info->ndev++;
322
323 return 0;
324 }
325
326 /*====================================================================*/
327
328 static int
329 first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
330 {
331 int i;
332 i = pcmcia_get_first_tuple(handle, tuple);
333 if (i != CS_SUCCESS)
334 return CS_NO_MORE_ITEMS;
335 i = pcmcia_get_tuple_data(handle, tuple);
336 if (i != CS_SUCCESS)
337 return i;
338 return pcmcia_parse_tuple(handle, tuple, parse);
339 }
340
341 static int
342 next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
343 {
344 int i;
345 i = pcmcia_get_next_tuple(handle, tuple);
346 if (i != CS_SUCCESS)
347 return CS_NO_MORE_ITEMS;
348 i = pcmcia_get_tuple_data(handle, tuple);
349 if (i != CS_SUCCESS)
350 return i;
351 return pcmcia_parse_tuple(handle, tuple, parse);
352 }
353
354 /*====================================================================*/
355
356 static int simple_config(dev_link_t *link)
357 {
358 static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
359 static int size_table[2] = { 8, 16 };
360 client_handle_t handle = link->handle;
361 struct serial_info *info = link->priv;
362 struct serial_cfg_mem *cfg_mem;
363 tuple_t *tuple;
364 u_char *buf;
365 cisparse_t *parse;
366 cistpl_cftable_entry_t *cf;
367 config_info_t config;
368 int i, j, try;
369 int s;
370
371 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
372 if (!cfg_mem)
373 return -1;
374
375 tuple = &cfg_mem->tuple;
376 parse = &cfg_mem->parse;
377 cf = &parse->cftable_entry;
378 buf = cfg_mem->buf;
379
380 /* If the card is already configured, look up the port and irq */
381 i = pcmcia_get_configuration_info(handle, &config);
382 if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
383 kio_addr_t port = 0;
384 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
385 port = config.BasePort2;
386 info->slave = 1;
387 } else if ((info->manfid == MANFID_OSITECH) &&
388 (config.NumPorts1 == 0x40)) {
389 port = config.BasePort1 + 0x28;
390 info->slave = 1;
391 }
392 if (info->slave) {
393 kfree(cfg_mem);
394 return setup_serial(handle, info, port, config.AssignedIRQ);
395 }
396 }
397 link->conf.Vcc = config.Vcc;
398
399 /* First pass: look for a config entry that looks normal. */
400 tuple->TupleData = (cisdata_t *) buf;
401 tuple->TupleOffset = 0;
402 tuple->TupleDataMax = 255;
403 tuple->Attributes = 0;
404 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
405 /* Two tries: without IO aliases, then with aliases */
406 for (s = 0; s < 2; s++) {
407 for (try = 0; try < 2; try++) {
408 i = first_tuple(handle, tuple, parse);
409 while (i != CS_NO_MORE_ITEMS) {
410 if (i != CS_SUCCESS)
411 goto next_entry;
412 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
413 link->conf.Vpp1 = link->conf.Vpp2 =
414 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
415 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
416 (cf->io.win[0].base != 0)) {
417 link->conf.ConfigIndex = cf->index;
418 link->io.BasePort1 = cf->io.win[0].base;
419 link->io.IOAddrLines = (try == 0) ?
420 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
421 i = pcmcia_request_io(link->handle, &link->io);
422 if (i == CS_SUCCESS)
423 goto found_port;
424 }
425 next_entry:
426 i = next_tuple(handle, tuple, parse);
427 }
428 }
429 }
430 /* Second pass: try to find an entry that isn't picky about
431 its base address, then try to grab any standard serial port
432 address, and finally try to get any free port. */
433 i = first_tuple(handle, tuple, parse);
434 while (i != CS_NO_MORE_ITEMS) {
435 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
436 ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
437 link->conf.ConfigIndex = cf->index;
438 for (j = 0; j < 5; j++) {
439 link->io.BasePort1 = base[j];
440 link->io.IOAddrLines = base[j] ? 16 : 3;
441 i = pcmcia_request_io(link->handle, &link->io);
442 if (i == CS_SUCCESS)
443 goto found_port;
444 }
445 }
446 i = next_tuple(handle, tuple, parse);
447 }
448
449 found_port:
450 if (i != CS_SUCCESS) {
451 printk(KERN_NOTICE
452 "serial_cs: no usable port range found, giving up\n");
453 cs_error(link->handle, RequestIO, i);
454 kfree(cfg_mem);
455 return -1;
456 }
457
458 i = pcmcia_request_irq(link->handle, &link->irq);
459 if (i != CS_SUCCESS) {
460 cs_error(link->handle, RequestIRQ, i);
461 link->irq.AssignedIRQ = 0;
462 }
463 if (info->multi && (info->manfid == MANFID_3COM))
464 link->conf.ConfigIndex &= ~(0x08);
465 i = pcmcia_request_configuration(link->handle, &link->conf);
466 if (i != CS_SUCCESS) {
467 cs_error(link->handle, RequestConfiguration, i);
468 kfree(cfg_mem);
469 return -1;
470 }
471 kfree(cfg_mem);
472 return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
473 }
474
475 static int multi_config(dev_link_t * link)
476 {
477 client_handle_t handle = link->handle;
478 struct serial_info *info = link->priv;
479 struct serial_cfg_mem *cfg_mem;
480 tuple_t *tuple;
481 u_char *buf;
482 cisparse_t *parse;
483 cistpl_cftable_entry_t *cf;
484 config_info_t config;
485 int i, rc, base2 = 0;
486
487 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
488 if (!cfg_mem)
489 return -1;
490 tuple = &cfg_mem->tuple;
491 parse = &cfg_mem->parse;
492 cf = &parse->cftable_entry;
493 buf = cfg_mem->buf;
494
495 i = pcmcia_get_configuration_info(handle, &config);
496 if (i != CS_SUCCESS) {
497 cs_error(handle, GetConfigurationInfo, i);
498 rc = -1;
499 goto free_cfg_mem;
500 }
501 link->conf.Vcc = config.Vcc;
502
503 tuple->TupleData = (cisdata_t *) buf;
504 tuple->TupleOffset = 0;
505 tuple->TupleDataMax = 255;
506 tuple->Attributes = 0;
507 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
508
509 /* First, look for a generic full-sized window */
510 link->io.NumPorts1 = info->multi * 8;
511 i = first_tuple(handle, tuple, parse);
512 while (i != CS_NO_MORE_ITEMS) {
513 /* The quad port cards have bad CIS's, so just look for a
514 window larger than 8 ports and assume it will be right */
515 if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&
516 (cf->io.win[0].len > 8)) {
517 link->conf.ConfigIndex = cf->index;
518 link->io.BasePort1 = cf->io.win[0].base;
519 link->io.IOAddrLines =
520 cf->io.flags & CISTPL_IO_LINES_MASK;
521 i = pcmcia_request_io(link->handle, &link->io);
522 base2 = link->io.BasePort1 + 8;
523 if (i == CS_SUCCESS)
524 break;
525 }
526 i = next_tuple(handle, tuple, parse);
527 }
528
529 /* If that didn't work, look for two windows */
530 if (i != CS_SUCCESS) {
531 link->io.NumPorts1 = link->io.NumPorts2 = 8;
532 info->multi = 2;
533 i = first_tuple(handle, tuple, parse);
534 while (i != CS_NO_MORE_ITEMS) {
535 if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
536 link->conf.ConfigIndex = cf->index;
537 link->io.BasePort1 = cf->io.win[0].base;
538 link->io.BasePort2 = cf->io.win[1].base;
539 link->io.IOAddrLines =
540 cf->io.flags & CISTPL_IO_LINES_MASK;
541 i = pcmcia_request_io(link->handle, &link->io);
542 base2 = link->io.BasePort2;
543 if (i == CS_SUCCESS)
544 break;
545 }
546 i = next_tuple(handle, tuple, parse);
547 }
548 }
549
550 if (i != CS_SUCCESS) {
551 cs_error(link->handle, RequestIO, i);
552 rc = -1;
553 goto free_cfg_mem;
554 }
555
556 i = pcmcia_request_irq(link->handle, &link->irq);
557 if (i != CS_SUCCESS) {
558 printk(KERN_NOTICE
559 "serial_cs: no usable port range found, giving up\n");
560 cs_error(link->handle, RequestIRQ, i);
561 link->irq.AssignedIRQ = 0;
562 }
563 /* Socket Dual IO: this enables irq's for second port */
564 if (info->multi && (info->manfid == MANFID_SOCKET)) {
565 link->conf.Present |= PRESENT_EXT_STATUS;
566 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
567 }
568 i = pcmcia_request_configuration(link->handle, &link->conf);
569 if (i != CS_SUCCESS) {
570 cs_error(link->handle, RequestConfiguration, i);
571 rc = -1;
572 goto free_cfg_mem;
573 }
574
575 /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
576 8 registers are for the UART, the others are extra registers */
577 if (info->manfid == MANFID_OXSEMI) {
578 if (cf->index == 1 || cf->index == 3) {
579 setup_serial(handle, info, base2, link->irq.AssignedIRQ);
580 outb(12, link->io.BasePort1 + 1);
581 } else {
582 setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
583 outb(12, base2 + 1);
584 }
585 rc = 0;
586 goto free_cfg_mem;
587 }
588
589 setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ);
590 /* The Nokia cards are not really multiport cards */
591 if (info->manfid == MANFID_NOKIA) {
592 rc = 0;
593 goto free_cfg_mem;
594 }
595 for (i = 0; i < info->multi - 1; i++)
596 setup_serial(handle, info, base2 + (8 * i),
597 link->irq.AssignedIRQ);
598 rc = 0;
599 free_cfg_mem:
600 kfree(cfg_mem);
601 return rc;
602 }
603
604 /*======================================================================
605
606 serial_config() is scheduled to run after a CARD_INSERTION event
607 is received, to configure the PCMCIA socket, and to make the
608 serial device available to the system.
609
610 ======================================================================*/
611
612 void serial_config(dev_link_t * link)
613 {
614 client_handle_t handle = link->handle;
615 struct serial_info *info = link->priv;
616 struct serial_cfg_mem *cfg_mem;
617 tuple_t *tuple;
618 u_char *buf;
619 cisparse_t *parse;
620 cistpl_cftable_entry_t *cf;
621 int i, last_ret, last_fn;
622
623 DEBUG(0, "serial_config(0x%p)\n", link);
624
625 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
626 if (!cfg_mem)
627 goto failed;
628
629 tuple = &cfg_mem->tuple;
630 parse = &cfg_mem->parse;
631 cf = &parse->cftable_entry;
632 buf = cfg_mem->buf;
633
634 tuple->TupleData = (cisdata_t *) buf;
635 tuple->TupleOffset = 0;
636 tuple->TupleDataMax = 255;
637 tuple->Attributes = 0;
638 /* Get configuration register information */
639 tuple->DesiredTuple = CISTPL_CONFIG;
640 last_ret = first_tuple(handle, tuple, parse);
641 if (last_ret != CS_SUCCESS) {
642 last_fn = ParseTuple;
643 goto cs_failed;
644 }
645 link->conf.ConfigBase = parse->config.base;
646 link->conf.Present = parse->config.rmask[0];
647
648 /* Configure card */
649 link->state |= DEV_CONFIG;
650
651 /* Is this a compliant multifunction card? */
652 tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
653 tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
654 info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS);
655
656 /* Is this a multiport card? */
657 tuple->DesiredTuple = CISTPL_MANFID;
658 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
659 info->manfid = parse->manfid.manf;
660 for (i = 0; i < MULTI_COUNT; i++)
661 if ((info->manfid == multi_id[i].manfid) &&
662 (parse->manfid.card == multi_id[i].prodid))
663 break;
664 if (i < MULTI_COUNT)
665 info->multi = multi_id[i].multi;
666 }
667
668 /* Another check for dual-serial cards: look for either serial or
669 multifunction cards that ask for appropriate IO port ranges */
670 tuple->DesiredTuple = CISTPL_FUNCID;
671 if ((info->multi == 0) &&
672 ((first_tuple(handle, tuple, parse) != CS_SUCCESS) ||
673 (parse->funcid.func == CISTPL_FUNCID_MULTI) ||
674 (parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
675 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
676 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) {
677 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
678 info->multi = cf->io.win[0].len >> 3;
679 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
680 (cf->io.win[1].len == 8))
681 info->multi = 2;
682 }
683 }
684
685 if (info->multi > 1)
686 multi_config(link);
687 else
688 simple_config(link);
689
690 if (info->ndev == 0)
691 goto failed;
692
693 if (info->manfid == MANFID_IBM) {
694 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
695 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
696 if (last_ret) {
697 last_fn = AccessConfigurationRegister;
698 goto cs_failed;
699 }
700 reg.Action = CS_WRITE;
701 reg.Value = reg.Value | 1;
702 last_ret = pcmcia_access_configuration_register(link->handle, &reg);
703 if (last_ret) {
704 last_fn = AccessConfigurationRegister;
705 goto cs_failed;
706 }
707 }
708
709 link->dev = &info->node[0];
710 link->state &= ~DEV_CONFIG_PENDING;
711 kfree(cfg_mem);
712 return;
713
714 cs_failed:
715 cs_error(link->handle, last_fn, last_ret);
716 failed:
717 serial_remove(link);
718 link->state &= ~DEV_CONFIG_PENDING;
719 kfree(cfg_mem);
720 }
721
722 /*======================================================================
723
724 The card status event handler. Mostly, this schedules other
725 stuff to run after an event is received. A CARD_REMOVAL event
726 also sets some flags to discourage the serial drivers from
727 talking to the ports.
728
729 ======================================================================*/
730
731 static int
732 serial_event(event_t event, int priority, event_callback_args_t * args)
733 {
734 dev_link_t *link = args->client_data;
735 struct serial_info *info = link->priv;
736
737 DEBUG(1, "serial_event(0x%06x)\n", event);
738
739 switch (event) {
740 case CS_EVENT_CARD_REMOVAL:
741 serial_remove(link);
742 break;
743
744 case CS_EVENT_CARD_INSERTION:
745 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
746 serial_config(link);
747 break;
748
749 case CS_EVENT_PM_SUSPEND:
750 serial_suspend(link);
751 break;
752
753 case CS_EVENT_RESET_PHYSICAL:
754 if ((link->state & DEV_CONFIG) && !info->slave)
755 pcmcia_release_configuration(link->handle);
756 break;
757
758 case CS_EVENT_PM_RESUME:
759 serial_resume(link);
760 break;
761
762 case CS_EVENT_CARD_RESET:
763 if (DEV_OK(link) && !info->slave)
764 pcmcia_request_configuration(link->handle, &link->conf);
765 break;
766 }
767 return 0;
768 }
769
770 static struct pcmcia_device_id serial_ids[] = {
771 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
772 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
773 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
774 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
775 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
776 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
777 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
778 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
779 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
780 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
781 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
782 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
783 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
784 PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
785 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
786 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
787 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
788 PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
789 PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
790 PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
791 PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
792 PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
793 PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
794 PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet ", 0x578ba6e7, 0x02d92d1e),
795 PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
796 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
797 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
798 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
799 PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
800 PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
801 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f),
802 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard", 0x0c2f80cd, 0x0573c29f),
803 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
804 PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
805 PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
806 PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet", 0x2e3ee845, 0xc0e778c2),
807 PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
808 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
809 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
810 PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
811 PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
812 PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c),
813 PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
814 PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
815 PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
816 PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
817 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
818 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
819 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
820 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
821 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
822 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
823 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
824 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
825 PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
826 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
827 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
828 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
829 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
830 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
831 PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
832 PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
833 PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
834 PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
835 PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
836 PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
837 PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
838 PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
839 PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
840 PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
841 PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
842 PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
843 PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
844 PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400", 0x816cc815, 0x23539b80),
845 PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
846 PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
847 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
848 PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
849 PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
850 PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
851 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
852 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
853 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
854 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
855 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "PCMLM28.cis"),
856 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
857 PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
858 PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
859 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
860 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
861 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
862 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
863 PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "MT5634ZLX.cis"),
864 PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "COMpad4.cis"),
865 PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "COMpad2.cis"),
866 PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "RS-COM-2P.cis"),
867 /* too generic */
868 /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
869 /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
870 PCMCIA_DEVICE_FUNC_ID(2),
871 PCMCIA_DEVICE_NULL,
872 };
873 MODULE_DEVICE_TABLE(pcmcia, serial_ids);
874
875 static struct pcmcia_driver serial_cs_driver = {
876 .owner = THIS_MODULE,
877 .drv = {
878 .name = "serial_cs",
879 },
880 .attach = serial_attach,
881 .event = serial_event,
882 .detach = serial_detach,
883 .id_table = serial_ids,
884 };
885
886 static int __init init_serial_cs(void)
887 {
888 return pcmcia_register_driver(&serial_cs_driver);
889 }
890
891 static void __exit exit_serial_cs(void)
892 {
893 pcmcia_unregister_driver(&serial_cs_driver);
894 BUG_ON(dev_list != NULL);
895 }
896
897 module_init(init_serial_cs);
898 module_exit(exit_serial_cs);
899
900 MODULE_LICENSE("GPL");
This page took 0.069018 seconds and 5 git commands to generate.