serial_cs.c 30.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
/*======================================================================

    A driver for PCMCIA serial devices

    serial_cs.c 1.134 2002/05/04 05:48:53

    The contents of this file are subject to the Mozilla Public
    License Version 1.1 (the "License"); you may not use this file
    except in compliance with the License. You may obtain a copy of
    the License at http://www.mozilla.org/MPL/

    Software distributed under the License is distributed on an "AS
    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
    implied. See the License for the specific language governing
    rights and limitations under the License.

    The initial developer of the original code is David A. Hinds
    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.

    Alternatively, the contents of this file may be used under the
    terms of the GNU General Public License version 2 (the "GPL"), in which
    case the provisions of the GPL are applicable instead of the
    above.  If you wish to allow the use of your version of this file
    only under the terms of the GPL and not to allow others to use
    your version of this file under the MPL, indicate your decision
    by deleting the provisions above and replace them with the notice
    and other provisions required by the GPL.  If you do not delete
    the provisions above, a recipient may use your version of this
    file under either the MPL or the GPL.
    
======================================================================*/

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/serial_core.h>
43
#include <linux/delay.h>
L
Linus Torvalds 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
#include <linux/major.h>
#include <asm/io.h>
#include <asm/system.h>

#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <pcmcia/cisreg.h>

#include "8250.h"


/*====================================================================*/

/* Parameters that can be set with 'insmod' */

/* Enable the speaker? */
static int do_sound = 1;
/* Skip strict UART tests? */
static int buggy_uart;

module_param(do_sound, int, 0444);
module_param(buggy_uart, int, 0444);

/*====================================================================*/

/* Table of multi-port card ID's */

74
struct serial_quirk {
75 76
	unsigned int manfid;
	unsigned int prodid;
L
Linus Torvalds 已提交
77
	int multi;		/* 1 = multifunction, > 1 = # ports */
78
	void (*config)(struct pcmcia_device *);
79
	void (*setup)(struct pcmcia_device *, struct uart_port *);
80
	void (*wakeup)(struct pcmcia_device *);
81
	int (*post)(struct pcmcia_device *);
L
Linus Torvalds 已提交
82 83
};

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
struct serial_info {
	struct pcmcia_device	*p_dev;
	int			ndev;
	int			multi;
	int			slave;
	int			manfid;
	int			prodid;
	int			c950ctrl;
	dev_node_t		node[4];
	int			line[4];
	const struct serial_quirk *quirk;
};

struct serial_cfg_mem {
	tuple_t tuple;
	cisparse_t parse;
	u_char buf[256];
};

103 104 105 106 107 108 109 110 111 112
/*
 * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6"
 * manfid 0x0160, 0x0104
 * This card appears to have a 14.7456MHz clock.
 */
static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
{
	port->uartclk = 14745600;
}

113 114 115
static int quirk_post_ibm(struct pcmcia_device *link)
{
	conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
116 117 118 119 120
	int ret;

	ret = pcmcia_access_configuration_register(link, &reg);
	if (ret)
		goto failed;
121 122 123

	reg.Action = CS_WRITE;
	reg.Value = reg.Value | 1;
124 125 126
	ret = pcmcia_access_configuration_register(link, &reg);
	if (ret)
		goto failed;
127 128
	return 0;

129
 failed:
130 131 132
	return -ENODEV;
}

133 134 135 136 137 138 139 140 141 142 143 144
/*
 * Nokia cards are not really multiport cards.  Shouldn't this
 * be handled by setting the quirk entry .multi = 0 | 1 ?
 */
static void quirk_config_nokia(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;

	if (info->multi > 1)
		info->multi = 1;
}

145 146 147 148
static void quirk_wakeup_oxsemi(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;

149 150
	if (info->c950ctrl)
		outb(12, info->c950ctrl + 1);
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
}

/* request_region? oxsemi branch does no request_region too... */
/*
 * This sequence is needed to properly initialize MC45 attached to OXCF950.
 * I tried decreasing these msleep()s, but it worked properly (survived
 * 1000 stop/start operations) with these timeouts (or bigger).
 */
