aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sunlance.c173
1 files changed, 97 insertions, 76 deletions
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 6381243d8d00..2c239ab63a80 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -266,7 +266,6 @@ struct lance_private {
266 char *name; 266 char *name;
267 dma_addr_t init_block_dvma; 267 dma_addr_t init_block_dvma;
268 struct net_device *dev; /* Backpointer */ 268 struct net_device *dev; /* Backpointer */
269 struct lance_private *next_module;
270 struct sbus_dev *sdev; 269 struct sbus_dev *sdev;
271 struct timer_list multicast_timer; 270 struct timer_list multicast_timer;
272}; 271};
@@ -298,8 +297,6 @@ int sparc_lance_debug = 2;
298 297
299#define LANCE_ADDR(x) ((long)(x) & ~0xff000000) 298#define LANCE_ADDR(x) ((long)(x) & ~0xff000000)
300 299
301static struct lance_private *root_lance_dev;
302
303/* Load the CSR registers */ 300/* Load the CSR registers */
304static void load_csrs(struct lance_private *lp) 301static void load_csrs(struct lance_private *lp)
305{ 302{
@@ -1327,9 +1324,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = {
1327 .get_link = sparc_lance_get_link, 1324 .get_link = sparc_lance_get_link,
1328}; 1325};
1329 1326
1330static int __init sparc_lance_init(struct sbus_dev *sdev, 1327static int __init sparc_lance_probe_one(struct sbus_dev *sdev,
1331 struct sbus_dma *ledma, 1328 struct sbus_dma *ledma,
1332 struct sbus_dev *lebuffer) 1329 struct sbus_dev *lebuffer)
1333{ 1330{
1334 static unsigned version_printed; 1331 static unsigned version_printed;
1335 struct net_device *dev; 1332 struct net_device *dev;
@@ -1473,6 +1470,7 @@ no_link_test:
1473 1470
1474 lp->dev = dev; 1471 lp->dev = dev;
1475 SET_MODULE_OWNER(dev); 1472 SET_MODULE_OWNER(dev);
1473 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
1476 dev->open = &lance_open; 1474 dev->open = &lance_open;
1477 dev->stop = &lance_close; 1475 dev->stop = &lance_close;
1478 dev->hard_start_xmit = &lance_start_xmit; 1476 dev->hard_start_xmit = &lance_start_xmit;
@@ -1500,8 +1498,7 @@ no_link_test:
1500 goto fail; 1498 goto fail;
1501 } 1499 }
1502 1500
1503 lp->next_module = root_lance_dev; 1501 dev_set_drvdata(&sdev->ofdev.dev, lp);
1504 root_lance_dev = lp;
1505 1502
1506 printk(KERN_INFO "%s: LANCE ", dev->name); 1503 printk(KERN_INFO "%s: LANCE ", dev->name);
1507 1504
@@ -1536,88 +1533,112 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev)
1536#include <asm/machines.h> 1533#include <asm/machines.h>
1537 1534
1538/* Find all the lance cards on the system and initialize them */ 1535/* Find all the lance cards on the system and initialize them */
1539static int __init sparc_lance_probe(void) 1536static struct sbus_dev sun4_sdev;
1537static int __init sparc_lance_init(void)
1540{ 1538{
1541 static struct sbus_dev sdev;
1542 static int called;
1543
1544 root_lance_dev = NULL;
1545
1546 if (called)
1547 return -ENODEV;
1548 called++;
1549
1550 if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || 1539 if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
1551 (idprom->id_machtype == (SM_SUN4|SM_4_470))) { 1540 (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
1552 memset(&sdev, 0, sizeof(sdev)); 1541 memset(&sun4_sdev, 0, sizeof(sdev));
1553 sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; 1542 sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
1554 sdev.irqs[0] = 6; 1543 sun4_sdev.irqs[0] = 6;
1555 return sparc_lance_init(&sdev, NULL, NULL); 1544 return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
1556 } 1545 }
1557 return -ENODEV; 1546 return -ENODEV;
1558} 1547}
1559 1548
1560#else /* !CONFIG_SUN4 */ 1549static int __exit sunlance_sun4_remove(void)
1561
1562/* Find all the lance cards on the system and initialize them */
1563static int __init sparc_lance_probe(void)
1564{ 1550{
1565 struct sbus_bus *bus; 1551 struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev);
1566 struct sbus_dev *sdev = NULL; 1552 struct net_device *net_dev = lp->dev;
1567 struct sbus_dma *ledma = NULL; 1553
1568 static int called; 1554 unregister_netdevice(net_dev);
1569 int cards = 0, v; 1555
1570 1556 lance_free_hwresources(root_lance_dev);
1571 root_lance_dev = NULL; 1557
1572 1558 free_netdev(net_dev);
1573 if (called) 1559
1574 return -ENODEV; 1560 dev_set_drvdata(&sun4_sdev->dev, NULL);
1575 called++; 1561
1576
1577 for_each_sbus (bus) {
1578 for_each_sbusdev (sdev, bus) {
1579 if (strcmp(sdev->prom_name, "le") == 0) {
1580 cards++;
1581 if ((v = sparc_lance_init(sdev, NULL, NULL)))
1582 return v;
1583 continue;
1584 }
1585 if (strcmp(sdev->prom_name, "ledma") == 0) {
1586 cards++;
1587 ledma = find_ledma(sdev);
1588 if ((v = sparc_lance_init(sdev->child,
1589 ledma, NULL)))
1590 return v;
1591 continue;
1592 }
1593 if (strcmp(sdev->prom_name, "lebuffer") == 0){
1594 cards++;
1595 if ((v = sparc_lance_init(sdev->child,
1596 NULL, sdev)))
1597 return v;
1598 continue;
1599 }
1600 } /* for each sbusdev */
1601 } /* for each sbus */
1602 if (!cards)
1603 return -ENODEV;
1604 return 0; 1562 return 0;
1605} 1563}
1606#endif /* !CONFIG_SUN4 */
1607 1564
1608static void __exit sparc_lance_cleanup(void) 1565#else /* !CONFIG_SUN4 */
1566
1567static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1609{ 1568{
1610 struct lance_private *lp; 1569 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1570 struct device_node *dp = dev->node;
1571 int err;
1572
1573 if (!strcmp(dp->name, "le")) {
1574 err = sparc_lance_probe_one(sdev, NULL, NULL);
1575 } else if (!strcmp(dp->name, "ledma")) {
1576 struct sbus_dma *ledma = find_ledma(sdev);
1611 1577
1612 while (root_lance_dev) { 1578 err = sparc_lance_probe_one(sdev->child, ledma, NULL);
1613 lp = root_lance_dev->next_module; 1579 } else {
1580 BUG_ON(strcmp(dp->name, "lebuffer"));
1614 1581
1615 unregister_netdev(root_lance_dev->dev); 1582 err = sparc_lance_probe_one(sdev->child, NULL, sdev);
1616 lance_free_hwresources(root_lance_dev);
1617 free_netdev(root_lance_dev->dev);
1618 root_lance_dev = lp;
1619 } 1583 }
1584
1585 return err;
1586}
1587
1588static int __devexit sunlance_sbus_remove(struct of_device *dev)
1589{
1590 struct lance_private *lp = dev_get_drvdata(&dev->dev);
1591 struct net_device *net_dev = lp->dev;
1592
1593 unregister_netdevice(net_dev);
1594
1595 lance_free_hwresources(lp);
1596
1597 free_netdev(net_dev);
1598
1599 dev_set_drvdata(&dev->dev, NULL);
1600
1601 return 0;
1602}
1603
1604static struct of_device_id sunlance_sbus_match[] = {
1605 {
1606 .name = "le",
1607 },
1608 {
1609 .name = "ledma",
1610 },
1611 {
1612 .name = "lebuffer",
1613 },
1614 {},
1615};
1616
1617MODULE_DEVICE_TABLE(of, sunlance_sbus_match);
1618
1619static struct of_platform_driver sunlance_sbus_driver = {
1620 .name = "sunlance",
1621 .match_table = sunlance_sbus_match,
1622 .probe = sunlance_sbus_probe,
1623 .remove = __devexit_p(sunlance_sbus_remove),
1624};
1625
1626
1627/* Find all the lance cards on the system and initialize them */
1628static int __init sparc_lance_init(void)
1629{
1630 return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
1631}
1632#endif /* !CONFIG_SUN4 */
1633
1634static void __exit sparc_lance_exit(void)
1635{
1636#ifdef CONFIG_SUN4
1637 sunlance_sun4_remove();
1638#else
1639 of_unregister_driver(&sunlance_sbus_driver);
1640#endif
1620} 1641}
1621 1642
1622module_init(sparc_lance_probe); 1643module_init(sparc_lance_init);
1623module_exit(sparc_lance_cleanup); 1644module_exit(sparc_lance_exit);