aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/atm/eni.c98
-rw-r--r--drivers/atm/eni.h5
2 files changed, 68 insertions, 35 deletions
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 485a11a6de96..6ff612d099c3 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -156,9 +156,6 @@ static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
156 156
157static struct atm_dev *eni_boards = NULL; 157static struct atm_dev *eni_boards = NULL;
158 158
159static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */
160static dma_addr_t zeroes;
161
162/* Read/write registers on card */ 159/* Read/write registers on card */
163#define eni_in(r) readl(eni_dev->reg+(r)*4) 160#define eni_in(r) readl(eni_dev->reg+(r)*4)
164#define eni_out(v,r) writel((v),eni_dev->reg+(r)*4) 161#define eni_out(v,r) writel((v),eni_dev->reg+(r)*4)
@@ -1138,8 +1135,10 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
1138 skb_shinfo(skb)->frags[i].page_offset, 1135 skb_shinfo(skb)->frags[i].page_offset,
1139 skb_frag_size(&skb_shinfo(skb)->frags[i])); 1136 skb_frag_size(&skb_shinfo(skb)->frags[i]));
1140 } 1137 }
1141 if (skb->len & 3) 1138 if (skb->len & 3) {
1142 put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3)); 1139 put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma,
1140 4 - (skb->len & 3));
1141 }
1143 /* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */ 1142 /* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
1144 eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) << 1143 eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
1145 MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) | 1144 MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
@@ -1728,6 +1727,7 @@ static int __devinit eni_do_init(struct atm_dev *dev)
1728 "mapping\n",dev->number); 1727 "mapping\n",dev->number);
1729 return error; 1728 return error;
1730 } 1729 }
1730 eni_dev->ioaddr = base;
1731 eni_dev->base_diff = real_base - (unsigned long) base; 1731 eni_dev->base_diff = real_base - (unsigned long) base;
1732 /* id may not be present in ASIC Tonga boards - check this @@@ */ 1732 /* id may not be present in ASIC Tonga boards - check this @@@ */
1733 if (!eni_dev->asic) { 1733 if (!eni_dev->asic) {
@@ -1789,6 +1789,14 @@ unmap:
1789 goto out; 1789 goto out;
1790} 1790}
1791 1791
1792static void eni_do_release(struct atm_dev *dev)
1793{
1794 struct eni_dev *ed = ENI_DEV(dev);
1795
1796 dev->phy->stop(dev);
1797 dev->phy = NULL;
1798 iounmap(ed->ioaddr);
1799}
1792 1800
1793static int __devinit eni_start(struct atm_dev *dev) 1801static int __devinit eni_start(struct atm_dev *dev)
1794{ 1802{
@@ -2220,48 +2228,60 @@ static const struct atmdev_ops ops = {
2220 2228
2221 2229
2222static int __devinit eni_init_one(struct pci_dev *pci_dev, 2230static int __devinit eni_init_one(struct pci_dev *pci_dev,
2223 const struct pci_device_id *ent) 2231 const struct pci_device_id *ent)
2224{ 2232{
2225 struct atm_dev *dev; 2233 struct atm_dev *dev;
2226 struct eni_dev *eni_dev; 2234 struct eni_dev *eni_dev;
2227 int error = -ENOMEM; 2235 struct eni_zero *zero;
2236 int rc;
2237
2238 rc = pci_enable_device(pci_dev);
2239 if (rc < 0)
2240 goto out;
2228 2241
2229 DPRINTK("eni_init_one\n"); 2242 rc = -ENOMEM;
2243 eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL);
2244 if (!eni_dev)
2245 goto err_disable;
2230 2246
2231 if (pci_enable_device(pci_dev)) { 2247 zero = &eni_dev->zero;
2232 error = -EIO; 2248 zero->addr = pci_alloc_consistent(pci_dev, ENI_ZEROES_SIZE, &zero->dma);
2233 goto out0; 2249 if (!zero->addr)
2234 } 2250 goto err_kfree;
2235 2251
2236 eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
2237 if (!eni_dev) goto out0;
2238 if (!cpu_zeroes) {
2239 cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
2240 &zeroes);
2241 if (!cpu_zeroes) goto out1;
2242 }
2243 dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); 2252 dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
2244 if (!dev) goto out2; 2253 if (!dev)
2254 goto err_free_consistent;
2255
2256 dev->dev_data = eni_dev;
2245 pci_set_drvdata(pci_dev, dev); 2257 pci_set_drvdata(pci_dev, dev);
2246 eni_dev->pci_dev = pci_dev; 2258 eni_dev->pci_dev = pci_dev;
2247 dev->dev_data = eni_dev;
2248 eni_dev->asic = ent->driver_data; 2259 eni_dev->asic = ent->driver_data;
2249 error = eni_do_init(dev); 2260
2250 if (error) goto out3; 2261 rc = eni_do_init(dev);
2251 error = eni_start(dev); 2262 if (rc < 0)
2252 if (error) goto out3; 2263 goto err_unregister;
2264
2265 rc = eni_start(dev);
2266 if (rc < 0)
2267 goto err_eni_release;
2268
2253 eni_dev->more = eni_boards; 2269 eni_dev->more = eni_boards;
2254 eni_boards = dev; 2270 eni_boards = dev;
2255 return 0; 2271out:
2256out3: 2272 return rc;
2273
2274err_eni_release:
2275 eni_do_release(dev);
2276err_unregister:
2257 atm_dev_deregister(dev); 2277 atm_dev_deregister(dev);
2258out2: 2278err_free_consistent:
2259 pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,cpu_zeroes,zeroes); 2279 pci_free_consistent(pci_dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
2260 cpu_zeroes = NULL; 2280err_kfree:
2261out1:
2262 kfree(eni_dev); 2281 kfree(eni_dev);
2263out0: 2282err_disable:
2264 return error; 2283 pci_disable_device(pci_dev);
2284 goto out;
2265} 2285}
2266 2286
2267 2287
@@ -2273,9 +2293,17 @@ static struct pci_device_id eni_pci_tbl[] = {
2273MODULE_DEVICE_TABLE(pci,eni_pci_tbl); 2293MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
2274 2294
2275 2295
2276static void __devexit eni_remove_one(struct pci_dev *pci_dev) 2296static void __devexit eni_remove_one(struct pci_dev *pdev)
2277{ 2297{
2278 /* grrr */ 2298 struct atm_dev *dev = pci_get_drvdata(pdev);
2299 struct eni_dev *ed = ENI_DEV(dev);
2300 struct eni_zero *zero = &ed->zero;
2301
2302 eni_do_release(dev);
2303 atm_dev_deregister(dev);
2304 pci_free_consistent(pdev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
2305 kfree(ed);
2306 pci_disable_device(pdev);
2279} 2307}
2280 2308
2281 2309
diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h
index dc9a62cc2605..565e53a5cb78 100644
--- a/drivers/atm/eni.h
+++ b/drivers/atm/eni.h
@@ -72,6 +72,7 @@ struct eni_dev {
72 u32 events; /* pending events */ 72 u32 events; /* pending events */
73 /*-------------------------------- base pointers into Midway address 73 /*-------------------------------- base pointers into Midway address
74 space */ 74 space */
75 void __iomem *ioaddr;
75 void __iomem *phy; /* PHY interface chip registers */ 76 void __iomem *phy; /* PHY interface chip registers */
76 void __iomem *reg; /* register base */ 77 void __iomem *reg; /* register base */
77 void __iomem *ram; /* RAM base */ 78 void __iomem *ram; /* RAM base */
@@ -86,6 +87,10 @@ struct eni_dev {
86 wait_queue_head_t tx_wait; /* for close */ 87 wait_queue_head_t tx_wait; /* for close */
87 int tx_bw; /* remaining bandwidth */ 88 int tx_bw; /* remaining bandwidth */
88 u32 dma[TX_DMA_BUF*2]; /* DMA request scratch area */ 89 u32 dma[TX_DMA_BUF*2]; /* DMA request scratch area */
90 struct eni_zero { /* aligned "magic" zeroes */
91 u32 *addr;
92 dma_addr_t dma;
93 } zero;
89 int tx_mult; /* buffer size multiplier (percent) */ 94 int tx_mult; /* buffer size multiplier (percent) */
90 /*-------------------------------- RX part */ 95 /*-------------------------------- RX part */
91 u32 serv_read; /* host service read index */ 96 u32 serv_read; /* host service read index */