vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / hamachi.c
index 6b0cb2c..3d96714 100644 (file)
@@ -170,10 +170,10 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/skbuff.h>
 #include <linux/ip.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
 #include <asm/uaccess.h>
 #include <asm/processor.h>     /* Processor type for cache alignment. */
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/unaligned.h>
 #include <asm/cache.h>
@@ -512,27 +512,28 @@ struct hamachi_private {
        u32 rx_int_var, tx_int_var;     /* interrupt control variables */
        u32 option;                                                     /* Hold on to a copy of the options */
        struct pci_dev *pci_dev;
+       void __iomem *base;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
 MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
 
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(mtu, "i");
-MODULE_PARM(debug, "i");
-MODULE_PARM(min_rx_pkt, "i");
-MODULE_PARM(max_rx_gap, "i");
-MODULE_PARM(max_rx_latency, "i");
-MODULE_PARM(min_tx_pkt, "i");
-MODULE_PARM(max_tx_gap, "i");
-MODULE_PARM(max_tx_latency, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(rx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(tx_params, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(force32, "i");
+module_param(max_interrupt_work, int, 0);
+module_param(mtu, int, 0);
+module_param(debug, int, 0);
+module_param(min_rx_pkt, int, 0);
+module_param(max_rx_gap, int, 0);
+module_param(max_rx_latency, int, 0);
+module_param(min_tx_pkt, int, 0);
+module_param(max_tx_gap, int, 0);
+module_param(max_tx_latency, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param_array(rx_params, int, NULL, 0);
+module_param_array(tx_params, int, NULL, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(force32, int, 0);
 MODULE_PARM_DESC(max_interrupt_work, "GNIC-II maximum events handled per interrupt");
 MODULE_PARM_DESC(mtu, "GNIC-II MTU (all boards)");
 MODULE_PARM_DESC(debug, "GNIC-II debug level (0-7)");
@@ -549,7 +550,7 @@ MODULE_PARM_DESC(options, "GNIC-II Bits 0-3: media type, bits 4-6: as force32, b
 MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
 MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
                                                                         
-static int read_eeprom(long ioaddr, int location);
+static int read_eeprom(void __iomem *ioaddr, int location);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int hamachi_open(struct net_device *dev);
@@ -565,7 +566,8 @@ static void hamachi_error(struct net_device *dev, int intr_status);
 static int hamachi_close(struct net_device *dev);
 static struct net_device_stats *hamachi_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
-
+static struct ethtool_ops ethtool_ops;
+static struct ethtool_ops ethtool_ops_no_mii;
 
 static int __devinit hamachi_init_one (struct pci_dev *pdev,
                                    const struct pci_device_id *ent)
@@ -574,7 +576,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
        int option, i, rx_int_var, tx_int_var, boguscnt;
        int chip_id = ent->driver_data;
        int irq;
-       long ioaddr;
+       void __iomem *ioaddr;
+       unsigned long base;
        static int card_idx;
        struct net_device *dev;
        void *ring_space;
@@ -593,9 +596,9 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
                goto err_out;
        }
 
-       ioaddr = pci_resource_start(pdev, 0);
+       base = pci_resource_start(pdev, 0);
 #ifdef __alpha__                               /* Really "64 bit addrs" */
-       ioaddr |= (pci_resource_start(pdev, 1) << 32);
+       base |= (pci_resource_start(pdev, 1) << 32);
 #endif
 
        pci_set_master(pdev);
@@ -604,7 +607,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
        if (i) return i;
 
        irq = pdev->irq;
-       ioaddr = (long) ioremap(ioaddr, 0x400);
+       ioaddr = ioremap(base, 0x400);
        if (!ioaddr)
                goto err_out_release;
 
@@ -631,7 +634,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
                                   read_eeprom(ioaddr, i), i % 16 != 15 ? " " : "\n");
 #endif
 
-       hmp = dev->priv;
+       hmp = netdev_priv(dev);
        spin_lock_init(&hmp->lock);
 
        hmp->mii_if.dev = dev;
@@ -677,7 +680,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
                i = readb(ioaddr + PCIClkMeas); 
        }
 
-       dev->base_addr = ioaddr;
+       hmp->base = ioaddr;
+       dev->base_addr = (unsigned long)ioaddr;
        dev->irq = irq;
        pci_set_drvdata(pdev, dev);
 
@@ -725,6 +729,10 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
        dev->get_stats = &hamachi_get_stats;
        dev->set_multicast_list = &set_rx_mode;
        dev->do_ioctl = &netdev_ioctl;
+       if (chip_tbl[hmp->chip_id].flags & CanHaveMII)
+               SET_ETHTOOL_OPS(dev, &ethtool_ops);
+       else
+               SET_ETHTOOL_OPS(dev, &ethtool_ops_no_mii);
        dev->tx_timeout = &hamachi_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
        if (mtu)
@@ -736,7 +744,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev,
                goto err_out_unmap_rx;
        }
 
-       printk(KERN_INFO "%s: %s type %x at 0x%lx, ",
+       printk(KERN_INFO "%s: %s type %x at %p, ",
                   dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev),
                   ioaddr);
        for (i = 0; i < 5; i++)
@@ -785,14 +793,14 @@ err_out_unmap_tx:
 err_out_cleardev:
        free_netdev (dev);
 err_out_iounmap:
-       iounmap((char *)ioaddr);
+       iounmap(ioaddr);
 err_out_release:
        pci_release_regions(pdev);
 err_out:
        return ret;
 }
 
-static int __devinit read_eeprom(long ioaddr, int location)
+static int __devinit read_eeprom(void __iomem *ioaddr, int location)
 {
        int bogus_cnt = 1000;
 
@@ -814,7 +822,8 @@ static int __devinit read_eeprom(long ioaddr, int location)
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
        int i;
 
        /* We should check busy first - per docs -KDU */
@@ -831,7 +840,8 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
        int i;
 
        /* We should check busy first - per docs -KDU */
@@ -851,8 +861,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
 \f
 static int hamachi_open(struct net_device *dev)
 {
-       struct hamachi_private *hmp = dev->priv;
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
        int i;
        u32 rx_int_var, tx_int_var;
        u16 fifo_info;
@@ -982,7 +992,7 @@ static int hamachi_open(struct net_device *dev)
        writew(0x001D, ioaddr + RxDMACtrl);
        writew(0x001D, ioaddr + TxDMACtrl);
 #endif
-       writew(0x0001, dev->base_addr + RxCmd);
+       writew(0x0001, ioaddr + RxCmd);
 
        if (hamachi_debug > 2) {
                printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n",
@@ -1000,7 +1010,7 @@ static int hamachi_open(struct net_device *dev)
 
 static inline int hamachi_tx(struct net_device *dev)
 {
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
 
        /* Update the dirty pointer until we find an entry that is
                still owned by the card */
@@ -1032,8 +1042,8 @@ static inline int hamachi_tx(struct net_device *dev)
 static void hamachi_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
-       struct hamachi_private *hmp = dev->priv;
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
        int next_tick = 10*HZ;
 
        if (hamachi_debug > 2) {
@@ -1057,8 +1067,8 @@ static void hamachi_timer(unsigned long data)
 static void hamachi_tx_timeout(struct net_device *dev)
 {
        int i;
-       struct hamachi_private *hmp = dev->priv;
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
 
        printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x,"
                   " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
@@ -1110,7 +1120,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
        }
 
        udelay(60); /* Sleep 60 us just for safety sake */
-       writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */
+       writew(0x0002, ioaddr + RxCmd); /* STOP Rx */
                
        writeb(0x01, ioaddr + ChipReset);  /* Reinit the hardware */ 
 
@@ -1152,9 +1162,9 @@ static void hamachi_tx_timeout(struct net_device *dev)
        hmp->stats.tx_errors++;
 
        /* Restart the chip's Tx/Rx processes . */
-       writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */
-       writew(0x0001, dev->base_addr + TxCmd); /* START Tx */
-       writew(0x0001, dev->base_addr + RxCmd); /* START Rx */
+       writew(0x0002, ioaddr + TxCmd); /* STOP Tx */
+       writew(0x0001, ioaddr + TxCmd); /* START Tx */
+       writew(0x0001, ioaddr + RxCmd); /* START Rx */
 
        netif_wake_queue(dev);
 }
@@ -1163,7 +1173,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
 /* Initialize the Rx and Tx rings, along with various 'dev' bits. */
 static void hamachi_init_ring(struct net_device *dev)
 {
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
        int i;
 
        hmp->tx_full = 0;
@@ -1255,7 +1265,7 @@ do { \
 
 static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
        unsigned entry;
        u16 status;
 
@@ -1270,9 +1280,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
                /* Wake the potentially-idle transmit channel. */
                /* If we don't need to read status, DON'T -KDU */
-               status=readw(dev->base_addr + TxStatus);
+               status=readw(hmp->base + TxStatus);
                if( !(status & 0x0001) || (status & 0x0002))
-                       writew(0x0001, dev->base_addr + TxCmd);
+                       writew(0x0001, hmp->base + TxCmd);
                return 1;
        } 
 
@@ -1338,9 +1348,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Wake the potentially-idle transmit channel. */
        /* If we don't need to read status, DON'T -KDU */
-       status=readw(dev->base_addr + TxStatus);
+       status=readw(hmp->base + TxStatus);
        if( !(status & 0x0001) || (status & 0x0002))
-               writew(0x0001, dev->base_addr + TxCmd);
+               writew(0x0001, hmp->base + TxCmd);
 
        /* Immediately before returning, let's clear as many entries as we can. */
        hamachi_tx(dev);
@@ -1371,8 +1381,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs)
 {
        struct net_device *dev = dev_instance;
-       struct hamachi_private *hmp;
-       long ioaddr, boguscnt = max_interrupt_work;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
+       long boguscnt = max_interrupt_work;
        int handled = 0;
 
 #ifndef final_version                  /* Can never occur. */
@@ -1382,8 +1393,6 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs
        }
 #endif
 
-       ioaddr = dev->base_addr;
-       hmp = dev->priv;
        spin_lock(&hmp->lock);
 
        do {
@@ -1477,7 +1486,7 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs
    for clarity and better register allocation. */
 static int hamachi_rx(struct net_device *dev)
 {
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
        int entry = hmp->cur_rx % RX_RING_SIZE;
        int boguscnt = (hmp->dirty_rx + RX_RING_SIZE) - hmp->cur_rx;
 
@@ -1682,8 +1691,8 @@ static int hamachi_rx(struct net_device *dev)
 
        /* Restart Rx engine if stopped. */
        /* If we don't need to check status, don't. -KDU */
-       if (readw(dev->base_addr + RxStatus) & 0x0002)
-               writew(0x0001, dev->base_addr + RxCmd);
+       if (readw(hmp->base + RxStatus) & 0x0002)
+               writew(0x0001, hmp->base + RxCmd);
 
        return 0;
 }
@@ -1692,8 +1701,8 @@ static int hamachi_rx(struct net_device *dev)
    than just errors. */
 static void hamachi_error(struct net_device *dev, int intr_status)
 {
-       long ioaddr = dev->base_addr;
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
 
        if (intr_status & (LinkChange|NegotiationChange)) {
                if (hamachi_debug > 1)
@@ -1726,8 +1735,8 @@ static void hamachi_error(struct net_device *dev, int intr_status)
 
 static int hamachi_close(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
        struct sk_buff *skb;
        int i;
 
@@ -1812,8 +1821,8 @@ static int hamachi_close(struct net_device *dev)
 
 static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
-       struct hamachi_private *hmp = dev->priv;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
 
        /* We should lock this segment of code for SMP eventually, although
           the vulnerability window is very small and statistics are
@@ -1840,7 +1849,8 @@ static struct net_device_stats *hamachi_get_stats(struct net_device *dev)
 
 static void set_rx_mode(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
+       struct hamachi_private *hmp = netdev_priv(dev);
+       void __iomem *ioaddr = hmp->base;
 
        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
                /* Unconditionally log net taps. */
@@ -1867,84 +1877,76 @@ static void set_rx_mode(struct net_device *dev)
        }
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+static int check_if_running(struct net_device *dev)
 {
-       struct hamachi_private *np = dev->priv;
-       u32 ethcmd;
-               
-       if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
-               return -EFAULT;
-
-        switch (ethcmd) {
-        case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strcpy(info.driver, DRV_NAME);
-               strcpy(info.version, DRV_VERSION);
-               strcpy(info.bus_info, pci_name(np->pci_dev));
-               if (copy_to_user(useraddr, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
+       if (!netif_running(dev))
+               return -EINVAL;
+       return 0;
+}
 
-       /* get settings */
-       case ETHTOOL_GSET: {
-               struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-               if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
-                       return -EINVAL;
-               spin_lock_irq(&np->lock);
-               mii_ethtool_gset(&np->mii_if, &ecmd);
-               spin_unlock_irq(&np->lock);
-               if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* set settings */
-       case ETHTOOL_SSET: {
-               int r;
-               struct ethtool_cmd ecmd;
-               if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
-                       return -EINVAL;
-               if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-                       return -EFAULT;
-               spin_lock_irq(&np->lock);
-               r = mii_ethtool_sset(&np->mii_if, &ecmd);
-               spin_unlock_irq(&np->lock);
-               return r;
-       }
-       /* restart autonegotiation */
-       case ETHTOOL_NWAY_RST: {
-               if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
-                       return -EINVAL;
-               return mii_nway_restart(&np->mii_if);
-       }
-       /* get link status */
-       case ETHTOOL_GLINK: {
-               struct ethtool_value edata = {ETHTOOL_GLINK};
-               if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
-                       return -EINVAL;
-               edata.data = mii_link_ok(&np->mii_if);
-               if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               return 0;
-       }
-        }
-       
-       return -EOPNOTSUPP;
+static void hamachi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+       struct hamachi_private *np = netdev_priv(dev);
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(np->pci_dev));
 }
 
+static int hamachi_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct hamachi_private *np = netdev_priv(dev);
+       spin_lock_irq(&np->lock);
+       mii_ethtool_gset(&np->mii_if, ecmd);
+       spin_unlock_irq(&np->lock);
+       return 0;
+}
+
+static int hamachi_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct hamachi_private *np = netdev_priv(dev);
+       int res;
+       spin_lock_irq(&np->lock);
+       res = mii_ethtool_sset(&np->mii_if, ecmd);
+       spin_unlock_irq(&np->lock);
+       return res;
+}
+
+static int hamachi_nway_reset(struct net_device *dev)
+{
+       struct hamachi_private *np = netdev_priv(dev);
+       return mii_nway_restart(&np->mii_if);
+}
+
+static u32 hamachi_get_link(struct net_device *dev)
+{
+       struct hamachi_private *np = netdev_priv(dev);
+       return mii_link_ok(&np->mii_if);
+}
+
+static struct ethtool_ops ethtool_ops = {
+       .begin = check_if_running,
+       .get_drvinfo = hamachi_get_drvinfo,
+       .get_settings = hamachi_get_settings,
+       .set_settings = hamachi_set_settings,
+       .nway_reset = hamachi_nway_reset,
+       .get_link = hamachi_get_link,
+};
+
+static struct ethtool_ops ethtool_ops_no_mii = {
+       .begin = check_if_running,
+       .get_drvinfo = hamachi_get_drvinfo,
+};
+
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct hamachi_private *np = dev->priv;
+       struct hamachi_private *np = netdev_priv(dev);
        struct mii_ioctl_data *data = if_mii(rq);
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
-       if (cmd == SIOCETHTOOL)
-               rc = netdev_ethtool_ioctl(dev, rq->ifr_data);
-
-       else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
+       if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
                u32 *d = (u32 *)&rq->ifr_ifru;
                /* Should add this check here or an ordinary user can do nasty
                 * things. -KDU
@@ -1953,11 +1955,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                 */
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               writel(d[0], dev->base_addr + TxIntrCtrl);
-               writel(d[1], dev->base_addr + RxIntrCtrl);
+               writel(d[0], np->base + TxIntrCtrl);
+               writel(d[1], np->base + RxIntrCtrl);
                printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
-                 (u32) readl(dev->base_addr + TxIntrCtrl),
-                 (u32) readl(dev->base_addr + RxIntrCtrl));
+                 (u32) readl(np->base + TxIntrCtrl),
+                 (u32) readl(np->base + RxIntrCtrl));
                rc = 0;
        }
 
@@ -1976,14 +1978,14 @@ static void __devexit hamachi_remove_one (struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
 
        if (dev) {
-               struct hamachi_private *hmp = dev->priv;
+               struct hamachi_private *hmp = netdev_priv(dev);
 
                pci_free_consistent(pdev, RX_TOTAL_SIZE, hmp->rx_ring, 
                        hmp->rx_ring_dma);
                pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, 
                        hmp->tx_ring_dma);
                unregister_netdev(dev);
-               iounmap((char *)dev->base_addr);
+               iounmap(hmp->base);
                free_netdev(dev);
                pci_release_regions(pdev);
                pci_set_drvdata(pdev, NULL);
@@ -2009,10 +2011,7 @@ static int __init hamachi_init (void)
 #ifdef MODULE
        printk(version);
 #endif
-       if (pci_register_driver(&hamachi_driver) > 0)
-               return 0;
-       pci_unregister_driver(&hamachi_driver);
-       return -ENODEV;
+       return pci_register_driver(&hamachi_driver);
 }
 
 static void __exit hamachi_exit (void)