X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fpcmcia%2Fsmc91c92_cs.c;fp=drivers%2Fnet%2Fpcmcia%2Fsmc91c92_cs.c;h=0122415dfeefaf344f9b0e7aae3f4dfc06f7fa77;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=a73d54553030d65b7caaa37b5c4cb29ea4a03f75;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index a73d54553..0122415df 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -60,7 +59,7 @@ /*====================================================================*/ -static const char *if_names[] = { "auto", "10baseT", "10base2"}; +static char *if_names[] = { "auto", "10baseT", "10base2"}; /* Module parameters */ @@ -104,7 +103,7 @@ static const char *version = #define MEMORY_WAIT_TIME 8 struct smc_private { - struct pcmcia_device *p_dev; + dev_link_t link; spinlock_t lock; u_short manfid; u_short cardid; @@ -279,8 +278,8 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002, /*====================================================================*/ static void smc91c92_detach(struct pcmcia_device *p_dev); -static int smc91c92_config(struct pcmcia_device *link); -static void smc91c92_release(struct pcmcia_device *link); +static void smc91c92_config(dev_link_t *link); +static void smc91c92_release(dev_link_t *link); static int smc_open(struct net_device *dev); static int smc_close(struct net_device *dev); @@ -309,9 +308,10 @@ static struct ethtool_ops ethtool_ops; ======================================================================*/ -static int smc91c92_probe(struct pcmcia_device *link) +static int smc91c92_attach(struct pcmcia_device *p_dev) { struct smc_private *smc; + dev_link_t *link; struct net_device *dev; DEBUG(0, "smc91c92_attach()\n"); @@ -321,7 +321,7 @@ static int smc91c92_probe(struct pcmcia_device *link) if (!dev) return -ENOMEM; smc = netdev_priv(dev); - smc->p_dev = link; + link = &smc->link; link->priv = dev; spin_lock_init(&smc->lock); @@ -333,6 +333,7 @@ static int smc91c92_probe(struct pcmcia_device *link) link->irq.Handler = &smc_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; + link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; /* The SMC91c92-specific entries in the device structure. */ @@ -356,7 +357,13 @@ static int smc91c92_probe(struct pcmcia_device *link) smc->mii_if.phy_id_mask = 0x1f; smc->mii_if.reg_num_mask = 0x1f; - return smc91c92_config(link); + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + smc91c92_config(link); + + return 0; } /* smc91c92_attach */ /*====================================================================== @@ -368,16 +375,18 @@ static int smc91c92_probe(struct pcmcia_device *link) ======================================================================*/ -static void smc91c92_detach(struct pcmcia_device *link) +static void smc91c92_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; DEBUG(0, "smc91c92_detach(0x%p)\n", link); - if (link->dev_node) + if (link->dev) unregister_netdev(dev); - smc91c92_release(link); + if (link->state & DEV_CONFIG) + smc91c92_release(link); free_netdev(dev); } /* smc91c92_detach */ @@ -405,7 +414,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s) /*====================================================================*/ -static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int first_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -416,7 +425,7 @@ static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple, return pcmcia_parse_tuple(handle, tuple, parse); } -static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, +static int next_tuple(client_handle_t handle, tuple_t *tuple, cisparse_t *parse) { int i; @@ -438,7 +447,7 @@ static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple, ======================================================================*/ -static int mhz_3288_power(struct pcmcia_device *link) +static int mhz_3288_power(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -460,7 +469,7 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } -static int mhz_mfc_config(struct pcmcia_device *link) +static int mhz_mfc_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -495,7 +504,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - i = first_tuple(link, tuple, parse); + i = first_tuple(link->handle, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ while (i == CS_SUCCESS) { @@ -504,11 +513,11 @@ static int mhz_mfc_config(struct pcmcia_device *link) for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; link->io.BasePort1 = k ^ 0x300; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i == CS_SUCCESS) break; - i = next_tuple(link, tuple, parse); + i = next_tuple(link->handle, tuple, parse); } if (i != CS_SUCCESS) goto free_cfg_mem; @@ -518,7 +527,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; req.Base = req.Size = 0; req.AccessSpeed = 0; - i = pcmcia_request_window(&link, &req, &link->win); + i = pcmcia_request_window(&link->handle, &req, &link->win); if (i != CS_SUCCESS) goto free_cfg_mem; smc->base = ioremap(req.Base, req.Size); @@ -537,8 +546,9 @@ free_cfg_mem: return i; } -static int mhz_setup(struct pcmcia_device *link) +static int mhz_setup(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -561,13 +571,13 @@ static int mhz_setup(struct pcmcia_device *link) /* Read the station address from the CIS. It is stored as the last (fourth) string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } /* Ugh -- the EM1144 card has two VERS_1 tuples!?! */ - if (next_tuple(link, tuple, parse) != CS_SUCCESS) - first_tuple(link, tuple, parse); + if (next_tuple(handle, tuple, parse) != CS_SUCCESS) + first_tuple(handle, tuple, parse); if (parse->version_1.ns > 3) { station_addr = parse->version_1.str + parse->version_1.ofs[3]; if (cvt_ascii_address(dev, station_addr) == 0) { @@ -578,11 +588,11 @@ static int mhz_setup(struct pcmcia_device *link) /* Another possibility: for the EM3288, in a special tuple */ tuple->DesiredTuple = 0x81; - if (pcmcia_get_first_tuple(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_first_tuple(handle, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } - if (pcmcia_get_tuple_data(link, tuple) != CS_SUCCESS) { + if (pcmcia_get_tuple_data(handle, tuple) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -606,7 +616,7 @@ free_cfg_mem: ======================================================================*/ -static void mot_config(struct pcmcia_device *link) +static void mot_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); @@ -627,7 +637,7 @@ static void mot_config(struct pcmcia_device *link) mdelay(100); } -static int mot_setup(struct pcmcia_device *link) +static int mot_setup(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -661,7 +671,7 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ -static int smc_config(struct pcmcia_device *link) +static int smc_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; @@ -686,16 +696,16 @@ static int smc_config(struct pcmcia_device *link) tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; link->io.NumPorts1 = 16; - i = first_tuple(link, tuple, parse); + i = first_tuple(link->handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } - i = next_tuple(link, tuple, parse); + i = next_tuple(link->handle, tuple, parse); } if (i == CS_SUCCESS) dev->base_addr = link->io.BasePort1; @@ -704,8 +714,9 @@ static int smc_config(struct pcmcia_device *link) return i; } -static int smc_setup(struct pcmcia_device *link) +static int smc_setup(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -728,11 +739,11 @@ static int smc_setup(struct pcmcia_device *link) /* Check for a LAN function extension tuple */ tuple->DesiredTuple = CISTPL_FUNCE; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); while (i == CS_SUCCESS) { if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID) break; - i = next_tuple(link, tuple, parse); + i = next_tuple(handle, tuple, parse); } if (i == CS_SUCCESS) { node_id = (cistpl_lan_node_id_t *)parse->funce.data; @@ -745,7 +756,7 @@ static int smc_setup(struct pcmcia_device *link) } /* Try the third string in the Version 1 Version/ID tuple. */ tuple->DesiredTuple = CISTPL_VERS_1; - if (first_tuple(link, tuple, parse) != CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) != CS_SUCCESS) { rc = -1; goto free_cfg_mem; } @@ -763,10 +774,10 @@ free_cfg_mem: /*====================================================================*/ -static int osi_config(struct pcmcia_device *link) +static int osi_config(dev_link_t *link) { struct net_device *dev = link->priv; - static const kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; + static kio_addr_t com[4] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; int i, j; link->conf.Attributes |= CONF_ENABLE_SPKR; @@ -783,21 +794,22 @@ static int osi_config(struct pcmcia_device *link) for (i = j = 0; j < 4; j++) { link->io.BasePort2 = com[j]; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { /* Fallback: turn off hard decode */ link->conf.ConfigIndex = 0x03; link->io.NumPorts2 = 0; - i = pcmcia_request_io(link, &link->io); + i = pcmcia_request_io(link->handle, &link->io); } dev->base_addr = link->io.BasePort1 + 0x10; return i; } -static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) +static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; @@ -818,12 +830,12 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid) /* Read the station address from tuple 0x90, subtuple 0x04 */ tuple->DesiredTuple = 0x90; - i = pcmcia_get_first_tuple(link, tuple); + i = pcmcia_get_first_tuple(handle, tuple); while (i == CS_SUCCESS) { - i = pcmcia_get_tuple_data(link, tuple); + i = pcmcia_get_tuple_data(handle, tuple); if ((i != CS_SUCCESS) || (buf[0] == 0x04)) break; - i = pcmcia_get_next_tuple(link, tuple); + i = pcmcia_get_next_tuple(handle, tuple); } if (i != CS_SUCCESS) { rc = -1; @@ -856,46 +868,56 @@ free_cfg_mem: return rc; } -static int smc91c92_suspend(struct pcmcia_device *link) +static int smc91c92_suspend(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - if (link->open) - netif_device_detach(dev); + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } return 0; } -static int smc91c92_resume(struct pcmcia_device *link) +static int smc91c92_resume(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); int i; - if ((smc->manfid == MANFID_MEGAHERTZ) && - (smc->cardid == PRODID_MEGAHERTZ_EM3288)) - mhz_3288_power(link); - if (smc->manfid == MANFID_MOTOROLA) - mot_config(link); - if ((smc->manfid == MANFID_OSITECH) && - (smc->cardid != PRODID_OSITECH_SEVEN)) { - /* Power up the card and enable interrupts */ - set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); - set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); - } - if (((smc->manfid == MANFID_OSITECH) && - (smc->cardid == PRODID_OSITECH_SEVEN)) || - ((smc->manfid == MANFID_PSION) && - (smc->cardid == PRODID_PSION_NET100))) { - /* Download the Seven of Diamonds firmware */ - for (i = 0; i < sizeof(__Xilinx7OD); i++) { - outb(__Xilinx7OD[i], link->io.BasePort1+2); - udelay(50); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if ((smc->manfid == MANFID_MEGAHERTZ) && + (smc->cardid == PRODID_MEGAHERTZ_EM3288)) + mhz_3288_power(link); + pcmcia_request_configuration(link->handle, &link->conf); + if (smc->manfid == MANFID_MOTOROLA) + mot_config(link); + if ((smc->manfid == MANFID_OSITECH) && + (smc->cardid != PRODID_OSITECH_SEVEN)) { + /* Power up the card and enable interrupts */ + set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR); + set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR); + } + if (((smc->manfid == MANFID_OSITECH) && + (smc->cardid == PRODID_OSITECH_SEVEN)) || + ((smc->manfid == MANFID_PSION) && + (smc->cardid == PRODID_PSION_NET100))) { + /* Download the Seven of Diamonds firmware */ + for (i = 0; i < sizeof(__Xilinx7OD); i++) { + outb(__Xilinx7OD[i], link->io.BasePort1+2); + udelay(50); + } + } + if (link->open) { + smc_reset(dev); + netif_device_attach(dev); } - } - if (link->open) { - smc_reset(dev); - netif_device_attach(dev); } return 0; @@ -909,7 +931,7 @@ static int smc91c92_resume(struct pcmcia_device *link) ======================================================================*/ -static int check_sig(struct pcmcia_device *link) +static int check_sig(dev_link_t *link) { struct net_device *dev = link->priv; kio_addr_t ioaddr = dev->base_addr; @@ -942,15 +964,13 @@ static int check_sig(struct pcmcia_device *link) } if (width) { - modconf_t mod = { - .Attributes = CONF_IO_CHANGE_WIDTH, - }; - printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); - - smc91c92_suspend(link); - pcmcia_modify_configuration(link, &mod); - smc91c92_resume(link); - return check_sig(link); + printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); + smc91c92_suspend(link->handle); + pcmcia_release_io(link->handle, &link->io); + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + pcmcia_request_io(link->handle, &link->io); + smc91c92_resume(link->handle); + return check_sig(link); } return -ENODEV; } @@ -964,10 +984,11 @@ static int check_sig(struct pcmcia_device *link) ======================================================================*/ #define CS_EXIT_TEST(ret, svc, label) \ -if (ret != CS_SUCCESS) { cs_error(link, svc, ret); goto label; } +if (ret != CS_SUCCESS) { cs_error(link->handle, svc, ret); goto label; } -static int smc91c92_config(struct pcmcia_device *link) +static void smc91c92_config(dev_link_t *link) { + client_handle_t handle = link->handle; struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; @@ -994,18 +1015,21 @@ static int smc91c92_config(struct pcmcia_device *link) tuple->TupleDataMax = 64; tuple->DesiredTuple = CISTPL_CONFIG; - i = first_tuple(link, tuple, parse); + i = first_tuple(handle, tuple, parse); CS_EXIT_TEST(i, ParseTuple, config_failed); link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; tuple->DesiredTuple = CISTPL_MANFID; tuple->Attributes = TUPLE_RETURN_COMMON; - if (first_tuple(link, tuple, parse) == CS_SUCCESS) { + if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { smc->manfid = parse->manfid.manf; smc->cardid = parse->manfid.card; } + /* Configure card */ + link->state |= DEV_CONFIG; + if ((smc->manfid == MANFID_OSITECH) && (smc->cardid != PRODID_OSITECH_SEVEN)) { i = osi_config(link); @@ -1019,9 +1043,9 @@ static int smc91c92_config(struct pcmcia_device *link) } CS_EXIT_TEST(i, RequestIO, config_failed); - i = pcmcia_request_irq(link, &link->irq); + i = pcmcia_request_irq(link->handle, &link->irq); CS_EXIT_TEST(i, RequestIRQ, config_failed); - i = pcmcia_request_configuration(link, &link->conf); + i = pcmcia_request_configuration(link->handle, &link->conf); CS_EXIT_TEST(i, RequestConfiguration, config_failed); if (smc->manfid == MANFID_MOTOROLA) @@ -1100,12 +1124,13 @@ static int smc91c92_config(struct pcmcia_device *link) SMC_SELECT_BANK(0); } - link->dev_node = &smc->node; - SET_NETDEV_DEV(dev, &handle_to_dev(link)); + link->dev = &smc->node; + link->state &= ~DEV_CONFIG_PENDING; + SET_NETDEV_DEV(dev, &handle_to_dev(handle)); if (register_netdev(dev) != 0) { printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); - link->dev_node = NULL; + link->dev = NULL; goto config_undo; } @@ -1135,14 +1160,15 @@ static int smc91c92_config(struct pcmcia_device *link) } } kfree(cfg_mem); - return 0; + return; config_undo: unregister_netdev(dev); config_failed: /* CS_EXIT_TEST() calls jump to here... */ smc91c92_release(link); + link->state &= ~DEV_CONFIG_PENDING; kfree(cfg_mem); - return -ENODEV; + } /* smc91c92_config */ /*====================================================================== @@ -1153,15 +1179,22 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */ ======================================================================*/ -static void smc91c92_release(struct pcmcia_device *link) +static void smc91c92_release(dev_link_t *link) { - DEBUG(0, "smc91c92_release(0x%p)\n", link); - if (link->win) { - struct net_device *dev = link->priv; - struct smc_private *smc = netdev_priv(dev); - iounmap(smc->base); - } - pcmcia_disable_device(link); + + DEBUG(0, "smc91c92_release(0x%p)\n", link); + + pcmcia_release_configuration(link->handle); + pcmcia_release_io(link->handle, &link->io); + pcmcia_release_irq(link->handle, &link->irq); + if (link->win) { + struct net_device *dev = link->priv; + struct smc_private *smc = netdev_priv(dev); + iounmap(smc->base); + pcmcia_release_window(link->win); + } + + link->state &= ~DEV_CONFIG; } /*====================================================================== @@ -1250,7 +1283,7 @@ static void smc_dump(struct net_device *dev) static int smc_open(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - struct pcmcia_device *link = smc->p_dev; + dev_link_t *link = &smc->link; #ifdef PCMCIA_DEBUG DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n", @@ -1259,7 +1292,7 @@ static int smc_open(struct net_device *dev) #endif /* Check that the PCMCIA card is still here. */ - if (!pcmcia_dev_present(link)) + if (!DEV_OK(link)) return -ENODEV; /* Physical device present signature. */ if (check_sig(link) < 0) { @@ -1287,7 +1320,7 @@ static int smc_open(struct net_device *dev) static int smc_close(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - struct pcmcia_device *link = smc->p_dev; + dev_link_t *link = &smc->link; kio_addr_t ioaddr = dev->base_addr; DEBUG(0, "%s: smc_close(), status %4.4x.\n", @@ -1883,7 +1916,7 @@ static void smc_reset(struct net_device *dev) /* Set the Window 1 control, configuration and station addr registers. No point in writing the I/O base register ;-> */ SMC_SELECT_BANK(1); - /* Automatically release successfully transmitted packets, + /* Automatically release succesfully transmitted packets, Accept link errors, counter and Tx error interrupts. */ outw(CTL_AUTO_RELEASE | CTL_TE_ENABLE | CTL_CR_ENABLE, ioaddr + CONTROL); @@ -2278,7 +2311,7 @@ static struct pcmcia_driver smc91c92_cs_driver = { .drv = { .name = "smc91c92_cs", }, - .probe = smc91c92_probe, + .probe = smc91c92_attach, .remove = smc91c92_detach, .id_table = smc91c92_ids, .suspend = smc91c92_suspend,