netdev
[Top] [All Lists]

[PATCH] (4//8) dscc4 convert to new hdlc_device

To: Krzysztof Halas <khc@xxxxxxxxx>, Jeff Garzik <jgarzik@xxxxxxxxx>
Subject: [PATCH] (4//8) dscc4 convert to new hdlc_device
From: Stephen Hemminger <shemminger@xxxxxxxx>
Date: Tue, 2 Dec 2003 14:01:15 -0800
Cc: netdev@xxxxxxxxxxx
Organization: Open Source Development Lab
Sender: netdev-bounce@xxxxxxxxxxx
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#                  ChangeSet    1.1493  -> 1.1494 
#       drivers/net/wan/dscc4.c 1.51    -> 1.52   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/11/26      shemminger@xxxxxxxx     1.1494
# Convert to work with hdlc_device that is not embedded.
# Use list macros for list of ports on card.
# --------------------------------------------
#
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c   Wed Nov 26 12:30:13 2003
+++ b/drivers/net/wan/dscc4.c   Wed Nov 26 12:30:13 2003
@@ -185,12 +185,14 @@
         spinlock_t lock;
         struct pci_dev *pdev;
 
-        struct dscc4_dev_priv *root;
+       struct list_head devs;
         dma_addr_t iqcfg_dma;
        u32 xtal_hz;
 };
 
 struct dscc4_dev_priv {
+       struct list_head dev_list;
+
         struct sk_buff *rx_skbuff[RX_RING_SIZE];
         struct sk_buff *tx_skbuff[TX_RING_SIZE];
 
@@ -228,7 +230,7 @@
 
        unsigned short encoding;
        unsigned short parity;
-       hdlc_device hdlc;
+       hdlc_device *hdlc;
        sync_serial_settings settings;
        u32 __pad __attribute__ ((aligned (4)));
 };
@@ -371,9 +373,17 @@
 static int dscc4_tx_poll(struct dscc4_dev_priv *, struct net_device *);
 #endif
 
+static inline struct dscc4_dev_priv *dscc4_root_priv(struct dscc4_pci_priv 
*ppriv)
+{
+       struct list_head *first = ppriv->devs.next;
+
+       return (first == &ppriv->devs) ? NULL 
+               : list_entry(first, struct dscc4_dev_priv, dev_list);
+}
+
 static inline struct dscc4_dev_priv *dscc4_priv(struct net_device *dev)
 {
-       return list_entry(dev, struct dscc4_dev_priv, hdlc.netdev);
+       return dev_to_hdlc(dev)->dev_data;
 }
 
 static void scc_patchl(u32 mask, u32 value, struct dscc4_dev_priv *dpriv,
@@ -636,7 +646,7 @@
                                struct net_device *dev)
 {
        struct RxFD *rx_fd = dpriv->rx_fd + dpriv->rx_current%RX_RING_SIZE;
-       struct net_device_stats *stats = &dpriv->hdlc.stats;
+       struct net_device_stats *stats = &dpriv->hdlc->stats;
        struct pci_dev *pdev = dpriv->pci_priv->pdev;
        struct sk_buff *skb;
        int pkt_len;
@@ -681,19 +691,16 @@
 
 static void dscc4_free1(struct pci_dev *pdev)
 {
-       struct dscc4_pci_priv *ppriv;
-       struct dscc4_dev_priv *root;
-       int i;
+       struct dscc4_pci_priv *ppriv = pci_get_drvdata(pdev);
+       struct dscc4_dev_priv *dpriv, *dnext;
 
-       ppriv = pci_get_drvdata(pdev);
-       root = ppriv->root;
-
-       for (i = 0; i < dev_per_card; i++)
-               unregister_hdlc_device(&root[i].hdlc);
+       list_for_each_entry_safe(dpriv, dnext, &ppriv->devs, dev_list) {
+               unregister_hdlc_device(dpriv->hdlc);
+               free_hdlc_device(dpriv->hdlc);
+       }
 
        pci_set_drvdata(pdev, NULL);
 
-       kfree(root);
        kfree(ppriv);
 }
 
@@ -704,7 +711,6 @@
        struct dscc4_dev_priv *dpriv;
        static int cards_found = 0;
        unsigned long ioaddr;
-       int i;
 
        printk(KERN_DEBUG "%s", version);
 
@@ -743,7 +749,8 @@
 
        priv = (struct dscc4_pci_priv *)pci_get_drvdata(pdev);
 
-       if (request_irq(pdev->irq, &dscc4_irq, SA_SHIRQ, DRV_NAME, priv->root)){
+       if (request_irq(pdev->irq, &dscc4_irq, SA_SHIRQ, DRV_NAME, 
+                       dscc4_root_priv(priv))) {
                printk(KERN_WARNING "%s: IRQ %d busy\n", DRV_NAME, pdev->irq);
                goto err_out_free1;
        }
@@ -772,21 +779,19 @@
         * SCC 0-3 private rx/tx irq structures
         * IQRX/TXi needs to be set soon. Learned it the hard way...
         */
-       for (i = 0; i < dev_per_card; i++) {
-               dpriv = priv->root + i;
+       list_for_each_entry(dpriv, &priv->devs, dev_list) {
                dpriv->iqtx = (u32 *) pci_alloc_consistent(pdev,
                        IRQ_RING_SIZE*sizeof(u32), &dpriv->iqtx_dma);
                if (!dpriv->iqtx)
                        goto err_out_free_iqtx;
-               writel(dpriv->iqtx_dma, ioaddr + IQTX0 + i*4);
+               writel(dpriv->iqtx_dma, ioaddr + IQTX0 + dpriv->dev_id*4);
        }
-       for (i = 0; i < dev_per_card; i++) {
-               dpriv = priv->root + i;
+       list_for_each_entry(dpriv, &priv->devs, dev_list) {
                dpriv->iqrx = (u32 *) pci_alloc_consistent(pdev,
                        IRQ_RING_SIZE*sizeof(u32), &dpriv->iqrx_dma);
                if (!dpriv->iqrx)
                        goto err_out_free_iqrx;
-               writel(dpriv->iqrx_dma, ioaddr + IQRX0 + i*4);
+               writel(dpriv->iqrx_dma, ioaddr + IQRX0 + dpriv->dev_id*4);
        }
 
        /* Cf application hint. Beware of hard-lock condition on threshold. */
@@ -804,22 +809,19 @@
        return 0;
 
 err_out_free_iqrx:
-       while (--i >= 0) {
-               dpriv = priv->root + i;
+       list_for_each_entry(dpriv, &priv->devs, dev_list) {
                pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
                                    dpriv->iqrx, dpriv->iqrx_dma);
        }
-       i = dev_per_card;
 err_out_free_iqtx:
-       while (--i >= 0) {
-               dpriv = priv->root + i;
+       list_for_each_entry(dpriv, &priv->devs, dev_list) {
                pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
                                    dpriv->iqtx, dpriv->iqtx_dma);
        }
        pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), priv->iqcfg,
                            priv->iqcfg_dma);
 err_out_free_irq:
-       free_irq(pdev->irq, priv->root);
+       free_irq(pdev->irq, dscc4_root_priv(priv));
 err_out_free1:
        dscc4_free1(pdev);
 err_out_iounmap:
@@ -863,29 +865,27 @@
 static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
 {
        struct dscc4_pci_priv *ppriv;
-       struct dscc4_dev_priv *root;
+       struct dscc4_dev_priv *dpriv, *dnext;
        int i, ret = -ENOMEM;
 
-       root = (struct dscc4_dev_priv *)
-               kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
-       if (!root) {
-               printk(KERN_ERR "%s: can't allocate data\n", DRV_NAME);
-               goto err_out;
-       }
-       memset(root, 0, dev_per_card*sizeof(*root));
-
        ppriv = (struct dscc4_pci_priv *) kmalloc(sizeof(*ppriv), GFP_KERNEL);
        if (!ppriv) {
                printk(KERN_ERR "%s: can't allocate private data\n", DRV_NAME);
-               goto err_free_dev;
+               goto err_out;
        }
        memset(ppriv, 0, sizeof(struct dscc4_pci_priv));
+       INIT_LIST_HEAD(&ppriv->devs);
 
        for (i = 0; i < dev_per_card; i++) {
-               struct dscc4_dev_priv *dpriv = root + i;
-               hdlc_device *hdlc = &dpriv->hdlc;
-               struct net_device *d = hdlc_to_dev(hdlc);
+               hdlc_device *hdlc = alloc_hdlc_device(sizeof(*dpriv));
+               struct net_device *d;
+
+               if (!hdlc) {
+                       ret = -ENOMEM;
+                       goto err_unregister;
+               }
 
+               d = hdlc_to_dev(hdlc);
                d->base_addr = ioaddr;
                d->init = NULL;
                d->irq = pdev->irq;
@@ -898,6 +898,8 @@
                SET_MODULE_OWNER(d);
                SET_NETDEV_DEV(d, &pdev->dev);
 
+               dpriv = dscc4_priv(d);
+               dpriv->hdlc = hdlc;
                dpriv->dev_id = i;
                dpriv->pci_priv = ppriv;
                spin_lock_init(&dpriv->lock);
@@ -920,23 +922,25 @@
                        unregister_hdlc_device(hdlc);
                        goto err_unregister;
                }
+               list_add_tail(&dpriv->dev_list, &ppriv->devs);
        }
-       ret = dscc4_set_quartz(root, quartz);
+
+
+       ret = dscc4_set_quartz(dscc4_root_priv(ppriv), quartz);
        if (ret < 0)
                goto err_unregister;
-       ppriv->root = root;
+
        spin_lock_init(&ppriv->lock);
        pci_set_drvdata(pdev, ppriv);
        return ret;
 
 err_unregister:
-       while (--i >= 0) {
-               dscc4_release_ring(root + i);
-               unregister_hdlc_device(&root[i].hdlc);
+       list_for_each_entry_safe(dpriv, dnext, &ppriv->devs, dev_list) {
+               dscc4_release_ring(dpriv);
+               unregister_hdlc_device(dpriv->hdlc);
+               free_hdlc_device(dpriv->hdlc);
        }
        kfree(ppriv);
-err_free_dev:
-       kfree(root);
 err_out:
        return ret;
 };
@@ -964,7 +968,7 @@
        sync_serial_settings *settings = &dpriv->settings;
 
        if (settings->loopback && (settings->clock_type != CLOCK_INT)) {
-               struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
+               struct net_device *dev = hdlc_to_dev(dpriv->hdlc);
 
                printk(KERN_INFO "%s: loopback requires clock\n", dev->name);
                return -1;
@@ -1015,7 +1019,7 @@
 static int dscc4_open(struct net_device *dev)
 {
        struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
-       hdlc_device *hdlc = &dpriv->hdlc;
+       hdlc_device *hdlc = dpriv->hdlc;
        struct dscc4_pci_priv *ppriv;
        int ret = -EAGAIN;
 
@@ -1467,7 +1471,7 @@
        int i, handled = 1;
 
        priv = root->pci_priv;
-       dev = hdlc_to_dev(&root->hdlc);
+       dev = hdlc_to_dev(root->hdlc);
 
        spin_lock_irqsave(&priv->lock, flags);
 
@@ -1518,7 +1522,7 @@
 static inline void dscc4_tx_irq(struct dscc4_pci_priv *ppriv,
                                struct dscc4_dev_priv *dpriv)
 {
-       struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
+       struct net_device *dev = hdlc_to_dev(dpriv->hdlc);
        u32 state;
        int cur, loop = 0;
 
@@ -1549,7 +1553,7 @@
 
        if (state & SccEvt) {
                if (state & Alls) {
-                       struct net_device_stats *stats = &dpriv->hdlc.stats;
+                       struct net_device_stats *stats = &dpriv->hdlc->stats;
                        struct sk_buff *skb;
                        struct TxFD *tx_fd;
 
@@ -1687,7 +1691,7 @@
 static inline void dscc4_rx_irq(struct dscc4_pci_priv *priv,
                                    struct dscc4_dev_priv *dpriv)
 {
-       struct net_device *dev = hdlc_to_dev(&dpriv->hdlc);
+       struct net_device *dev = hdlc_to_dev(dpriv->hdlc);
        u32 state;
        int cur;
 
@@ -1954,23 +1958,21 @@
 static void __devexit dscc4_remove_one(struct pci_dev *pdev)
 {
        struct dscc4_pci_priv *ppriv;
-       struct dscc4_dev_priv *root;
+       struct dscc4_dev_priv *root,  *dpriv;
        unsigned long ioaddr;
-       int i;
 
        ppriv = pci_get_drvdata(pdev);
-       root = ppriv->root;
+       root = dscc4_root_priv(ppriv);
 
-       ioaddr = hdlc_to_dev(&root->hdlc)->base_addr;
+       ioaddr = hdlc_to_dev(root->hdlc)->base_addr;
 
        dscc4_pci_reset(pdev, ioaddr);
 
        free_irq(pdev->irq, root);
        pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), ppriv->iqcfg,
                            ppriv->iqcfg_dma);
-       for (i = 0; i < dev_per_card; i++) {
-               struct dscc4_dev_priv *dpriv = root + i;
 
+       list_for_each_entry(dpriv, &ppriv->devs, dev_list) {
                dscc4_release_ring(dpriv);
                pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
                                    dpriv->iqrx, dpriv->iqrx_dma);

<Prev in Thread] Current Thread [Next in Thread>