Commit 77921e9e authored by David S. Miller's avatar David S. Miller

[NET]: Actually apply Al's sunqe.c changes.

parent 44c7e9f8
...@@ -722,34 +722,31 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -722,34 +722,31 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
struct net_device *qe_devs[4]; struct net_device *qe_devs[4];
struct sunqe *qeps[4]; struct sunqe *qeps[4];
struct sbus_dev *qesdevs[4]; struct sbus_dev *qesdevs[4];
struct sbus_dev *child;
struct sunqec *qecp = NULL; struct sunqec *qecp = NULL;
u8 bsizes, bsizes_more; u8 bsizes, bsizes_more;
int i, j, res = ENOMEM; int i, j, res = -ENOMEM;
dev = init_etherdev(0, sizeof(struct sunqe)); for (i = 0; i < 4; i++) {
qe_devs[0] = dev; qe_devs[i] = alloc_etherdev(sizeof(struct sunqe));
qeps[0] = (struct sunqe *) dev->priv; if (!qe_devs[i])
qeps[0]->channel = 0; goto out;
spin_lock_init(&qeps[0]->lock); }
for (j = 0; j < 6; j++)
qe_devs[0]->dev_addr[j] = idprom->id_ethaddr[j];
if (version_printed++ == 0) if (version_printed++ == 0)
printk(KERN_INFO "%s", version); printk(KERN_INFO "%s", version);
qe_devs[1] = qe_devs[2] = qe_devs[3] = NULL; for (i = 0; i < 4; i++) {
for (i = 1; i < 4; i++) {
qe_devs[i] = init_etherdev(0, sizeof(struct sunqe));
if (qe_devs[i] == NULL || qe_devs[i]->priv == NULL)
goto qec_free_devs;
qeps[i] = (struct sunqe *) qe_devs[i]->priv; qeps[i] = (struct sunqe *) qe_devs[i]->priv;
for (j = 0; j < 6; j++) for (j = 0; j < 6; j++)
qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j]; qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j];
qeps[i]->channel = i; qeps[i]->channel = i;
spin_lock_init(&qeps[i]->lock);
} }
qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL); qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL);
if (qecp == NULL) if (qecp == NULL)
goto qec_free_devs; goto out1;
qecp->qec_sdev = sdev; qecp->qec_sdev = sdev;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -758,25 +755,15 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -758,25 +755,15 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
qeps[i]->parent = qecp; qeps[i]->parent = qecp;
} }
/* Link in channel 0. */ res = -ENODEV;
i = prom_getintdefault(sdev->child->prom_node, "channel#", -1);
if (i == -1) { res=ENODEV; goto qec_free_devs; }
qesdevs[i] = sdev->child;
/* Link in channel 1. */
i = prom_getintdefault(sdev->child->next->prom_node, "channel#", -1);
if (i == -1) { res=ENODEV; goto qec_free_devs; }
qesdevs[i] = sdev->child->next;
/* Link in channel 2. */ for (i = 0, child = sdev->child; i < 4; i++, child = child->next) {
i = prom_getintdefault(sdev->child->next->next->prom_node, "channel#", -1); /* Link in channel */
if (i == -1) { res=ENODEV; goto qec_free_devs; } j = prom_getintdefault(child->prom_node, "channel#", -1);
qesdevs[i] = sdev->child->next->next; if (j == -1)
goto out2;
/* Link in channel 3. */ qesdevs[j] = child;
i = prom_getintdefault(sdev->child->next->next->next->prom_node, "channel#", -1); }
if (i == -1) { res=ENODEV; goto qec_free_devs; }
qesdevs[i] = sdev->child->next->next->next;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
qeps[i]->qe_sdev = qesdevs[i]; qeps[i]->qe_sdev = qesdevs[i];
...@@ -786,22 +773,18 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -786,22 +773,18 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
GLOB_REG_SIZE, "QEC Global Registers"); GLOB_REG_SIZE, "QEC Global Registers");
if (!qecp->gregs) { if (!qecp->gregs) {
printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n"); printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n");
res = ENODEV; goto out2;
goto qec_free_devs;
} }
/* Make sure the QEC is in MACE mode. */ /* Make sure the QEC is in MACE mode. */
if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) { if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) {
printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n"); printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n");
res = ENODEV; goto out3;
goto qec_free_devs;
} }
/* Reset the QEC. */ /* Reset the QEC. */
if (qec_global_reset(qecp->gregs)) { if (qec_global_reset(qecp->gregs))
res = ENODEV; goto out3;
goto qec_free_devs;
}
/* Find and set the burst sizes for the QEC, since it does /* Find and set the burst sizes for the QEC, since it does
* the actual dma for all 4 channels. * the actual dma for all 4 channels.
...@@ -824,40 +807,36 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -824,40 +807,36 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
qec_init_once(qecp, sdev); qec_init_once(qecp, sdev);
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
struct sunqe *qe = qeps[i];
/* Map in QEC per-channel control registers. */ /* Map in QEC per-channel control registers. */
qeps[i]->qcregs = sbus_ioremap(&qesdevs[i]->resource[0], 0, qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
CREG_REG_SIZE, "QEC Channel Registers"); CREG_REG_SIZE, "QEC Channel Registers");
if (!qeps[i]->qcregs) { if (!qe->qcregs) {
printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i); printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i);
res = ENODEV; goto out4;
goto qec_free_devs;
} }
/* Map in per-channel AMD MACE registers. */ /* Map in per-channel AMD MACE registers. */
qeps[i]->mregs = sbus_ioremap(&qesdevs[i]->resource[1], 0, qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
MREGS_REG_SIZE, "QE MACE Registers"); MREGS_REG_SIZE, "QE MACE Registers");
if (!qeps[i]->mregs) { if (!qe->mregs) {
printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i); printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i);
res = ENODEV; goto out4;
goto qec_free_devs;
} }
qeps[i]->qe_block = sbus_alloc_consistent(qesdevs[i], qe->qe_block = sbus_alloc_consistent(qe->qe_sdev,
PAGE_SIZE, PAGE_SIZE,
&qeps[i]->qblock_dvma); &qe->qblock_dvma);
qeps[i]->buffers = sbus_alloc_consistent(qesdevs[i], qe->buffers = sbus_alloc_consistent(qe->qe_sdev,
sizeof(struct sunqe_buffers), sizeof(struct sunqe_buffers),
&qeps[i]->buffers_dvma); &qe->buffers_dvma);
if (qeps[i]->qe_block == NULL || if (qe->qe_block == NULL || qe->qblock_dvma == 0 ||
qeps[i]->qblock_dvma == 0 || qe->buffers == NULL || qe->buffers_dvma == 0) {
qeps[i]->buffers == NULL || goto out4;
qeps[i]->buffers_dvma == 0) {
res = ENODEV;
goto qec_free_devs;
} }
/* Stop this QE. */ /* Stop this QE. */
qe_stop(qeps[i]); qe_stop(qe);
} }
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
...@@ -871,7 +850,6 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -871,7 +850,6 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
qe_devs[i]->watchdog_timeo = 5*HZ; qe_devs[i]->watchdog_timeo = 5*HZ;
qe_devs[i]->irq = sdev->irqs[0]; qe_devs[i]->irq = sdev->irqs[0];
qe_devs[i]->dma = 0; qe_devs[i]->dma = 0;
ether_setup(qe_devs[i]);
} }
/* QEC receives interrupts from each QE, then it sends the actual /* QEC receives interrupts from each QE, then it sends the actual
...@@ -882,8 +860,13 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -882,8 +860,13 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
if (request_irq(sdev->irqs[0], &qec_interrupt, if (request_irq(sdev->irqs[0], &qec_interrupt,
SA_SHIRQ, "QuadEther", (void *) qecp)) { SA_SHIRQ, "QuadEther", (void *) qecp)) {
printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n"); printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n");
res = EAGAIN; res = -EAGAIN;
goto qec_free_devs; goto out4;
}
for (i = 0; i < 4; i++) {
if (register_netdev(qe_devs[i]) != 0)
goto out5;
} }
/* Report the QE channels. */ /* Report the QE channels. */
...@@ -899,42 +882,43 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev) ...@@ -899,42 +882,43 @@ static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
/* We are home free at this point, link the qe's into /* We are home free at this point, link the qe's into
* the master list for later driver exit. * the master list for later driver exit.
*/ */
for (i = 0; i < 4; i++)
qe_devs[i]->ifindex = dev_new_index();
qecp->next_module = root_qec_dev; qecp->next_module = root_qec_dev;
root_qec_dev = qecp; root_qec_dev = qecp;
return 0; return 0;
qec_free_devs: out5:
while (i--)
unregister_netdev(qe_devs[i]);
free_irq(sdev->irqs[0], (void *)qecp);
out4:
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (qe_devs[i] != NULL) { struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv;
if (qe_devs[i]->priv) {
struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv; if (qe->qcregs)
sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
if (qe->qcregs) if (qe->mregs)
sbus_iounmap(qe->qcregs, CREG_REG_SIZE); sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
if (qe->mregs) if (qe->qe_block)
sbus_iounmap(qe->mregs, MREGS_REG_SIZE); sbus_free_consistent(qe->qe_sdev,
if (qe->qe_block != NULL) PAGE_SIZE,
sbus_free_consistent(qe->qe_sdev, qe->qe_block,
PAGE_SIZE, qe->qblock_dvma);
qe->qe_block, if (qe->buffers)
qe->qblock_dvma); sbus_free_consistent(qe->qe_sdev,
if (qe->buffers != NULL) sizeof(struct sunqe_buffers),
sbus_free_consistent(qe->qe_sdev, qe->buffers,
sizeof(struct sunqe_buffers), qe->buffers_dvma);
qe->buffers, }
qe->buffers_dvma); out3:
} sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
kfree(qe_devs[i]); out2:
} kfree(qecp);
} out1:
if (qecp != NULL) { i = 4;
if (qecp->gregs) out:
sbus_iounmap(qecp->gregs, GLOB_REG_SIZE); while (i--)
kfree(qecp); kfree(qe_devs[i]);
}
return res; return res;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment