Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / wan / dscc4.c
index 4cbda75..4505540 100644 (file)
 #include <linux/delay.h>
 #include <net/syncppp.h>
 #include <linux/hdlc.h>
+#include <linux/mutex.h>
 
 /* Version */
 static const char version[] = "$Id: dscc4.c,v 1.173 2003/09/20 23:55:34 romieu Exp $ for Linux\n";
@@ -112,7 +113,7 @@ static int debug;
 static int quartz;
 
 #ifdef CONFIG_DSCC4_PCI_RST
-static DECLARE_MUTEX(dscc4_sem);
+static DEFINE_MUTEX(dscc4_mutex);
 static u32 dscc4_pci_config_store[16];
 #endif
 
@@ -125,9 +126,9 @@ static u32 dscc4_pci_config_store[16];
 MODULE_AUTHOR("Maintainer: Francois Romieu <romieu@cogenit.fr>");
 MODULE_DESCRIPTION("Siemens PEB20534 PCI Controler");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug,"i");
+module_param(debug, int, 0);
 MODULE_PARM_DESC(debug,"Enable/disable extra messages");
-MODULE_PARM(quartz,"i");
+module_param(quartz, int, 0);
 MODULE_PARM_DESC(quartz,"If present, on-board quartz frequency (Hz)");
 
 /* Structures */
@@ -230,6 +231,7 @@ struct dscc4_dev_priv {
        unsigned short parity;
        struct net_device *dev;
        sync_serial_settings settings;
+       void __iomem *base_addr;
        u32 __pad __attribute__ ((aligned (4)));
 };
 
