Skip to content

Commit 126a3fd

Browse files
françois romieudavem330
authored andcommitted
eni: fix driver remove function and driver probe error path.
- add eni_do_release() to balance eni_do_init - turn the zeroes DMA area into a per device data Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 4823cd3 commit 126a3fd

File tree

2 files changed

+68
-35
lines changed

2 files changed

+68
-35
lines changed

drivers/atm/eni.c

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,6 @@ static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
156156

157157
static struct atm_dev *eni_boards = NULL;
158158

159-
static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */
160-
static dma_addr_t zeroes;
161-
162159
/* Read/write registers on card */
163160
#define eni_in(r) readl(eni_dev->reg+(r)*4)
164161
#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 */
11381135
skb_shinfo(skb)->frags[i].page_offset,
11391136
skb_frag_size(&skb_shinfo(skb)->frags[i]));
11401137
}
1141-
if (skb->len & 3)
1142-
put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));
1138+
if (skb->len & 3) {
1139+
put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma,
1140+
4 - (skb->len & 3));
1141+
}
11431142
/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
11441143
eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
11451144
MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
@@ -1728,6 +1727,7 @@ static int __devinit eni_do_init(struct atm_dev *dev)
17281727
"mapping\n",dev->number);
17291728
return error;
17301729
}
1730+
eni_dev->ioaddr = base;
17311731
eni_dev->base_diff = real_base - (unsigned long) base;
17321732
/* id may not be present in ASIC Tonga boards - check this @@@ */
17331733
if (!eni_dev->asic) {
@@ -1789,6 +1789,14 @@ static int __devinit eni_do_init(struct atm_dev *dev)
17891789
goto out;
17901790
}
17911791

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+
}
17921800

17931801
static int __devinit eni_start(struct atm_dev *dev)
17941802
{
@@ -2220,48 +2228,60 @@ static const struct atmdev_ops ops = {
22202228

22212229

22222230
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)
22242232
{
22252233
struct atm_dev *dev;
22262234
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;
22282241

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;
22302246

2231-
if (pci_enable_device(pci_dev)) {
2232-
error = -EIO;
2233-
goto out0;
2234-
}
2247+
zero = &eni_dev->zero;
2248+
zero->addr = pci_alloc_consistent(pci_dev, ENI_ZEROES_SIZE, &zero->dma);
2249+
if (!zero->addr)
2250+
goto err_kfree;
22352251

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-
}
22432252
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;
22452257
pci_set_drvdata(pci_dev, dev);
22462258
eni_dev->pci_dev = pci_dev;
2247-
dev->dev_data = eni_dev;
22482259
eni_dev->asic = ent->driver_data;
2249-
error = eni_do_init(dev);
2250-
if (error) goto out3;
2251-
error = eni_start(dev);
2252-
if (error) goto out3;
2260+
2261+
rc = eni_do_init(dev);
2262+
if (rc < 0)
2263+
goto err_unregister;
2264+
2265+
rc = eni_start(dev);
2266+
if (rc < 0)
2267+
goto err_eni_release;
2268+
22532269
eni_dev->more = eni_boards;
22542270
eni_boards = dev;
2255-
return 0;
2256-
out3:
2271+
out:
2272+
return rc;
2273+
2274+
err_eni_release:
2275+
eni_do_release(dev);
2276+
err_unregister:
22572277
atm_dev_deregister(dev);
2258-
out2:
2259-
pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,cpu_zeroes,zeroes);
2260-
cpu_zeroes = NULL;
2261-
out1:
2278+
err_free_consistent:
2279+
pci_free_consistent(pci_dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
2280+
err_kfree:
22622281
kfree(eni_dev);
2263-
out0:
2264-
return error;
2282+
err_disable:
2283+
pci_disable_device(pci_dev);
2284+
goto out;
22652285
}
22662286

22672287

@@ -2273,9 +2293,17 @@ static struct pci_device_id eni_pci_tbl[] = {
22732293
MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
22742294

22752295

2276-
static void __devexit eni_remove_one(struct pci_dev *pci_dev)
2296+
static void __devexit eni_remove_one(struct pci_dev *pdev)
22772297
{
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);
22792307
}
22802308

22812309

drivers/atm/eni.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct eni_dev {
7272
u32 events; /* pending events */
7373
/*-------------------------------- base pointers into Midway address
7474
space */
75+
void __iomem *ioaddr;
7576
void __iomem *phy; /* PHY interface chip registers */
7677
void __iomem *reg; /* register base */
7778
void __iomem *ram; /* RAM base */
@@ -86,6 +87,10 @@ struct eni_dev {
8687
wait_queue_head_t tx_wait; /* for close */
8788
int tx_bw; /* remaining bandwidth */
8889
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;
8994
int tx_mult; /* buffer size multiplier (percent) */
9095
/*-------------------------------- RX part */
9196
u32 serv_read; /* host service read index */

0 commit comments

Comments
 (0)