From: Jeff Kirsher Date: Tue, 23 Aug 2011 00:37:03 +0000 (-0700) Subject: ixbmtr_cs: Move the IBM PCMCIA Token Ring driver X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=c0153225a0e86013b8b8267ffd94e5484d83b916;p=~shefty%2Frdma-dev.git ixbmtr_cs: Move the IBM PCMCIA Token Ring driver Move the IBM PCMCIA Token Ring driver into drivers/net/tokenring/ with the other Token Ring drivers. Made the necessary Kconfig and Makefile changes as well. CC: Mike Phillips CC: Burt Silverman Signed-off-by: Jeff Kirsher --- diff --git a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig index 12e7ae47c06..ff4deb0ace4 100644 --- a/drivers/net/pcmcia/Kconfig +++ b/drivers/net/pcmcia/Kconfig @@ -31,15 +31,4 @@ config ARCNET_COM20020_CS To compile this driver as a module, choose M here: the module will be called com20020_cs. If unsure, say N. -config PCMCIA_IBMTR - tristate "IBM PCMCIA tokenring adapter support" - depends on IBMTR!=y && TR - help - Say Y here if you intend to attach this type of Token Ring PCMCIA - card to your computer. You then also need to say Y to "Token Ring - driver support". - - To compile this driver as a module, choose M here: the module will be - called ibmtr_cs. - endif # NET_PCMCIA diff --git a/drivers/net/pcmcia/Makefile b/drivers/net/pcmcia/Makefile index 618e81667ca..b98a0a4753f 100644 --- a/drivers/net/pcmcia/Makefile +++ b/drivers/net/pcmcia/Makefile @@ -4,5 +4,3 @@ # 16-bit client drivers obj-$(CONFIG_ARCNET_COM20020_CS)+= com20020_cs.o - -obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c deleted file mode 100644 index 6006d5488fb..00000000000 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ /dev/null @@ -1,371 +0,0 @@ -/*====================================================================== - - A PCMCIA token-ring driver for IBM-based cards - - This driver supports the IBM PCMCIA Token-Ring Card. - Written by Steve Kipisz, kipisz@vnet.ibm.com or - bungy@ibm.net - - Written 1995,1996. - - This code is based on pcnet_cs.c from David Hinds. - - V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com - - Linux V2.2.x presented significant changes to the underlying - ibmtr.c code. Mainly the code became a lot more organized and - modular. - - This caused the old PCMCIA Token Ring driver to give up and go - home early. Instead of just patching the old code to make it - work, the PCMCIA code has been streamlined, updated and possibly - improved. - - This code now only contains code required for the Card Services. - All we do here is set the card up enough so that the real ibmtr.c - driver can find it and work with it properly. - - i.e. We set up the io port, irq, mmio memory and shared ram - memory. This enables ibmtr_probe in ibmtr.c to find the card and - configure it as though it was a normal ISA and/or PnP card. - - CHANGES - - v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com) - Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c - - v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com) - Updated to version 2.2.7 to match the first version of the kernel - that the modification to ibmtr.c were incorporated into. - - v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com) - Address translation feature of PCMCIA controller is usable so - memory windows can be placed in High memory (meaning above - 0xFFFFF.) - -======================================================================*/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#define PCMCIA -#include "../tokenring/ibmtr.c" - - -/*====================================================================*/ - -/* Parameters that can be set with 'insmod' */ - -/* MMIO base address */ -static u_long mmiobase = 0xce000; - -/* SRAM base address */ -static u_long srambase = 0xd0000; - -/* SRAM size 8,16,32,64 */ -static u_long sramsize = 64; - -/* Ringspeed 4,16 */ -static int ringspeed = 16; - -module_param(mmiobase, ulong, 0); -module_param(srambase, ulong, 0); -module_param(sramsize, ulong, 0); -module_param(ringspeed, int, 0); -MODULE_LICENSE("GPL"); - -/*====================================================================*/ - -static int ibmtr_config(struct pcmcia_device *link); -static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); -static void ibmtr_release(struct pcmcia_device *link); -static void ibmtr_detach(struct pcmcia_device *p_dev); - -/*====================================================================*/ - -typedef struct ibmtr_dev_t { - struct pcmcia_device *p_dev; - struct net_device *dev; - struct tok_info *ti; -} ibmtr_dev_t; - -static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { - ibmtr_dev_t *info = dev_id; - struct net_device *dev = info->dev; - return tok_interrupt(irq, dev); -}; - -static int __devinit ibmtr_attach(struct pcmcia_device *link) -{ - ibmtr_dev_t *info; - struct net_device *dev; - - dev_dbg(&link->dev, "ibmtr_attach()\n"); - - /* Create new token-ring device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) return -ENOMEM; - dev = alloc_trdev(sizeof(struct tok_info)); - if (!dev) { - kfree(info); - return -ENOMEM; - } - - info->p_dev = link; - link->priv = info; - info->ti = netdev_priv(dev); - - link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; - link->resource[0]->end = 4; - link->config_flags |= CONF_ENABLE_IRQ; - link->config_regs = PRESENT_OPTION; - - info->dev = dev; - - return ibmtr_config(link); -} /* ibmtr_attach */ - -static void ibmtr_detach(struct pcmcia_device *link) -{ - struct ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - struct tok_info *ti = netdev_priv(dev); - - dev_dbg(&link->dev, "ibmtr_detach\n"); - - /* - * When the card removal interrupt hits tok_interrupt(), - * bail out early, so we don't crash the machine - */ - ti->sram_phys |= 1; - - unregister_netdev(dev); - - del_timer_sync(&(ti->tr_timer)); - - ibmtr_release(link); - - free_netdev(dev); - kfree(info); -} /* ibmtr_detach */ - -static int __devinit ibmtr_config(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - struct tok_info *ti = netdev_priv(dev); - int i, ret; - - dev_dbg(&link->dev, "ibmtr_config\n"); - - link->io_lines = 16; - link->config_index = 0x61; - - /* Determine if this is PRIMARY or ALTERNATE. */ - - /* Try PRIMARY card at 0xA20-0xA23 */ - link->resource[0]->start = 0xA20; - i = pcmcia_request_io(link); - if (i != 0) { - /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ - link->resource[0]->start = 0xA24; - ret = pcmcia_request_io(link); - if (ret) - goto failed; - } - dev->base_addr = link->resource[0]->start; - - ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); - if (ret) - goto failed; - dev->irq = link->irq; - ti->irq = link->irq; - ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); - - /* Allocate the MMIO memory window */ - link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; - link->resource[2]->flags |= WIN_USE_WAIT; - link->resource[2]->start = 0; - link->resource[2]->end = 0x2000; - ret = pcmcia_request_window(link, link->resource[2], 250); - if (ret) - goto failed; - - ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase); - if (ret) - goto failed; - ti->mmio = ioremap(link->resource[2]->start, - resource_size(link->resource[2])); - - /* Allocate the SRAM memory window */ - link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; - link->resource[3]->flags |= WIN_USE_WAIT; - link->resource[3]->start = 0; - link->resource[3]->end = sramsize * 1024; - ret = pcmcia_request_window(link, link->resource[3], 250); - if (ret) - goto failed; - - ret = pcmcia_map_mem_page(link, link->resource[3], srambase); - if (ret) - goto failed; - - ti->sram_base = srambase >> 12; - ti->sram_virt = ioremap(link->resource[3]->start, - resource_size(link->resource[3])); - ti->sram_phys = link->resource[3]->start; - - ret = pcmcia_enable_device(link); - if (ret) - goto failed; - - /* Set up the Token-Ring Controller Configuration Register and - turn on the card. Check the "Local Area Network Credit Card - Adapters Technical Reference" SC30-3585 for this info. */ - ibmtr_hw_setup(dev, mmiobase); - - SET_NETDEV_DEV(dev, &link->dev); - - i = ibmtr_probe_card(dev); - if (i != 0) { - pr_notice("register_netdev() failed\n"); - goto failed; - } - - netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", - dev->base_addr, dev->irq, - (u_long)ti->mmio, (u_long)(ti->sram_base << 12), - dev->dev_addr); - return 0; - -failed: - ibmtr_release(link); - return -ENODEV; -} /* ibmtr_config */ - -static void ibmtr_release(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - dev_dbg(&link->dev, "ibmtr_release\n"); - - if (link->resource[2]->end) { - struct tok_info *ti = netdev_priv(dev); - iounmap(ti->mmio); - } - pcmcia_disable_device(link); -} - -static int ibmtr_suspend(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - if (link->open) - netif_device_detach(dev); - - return 0; -} - -static int __devinit ibmtr_resume(struct pcmcia_device *link) -{ - ibmtr_dev_t *info = link->priv; - struct net_device *dev = info->dev; - - if (link->open) { - ibmtr_probe(dev); /* really? */ - netif_device_attach(dev); - } - - return 0; -} - - -/*====================================================================*/ - -static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase) -{ - int i; - - /* Bizarre IBM behavior, there are 16 bits of information we - need to set, but the card only allows us to send 4 bits at a - time. For each byte sent to base_addr, bits 7-4 tell the - card which part of the 16 bits we are setting, bits 3-0 contain - the actual information */ - - /* First nibble provides 4 bits of mmio */ - i = (mmiobase >> 16) & 0x0F; - outb(i, dev->base_addr); - - /* Second nibble provides 3 bits of mmio */ - i = 0x10 | ((mmiobase >> 12) & 0x0E); - outb(i, dev->base_addr); - - /* Third nibble, hard-coded values */ - i = 0x26; - outb(i, dev->base_addr); - - /* Fourth nibble sets shared ram page size */ - - /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */ - i = (sramsize >> 4) & 0x07; - i = ((i == 4) ? 3 : i) << 2; - i |= 0x30; - - if (ringspeed == 16) - i |= 2; - if (dev->base_addr == 0xA24) - i |= 1; - outb(i, dev->base_addr); - - /* 0x40 will release the card for use */ - outb(0x40, dev->base_addr); -} - -static const struct pcmcia_device_id ibmtr_ids[] = { - PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e), - PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47), - PCMCIA_DEVICE_NULL, -}; -MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids); - -static struct pcmcia_driver ibmtr_cs_driver = { - .owner = THIS_MODULE, - .name = "ibmtr_cs", - .probe = ibmtr_attach, - .remove = ibmtr_detach, - .id_table = ibmtr_ids, - .suspend = ibmtr_suspend, - .resume = ibmtr_resume, -}; - -static int __init init_ibmtr_cs(void) -{ - return pcmcia_register_driver(&ibmtr_cs_driver); -} - -static void __exit exit_ibmtr_cs(void) -{ - pcmcia_unregister_driver(&ibmtr_cs_driver); -} - -module_init(init_ibmtr_cs); -module_exit(exit_ibmtr_cs); diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index c4137b0f808..0f701588c7e 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig @@ -6,7 +6,7 @@ menuconfig TR tristate "Token Ring driver support" depends on NETDEVICES && !UML - depends on (PCI || ISA || MCA || CCW) + depends on (PCI || ISA || MCA || CCW || PCMCIA) select LLC help Token Ring is IBM's way of communication on a local network; the @@ -20,6 +20,17 @@ menuconfig TR if TR +config PCMCIA_IBMTR + tristate "IBM PCMCIA tokenring adapter support" + depends on IBMTR!=y && PCMCIA + ---help--- + Say Y here if you intend to attach this type of Token Ring PCMCIA + card to your computer. You then also need to say Y to "Token Ring + driver support". + + To compile this driver as a module, choose M here: the module will be + called ibmtr_cs. + config IBMTR tristate "IBM Tropic chipset based adapter support" depends on ISA || MCA diff --git a/drivers/net/tokenring/Makefile b/drivers/net/tokenring/Makefile index c88b0a5e538..f1be8d97b7a 100644 --- a/drivers/net/tokenring/Makefile +++ b/drivers/net/tokenring/Makefile @@ -2,14 +2,15 @@ # Makefile for drivers/net/tokenring # -obj-$(CONFIG_IBMTR) += ibmtr.o -obj-$(CONFIG_IBMOL) += olympic.o -obj-$(CONFIG_IBMLS) += lanstreamer.o -obj-$(CONFIG_TMS380TR) += tms380tr.o -obj-$(CONFIG_ABYSS) += abyss.o -obj-$(CONFIG_MADGEMC) += madgemc.o -obj-$(CONFIG_PROTEON) += proteon.o -obj-$(CONFIG_TMSPCI) += tmspci.o -obj-$(CONFIG_SKISA) += skisa.o -obj-$(CONFIG_SMCTR) += smctr.o +obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o +obj-$(CONFIG_IBMTR) += ibmtr.o +obj-$(CONFIG_IBMOL) += olympic.o +obj-$(CONFIG_IBMLS) += lanstreamer.o +obj-$(CONFIG_TMS380TR) += tms380tr.o +obj-$(CONFIG_ABYSS) += abyss.o +obj-$(CONFIG_MADGEMC) += madgemc.o +obj-$(CONFIG_PROTEON) += proteon.o +obj-$(CONFIG_TMSPCI) += tmspci.o +obj-$(CONFIG_SKISA) += skisa.o +obj-$(CONFIG_SMCTR) += smctr.o obj-$(CONFIG_3C359) += 3c359.o diff --git a/drivers/net/tokenring/ibmtr_cs.c b/drivers/net/tokenring/ibmtr_cs.c new file mode 100644 index 00000000000..91b684630fc --- /dev/null +++ b/drivers/net/tokenring/ibmtr_cs.c @@ -0,0 +1,371 @@ +/*====================================================================== + + A PCMCIA token-ring driver for IBM-based cards + + This driver supports the IBM PCMCIA Token-Ring Card. + Written by Steve Kipisz, kipisz@vnet.ibm.com or + bungy@ibm.net + + Written 1995,1996. + + This code is based on pcnet_cs.c from David Hinds. + + V2.2.0 February 1999 - Mike Phillips phillim@amtrak.com + + Linux V2.2.x presented significant changes to the underlying + ibmtr.c code. Mainly the code became a lot more organized and + modular. + + This caused the old PCMCIA Token Ring driver to give up and go + home early. Instead of just patching the old code to make it + work, the PCMCIA code has been streamlined, updated and possibly + improved. + + This code now only contains code required for the Card Services. + All we do here is set the card up enough so that the real ibmtr.c + driver can find it and work with it properly. + + i.e. We set up the io port, irq, mmio memory and shared ram + memory. This enables ibmtr_probe in ibmtr.c to find the card and + configure it as though it was a normal ISA and/or PnP card. + + CHANGES + + v2.2.5 April 1999 Mike Phillips (phillim@amtrak.com) + Obscure bug fix, required changed to ibmtr.c not ibmtr_cs.c + + v2.2.7 May 1999 Mike Phillips (phillim@amtrak.com) + Updated to version 2.2.7 to match the first version of the kernel + that the modification to ibmtr.c were incorporated into. + + v2.2.17 July 2000 Burt Silverman (burts@us.ibm.com) + Address translation feature of PCMCIA controller is usable so + memory windows can be placed in High memory (meaning above + 0xFFFFF.) + +======================================================================*/ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define PCMCIA +#include "ibmtr.c" + + +/*====================================================================*/ + +/* Parameters that can be set with 'insmod' */ + +/* MMIO base address */ +static u_long mmiobase = 0xce000; + +/* SRAM base address */ +static u_long srambase = 0xd0000; + +/* SRAM size 8,16,32,64 */ +static u_long sramsize = 64; + +/* Ringspeed 4,16 */ +static int ringspeed = 16; + +module_param(mmiobase, ulong, 0); +module_param(srambase, ulong, 0); +module_param(sramsize, ulong, 0); +module_param(ringspeed, int, 0); +MODULE_LICENSE("GPL"); + +/*====================================================================*/ + +static int ibmtr_config(struct pcmcia_device *link); +static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase); +static void ibmtr_release(struct pcmcia_device *link); +static void ibmtr_detach(struct pcmcia_device *p_dev); + +/*====================================================================*/ + +typedef struct ibmtr_dev_t { + struct pcmcia_device *p_dev; + struct net_device *dev; + struct tok_info *ti; +} ibmtr_dev_t; + +static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { + ibmtr_dev_t *info = dev_id; + struct net_device *dev = info->dev; + return tok_interrupt(irq, dev); +}; + +static int __devinit ibmtr_attach(struct pcmcia_device *link) +{ + ibmtr_dev_t *info; + struct net_device *dev; + + dev_dbg(&link->dev, "ibmtr_attach()\n"); + + /* Create new token-ring device */ + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) return -ENOMEM; + dev = alloc_trdev(sizeof(struct tok_info)); + if (!dev) { + kfree(info); + return -ENOMEM; + } + + info->p_dev = link; + link->priv = info; + info->ti = netdev_priv(dev); + + link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; + link->resource[0]->end = 4; + link->config_flags |= CONF_ENABLE_IRQ; + link->config_regs = PRESENT_OPTION; + + info->dev = dev; + + return ibmtr_config(link); +} /* ibmtr_attach */ + +static void ibmtr_detach(struct pcmcia_device *link) +{ + struct ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + struct tok_info *ti = netdev_priv(dev); + + dev_dbg(&link->dev, "ibmtr_detach\n"); + + /* + * When the card removal interrupt hits tok_interrupt(), + * bail out early, so we don't crash the machine + */ + ti->sram_phys |= 1; + + unregister_netdev(dev); + + del_timer_sync(&(ti->tr_timer)); + + ibmtr_release(link); + + free_netdev(dev); + kfree(info); +} /* ibmtr_detach */ + +static int __devinit ibmtr_config(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + struct tok_info *ti = netdev_priv(dev); + int i, ret; + + dev_dbg(&link->dev, "ibmtr_config\n"); + + link->io_lines = 16; + link->config_index = 0x61; + + /* Determine if this is PRIMARY or ALTERNATE. */ + + /* Try PRIMARY card at 0xA20-0xA23 */ + link->resource[0]->start = 0xA20; + i = pcmcia_request_io(link); + if (i != 0) { + /* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */ + link->resource[0]->start = 0xA24; + ret = pcmcia_request_io(link); + if (ret) + goto failed; + } + dev->base_addr = link->resource[0]->start; + + ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt); + if (ret) + goto failed; + dev->irq = link->irq; + ti->irq = link->irq; + ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq); + + /* Allocate the MMIO memory window */ + link->resource[2]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; + link->resource[2]->flags |= WIN_USE_WAIT; + link->resource[2]->start = 0; + link->resource[2]->end = 0x2000; + ret = pcmcia_request_window(link, link->resource[2], 250); + if (ret) + goto failed; + + ret = pcmcia_map_mem_page(link, link->resource[2], mmiobase); + if (ret) + goto failed; + ti->mmio = ioremap(link->resource[2]->start, + resource_size(link->resource[2])); + + /* Allocate the SRAM memory window */ + link->resource[3]->flags = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; + link->resource[3]->flags |= WIN_USE_WAIT; + link->resource[3]->start = 0; + link->resource[3]->end = sramsize * 1024; + ret = pcmcia_request_window(link, link->resource[3], 250); + if (ret) + goto failed; + + ret = pcmcia_map_mem_page(link, link->resource[3], srambase); + if (ret) + goto failed; + + ti->sram_base = srambase >> 12; + ti->sram_virt = ioremap(link->resource[3]->start, + resource_size(link->resource[3])); + ti->sram_phys = link->resource[3]->start; + + ret = pcmcia_enable_device(link); + if (ret) + goto failed; + + /* Set up the Token-Ring Controller Configuration Register and + turn on the card. Check the "Local Area Network Credit Card + Adapters Technical Reference" SC30-3585 for this info. */ + ibmtr_hw_setup(dev, mmiobase); + + SET_NETDEV_DEV(dev, &link->dev); + + i = ibmtr_probe_card(dev); + if (i != 0) { + pr_notice("register_netdev() failed\n"); + goto failed; + } + + netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", + dev->base_addr, dev->irq, + (u_long)ti->mmio, (u_long)(ti->sram_base << 12), + dev->dev_addr); + return 0; + +failed: + ibmtr_release(link); + return -ENODEV; +} /* ibmtr_config */ + +static void ibmtr_release(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + dev_dbg(&link->dev, "ibmtr_release\n"); + + if (link->resource[2]->end) { + struct tok_info *ti = netdev_priv(dev); + iounmap(ti->mmio); + } + pcmcia_disable_device(link); +} + +static int ibmtr_suspend(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + if (link->open) + netif_device_detach(dev); + + return 0; +} + +static int __devinit ibmtr_resume(struct pcmcia_device *link) +{ + ibmtr_dev_t *info = link->priv; + struct net_device *dev = info->dev; + + if (link->open) { + ibmtr_probe(dev); /* really? */ + netif_device_attach(dev); + } + + return 0; +} + + +/*====================================================================*/ + +static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase) +{ + int i; + + /* Bizarre IBM behavior, there are 16 bits of information we + need to set, but the card only allows us to send 4 bits at a + time. For each byte sent to base_addr, bits 7-4 tell the + card which part of the 16 bits we are setting, bits 3-0 contain + the actual information */ + + /* First nibble provides 4 bits of mmio */ + i = (mmiobase >> 16) & 0x0F; + outb(i, dev->base_addr); + + /* Second nibble provides 3 bits of mmio */ + i = 0x10 | ((mmiobase >> 12) & 0x0E); + outb(i, dev->base_addr); + + /* Third nibble, hard-coded values */ + i = 0x26; + outb(i, dev->base_addr); + + /* Fourth nibble sets shared ram page size */ + + /* 8 = 00, 16 = 01, 32 = 10, 64 = 11 */ + i = (sramsize >> 4) & 0x07; + i = ((i == 4) ? 3 : i) << 2; + i |= 0x30; + + if (ringspeed == 16) + i |= 2; + if (dev->base_addr == 0xA24) + i |= 1; + outb(i, dev->base_addr); + + /* 0x40 will release the card for use */ + outb(0x40, dev->base_addr); +} + +static const struct pcmcia_device_id ibmtr_ids[] = { + PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e), + PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47), + PCMCIA_DEVICE_NULL, +}; +MODULE_DEVICE_TABLE(pcmcia, ibmtr_ids); + +static struct pcmcia_driver ibmtr_cs_driver = { + .owner = THIS_MODULE, + .name = "ibmtr_cs", + .probe = ibmtr_attach, + .remove = ibmtr_detach, + .id_table = ibmtr_ids, + .suspend = ibmtr_suspend, + .resume = ibmtr_resume, +}; + +static int __init init_ibmtr_cs(void) +{ + return pcmcia_register_driver(&ibmtr_cs_driver); +} + +static void __exit exit_ibmtr_cs(void) +{ + pcmcia_unregister_driver(&ibmtr_cs_driver); +} + +module_init(init_ibmtr_cs); +module_exit(exit_ibmtr_cs);