static void quirk_wakeup_possio_gcc(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;
	unsigned int ctrl = info->c950ctrl;

	outb(0xA, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(300);
	outb(0xC, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(200);
	outb(0xF, ctrl + 1);
	msleep(100);
	outb(0xE, ctrl + 1);
	msleep(100);
	outb(0xC, ctrl + 1);
}

179 180 181 182 183 184 185 186 187 188 189 190 191
/*
 * Socket Dual IO: this enables irq's for second port
 */
static void quirk_config_socket(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;

	if (info->multi) {
		link->conf.Present |= PRESENT_EXT_STATUS;
		link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
	}
}

192 193
static const struct serial_quirk quirks[] = {
	{
194 195 196 197 198
		.manfid	= 0x0160,
		.prodid	= 0x0104,
		.multi	= -1,
		.setup	= quirk_setup_brainboxes_0104,
	}, {
199 200 201 202
		.manfid	= MANFID_IBM,
		.prodid	= ~0,
		.multi	= -1,
		.post	= quirk_post_ibm,
203 204 205 206 207 208 209 210
	}, {
		.manfid	= MANFID_INTEL,
		.prodid	= PRODID_INTEL_DUAL_RS232,
		.multi	= 2,
	}, {
		.manfid	= MANFID_NATINST,
		.prodid	= PRODID_NATINST_QUAD_RS232,
		.multi	= 4,
211 212 213 214 215
	}, {
		.manfid	= MANFID_NOKIA,
		.prodid	= ~0,
		.multi	= -1,
		.config	= quirk_config_nokia,
216
	}, {
217 218 219
		.manfid	= MANFID_OMEGA,
		.prodid	= PRODID_OMEGA_QSP_100,
		.multi	= 4,
220 221 222 223 224 225 226 227 228 229
	}, {
		.manfid	= MANFID_OXSEMI,
		.prodid	= ~0,
		.multi	= -1,
		.wakeup	= quirk_wakeup_oxsemi,
	}, {
		.manfid	= MANFID_POSSIO,
		.prodid	= PRODID_POSSIO_GCC,
		.multi	= -1,
		.wakeup	= quirk_wakeup_possio_gcc,
230 231 232 233 234 235 236 237
	}, {
		.manfid	= MANFID_QUATECH,
		.prodid	= PRODID_QUATECH_DUAL_RS232,
		.multi	= 2,
	}, {
		.manfid	= MANFID_QUATECH,
		.prodid	= PRODID_QUATECH_DUAL_RS232_D1,
		.multi	= 2,
238 239 240 241
	}, {
		.manfid	= MANFID_QUATECH,
		.prodid	= PRODID_QUATECH_DUAL_RS232_G,
		.multi	= 2,
242 243 244 245 246 247 248 249
	}, {
		.manfid	= MANFID_QUATECH,
		.prodid	= PRODID_QUATECH_QUAD_RS232,
		.multi	= 4,
	}, {
		.manfid	= MANFID_SOCKET,
		.prodid	= PRODID_SOCKET_DUAL_RS232,
		.multi	= 2,
250 251 252 253 254 255
		.config	= quirk_config_socket,
	}, {
		.manfid	= MANFID_SOCKET,
		.prodid	= ~0,
		.multi	= -1,
		.config	= quirk_config_socket,
256
	}
L
Linus Torvalds 已提交
257 258
};

259

260
static int serial_config(struct pcmcia_device * link);
L
Linus Torvalds 已提交
261 262 263 264 265 266 267 268 269


/*======================================================================

    After a card is removed, serial_remove() will unregister
    the serial device(s), and release the PCMCIA configuration.
    
======================================================================*/

270
static void serial_remove(struct pcmcia_device *link)
L
Linus Torvalds 已提交
271 272 273 274
{
	struct serial_info *info = link->priv;
	int i;

275
	dev_dbg(&link->dev, "serial_release\n");
L
Linus Torvalds 已提交
276 277 278 279

	/*
	 * Recheck to see if the device is still configured.
	 */
280 281
	for (i = 0; i < info->ndev; i++)
		serial8250_unregister_port(info->line[i]);
L
Linus Torvalds 已提交
282

283
	info->p_dev->dev_node = NULL;
L
Linus Torvalds 已提交
284

285 286
	if (!info->slave)
		pcmcia_disable_device(link);
L
Linus Torvalds 已提交
287 288
}

289
static int serial_suspend(struct pcmcia_device *link)
L
Linus Torvalds 已提交
290
{
291 292
	struct serial_info *info = link->priv;
	int i;
L
Linus Torvalds 已提交
293

294 295
	for (i = 0; i < info->ndev; i++)
		serial8250_suspend_port(info->line[i]);
296 297

	return 0;
L
Linus Torvalds 已提交
298 299
}

300
static int serial_resume(struct pcmcia_device *link)
L
Linus Torvalds 已提交
301
{
R
Russell King 已提交
302 303
	struct serial_info *info = link->priv;
	int i;
L
Linus Torvalds 已提交
304

R
Russell King 已提交
305 306
	for (i = 0; i < info->ndev; i++)
		serial8250_resume_port(info->line[i]);
307

R
Russell King 已提交
308 309
	if (info->quirk && info->quirk->wakeup)
		info->quirk->wakeup(link);
310 311

	return 0;
L
Linus Torvalds 已提交
312 313 314 315 316 317 318 319 320 321
}

/*======================================================================

    serial_attach() creates an "instance" of the driver, allocating
    local data structures for one device.  The device is registered
    with Card Services.

======================================================================*/

322
static int serial_probe(struct pcmcia_device *link)
L
Linus Torvalds 已提交
323 324 325
{
	struct serial_info *info;

326
	dev_dbg(&link->dev, "serial_attach()\n");
L
Linus Torvalds 已提交
327 328

	/* Create new serial device */
329
	info = kzalloc(sizeof (*info), GFP_KERNEL);
L
Linus Torvalds 已提交
330
	if (!info)
331
		return -ENOMEM;
332
	info->p_dev = link;
L
Linus Torvalds 已提交
333 334 335 336
	link->priv = info;

	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
	link->io.NumPorts1 = 8;
337
	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
L
Linus Torvalds 已提交
338 339 340 341 342 343 344
	link->conf.Attributes = CONF_ENABLE_IRQ;
	if (do_sound) {
		link->conf.Attributes |= CONF_ENABLE_SPKR;
		link->conf.Status = CCSR_AUDIO_ENA;
	}
	link->conf.IntType = INT_MEMORY_AND_IO;

345
	return serial_config(link);
L
Linus Torvalds 已提交
346 347 348 349 350 351 352 353 354 355 356
}

/*======================================================================

    This deletes a driver "instance".  The device is de-registered
    with Card Services.  If it has been released, all local data
    structures are freed.  Otherwise, the structures will be freed
    when the device is released.

======================================================================*/

357
static void serial_detach(struct pcmcia_device *link)
L
Linus Torvalds 已提交
358 359 360
{
	struct serial_info *info = link->priv;

361
	dev_dbg(&link->dev, "serial_detach\n");
L
Linus Torvalds 已提交
362 363 364 365 366 367 368 369 370 371 372

	/*
	 * Ensure any outstanding scheduled tasks are completed.
	 */
	flush_scheduled_work();

	/*
	 * Ensure that the ports have been released.
	 */
	serial_remove(link);

373
	/* free bits */
L
Linus Torvalds 已提交
374 375 376 377 378
	kfree(info);
}

/*====================================================================*/

379
static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
380
			unsigned int iobase, int irq)
L
Linus Torvalds 已提交
381 382 383 384 385 386 387 388 389
{
	struct uart_port port;
	int line;

	memset(&port, 0, sizeof (struct uart_port));
	port.iobase = iobase;
	port.irq = irq;
	port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
	port.uartclk = 1843200;
390
	port.dev = &handle->dev;
L
Linus Torvalds 已提交
391 392
	if (buggy_uart)
		port.flags |= UPF_BUGGY_UART;
393 394 395 396

	if (info->quirk && info->quirk->setup)
		info->quirk->setup(handle, &port);

L
Linus Torvalds 已提交
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
	line = serial8250_register_port(&port);
	if (line < 0) {
		printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
		       "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
		return -EINVAL;
	}

	info->line[info->ndev] = line;
	sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
	info->node[info->ndev].major = TTY_MAJOR;
	info->node[info->ndev].minor = 0x40 + line;
	if (info->ndev > 0)
		info->node[info->ndev - 1].next = &info->node[info->ndev];
	info->ndev++;

	return 0;
}

/*====================================================================*/

417 418
static int simple_config_check(struct pcmcia_device *p_dev,
			       cistpl_cftable_entry_t *cf,
419
			       cistpl_cftable_entry_t *dflt,
420
			       unsigned int vcc,
421
			       void *priv_data)
L
Linus Torvalds 已提交
422
{
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
	static const int size_table[2] = { 8, 16 };
	int *try = priv_data;

	if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
		p_dev->conf.Vpp =
			cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;

	if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[(*try >> 1)])
	    && (cf->io.win[0].base != 0)) {
		p_dev->io.BasePort1 = cf->io.win[0].base;
		p_dev->io.IOAddrLines = ((*try & 0x1) == 0) ?
			16 : cf->io.flags & CISTPL_IO_LINES_MASK;
		if (!pcmcia_request_io(p_dev, &p_dev->io))
			return 0;
	}
	return -EINVAL;
