162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) 262306a36Sopenharmony_ci/*====================================================================== 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci A driver for PCMCIA serial devices 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci serial_cs.c 1.134 2002/05/04 05:48:53 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci The contents of this file are subject to the Mozilla Public 962306a36Sopenharmony_ci License Version 1.1 (the "License"); you may not use this file 1062306a36Sopenharmony_ci except in compliance with the License. You may obtain a copy of 1162306a36Sopenharmony_ci the License at http://www.mozilla.org/MPL/ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci Software distributed under the License is distributed on an "AS 1462306a36Sopenharmony_ci IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 1562306a36Sopenharmony_ci implied. See the License for the specific language governing 1662306a36Sopenharmony_ci rights and limitations under the License. 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci The initial developer of the original code is David A. Hinds 1962306a36Sopenharmony_ci <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 2062306a36Sopenharmony_ci are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci Alternatively, the contents of this file may be used under the 2362306a36Sopenharmony_ci terms of the GNU General Public License version 2 (the "GPL"), in which 2462306a36Sopenharmony_ci case the provisions of the GPL are applicable instead of the 2562306a36Sopenharmony_ci above. If you wish to allow the use of your version of this file 2662306a36Sopenharmony_ci only under the terms of the GPL and not to allow others to use 2762306a36Sopenharmony_ci your version of this file under the MPL, indicate your decision 2862306a36Sopenharmony_ci by deleting the provisions above and replace them with the notice 2962306a36Sopenharmony_ci and other provisions required by the GPL. If you do not delete 3062306a36Sopenharmony_ci the provisions above, a recipient may use your version of this 3162306a36Sopenharmony_ci file under either the MPL or the GPL. 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci======================================================================*/ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#include <linux/module.h> 3662306a36Sopenharmony_ci#include <linux/moduleparam.h> 3762306a36Sopenharmony_ci#include <linux/kernel.h> 3862306a36Sopenharmony_ci#include <linux/ptrace.h> 3962306a36Sopenharmony_ci#include <linux/slab.h> 4062306a36Sopenharmony_ci#include <linux/string.h> 4162306a36Sopenharmony_ci#include <linux/timer.h> 4262306a36Sopenharmony_ci#include <linux/serial_core.h> 4362306a36Sopenharmony_ci#include <linux/delay.h> 4462306a36Sopenharmony_ci#include <linux/major.h> 4562306a36Sopenharmony_ci#include <asm/io.h> 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#include <pcmcia/cistpl.h> 4862306a36Sopenharmony_ci#include <pcmcia/ciscode.h> 4962306a36Sopenharmony_ci#include <pcmcia/ds.h> 5062306a36Sopenharmony_ci#include <pcmcia/cisreg.h> 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#include "8250.h" 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/*====================================================================*/ 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci/* Parameters that can be set with 'insmod' */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Enable the speaker? */ 6062306a36Sopenharmony_cistatic int do_sound = 1; 6162306a36Sopenharmony_ci/* Skip strict UART tests? */ 6262306a36Sopenharmony_cistatic int buggy_uart; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cimodule_param(do_sound, int, 0444); 6562306a36Sopenharmony_cimodule_param(buggy_uart, int, 0444); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci/*====================================================================*/ 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* Table of multi-port card ID's */ 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistruct serial_quirk { 7262306a36Sopenharmony_ci unsigned int manfid; 7362306a36Sopenharmony_ci unsigned int prodid; 7462306a36Sopenharmony_ci int multi; /* 1 = multifunction, > 1 = # ports */ 7562306a36Sopenharmony_ci void (*config)(struct pcmcia_device *); 7662306a36Sopenharmony_ci void (*setup)(struct pcmcia_device *, struct uart_8250_port *); 7762306a36Sopenharmony_ci void (*wakeup)(struct pcmcia_device *); 7862306a36Sopenharmony_ci int (*post)(struct pcmcia_device *); 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct serial_info { 8262306a36Sopenharmony_ci struct pcmcia_device *p_dev; 8362306a36Sopenharmony_ci int ndev; 8462306a36Sopenharmony_ci int multi; 8562306a36Sopenharmony_ci int slave; 8662306a36Sopenharmony_ci int manfid; 8762306a36Sopenharmony_ci int prodid; 8862306a36Sopenharmony_ci int c950ctrl; 8962306a36Sopenharmony_ci int line[4]; 9062306a36Sopenharmony_ci const struct serial_quirk *quirk; 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_cistruct serial_cfg_mem { 9462306a36Sopenharmony_ci tuple_t tuple; 9562306a36Sopenharmony_ci cisparse_t parse; 9662306a36Sopenharmony_ci u_char buf[256]; 9762306a36Sopenharmony_ci}; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci/* 10062306a36Sopenharmony_ci * vers_1 5.0, "Brain Boxes", "2-Port RS232 card", "r6" 10162306a36Sopenharmony_ci * manfid 0x0160, 0x0104 10262306a36Sopenharmony_ci * This card appears to have a 14.7456MHz clock. 10362306a36Sopenharmony_ci */ 10462306a36Sopenharmony_ci/* Generic Modem: MD55x (GPRS/EDGE) have 10562306a36Sopenharmony_ci * Elan VPU16551 UART with 14.7456MHz oscillator 10662306a36Sopenharmony_ci * manfid 0x015D, 0x4C45 10762306a36Sopenharmony_ci */ 10862306a36Sopenharmony_cistatic void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci uart->port.uartclk = 14745600; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic int quirk_post_ibm(struct pcmcia_device *link) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci u8 val; 11662306a36Sopenharmony_ci int ret; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci ret = pcmcia_read_config_byte(link, 0x800, &val); 11962306a36Sopenharmony_ci if (ret) 12062306a36Sopenharmony_ci goto failed; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci ret = pcmcia_write_config_byte(link, 0x800, val | 1); 12362306a36Sopenharmony_ci if (ret) 12462306a36Sopenharmony_ci goto failed; 12562306a36Sopenharmony_ci return 0; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci failed: 12862306a36Sopenharmony_ci return -ENODEV; 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci/* 13262306a36Sopenharmony_ci * Nokia cards are not really multiport cards. Shouldn't this 13362306a36Sopenharmony_ci * be handled by setting the quirk entry .multi = 0 | 1 ? 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_cistatic void quirk_config_nokia(struct pcmcia_device *link) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci struct serial_info *info = link->priv; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci if (info->multi > 1) 14062306a36Sopenharmony_ci info->multi = 1; 14162306a36Sopenharmony_ci} 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_cistatic void quirk_wakeup_oxsemi(struct pcmcia_device *link) 14462306a36Sopenharmony_ci{ 14562306a36Sopenharmony_ci struct serial_info *info = link->priv; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci if (info->c950ctrl) 14862306a36Sopenharmony_ci outb(12, info->c950ctrl + 1); 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci/* request_region? oxsemi branch does no request_region too... */ 15262306a36Sopenharmony_ci/* 15362306a36Sopenharmony_ci * This sequence is needed to properly initialize MC45 attached to OXCF950. 15462306a36Sopenharmony_ci * I tried decreasing these msleep()s, but it worked properly (survived 15562306a36Sopenharmony_ci * 1000 stop/start operations) with these timeouts (or bigger). 15662306a36Sopenharmony_ci */ 15762306a36Sopenharmony_cistatic void quirk_wakeup_possio_gcc(struct pcmcia_device *link) 15862306a36Sopenharmony_ci{ 15962306a36Sopenharmony_ci struct serial_info *info = link->priv; 16062306a36Sopenharmony_ci unsigned int ctrl = info->c950ctrl; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci outb(0xA, ctrl + 1); 16362306a36Sopenharmony_ci msleep(100); 16462306a36Sopenharmony_ci outb(0xE, ctrl + 1); 16562306a36Sopenharmony_ci msleep(300); 16662306a36Sopenharmony_ci outb(0xC, ctrl + 1); 16762306a36Sopenharmony_ci msleep(100); 16862306a36Sopenharmony_ci outb(0xE, ctrl + 1); 16962306a36Sopenharmony_ci msleep(200); 17062306a36Sopenharmony_ci outb(0xF, ctrl + 1); 17162306a36Sopenharmony_ci msleep(100); 17262306a36Sopenharmony_ci outb(0xE, ctrl + 1); 17362306a36Sopenharmony_ci msleep(100); 17462306a36Sopenharmony_ci outb(0xC, ctrl + 1); 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci/* 17862306a36Sopenharmony_ci * Socket Dual IO: this enables irq's for second port 17962306a36Sopenharmony_ci */ 18062306a36Sopenharmony_cistatic void quirk_config_socket(struct pcmcia_device *link) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci struct serial_info *info = link->priv; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci if (info->multi) 18562306a36Sopenharmony_ci link->config_flags |= CONF_ENABLE_ESR; 18662306a36Sopenharmony_ci} 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_cistatic const struct serial_quirk quirks[] = { 18962306a36Sopenharmony_ci { 19062306a36Sopenharmony_ci .manfid = 0x0160, 19162306a36Sopenharmony_ci .prodid = 0x0104, 19262306a36Sopenharmony_ci .multi = -1, 19362306a36Sopenharmony_ci .setup = quirk_setup_brainboxes_0104, 19462306a36Sopenharmony_ci }, { 19562306a36Sopenharmony_ci .manfid = 0x015D, 19662306a36Sopenharmony_ci .prodid = 0x4C45, 19762306a36Sopenharmony_ci .multi = -1, 19862306a36Sopenharmony_ci .setup = quirk_setup_brainboxes_0104, 19962306a36Sopenharmony_ci }, { 20062306a36Sopenharmony_ci .manfid = MANFID_IBM, 20162306a36Sopenharmony_ci .prodid = ~0, 20262306a36Sopenharmony_ci .multi = -1, 20362306a36Sopenharmony_ci .post = quirk_post_ibm, 20462306a36Sopenharmony_ci }, { 20562306a36Sopenharmony_ci .manfid = MANFID_INTEL, 20662306a36Sopenharmony_ci .prodid = PRODID_INTEL_DUAL_RS232, 20762306a36Sopenharmony_ci .multi = 2, 20862306a36Sopenharmony_ci }, { 20962306a36Sopenharmony_ci .manfid = MANFID_NATINST, 21062306a36Sopenharmony_ci .prodid = PRODID_NATINST_QUAD_RS232, 21162306a36Sopenharmony_ci .multi = 4, 21262306a36Sopenharmony_ci }, { 21362306a36Sopenharmony_ci .manfid = MANFID_NOKIA, 21462306a36Sopenharmony_ci .prodid = ~0, 21562306a36Sopenharmony_ci .multi = -1, 21662306a36Sopenharmony_ci .config = quirk_config_nokia, 21762306a36Sopenharmony_ci }, { 21862306a36Sopenharmony_ci .manfid = MANFID_OMEGA, 21962306a36Sopenharmony_ci .prodid = PRODID_OMEGA_QSP_100, 22062306a36Sopenharmony_ci .multi = 4, 22162306a36Sopenharmony_ci }, { 22262306a36Sopenharmony_ci .manfid = MANFID_OXSEMI, 22362306a36Sopenharmony_ci .prodid = ~0, 22462306a36Sopenharmony_ci .multi = -1, 22562306a36Sopenharmony_ci .wakeup = quirk_wakeup_oxsemi, 22662306a36Sopenharmony_ci }, { 22762306a36Sopenharmony_ci .manfid = MANFID_POSSIO, 22862306a36Sopenharmony_ci .prodid = PRODID_POSSIO_GCC, 22962306a36Sopenharmony_ci .multi = -1, 23062306a36Sopenharmony_ci .wakeup = quirk_wakeup_possio_gcc, 23162306a36Sopenharmony_ci }, { 23262306a36Sopenharmony_ci .manfid = MANFID_QUATECH, 23362306a36Sopenharmony_ci .prodid = PRODID_QUATECH_DUAL_RS232, 23462306a36Sopenharmony_ci .multi = 2, 23562306a36Sopenharmony_ci }, { 23662306a36Sopenharmony_ci .manfid = MANFID_QUATECH, 23762306a36Sopenharmony_ci .prodid = PRODID_QUATECH_DUAL_RS232_D1, 23862306a36Sopenharmony_ci .multi = 2, 23962306a36Sopenharmony_ci }, { 24062306a36Sopenharmony_ci .manfid = MANFID_QUATECH, 24162306a36Sopenharmony_ci .prodid = PRODID_QUATECH_DUAL_RS232_G, 24262306a36Sopenharmony_ci .multi = 2, 24362306a36Sopenharmony_ci }, { 24462306a36Sopenharmony_ci .manfid = MANFID_QUATECH, 24562306a36Sopenharmony_ci .prodid = PRODID_QUATECH_QUAD_RS232, 24662306a36Sopenharmony_ci .multi = 4, 24762306a36Sopenharmony_ci }, { 24862306a36Sopenharmony_ci .manfid = MANFID_SOCKET, 24962306a36Sopenharmony_ci .prodid = PRODID_SOCKET_DUAL_RS232, 25062306a36Sopenharmony_ci .multi = 2, 25162306a36Sopenharmony_ci .config = quirk_config_socket, 25262306a36Sopenharmony_ci }, { 25362306a36Sopenharmony_ci .manfid = MANFID_SOCKET, 25462306a36Sopenharmony_ci .prodid = ~0, 25562306a36Sopenharmony_ci .multi = -1, 25662306a36Sopenharmony_ci .config = quirk_config_socket, 25762306a36Sopenharmony_ci } 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic int serial_config(struct pcmcia_device *link); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_cistatic void serial_remove(struct pcmcia_device *link) 26562306a36Sopenharmony_ci{ 26662306a36Sopenharmony_ci struct serial_info *info = link->priv; 26762306a36Sopenharmony_ci int i; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci dev_dbg(&link->dev, "serial_release\n"); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* 27262306a36Sopenharmony_ci * Recheck to see if the device is still configured. 27362306a36Sopenharmony_ci */ 27462306a36Sopenharmony_ci for (i = 0; i < info->ndev; i++) 27562306a36Sopenharmony_ci serial8250_unregister_port(info->line[i]); 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci if (!info->slave) 27862306a36Sopenharmony_ci pcmcia_disable_device(link); 27962306a36Sopenharmony_ci} 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_cistatic int serial_suspend(struct pcmcia_device *link) 28262306a36Sopenharmony_ci{ 28362306a36Sopenharmony_ci struct serial_info *info = link->priv; 28462306a36Sopenharmony_ci int i; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci for (i = 0; i < info->ndev; i++) 28762306a36Sopenharmony_ci serial8250_suspend_port(info->line[i]); 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci return 0; 29062306a36Sopenharmony_ci} 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistatic int serial_resume(struct pcmcia_device *link) 29362306a36Sopenharmony_ci{ 29462306a36Sopenharmony_ci struct serial_info *info = link->priv; 29562306a36Sopenharmony_ci int i; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci for (i = 0; i < info->ndev; i++) 29862306a36Sopenharmony_ci serial8250_resume_port(info->line[i]); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci if (info->quirk && info->quirk->wakeup) 30162306a36Sopenharmony_ci info->quirk->wakeup(link); 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci return 0; 30462306a36Sopenharmony_ci} 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cistatic int serial_probe(struct pcmcia_device *link) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci struct serial_info *info; 30962306a36Sopenharmony_ci int ret; 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci dev_dbg(&link->dev, "serial_attach()\n"); 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci /* Create new serial device */ 31462306a36Sopenharmony_ci info = kzalloc(sizeof(*info), GFP_KERNEL); 31562306a36Sopenharmony_ci if (!info) 31662306a36Sopenharmony_ci return -ENOMEM; 31762306a36Sopenharmony_ci info->p_dev = link; 31862306a36Sopenharmony_ci link->priv = info; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; 32162306a36Sopenharmony_ci if (do_sound) 32262306a36Sopenharmony_ci link->config_flags |= CONF_ENABLE_SPKR; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci ret = serial_config(link); 32562306a36Sopenharmony_ci if (ret) 32662306a36Sopenharmony_ci goto free_info; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci return 0; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_cifree_info: 33162306a36Sopenharmony_ci kfree(info); 33262306a36Sopenharmony_ci return ret; 33362306a36Sopenharmony_ci} 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_cistatic void serial_detach(struct pcmcia_device *link) 33662306a36Sopenharmony_ci{ 33762306a36Sopenharmony_ci struct serial_info *info = link->priv; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci dev_dbg(&link->dev, "serial_detach\n"); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci /* 34262306a36Sopenharmony_ci * Ensure that the ports have been released. 34362306a36Sopenharmony_ci */ 34462306a36Sopenharmony_ci serial_remove(link); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci /* free bits */ 34762306a36Sopenharmony_ci kfree(info); 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci/*====================================================================*/ 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic int setup_serial(struct pcmcia_device *handle, struct serial_info *info, 35362306a36Sopenharmony_ci unsigned int iobase, int irq) 35462306a36Sopenharmony_ci{ 35562306a36Sopenharmony_ci struct uart_8250_port uart; 35662306a36Sopenharmony_ci int line; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci memset(&uart, 0, sizeof(uart)); 35962306a36Sopenharmony_ci uart.port.iobase = iobase; 36062306a36Sopenharmony_ci uart.port.irq = irq; 36162306a36Sopenharmony_ci uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; 36262306a36Sopenharmony_ci uart.port.uartclk = 1843200; 36362306a36Sopenharmony_ci uart.port.dev = &handle->dev; 36462306a36Sopenharmony_ci if (buggy_uart) 36562306a36Sopenharmony_ci uart.port.flags |= UPF_BUGGY_UART; 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_ci if (info->quirk && info->quirk->setup) 36862306a36Sopenharmony_ci info->quirk->setup(handle, &uart); 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci line = serial8250_register_8250_port(&uart); 37162306a36Sopenharmony_ci if (line < 0) { 37262306a36Sopenharmony_ci pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n", 37362306a36Sopenharmony_ci (unsigned long)iobase, irq); 37462306a36Sopenharmony_ci return -EINVAL; 37562306a36Sopenharmony_ci } 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci info->line[info->ndev] = line; 37862306a36Sopenharmony_ci info->ndev++; 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci return 0; 38162306a36Sopenharmony_ci} 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci/*====================================================================*/ 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic int pfc_config(struct pcmcia_device *p_dev) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci unsigned int port = 0; 38862306a36Sopenharmony_ci struct serial_info *info = p_dev->priv; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci if ((p_dev->resource[1]->end != 0) && 39162306a36Sopenharmony_ci (resource_size(p_dev->resource[1]) == 8)) { 39262306a36Sopenharmony_ci port = p_dev->resource[1]->start; 39362306a36Sopenharmony_ci info->slave = 1; 39462306a36Sopenharmony_ci } else if ((info->manfid == MANFID_OSITECH) && 39562306a36Sopenharmony_ci (resource_size(p_dev->resource[0]) == 0x40)) { 39662306a36Sopenharmony_ci port = p_dev->resource[0]->start + 0x28; 39762306a36Sopenharmony_ci info->slave = 1; 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci if (info->slave) 40062306a36Sopenharmony_ci return setup_serial(p_dev, info, port, p_dev->irq); 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci dev_warn(&p_dev->dev, "no usable port range found, giving up\n"); 40362306a36Sopenharmony_ci return -ENODEV; 40462306a36Sopenharmony_ci} 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_cistatic int simple_config_check(struct pcmcia_device *p_dev, void *priv_data) 40762306a36Sopenharmony_ci{ 40862306a36Sopenharmony_ci static const int size_table[2] = { 8, 16 }; 40962306a36Sopenharmony_ci int *try = priv_data; 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_ci if (p_dev->resource[0]->start == 0) 41262306a36Sopenharmony_ci return -ENODEV; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci if ((*try & 0x1) == 0) 41562306a36Sopenharmony_ci p_dev->io_lines = 16; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci if (p_dev->resource[0]->end != size_table[(*try >> 1)]) 41862306a36Sopenharmony_ci return -ENODEV; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci p_dev->resource[0]->end = 8; 42162306a36Sopenharmony_ci p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 42262306a36Sopenharmony_ci p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci return pcmcia_request_io(p_dev); 42562306a36Sopenharmony_ci} 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_cistatic int simple_config_check_notpicky(struct pcmcia_device *p_dev, 42862306a36Sopenharmony_ci void *priv_data) 42962306a36Sopenharmony_ci{ 43062306a36Sopenharmony_ci static const unsigned int base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 43162306a36Sopenharmony_ci int j; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci if (p_dev->io_lines > 3) 43462306a36Sopenharmony_ci return -ENODEV; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 43762306a36Sopenharmony_ci p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 43862306a36Sopenharmony_ci p_dev->resource[0]->end = 8; 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci for (j = 0; j < 5; j++) { 44162306a36Sopenharmony_ci p_dev->resource[0]->start = base[j]; 44262306a36Sopenharmony_ci p_dev->io_lines = base[j] ? 16 : 3; 44362306a36Sopenharmony_ci if (!pcmcia_request_io(p_dev)) 44462306a36Sopenharmony_ci return 0; 44562306a36Sopenharmony_ci } 44662306a36Sopenharmony_ci return -ENODEV; 44762306a36Sopenharmony_ci} 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_cistatic int simple_config(struct pcmcia_device *link) 45062306a36Sopenharmony_ci{ 45162306a36Sopenharmony_ci struct serial_info *info = link->priv; 45262306a36Sopenharmony_ci int ret, try; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci /* 45562306a36Sopenharmony_ci * First pass: look for a config entry that looks normal. 45662306a36Sopenharmony_ci * Two tries: without IO aliases, then with aliases. 45762306a36Sopenharmony_ci */ 45862306a36Sopenharmony_ci link->config_flags |= CONF_AUTO_SET_VPP; 45962306a36Sopenharmony_ci for (try = 0; try < 4; try++) 46062306a36Sopenharmony_ci if (!pcmcia_loop_config(link, simple_config_check, &try)) 46162306a36Sopenharmony_ci goto found_port; 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci /* 46462306a36Sopenharmony_ci * Second pass: try to find an entry that isn't picky about 46562306a36Sopenharmony_ci * its base address, then try to grab any standard serial port 46662306a36Sopenharmony_ci * address, and finally try to get any free port. 46762306a36Sopenharmony_ci */ 46862306a36Sopenharmony_ci ret = pcmcia_loop_config(link, simple_config_check_notpicky, NULL); 46962306a36Sopenharmony_ci if (ret) { 47062306a36Sopenharmony_ci dev_warn(&link->dev, "no usable port range found, giving up\n"); 47162306a36Sopenharmony_ci return ret; 47262306a36Sopenharmony_ci } 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_cifound_port: 47562306a36Sopenharmony_ci if (info->multi && (info->manfid == MANFID_3COM)) 47662306a36Sopenharmony_ci link->config_index &= ~(0x08); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci /* 47962306a36Sopenharmony_ci * Apply any configuration quirks. 48062306a36Sopenharmony_ci */ 48162306a36Sopenharmony_ci if (info->quirk && info->quirk->config) 48262306a36Sopenharmony_ci info->quirk->config(link); 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci ret = pcmcia_enable_device(link); 48562306a36Sopenharmony_ci if (ret != 0) 48662306a36Sopenharmony_ci return ret; 48762306a36Sopenharmony_ci return setup_serial(link, info, link->resource[0]->start, link->irq); 48862306a36Sopenharmony_ci} 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_cistatic int multi_config_check(struct pcmcia_device *p_dev, void *priv_data) 49162306a36Sopenharmony_ci{ 49262306a36Sopenharmony_ci int *multi = priv_data; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci if (p_dev->resource[1]->end) 49562306a36Sopenharmony_ci return -EINVAL; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /* 49862306a36Sopenharmony_ci * The quad port cards have bad CIS's, so just look for a 49962306a36Sopenharmony_ci * window larger than 8 ports and assume it will be right. 50062306a36Sopenharmony_ci */ 50162306a36Sopenharmony_ci if (p_dev->resource[0]->end <= 8) 50262306a36Sopenharmony_ci return -EINVAL; 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 50562306a36Sopenharmony_ci p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 50662306a36Sopenharmony_ci p_dev->resource[0]->end = *multi * 8; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci if (pcmcia_request_io(p_dev)) 50962306a36Sopenharmony_ci return -ENODEV; 51062306a36Sopenharmony_ci return 0; 51162306a36Sopenharmony_ci} 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistatic int multi_config_check_notpicky(struct pcmcia_device *p_dev, 51462306a36Sopenharmony_ci void *priv_data) 51562306a36Sopenharmony_ci{ 51662306a36Sopenharmony_ci int *base2 = priv_data; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci if (!p_dev->resource[0]->end || !p_dev->resource[1]->end || 51962306a36Sopenharmony_ci p_dev->resource[0]->start + 8 != p_dev->resource[1]->start) 52062306a36Sopenharmony_ci return -ENODEV; 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci p_dev->resource[0]->end = p_dev->resource[1]->end = 8; 52362306a36Sopenharmony_ci p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; 52462306a36Sopenharmony_ci p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_ci if (pcmcia_request_io(p_dev)) 52762306a36Sopenharmony_ci return -ENODEV; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci *base2 = p_dev->resource[0]->start + 8; 53062306a36Sopenharmony_ci return 0; 53162306a36Sopenharmony_ci} 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_cistatic int multi_config(struct pcmcia_device *link) 53462306a36Sopenharmony_ci{ 53562306a36Sopenharmony_ci struct serial_info *info = link->priv; 53662306a36Sopenharmony_ci int i, base2 = 0; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci /* First, look for a generic full-sized window */ 53962306a36Sopenharmony_ci if (!pcmcia_loop_config(link, multi_config_check, &info->multi)) 54062306a36Sopenharmony_ci base2 = link->resource[0]->start + 8; 54162306a36Sopenharmony_ci else { 54262306a36Sopenharmony_ci /* If that didn't work, look for two windows */ 54362306a36Sopenharmony_ci info->multi = 2; 54462306a36Sopenharmony_ci if (pcmcia_loop_config(link, multi_config_check_notpicky, 54562306a36Sopenharmony_ci &base2)) { 54662306a36Sopenharmony_ci dev_warn(&link->dev, 54762306a36Sopenharmony_ci "no usable port range found, giving up\n"); 54862306a36Sopenharmony_ci return -ENODEV; 54962306a36Sopenharmony_ci } 55062306a36Sopenharmony_ci } 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (!link->irq) 55362306a36Sopenharmony_ci dev_warn(&link->dev, "no usable IRQ found, continuing...\n"); 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci /* 55662306a36Sopenharmony_ci * Apply any configuration quirks. 55762306a36Sopenharmony_ci */ 55862306a36Sopenharmony_ci if (info->quirk && info->quirk->config) 55962306a36Sopenharmony_ci info->quirk->config(link); 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci i = pcmcia_enable_device(link); 56262306a36Sopenharmony_ci if (i != 0) 56362306a36Sopenharmony_ci return -ENODEV; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 56662306a36Sopenharmony_ci * 8 registers are for the UART, the others are extra registers. 56762306a36Sopenharmony_ci * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. 56862306a36Sopenharmony_ci */ 56962306a36Sopenharmony_ci if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && 57062306a36Sopenharmony_ci info->prodid == PRODID_POSSIO_GCC)) { 57162306a36Sopenharmony_ci if (link->config_index == 1 || 57262306a36Sopenharmony_ci link->config_index == 3) { 57362306a36Sopenharmony_ci setup_serial(link, info, base2, link->irq); 57462306a36Sopenharmony_ci base2 = link->resource[0]->start; 57562306a36Sopenharmony_ci } else { 57662306a36Sopenharmony_ci setup_serial(link, info, link->resource[0]->start, 57762306a36Sopenharmony_ci link->irq); 57862306a36Sopenharmony_ci } 57962306a36Sopenharmony_ci info->c950ctrl = base2; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci /* 58262306a36Sopenharmony_ci * FIXME: We really should wake up the port prior to 58362306a36Sopenharmony_ci * handing it over to the serial layer. 58462306a36Sopenharmony_ci */ 58562306a36Sopenharmony_ci if (info->quirk && info->quirk->wakeup) 58662306a36Sopenharmony_ci info->quirk->wakeup(link); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ci return 0; 58962306a36Sopenharmony_ci } 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci setup_serial(link, info, link->resource[0]->start, link->irq); 59262306a36Sopenharmony_ci for (i = 0; i < info->multi - 1; i++) 59362306a36Sopenharmony_ci setup_serial(link, info, base2 + (8 * i), 59462306a36Sopenharmony_ci link->irq); 59562306a36Sopenharmony_ci return 0; 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic int serial_check_for_multi(struct pcmcia_device *p_dev, void *priv_data) 59962306a36Sopenharmony_ci{ 60062306a36Sopenharmony_ci struct serial_info *info = p_dev->priv; 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci if (!p_dev->resource[0]->end) 60362306a36Sopenharmony_ci return -EINVAL; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci if ((!p_dev->resource[1]->end) && (p_dev->resource[0]->end % 8 == 0)) 60662306a36Sopenharmony_ci info->multi = p_dev->resource[0]->end >> 3; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci if ((p_dev->resource[1]->end) && (p_dev->resource[0]->end == 8) 60962306a36Sopenharmony_ci && (p_dev->resource[1]->end == 8)) 61062306a36Sopenharmony_ci info->multi = 2; 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci return 0; /* break */ 61362306a36Sopenharmony_ci} 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic int serial_config(struct pcmcia_device *link) 61762306a36Sopenharmony_ci{ 61862306a36Sopenharmony_ci struct serial_info *info = link->priv; 61962306a36Sopenharmony_ci int i; 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci dev_dbg(&link->dev, "serial_config\n"); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_ci /* Is this a compliant multifunction card? */ 62462306a36Sopenharmony_ci info->multi = (link->socket->functions > 1); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci /* Is this a multiport card? */ 62762306a36Sopenharmony_ci info->manfid = link->manf_id; 62862306a36Sopenharmony_ci info->prodid = link->card_id; 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(quirks); i++) 63162306a36Sopenharmony_ci if ((quirks[i].manfid == ~0 || 63262306a36Sopenharmony_ci quirks[i].manfid == info->manfid) && 63362306a36Sopenharmony_ci (quirks[i].prodid == ~0 || 63462306a36Sopenharmony_ci quirks[i].prodid == info->prodid)) { 63562306a36Sopenharmony_ci info->quirk = &quirks[i]; 63662306a36Sopenharmony_ci break; 63762306a36Sopenharmony_ci } 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci /* 64062306a36Sopenharmony_ci * Another check for dual-serial cards: look for either serial or 64162306a36Sopenharmony_ci * multifunction cards that ask for appropriate IO port ranges. 64262306a36Sopenharmony_ci */ 64362306a36Sopenharmony_ci if ((info->multi == 0) && 64462306a36Sopenharmony_ci (link->has_func_id) && 64562306a36Sopenharmony_ci (link->socket->pcmcia_pfc == 0) && 64662306a36Sopenharmony_ci ((link->func_id == CISTPL_FUNCID_MULTI) || 64762306a36Sopenharmony_ci (link->func_id == CISTPL_FUNCID_SERIAL))) { 64862306a36Sopenharmony_ci if (pcmcia_loop_config(link, serial_check_for_multi, info)) 64962306a36Sopenharmony_ci goto failed; 65062306a36Sopenharmony_ci } 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci /* 65362306a36Sopenharmony_ci * Apply any multi-port quirk. 65462306a36Sopenharmony_ci */ 65562306a36Sopenharmony_ci if (info->quirk && info->quirk->multi != -1) 65662306a36Sopenharmony_ci info->multi = info->quirk->multi; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci dev_info(&link->dev, 65962306a36Sopenharmony_ci "trying to set up [0x%04x:0x%04x] (pfc: %d, multi: %d, quirk: %p)\n", 66062306a36Sopenharmony_ci link->manf_id, link->card_id, 66162306a36Sopenharmony_ci link->socket->pcmcia_pfc, info->multi, info->quirk); 66262306a36Sopenharmony_ci if (link->socket->pcmcia_pfc) 66362306a36Sopenharmony_ci i = pfc_config(link); 66462306a36Sopenharmony_ci else if (info->multi > 1) 66562306a36Sopenharmony_ci i = multi_config(link); 66662306a36Sopenharmony_ci else 66762306a36Sopenharmony_ci i = simple_config(link); 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci if (i || info->ndev == 0) 67062306a36Sopenharmony_ci goto failed; 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci /* 67362306a36Sopenharmony_ci * Apply any post-init quirk. FIXME: This should really happen 67462306a36Sopenharmony_ci * before we register the port, since it might already be in use. 67562306a36Sopenharmony_ci */ 67662306a36Sopenharmony_ci if (info->quirk && info->quirk->post) 67762306a36Sopenharmony_ci if (info->quirk->post(link)) 67862306a36Sopenharmony_ci goto failed; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci return 0; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_cifailed: 68362306a36Sopenharmony_ci dev_warn(&link->dev, "failed to initialize\n"); 68462306a36Sopenharmony_ci serial_remove(link); 68562306a36Sopenharmony_ci return -ENODEV; 68662306a36Sopenharmony_ci} 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_cistatic const struct pcmcia_device_id serial_ids[] = { 68962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021), 69062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), 69162306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a), 69262306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0d0a), 69362306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0x0e0a), 69462306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0105, 0xea15), 69562306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0109, 0x0501), 69662306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0138, 0x110a), 69762306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0140, 0x000a), 69862306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0x3341), 69962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0143, 0xc0ab), 70062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x016c, 0x0081), 70162306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x021b, 0x0101), 70262306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x08a1, 0xc0ab), 70362306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63), 70462306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "CC/XJEM3336", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x0143b773, 0x46a52d63), 70562306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "EM1144T", "PCMCIA MODEM", 0xf510db04, 0x856d66c8, 0xbd6c43ef), 70662306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID123(1, "MEGAHERTZ", "XJEM1144/CCEM1144", "PCMCIA MODEM", 0xf510db04, 0x52d21e1e, 0xbd6c43ef), 70762306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea), 70862306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM33", 0x2e3ee845, 0x80609023), 70962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "CEM56", 0x2e3ee845, 0xa650c32a), 71062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "REM10", 0x2e3ee845, 0x76df1d29), 71162306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID13(1, "Xircom", "XEM5600", 0x2e3ee845, 0xf1403719), 71262306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), 71362306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), 71462306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), 71562306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Gateway 2000", "XJEM3336", 0xdd9989be, 0x662c394c), 71662306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), 71762306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), 71862306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), 71962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "MEGAHERTZ", "XJEM1144/CCEM1144", 0xf510db04, 0x52d21e1e), 72062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), 72162306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "NEC", "PK-UG-J001", 0x18df0ba0, 0x831b1064), 72262306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Diamonds Modem+Ethernet", 0xc2f80cd, 0x656947b9), 72362306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Ositech", "Trumpcard:Jack of Hearts Modem+Ethernet", 0xc2f80cd, 0xdc9ba5ed), 72462306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), 72562306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), 72662306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed), 72762306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_PROD_ID12(1, "Xircom", "CreditCard Ethernet+Modem II", 0x2e3ee845, 0xeca401bf), 72862306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0e01), 72962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0a05), 73062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x0b05), 73162306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0032, 0x1101), 73262306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0104, 0x0070), 73362306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0101, 0x0562), 73462306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0104, 0x0070), 73562306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x016c, 0x0020), 73662306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID123(1, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f), 73762306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), 73862306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3), 73962306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15), 74062306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), 74162306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), 74262306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), 74362306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276), 74462306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), 74562306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), 74662306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0105, 0x0101), /* TDK DF2814 */ 74762306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0105, 0x100a), /* Xircom CM-56G */ 74862306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0105, 0x3e0a), /* TDK DF5660 */ 74962306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), 75062306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0107, 0x0002), /* USRobotics 14,400 */ 75162306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d50), 75262306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d51), 75362306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d52), 75462306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0d53), 75562306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x010b, 0xd180), 75662306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0115, 0x3330), /* USRobotics/SUN 14,400 */ 75762306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0124, 0x0100), /* Nokia DTP-2 ver II */ 75862306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0134, 0x5600), /* LASAT COMMUNICATIONS A/S */ 75962306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0137, 0x000e), 76062306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0137, 0x001b), 76162306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0025), 76262306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0045), 76362306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0052), 76462306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x016c, 0x0006), /* Psion 56K+Fax */ 76562306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0200, 0x0001), /* MultiMobile */ 76662306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID134("ADV", "TECH", "COMpad-32/85", 0x67459937, 0x916d02ba, 0x8fbe92ae), 76762306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID124("GATEWAY2000", "CC3144", "PCMCIA MODEM", 0x506bccae, 0xcb3685f1, 0xbd6c43ef), 76862306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), 76962306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), 77062306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), 77162306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e), 77262306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), 77362306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), 77462306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), 77562306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 28800 FAX/DATA MODEM", 0xa3a3062c, 0x8cbd7c76), 77662306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("COMPAQ", "PCMCIA 33600 FAX/DATA MODEM", 0xa3a3062c, 0x5a00ce95), 77762306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Computerboards, Inc.", "PCM-COM422", 0xd0b78f51, 0x7e2d49ed), 77862306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Dr. Neuhaus", "FURY CARD 14K4", 0x76942813, 0x8b96ce65), 77962306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("IBM", "ISDN/56K/GSM", 0xb569a6e5, 0xfee5297b), 78062306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Intelligent", "ANGIA FAX/MODEM", 0xb496e65e, 0xf31602a6), 78162306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Intel", "MODEM 2400+", 0x816cc815, 0x412729fb), 78262306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Intertex", "IX34-PCMCIA", 0xf8a097e3, 0x97880447), 78362306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("IOTech Inc ", "PCMCIA Dual RS-232 Serial Port Card", 0x3bd2d898, 0x92abc92f), 78462306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("MACRONIX", "FAX/MODEM", 0x668388b3, 0x3f9bdf2f), 78562306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT1432LT", 0x5f73be51, 0x0b3e2383), 78662306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Multi-Tech", "MT2834LT", 0x5f73be51, 0x4cd7c09e), 78762306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), 78862306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Option International", "V34bis GSM/PSTN Data/Fax Modem", 0x9d7cd6f5, 0x5cb8bf41), 78962306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Option International", "GSM-Ready 56K/ISDN", 0x9d7cd6f5, 0xb23844aa), 79062306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), 79162306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), 79262306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d), 79362306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Telia", "SurfinBird 560P/A+", 0xe2cdd5e, 0xc9314b38), 79462306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID1("Smart Serial Port", 0x2d8ce292), 79562306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), 79662306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), 79762306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), 79862306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), 79962306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), 80062306a36Sopenharmony_ci PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), 80162306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), 80262306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), 80362306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), 80462306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "cis/DP83903.cis"), 80562306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"), 80662306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"), 80762306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */ 80862306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC860", 0xd85f6206, 0x698f93db, "cis/SW_8xx_SER.cis"), /* Sierra Wireless AC860 3G Network Adapter R1 */ 80962306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC710/AC750", 0xd85f6206, 0x761b11e0, "cis/SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ 81062306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 81162306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "cis/SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 81262306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("MultiTech", "PCMCIA 56K DataFax", 0x842047ee, 0xc2efcf03, "cis/MT5634ZLX.cis"), 81362306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-2", 0x96913a85, 0x27ab5437, "cis/COMpad2.cis"), 81462306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID12("ADVANTECH", "COMpad-32/85B-4", 0x96913a85, 0xcec8f102, "cis/COMpad4.cis"), 81562306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID123("ADVANTECH", "COMpad-32/85", "1.0", 0x96913a85, 0x8fbe92ae, 0x0877b627, "cis/COMpad2.cis"), 81662306a36Sopenharmony_ci PCMCIA_DEVICE_CIS_PROD_ID2("RS-COM 2P", 0xad20b156, "cis/RS-COM-2P.cis"), 81762306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100 1.00.", 0x19ca78af, 0xf964f42b), 81862306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL100", 0x19ca78af, 0x71d98e83), 81962306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232 1.00.", 0x19ca78af, 0x69fb7490), 82062306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c1997.", "SERIAL CARD: SL232", 0x19ca78af, 0xb6bc0235), 82162306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.", "SERIAL CARD: CF232", 0x63f2e0bd, 0xb9e175d3), 82262306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("ELAN DIGITAL SYSTEMS LTD, c2000.", "SERIAL CARD: CF232-5", 0x63f2e0bd, 0xfce33442), 82362306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF232", 0x3beb8cf2, 0x171e7190), 82462306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF232-5", 0x3beb8cf2, 0x20da4262), 82562306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF428", 0x3beb8cf2, 0xea5dd57d), 82662306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: CF500", 0x3beb8cf2, 0xd77255fa), 82762306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: IC232", 0x3beb8cf2, 0x6a709903), 82862306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: SL232", 0x3beb8cf2, 0x18430676), 82962306a36Sopenharmony_ci PCMCIA_DEVICE_PROD_ID12("Elan", "Serial Port: XL232", 0x3beb8cf2, 0x6f933767), 83062306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: CF332", 0x3beb8cf2, 0x16dc1ba7), 83162306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL332", 0x3beb8cf2, 0x19816c41), 83262306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL385", 0x3beb8cf2, 0x64112029), 83362306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), 83462306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(0, "Elan", "Serial+Parallel Port: SP230", 0x3beb8cf2, 0xdb9e58bc), 83562306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: CF332", 0x3beb8cf2, 0x16dc1ba7), 83662306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL332", 0x3beb8cf2, 0x19816c41), 83762306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL385", 0x3beb8cf2, 0x64112029), 83862306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(1, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), 83962306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(2, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), 84062306a36Sopenharmony_ci PCMCIA_MFC_DEVICE_PROD_ID12(3, "Elan", "Serial Port: SL432", 0x3beb8cf2, 0x1cce7ac4), 84162306a36Sopenharmony_ci PCMCIA_DEVICE_MANF_CARD(0x0279, 0x950b), 84262306a36Sopenharmony_ci /* too generic */ 84362306a36Sopenharmony_ci /* PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0160, 0x0002), */ 84462306a36Sopenharmony_ci /* PCMCIA_MFC_DEVICE_MANF_CARD(1, 0x0160, 0x0002), */ 84562306a36Sopenharmony_ci PCMCIA_DEVICE_FUNC_ID(2), 84662306a36Sopenharmony_ci PCMCIA_DEVICE_NULL, 84762306a36Sopenharmony_ci}; 84862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pcmcia, serial_ids); 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ciMODULE_FIRMWARE("cis/PCMLM28.cis"); 85162306a36Sopenharmony_ciMODULE_FIRMWARE("cis/DP83903.cis"); 85262306a36Sopenharmony_ciMODULE_FIRMWARE("cis/3CCFEM556.cis"); 85362306a36Sopenharmony_ciMODULE_FIRMWARE("cis/3CXEM556.cis"); 85462306a36Sopenharmony_ciMODULE_FIRMWARE("cis/SW_8xx_SER.cis"); 85562306a36Sopenharmony_ciMODULE_FIRMWARE("cis/SW_7xx_SER.cis"); 85662306a36Sopenharmony_ciMODULE_FIRMWARE("cis/SW_555_SER.cis"); 85762306a36Sopenharmony_ciMODULE_FIRMWARE("cis/MT5634ZLX.cis"); 85862306a36Sopenharmony_ciMODULE_FIRMWARE("cis/COMpad2.cis"); 85962306a36Sopenharmony_ciMODULE_FIRMWARE("cis/COMpad4.cis"); 86062306a36Sopenharmony_ciMODULE_FIRMWARE("cis/RS-COM-2P.cis"); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_cistatic struct pcmcia_driver serial_cs_driver = { 86362306a36Sopenharmony_ci .owner = THIS_MODULE, 86462306a36Sopenharmony_ci .name = "serial_cs", 86562306a36Sopenharmony_ci .probe = serial_probe, 86662306a36Sopenharmony_ci .remove = serial_detach, 86762306a36Sopenharmony_ci .id_table = serial_ids, 86862306a36Sopenharmony_ci .suspend = serial_suspend, 86962306a36Sopenharmony_ci .resume = serial_resume, 87062306a36Sopenharmony_ci}; 87162306a36Sopenharmony_cimodule_pcmcia_driver(serial_cs_driver); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 874