diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/atm/eni.c | 98 | ||||
-rw-r--r-- | drivers/atm/eni.h | 5 |
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 | ||
157 | static struct atm_dev *eni_boards = NULL; | 157 | static struct atm_dev *eni_boards = NULL; |
158 | 158 | ||
159 | static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */ | ||
160 | static 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 | ||
1792 | static 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 | ||
1793 | static int __devinit eni_start(struct atm_dev *dev) | 1801 | static int __devinit eni_start(struct atm_dev *dev) |
1794 | { | 1802 | { |
@@ -2220,48 +2228,60 @@ static const struct atmdev_ops ops = { | |||
2220 | 2228 | ||
2221 | 2229 | ||
2222 | static int __devinit eni_init_one(struct pci_dev *pci_dev, | 2230 | static 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; | 2271 | out: |
2256 | out3: | 2272 | return rc; |
2273 | |||
2274 | err_eni_release: | ||
2275 | eni_do_release(dev); | ||
2276 | err_unregister: | ||
2257 | atm_dev_deregister(dev); | 2277 | atm_dev_deregister(dev); |
2258 | out2: | 2278 | err_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; | 2280 | err_kfree: |
2261 | out1: | ||
2262 | kfree(eni_dev); | 2281 | kfree(eni_dev); |
2263 | out0: | 2282 | err_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[] = { | |||
2273 | MODULE_DEVICE_TABLE(pci,eni_pci_tbl); | 2293 | MODULE_DEVICE_TABLE(pci,eni_pci_tbl); |
2274 | 2294 | ||
2275 | 2295 | ||
2276 | static void __devexit eni_remove_one(struct pci_dev *pci_dev) | 2296 | static 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 */ |