L
Linus Torvalds 已提交
439 440
}

441 442
static int simple_config_check_notpicky(struct pcmcia_device *p_dev,
					cistpl_cftable_entry_t *cf,
443
					cistpl_cftable_entry_t *dflt,
444
					unsigned int vcc,
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
					void *priv_data)
{
	static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
	int j;

	if ((cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
		for (j = 0; j < 5; j++) {
			p_dev->io.BasePort1 = base[j];
			p_dev->io.IOAddrLines = base[j] ? 16 : 3;
			if (!pcmcia_request_io(p_dev, &p_dev->io))
				return 0;
		}
	}
	return -ENODEV;
}
L
Linus Torvalds 已提交
460

461
static int simple_config(struct pcmcia_device *link)
L
Linus Torvalds 已提交
462 463
{
	struct serial_info *info = link->priv;
464
	int i = -ENODEV, try;
465

L
Linus Torvalds 已提交
466
	/* If the card is already configured, look up the port and irq */
467
	if (link->function_config) {
468
		unsigned int port = 0;
469 470 471
		if ((link->io.BasePort2 != 0) &&
		    (link->io.NumPorts2 == 8)) {
			port = link->io.BasePort2;
L
Linus Torvalds 已提交
472 473
			info->slave = 1;
		} else if ((info->manfid == MANFID_OSITECH) &&
474 475
			   (link->io.NumPorts1 == 0x40)) {
			port = link->io.BasePort1 + 0x28;
L
Linus Torvalds 已提交
476 477
			info->slave = 1;
		}
478
		if (info->slave) {
479 480
			return setup_serial(link, info, port,
					    link->irq.AssignedIRQ);
481
		}
L
Linus Torvalds 已提交
482 483
	}

484 485 486 487 488 489
	/* First pass: look for a config entry that looks normal.
	 * Two tries: without IO aliases, then with aliases */
	for (try = 0; try < 4; try++)
		if (!pcmcia_loop_config(link, simple_config_check, &try))
			goto found_port;

L
Linus Torvalds 已提交
490 491 492
	/* Second pass: try to find an entry that isn't picky about
	   its base address, then try to grab any standard serial port
	   address, and finally try to get any free port. */
493 494
	if (!pcmcia_loop_config(link, simple_config_check_notpicky, NULL))
		goto found_port;
L
Linus Torvalds 已提交
495

496 497 498
	printk(KERN_NOTICE
	       "serial_cs: no usable port range found, giving up\n");
	return -1;
L
Linus Torvalds 已提交
499

500
found_port:
501
	i = pcmcia_request_irq(link, &link->irq);
502
	if (i != 0)
L
Linus Torvalds 已提交
503
		link->irq.AssignedIRQ = 0;
504

L
Linus Torvalds 已提交
505 506
	if (info->multi && (info->manfid == MANFID_3COM))
		link->conf.ConfigIndex &= ~(0x08);
507 508 509 510 511 512 513

	/*
	 * Apply any configuration quirks.
	 */
	if (info->quirk && info->quirk->config)
		info->quirk->config(link);

514
	i = pcmcia_request_configuration(link, &link->conf);
515
	if (i != 0)
L
Linus Torvalds 已提交
516
		return -1;
517
	return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
L
Linus Torvalds 已提交
518 519
}

520 521
static int multi_config_check(struct pcmcia_device *p_dev,
			      cistpl_cftable_entry_t *cf,
522
			      cistpl_cftable_entry_t *dflt,
523
			      unsigned int vcc,
524
			      void *priv_data)
L
Linus Torvalds 已提交
525
{
526 527 528 529 530 531 532 533 534 535 536 537 538 539
	int *base2 = priv_data;

	/* The quad port cards have bad CIS's, so just look for a
	   window larger than 8 ports and assume it will be right */
	if ((cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
		p_dev->io.BasePort1 = cf->io.win[0].base;
		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
		if (!pcmcia_request_io(p_dev, &p_dev->io)) {
			*base2 = p_dev->io.BasePort1 + 8;
			return 0;
		}
	}
	return -ENODEV;
}
540

541 542
static int multi_config_check_notpicky(struct pcmcia_device *p_dev,
				       cistpl_cftable_entry_t *cf,
543
				       cistpl_cftable_entry_t *dflt,
544
				       unsigned int vcc,
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
				       void *priv_data)
{
	int *base2 = priv_data;

	if (cf->io.nwin == 2) {
		p_dev->io.BasePort1 = cf->io.win[0].base;
		p_dev->io.BasePort2 = cf->io.win[1].base;
		p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
		if (!pcmcia_request_io(p_dev, &p_dev->io)) {
			*base2 = p_dev->io.BasePort2;
			return 0;
		}
	}
	return -ENODEV;
}
L
Linus Torvalds 已提交
560

561 562 563 564
static int multi_config(struct pcmcia_device *link)
{
	struct serial_info *info = link->priv;
	int i, base2 = 0;
L
Linus Torvalds 已提交
565 566 567

	/* First, look for a generic full-sized window */
	link->io.NumPorts1 = info->multi * 8;
568 569
	if (pcmcia_loop_config(link, multi_config_check, &base2)) {
		/* If that didn't work, look for two windows */
L
Linus Torvalds 已提交
570 571
		link->io.NumPorts1 = link->io.NumPorts2 = 8;
		info->multi = 2;
572 573 574 575 576
		if (pcmcia_loop_config(link, multi_config_check_notpicky,
				       &base2)) {
			printk(KERN_NOTICE "serial_cs: no usable port range"
			       "found, giving up\n");
			return -ENODEV;
L
Linus Torvalds 已提交
577 578 579
		}
	}

580
	i = pcmcia_request_irq(link, &link->irq);
D
Dominik Brodowski 已提交
581
	if (i != 0) {
582
		/* FIXME: comment does not fit, error handling does not fit */
L
Linus Torvalds 已提交
583 584 585 586
		printk(KERN_NOTICE
		       "serial_cs: no usable port range found, giving up\n");
		link->irq.AssignedIRQ = 0;
	}
587 588 589 590 591 592 593

	/*
	 * Apply any configuration quirks.
	 */
	if (info->quirk && info->quirk->config)
		info->quirk->config(link);

594
	i = pcmcia_request_configuration(link, &link->conf);
595
	if (i != 0)
596
		return -ENODEV;
L
Linus Torvalds 已提交
597 598

	/* The Oxford Semiconductor OXCF950 cards are in fact single-port:
599 600 601 602 603 604 605
	 * 8 registers are for the UART, the others are extra registers.
	 * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
	 */
	if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
				info->prodid == PRODID_POSSIO_GCC)) {
		int err;

606 607
		if (link->conf.ConfigIndex == 1 ||
		    link->conf.ConfigIndex == 3) {
608 609 610
			err = setup_serial(link, info, base2,
					link->irq.AssignedIRQ);
			base2 = link->io.BasePort1;
L
Linus Torvalds 已提交
611
		} else {
612 613
			err = setup_serial(link, info, link->io.BasePort1,
					link->irq.AssignedIRQ);
L
Linus Torvalds 已提交
614
		}
615
		info->c950ctrl = base2;
616 617 618 619 620 621 622 623

		/*
		 * FIXME: We really should wake up the port prior to
		 * handing it over to the serial layer.
		 */
		if (info->quirk && info->quirk->wakeup)
			info->quirk->wakeup(link);

624
		return 0;
L
Linus Torvalds 已提交
625 626
	}

627
	setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
L
Linus Torvalds 已提交
628
	for (i = 0; i < info->multi - 1; i++)
629
		setup_serial(link, info, base2 + (8 * i),
630
				link->irq.AssignedIRQ);
631
	return 0;
L
Linus Torvalds 已提交
632 633
}

