aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-29 14:36:33 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-29 14:36:33 -0400
commit2b7fc477b0423cbcc7be8ad8652e3552198de418 (patch)
tree58f6e51300fb344252e171ce4b167498e6be81e3
parent41c91996d99394a75912aa5bfda300b85789ed43 (diff)
parent5b85bad2a473a8b90cac93d21ab024ba221a8b09 (diff)
Merge branch 'arcnet-EAE'
Michael Grzeschik says: ==================== ARCNET: add support for EAE multi interfac card this series adds support for the PLX Bridge based multi interface pci cards and adds support to change device address on com200xx chips during runtime. This series is based on v3.17-rc7. It is fixed for build against com20020_cs. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/arcnet/arcnet.c2
-rw-r--r--drivers/net/arcnet/com20020-pci.c369
-rw-r--r--drivers/net/arcnet/com20020.c14
-rw-r--r--drivers/net/arcnet/com20020_cs.c4
-rw-r--r--include/linux/com20020.h29
5 files changed, 330 insertions, 88 deletions
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 3b790de6c976..09de683c167e 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -777,7 +777,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
777 ACOMMAND(CFLAGScmd | RESETclear); 777 ACOMMAND(CFLAGScmd | RESETclear);
778 AINTMASK(0); 778 AINTMASK(0);
779 spin_unlock(&lp->lock); 779 spin_unlock(&lp->lock);
780 return IRQ_HANDLED; 780 return retval;
781 } 781 }
782 782
783 BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n", 783 BUGMSG(D_DURING, "in arcnet_inthandler (status=%Xh, intmask=%Xh)\n",
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 7bb292e59559..6c99ff0b0bdd 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -38,6 +38,7 @@
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <linux/arcdevice.h> 39#include <linux/arcdevice.h>
40#include <linux/com20020.h> 40#include <linux/com20020.h>
41#include <linux/list.h>
41 42
42#include <asm/io.h> 43#include <asm/io.h>
43 44
@@ -61,115 +62,317 @@ module_param(clockp, int, 0);
61module_param(clockm, int, 0); 62module_param(clockm, int, 0);
62MODULE_LICENSE("GPL"); 63MODULE_LICENSE("GPL");
63 64
65static void com20020pci_remove(struct pci_dev *pdev);
66
64static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 67static int com20020pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
65{ 68{
69 struct com20020_pci_card_info *ci;
66 struct net_device *dev; 70 struct net_device *dev;
67 struct arcnet_local *lp; 71 struct arcnet_local *lp;
68 int ioaddr, err; 72 struct com20020_priv *priv;
73 int i, ioaddr, ret;
74 struct resource *r;
69 75
70 if (pci_enable_device(pdev)) 76 if (pci_enable_device(pdev))
71 return -EIO; 77 return -EIO;
72 dev = alloc_arcdev(device);
73 if (!dev)
74 return -ENOMEM;
75 78
76 dev->netdev_ops = &com20020_netdev_ops; 79 priv = devm_kzalloc(&pdev->dev, sizeof(struct com20020_priv),
80 GFP_KERNEL);
81 ci = (struct com20020_pci_card_info *)id->driver_data;
82 priv->ci = ci;
77 83
78 lp = netdev_priv(dev); 84 INIT_LIST_HEAD(&priv->list_dev);
79 85
80 pci_set_drvdata(pdev, dev);
81 86
82 // SOHARD needs PCI base addr 4 87 for (i = 0; i < ci->devcount; i++) {
83 if (pdev->vendor==0x10B5) { 88 struct com20020_pci_channel_map *cm = &ci->chan_map_tbl[i];
84 BUGMSG(D_NORMAL, "SOHARD\n"); 89 struct com20020_dev *card;
85 ioaddr = pci_resource_start(pdev, 4);
86 }
87 else {
88 BUGMSG(D_NORMAL, "Contemporary Controls\n");
89 ioaddr = pci_resource_start(pdev, 2);
90 }
91 90
92 if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com20020-pci")) { 91 dev = alloc_arcdev(device);
93 BUGMSG(D_INIT, "IO region %xh-%xh already allocated.\n", 92 if (!dev) {
94 ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1); 93 ret = -ENOMEM;
95 err = -EBUSY; 94 goto out_port;
96 goto out_dev; 95 }
97 }
98 96
99 // Dummy access after Reset 97 dev->netdev_ops = &com20020_netdev_ops;
100 // ARCNET controller needs this access to detect bustype 98
101 outb(0x00,ioaddr+1); 99 lp = netdev_priv(dev);
102 inb(ioaddr+1); 100
103 101 BUGMSG(D_NORMAL, "%s Controls\n", ci->name);
104 dev->base_addr = ioaddr; 102 ioaddr = pci_resource_start(pdev, cm->bar) + cm->offset;
105 dev->irq = pdev->irq; 103
106 dev->dev_addr[0] = node; 104 r = devm_request_region(&pdev->dev, ioaddr, cm->size,
107 lp->card_name = "PCI COM20020"; 105 "com20020-pci");
108 lp->card_flags = id->driver_data; 106 if (!r) {
109 lp->backplane = backplane; 107 pr_err("IO region %xh-%xh already allocated.\n",
110 lp->clockp = clockp & 7; 108 ioaddr, ioaddr + cm->size - 1);
111 lp->clockm = clockm & 3; 109 ret = -EBUSY;
112 lp->timeout = timeout; 110 goto out_port;
113 lp->hw.owner = THIS_MODULE; 111 }
114 112
115 if (ASTATUS() == 0xFF) { 113 /* Dummy access after Reset
116 BUGMSG(D_NORMAL, "IO address %Xh was reported by PCI BIOS, " 114 * ARCNET controller needs
117 "but seems empty!\n", ioaddr); 115 * this access to detect bustype
118 err = -EIO; 116 */
119 goto out_port; 117 outb(0x00, ioaddr + 1);
120 } 118 inb(ioaddr + 1);
121 if (com20020_check(dev)) { 119
122 err = -EIO; 120 dev->base_addr = ioaddr;
123 goto out_port; 121 dev->dev_addr[0] = node;
122 dev->irq = pdev->irq;
123 lp->card_name = "PCI COM20020";
124 lp->card_flags = ci->flags;
125 lp->backplane = backplane;
126 lp->clockp = clockp & 7;
127 lp->clockm = clockm & 3;
128 lp->timeout = timeout;
129 lp->hw.owner = THIS_MODULE;
130
131 if (ASTATUS() == 0xFF) {
132 pr_err("IO address %Xh is empty!\n", ioaddr);
133 ret = -EIO;
134 goto out_port;
135 }
136 if (com20020_check(dev)) {
137 ret = -EIO;
138 goto out_port;
139 }
140
141 card = devm_kzalloc(&pdev->dev, sizeof(struct com20020_dev),
142 GFP_KERNEL);
143 if (!card) {
144 pr_err("%s out of memory!\n", __func__);
145 return -ENOMEM;
146 }
147
148 card->index = i;
149 card->pci_priv = priv;
150 card->dev = dev;
151
152 dev_set_drvdata(&dev->dev, card);
153
154 ret = com20020_found(dev, IRQF_SHARED);
155 if (ret)
156 goto out_port;
157
158 list_add(&card->list, &priv->list_dev);
124 } 159 }
125 160
126 if ((err = com20020_found(dev, IRQF_SHARED)) != 0) 161 pci_set_drvdata(pdev, priv);
127 goto out_port;
128 162
129 return 0; 163 return 0;
130 164
131out_port: 165out_port:
132 release_region(ioaddr, ARCNET_TOTAL_SIZE); 166 com20020pci_remove(pdev);
133out_dev: 167 return ret;
134 free_netdev(dev);
135 return err;
136} 168}
137 169</