X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fpcmcia%2Fsmc91c92_cs.c;h=85a152173148c2f52f03aed39b99b07d9a8b6ac7;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=49d60d9ca062adb3f62bb7de135f9e554a8a10db;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 49d60d9ca..85a152173 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -66,7 +66,7 @@ static char *if_names[] = { "auto", "10baseT", "10base2"}; MODULE_DESCRIPTION("SMC 91c92 series PCMCIA ethernet driver"); MODULE_LICENSE("GPL"); -#define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i") +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) /* Transceiver/media type. @@ -76,11 +76,6 @@ MODULE_LICENSE("GPL"); */ INT_MODULE_PARM(if_port, 0); -/* Bit map of interrupts to choose from. */ -INT_MODULE_PARM(irq_mask, 0xdeb8); -static int irq_list[4] = { -1 }; -MODULE_PARM(irq_list, "1-4i"); - #ifdef PCMCIA_DEBUG INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG); static const char *version = @@ -120,7 +115,7 @@ struct smc_private { dev_node_t node; struct sk_buff *saved_skb; int packets_waiting; - caddr_t base; + void __iomem *base; u_short cfg; struct timer_list media; int watchdog, tx_err; @@ -300,10 +295,11 @@ static int s9k_config(struct net_device *dev, struct ifmap *map); static void smc_set_xcvr(struct net_device *dev, int if_port); static void smc_reset(struct net_device *dev); static void media_check(u_long arg); -static void mdio_sync(ioaddr_t addr); +static void mdio_sync(kio_addr_t addr); static int mdio_read(struct net_device *dev, int phy_id, int loc); static void mdio_write(struct net_device *dev, int phy_id, int loc, int value); static int smc_link_ok(struct net_device *dev); +static struct ethtool_ops ethtool_ops; /*====================================================================== @@ -319,7 +315,7 @@ static dev_link_t *smc91c92_attach(void) struct smc_private *smc; dev_link_t *link; struct net_device *dev; - int i, ret; + int ret; DEBUG(0, "smc91c92_attach()\n"); @@ -336,12 +332,7 @@ static dev_link_t *smc91c92_attach(void) link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; link->io.IOAddrLines = 4; link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; - link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; - if (irq_list[0] == -1) - link->irq.IRQInfo2 = irq_mask; - else - for (i = 0; i < 4; i++) - link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &smc_interrupt; link->irq.Instance = dev; link->conf.Attributes = CONF_ENABLE_IRQ; @@ -357,6 +348,7 @@ static dev_link_t *smc91c92_attach(void) dev->open = &smc_open; dev->stop = &smc_close; dev->do_ioctl = &smc_ioctl; + SET_ETHTOOL_OPS(dev, ðtool_ops); #ifdef HAVE_TX_TIMEOUT dev->tx_timeout = smc_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -372,7 +364,6 @@ static dev_link_t *smc91c92_attach(void) link->next = dev_list; dev_list = link; client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; client_reg.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; @@ -620,8 +611,8 @@ static void mot_config(dev_link_t *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; - ioaddr_t iouart = link->io.BasePort2; + kio_addr_t ioaddr = dev->base_addr; + kio_addr_t iouart = link->io.BasePort2; /* Set UART base address and force map with COR bit 1 */ writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0); @@ -640,7 +631,7 @@ static void mot_config(dev_link_t *link) static int mot_setup(dev_link_t *link) { struct net_device *dev = link->priv; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; int i, wait, loop; u_int addr; @@ -748,7 +739,7 @@ static int smc_setup(dev_link_t *link) static int osi_config(dev_link_t *link) { struct net_device *dev = link->priv; - static ioaddr_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; @@ -837,7 +828,7 @@ static int osi_setup(dev_link_t *link, u_short manfid, u_short cardid) static int check_sig(dev_link_t *link) { struct net_device *dev = link->priv; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; int width; u_short s; @@ -901,7 +892,7 @@ static void smc91c92_config(dev_link_t *link) u_short buf[32]; char *name; int i, j, rev; - ioaddr_t ioaddr; + kio_addr_t ioaddr; u_long mir; DEBUG(0, "smc91c92_config(0x%p)\n", link); @@ -1022,6 +1013,7 @@ static void smc91c92_config(dev_link_t *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"); @@ -1179,7 +1171,7 @@ static int smc91c92_event(event_t event, int priority, #define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT) #define MDIO_DATA_READ 0x02 -static void mdio_sync(ioaddr_t addr) +static void mdio_sync(kio_addr_t addr) { int bits; for (bits = 0; bits < 32; bits++) { @@ -1190,7 +1182,7 @@ static void mdio_sync(ioaddr_t addr) static int mdio_read(struct net_device *dev, int phy_id, int loc) { - ioaddr_t addr = dev->base_addr + MGMT; + kio_addr_t addr = dev->base_addr + MGMT; u_int cmd = (0x06<<10)|(phy_id<<5)|loc; int i, retval = 0; @@ -1210,7 +1202,7 @@ static int mdio_read(struct net_device *dev, int phy_id, int loc) static void mdio_write(struct net_device *dev, int phy_id, int loc, int value) { - ioaddr_t addr = dev->base_addr + MGMT; + kio_addr_t addr = dev->base_addr + MGMT; u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; int i; @@ -1236,7 +1228,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int loc, int value) #ifdef PCMCIA_DEBUG static void smc_dump(struct net_device *dev) { - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_short i, w, save; save = inw(ioaddr + BANK_SELECT); for (w = 0; w < 4; w++) { @@ -1291,7 +1283,7 @@ static int smc_close(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); dev_link_t *link = &smc->link; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; DEBUG(0, "%s: smc_close(), status %4.4x.\n", dev->name, inw(ioaddr + BANK_SELECT)); @@ -1328,7 +1320,7 @@ static void smc_hardware_send_packet(struct net_device * dev) { struct smc_private *smc = netdev_priv(dev); struct sk_buff *skb = smc->saved_skb; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_char packet_no; if (!skb) { @@ -1392,7 +1384,7 @@ static void smc_hardware_send_packet(struct net_device * dev) static void smc_tx_timeout(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " "Tx_status %2.2x status %4.4x.\n", @@ -1407,7 +1399,7 @@ static void smc_tx_timeout(struct net_device *dev) static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_short num_pages; short time_out, ir; @@ -1473,7 +1465,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev) static void smc_tx_err(struct net_device * dev) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; int saved_packet = inw(ioaddr + PNR_ARR) & 0xff; int packet_no = inw(ioaddr + FIFO_PORTS) & 0x7f; int tx_status; @@ -1517,7 +1509,7 @@ static void smc_tx_err(struct net_device * dev) static void smc_eph_irq(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_short card_stats, ephs; SMC_SELECT_BANK(0); @@ -1552,7 +1544,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = dev_id; struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr; + kio_addr_t ioaddr; u_short saved_bank, saved_pointer, mask, status; unsigned int handled = 1; char bogus_cnt = INTR_WORK; /* Work we are willing to do. */ @@ -1670,7 +1662,7 @@ irq_done: static void smc_rx(struct net_device *dev) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; int rx_status; int packet_length; /* Caution: not frame length, rather words to transfer from the chip. */ @@ -1776,7 +1768,7 @@ static void fill_multicast_tbl(int count, struct dev_mc_list *addrs, static void set_rx_mode(struct net_device *dev) { - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; struct smc_private *smc = netdev_priv(dev); u_int multicast_table[ 2 ] = { 0, }; unsigned long flags; @@ -1843,7 +1835,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) static void smc_set_xcvr(struct net_device *dev, int if_port) { struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_short saved_bank; saved_bank = inw(ioaddr + BANK_SELECT); @@ -1866,7 +1858,7 @@ static void smc_set_xcvr(struct net_device *dev, int if_port) static void smc_reset(struct net_device *dev) { - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; struct smc_private *smc = netdev_priv(dev); int i; @@ -1943,7 +1935,7 @@ static void media_check(u_long arg) { struct net_device *dev = (struct net_device *) arg; struct smc_private *smc = netdev_priv(dev); - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; u_short i, media, saved_bank; u_short link; @@ -2055,7 +2047,7 @@ reschedule: static int smc_link_ok(struct net_device *dev) { - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; struct smc_private *smc = netdev_priv(dev); if (smc->cfg & CFG_MII_SELECT) { @@ -2069,7 +2061,7 @@ static int smc_link_ok(struct net_device *dev) static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) { u16 tmp; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; ecmd->supported = (SUPPORTED_TP | SUPPORTED_AUI | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full); @@ -2091,7 +2083,7 @@ static int smc_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) { u16 tmp; - ioaddr_t ioaddr = dev->base_addr; + kio_addr_t ioaddr = dev->base_addr; if (ecmd->speed != SPEED_10) return -EINVAL; @@ -2113,136 +2105,135 @@ static int smc_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd) tmp |= TCR_FDUPLX; else tmp &= ~TCR_FDUPLX; - outw(ioaddr + TCR, tmp); + outw(tmp, ioaddr + TCR); return 0; } -static int smc_ethtool_ioctl (struct net_device *dev, void __user *useraddr) +static int check_if_running(struct net_device *dev) { - u32 ethcmd; - struct smc_private *smc = netdev_priv(dev); - - if (get_user(ethcmd, (u32 __user *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; + if (!netif_running(dev)) + return -EINVAL; return 0; - } +} - /* get settings */ - case ETHTOOL_GSET: { +static void smc_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); +} + +static int smc_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct smc_private *smc = netdev_priv(dev); + kio_addr_t ioaddr = dev->base_addr; + u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + + SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); if (smc->cfg & CFG_MII_SELECT) - ret = mii_ethtool_gset(&smc->mii_if, &ecmd); + ret = mii_ethtool_gset(&smc->mii_if, ecmd); else - ret = smc_netdev_get_ecmd(dev, &ecmd); + ret = smc_netdev_get_ecmd(dev, ecmd); spin_unlock_irq(&smc->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; + SMC_SELECT_BANK(saved_bank); return ret; - } +} - /* set settings */ - case ETHTOOL_SSET: { +static int smc_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct smc_private *smc = netdev_priv(dev); + kio_addr_t ioaddr = dev->base_addr; + u16 saved_bank = inw(ioaddr + BANK_SELECT); int ret; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; + + SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); if (smc->cfg & CFG_MII_SELECT) - ret = mii_ethtool_sset(&smc->mii_if, &ecmd); + ret = mii_ethtool_sset(&smc->mii_if, ecmd); else - ret = smc_netdev_set_ecmd(dev, &ecmd); + ret = smc_netdev_set_ecmd(dev, ecmd); spin_unlock_irq(&smc->lock); + SMC_SELECT_BANK(saved_bank); return ret; - } +} - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = { ETHTOOL_GLINK }; +static u32 smc_get_link(struct net_device *dev) +{ + struct smc_private *smc = netdev_priv(dev); + kio_addr_t ioaddr = dev->base_addr; + u16 saved_bank = inw(ioaddr + BANK_SELECT); + u32 ret; + + SMC_SELECT_BANK(3); spin_lock_irq(&smc->lock); - edata.data = smc_link_ok(dev); + ret = smc_link_ok(dev); spin_unlock_irq(&smc->lock); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + SMC_SELECT_BANK(saved_bank); + return ret; +} #ifdef PCMCIA_DEBUG - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = { ETHTOOL_GMSGLVL }; - edata.data = pc_debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } +static u32 smc_get_msglevel(struct net_device *dev) +{ + return pc_debug; +} - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - pc_debug = edata.data; - return 0; - } +static void smc_set_msglevel(struct net_device *dev, u32 val) +{ + pc_debug = val; +} #endif - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - if (smc->cfg & CFG_MII_SELECT) - return mii_nway_restart(&smc->mii_if); - else - return -EOPNOTSUPP; - } - - default: - break; - } - return -EOPNOTSUPP; +static int smc_nway_reset(struct net_device *dev) +{ + struct smc_private *smc = netdev_priv(dev); + if (smc->cfg & CFG_MII_SELECT) { + kio_addr_t ioaddr = dev->base_addr; + u16 saved_bank = inw(ioaddr + BANK_SELECT); + int res; + + SMC_SELECT_BANK(3); + res = mii_nway_restart(&smc->mii_if); + SMC_SELECT_BANK(saved_bank); + + return res; + } else + return -EOPNOTSUPP; } +static struct ethtool_ops ethtool_ops = { + .begin = check_if_running, + .get_drvinfo = smc_get_drvinfo, + .get_settings = smc_get_settings, + .set_settings = smc_set_settings, + .get_link = smc_get_link, +#ifdef PCMCIA_DEBUG + .get_msglevel = smc_get_msglevel, + .set_msglevel = smc_set_msglevel, +#endif + .nway_reset = smc_nway_reset, +}; + static int smc_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { - struct smc_private *smc = netdev_priv(dev); - struct mii_ioctl_data *mii; - int rc = 0; - u_short saved_bank; - ioaddr_t ioaddr = dev->base_addr; - - mii = if_mii(rq); - if (!netif_running(dev)) - return -EINVAL; + struct smc_private *smc = netdev_priv(dev); + struct mii_ioctl_data *mii = if_mii(rq); + int rc = 0; + u16 saved_bank; + kio_addr_t ioaddr = dev->base_addr; - switch (cmd) { - case SIOCETHTOOL: - saved_bank = inw(ioaddr + BANK_SELECT); - SMC_SELECT_BANK(3); - rc = smc_ethtool_ioctl(dev, rq->ifr_data); - SMC_SELECT_BANK(saved_bank); - break; + if (!netif_running(dev)) + return -EINVAL; - default: spin_lock_irq(&smc->lock); saved_bank = inw(ioaddr + BANK_SELECT); SMC_SELECT_BANK(3); rc = generic_mii_ioctl(&smc->mii_if, mii, cmd, NULL); SMC_SELECT_BANK(saved_bank); spin_unlock_irq(&smc->lock); - break; - } - - return rc; + return rc; } static struct pcmcia_driver smc91c92_cs_driver = { @@ -2262,8 +2253,7 @@ static int __init init_smc91c92_cs(void) static void __exit exit_smc91c92_cs(void) { pcmcia_unregister_driver(&smc91c92_cs_driver); - while (dev_list != NULL) - smc91c92_detach(dev_list); + BUG_ON(dev_list != NULL); } module_init(init_smc91c92_cs);