@@ -351,9 +353,9 @@ struct dscc4_dev_priv {
 #endif
 
 /* Functions prototypes */
-static inline void dscc4_rx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
-static inline void dscc4_tx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
-static int dscc4_found1(struct pci_dev *, unsigned long ioaddr);
+static void dscc4_rx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
+static void dscc4_tx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
+static int dscc4_found1(struct pci_dev *, void __iomem *ioaddr);
 static int dscc4_init_one(struct pci_dev *, const struct pci_device_id *ent);
 static int dscc4_open(struct net_device *);
 static int dscc4_start_xmit(struct sk_buff *, struct net_device *);
@@ -366,7 +368,6 @@ static void dscc4_tx_timeout(struct net_device *);
 static irqreturn_t dscc4_irq(int irq, void *dev_id, struct pt_regs *ptregs);
 static int dscc4_hdlc_attach(struct net_device *, unsigned short, unsigned short);
 static int dscc4_set_iface(struct dscc4_dev_priv *, struct net_device *);
-static inline int dscc4_set_quartz(struct dscc4_dev_priv *, int);
 #ifdef DSCC4_POLLING
 static int dscc4_tx_poll(struct dscc4_dev_priv *, struct net_device *);
 #endif
@@ -391,7 +392,7 @@ static void scc_patchl(u32 mask, u32 value, struct dscc4_dev_priv *dpriv,
        state &= ~mask;
        state |= value;
        dpriv->scc_regs[offset >> 2] = state;
-       writel(state, dev->base_addr + SCC_REG_START(dpriv) + offset);
+       writel(state, dpriv->base_addr + SCC_REG_START(dpriv) + offset);
 }
 
 static void scc_writel(u32 bits, struct dscc4_dev_priv *dpriv,
@@ -402,7 +403,7 @@ static void scc_writel(u32 bits, struct dscc4_dev_priv *dpriv,
         * As of 2002/02/16, there are no thread racing for access.
         */
        dpriv->scc_regs[offset >> 2] = bits;
-       writel(bits, dev->base_addr + SCC_REG_START(dpriv) + offset);
+       writel(bits, dpriv->base_addr + SCC_REG_START(dpriv) + offset);
 }
 
 static inline u32 scc_readl(struct dscc4_dev_priv *dpriv, int offset)
@@ -413,8 +414,8 @@ static inline u32 scc_readl(struct dscc4_dev_priv *dpriv, int offset)
 static u32 scc_readl_star(struct dscc4_dev_priv *dpriv, struct net_device *dev)
 {
        /* Cf errata DS5 p.4 */
-       readl(dev->base_addr + SCC_REG_START(dpriv) + STAR);
-       return readl(dev->base_addr + SCC_REG_START(dpriv) + STAR);
+       readl(dpriv->base_addr + SCC_REG_START(dpriv) + STAR);
+       return readl(dpriv->base_addr + SCC_REG_START(dpriv) + STAR);
 }
 
 static inline void dscc4_do_tx(struct dscc4_dev_priv *dpriv,
@@ -422,9 +423,9 @@ static inline void dscc4_do_tx(struct dscc4_dev_priv *dpriv,
 {
        dpriv->ltda = dpriv->tx_fd_dma +
                       ((dpriv->tx_current-1)%TX_RING_SIZE)*sizeof(struct TxFD);
-       writel(dpriv->ltda, dev->base_addr + CH0LTDA + dpriv->dev_id*4);
+       writel(dpriv->ltda, dpriv->base_addr + CH0LTDA + dpriv->dev_id*4);
        /* Flush posted writes *NOW* */
-       readl(dev->base_addr + CH0LTDA + dpriv->dev_id*4);
+       readl(dpriv->base_addr + CH0LTDA + dpriv->dev_id*4);
 }
 
 static inline void dscc4_rx_update(struct dscc4_dev_priv *dpriv,
@@ -432,7 +433,7 @@ static inline void dscc4_rx_update(struct dscc4_dev_priv *dpriv,
 {
        dpriv->lrda = dpriv->rx_fd_dma +
                      ((dpriv->rx_dirty - 1)%RX_RING_SIZE)*sizeof(struct RxFD);
-       writel(dpriv->lrda, dev->base_addr + CH0LRDA + dpriv->dev_id*4);
+       writel(dpriv->lrda, dpriv->base_addr + CH0LRDA + dpriv->dev_id*4);
 }
 
 static inline unsigned int dscc4_tx_done(struct dscc4_dev_priv *dpriv)
@@ -443,11 +444,11 @@ static inline unsigned int dscc4_tx_done(struct dscc4_dev_priv *dpriv)
 static inline unsigned int dscc4_tx_quiescent(struct dscc4_dev_priv *dpriv,
                                              struct net_device *dev)
 {
-       return readl(dev->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
+       return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
 }
 
-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
-               const char *msg)
+static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
+                      struct net_device *dev, const char *msg)
 {
        int ret = 0;
 
@@ -466,8 +467,9 @@ int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
        return ret;
 }
 
-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
-                   char *msg)
+static void dscc4_tx_print(struct net_device *dev,
+                          struct dscc4_dev_priv *dpriv,
+                          char *msg)
 {
        printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
               dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@@ -507,7 +509,8 @@ static void dscc4_release_ring(struct dscc4_dev_priv *dpriv)
        }
 }
 
-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
+                                struct net_device *dev)
 {
        unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
        struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@@ -518,9 +521,7 @@ inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
        skb = dev_alloc_skb(len);
        dpriv->rx_skbuff[dirty] = skb;
        if (skb) {
-               skb->dev = dev;
                skb->protocol = hdlc_type_trans(skb, dev);
-               skb->mac.raw = skb->data;
                rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
                                             len, PCI_DMA_FROMDEVICE);
        } else {
@@ -544,8 +545,7 @@ static int dscc4_wait_ack_cec(struct dscc4_dev_priv *dpriv,
                               msg, i);
                        goto done;
                }
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout_uninterruptible(10);
                rmb();
        } while (++i > 0);
        printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@@ -555,7 +555,7 @@ done:
 
 static int dscc4_do_action(struct net_device *dev, char *msg)
 {
-       unsigned long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = dscc4_priv(dev)->base_addr;
        s16 i = 0;
 
        writel(Action, ioaddr + GCMDR);
@@ -590,8 +590,7 @@ static inline int dscc4_xpr_ack(struct dscc4_dev_priv *dpriv)
                    (dpriv->iqtx[cur] & Xpr))
                        break;
                smp_rmb();
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(10);
+               schedule_timeout_uninterruptible(10);
        } while (++i > 0);
 
        return (i >= 0 ) ? i : -EAGAIN;
@@ -604,11 +603,11 @@ static void dscc4_rx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
 
        spin_lock_irqsave(&dpriv->pci_priv->lock, flags);
        /* Cf errata DS5 p.6 */
