cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

serial_cs.c (30163B)


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