634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
static int serial_check_for_multi(struct pcmcia_device *p_dev,
				  cistpl_cftable_entry_t *cf,
				  cistpl_cftable_entry_t *dflt,
				  unsigned int vcc,
				  void *priv_data)
{
	struct serial_info *info = p_dev->priv;

	if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
		info->multi = cf->io.win[0].len >> 3;

	if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
		(cf->io.win[1].len == 8))
		info->multi = 2;

	return 0; /* break */
}


L
Linus Torvalds 已提交
653 654 655 656 657 658 659 660
/*======================================================================

    serial_config() is scheduled to run after a CARD_INSERTION event
    is received, to configure the PCMCIA socket, and to make the
    serial device available to the system.

======================================================================*/

661
static int serial_config(struct pcmcia_device * link)
L
Linus Torvalds 已提交
662 663
{
	struct serial_info *info = link->priv;
664
	int i;
665

666
	dev_dbg(&link->dev, "serial_config\n");
667

L
Linus Torvalds 已提交
668
	/* Is this a compliant multifunction card? */
669
	info->multi = (link->socket->functions > 1);
L
Linus Torvalds 已提交
670 671

	/* Is this a multiport card? */
672 673 674 675 676 677 678 679 680 681 682
	info->manfid = link->manf_id;
	info->prodid = link->card_id;

	for (i = 0; i < ARRAY_SIZE(quirks); i++)
		if ((quirks[i].manfid == ~0 ||
		     quirks[i].manfid == info->manfid) &&
		    (quirks[i].prodid == ~0 ||
		     quirks[i].prodid == info->prodid)) {
			info->quirk = &quirks[i];
			break;
		}
L
Linus Torvalds 已提交
683 684 685 686

	/* Another check for dual-serial cards: look for either serial or
	   multifunction cards that ask for appropriate IO port ranges */
	if ((info->multi == 0) &&
687 688
	    (link->has_func_id) &&
	    ((link->func_id == CISTPL_FUNCID_MULTI) ||
689 690
	     (link->func_id == CISTPL_FUNCID_SERIAL)))
		pcmcia_loop_config(link, serial_check_for_multi, info);
L
Linus Torvalds 已提交
691

692 693 694 695 696 697
	/*
	 * Apply any multi-port quirk.
	 */
	if (info->quirk && info->quirk->multi != -1)
		info->multi = info->quirk->multi;

L
Linus Torvalds 已提交
698 699 700 701 702 703 704 705
	if (info->multi > 1)
		multi_config(link);
	else
		simple_config(link);

	if (info->ndev == 0)
		goto failed;

706 707 708 709 710 711 712
	/*
	 * Apply any post-init quirk.  FIXME: This should really happen
	 * before we register the port, since it might already be in use.
	 */
	if (info->quirk && info->quirk->post)
		if (info->quirk->post(link))
			goto failed;
L
Linus Torvalds 已提交
713

714
	link->dev_node = &info->node[0];
715
	return 0;
L
Linus Torvalds 已提交
716

717
failed:
L
Linus Torvalds 已提交
718
	serial_remove(link);
719
	return -ENODEV;
L
Linus Torvalds 已提交
720 721
}