-       writel(0x00000000, dev->base_addr + CH0LRDA + dpriv->dev_id*4);
+       writel(0x00000000, dpriv->base_addr + CH0LRDA + dpriv->dev_id*4);
        scc_patchl(PowerUp, 0, dpriv, dev, CCR0);
-       readl(dev->base_addr + CH0LRDA + dpriv->dev_id*4);
-       writel(MTFi|Rdr, dev->base_addr + dpriv->dev_id*0x0c + CH0CFG);
-       writel(Action, dev->base_addr + GCMDR);
+       readl(dpriv->base_addr + CH0LRDA + dpriv->dev_id*4);
+       writel(MTFi|Rdr, dpriv->base_addr + dpriv->dev_id*0x0c + CH0CFG);
+       writel(Action, dpriv->base_addr + GCMDR);
        spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags);
 }
 
@@ -630,7 +629,7 @@ static void dscc4_tx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
                wmb();
        }
 
-       writel(MTFi|Rdt, dev->base_addr + dpriv->dev_id*0x0c + CH0CFG);
+       writel(MTFi|Rdt, dpriv->base_addr + dpriv->dev_id*0x0c + CH0CFG);
        if (dscc4_do_action(dev, "Rdt") < 0)
                printk(KERN_ERR "%s: Tx reset failed\n", dev->name);
 }
@@ -693,7 +692,7 @@ static void dscc4_free1(struct pci_dev *pdev)
        root = ppriv->root;
 
        for (i = 0; i < dev_per_card; i++)
-               unregister_hdlc_device(dscc4_to_dev(&root[i]));
+               unregister_hdlc_device(dscc4_to_dev(root + i));
 
        pci_set_drvdata(pdev, NULL);
 
@@ -708,33 +707,36 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
 {
        struct dscc4_pci_priv *priv;
        struct dscc4_dev_priv *dpriv;
-       static int cards_found = 0;
-       unsigned long ioaddr;
-       int i;
+       void __iomem *ioaddr;
+       int i, rc;
 
        printk(KERN_DEBUG "%s", version);
 
-       if (pci_enable_device(pdev))
-               goto err_out;
-       if (!request_mem_region(pci_resource_start(pdev, 0),
-                               pci_resource_len(pdev, 0), "registers")) {
+       rc = pci_enable_device(pdev);
+       if (rc < 0)
+               goto out;
+
+       rc = pci_request_region(pdev, 0, "registers");
+       if (rc < 0) {
                printk(KERN_ERR "%s: can't reserve MMIO region (regs)\n",
                        DRV_NAME);
-               goto err_out;
+               goto err_disable_0;
        }
-       if (!request_mem_region(pci_resource_start(pdev, 1),
-                               pci_resource_len(pdev, 1), "LBI interface")) {
+       rc = pci_request_region(pdev, 1, "LBI interface");
+       if (rc < 0) {
                printk(KERN_ERR "%s: can't reserve MMIO region (lbi)\n",
                        DRV_NAME);
-               goto err_out_free_mmio_region0;
+               goto err_free_mmio_region_1;
        }
-       ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0),
+
+       ioaddr = ioremap(pci_resource_start(pdev, 0),
                                        pci_resource_len(pdev, 0));
        if (!ioaddr) {
                printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n",
                        DRV_NAME, pci_resource_len(pdev, 0),
                        pci_resource_start(pdev, 0));
-               goto err_out_free_mmio_region;
+               rc = -EIO;
+               goto err_free_mmio_regions_2;
        }
        printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n",
                pci_resource_start(pdev, 0),
@@ -744,14 +746,16 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
        pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8);
        pci_set_master(pdev);
 
-       if (dscc4_found1(pdev, ioaddr))
-               goto err_out_iounmap;
+       rc = dscc4_found1(pdev, ioaddr);
+       if (rc < 0)
+               goto err_iounmap_3;
 
-       priv = (struct dscc4_pci_priv *)pci_get_drvdata(pdev);
+       priv = pci_get_drvdata(pdev);
 
-       if (request_irq(pdev->irq, &dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root)){
+       rc = request_irq(pdev->irq, dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root);
+       if (rc < 0) {
                printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq);
-               goto err_out_free1;
+               goto err_release_4;
        }
 
        /* power up/little endian/dma core controlled via lrda/ltda */
