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