1 | // SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) |
2 | /*====================================================================== |
3 | |
4 | A driver for PCMCIA serial devices |
5 | |
6 | serial_cs.c 1.134 2002/05/04 05:48:53 |
7 | |
8 | The contents of this file are subject to the Mozilla Public |
9 | License Version 1.1 (the "License"); you may not use this file |
10 | except in compliance with the License. You may obtain a copy of |
11 | the License at http://www.mozilla.org/MPL/ |
12 | |
13 | Software distributed under the License is distributed on an "AS |
14 | IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
15 | implied. See the License for the specific language governing |
16 | rights and limitations under the License. |
17 | |
18 | The initial developer of the original code is David A. Hinds |
19 | <dahinds@users.sourceforge.net>. Portions created by David A. Hinds |
20 | are Copyright (C) 1999 David A. Hinds. All Rights Reserved. |
21 | |
22 | Alternatively, the contents of this file may be used under the |
23 | terms of the GNU General Public License version 2 (the "GPL"), in which |
24 | case the provisions of the GPL are applicable instead of the |
25 | above. If you wish to allow the use of your version of this file |
26 | only under the terms of the GPL and not to allow others to use |
27 | your version of this file under the MPL, indicate your decision |
28 | by deleting the provisions above and replace them with the notice |
29 | and other provisions required by the GPL. If you do not delete |
30 | the provisions above, a recipient may use your version of this |
31 | file under either the MPL or the GPL. |
32 | |
33 | ======================================================================*/ |
34 | |
35 | #include <linux/module.h> |
36 | #include <linux/moduleparam.h> |
37 | #include <linux/kernel.h> |
38 | #include <linux/ptrace.h> |
39 | #include <linux/slab.h> |
40 | #include <linux/string.h> |
41 | #include <linux/timer.h> |
42 | #include <linux/serial_core.h> |
43 | #include <linux/delay.h> |
44 | #include <linux/major.h> |
45 | #include <asm/io.h> |
46 | |
47 | #include <pcmcia/cistpl.h> |
48 | #include <pcmcia/ciscode.h> |
49 | #include <pcmcia/ds.h> |
50 | #include <pcmcia/cisreg.h> |
51 | |
52 | #include "8250.h" |
53 | |
54 | |
55 | /*====================================================================*/ |
56 | |
57 | /* Parameters that can be set with 'insmod' */ |
58 | |
59 | /* Enable the speaker? */ |
60 | static int do_sound = 1; |
61 | /* Skip strict UART tests? */ |
62 | static int buggy_uart; |
63 | |
64 | module_param(do_sound, int, 0444); |
65 | module_param(buggy_uart, int, 0444); |
66 | |
67 | /*====================================================================*/ |
68 | |
69 | /* Table of multi-port card ID's */ |
70 | |
71 | struct serial_quirk { |
72 | unsigned int manfid; |
73 | unsigned int prodid; |
74 | int multi; /* 1 = multifunction, > 1 = # ports */ |
75 | void (*config)(struct pcmcia_device *); |
76 | void (*setup)(struct pcmcia_device *, struct uart_8250_port *); |
77 | void (*wakeup)(struct pcmcia_device *); |
78 | int (*post)(struct pcmcia_device *); |
79 | }; |
80 | |
81 | struct serial_info { |
82 | struct pcmcia_device *p_dev; |
83 | int ndev; |
84 | int multi; |
85 | int slave; |
86 | int manfid; |
87 | int prodid; |
88 | int c950ctrl; |
89 | int line[4]; |
90 | const struct serial_quirk *quirk; |
91 | }; |
92 | |
93 | /* |
94 | * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6" |
95 | * manfid 0x0160, 0x0104 |
96 | * This card appears to have a 14.7456MHz clock. |
97 | */ |
98 | /* Generic Modem: MD55x (GPRS/EDGE) have |
99 | * Elan VPU16551 UART with 14.7456MHz oscillator |
100 | * manfid 0x015D, 0x4C45 |
101 | */ |
102 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart) |
103 | { |
104 | uart->port.uartclk = 14745600; |
105 | } |
106 | |
107 | static int quirk_post_ibm(struct pcmcia_device *link) |
108 | { |
109 | u8 val; |
110 | int ret; |
111 | |
112 | ret = pcmcia_read_config_byte(p_dev: link, where: 0x800, val: &val); |
113 | if (ret) |
114 | goto failed; |
115 | |
116 | ret = pcmcia_write_config_byte(p_dev: link, where: 0x800, val: val | 1); |
117 | if (ret) |
118 | goto failed; |
119 | return 0; |
120 | |
121 | failed: |
122 | return -ENODEV; |
123 | } |
124 | |
125 | /* |
126 | * Nokia cards are not really multiport cards. Shouldn't this |
127 | * be handled by setting the quirk entry .multi = 0 | 1 ? |
128 | */ |
129 | static void quirk_config_nokia(struct pcmcia_device *link) |
130 | { |
131 | struct serial_info *info = link->priv; |
132 | |
133 | if (info->multi > 1) |
134 | info->multi = 1; |
135 | } |
136 | |
137 | static void quirk_wakeup_oxsemi(struct pcmcia_device *link) |
138 | { |
139 | struct serial_info *info = link->priv; |
140 | |
141 | if (info->c950ctrl) |
142 | outb(value: 12, port: info->c950ctrl + 1); |
143 | } |
144 | |
145 | /* request_region? oxsemi branch does no request_region too... */ |
146 | /* |
147 | * This sequence is needed to properly initialize MC45 attached to OXCF950. |
148 | * I tried decreasing these msleep()s, but it worked properly (survived |
149 | * 1000 stop/start operations) with these timeouts (or bigger). |
150 | */ |
151 | static void quirk_wakeup_possio_gcc(struct pcmcia_device *link) |
152 | { |
153 | struct serial_info *info = link->priv; |
154 | unsigned int ctrl = info->c950ctrl; |
155 | |
156 | outb(value: 0xA, port: ctrl + 1); |
157 | msleep(msecs: 100); |
158 | outb(value: 0xE, port: ctrl + 1); |
159 | msleep(msecs: 300); |
160 | outb(value: 0xC, port: ctrl + 1); |
161 | msleep(msecs: 100); |
162 | outb(value: 0xE, port: ctrl + 1); |
163 | msleep(msecs: 200); |
164 | outb(value: 0xF, port: ctrl + 1); |
165 | msleep(msecs: 100); |
166 | outb(value: 0xE, port: ctrl + 1); |
167 | msleep(msecs: 100); |
168 | outb(value: 0xC, port: ctrl + 1); |
169 | } |
170 | |
171 | /* |
172 | * Socket Dual IO: this enables irq's for second port |
173 | */ |
174 | static void quirk_config_socket(struct pcmcia_device *link) |
175 | { |
176 | struct serial_info *info = link->priv; |
177 | |
178 | if (info->multi) |
179 | link->config_flags |= CONF_ENABLE_ESR; |
180 | } |
181 | |
182 | static const struct serial_quirk quirks[] = { |
183 | { |
184 | .manfid = 0x0160, |
185 | .prodid = 0x0104, |
186 | .multi = -1, |
187 | .setup = quirk_setup_brainboxes_0104, |
188 | }, { |
189 | .manfid = 0x015D, |
190 | .prodid = 0x4C45, |
191 | .multi = -1, |
192 | .setup = quirk_setup_brainboxes_0104, |
193 | }, { |
194 | .manfid = MANFID_IBM, |
195 | .prodid = ~0, |
196 | .multi = -1, |
197 | .post = quirk_post_ibm, |
198 | }, { |
199 | .manfid = MANFID_INTEL, |
200 | .prodid = PRODID_INTEL_DUAL_RS232, |
201 | .multi = 2, |
202 | }, { |
203 | .manfid = MANFID_NATINST, |
204 | .prodid = PRODID_NATINST_QUAD_RS232, |
205 | .multi = 4, |
206 | }, { |
207 | .manfid = MANFID_NOKIA, |
208 | .prodid = ~0, |
209 | .multi = -1, |
210 | .config = quirk_config_nokia, |
211 | }, { |
212 | .manfid = MANFID_OMEGA, |
213 | .prodid = PRODID_OMEGA_QSP_100, |
214 | .multi = 4, |
215 | }, { |
216 | .manfid = MANFID_OXSEMI, |
217 | .prodid = ~0, |
218 | .multi = -1, |
219 | .wakeup = quirk_wakeup_oxsemi, |
220 | }, { |
221 | .manfid = MANFID_POSSIO, |
222 | .prodid = PRODID_POSSIO_GCC, |
223 | .multi = -1, |
224 | .wakeup = quirk_wakeup_possio_gcc, |
225 | }, { |
226 | .manfid = MANFID_QUATECH, |
227 | .prodid = PRODID_QUATECH_DUAL_RS232, |
228 | .multi = 2, |
229 | }, { |
230 | .manfid = MANFID_QUATECH, |
231 | .prodid = PRODID_QUATECH_DUAL_RS232_D1, |
232 | .multi = 2, |
233 | }, { |
234 | .manfid = MANFID_QUATECH, |
235 | .prodid = PRODID_QUATECH_DUAL_RS232_G, |
236 | .multi = 2, |
237 | }, { |
238 | .manfid = MANFID_QUATECH, |
239 | .prodid = PRODID_QUATECH_QUAD_RS232, |
240 | .multi = 4, |
241 | }, { |
242 | .manfid = MANFID_SOCKET, |
243 | .prodid = PRODID_SOCKET_DUAL_RS232, |
244 | .multi = 2, |
245 | .config = quirk_config_socket, |
246 | }, { |
247 | .manfid = MANFID_SOCKET, |
248 | .prodid = ~0, |
249 | .multi = -1, |
250 | .config = quirk_config_socket, |
251 | } |
252 | }; |
253 | |
254 | |
255 | static int serial_config(struct pcmcia_device *link); |
256 | |
257 | |
258 | static void serial_remove(struct pcmcia_device *link) |
259 | { |
260 | struct serial_info *info = link->priv; |
261 | int i; |
262 | |
263 | dev_dbg(&link->dev, "serial_release\n" ); |
264 | |
265 | /* |
266 | * Recheck to see if the device is still configured. |
267 | */ |
268 | for (i = 0; i < info->ndev; i++) |
269 | serial8250_unregister_port(line: info->line[i]); |
270 | |
271 | if (!info->slave) |
272 | pcmcia_disable_device(p_dev: link); |
273 | } |
274 | |
275 | static int serial_suspend(struct pcmcia_device *link) |
276 | { |
277 | struct serial_info *info = link->priv; |
278 | int i; |
279 | |
280 | for (i = 0; i < info->ndev; i++) |
281 | serial8250_suspend_port(line: info->line[i]); |
282 | |
283 | return 0; |
284 | } |
285 | |
286 | static int serial_resume(struct pcmcia_device *link) |
287 | { |
288 | struct serial_info *info = link->priv; |
289 | int i; |
290 | |
291 | for (i = 0; i < info->ndev; i++) |
292 | serial8250_resume_port(line: info->line[i]); |
293 | |
294 | if (info->quirk && info->quirk->wakeup) |
295 | info->quirk->wakeup(link); |
296 | |
297 | return 0; |
298 | } |
299 | |
300 | static int serial_probe(struct pcmcia_device *link) |
301 | { |
302 | struct serial_info *info; |
303 | int ret; |
304 | |
305 | dev_dbg(&link->dev, "serial_attach()\n" ); |
306 | |
307 | /* Create new serial device */ |
308 | info = kzalloc(size: sizeof(*info), GFP_KERNEL); |
309 | if (!info) |
310 | return -ENOMEM; |
311 | info->p_dev = link; |
312 | link->priv = info; |
313 | |
314 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
315 | if (do_sound) |
316 | link->config_flags |= CONF_ENABLE_SPKR; |
317 | |
318 | ret = serial_config(link); |
319 | if (ret) |
320 | goto free_info; |
321 | |
322 | return 0; |
323 | |
324 | free_info: |
325 | kfree(objp: info); |
326 | return ret; |
327 | } |
328 | |
329 | static void serial_detach(struct pcmcia_device *link) |
330 | { |
331 | struct serial_info *info = link->priv; |
332 | |
333 | dev_dbg(&link->dev, "serial_detach\n" ); |
334 | |
335 | /* |
336 | * Ensure that the ports have been released. |
337 | */ |
338 | serial_remove(link); |
339 | |
340 | /* free bits */ |
341 | kfree(objp: info); |
342 | } |
343 | |
344 | /*====================================================================*/ |
345 | |
346 | static int setup_serial(struct pcmcia_device *handle, struct serial_info *info, |
347 | unsigned int iobase, int irq) |
348 | { |
349 | struct uart_8250_port uart; |
350 | int line; |
351 | |
352 | memset(&uart, 0, sizeof(uart)); |
353 | uart.port.iobase = iobase; |
354 | uart.port.irq = irq; |
355 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; |
356 | uart.port.uartclk = 1843200; |
357 | uart.port.dev = &handle->dev; |
358 | if (buggy_uart) |
359 | uart.port.flags |= UPF_BUGGY_UART; |
360 | |
361 | if (info->quirk && info->quirk->setup) |
362 | info->quirk->setup(handle, &uart); |
363 | |
364 | line = serial8250_register_8250_port(&uart); |
365 | if (line < 0) { |
366 | pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n" , |
367 | (unsigned long)iobase, irq); |
368 | return -EINVAL; |
369 | } |
370 | |
371 | info->line[info->ndev] = line; |
372 | info->ndev++; |
373 | |
374 | return 0; |
375 | } |
376 | |
377 | /*====================================================================*/ |
378 | |
379 | static int pfc_config(struct pcmcia_device *p_dev) |
380 | { |
381 | unsigned int port = 0; |
382 | struct serial_info *info = p_dev->priv; |
383 | |
384 | if ((p_dev->resource[1]->end != 0) && |
385 | (resource_size(res: p_dev->resource[1]) == 8)) { |
386 | port = p_dev->resource[1]->start; |
387 | info->slave = 1; |
388 | } else if ((info->manfid == MANFID_OSITECH) && |
389 | (resource_size(res: p_dev->resource[0]) == 0x40)) { |
390 | port = p_dev->resource[0]->start + 0x28; |
391 | info->slave = 1; |
392 | } |
393 | if (info->slave) |
394 | return setup_serial(handle: p_dev, info, iobase: port, irq: p_dev->irq); |
395 | |
396 | dev_warn(&p_dev->dev, "no usable port range found, giving up\n" ); |
397 | return -ENODEV; |
398 | } |
399 | |
400 | static int simple_config_check(struct pcmcia_device *p_dev, void *priv_data) |
401 | { |
402 | static const int size_table[2] = { 8, 16 }; |
403 | int *try = priv_data; |
404 | |
405 | if (p_dev->resource[0]->start == 0) |
406 | return -ENODEV; |
407 | |
408 | if ((*try & 0x1) == 0) |
409 | p_dev->io_lines = 16; |
410 | |
411 | if (p_dev->resource[0]->end != size_table[(*try >> 1)]) |
412 | return -ENODEV; |
413 | |
414 | p_dev->resource[0]->end = 8; |
415 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
416 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
417 | |
418 | return pcmcia_request_io(p_dev); |
419 | } |
420 | |
421 | static int simple_config_check_notpicky(struct pcmcia_device *p_dev, |
422 | void *priv_data) |
423 | { |
424 | static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; |
425 | int j; |
426 | |
427 | if (p_dev->io_lines > 3) |
428 | return -ENODEV; |
429 | |
430 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
431 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
432 | p_dev->resource[0]->end = 8; |
433 | |
434 | for (j = 0; j < 5; j++) { |
435 | p_dev->resource[0]->start = base[j]; |
436 | p_dev->io_lines = base[j] ? 16 : 3; |
437 | if (!pcmcia_request_io(p_dev)) |
438 | return 0; |
439 | } |
440 | return -ENODEV; |
441 | } |
442 | |
443 | static int simple_config(struct pcmcia_device *link) |
444 | { |
445 | struct serial_info *info = link->priv; |
446 | int ret, try; |
447 | |
448 | /* |
449 | * First pass: look for a config entry that looks normal. |
450 | * Two tries: without IO aliases, then with aliases. |
451 | */ |
452 | link->config_flags |= CONF_AUTO_SET_VPP; |
453 | for (try = 0; try < 4; try++) |
454 | if (!pcmcia_loop_config(p_dev: link, conf_check: simple_config_check, priv_data: &try)) |
455 | goto found_port; |
456 | |
457 | /* |
458 | * Second pass: try to find an entry that isn't picky about |
459 | * its base address, then try to grab any standard serial port |
460 | * address, and finally try to get any free port. |
461 | */ |
462 | ret = pcmcia_loop_config(p_dev: link, conf_check: simple_config_check_notpicky, NULL); |
463 | if (ret) { |
464 | dev_warn(&link->dev, "no usable port range found, giving up\n" ); |
465 | return ret; |
466 | } |
467 | |
468 | found_port: |
469 | if (info->multi && (info->manfid == MANFID_3COM)) |
470 | link->config_index &= ~(0x08); |
471 | |
472 | /* |
473 | * Apply any configuration quirks. |
474 | */ |
475 | if (info->quirk && info->quirk->config) |
476 | info->quirk->config(link); |
477 | |
478 | ret = pcmcia_enable_device(p_dev: link); |
479 | if (ret != 0) |
480 | return ret; |
481 | return setup_serial(handle: link, info, iobase: link->resource[0]->start, irq: link->irq); |
482 | } |
483 | |
484 | static int multi_config_check(struct pcmcia_device *p_dev, void *priv_data) |
485 | { |
486 | int *multi = priv_data; |
487 | |
488 | if (p_dev->resource[1]->end) |
489 | return -EINVAL; |
490 | |
491 | /* |
492 | * The quad port cards have bad CIS's, so just look for a |
493 | * window larger than 8 ports and assume it will be right. |
494 | */ |
495 | if (p_dev->resource[0]->end <= 8) |
496 | return -EINVAL; |
497 | |
498 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
499 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
500 | p_dev->resource[0]->end = *multi * 8; |
501 | |
502 | if (pcmcia_request_io(p_dev)) |
503 | return -ENODEV; |
504 | return 0; |
505 | } |
506 | |
507 | static int multi_config_check_notpicky(struct pcmcia_device *p_dev, |
508 | void *priv_data) |
509 | { |
510 | int *base2 = priv_data; |
511 | |
512 | if (!p_dev->resource[0]->end || !p_dev->resource[1]->end || |
513 | p_dev->resource[0]->start + 8 != p_dev->resource[1]->start) |
514 | return -ENODEV; |
515 | |
516 | p_dev->resource[0]->end = p_dev->resource[1]->end = 8; |
517 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
518 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; |
519 | |
520 | if (pcmcia_request_io(p_dev)) |
521 | return -ENODEV; |
522 | |
523 | *base2 = p_dev->resource[0]->start + 8; |
524 | return 0; |
525 | } |
526 | |
527 | static int multi_config(struct pcmcia_device *link) |
528 | { |
529 | struct serial_info *info = link->priv; |
530 | int i, base2 = 0; |
531 | |
532 | /* First, look for a generic full-sized window */ |
533 | if (!pcmcia_loop_config(p_dev: link, conf_check: multi_config_check, priv_data: &info->multi)) |
534 | base2 = link->resource[0]->start + 8; |
535 | else { |
536 | /* If that didn't work, look for two windows */ |
537 | info->multi = 2; |
538 | if (pcmcia_loop_config(p_dev: link, conf_check: multi_config_check_notpicky, |
539 | priv_data: &base2)) { |
540 | dev_warn(&link->dev, |
541 | "no usable port range found, giving up\n" ); |
542 | return -ENODEV; |
543 | } |
544 | } |
545 | |
546 | if (!link->irq) |
547 | dev_warn(&link->dev, "no usable IRQ found, continuing...\n" ); |
548 | |
549 | /* |
550 | * Apply any configuration quirks. |
551 | */ |
552 | if (info->quirk && info->quirk->config) |
553 | info->quirk->config(link); |
554 | |
555 | i = pcmcia_enable_device(p_dev: link); |
556 | if (i != 0) |
557 | return -ENODEV; |
558 | |
559 | /* The Oxford Semiconductor OXCF950 cards are in fact single-port: |
560 | * 8 registers are for the UART, the others are extra registers. |
561 | * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. |
562 | */ |
563 | if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && |
564 | info->prodid == PRODID_POSSIO_GCC)) { |
565 | if (link->config_index == 1 || |
566 | link->config_index == 3) { |
567 | setup_serial(handle: link, info, iobase: base2, irq: link->irq); |
568 | base2 = link->resource[0]->start; |
569 | } else { |
570 | setup_serial(handle: link, info, iobase: link->resource[0]->start, |
571 | irq: link->irq); |
572 | } |
573 | info->c950ctrl = base2; |
574 | |
575 | /* |
576 | * FIXME: We really should wake up the port prior to |
577 | * handing it over to the serial layer. |
578 | */ |
579 | if (info->quirk && info->quirk->wakeup) |
580 | info->quirk->wakeup(link); |
581 | |
582 | return 0; |
583 | } |
584 | |
585 | setup_serial(handle: link, info, iobase: link->resource[0]->start, irq: link->irq); |
586 | for (i = 0; i < info->multi - 1; i++) |
587 | setup_serial(handle: link, info, iobase: base2 + (8 * i), |
588 | irq: link->irq); |
589 | return 0; |
590 | } |
591 | |
592 | static int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data) |
593 | { |
594 | struct serial_info *info = p_dev->priv; |
595 | |
596 | if (!p_dev->resource[0]->end) |
597 | return -EINVAL; |
598 | |
599 | if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0)) |
600 | info->multi = p_dev->resource[0]->end >> 3; |
601 | |
602 | if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8) |
603 | && (p_dev->resource[1]->end == 8)) |
604 | info->multi = 2; |
605 | |
606 | return 0; /* break */ |
607 | } |
608 | |
609 | |
610 | static int serial_config(struct pcmcia_device *link) |
611 | { |
612 | struct serial_info *info = link->priv; |
613 | int i; |
614 | |
615 | dev_dbg(&link->dev, "serial_config\n" ); |
616 | |
617 | /* Is this a compliant multifunction card? */ |
618 | info->multi = (link->socket->functions > 1); |
619 | |
620 | /* Is this a multiport card? */ |
621 | info->manfid = link->manf_id; |
622 | info->prodid = link->card_id; |
623 | |
624 | for (i = 0; i < ARRAY_SIZE(quirks); i++) |
625 | if ((quirks[i].manfid == ~0 || |
626 | quirks[i].manfid == info->manfid) && |
627 | (quirks[i].prodid == ~0 || |
628 | quirks[i].prodid == info->prodid)) { |
629 | info->quirk = &quirks[i]; |
630 | break; |
631 | } |
632 | |
633 | /* |
634 | * Another check for dual-serial cards: look for either serial or |
635 | * multifunction cards that ask for appropriate IO port ranges. |
636 | */ |
637 | if ((info->multi == 0) && |
638 | (link->has_func_id) && |
639 | (link->socket->pcmcia_pfc == 0) && |
640 | ((link->func_id == CISTPL_FUNCID_MULTI) || |
641 | (link->func_id == CISTPL_FUNCID_SERIAL))) { |
642 | if (pcmcia_loop_config(p_dev: link, conf_check: serial_check_for_multi, priv_data: info)) |
643 | goto failed; |
644 | } |
645 | |
646 | /* |
647 | * Apply any multi-port quirk. |
648 | */ |
649 | if (info->quirk && info->quirk->multi != -1) |
650 | info->multi = info->quirk->multi; |
651 | |
652 | dev_info(&link->dev, |
653 | "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n" , |
654 | link->manf_id, link->card_id, |
655 | link->socket->pcmcia_pfc, info->multi, info->quirk); |
656 | if (link->socket->pcmcia_pfc) |
657 | i = pfc_config(p_dev: link); |
658 | else if (info->multi > 1) |
659 | i = multi_config(link); |
660 | else |
661 | i = simple_config(link); |
662 | |
663 | if (i || info->ndev == 0) |
664 | goto failed; |
665 | |
666 | /* |
667 | * Apply any post-init quirk. FIXME: This should really happen |
668 | * before we register the port, since it might already be in use. |
669 | */ |
670 | if (info->quirk && info->quirk->post) |
671 | if (info->quirk->post(link)) |
672 | goto failed; |
673 | |
674 | return 0; |
675 | |
676 | failed: |
677 | dev_warn(&link->dev, "failed to initialize\n" ); |
678 | serial_remove(link); |
679 | return -ENODEV; |
680 | } |
681 | |
682 | static const struct pcmcia_device_id serial_ids[] = { |
683 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), |
684 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), |
685 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), |
686 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), |
687 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), |
688 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), |
689 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), |
690 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), |
691 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a), |
692 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341), |
693 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab), |
694 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), |
695 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), |
696 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), |
697 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ" , "CC/XJEM3288" , "DATA/FAX/CELL ETHERNET MODEM" , 0xf510db04, 0x04cd2988, 0x46a52d63), |
698 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ" , "CC/XJEM3336" , "DATA/FAX/CELL ETHERNET MODEM" , 0xf510db04, 0x0143b773, 0x46a52d63), |
699 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ" , "EM1144T" , "PCMCIA MODEM" , 0xf510db04, 0x856d66c8, 0xbd6c43ef), |
700 | PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ" , "XJEM1144/CCEM1144" , "PCMCIA MODEM" , 0xf510db04, 0x52d21e1e, 0xbd6c43ef), |
701 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom" , "CEM28" , 0x2e3ee845, 0x0ea978ea), |
702 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom" , "CEM33" , 0x2e3ee845, 0x80609023), |
703 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom" , "CEM56" , 0x2e3ee845, 0xa650c32a), |
704 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom" , "REM10" , 0x2e3ee845, 0x76df1d29), |
705 | PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom" , "XEM5600" , 0x2e3ee845, 0xf1403719), |
706 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom" , "Fast Ethernet + 56K COMBO" , 0x578ba6e7, 0xb0ac62c4), |
707 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK" , "LM33-PCM-T" , 0xba9eb7e2, 0x077c174e), |
708 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link" , "DME336T" , 0x1a424a1c, 0xb23897ff), |
709 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000" , "XJEM3336" , 0xdd9989be, 0x662c394c), |
710 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell" , "GCS3000" , 0x2a151fac, 0x48b932ae), |
711 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys" , "EtherFast 10&100 + 56K PC Card (PCMLM56)" , 0x0733cc81, 0xb3765033), |
712 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS" , "PCMLM336" , 0xf7cb0b07, 0x7a821b58), |
713 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ" , "XJEM1144/CCEM1144" , 0xf510db04, 0x52d21e1e), |
714 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH" , "COMBO-L/M-336" , 0xb2ced065, 0x3ced0555), |
715 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC" , "PK-UG-J001" , 0x18df0ba0, 0x831b1064), |
716 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech" , "Trumpcard:Jack of Diamonds Modem+Ethernet" , 0xc2f80cd, 0x656947b9), |
717 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech" , "Trumpcard:Jack of Hearts Modem+Ethernet" , 0xc2f80cd, 0xdc9ba5ed), |
718 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs" , "ComboCard" , 0xdcfe12d3, 0xcd8906cc), |
719 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs" , "LanModem" , 0xdcfe12d3, 0xc67c648f), |
720 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK" , "GlobalNetworker 3410/3412" , 0x1eae9475, 0xd9a93bed), |
721 | PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom" , "CreditCard Ethernet+Modem II" , 0x2e3ee845, 0xeca401bf), |
722 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01), |
723 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), |
724 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05), |
725 | PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), |
726 | PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), |
727 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), |
728 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), |
729 | PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020), |
730 | PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA" , "MULTICARD" , "ETHERNET-MODEM" , 0x11c2da09, 0x7289dc5d, 0xaad95e1f), |
731 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM" , "Home and Away 28.8 PC Card " , 0xb569a6e5, 0x5bd4ff2c), |
732 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM" , "Home and Away Credit Card Adapter" , 0xb569a6e5, 0x4bdf15c3), |
733 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM" , "w95 Home and Away Credit Card " , 0xb569a6e5, 0xae911c15), |
734 | PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS" , 0xf03e4e77), |
735 | PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card " , 0x1ed59302), |
736 | PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), |
737 | PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), |
738 | PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), |
739 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), |
740 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */ |
741 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */ |
742 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */ |
743 | PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), |
744 | PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */ |
745 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), |
746 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), |
747 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), |
748 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), |
749 | PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), |
750 | PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */ |
751 | PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */ |
752 | PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */ |
753 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), |
754 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), |
755 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), |
756 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), |
757 | PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), |
758 | PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */ |
759 | PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */ |
760 | PCMCIA_DEVICE_PROD_ID134("ADV" , "TECH" , "COMpad-32/85" , 0x67459937, 0x916d02ba, 0x8fbe92ae), |
761 | PCMCIA_DEVICE_PROD_ID124("GATEWAY2000" , "CC3144" , "PCMCIA MODEM" , 0x506bccae, 0xcb3685f1, 0xbd6c43ef), |
762 | PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ" , "PCMCIA MODEM" , 0xf510db04, 0xbd6c43ef), |
763 | PCMCIA_DEVICE_PROD_ID124("TOSHIBA" , "T144PF" , "PCMCIA MODEM" , 0xb4585a1a, 0x7271409c, 0xbd6c43ef), |
764 | PCMCIA_DEVICE_PROD_ID123("FUJITSU" , "FC14F " , "MBH10213" , 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), |
765 | PCMCIA_DEVICE_PROD_ID123("Novatel Wireless" , "Merlin UMTS Modem" , "U630" , 0x32607776, 0xd9e73b13, 0xe87332e), |
766 | PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ" , "V.34 PCMCIA MODEM" , 0xf510db04, 0xbb2cce4a), |
767 | PCMCIA_DEVICE_PROD_ID12("Brain Boxes" , "Bluetooth PC Card" , 0xee138382, 0xd4ce9b02), |
768 | PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC" , "FAX MODEM" , 0xe625f451, 0xcecd6dfa), |
769 | PCMCIA_DEVICE_PROD_ID12("COMPAQ" , "PCMCIA 28800 FAX/DATA MODEM" , 0xa3a3062c, 0x8cbd7c76), |
770 | PCMCIA_DEVICE_PROD_ID12("COMPAQ" , "PCMCIA 33600 FAX/DATA MODEM" , 0xa3a3062c, 0x5a00ce95), |
771 | PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc." , "PCM-COM422" , 0xd0b78f51, 0x7e2d49ed), |
772 | PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus" , "FURY CARD 14K4" , 0x76942813, 0x8b96ce65), |
773 | PCMCIA_DEVICE_PROD_ID12("IBM" , "ISDN/56K/GSM" , 0xb569a6e5, 0xfee5297b), |
774 | PCMCIA_DEVICE_PROD_ID12("Intelligent" , "ANGIA FAX/MODEM" , 0xb496e65e, 0xf31602a6), |
775 | PCMCIA_DEVICE_PROD_ID12("Intel" , "MODEM 2400+" , 0x816cc815, 0x412729fb), |
776 | PCMCIA_DEVICE_PROD_ID12("Intertex" , "IX34-PCMCIA" , 0xf8a097e3, 0x97880447), |
777 | PCMCIA_DEVICE_PROD_ID12("IOTech Inc " , "PCMCIA Dual RS-232 Serial Port Card" , 0x3bd2d898, 0x92abc92f), |
778 | PCMCIA_DEVICE_PROD_ID12("MACRONIX" , "FAX/MODEM" , 0x668388b3, 0x3f9bdf2f), |
779 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech" , "MT1432LT" , 0x5f73be51, 0x0b3e2383), |
780 | PCMCIA_DEVICE_PROD_ID12("Multi-Tech" , "MT2834LT" , 0x5f73be51, 0x4cd7c09e), |
781 | PCMCIA_DEVICE_PROD_ID12("OEM " , "C288MX " , 0xb572d360, 0xd2385b7a), |
782 | PCMCIA_DEVICE_PROD_ID12("Option International" , "V34bis GSM/PSTN Data/Fax Modem" , 0x9d7cd6f5, 0x5cb8bf41), |
783 | PCMCIA_DEVICE_PROD_ID12("Option International" , "GSM-Ready 56K/ISDN" , 0x9d7cd6f5, 0xb23844aa), |
784 | PCMCIA_DEVICE_PROD_ID12("PCMCIA " , "C336MX " , 0x99bcafe9, 0xaa25bcab), |
785 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc" , "PCMCIA Dual RS-232 Serial Port Card" , 0xc4420b35, 0x92abc92f), |
786 | PCMCIA_DEVICE_PROD_ID12("Quatech Inc" , "Dual RS-232 Serial Port PC Card" , 0xc4420b35, 0x031a380d), |
787 | PCMCIA_DEVICE_PROD_ID12("Telia" , "SurfinBird 560P/A+" , 0xe2cdd5e, 0xc9314b38), |
788 | PCMCIA_DEVICE_PROD_ID1("Smart Serial Port" , 0x2d8ce292), |
789 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA" , "EN2218-LAN/MODEM" , 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis" ), |
790 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA" , "UE2218-LAN/MODEM" , 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis" ), |
791 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom" , "Gold Card V34 Ethernet" , 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis" ), |
792 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom" , "Gold Card V34 Ethernet GSM" , 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis" ), |
793 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS" , "PCMLM28" , 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis" ), |
794 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA" , "Modem/LAN Card" , 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis" ), |
795 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS" , "LAN AND MODEM MULTIFUNCTION" , 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis" ), |
796 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem" , 0x58fc6056, "cis/DP83903.cis" ), |
797 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis" ), |
798 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis" ), |
799 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis" ), |
800 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis" ), |
801 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless" , "AC850" , 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis" ), /* Sierra Wireless AC850 3G Network Adapter R1 */ |
802 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless" , "AC860" , 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis" ), /* Sierra Wireless AC860 3G Network Adapter R1 */ |
803 | PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless" , "AC710/AC750" , 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis" ), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ |
804 | PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis" ), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ |
805 | PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis" ), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ |
806 | PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech" , "PCMCIA 56K DataFax" , 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis" ), |
807 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH" , "COMpad-32/85B-2" , 0x96913a85, 0x27ab5437, "cis/COMpad2.cis" ), |
808 | PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH" , "COMpad-32/85B-4" , 0x96913a85, 0xcec8f102, "cis/COMpad4.cis" ), |
809 | PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH" , "COMpad-32/85" , "1.0" , 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis" ), |
810 | PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P" , 0xad20b156, "cis/RS-COM-2P.cis" ), |
811 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997." , "SERIAL CARD: SL100 1.00." , 0x19ca78af, 0xf964f42b), |
812 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997." , "SERIAL CARD: SL100" , 0x19ca78af, 0x71d98e83), |
813 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997." , "SERIAL CARD: SL232 1.00." , 0x19ca78af, 0x69fb7490), |
814 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997." , "SERIAL CARD: SL232" , 0x19ca78af, 0xb6bc0235), |
815 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000." , "SERIAL CARD: CF232" , 0x63f2e0bd, 0xb9e175d3), |
816 | PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000." , "SERIAL CARD: CF232-5" , 0x63f2e0bd, 0xfce33442), |
817 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: CF232" , 0x3beb8cf2, 0x171e7190), |
818 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: CF232-5" , 0x3beb8cf2, 0x20da4262), |
819 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: CF428" , 0x3beb8cf2, 0xea5dd57d), |
820 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: CF500" , 0x3beb8cf2, 0xd77255fa), |
821 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: IC232" , 0x3beb8cf2, 0x6a709903), |
822 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: SL232" , 0x3beb8cf2, 0x18430676), |
823 | PCMCIA_DEVICE_PROD_ID12("Elan" , "Serial Port: XL232" , 0x3beb8cf2, 0x6f933767), |
824 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan" , "Serial Port: CF332" , 0x3beb8cf2, 0x16dc1ba7), |
825 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan" , "Serial Port: SL332" , 0x3beb8cf2, 0x19816c41), |
826 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan" , "Serial Port: SL385" , 0x3beb8cf2, 0x64112029), |
827 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan" , "Serial Port: SL432" , 0x3beb8cf2, 0x1cce7ac4), |
828 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan" , "Serial+Parallel Port: SP230" , 0x3beb8cf2, 0xdb9e58bc), |
829 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan" , "Serial Port: CF332" , 0x3beb8cf2, 0x16dc1ba7), |
830 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan" , "Serial Port: SL332" , 0x3beb8cf2, 0x19816c41), |
831 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan" , "Serial Port: SL385" , 0x3beb8cf2, 0x64112029), |
832 | PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan" , "Serial Port: SL432" , 0x3beb8cf2, 0x1cce7ac4), |
833 | PCMCIA_MFC_DEVICE_PROD_ID12(2, "Elan" , "Serial Port: SL432" , 0x3beb8cf2, 0x1cce7ac4), |
834 | PCMCIA_MFC_DEVICE_PROD_ID12(3, "Elan" , "Serial Port: SL432" , 0x3beb8cf2, 0x1cce7ac4), |
835 | PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b), |
836 | /* too generic */ |
837 | /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ |
838 | /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ |
839 | PCMCIA_DEVICE_FUNC_ID(2), |
840 | PCMCIA_DEVICE_NULL, |
841 | }; |
842 | MODULE_DEVICE_TABLE(pcmcia, serial_ids); |
843 | |
844 | MODULE_FIRMWARE("cis/PCMLM28.cis" ); |
845 | MODULE_FIRMWARE("cis/DP83903.cis" ); |
846 | MODULE_FIRMWARE("cis/3CCFEM556.cis" ); |
847 | MODULE_FIRMWARE("cis/3CXEM556.cis" ); |
848 | MODULE_FIRMWARE("cis/SW_8xx_SER.cis" ); |
849 | MODULE_FIRMWARE("cis/SW_7xx_SER.cis" ); |
850 | MODULE_FIRMWARE("cis/SW_555_SER.cis" ); |
851 | MODULE_FIRMWARE("cis/MT5634ZLX.cis" ); |
852 | MODULE_FIRMWARE("cis/COMpad2.cis" ); |
853 | MODULE_FIRMWARE("cis/COMpad4.cis" ); |
854 | MODULE_FIRMWARE("cis/RS-COM-2P.cis" ); |
855 | |
856 | static struct pcmcia_driver serial_cs_driver = { |
857 | .owner = THIS_MODULE, |
858 | .name = "serial_cs" , |
859 | .probe = serial_probe, |
860 | .remove = serial_detach, |
861 | .id_table = serial_ids, |
862 | .suspend = serial_suspend, |
863 | .resume = serial_resume, |
864 | }; |
865 | module_pcmcia_driver(serial_cs_driver); |
866 | |
867 | MODULE_LICENSE("GPL" ); |
868 | |