@@ -771,9 +775,11 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
        priv->iqcfg = (u32 *) pci_alloc_consistent(pdev,
                IRQ_RING_SIZE*sizeof(u32), &priv->iqcfg_dma);
        if (!priv->iqcfg)
-               goto err_out_free_irq;
+               goto err_free_irq_5;
        writel(priv->iqcfg_dma, ioaddr + IQCFG);
 
+       rc = -ENOMEM;
+
        /*
         * SCC 0-3 private rx/tx irq structures
         * IQRX/TXi needs to be set soon. Learned it the hard way...
@@ -783,7 +789,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
                dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev,
                        IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
                if (!dpriv->iqtx)
-                       goto err_out_free_iqtx;
+                       goto err_free_iqtx_6;
                writel(dpriv->iqtx_dma, ioaddr + IQTX0 + i*4);
        }
        for (i = 0; i < dev_per_card; i++) {
@@ -791,7 +797,7 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
                dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev,
                        IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
                if (!dpriv->iqrx)
-                       goto err_out_free_iqrx;
+                       goto err_free_iqrx_7;
                writel(dpriv->iqrx_dma, ioaddr + IQRX0 + i*4);
        }
 
@@ -806,17 +812,18 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev,
 
        writel(0xff200001, ioaddr + GCMDR);
 
-       cards_found++;
-       return 0;
+       rc = 0;
+out:
+       return rc;
 
-err_out_free_iqrx:
+err_free_iqrx_7:
        while (--i >= 0) {
                dpriv = priv->root + i;
                pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
                                    dpriv->iqrx, dpriv->iqrx_dma);
        }
        i = dev_per_card;
-err_out_free_iqtx:
+err_free_iqtx_6:
        while (--i >= 0) {
                dpriv = priv->root + i;
                pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
@@ -824,20 +831,19 @@ err_out_free_iqtx:
        }
        pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), priv->iqcfg,
                            priv->iqcfg_dma);
-err_out_free_irq:
+err_free_irq_5:
        free_irq(pdev->irq, priv->root);
-err_out_free1:
+err_release_4:
        dscc4_free1(pdev);
-err_out_iounmap:
-       iounmap ((void *)ioaddr);
-err_out_free_mmio_region:
-       release_mem_region(pci_resource_start(pdev, 1),
-                          pci_resource_len(pdev, 1));
-err_out_free_mmio_region0:
-       release_mem_region(pci_resource_start(pdev, 0),
-                          pci_resource_len(pdev, 0));
-err_out:
-       return -ENODEV;
+err_iounmap_3:
+       iounmap (ioaddr);
+err_free_mmio_regions_2:
+       pci_release_region(pdev, 1);
+err_free_mmio_region_1:
+       pci_release_region(pdev, 0);
+err_disable_0:
+       pci_disable_device(pdev);
+       goto out;
 };
 
 /*
@@ -866,14 +872,25 @@ static void dscc4_init_registers(struct dscc4_dev_priv *dpriv,
        //scc_writel(0x00250008 & ~RxActivate, dpriv, dev, CCR2);
 }
 
-static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
+static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
+{
+       int ret = 0;
+
+       if ((hz < 0) || (hz > DSCC4_HZ_MAX))
+               ret = -EOPNOTSUPP;
+       else
+               dpriv->pci_priv->xtal_hz = hz;
+
+       return ret;
+}
+
+static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr)
 {
        struct dscc4_pci_priv *ppriv;
        struct dscc4_dev_priv *root;
        int i, ret = -ENOMEM;
 
-       root = (struct dscc4_dev_priv *)
-               kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
+       root = kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
        if (!root) {
                printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME);
                goto err_out;
@@ -882,22 +899,17 @@ static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
 
        for (i = 0; i < dev_per_card; i++) {
                root[i].dev = alloc_hdlcdev(root + i);
-               if (!root[i].dev) {
-                       while (i--)
-                               free_netdev(root[i].dev);
+               if (!root[i].dev)
                        goto err_free_dev;
-               }
        }
 
-       ppriv = (struct dscc4_pci_priv *) kmalloc(sizeof(*ppriv), GFP_KERNEL);
+       ppriv = kmalloc(sizeof(*ppriv), GFP_KERNEL);
        if (!ppriv) {
                printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME);
-               goto err_free_dev2;
+               goto err_free_dev;
        }
        memset(ppriv, 0, sizeof(struct dscc4_pci_priv));
-       ret = dscc4_set_quartz(root, quartz);
-       if (ret < 0)
-               goto err_free_priv;
+
        ppriv->root = root;
        spin_lock_init(&ppriv->lock);
 
@@ -906,7 +918,7 @@ static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
                struct net_device *d = dscc4_to_dev(dpriv);
                hdlc_device *hdlc = dev_to_hdlc(d);
 
-               d->base_addr = ioaddr;
+               d->base_addr = (unsigned long)ioaddr;
                d->init = NULL;
                d->irq = pdev->irq;
                d->open = dscc4_open;
@@ -920,6 +932,7 @@ static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
 
                dpriv->dev_id = i;
                dpriv->pci_priv = ppriv;
+               dpriv->base_addr = ioaddr;
                spin_lock_init(&dpriv->lock);
 
                hdlc->xmit = dscc4_start_xmit;
@@ -940,20 +953,24 @@ static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
                        goto err_unregister;
                }
        }
+
+       ret = dscc4_set_quartz(root, quartz);
+       if (ret < 0)
+               goto err_unregister;
+
        pci_set_drvdata(pdev, ppriv);
        return ret;
 
 err_unregister:
-       while (--i >= 0) {
+       while (i-- > 0) {
                dscc4_release_ring(root + i);
-               unregister_hdlc_device(dscc4_to_dev(&root[i]));
+               unregister_hdlc_device(dscc4_to_dev(root + i));
        }
-err_free_priv:
        kfree(ppriv);
-err_free_dev2:
-       for (i = 0; i < dev_per_card; i++)
-               free_netdev(root[i].dev);
+       i = dev_per_card;
 err_free_dev:
+       while (i-- > 0)
+               free_netdev(root[i].dev);
        kfree(root);
 err_out:
        return ret;
@@ -998,11 +1015,11 @@ static int dscc4_loopback_check(struct dscc4_dev_priv *dpriv)
  *
  * This code doesn't need to be efficient. Keep It Simple
  */
