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