722 723 724 725 726 727 728 729 730 731 732 733 734
static struct pcmcia_device_id serial_ids[] = {
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab),
735 736
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a),
737 738 739 740 741 742 743 744 745
	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63),
	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef),
	PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef),
	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023),
	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a),
	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29),
	PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719),
K
Komuro 已提交
746
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4),
747 748 749 750 751 752
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e),
753 754
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),
K
Komuro 已提交
755 756
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed),
757 758 759
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f),
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),
K
Komuro 已提交
760
	PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf),
761
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01),
762 763
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05),
	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101),
764 765 766 767 768 769 770 771 772 773 774
	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070),
	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562),
	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070),
	PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020),
	PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f),
	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card       ", 0xb569a6e5, 0x5bd4ff2c),
	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3),
	PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15),
	PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
	PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
775
	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
	PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50),
	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51),
	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52),
	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53),
	PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180),
	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e),
	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b),
	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025),
	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045),
	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052),
	PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae),
	PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef),
	PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
	PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
	PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
794
	PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
795 796 797 798 799 800 801 802
	PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
	PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
	PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),
	PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76),
	PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95),
	PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed),
	PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65),
	PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6),
K
Komuro 已提交
803
	PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb),
804 805 806 807 808 809 810
	PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f),
	PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f),
	PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383),
	PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e),
	PCMCIA_DEVICE_PROD_ID12("OEM      ", "C288MX     ", 0xb572d360, 0xd2385b7a),
	PCMCIA_DEVICE_PROD_ID12("PCMCIA   ", "C336MX     ", 0x99bcafe9, 0xaa25bcab),
	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
811
	PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
812 813 814 815 816
	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"),
	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"),
	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"),
	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"),
	PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"),
817 818
	PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"),
	PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"),
819
	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
820
	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"),
821 822
	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
823
	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
824
	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */
825 826 827
	PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
	PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
	PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
828
	PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"),
829 830 831
	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"),
	PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"),
	PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"),
832
	PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"),
833
	PCMCIA_DEVICE_CIS_MANF_CARD(0x0013, 0x0000, "cis/GLOBETROTTER.cis"),
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100  1.00.",0x19ca78af,0xf964f42b),
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL100",0x19ca78af,0x71d98e83),
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232  1.00.",0x19ca78af,0x69fb7490),
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.","SERIAL CARD: SL232",0x19ca78af,0xb6bc0235),
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232",0x63f2e0bd,0xb9e175d3),
	PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.","SERIAL CARD: CF232-5",0x63f2e0bd,0xfce33442),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232",0x3beb8cf2,0x171e7190),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF232-5",0x3beb8cf2,0x20da4262),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF428",0x3beb8cf2,0xea5dd57d),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: CF500",0x3beb8cf2,0xd77255fa),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: IC232",0x3beb8cf2,0x6a709903),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: SL232",0x3beb8cf2,0x18430676),
	PCMCIA_DEVICE_PROD_ID12("Elan","Serial Port: XL232",0x3beb8cf2,0x6f933767),
	PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
	PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
	PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
	PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
	PCMCIA_MFC_DEVICE_PROD_ID12(0,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
	PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: CF332",0x3beb8cf2,0x16dc1ba7),
	PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL332",0x3beb8cf2,0x19816c41),
	PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL385",0x3beb8cf2,0x64112029),
	PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
	PCMCIA_MFC_DEVICE_PROD_ID12(2,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
	PCMCIA_MFC_DEVICE_PROD_ID12(3,"Elan","Serial Port: SL432",0x3beb8cf2,0x1cce7ac4),
858
	PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b),
859 860 861 862 863 864 865 866
	/* too generic */
	/* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */
	/* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */
	PCMCIA_DEVICE_FUNC_ID(2),
	PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, serial_ids);

867 868 869 870 871 872 873 874 875 876 877 878
MODULE_FIRMWARE("cis/PCMLM28.cis");
MODULE_FIRMWARE("cis/DP83903.cis");
MODULE_FIRMWARE("cis/3CCFEM556.cis");
MODULE_FIRMWARE("cis/3CXEM556.cis");
MODULE_FIRMWARE("cis/SW_8xx_SER.cis");
MODULE_FIRMWARE("cis/SW_7xx_SER.cis");
MODULE_FIRMWARE("cis/SW_555_SER.cis");
MODULE_FIRMWARE("cis/MT5634ZLX.cis");
MODULE_FIRMWARE("cis/COMpad2.cis");
MODULE_FIRMWARE("cis/COMpad4.cis");
MODULE_FIRMWARE("cis/RS-COM-2P.cis");

L
Linus Torvalds 已提交
879 880 881 882 883
static struct pcmcia_driver serial_cs_driver = {
	.owner		= THIS_MODULE,
	.drv		= {
		.name	= "serial_cs",
	},
884
	.probe		= serial_probe,
885
	.remove		= serial_detach,
886
	.id_table	= serial_ids,
887 888
	.suspend	= serial_suspend,
	.resume		= serial_resume,
L
Linus Torvalds 已提交
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
};

static int __init init_serial_cs(void)
{
	return pcmcia_register_driver(&serial_cs_driver);
}

static void __exit exit_serial_cs(void)
{
	pcmcia_unregister_driver(&serial_cs_driver);
}

module_init(init_serial_cs);
module_exit(exit_serial_cs);

MODULE_LICENSE("GPL");