aboutsummaryrefslogtreecommitdiff
path: root/drivers/atm/eni.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/atm/eni.c')
-rw-r--r--drivers/atm/eni.c132
1 files changed, 77 insertions, 55 deletions
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
index 97c5898cd76..b1955ba40d6 100644
--- a/drivers/atm/eni.c
+++ b/drivers/atm/eni.c
@@ -19,9 +19,8 @@
#include <linux/atm_eni.h>
#include <linux/bitops.h>
#include <linux/slab.h>
-#include <asm/system.h>
#include <asm/io.h>
-#include <asm/atomic.h>
+#include <linux/atomic.h>
#include <asm/uaccess.h>
#include <asm/string.h>
#include <asm/byteorder.h>
@@ -156,9 +155,6 @@ static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
static struct atm_dev *eni_boards = NULL;
-static u32 *cpu_zeroes = NULL; /* aligned "magic" zeroes */
-static dma_addr_t zeroes;
-
/* Read/write registers on card */
#define eni_in(r) readl(eni_dev->reg+(r)*4)
#define eni_out(v,r) writel((v),eni_dev->reg+(r)*4)
@@ -1134,11 +1130,14 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
skb_headlen(skb));
else
put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
- skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
- skb_shinfo(skb)->frags[i].size);
+ skb_frag_page(&skb_shinfo(skb)->frags[i]) +
+ skb_shinfo(skb)->frags[i].page_offset,
+ skb_frag_size(&skb_shinfo(skb)->frags[i]));
+ }
+ if (skb->len & 3) {
+ put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma,
+ 4 - (skb->len & 3));
}
- if (skb->len & 3)
- put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));
/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
@@ -1469,10 +1468,7 @@ if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
static void bug_int(struct atm_dev *dev,unsigned long reason)
{
- struct eni_dev *eni_dev;
-
DPRINTK(">bug_int\n");
- eni_dev = ENI_DEV(dev);
if (reason & MID_DMA_ERR_ACK)
printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
"error\n",dev->number);
@@ -1571,7 +1567,7 @@ tx_complete++;
/*--------------------------------- entries ---------------------------------*/
-static const char *media_name[] __devinitdata = {
+static char * const media_name[] = {
"MMF", "SMF", "MMF", "03?", /* 0- 3 */
"UTP", "05?", "06?", "07?", /* 4- 7 */
"TAXI","09?", "10?", "11?", /* 8-11 */
@@ -1595,7 +1591,7 @@ static const char *media_name[] __devinitdata = {
} })
-static int __devinit get_esi_asic(struct atm_dev *dev)
+static int get_esi_asic(struct atm_dev *dev)
{
struct eni_dev *eni_dev;
unsigned char tonga;
@@ -1687,7 +1683,7 @@ static int __devinit get_esi_asic(struct atm_dev *dev)
#undef GET_SEPROM
-static int __devinit get_esi_fpga(struct atm_dev *dev, void __iomem *base)
+static int get_esi_fpga(struct atm_dev *dev, void __iomem *base)
{
void __iomem *mac_base;
int i;
@@ -1698,7 +1694,7 @@ static int __devinit get_esi_fpga(struct atm_dev *dev, void __iomem *base)
}
-static int __devinit eni_do_init(struct atm_dev *dev)
+static int eni_do_init(struct atm_dev *dev)
{
struct midway_eprom __iomem *eprom;
struct eni_dev *eni_dev;
@@ -1730,6 +1726,7 @@ static int __devinit eni_do_init(struct atm_dev *dev)
"mapping\n",dev->number);
return error;
}
+ eni_dev->ioaddr = base;
eni_dev->base_diff = real_base - (unsigned long) base;
/* id may not be present in ASIC Tonga boards - check this @@@ */
if (!eni_dev->asic) {
@@ -1791,8 +1788,16 @@ unmap:
goto out;
}
+static void eni_do_release(struct atm_dev *dev)
+{
+ struct eni_dev *ed = ENI_DEV(dev);
+
+ dev->phy->stop(dev);
+ dev->phy = NULL;
+ iounmap(ed->ioaddr);
+}
-static int __devinit eni_start(struct atm_dev *dev)
+static int eni_start(struct atm_dev *dev)
{
struct eni_dev *eni_dev;
@@ -1875,7 +1880,7 @@ free_list:
kfree(eni_dev->free_list);
free_irq:
- free_irq(eni_dev->irq, eni_dev);
+ free_irq(eni_dev->irq, dev);
out:
return error;
@@ -1900,7 +1905,6 @@ static void eni_close(struct atm_vcc *vcc)
static int eni_open(struct atm_vcc *vcc)
{
- struct eni_dev *eni_dev;
struct eni_vcc *eni_vcc;
int error;
short vpi = vcc->vpi;
@@ -1910,7 +1914,6 @@ static int eni_open(struct atm_vcc *vcc)
EVENT("eni_open\n",0,0);
if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
vcc->dev_data = NULL;
- eni_dev = ENI_DEV(vcc->dev);
if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
set_bit(ATM_VF_ADDR,&vcc->flags);
if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
@@ -2090,7 +2093,6 @@ static unsigned char eni_phy_get(struct atm_dev *dev,unsigned long addr)
static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
{
- struct hlist_node *node;
struct sock *s;
static const char *signal[] = { "LOST","unknown","okay" };
struct eni_dev *eni_dev = ENI_DEV(dev);
@@ -2168,7 +2170,7 @@ static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
struct hlist_head *head = &vcc_hash[i];
- sk_for_each(s, node, head) {
+ sk_for_each(s, head) {
struct eni_vcc *eni_vcc;
int length;
@@ -2223,49 +2225,61 @@ static const struct atmdev_ops ops = {
};
-static int __devinit eni_init_one(struct pci_dev *pci_dev,
- const struct pci_device_id *ent)
+static int eni_init_one(struct pci_dev *pci_dev,
+ const struct pci_device_id *ent)
{
struct atm_dev *dev;
struct eni_dev *eni_dev;
- int error = -ENOMEM;
+ struct eni_zero *zero;
+ int rc;
- DPRINTK("eni_init_one\n");
+ rc = pci_enable_device(pci_dev);
+ if (rc < 0)
+ goto out;
- if (pci_enable_device(pci_dev)) {
- error = -EIO;
- goto out0;
- }
+ rc = -ENOMEM;
+ eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL);
+ if (!eni_dev)
+ goto err_disable;
- eni_dev = kmalloc(sizeof(struct eni_dev),GFP_KERNEL);
- if (!eni_dev) goto out0;
- if (!cpu_zeroes) {
- cpu_zeroes = pci_alloc_consistent(pci_dev,ENI_ZEROES_SIZE,
- &zeroes);
- if (!cpu_zeroes) goto out1;
- }
- dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL);
- if (!dev) goto out2;
+ zero = &eni_dev->zero;
+ zero->addr = pci_alloc_consistent(pci_dev, ENI_ZEROES_SIZE, &zero->dma);
+ if (!zero->addr)
+ goto err_kfree;
+
+ dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
+ if (!dev)
+ goto err_free_consistent;
+
+ dev->dev_data = eni_dev;
pci_set_drvdata(pci_dev, dev);
eni_dev->pci_dev = pci_dev;
- dev->dev_data = eni_dev;
eni_dev->asic = ent->driver_data;
- error = eni_do_init(dev);
- if (error) goto out3;
- error = eni_start(dev);
- if (error) goto out3;
+
+ rc = eni_do_init(dev);
+ if (rc < 0)
+ goto err_unregister;
+
+ rc = eni_start(dev);
+ if (rc < 0)
+ goto err_eni_release;
+
eni_dev->more = eni_boards;
eni_boards = dev;
- return 0;
-out3:
+out:
+ return rc;
+
+err_eni_release:
+ eni_do_release(dev);
+err_unregister:
atm_dev_deregister(dev);
-out2:
- pci_free_consistent(eni_dev->pci_dev,ENI_ZEROES_SIZE,cpu_zeroes,zeroes);
- cpu_zeroes = NULL;
-out1:
+err_free_consistent:
+ pci_free_consistent(pci_dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
+err_kfree:
kfree(eni_dev);
-out0:
- return error;
+err_disable:
+ pci_disable_device(pci_dev);
+ goto out;
}
@@ -2277,9 +2291,17 @@ static struct pci_device_id eni_pci_tbl[] = {
MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
-static void __devexit eni_remove_one(struct pci_dev *pci_dev)
+static void eni_remove_one(struct pci_dev *pdev)
{
- /* grrr */
+ struct atm_dev *dev = pci_get_drvdata(pdev);
+ struct eni_dev *ed = ENI_DEV(dev);
+ struct eni_zero *zero = &ed->zero;
+
+ eni_do_release(dev);
+ atm_dev_deregister(dev);
+ pci_free_consistent(pdev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
+ kfree(ed);
+ pci_disable_device(pdev);
}
@@ -2287,7 +2309,7 @@ static struct pci_driver eni_driver = {
.name = DEV_LABEL,
.id_table = eni_pci_tbl,
.probe = eni_init_one,
- .remove = __devexit_p(eni_remove_one),
+ .remove = eni_remove_one,
};