-static void dscc4_pci_reset(struct pci_dev *pdev, unsigned long ioaddr)
+static void dscc4_pci_reset(struct pci_dev *pdev, void __iomem *ioaddr)
 {
        int i;
 
-       down(&dscc4_sem);
+       mutex_lock(&dscc4_mutex);
        for (i = 0; i < 16; i++)
                pci_read_config_dword(pdev, i << 2, dscc4_pci_config_store + i);
 
@@ -1019,12 +1036,11 @@ static void dscc4_pci_reset(struct pci_dev *pdev, unsigned long ioaddr)
        /* Flush posted writes */
        readl(ioaddr + GSTAR);
 
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(10);
+       schedule_timeout_uninterruptible(10);
 
        for (i = 0; i < 16; i++)
                pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
-       up(&dscc4_sem);
+       mutex_unlock(&dscc4_mutex);
 }
 #else
 #define dscc4_pci_reset(pdev,ioaddr)   do {} while (0)
@@ -1340,18 +1356,6 @@ static int dscc4_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        return ret;
 }
 
-static inline int dscc4_set_quartz(struct dscc4_dev_priv *dpriv, int hz)
-{
-       int ret = 0;
-
-       if ((hz < 0) || (hz > DSCC4_HZ_MAX))
-               ret = -EOPNOTSUPP;
-       else
-               dpriv->pci_priv->xtal_hz = hz;
-
-       return ret;
-}
-
 static int dscc4_match(struct thingie *p, int value)
 {
        int i;
@@ -1477,7 +1481,7 @@ static irqreturn_t dscc4_irq(int irq, void *token, struct pt_regs *ptregs)
        struct dscc4_dev_priv *root = token;
        struct dscc4_pci_priv *priv;
        struct net_device *dev;
-       unsigned long ioaddr;
+       void __iomem *ioaddr;
        u32 state;
        unsigned long flags;
        int i, handled = 1;
@@ -1487,7 +1491,7 @@ static irqreturn_t dscc4_irq(int irq, void *token, struct pt_regs *ptregs)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       ioaddr = dev->base_addr;
+       ioaddr = root->base_addr;
 
        state = readl(ioaddr + GSTAR);
        if (!state) {
@@ -1531,7 +1535,7 @@ out:
        return IRQ_RETVAL(handled);
 }
 
-static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
+static void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
                                struct dscc4_dev_priv *dpriv)
 {
        struct net_device *dev = dscc4_to_dev(dpriv);
@@ -1614,8 +1618,8 @@ try:
                        dpriv->flags = NeedIDT;
                        /* Tx reset */
                        writel(MTFi | Rdt,
-                              dev->base_addr + 0x0c*dpriv->dev_id + CH0CFG);
-                       writel(Action, dev->base_addr + GCMDR);
+                              dpriv->base_addr + 0x0c*dpriv->dev_id + CH0CFG);
+                       writel(Action, dpriv->base_addr + GCMDR);
                        return;
                }
                if (state & Cts) {
@@ -1630,7 +1634,8 @@ try:
                                goto try;
                }
                if (state & Xpr) {
-                       unsigned long scc_addr, ring;
+                       void __iomem *scc_addr;
+                       unsigned long ring;
                        int i;
 
                        /*
@@ -1644,7 +1649,7 @@ try:
                        if (!i)
                                printk(KERN_INFO "%s busy in irq\n", dev->name);
 
-                       scc_addr = dev->base_addr + 0x0c*dpriv->dev_id;
+                       scc_addr = dpriv->base_addr + 0x0c*dpriv->dev_id;
                        /* Keep this order: IDT before IDR */
                        if (dpriv->flags & NeedIDT) {
                                if (debug > 2)
@@ -1700,7 +1705,7 @@ try:
        goto try;
 }
 
-static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
+static void dscc4_rx_irq(struct dscc4_pci_priv *priv,
                                    struct dscc4_dev_priv *dpriv)
 {
        struct net_device *dev = dscc4_to_dev(dpriv);
@@ -1802,12 +1807,12 @@ try:
                 */
                if (state & Rdo) {
                        struct RxFD *rx_fd;
-                       u32 scc_addr;
+                       void __iomem *scc_addr;
                        int cur;
 
                        //if (debug)
                        //      dscc4_rx_dump(dpriv);
-                       scc_addr = dev->base_addr + 0x0c*dpriv->dev_id;
+                       scc_addr = dpriv->base_addr + 0x0c*dpriv->dev_id;
 
                        scc_patchl(RxActivate, 0, dpriv, dev, CCR2);
                        /*
@@ -1889,7 +1894,7 @@ try:
  * It failed and locked solid. Thus the introduction of a dummy skb.
  * Problem is acknowledged in errata sheet DS5. Joy :o/
  */
-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
 {
        struct sk_buff *skb;
 
@@ -1939,7 +1944,7 @@ static int dscc4_init_ring(struct net_device *dev)
                                        (++i%TX_RING_SIZE)*sizeof(*tx_fd));
        } while (i < TX_RING_SIZE);
 
-       if (dscc4_init_dummy_skb(dpriv) < 0)
+       if (!dscc4_init_dummy_skb(dpriv))
                goto err_free_dma_tx;
 
        memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE);
@@ -1971,13 +1976,13 @@ static void __devexit dscc4_remove_one(struct pci_dev *pdev)
 {
        struct dscc4_pci_priv *ppriv;
        struct dscc4_dev_priv *root;
-       unsigned long ioaddr;
+       void __iomem *ioaddr;
        int i;
 
        ppriv = pci_get_drvdata(pdev);
        root = ppriv->root;
 
-       ioaddr = dscc4_to_dev(root)->base_addr;
+       ioaddr = root->base_addr;
 
        dscc4_pci_reset(pdev, ioaddr);
 
@@ -1996,12 +2001,12 @@ static void __devexit dscc4_remove_one(struct pci_dev *pdev)
 
        dscc4_free1(pdev);
 
-       iounmap((void *)ioaddr);
+       iounmap(ioaddr);
+
+       pci_release_region(pdev, 1);
+       pci_release_region(pdev, 0);
 
-       release_mem_region(pci_resource_start(pdev, 1),
-                          pci_resource_len(pdev, 1));
-       release_mem_region(pci_resource_start(pdev, 0),
-                          pci_resource_len(pdev, 0));
+       pci_disable_device(pdev);
 }
 
 static int dscc4_hdlc_attach(struct net_device *dev, unsigned short encoding,